我正在创建一个简单的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
要求它是相同的内存地址一样?那将是非常愚蠢的,但我真的不知道了。
关于导致这种情况的任何想法?关于如何以不同方式将其保存到循环缓冲区的想法?
答案 0 :(得分:2)
事实证明inPacketDescs
是array
的{{1}}。
因此,仅复制第一个值失败。
解决方案:
AudioStreamPackedDescription