AudioConverterFillComplexBuffer使用Internet流式mp3

时间:2012-11-26 20:14:42

标签: ios mp3 converter

我目前正在通过互联网传输mp3音频。我正在使用AudioFileStream来解析mp3 steam 来自CFReadStreamRef,使用AudioConverterFillComplexBuffer解码mp3并复制转换后的PCM 将数据放入环形缓冲区,最后使用RemoteIO播放PCM。

我目前面临的问题是AudioConverterFillComplexBuffer始终返回0(无错误)但转换 结果似乎不正确。详情请注意,

一个。 UInt32 * ioOutputDataPacketSize保持与我发送的值相同。

B中。 convertedData.mBuffers [0] .mDataByteSize总是被设置为outputbuffer的大小(无论缓冲区有多大)。

℃。我只能通过输出数据听到咔嗒声。

以下是我渲染音频的程序。 我相信,同样的程序适用于我的音频队列实现 在我调用AudioConverterFillComplexBuffer或AudioConverterFillComplexBuffer的回调的地方,我没有出错。

我长期以来一直坚持这个问题。任何帮助将受到高度赞赏。

  1. 打开AudioFileStream。

    //创建一个音频文件流解析器 AudioFileTypeID fileTypeHint = kAudioFileMP3Type;
    AudioFileStreamOpen(self,MyPropertyListenerProc,MyPacketsProc,fileTypeHint,& audioFileStream);

  2. 处理回调函数中的已解析数据(“MyPacketsProc”)。

    void MyPacketsProc(void * inClientData,                    UInt32 inNumberBytes,                    UInt32 inNumberPackets,                    const void * inInputData,                    AudioStreamPacketDescription * inPacketDescriptions) { @synchronized(个体经营)     {         //初始化音频转换器。         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;
    
    
    
        // Prepare the input data for the callback.
        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;
    
        // Convert.
        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. 从其回调函数(“converterComplexInputDataProc”)中提供音频转换器。

  4. 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;
    

    }

    1. 使用RemoteIO组件播放。

    2. 输入和输出AudioStreamBasicDescription。

    3. 输入:

      采样率:16000 格式ID:.mp3

      格式标志:0

      每个数据包的字节数:0

      每个数据包的帧数:576

      每帧字节数:0

      每帧频道数:1

      每通道位数:0

      输出:

      采样率:44100

      格式ID:lpcm

      格式标志:3116

      每个数据包的字节数:4

      每个数据包的帧数:1

      每帧字节数:4

      每帧频道数:1

      每通道位数:32

0 个答案:

没有答案