IOS中重复音频的损坏录音
Posted
技术标签:
【中文标题】IOS中重复音频的损坏录音【英文标题】:Corrupt recording with repeating audio in IOS 【发布时间】:2014-07-31 14:31:33 【问题描述】:我的应用程序在 iPhone 上录制流式音频。我的问题是一小部分(~2%)的录音被破坏了。他们似乎有一些重复的音频缓冲区。
例如收听this file。
编辑:令人惊讶的是,使用 Audacity 仔细查看数据会发现重复部分非常相似但并不完全相同。由于 FLAC(我用于编码音频的格式)是一种无损压缩,我想这不是流/编码中的错误,而是问题源于来自麦克风的数据!
下面是我用来设置音频录制流的代码 - 有什么问题吗?
// see functions implementation below
- (void)startRecording
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
, ^
[self setUpRecordQueue];
[self setUpRecordQueueBuffers];
[self primeRecordQueueBuffers];
AudioQueueStart(recordQueue, NULL);
);
// this is called only once before any recording takes place
- (void)setUpAudioFormat
AudiosessionInitialize(
NULL,
NULL,
nil,
(__bridge void *)(self)
);
UInt32 sessionCategory = kAudioSessionCategory_PlayAndRecord;
AudioSessionSetProperty(
kAudioSessionProperty_AudioCategory,
sizeof(sessionCategory),
&sessionCategory
);
AudioSessionSetActive(true);
audioFormat.mFormatID = kAudioFormatLinearPCM;
audioFormat.mSampleRate = SAMPLE_RATE;//16000.0;
audioFormat.mChannelsPerFrame = CHANNELS;//1;
audioFormat.mBitsPerChannel = 16;
audioFormat.mFramesPerPacket = 1;
audioFormat.mBytesPerFrame = audioFormat.mChannelsPerFrame * sizeof(SInt16);
audioFormat.mBytesPerPacket = audioFormat.mBytesPerFrame * audioFormat.mFramesPerPacket;
audioFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
bufferNumPackets = 2048; // must be power of 2 for FFT!
bufferByteSize = [self byteSizeForNumPackets:bufferNumPackets];
// I suspect the duplicate buffers arrive here:
static void recordCallback(
void* inUserData,
AudioQueueRef inAudioQueue,
AudioQueueBufferRef inBuffer,
const AudioTimeStamp* inStartTime,
UInt32 inNumPackets,
const AudioStreamPacketDescription* inPacketDesc)
Recorder* recorder = (__bridge Recorder*) inUserData;
if (inNumPackets > 0)
// append the buffer to FLAC encoder
[recorder recordedBuffer:inBuffer->mAudioData byteSize:inBuffer->mAudioDataByteSize packetsNum:inNumPackets];
AudioQueueEnqueueBuffer(inAudioQueue, inBuffer, 0, NULL);
- (void)setUpRecordQueue
OSStatus errorStatus = AudioQueueNewInput(
&audioFormat,
recordCallback,
(__bridge void *)(self), // userData
CFRunLoopGetMain(), // run loop
NULL, // run loop mode
0, // flags
&recordQueue);
UInt32 trueValue = true;
AudioQueueSetProperty(recordQueue,kAudioQueueProperty_EnableLevelMetering,&trueValue,sizeof (UInt32));
- (void)setUpRecordQueueBuffers
for (int t = 0; t < NUMBER_AUDIO_DATA_BUFFERS; ++t)
OSStatus errorStatus = AudioQueueAllocateBuffer(
recordQueue,
bufferByteSize,
&recordQueueBuffers[t]);
- (void)primeRecordQueueBuffers
for (int t = 0; t < NUMBER_AUDIO_DATA_BUFFERS; ++t)
OSStatus errorStatus = AudioQueueEnqueueBuffer(
recordQueue,
recordQueueBuffers[t],
0,
NULL);
【问题讨论】:
【参考方案1】:原来有一个罕见的错误允许多个录音几乎同时开始 - 所以两个录音并行发生,但将音频缓冲区发送到同一个回调,使编码录音中的重复缓冲区失真......
【讨论】:
以上是关于IOS中重复音频的损坏录音的主要内容,如果未能解决你的问题,请参考以下文章