• 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
AudioUnit PCM compression to iLBC and decompression to PCM
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

AudioUnit PCM compression to iLBC and decompression to PCM


  • Subject: AudioUnit PCM compression to iLBC and decompression to PCM
  • From: Tomasz Łoś <email@hidden>
  • Date: Wed, 10 Apr 2013 03:09:30 +0200

Hello,

 

I am developing an app that is getting PCM data from recoding device -> compress it to iLBC format -> writes it to singleton -> reads from singleton -> decompress it back to PCM and write to playback device. I believe that compression works well, tho decompression is not working properly. At first PCM buffer is 1024 bytes, after comression iLBC has 38 bytes, after attempt to decompress data buffer has 2 bytes.

 

My class for compression:

 

-(void)convertBuffer:(unsigned char**) stream size:(int *)streamSize {

    // create an audio converter

    AudioConverterRef audioConverter;

//    outputDescription = audioFormat;



    OSStatus acCreationResult = AudioConverterNew(&audioFormat, &outputDescription, &audioConverter);

    if(!audioConverter)

    {

        // bail out

        free(*stream);

        *streamSize = 0;

        *stream = (unsigned char*)malloc(0);

        return;

    }



    // calculate number of bytes required for output of input stream.

    // allocate buffer of adequate size.

//    UInt32 outputBytes = outputDescription.mBytesPerPacket * (*streamSize / audioFormat.mBytesPerPacket); // outputDescription.mFramesPerPacket * outputDescription.mBytesPerFrame;

    UInt32 size = sizeof(UInt32);

    UInt32 outputBytes;

    AudioConverterGetProperty(audioConverter, kAudioConverterPropertyMaximumOutputPacketSize, &size, &outputBytes);



    unsigned char *outputBuffer = (unsigned char*)malloc(outputBytes);

    memset(outputBuffer, 0, outputBytes);



    // describe input data we'll pass into converter

    AudioBuffer inputBuffer;

    inputBuffer.mNumberChannels = audioFormat.mChannelsPerFrame;

    inputBuffer.mDataByteSize = *streamSize;

    inputBuffer.mData = *stream;



    // describe output data buffers into which we can receive data.

    AudioBufferList outputBufferList;

    outputBufferList.mNumberBuffers = 1;

    outputBufferList.mBuffers[0].mNumberChannels = outputDescription.mChannelsPerFrame;

    outputBufferList.mBuffers[0].mDataByteSize = outputBytes;

    outputBufferList.mBuffers[0].mData = outputBuffer;



    // set output data packet size

    UInt32 outputDataPacketSize = outputBytes; // / outputDescription.mBytesPerPacket;



    // fill class members with data that we'll pass into

    // the InputDataProc

    _converter_currentBuffer = &inputBuffer;

    _converter_currentInputDescription = audioFormat;



    // convert

    OSStatus result = AudioConverterFillComplexBuffer(audioConverter, /* AudioConverterRef inAudioConverter */

                                                      _converterComplexInputDataProc, /* AudioConverterComplexInputDataProc inInputDataProc */

                                                      self, /* void *inInputDataProcUserData */

                                                      &outputDataPacketSize, /* UInt32 *ioOutputDataPacketSize */

                                                      &outputBufferList, /* AudioBufferList *outOutputData */

                                                      NULL /* AudioStreamPacketDescription *outPacketDescription */

                                                      );





    //if (err) {NSLog(@"%s : AudioFormat Convert error %d\n",__FUNCTION__, (int)err);  }

    NSLog(@"Before %d after %d", *streamSize, (unsigned int)outputBytes);

    // change "stream" to describe our output buffer.

    // even if error occured, we'd rather have silence than unconverted audio.

    free(*stream);

    *stream = outputBuffer;

    *streamSize = outputBytes;



    // dispose of the audio converter

    AudioConverterDispose(audioConverter);





    Data *data = "" sharedData];



     // copy incoming audio data to the audio buffer

    //intFromBuffer = audioBufferList->mBuffers[0].mData;



    NSMutableData *dataOut = [[NSMutableData alloc] initWithCapacity:0];

    [dataOut appendBytes:(const void *)outputBuffer length:outputBytes];



    [data setMOutput:dataOut];

}


 

Code for decompression:

 

-(void)convertBufferBack:(unsigned char**) stream size:(int *)streamSize {

    // create an audio converter

    AudioConverterRef audioConverter1;

    //    outputDescription = audioFormat;



    OSStatus acCreationResult = AudioConverterNew(&outputDescription, &audioFormat, &audioConverter1);

    if(!audioConverter1)

    {

        // bail out

        free(*stream);

        *streamSize = 0;

        *stream = (unsigned char*)malloc(0);

        return;

    }



    // calculate number of bytes required for output of input stream.

    // allocate buffer of adequate size.

//    UInt32 outputBytes = audioFormat.mFramesPerPacket * audioFormat.mBytesPerFrame;

    UInt32 size = sizeof(UInt32);

    UInt32 outputBytes;

    AudioConverterGetProperty(audioConverter1, kAudioConverterPropertyMaximumOutputPacketSize, &size, &outputBytes); //this returns 2 bytes



    unsigned char *outputBuffer = (unsigned char*)malloc(outputBytes);

    memset(outputBuffer, 0, outputBytes);



    // describe input data we'll pass into converter

    AudioBuffer inputBuffer;

    inputBuffer.mNumberChannels = outputDescription.mChannelsPerFrame;

    inputBuffer.mDataByteSize = *streamSize;

    inputBuffer.mData = *stream;



    // describe output data buffers into which we can receive data.

    AudioBufferList outputBufferList;

    outputBufferList.mNumberBuffers = 1;

    outputBufferList.mBuffers[0].mNumberChannels = audioFormat.mChannelsPerFrame;

    outputBufferList.mBuffers[0].mDataByteSize = outputBytes;

    outputBufferList.mBuffers[0].mData = outputBuffer;



    // set output data packet size

    UInt32 outputDataPacketSize = outputBytes / audioFormat.mBytesPerPacket;



    // fill class members with data that we'll pass into

    // the InputDataProc

    _converter_currentBuffer = &inputBuffer;

    _converter_currentInputDescription = outputDescription;



    // convert

    OSStatus result = AudioConverterFillComplexBuffer(audioConverter1, /* AudioConverterRef inAudioConverter */

                                                      _converterComplexInputDataProc, /* AudioConverterComplexInputDataProc inInputDataProc */

                                                      self, /* void *inInputDataProcUserData */

                                                      &outputDataPacketSize, /* UInt32 *ioOutputDataPacketSize */

                                                      &outputBufferList, /* AudioBufferList *outOutputData */

                                                      NULL /* AudioStreamPacketDescription *outPacketDescription */

                                                      );

    NSLog(@"Before %d after %d", *streamSize, (unsigned int)outputBytes);

    // change "stream" to describe our output buffer.

    // even if error occured, we'd rather have silence than unconverted audio.

    free(*stream);

    *stream = outputBuffer;

    *streamSize = outputBytes;



    // dispose of the audio converter

    AudioConverterDispose(audioConverter1);





    Data *data = "" sharedData];



     // copy incoming audio data to the audio buffer

    //intFromBuffer = audioBufferList->mBuffers[0].mData;



    NSMutableData *dataOut = [[NSMutableData alloc] initWithCapacity:0];

    [dataOut appendBytes:(const void *)outputBuffer length:outputBytes];



    [data setMOutput:dataOut];

}

 

My callback for AudioConverterFillComplexBuffer:

 

OSStatus _converterComplexInputDataProc(AudioConverterRef inAudioConverter, UInt32* ioNumberDataPackets, AudioBufferList* ioData, AudioStreamPacketDescription** ioDataPacketDescription, void* inUserData)

{   

    AudioProcessor *conv = (AudioProcessor *)inUserData;

    ioData->mNumberBuffers = 1;

    ioData->mBuffers[0] = *(conv->_converter_currentBuffer);

    if(conv->_converter_currentInputDescription.mBytesPerPacket)

        *ioNumberDataPackets = ioData->mBuffers[0].mDataByteSize / conv->_converter_currentInputDescription.mBytesPerPacket;

    else

        *ioNumberDataPackets = ioData->mBuffers[0].mDataByteSize;





    return 0;



}

 

 

And finally format descriptors:

 

memset(&audioFormat, 0, sizeof(AudioStreamBasicDescription));

     audioFormat.mSampleRate               = 44100;

     audioFormat.mFormatID               = kAudioFormatLinearPCM;

     audioFormat.mFormatFlags          = kAudioFormatFlagIsPacked | kAudioFormatFlagIsSignedInteger;

     audioFormat.mFramesPerPacket     = 1;

     audioFormat.mChannelsPerFrame     = 1;

     audioFormat.mBitsPerChannel          = 16;

     audioFormat.mBytesPerPacket          = 2;

     audioFormat.mBytesPerFrame          = 2;



    memset(&outputDescription, 0, sizeof(AudioStreamBasicDescription));

    outputDescription.mFormatID = kAudioFormatiLBC;

    outputDescription.mFormatFlags = 0;

    outputDescription.mSampleRate = 8000;

    outputDescription.mBitsPerChannel = 0;

    outputDescription.mChannelsPerFrame = 1;

    outputDescription.mBytesPerFrame = 0;

    outputDescription.mFramesPerPacket = 160;

    outputDescription.mBytesPerPacket = 38;

 

 

Please help me. I need it urgently. Test project included.
 _______________________________________________
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

  • Prev by Date: Re: Getting an AUGraph
  • Next by Date: Hide Audio device using codeless kext
  • Previous by thread: Re: Getting an AUGraph
  • Next by thread: Hide Audio device using codeless kext
  • Index(es):
    • Date
    • Thread