Timeline: Fixes for flac and ogg/vorbis playback and recording. Add new Ogg capture formats at various quality levels.

pull/116/head
Jonathan Moore Liles 2013-08-22 18:02:19 -07:00
parent 2afec38a54
commit 8fe598eff4
4 changed files with 61 additions and 13 deletions

View File

@ -88,6 +88,21 @@ Audio_File::filename ( void ) const
return _path;
}
static bool is_poor_seeker ( const char * filename )
{
if ( ( strlen(filename) > 4 &&
! strcasecmp( &filename[strlen(filename)-4], ".ogg" ) )
||
( strlen(filename) > 5 &&
! strcasecmp( &filename[strlen(filename)-5], ".flac" ) )
)
{
return true;
}
return false;
}
/** attempt to open any supported filetype */
Audio_File *
Audio_File::from_file ( const char * filename )
@ -96,11 +111,21 @@ Audio_File::from_file ( const char * filename )
Audio_File *a;
if ( ( a = _open_files[ std::string( filename ) ] ) )
if ( is_poor_seeker(filename) )
{
++a->_refs;
return a;
/* OGG and FLAC have poor seek performance, so they require
* separate file descriptors to be useful */
}
else
{
/* WAV are quick enough to seek that we can save
* filedescriptors by sharing them between regions */
if ( ( a = _open_files[ std::string( filename ) ] ) )
{
++a->_refs;
return a;
}
}
if ( ( a = Audio_File_SF::from_file( filename ) ) )
@ -118,7 +143,7 @@ Audio_File::from_file ( const char * filename )
done:
ASSERT( ! _open_files[ std::string( filename ) ], "Programming errror" );
/* ASSERT( ! _open_files[ std::string( filename ) ], "Programming errror" ); */
_open_files[ std::string( filename ) ] = a;
@ -130,8 +155,15 @@ done:
Audio_File *
Audio_File::duplicate ( void )
{
++_refs;
return this;
if ( is_poor_seeker( _filename ) )
{
return from_file(_filename);
}
else
{
++_refs;
return this;
}
}
/** release the resources assoicated with this audio file if no other

View File

@ -49,6 +49,7 @@ protected:
const char *name;
const char *extension;
unsigned long id;
int quality;
};
char *_filename;

View File

@ -42,11 +42,13 @@ const Audio_File::format_desc Audio_File_SF::supported_formats[] =
{ "Wav 24", "wav", SF_FORMAT_WAV | SF_FORMAT_PCM_24 | SF_ENDIAN_FILE },
{ "Wav 16", "wav", SF_FORMAT_WAV | SF_FORMAT_PCM_16 | SF_ENDIAN_FILE },
{ "Wav f32", "wav", SF_FORMAT_WAV | SF_FORMAT_FLOAT | SF_ENDIAN_FILE },
{ "Au 24", "au", SF_FORMAT_AU | SF_FORMAT_PCM_24 | SF_ENDIAN_FILE },
{ "Au 16", "au", SF_FORMAT_AU | SF_FORMAT_PCM_16 | SF_ENDIAN_FILE },
{ "FLAC", "flac", SF_FORMAT_FLAC | SF_FORMAT_PCM_24 },
#ifdef HAS_SF_FORMAT_VORBIS
{ "Ogg Vorbis", "ogg", SF_FORMAT_OGG | SF_FORMAT_VORBIS | SF_FORMAT_PCM_16 },
{ "Au 24", "au", SF_FORMAT_AU | SF_FORMAT_PCM_24 | SF_ENDIAN_FILE },
{ "Au 16", "au", SF_FORMAT_AU | SF_FORMAT_PCM_16 | SF_ENDIAN_FILE },
{ "FLAC", "flac", SF_FORMAT_FLAC | SF_FORMAT_PCM_24 },
#ifdef HAVE_SF_FORMAT_VORBIS
{ "Vorbis q10", "ogg", SF_FORMAT_OGG | SF_FORMAT_VORBIS, 10 },
{ "Vorbis q6", "ogg", SF_FORMAT_OGG | SF_FORMAT_VORBIS, 6 },
{ "Vorbis q3", "ogg", SF_FORMAT_OGG | SF_FORMAT_VORBIS, 3 },
#endif
{ 0, 0 }
};
@ -125,6 +127,14 @@ Audio_File_SF::create ( const char *filename, nframes_t samplerate, int channels
return NULL;
}
if ( !strcmp( fd->extension, "ogg" ) )
{
/* set high quality encoding for vorbis */
double quality = ( fd->quality + 1 ) / (float)11;
sf_command( out, SFC_SET_VBR_ENCODING_QUALITY, &quality, sizeof( double ) );
}
Audio_File_SF *c = new Audio_File_SF;
c->_path = filepath;

View File

@ -31,7 +31,12 @@ def configure(conf):
# conf.env.append_value('CXXFLAGS', '-D_FILE_OFFSET_BITS=64')
conf.check_cfg(package='sndfile', uselib_store='SNDFILE',args="--cflags --libs",
atleast_version='1.0.17', mandatory=True)
atleast_version='1.0.18', mandatory=True)
conf.check(msg='Checking for SF_FORMAT_VORBIS',
define_name='HAVE_SF_FORMAT_VORBIS',
fragment='#include <sndfile.h>\nint main ( int argc, char **argv ) { return SF_FORMAT_VORBIS; }',
execute=False, mandatory=False)
conf.define('VERSION', PACKAGE_VERSION)
conf.define('SYSTEM_PATH', '/'.join( [ conf.env.DATADIR, APPNAME ] ) )