iosiocore-audionoiseaudiobuffer

Remote IO audio is very noisy


I am new to core audio and remote io. I need data of size 320 bytes which I encode and send. Also a minimum of 50 frames per second. Here is what I have done:

    AudioComponentDescription desc;

    desc.componentType = kAudioUnitType_Output;
    desc.componentSubType = kAudioUnitSubType_RemoteIO;
    desc.componentFlags = 0;
    desc.componentFlagsMask = 0;
    desc.componentManufacturer = 0;


    // Get component
    AudioComponent inputComponent = AudioComponentFindNext(NULL, &desc);

    // Get audio units
    AudioComponentInstanceNew(inputComponent, &audioUnit);

    // Enable IO for recording
    UInt32 flag = 1;                   AudioUnitSetProperty(audioUnit,  kAudioOutputUnitProperty_EnableIO,  kAudioUnitScope_Input,   kInputBus,  &flag,   sizeof(flag));

    // Enable IO for playback     AudioUnitSetProperty(audioUnit,  kAudioOutputUnitProperty_EnableIO,   kAudioUnitScope_Output,   kOutputBus, &flag,   sizeof(flag));

     UInt32 shouldAllocateBuffer = 1;
     AudioUnitSetProperty(audioUnit, kAudioUnitProperty_ShouldAllocateBuffer,      kAudioUnitScope_Global, 1, &shouldAllocateBuffer, sizeof(shouldAllocateBuffer));

    // Describe format
    audioFormat.mSampleRate = 8000.00;
    audioFormat.mFormatID = kAudioFormatLinearPCM;
    audioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger|kAudioFormatFlagIsPacked;
    audioFormat.mFramesPerPacket = 1;
    audioFormat.mChannelsPerFrame = 1;
    audioFormat.mBitsPerChannel = 16;
    audioFormat.mBytesPerPacket = 2;
    audioFormat.mBytesPerFrame = 2;


    // Apply format   AudioUnitSetProperty(audioUnit,  kAudioUnitProperty_StreamFormat,  kAudioUnitScope_Output, 1,   &audioFormat,  sizeof(audioFormat));

      AudioUnitSetProperty(audioUnit,  kAudioUnitProperty_StreamFormat,  kAudioUnitScope_Input,  0,  &audioFormat,  sizeof(audioFormat));

    // Set input callback
    AURenderCallbackStruct callbackStruct;
    callbackStruct.inputProc = recordingCallback;
    callbackStruct.inputProcRefCon = self;
        AudioUnitSetProperty(audioUnit,   kAudioOutputUnitProperty_SetInputCallback,   kAudioUnitScope_Global,   1,   &callbackStruct,   sizeof(callbackStruct));



    // Set output callback
    callbackStruct.inputProc = playbackCallback;
    callbackStruct.inputProcRefCon = self;
      AudioUnitSetProperty(audioUnit, kAudioUnitProperty_SetRenderCallback,  kAudioUnitScope_Global,   0, &callbackStruct,  sizeof(callbackStruct));


    // Initialise
    AudioUnitInitialize(audioUnit);

    AudioOutputUnitStart(audioUnit);

With this settings, i get 186 frames in the callback method when tried with device. I have allocated by buffer:

    bufferList = (AudioBufferList*) malloc(sizeof(AudioBufferList));
    bufferList->mNumberBuffers = 1; //mono input
    for(UInt32 i=0;i<bufferList->mNumberBuffers;i++)
    {
          bufferList->mBuffers[i].mNumberChannels = 1;
          bufferList->mBuffers[i].mDataByteSize = 2*186;
          bufferList->mBuffers[i].mData = malloc(bufferList->mBuffers[i].mDataByteSize);
    } 

From this 372(2 x 186)  bytes in the callback, i took 320 byte data and used as per my requirement. It is working, but very noisy.

Someone please help me. I am in big trouble.


Solution

  • A couple of suggestions -

    1. Sample rate and buffer size get set using the AVAudioSession class.
    2. 386 is an unusual number of frames. Your callback is probably asking for 512 or 1024. You might try using a ring buffer to allow varying varying buffer size/ frame rates to suit your needs.

    Here are some examples:

    MixerHost
    TimeCode