我正在编写一个 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?