音频队列服务回调:AudioStreamPacketDescription 无法复制?

发布于 2024-12-25 07:20:19 字数 1747 浏览 4 评论 0原文

我正在创建一个简单的 iOS 应用程序,用循环缓冲区记录音频。这意味着它会持续记录音频,但仅将最后 15 个缓冲区保留在内存中。

我通过复制从 AudioInputCallback 获得的所有数据来完成此操作:

void AudioInputCallback(
                    void *inUserData, 
                    AudioQueueRef inAQ, 
                    AudioQueueBufferRef inBuffer, 
                    const AudioTimeStamp *inStartTime, 
                    UInt32 inNumberPacketDescriptions, 
                    const AudioStreamPacketDescription *inPacketDescs) 

这非常有效,当我将所有缓冲区保存到文件后,我可以正确记录 AIF 文件。停止录音。因此,将数据复制到其他缓冲区可以正常工作。

然而问题是,当我使用使用变量数据包的 M4A 时,相同的例程不起作用。当我将 AudioFileWritePackets 方法放入回调中时,它可以正常工作,但是当我随后在存储的缓冲数据上使用它时,它会失败。

事实证明,这是由 const AudioStreamPacketDescription *inPacketDescs 的数据引起的。当我将回调函数本身(在那里记录)中的数据更改为我的副本时,它立即失败。然而数据本身是相同的。

格式如下:

struct AudioStreamPacketDescription {
   SInt64  mStartOffset;
   UInt32  mVariableFramesInPacket;
   UInt32  mDataByteSize;
};
typedef struct AudioStreamPacketDescription AudioStreamPacketDescription;

我使用以下方法在代码中创建一个副本:

item.inPacketDescs = (AudioStreamPacketDescription *)(malloc(sizeof(AudioStreamPacketDescription)));

    item.inPacketDescs->mDataByteSize = inPacketDescs->mDataByteSize;
    item.inPacketDescs->mStartOffset = inPacketDescs->mStartOffset;
    item.inPacketDescs->mVariableFramesInPacket = inPacketDescs->mVariableFramesInPacket;

但是,当使用 item.inPacketDescs 而不是 inPacketDescs 时,它会立即失败。而此时这三个字段的数据是相同的。 (我使用调试器检查过)。

我现在有点别无选择。我看到提供的变量是 const,所以我担心这有一些有意义的目的,比如 AudioFileWritePackets 要求它是相同的内存地址等等?那将是非常愚蠢的,但我真的不知道了。

关于造成这种情况的原因有什么想法吗?关于如何将其以不同方式保存到循环缓冲区的想法?

I am creating a simple iOS app that records audio with a circular buffer. This means that it continually records audio, but only keeps the last 15 buffers in memory.

I do this by copying all the data I get from the AudioInputCallback:

void AudioInputCallback(
                    void *inUserData, 
                    AudioQueueRef inAQ, 
                    AudioQueueBufferRef inBuffer, 
                    const AudioTimeStamp *inStartTime, 
                    UInt32 inNumberPacketDescriptions, 
                    const AudioStreamPacketDescription *inPacketDescs) 

This works great and I can record an AIF file correctly when I save all my buffers to a file after I stop recording. So, the copying of the data to other buffers works correctly.

Problem however is that when I use M4A that uses variable packets, that same routine does not work. When I put the AudioFileWritePackets method in the callback it works correctly, but when I use it afterwards on the stored buffered data, it fails.

It turns out that this is caused by the data of const AudioStreamPacketDescription *inPacketDescs When I change that in the callback function itself (recording there) to my copy it fails immediately. However the data itself is identical.

This is the format:

struct AudioStreamPacketDescription {
   SInt64  mStartOffset;
   UInt32  mVariableFramesInPacket;
   UInt32  mDataByteSize;
};
typedef struct AudioStreamPacketDescription AudioStreamPacketDescription;

I create a copy in my code using the following method:

item.inPacketDescs = (AudioStreamPacketDescription *)(malloc(sizeof(AudioStreamPacketDescription)));

    item.inPacketDescs->mDataByteSize = inPacketDescs->mDataByteSize;
    item.inPacketDescs->mStartOffset = inPacketDescs->mStartOffset;
    item.inPacketDescs->mVariableFramesInPacket = inPacketDescs->mVariableFramesInPacket;

However, when then using the item.inPacketDescs instead of the inPacketDescs makes it fail immediately. And this while the data of these three fields is identical. (I checked using debugger).

I am a bit out of options now. I see that the supplied variable is const, so I am afraid that this has some meaningfull purpose, like that the AudioFileWritePackets requires it to be the same memory address or so? That would be amazingly stupid, but I don't really know anymore.

Any ideas on what is causing this? Ideas on how to save it differently to a circular buffer?

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

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

发布评论

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

评论(1

温馨耳语 2025-01-01 07:20:19

事实证明,inPacketDescsAudioStreamPackedDescription数组
因此,仅复制第一个值失败。

解决方案:

AudioStreamPacketDescription * test = (AudioStreamPacketDescription *)(malloc(inNumberPacketDescriptions * sizeof(AudioStreamPacketDescription)));
    memcpy(test, inPacketDescs, inNumberPacketDescriptions * sizeof(AudioStreamPacketDescription));

It turns out that inPacketDescs is a array of AudioStreamPackedDescription.
Therefore copying only the first value was failing.

Solution:

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