Iftah
Iftah

Reputation: 9572

Distorted (robotic) audio recording on iOS using AudioQueue

I'm using AudioQueue in iOS to implement streaming of recording to the web.

The problem is that it usually works quite well, but sometimes (~20% of my attempts) the sound is horribly distorted - it sounds robotic.

Edit: I am able to reproduce it quite easily on the ios6 and ios6.1 simulator - but I wasn't able to reproduce it on a real phone (ios6.1.3).

Attempting to debug it I save the PCM data to a file. The same distortion appears in the PCM file, so this is not a problem in the encoding or upload code. I've also tried to play with the number of buffers and the size of the buffers - nothing helped.

The problem is I don't know how to debug it farther - it appears the buffer is distorted as input to the callback - before my code is activated (except for the audio queue config).

Queue setup code:

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);
}

Start recording function:

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

Callback code:

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);
}

Upvotes: 6

Views: 646

Answers (1)

OJay
OJay

Reputation: 1239

we had the exact same issue in SoundJS Web Audio on iOS whenever a video element was present and the cache was empty. Once cached, the problem went away. We were unable to find a fix or a work around for the issue.

You can read the details in our community forum:

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

Hope that helps.

Upvotes: 0

Related Questions