gpt4 book ai didi

ios - 将 AudioBufferList 转换为 CMSampleBuffer 会产生意外结果

转载 作者:可可西里 更新时间:2023-11-01 06:05:41 25 4
gpt4 key购买 nike

我正在尝试将从音频单元获取的 AudioBufferList 转换为可以传递给 AVAssetWriterCMSampleBuffer保存来自麦克风的音频。此转换有效,因为我为执行转换所做的调用不会失败,但记录最终会失败,而且我在日志中看到一些输出似乎值得关注。

我使用的代码如下所示:

- (void)handleAudioSamples:(AudioBufferList*)samples numSamples:(UInt32)numSamples hostTime:(UInt64)hostTime {
// Create a CMSampleBufferRef from the list of samples, which we'll own
AudioStreamBasicDescription monoStreamFormat;
memset(&monoStreamFormat, 0, sizeof(monoStreamFormat));
monoStreamFormat.mSampleRate = 48000;
monoStreamFormat.mFormatID = kAudioFormatLinearPCM;
monoStreamFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked | kAudioFormatFlagIsNonInterleaved;
monoStreamFormat.mBytesPerPacket = 2;
monoStreamFormat.mFramesPerPacket = 1;
monoStreamFormat.mBytesPerFrame = 2;
monoStreamFormat.mChannelsPerFrame = 1;
monoStreamFormat.mBitsPerChannel = 16;

CMFormatDescriptionRef format = NULL;
OSStatus status = CMAudioFormatDescriptionCreate(kCFAllocatorDefault, &monoStreamFormat, 0, NULL, 0, NULL, NULL, &format);
if (status != noErr) {
// really shouldn't happen
return;
}

CMSampleTimingInfo timing = { CMTimeMake(1, 48000), kCMTimeZero, kCMTimeInvalid };

CMSampleBufferRef sampleBuffer = NULL;
status = CMSampleBufferCreate(kCFAllocatorDefault, NULL, false, NULL, NULL, format, numSamples, 1, &timing, 0, NULL, &sampleBuffer);
if (status != noErr) {
// couldn't create the sample buffer
PTKLogError(@"Failed to create sample buffer");
CFRelease(format);
return;
}

// add the samples to the buffer
status = CMSampleBufferSetDataBufferFromAudioBufferList(sampleBuffer,
kCFAllocatorDefault,
kCFAllocatorDefault,
0,
samples);
if (status != noErr) {
PTKLogError(@"Failed to add samples to sample buffer");
CFRelease(sampleBuffer);
CFRelease(format);
return;
}

NSLog(@"Original sample buf size: %ld for %d samples from %d buffers, first buffer has size %d", CMSampleBufferGetTotalSampleSize(sampleBuffer), numSamples, samples->mNumberBuffers, samples->mBuffers[0].mDataByteSize);
NSLog(@"Original sample buf has %ld samples", CMSampleBufferGetNumSamples(sampleBuffer));

正如我所提到的,代码本身似乎并没有失败,但是 AVAssetWriter 不喜欢它,而且我正在创建的 CMSampleBuffer基于记录以下日志条目的事实,大小似乎为 0:

2015-07-09 19:34:00.710 xxxx[1481:271334] Original sample buf size: 0 for 1024 samples from 1 buffers, first buffer has size 2048
2015-07-09 19:34:00.710 xxxx[1481:271334] Original sample buf has 1024 samples

奇怪的是,样本缓冲区报告它有 1024 个样本,但大小为 0。原始 AudioBufferList 有 2048 字节的数据,这是我对 1024 个 2 字节样本的预期。

我在初始化和填充 CMSampleBuffer 方面做错了什么吗?

最佳答案

事实证明,样本量恢复为 0 的事实是转移注意力。一旦我清理了一些东西——值得注意的是,我正确地设置了时间戳,如下所示:

uint64_t timeNS = (uint64_t)(hostTime * _hostTimeToNSFactor);
CMTime presentationTime = CMTimeMake(timeNS, 1000000000);
CMSampleTimingInfo timing = { CMTimeMake(1, 48000), presentationTime, kCMTimeInvalid };

录音开始工作。

因此,如果其他人被报告的 0 样本缓冲区大小所困扰,请注意这是可以的,至少在您将数据输入 AVAssetWriter .

关于ios - 将 AudioBufferList 转换为 CMSampleBuffer 会产生意外结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31331720/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com