Issue converting audio files to Apple Lossless
Issue converting audio files to Apple Lossless
- Subject: Issue converting audio files to Apple Lossless
- From: email@hidden (Scott C. Brown 02)
- Date: 07 Mar 2010 15:24:32 -0500
I'm stumped right now on something. Following Apple's ConvertFile example, I've
writeen some code to do a simple conversion of .wav files to Apple Lossless.
The code seems to work and I get an output file that plays and sounds like I would
expect. But if I decode the file, the bytes don't match up. If I use ConvertFile
directly, the bytes seem to match up on decode
example:
I have a wav file of 70619680 bytes of audio data, of length 6:40.24. When I
encode it to Apple Lossless using my code and then decode it, the resulting wav
file has 70603840 bytes of audio data and is of length 6:40.17. The audio data
in the file matches up to the first 70599744 bytes. So something in my code doesn't
seem to be right
(If I use Apple's ConvertFile directly, I get the full 70619680 bytes on decode)
Does anyone notice anything "off" in my code below? It looks ok to me. But the
files it's outputting aren't exact.
Thanks,
Scott
outputPath and fileName are the output directory and input file, already populated
somewhere else
----
ExtAudioFileRef inFileExtAudioFileRef=nil;
ExtAudioFileRef outFileExtAudioFileRef=nil;
@try
{
NSString *outFile = [outputPath stringByAppendingPathComponent:
[[[fileName lastPathComponent]stringByDeletingPathExtension] stringByAppendingPathExtension:@"m4a"]];
NSURL *inURL = [NSURL fileURLWithPath:fileName];
NSURL *outURL = [NSURL fileURLWithPath:outFile];
AudioStreamBasicDescription inputFormat;
AudioStreamBasicDescription outputFormat;
AudioStreamBasicDescription clientFormat;
// first open the input file
OSStatus err = ExtAudioFileOpenURL ((CFURLRef)inURL, &inFileExtAudioFileRef);
if(err != noErr)
@throw [NSException exceptionWithName:@"Exception" reason:@"ExtAudioFileOpenURL
failed" userInfo:nil];
// get the input file format
UInt32 size = sizeof(inputFormat);
err = ExtAudioFileGetProperty(inFileExtAudioFileRef, kExtAudioFileProperty_FileDataFormat,
&size, &inputFormat);
if(err != noErr)
@throw [NSException exceptionWithName:@"Exception" reason:@"input ExtAudioFileGetProperty
kExtAudioFileProperty_FileDataFormat failed" userInfo:nil];
//get the total length of the in file
UInt32 dataSize;
SInt64 totalFrameCount;
dataSize = sizeof(totalFrameCount);
err = ExtAudioFileGetProperty(inFileExtAudioFileRef, kExtAudioFileProperty_FileLengthFrames,
&dataSize, &totalFrameCount);
if(err != noErr)
@throw [NSException exceptionWithName:@"Exception" reason:[NSString stringWithFormat:@"input
ExtAudioFileGetProperty kExtAudioFileProperty_FileLengthFrames failed %@", UTCreateStringForOSType(err)]
userInfo:nil];
// create the output format
bzero(&outputFormat, sizeof(AudioStreamBasicDescription));
outputFormat.mFormatID = kAudioFormatAppleLossless;
outputFormat.mSampleRate = inputFormat.mSampleRate;
outputFormat.mChannelsPerFrame = inputFormat.mChannelsPerFrame;
switch(inputFormat.mBitsPerChannel) {
case 16:
outputFormat.mFormatFlags = kAppleLosslessFormatFlag_16BitSourceData;
break;
case 20:
outputFormat.mFormatFlags = kAppleLosslessFormatFlag_20BitSourceData;
break;
case 24:
outputFormat.mFormatFlags = kAppleLosslessFormatFlag_24BitSourceData;
break;
case 32:
outputFormat.mFormatFlags = kAppleLosslessFormatFlag_32BitSourceData;
break;
}
// use AudioFormat API to fill out the rest.
size = sizeof(outputFormat);
err = AudioFormatGetProperty(kAudioFormatProperty_FormatInfo, 0, NULL, &size,
&outputFormat);
if(err && err != noErr)
@throw [NSException exceptionWithName:@"Exception" reason:@"output AudioFormatGetProperty
kAudioFormatProperty_FormatInfo failed" userInfo:nil];
// create the output file
//UInt32 flags = _allowsOverwrite ?kAudioFileFlags_EraseFile :0;
err = ExtAudioFileCreateWithURL ((CFURLRef)outURL, kAudioFileM4AType , &outputFormat,
NULL, kAudioFileFlags_EraseFile, &outFileExtAudioFileRef);
if(err && err != noErr)
@throw [NSException exceptionWithName:@"Exception" reason:@"ExtAudioFileCreateWithURL
failed" userInfo:nil];
clientFormat = inputFormat;
//set client data format
size = sizeof(clientFormat);
err = ExtAudioFileSetProperty(inFileExtAudioFileRef, kExtAudioFileProperty_ClientDataFormat,
size, &clientFormat);
if(err != noErr)
@throw [NSException exceptionWithName:@"Exception" reason:@"ExtAudioFileSetProperty
inFile, kExtAudioFileProperty_ClientDataFormat failed" userInfo:nil];
size = sizeof(clientFormat);
err = ExtAudioFileSetProperty(outFileExtAudioFileRef, kExtAudioFileProperty_ClientDataFormat,
size, &clientFormat);
if(err != noErr)
{
NSLog(@"Error %i",err);
@throw [NSException exceptionWithName:@"Exception" reason:@"ExtAudioFileSetProperty
outFile, kExtAudioFileProperty_ClientDataFormat failed" userInfo:nil];
}
// set up buffers
const UInt32 bufferSize = 32*1024;
//char *srcBuffer = new char[bufferSize];
char srcBuffer[bufferSize];
// do the read and write - the conversion is done on and by the write call
int loopCount = 1;
while (1)
{
if(userCancelled)
{
break;
}
AudioBufferList fillBufList;
fillBufList.mNumberBuffers = 1;
fillBufList.mBuffers[0].mNumberChannels = inputFormat.mChannelsPerFrame;
fillBufList.mBuffers[0].mDataByteSize = bufferSize;
fillBufList.mBuffers[0].mData = srcBuffer;
// client format is always linear PCM - so here we determine how many frames
of lpcm
// we can read/write given our buffer size
UInt32 numFrames = (bufferSize / clientFormat.mBytesPerFrame);
err = ExtAudioFileRead (inFileExtAudioFileRef, &numFrames, &fillBufList);
if(err != noErr)
@throw [NSException exceptionWithName:@"Exception" reason:@"ExtAudioFileRead
failed" userInfo:nil];
if (!numFrames) {
// this is our termination condition
break;
}
err = ExtAudioFileWrite(outFileExtAudioFileRef, numFrames, &fillBufList);
if(err != noErr)
@throw [NSException exceptionWithName:@"Exception" reason:@"ExtAudioFileWrite
failed" userInfo:nil];
double percentage = 100.0*(loopCount * (double)numFrames)/(double)totalFrameCount;
[progressIndicator setDoubleValue:percentage];
loopCount++;
}
}
@catch (NSException * e)
{
NSLog(@"Exception %@",e);
error = YES;
}
@finally
{
ExtAudioFileDispose(outFileExtAudioFileRef);
ExtAudioFileDispose(inFileExtAudioFileRef);
}
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden