Ogg vs Caf for audio
Page 1 of 3 • Share •
Page 1 of 3 • 1, 2, 3 
Ogg vs Caf for audio
First off, in Tutorial09 you used .ogg files for all audio. Are .caf files supported as well?
What is the preferred audio file format? I may be mistaken, but I thought the iPhone can play .caf files natively and that it was the file format Apple was recommending for all audio. Don't .ogg files require a bit of processor time to make them playable? What are the pros/cons of using .ogg vs .caf?
Thanks for an awesome engine by the way. I am liking SIO2 more and more every day that i use it.
What is the preferred audio file format? I may be mistaken, but I thought the iPhone can play .caf files natively and that it was the file format Apple was recommending for all audio. Don't .ogg files require a bit of processor time to make them playable? What are the pros/cons of using .ogg vs .caf?
Thanks for an awesome engine by the way. I am liking SIO2 more and more every day that i use it.
uprise78- Posts: 228
Join date: 2008-10-31
Re: Ogg vs Caf for audio
Yeah OGG require some processing to be playable (and a little bit way too much I think...), Im really not familiar with CAF but i'll check it out...
Tks for the tip!
Cheers,
Tks for the tip!
Cheers,

sio2interactive- Posts: 1524
Join date: 2008-08-26
Age: 30
Location: Shanghai

Re: Ogg vs Caf for audio
Here is a bit of info about .caf files:
The command I have been using to convert audio files for other iPhone projects is:
This command will give you all of the possible options for afconvert:
- For uncompressed audio, use 16-bit, little-endian, linear PCM audio packaged in a CAF file
- If you need to play multiple compressed sounds simultaneously, use the IMA/ADPCM audio (IMA4) format.
The command I have been using to convert audio files for other iPhone projects is:
- Code:
/usr/bin/afconvert -f caff -d LEI16 {INPUT} {OUTPUT}
This command will give you all of the possible options for afconvert:
- Code:
afconvert -h
uprise78- Posts: 228
Join date: 2008-10-31
Re: Ogg vs Caf for audio
Yeah that's all great... but what Im expecting for its a loader to plug the binary data to OpenAL 

sio2interactive- Posts: 1524
Join date: 2008-08-26
Age: 30
Location: Shanghai

Re: Ogg vs Caf for audio
I can give creating the loader a shot. Do you have any pointers on where to start such as the location of the ogg to openal code?
uprise78- Posts: 228
Join date: 2008-10-31
Re: Ogg vs Caf for audio
The Sound_Engine.cpp which comes with the CrashLander SDK example should be a good starting point. It uses CAF files and feeds them into OpenAL.
Best,
Matt
Best,
Matt
matt- Posts: 155
Join date: 2008-09-30

Re: Ogg vs Caf for audio
I had some problems with Sound_Engine.cpp that I never resolved in my initial testing of it. In particular is this puzzling line of code located in LoadFileData function.
It seems to limit sound files to only 8bits. Changing this to 16 didn't work, but maybe my file wasn't compatible (afconvert is a great tip! ). When I asked someone about this, they told me to use some code from WWDC which was better and they had no problems with 16 bit sounds.
- Code:
if (!TestAudioFormatNativeEndian(theFileFormat) && (theFileFormat.mBitsPerChannel > 8))
return kSoundEngineErrInvalidFileFormat;
It seems to limit sound files to only 8bits. Changing this to 16 didn't work, but maybe my file wasn't compatible (afconvert is a great tip! ). When I asked someone about this, they told me to use some code from WWDC which was better and they had no problems with 16 bit sounds.
zzajin- Posts: 81
Join date: 2008-10-14
Re: Ogg vs Caf for audio
zzajin wrote:
When I asked someone about this, they told me to use some code from WWDC which was better and they had no problems with 16 bit sounds.
What code from WWDC did they recommend? I went and have access to all of the code and SoundEngine is what I have been using without issue.
uprise78- Posts: 228
Join date: 2008-10-31
Re: Ogg vs Caf for audio
They didn't say. I assume it was the TouchFighter (game?) code people seem to want access to.
zzajin- Posts: 81
Join date: 2008-10-14
Re: Ogg vs Caf for audio
Looks like TouchFighter uses the same SoundEngine class.
Has anyone dug into SIO2's audio playback code enough to let me know where I need to plugin the caf loader? SoundEngine is a bit heavy to plugin completely as it would completely replace the current SIO2 audio playback and openAL management code so knowing where to plugin caf loading and playback would be great. This would definitely be a worthwhile addition to SIO2.
Has anyone dug into SIO2's audio playback code enough to let me know where I need to plugin the caf loader? SoundEngine is a bit heavy to plugin completely as it would completely replace the current SIO2 audio playback and openAL management code so knowing where to plugin caf loading and playback would be great. This would definitely be a worthwhile addition to SIO2.
uprise78- Posts: 228
Join date: 2008-10-31
Re: Ogg vs Caf for audio
My guess is that loading soundbufffers would be similar to the way images are done. Probably what is in sio2SoundBufferLoad would get moved to a sio2SoundBufferLoadOGG and a switch statement would select that or a sio2SoundBufferLoadCAF function based on the stream's filename. Checkout sio2ImageLoad in sio_image.
zzajin- Posts: 81
Join date: 2008-10-14
Re: Ogg vs Caf for audio
I have basic .caf file playback working but it is not without issues. There is an odd sound artifiact that plays for a split second when the sound loops. Also missing is automatic detection of frequency and format.
Modify sio2_soundbuffer.cc:
In order to get the exporter to let you export a CAF file from blender you need to modify the exporter python script. Replace the following two lines (238, 240):
with these 2 lines:
That should get you going. If anyone can give me a clue as to why the sound artifact is there I would be happy to look into it to the best of my abilities.
Modify sio2_soundbuffer.cc:
- Code:
// Replace the old sio2SoundBufferLoad function with this one
void sio2SoundBufferLoad( SIO2soundbuffer *_SIO2soundbuffer,
SIO2stream *_SIO2stream )
{
if( strstr( _SIO2stream->fname, ".ogg" ) ||
strstr( _SIO2stream->fname, ".OGG" ))
{
sio2SoundBufferLoadOGG( _SIO2soundbuffer, _SIO2stream );
}
else if( strstr( _SIO2stream->fname, ".caf" ) ||
strstr( _SIO2stream->fname, ".CAF" ))
{
sio2SoundBufferLoadCAF( _SIO2soundbuffer, _SIO2stream );
}
}
// This is a new function. Put it in the header also.
void sio2SoundBufferLoadOGG( SIO2soundbuffer *_SIO2soundbuffer,
SIO2stream *_SIO2stream )
{
OggVorbis_File ovfile;
vorbis_info *info;
ov_callbacks callbacks;
int count,
bitstream;
char *cursor;
callbacks.read_func = sio2SoundBufferRead;
callbacks.seek_func = sio2SoundBufferSeek;
callbacks.tell_func = sio2SoundBufferTell;
callbacks.close_func = sio2SoundBufferClose;
ov_open_callbacks( _SIO2stream, &ovfile, NULL, 0, callbacks );
info = ov_info( &ovfile, -1 );
if( info->channels == 1 )
{ _SIO2soundbuffer->format = AL_FORMAT_MONO16; }
else
{ _SIO2soundbuffer->format = AL_FORMAT_STEREO16; }
_SIO2soundbuffer->size = ( ov_pcm_total( &ovfile, -1 ) * info->channels << 1 );
_SIO2soundbuffer->data = ( char * ) malloc( _SIO2soundbuffer->size );
_SIO2soundbuffer->freq = info->rate;
cursor = _SIO2soundbuffer->data;
while( ( count = ov_read( &ovfile,
cursor,
SIO2_SOUND_BUFFER_SIZE,
0, 2, 1,
&bitstream ) ) > 0 )
{ cursor += count; }
ov_clear( &ovfile );
}
// This is a new function. Put it in the header also.
void sio2SoundBufferLoadCAF( SIO2soundbuffer *_SIO2soundbuffer,
SIO2stream *_SIO2stream )
{
_SIO2soundbuffer->format = AL_FORMAT_STEREO16;
_SIO2soundbuffer->size = ( _SIO2stream->size );
_SIO2soundbuffer->freq = 44100;
_SIO2soundbuffer->data = ( char * ) malloc( _SIO2soundbuffer->size );
sio2StreamRead( _SIO2stream, &_SIO2soundbuffer->data[ 0 ], _SIO2stream->size - 1 );
}
In order to get the exporter to let you export a CAF file from blender you need to modify the exporter python script. Replace the following two lines (238, 240):
- Code:
ogg_uc_pos = t_name.upper().rfind('.OGG' )
if( ogg_uc_pos > -1 ):
with these 2 lines:
- Code:
if( t_name.upper().endswith('.OGG') or t_name.upper().endswith('.CAF') ):
That should get you going. If anyone can give me a clue as to why the sound artifact is there I would be happy to look into it to the best of my abilities.
uprise78- Posts: 228
Join date: 2008-10-31
Re: Ogg vs Caf for audio
It looks like caf files have at least 2 "chunks" an audio description and an audio data chunk.
http://developer.apple.com/documentation/MusicAudio/Reference/CAFSpec/CAF_overview/chapter_2_section_3.html#//apple_ref/doc/uid/TP40001862-CH209-TPXREF102
Perhaps there is some noise because the audio description is sent to the OpenAL buffer. Doesn't it need only the data chunk?
http://developer.apple.com/documentation/MusicAudio/Reference/CAFSpec/CAF_overview/chapter_2_section_3.html#//apple_ref/doc/uid/TP40001862-CH209-TPXREF102
Perhaps there is some noise because the audio description is sent to the OpenAL buffer. Doesn't it need only the data chunk?
zzajin- Posts: 81
Join date: 2008-10-14
Re: Ogg vs Caf for audio
good call zzajin. The clicking artifact is most definetely the header and description chunk. I'll try parsing them put and I might as well grab the correct file format data as well.
uprise78- Posts: 228
Join date: 2008-10-31
Re: Ogg vs Caf for audio
Parsing out the header did the trick. Caf files are working flawlessly now. Here is the code for sio2_soundbuffer.cc:
You will need to make the change to the exporter as shown above. You will also need to include the AudioToolbox.framework in your project and add one line to sio2.h:
If anyone can write a CAF parser the AudioToolbox/AudioFileStream.h requirement can be removed though that probably isn't all that important. This solution should work with any CAF files that are supported by the iPhones openAL implementation.
- Code:
void sio2SoundBufferLoad( SIO2soundbuffer *_SIO2soundbuffer,
SIO2stream *_SIO2stream )
{
if( strstr( _SIO2stream->fname, ".ogg" ) ||
strstr( _SIO2stream->fname, ".OGG" ))
{
sio2SoundBufferLoadOGG( _SIO2soundbuffer, _SIO2stream );
}
else if( strstr( _SIO2stream->fname, ".caf" ) ||
strstr( _SIO2stream->fname, ".CAF" ))
{
sio2SoundBufferLoadCAF( _SIO2soundbuffer, _SIO2stream );
}
}
void sio2SoundBufferLoadOGG( SIO2soundbuffer *_SIO2soundbuffer,
SIO2stream *_SIO2stream )
{
OggVorbis_File ovfile;
vorbis_info *info;
ov_callbacks callbacks;
int count,
bitstream;
char *cursor;
callbacks.read_func = sio2SoundBufferRead;
callbacks.seek_func = sio2SoundBufferSeek;
callbacks.tell_func = sio2SoundBufferTell;
callbacks.close_func = sio2SoundBufferClose;
ov_open_callbacks( _SIO2stream, &ovfile, NULL, 0, callbacks );
info = ov_info( &ovfile, -1 );
if( info->channels == 1 )
{ _SIO2soundbuffer->format = AL_FORMAT_MONO16; }
else
{ _SIO2soundbuffer->format = AL_FORMAT_STEREO16; }
_SIO2soundbuffer->size = ( ov_pcm_total( &ovfile, -1 ) * info->channels << 1 );
_SIO2soundbuffer->data = ( char * ) malloc( _SIO2soundbuffer->size );
_SIO2soundbuffer->freq = info->rate;
cursor = _SIO2soundbuffer->data;
while( ( count = ov_read( &ovfile,
cursor,
SIO2_SOUND_BUFFER_SIZE,
0, 2, 1,
&bitstream ) ) > 0 )
{ cursor += count; }
ov_clear( &ovfile );
}
void sio2SoundBufferLoadCAF( SIO2soundbuffer *_SIO2soundbuffer,
SIO2stream *_SIO2stream )
{
// TODO: add error checking on the OSStatus return values
// Open the audio file stream and parse it
AudioFileStreamID afID;
OSStatus result = AudioFileStreamOpen(_SIO2soundbuffer, sio2CAFAudioPropertyListener, sio2CAFProcessAudioStreamPackets, kAudioFileCAFType, &afID);
result = AudioFileStreamParseBytes(afID, (UInt32)_SIO2stream->size, _SIO2stream->buf, NULL);
AudioFileStreamClose(afID);
}
void sio2CAFAudioPropertyListener( void *_source,
AudioFileStreamID inAudioFileStream,
AudioFileStreamPropertyID inPropertyID,
UInt32 *ioFlags )
{
// We only really care about the dataFormat
if(inPropertyID == kAudioFilePropertyDataFormat)
{
AudioStreamBasicDescription audioFormat;
UInt32 sizeOfPlaybackFormatASBDStruct = sizeof(audioFormat);
AudioFileStreamGetProperty(inAudioFileStream, kAudioFilePropertyDataFormat, &sizeOfPlaybackFormatASBDStruct, &audioFormat);
// Copy relevant data to the soundBuffer
SIO2soundbuffer *_SIO2soundbuffer = ( SIO2soundbuffer *)_source;
if( audioFormat.mChannelsPerFrame == 1 )
_SIO2soundbuffer->format = AL_FORMAT_MONO16;
else
_SIO2soundbuffer->format = AL_FORMAT_STEREO16;
_SIO2soundbuffer->freq = audioFormat.mSampleRate;
}
}
void sio2CAFProcessAudioStreamPackets( void *_source,
UInt32 inNumberBytes,
UInt32 inNumberPackets,
const void *inInputData,
AudioStreamPacketDescription *inPacketDescriptions )
{
SIO2soundbuffer *_SIO2soundbuffer = ( SIO2soundbuffer *)_source;
_SIO2soundbuffer->size = inNumberBytes;
_SIO2soundbuffer->data = ( char * ) malloc( inNumberBytes );
memcpy(_SIO2soundbuffer->data, inInputData, inNumberBytes);
}
You will need to make the change to the exporter as shown above. You will also need to include the AudioToolbox.framework in your project and add one line to sio2.h:
- Code:
#include #include <AudioToolbox/AudioFileStream.h>
If anyone can write a CAF parser the AudioToolbox/AudioFileStream.h requirement can be removed though that probably isn't all that important. This solution should work with any CAF files that are supported by the iPhones openAL implementation.
uprise78- Posts: 228
Join date: 2008-10-31
Page 1 of 3 • 1, 2, 3 
Permissions of this forum:
You cannot reply to topics in this forum



