1

如何使用音频队列服务播放 [NSData 字节],从 speakHere 示例中,字节是来自 AudioFile 的令牌,但我从互联网下载了声音,我需要使用队列服务播放它。我试过这样的参数:

      memset(&mDataFormat, 0, sizeof(mDataFormat));
audioData = [[NSData alloc]initWithContentsOfFile:[[NSBundle mainBundle]pathForResource:@"1" ofType:@"mp3"]];
    UInt32 size = sizeof(mDataFormat.mSampleRate);
    XThrowIfError(AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareSampleRate, &size,&mDataFormat.mSampleRate), "couldn't get hardware sample rate");
    size = sizeof(mDataFormat.mChannelsPerFrame);
    XThrowIfError(AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareInputNumberChannels,&size,&mDataFormat.mChannelsPerFrame), "couldn't get input channel count");
    mDataFormat.mFormatID = kAudioFormatLinearPCM;
    if (mDataFormat.mFormatID == kAudioFormatLinearPCM)
    {
        mDataFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
        mDataFormat.mBitsPerChannel = 8;
        mDataFormat.mBytesPerPacket = mDataFormat.mBytesPerFrame = (mDataFormat.mBitsPerChannel / 8) * mDataFormat.mChannelsPerFrame;
        mDataFormat.mFramesPerPacket = 1;
    }



AudioQueueNewOutput(&mDataFormat, AQPlayer::AQBufferCallback, this, CFRunLoopGetCurrent(), kCFRunLoopCommonModes, 0, &mQueue);
UInt32 maxPacketSize;
UInt32 _size = sizeof(maxPacketSize);
AudioFileGetProperty(mAudioFile, kAudioFilePropertyPacketSizeUpperBound, &_size, &maxPacketSize);
UInt32 bufferByteSize = (UInt32)[audioData length];
CalculateBytesForTime (mDataFormat, maxPacketSize, kBufferDurationSeconds, &bufferByteSize, &mNumPacketsToRead);
AudioQueueSetParameter(mQueue, kAudioQueueParam_Volume, 1.0);

回调正在工作,但不幸的是无法设置缓冲区中的字节:

if (nPackets > 0) 
{
    inCompleteAQBuffer->mAudioDataByteSize = numBytes;      
    inCompleteAQBuffer->mPacketDescriptionCount = nPackets; 

  for (int i = 0; i < inCompleteAQBuffer->mAudioDataByteSize; i++)
   {
        char * cash = (void *)[THIS->audioData bytes];

       // inCompleteAQBuffer->mUserData[i] = cash[i];

   }

    //inCompleteAQBuffer->mUserData = data;

其中 inCompleteAQBuffer 是 AudioQueueBufferRef 类型,请帮助...

4

1 回答 1

1

您需要知道 NSData 中包含的音频的格式。标题?未压缩/原始 PCM?多少位?字节序?有多少频道?需要采样率(或滤波插值率)?

如果数据被压缩,您需要将其解压缩为原始音频,或配置音频队列以播放适当的压缩格式(如果支持)。

一旦您知道格式,对于未压缩的音频,您可以将指向您的 NSData 字节的指针转换为正确的数组或结构数组 C 类型(无符号字符、短整数、短整数对等)。然后将请求数量的样本从数组复制到回调缓冲区。您的回调还必须跟踪该数组的哪一部分已在回调之间的先前回调(例如数组索引)中使用。

于 2011-11-17T00:54:52.503 回答