• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Decoding compressed to LPCM
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Decoding compressed to LPCM


  • Subject: Re: Decoding compressed to LPCM
  • From: Jens Alfke <email@hidden>
  • Date: Mon, 21 Apr 2008 16:07:27 -0700


On 21 Apr '08, at 12:22 PM, Aurélien Ammeloot wrote:

This code works for converting big endian AIFF to little endian WAV. But it doesn't work from a compressed audio file AAC or MP3 to little endian WAV. I've tried step-by-step debugging and it seems ExtAudioFileCreateNew(...) fails in the latter cases.

To pipe samples from the input to the output, both ends have to have the same client data format. You're not doing that.


In other words, reading from an ExtAudioFile converts from the file data format to the client data format.
Writing to an ExtAudioFile converts from the client data format to the file data format.


Here's some code I've used in one of my projects to convert between file formats (I used it for MP3-to-AAC, or to change bit-rates.)
The variables starting with "_" are instance variables that have already been set up elsewhere.
The code uses some private utilities of mine, so it won't all compile directly, but it should show you how to do the task.


—Jens

- (void) main
{
	ExtAudioFileRef infile=NULL, outfile=NULL;
    char *srcBuffer = NULL;
    CFAbsoluteTime time = 0;

try{
// first open the input file
OSStatus err = ExtAudioFileOpenURL ((CFURLRef)_inputURL, &infile);
XThrowIfError (err, "ExtAudioFileOpen");


// get the input file format
AudioStreamBasicDescription inputFormat;
UInt32 size = sizeof(inputFormat);
err = ExtAudioFileGetProperty(infile, kExtAudioFileProperty_FileDataFormat, &size, &inputFormat);
XThrowIfError (err, "ExtAudioFileGetProperty kExtAudioFileProperty_FileDataFormat");


// Fill in the output format
if( _outputFormat.mSampleRate == 0 ) {
_outputFormat.mSampleRate = inputFormat.mSampleRate;
_outputFormat.mChannelsPerFrame = inputFormat.mChannelsPerFrame;
if( _outputFormat.mFormatID != kAudioFormatLinearPCM ) {
// use AudioFormat API to fill out the rest.
size = sizeof(_outputFormat);
err = AudioFormatGetProperty(kAudioFormatProperty_FormatInfo, 0, NULL, &size, &_outputFormat);
XThrowIfError (err, "AudioFormatGetProperty kAudioFormatProperty_FormatInfo");
}
}


// create the output file
UInt32 flags = _allowsOverwrite ?kAudioFileFlags_EraseFile :0;
err = ExtAudioFileCreateWithURL ((CFURLRef)_outputURL, _outputFileType, &_outputFormat, NULL, flags, &outfile);
XThrowIfError (err, "ExtAudioFileCreateNew");


// get and set the client format - it should be lpcm
AudioStreamBasicDescription clientFormat;
if( inputFormat.mFormatID == kAudioFormatLinearPCM )
clientFormat = inputFormat;
else if( inputFormat.mFormatID == kAudioFormatLinearPCM )
clientFormat = _outputFormat;
else {
// Compressed-to-compressed conversion; make an lpcm intermediary
clientFormat = inputFormat;
clientFormat.mFormatID = kAudioFormatLinearPCM;
clientFormat.mFormatFlags = kAudioFormatFlagsCanonical;
clientFormat.mBitsPerChannel = 8 * sizeof(AudioSampleType);
clientFormat.mFramesPerPacket = 1;
clientFormat.mBytesPerFrame = inputFormat.mChannelsPerFrame * sizeof(AudioSampleType);
clientFormat.mBytesPerPacket = clientFormat.mBytesPerFrame;
}


size = sizeof(clientFormat);
err = ExtAudioFileSetProperty(infile, kExtAudioFileProperty_ClientDataFormat, size, &clientFormat);
XThrowIfError (err, "ExtAudioFileSetProperty inFile, kExtAudioFileProperty_ClientDataFormat");


size = sizeof(clientFormat);
err = ExtAudioFileSetProperty(outfile, kExtAudioFileProperty_ClientDataFormat, size, &clientFormat);
XThrowIfError (err, "ExtAudioFileSetProperty outFile, kExtAudioFileProperty_ClientDataFormat");


// set the bit-rate of the output file, if specified:
if( _outputBitRate > 0 ) {
AudioConverterRef outConverter;
size = sizeof(outConverter);
err = ExtAudioFileGetProperty(outfile, kExtAudioFileProperty_AudioConverter, &size, &outConverter);
XThrowIfError (err, "ExtAudioFileGetProperty outFile, kExtAudioFileProperty_AudioConverter");


err = AudioConverterSetProperty(outConverter, kAudioConverterEncodeBitRate,
sizeof(_outputBitRate), &_outputBitRate);
XThrowIfError (err, "AudioConverterSetProperty, kAudioConverterEncodeBitRate");


CFArrayRef config = NULL;
err = ExtAudioFileSetProperty(outfile, kExtAudioFileProperty_ConverterConfig, sizeof(config), &config);
XThrowIfError (err, "ExtAudioFileSetProperty outFile, kExtAudioFileProperty_ConverterConfig");
}


        // set up buffers
        const UInt32 kSrcBufSize = 32*1024;
        char *srcBuffer = new char[kSrcBufSize];

// do the read and write - the conversion is done on and by the write call
time = TimeIntervalSinceBoot();
int nBuffers;
for( nBuffers=0; true; nBuffers++ )
{
if( self.isCancelled )
XThrowIfError(userCanceledErr,"canceled");


AudioBufferList fillBufList;
fillBufList.mNumberBuffers = 1;
fillBufList.mBuffers[0].mNumberChannels = inputFormat.mChannelsPerFrame;
fillBufList.mBuffers[0].mDataByteSize = kSrcBufSize;
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 = (kSrcBufSize / clientFormat.mBytesPerFrame);


err = ExtAudioFileRead (infile, &numFrames, &fillBufList);
XThrowIfError (err, "ExtAudioFileRead");
if (!numFrames) {
// this is our termination condition
NSLog(@"ConvertAudioFile: EOF after %i buffers (err= %i,numFrames=%i)",nBuffers,err,numFrames);
break;
}


err = ExtAudioFileWrite/*Async*/(outfile, numFrames, &fillBufList);
XThrowIfError (err, "ExtAudioFileWrite");


            if( ! _startedWriting )
                self.startedWriting = YES;
        }
    }catch( OSStatus err ) {
        _error = err;
    }

    // close
    delete[] srcBuffer;
	if( outfile ) ExtAudioFileDispose(outfile);
	if( infile ) ExtAudioFileDispose(infile);
}

Attachment: smime.p7s
Description: S/MIME cryptographic signature

 _______________________________________________
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

  • Follow-Ups:
    • Re: Decoding compressed to LPCM
      • From: Aurélien Ammeloot <email@hidden>
References: 
 >Decoding compressed to LPCM (From: Aurélien Ammeloot <email@hidden>)
 >Re: Decoding compressed to LPCM (From: Jens Alfke <email@hidden>)
 >Re: Decoding compressed to LPCM (From: Aurélien Ammeloot <email@hidden>)

  • Prev by Date: My parameters are off in Logic
  • Next by Date: Parsing Stream Audio samples
  • Previous by thread: Re: Decoding compressed to LPCM
  • Next by thread: Re: Decoding compressed to LPCM
  • Index(es):
    • Date
    • Thread