使用 AudioQueue 在 iOS 上进行失真(机器人)音频录制

Posted

技术标签:

【中文标题】使用 AudioQueue 在 iOS 上进行失真(机器人)音频录制【英文标题】:Distorted (robotic) audio recording on iOS using AudioQueue 【发布时间】:2013-10-08 13:11:03 【问题描述】:

我在 ios 中使用AudioQueue 来实现将录制流式传输到网络。

问题在于它通常效果很好,但有时(大约 20% 的尝试)声音会严重失真 - 听起来很机器人。

编辑: 我可以在 ios6 和 ios6.1 模拟器上轻松重现它 - 但我无法在真实手机 (ios6.1.3) 上重现它。

尝试调试它我将 PCM 数据保存到一个文件中。同样的失真出现在 PCM 文件中,所以这不是编码或上传代码的问题。我也尝试过使用缓冲区的数量和缓冲区的大小 - 没有任何帮助。

问题是我不知道如何进一步调试它 - 在我的代码被激活之前(音频队列配置除外),缓冲区似乎作为回调的输入被扭曲了。

您知道可能是什么问题吗? 或者如何进一步调试?

队列设置代码:

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;

AudioQueueNewInput(
    &audioFormat,
    recordCallback,
    self,                // userData
    CFRunLoopGetMain(),  // run loop
    NULL,                // run loop mode
    0,                   // flags
    &recordQueue);

UInt32 trueValue = true;
  AudioQueueSetProperty(recordQueue,kAudioQueueProperty_EnableLevelMetering,&trueValue,sizeof (UInt32));

for (int t = 0; t < NUMBER_AUDIO_DATA_BUFFERS; ++t)

    AudioQueueAllocateBuffer(
        recordQueue,
        bufferByteSize,
        &recordQueueBuffers[t]);


for (int t = 0; t < NUMBER_AUDIO_DATA_BUFFERS; ++t)

    AudioQueueEnqueueBuffer(
        recordQueue,
        recordQueueBuffers[t],
        0,
        NULL);

开始录音功能:

pcmFile = [[NSOutputStream alloc] initToFileAtPath:pcmFilePath append:YES];
[pcmFile scheduleInRunLoop:[NSRunLoop currentRunLoop]
                       forMode:NSDefaultRunLoopMode];
[pcmFile open];
setupQueue(); // see above
AudioQueueStart(recordQueue, NULL);

回调代码:

static void recordCallback(
    void* inUserData,
    AudioQueueRef inAudioQueue,
    AudioQueueBufferRef inBuffer,
    const AudioTimeStamp* inStartTime,
    UInt32 inNumPackets,
    const AudioStreamPacketDescription* inPacketDesc)

    Recorder* recorder = (Recorder*) inUserData;
    if (!recorder.recording)
        return;
    [recorder.pcmFile write:inBuffer->mAudioData maxLength:inBuffer->mAudioDataByteSize];
    AudioQueueEnqueueBuffer(inAudioQueue, inBuffer, 0, NULL);

【问题讨论】:

【参考方案1】:

每当存在视频元素并且缓存为空时,我们在 iOS 上的 SoundJS Web Audio 中遇到了完全相同的问题。一旦缓存,问题就消失了。我们无法找到解决此问题的方法或解决方法。

您可以在我们的社区论坛中阅读详细信息:

http://community.createjs.com/discussions/soundjs/162-ios-audio-distortion-when-video-element-exists

希望对您有所帮助。

【讨论】:

以上是关于使用 AudioQueue 在 iOS 上进行失真(机器人)音频录制的主要内容,如果未能解决你的问题,请参考以下文章

如何降低 iphone 的 sdk Audioqueue 的声音?

iOS:使用 AudioQueue 时快进音频

如何从 iOS 上的 AudioQueue 服务获取样本

带有三次插值的正弦图像失真

iOS AudioQueue播放AAC数据总是延迟2-3秒

ios音频:使用audioqueue改变播放进度