2

I am using OpenAL in the iOS app that I'm working on and our client gave us a bunch of audio files that are all in big-endian format. My problem is that OpenAL only plays little-endian formats.

So I figure all I need to do is find the audio data, and reverse it, correct?

My code for extracting the audio data (taken from the OpenAL tutorial):

-(void)addSound:(NSString*)theSound
{
// get the full path of the file
NSString* fileName = [[NSBundle mainBundle] pathForResource:theSound ofType:@"caf"];
// first, open the file
NSLog(@"fileNAme is ===== %@", fileName);
AudioFileID fileID = [self openAudioFile:fileName];

// find out how big the actual audio data is
UInt32 fileSize = [self audioFileSize:fileID];

// this is where the audio data will live for the moment
unsigned char * outData = malloc(fileSize);

// this where we actually get the bytes from the file and put them
// into the data buffer
OSStatus result = noErr;
result = AudioFileReadBytes(fileID, false, 0, &fileSize, outData);
NSLog(@"OUT DATA IS == %d", outData);
AudioFileClose(fileID); //close the file

if (result != 0) NSLog(@"cannot load effect: %@",fileName);

NSUInteger bufferID;
// grab a buffer ID from openAL
alGenBuffers(1, &bufferID);

// jam the audio data into the new buffer
alBufferData(bufferID,AL_FORMAT_STEREO16,outData,fileSize,44100);

// save the buffer so I can release it later
[bufferStorageArray addObject:[NSNumber numberWithUnsignedInteger:bufferID]];

NSUInteger sourceID;

// grab a source ID from openAL
alGenSources(1, &sourceID);

// attach the buffer to the source
alSourcei(sourceID, AL_BUFFER, bufferID);
// set some basic source prefs
alSourcef(sourceID, AL_PITCH, 1.0f);
alSourcef(sourceID, AL_GAIN, 1.0f);

//alSourcei(sourceID, AL_LOOPING, AL_TRUE);

// store this for future use
[soundDictionary setObject:[NSNumber numberWithUnsignedInt:sourceID] forKey:theSound];

// clean up the buffer
if (outData)
{
    free(outData);
    outData = NULL;
}
}

I figure unsigned char * outdata; is what I need to reverse (after the audio file data is loaded into it, of course), but I have no idea how to do so. Can anyone help me out with this please?

jscs
  • 63,694
  • 13
  • 151
  • 195
rbertsch8
  • 222
  • 2
  • 12
  • possible duplicate of [Convert big endian to little endian when reading from a binary file](http://stackoverflow.com/questions/3823921/convert-big-endian-to-little-endian-when-reading-from-a-binary-file) – jscs Aug 14 '12 at 20:24
  • see concise solution at http://stackoverflow.com/questions/8552864/bit-conversion-tool-in-objective-c – Scott Stensland Aug 15 '12 at 14:54

1 Answers1

1

in this case, you should use ExtAudioFileRead after configuring the ExtAudioFile's AudioConvertor's format. it will save you a lot of time. you might swap yourself if you know all your input files have the same sample format.

ExtAudioFile is in AudioToolbox.framework on OS X and iOS (basically a layer above AudioFile with more high level capabilities), and you can create one by wrapping an AudioFile.

AudioConvertor could also be used without ExtAudioFile.

in some cases, you can just use the OS X afonvert utility to swap them to LE, and be done with it without adding (unnecessary) programming challenges.

writing your own endian-swapping routines for arrays isn't hard - it's just time consuming, tedious, and you typically need to make sure it's fast and capable of supporting unnaturally aligned sample data. this involves:

for (each sample) {
  reverse order of bytes in sample
}

W'rkncacnter furnished this link: Convert big endian to little endian when reading from a binary file

you can use that approach it if is naturally aligned. and you would need variants for each size and sample description you would see on input. the OS also offers OSSwap routines, but these don't handle all sample formats -- they focus on builtin types.

Community
  • 1
  • 1
justin
  • 104,054
  • 14
  • 179
  • 226
  • thanks for the response. ill try that out. I would prefer to use afconvert, but unfortunately for this app the user will be able to download additional media to it so it must be done programmatically. – rbertsch8 Aug 14 '12 at 21:04
  • @rbertsch8 ok, bummer - i also provided an overview of how you would approach writing your own swapping routines. – justin Aug 14 '12 at 21:11
  • 2
    Here's an implementation that loads any format iOS supports into 16-bit PCM LEI (OpenAL): https://github.com/kstenerud/ObjectAL-for-iPhone/blob/master/ObjectAL/ObjectAL/Support/OALAudioFile.m If possible, you should try to get the client to use AAC encoding, saving up to 10x the bandwidth compared to uncompressed audio. – Karl Aug 15 '12 at 15:26
  • @Karl thanks. this is an implementation using `ExtAudioFileRead` – justin Aug 15 '12 at 23:52