• 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
AudioConverterFillComplexBuffer decoding Internet streamed mp3
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

AudioConverterFillComplexBuffer decoding Internet streamed mp3


  • Subject: AudioConverterFillComplexBuffer decoding Internet streamed mp3
  • From: yu song <email@hidden>
  • Date: Mon, 26 Nov 2012 14:20:18 -0600
  • Importance: Normal

Hi,

I am currently working on streaming mp3 audio through the Internet. I am using AudioFileStream to parse the mp3 steam 
comes through a CFReadStreamRef, decode the mp3 using AudioConverterFillComplexBuffer and copy the converted PCM 
data into a ring buffer and finally play the PCM using RemoteIO.

The problem I am currently facing is the AudioConverterFillComplexBuffer always returns 0 (no error) but the conversion 
result seems incorrect. In details, I can notice,
A. The UInt32 *ioOutputDataPacketSize keeps the same value I sent in,
B. The convertedData.mBuffers[0].mDataByteSize always been set to the size of the outputbuffer (doesn't matter how big the buffer is).
C. I can only hear clicking noise with the output data.



Below are my procedures for rendering the audio. 
The same procedure works for my Audio queue implementation so I believe 
I did something wrong in either the place I invoking the AudioConverterFillComplexBuffer or 
the callback of AudioConverterFillComplexBuffer.


I have been stuck on this issue for a long time. Any help will be highly appreciated.



1. Open a AudioFileStream.

// create an audio file stream parser
AudioFileTypeID fileTypeHint = kAudioFileMP3Type;      
AudioFileStreamOpen(self, MyPropertyListenerProc, MyPacketsProc, fileTypeHint, &audioFileStream);          



2. Handle the parsed data in the callback function ("MyPacketsProc").


void MyPacketsProc(void * inClientData,
                   UInt32 inNumberBytes,
                   UInt32 inNumberPackets,
                   const void * inInputData,
                   AudioStreamPacketDescription *inPacketDescriptions)
{
@synchronized(self)
{
        // Init the audio converter.
        if (!audioConverter)
            AudioConverterNew(&asbd, &asbd_out, &audioConverter);
        
        
        struct mp3Data mSettings;
        memset(&mSettings, 0, sizeof(mSettings));
        
        
        UInt32 packetsPerBuffer = 0;
        UInt32 outputBufferSize = 1024 * 32; // 32 KB is a good starting point.
        UInt32 sizePerPacket = asbd.mBytesPerPacket;
        
        
        // Calculate the size per buffer.
        // Variable Bit Rate Data.
        if (sizePerPacket == 0)
        {
            UInt32 size = sizeof(sizePerPacket);
            AudioConverterGetProperty(audioConverter, kAudioConverterPropertyMaximumOutputPacketSize, &size, &sizePerPacket);
            
            if (sizePerPacket > outputBufferSize)
                outputBufferSize = sizePerPacket;
           
            packetsPerBuffer = outputBufferSize / sizePerPacket;
        }
        //CBR
        else
            packetsPerBuffer = outputBufferSize / sizePerPacket;

        
        
        
        mSettings.inputBuffer.mDataByteSize = inNumberBytes;
        mSettings.inputBuffer.mData = (void *)inInputData;
        mSettings.inputBuffer.mNumberChannels = 1;
        mSettings.numberPackets = inNumberPackets;
        mSettings.packetDescription = inPacketDescriptions;
        
        
        // Set up our output buffers
        UInt8 * outputBuffer = (UInt8*)malloc(sizeof(UInt8) * outputBufferSize);
        memset(outputBuffer, 0, outputBufferSize);
        
        
        // describe output data buffers into which we can receive data.
        AudioBufferList convertedData;
        convertedData.mNumberBuffers = 1;
        convertedData.mBuffers[0].mNumberChannels = 1;
        convertedData.mBuffers[0].mDataByteSize = outputBufferSize;
        convertedData.mBuffers[0].mData = outputBuffer;
        
        
        UInt32 ioOutputDataPackets = packetsPerBuffer;
        OSStatus result = AudioConverterFillComplexBuffer(audioConverter,                
                                                          converterComplexInputDataProc, 
                                                          &mSettings,                          
                                                          &ioOutputDataPackets,          
                                                          &convertedData,            
                                                          NULL                 
                                                          );
        
        // Enqueue the ouput pcm data.
        TPCircularBufferProduceBytes(&m_pcmBuffer, convertedData.mBuffers[0].mData, convertedData.mBuffers[0].mDataByteSize);
        free(outputBuffer);
    }
}

3. Feed the audio converter from its callback function ("converterComplexInputDataProc").

OSStatus converterComplexInputDataProc(AudioConverterRef inAudioConverter,
                                       UInt32* ioNumberDataPackets,
                                       AudioBufferList* ioData,
                                       AudioStreamPacketDescription** ioDataPacketDescription,
                                       void* inUserData)
{
    struct mp3Data *THIS = (struct mp3Data*) inUserData;
    
    if (THIS->inputBuffer.mDataByteSize > 0)
    {
        *ioNumberDataPackets = THIS->numberPackets;
        ioData->mNumberBuffers = 1;
        ioData->mBuffers[0].mDataByteSize = THIS->inputBuffer.mDataByteSize;
        ioData->mBuffers[0].mData = THIS->inputBuffer.mData;
        ioData->mBuffers[0].mNumberChannels = 1;
        
        if (ioDataPacketDescription)
            *ioDataPacketDescription = THIS->packetDescription;
    }
    else
        *ioDataPacketDescription = 0;
    
    return 0;
}


4. Playback using the RemoteIO component.


5. The input and output AudioStreamBasicDescription.

Input:
2012-11-21 12:12:32.197 BAM_IOS[48999:4b03]   Sample Rate:              16000
2012-11-21 12:12:32.197 BAM_IOS[48999:4b03]   Format ID:                 .mp3
2012-11-21 12:12:32.198 BAM_IOS[48999:4b03]   Format Flags:                 0
2012-11-21 12:12:32.198 BAM_IOS[48999:4b03]   Bytes per Packet:             0
2012-11-21 12:12:32.199 BAM_IOS[48999:4b03]   Frames per Packet:          576
2012-11-21 12:12:32.199 BAM_IOS[48999:4b03]   Bytes per Frame:              0
2012-11-21 12:12:32.199 BAM_IOS[48999:4b03]   Channels per Frame:           1
2012-11-21 12:12:32.200 BAM_IOS[48999:4b03]   Bits per Channel:             0

output:
2012-11-21 12:12:32.200 BAM_IOS[48999:4b03]   Sample Rate:              44100
2012-11-21 12:12:32.200 BAM_IOS[48999:4b03]   Format ID:                 lpcm
2012-11-21 12:12:32.201 BAM_IOS[48999:4b03]   Format Flags:              3116
2012-11-21 12:12:32.201 BAM_IOS[48999:4b03]   Bytes per Packet:             4
2012-11-21 12:12:32.202 BAM_IOS[48999:4b03]   Frames per Packet:            1
2012-11-21 12:12:32.202 BAM_IOS[48999:4b03]   Bytes per Frame:              4
2012-11-21 12:12:32.205 BAM_IOS[48999:4b03]   Channels per Frame:           1
2012-11-21 12:12:32.205 BAM_IOS[48999:4b03]   Bits per Channel:            32

 _______________________________________________
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: AUNewTimePitch distorted on iOS device but fine in simulator
  • Next by Date: Re: AUNewTimePitch distorted on iOS device but fine in simulator
  • Previous by thread: Re: AUNewTimePitch distorted on iOS device but fine in simulator
  • Next by thread: AU SDK for XCode 3.2.6
  • Index(es):
    • Date
    • Thread