0

我正在编写一个 iPhone 应用程序,它从互联网下载音频文件并可以在下载时播放它们(如果网络缓冲区为空,则播放白噪声),所以,我认为,我不能只使用 AVAudioPlayer,应该自己填充音频缓冲区. 文件在 MP3 中,它们应该是硬件解码的。我的第一次尝试是 AudioUnit:

AudioStreamBasicDescription audioFormat;
bzero(&audioFormat, sizeof(AudioStreamBasicDescription));
audioFormat.mSampleRate = 44100;
audioFormat.mChannelsPerFrame = 2;
audioFormat.mFormatID = kAudioFormatMPEGLayer3;
audioFormat.mFramesPerPacket = 1152;

然后用 MP3 数据包填充缓冲区,但这不起作用,因为远程 IO 不适用于压缩流,所以我决定深入研究音频队列:

static void HandleOutputBuffer (
    void                *aqData,
    AudioQueueRef       inAQ,
    AudioQueueBufferRef inBuffer
) {
    AQPlayerState *pAqData = (AQPlayerState *) aqData;        // 1
    if (pAqData->mIsRunning == 0) return;                     // 2
    UInt32 numBytesReadFromFile;                              // 3
    UInt32 numPackets = pAqData->mNumPacketsToRead;           // 4
    AudioFileReadPackets (
        pAqData->mAudioFile,
        false,
        &numBytesReadFromFile,
        pAqData->mPacketDescs,
        pAqData->mCurrentPacket,
        &numPackets,
        inBuffer->mAudioData
    );
    if (numPackets > 0) {                                     // 5
        inBuffer->mAudioDataByteSize = numBytesReadFromFile;  // 6
        AudioQueueEnqueueBuffer (
            pAqData->mQueue,
            inBuffer,
            (pAqData->mPacketDescs ? numPackets : 0),
            pAqData->mPacketDescs
        );
        pAqData->mCurrentPacket += numPackets;                // 7
    } else {
        AudioQueueStop (
            pAqData->mQueue,
            false
        );
        pAqData->mIsRunning = false;
    }
}

问题是:会pAqData->mAudioFile以这种方式进行硬件解码吗?另一个问题是:如何将存储在 NSData 中的 mp3 数据提供给 AudioQueueEnqueueBuffer?

4

0 回答 0