如何使用音频队列播放 NSData(bytes)?

发布于 2024-12-16 12:00:08 字数 2237 浏览 1 评论 0原文

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

      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 类型,请帮助...

how to play [NSData bytes] with Audio Queue Services, from speakHere example the bytes are token from the AudioFile, but i'm having sound downloaded from internet i need to play it with Queue Services. Iv've tried to the parameters like this:

      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);

the callback is working but unfortunately a cannot set the bytes in the buffer:

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;

where inCompleteAQBuffer is AudioQueueBufferRef type, please help ...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

瘫痪情歌 2024-12-23 12:00:08

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

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

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

You need to know the format of the audio contained in the NSData. Header? Uncompressed/raw PCM? How many bits? Endian-ness? How many channels? Sample rate (or filtered interpolation rate) required?

If the data is compressed, you will need to uncompress it to raw audio, or configure the Audio Queue to play the appropriate compressed format, if it's so supported.

Once you know the format, for uncompressed audio, you can cast a pointer to your NSData bytes to the proper array or array of structures C type (unsigned char, short int, pair of short ints, etc.). Then copy the requested number of samples from the array to the callback buffer. Your callback will also have to keep track of what part of this array has already been used in a previous callback (e.g. the array index) between callbacks.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文