IOS中重复音频的录制已损坏

IOS中重复音频的录制已损坏,ios,iphone,audio,audio-streaming,audio-recording,Ios,Iphone,Audio,Audio Streaming,Audio Recording,我的应用程序在iPhone上录制流媒体音频。我的问题是,一小部分(约2%)的录音被破坏。它们似乎复制了一些音频缓冲区 比如听 编辑:令人惊讶的是,使用Audacity仔细查看数据,发现重复部分非常相似,但并不完全相同。由于FLAC(我用于音频编码的格式)是一种无损耗压缩,我想这不是流/编码中的错误,但问题源于来自麦克风的数据 下面是我用来设置音频录制流的代码-有什么问题吗 // see functions implementation below - (void)startRecording

我的应用程序在iPhone上录制流媒体音频。我的问题是,一小部分(约2%)的录音被破坏。它们似乎复制了一些音频缓冲区

比如听


编辑:令人惊讶的是,使用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);
    }
}
//参见下面的函数实现
-(无效)开始记录
{
调度异步(调度获取全局队列(调度队列优先级默认为0)
, ^{
[自设置记录队列];
[自设置记录队列缓冲区];
[自启动记录队列缓冲区];
AudioQueueStart(recordQueue,NULL);
});
}
//在进行任何录制之前只调用一次
-(无效)设置音频格式
{
听力会话初始化(
无效的
无效的
无
(桥空*)(自)
);
UInt32会话类别=kAudioSessionCategory_Play和Record;
AudioSessionSetProperty(
kAudioSessionProperty_AudioCategory,
sizeof(会话类别),
&会话分类
);
AudioSessionSetActive(正确);
audioFormat.mFormatID=kAudioFormatLinearPCM;
audioFormat.mSampleRate=采样率;//16000.0;
audioFormat.mChannelsPerFrame=通道;//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;//FFT必须是2的幂!
bufferByteSize=[self byteSizeForNumPackets:bufferNumPackets];
}
//我怀疑重复缓冲区到达这里:
静态无效记录回调(
void*inUserData,
AudioQueueRef inAudioQueue,
AudioQueueBufferRef inBuffer,
const AudioTimeStamp*inStartTime,
UInt32 inNumPackets,
const AudioStreamPacketDescription*inPacketDesc)
{
记录器*记录器=(u_桥记录器*)内部数据;
如果(inNumPackets>0)
{
//将缓冲区附加到FLAC编码器
[记录器记录缓冲区:inBuffer->mAudioData byteSize:inBuffer->mAudioData byteSize打包:inNumPackets];
}
AudioQueuenQueueBuffer(InudioQueue,inBuffer,0,NULL);
}
-(void)setUpRecordQueue
{
OSStatus errorStatus=音频队列新输入(
&音频格式,
记录回调,
(_桥空*)(self),//userData
CFRunLoopGetMain(),//运行循环
NULL,//运行循环模式
0,//标志
&记录队列);
UInt32 trueValue=true;
AudioQueueSetProperty(recordQueue、kAudioQueueProperty_EnableLevelMetering和trueValue、sizeof(UInt32));
}
-(无效)setUpRecordQueueBuffers
{
对于(int t=0;t
原来有一个罕见的错误,允许多个录音几乎同时开始-因此两个录音并行进行,但将音频缓冲区发送到同一个回调,使编码录音中的重复缓冲区失真