pawneebill
pawneebill

Reputation: 171

Reduce latency/lag in audio in AVCaptureSession?

I am trying to route audio from an arbitrary input (USB audio device) to an arbitrary output (another USB audio device). Think in terms of a crosspoint switch. No recording, no processing, just connect input A to output B.

I have been able to accomplish this using the following proof-of-concept code, but the delay/latency between input and output is excessive (almost 1 second). I have seen a posting (somewhere) asserting that AVFoundation uses rather large buffers for audio, and that is responsible for the lag, but I have not found anywhere that I can change the buffer size.

Can anyone suggest a solution to reducing the lag,

OR:

Provide a suggestion as to how I can integrate some (as little as possible) Core Audio (or other) code to accomplish my objective?

In the following code, "IN_1" and "OUT_0,1" are aggregate devices created in the Audio MIDI Setup control panel. For testing purposes, it is all implemented in my test application delegate.

- (void) setUpCaptureSession
{
    NSError * error;
    self.captureSession = [AVCaptureSession new];
    AVCaptureSession * session = self.captureSession;
    AVCaptureDevice * inputDevice = [self deviceWithLocalizedName:@"IN_1"];
    AVCaptureDevice * outputDevice = [self deviceWithLocalizedName: @"OUT_0,1"];
    session.sessionPreset = AVCaptureSessionPresetLow;
    if(inputDevice)
        {
        AVCaptureInput * input = [AVCaptureDeviceInput deviceInputWithDevice: inputDevice error:&error];
        if([session canAddInput: input])
            {
            [session addInput: input];
            }
        }
    if(outputDevice)
        {
        AVCaptureAudioPreviewOutput * output = [AVCaptureAudioPreviewOutput new];
        output.outputDeviceUniqueID = outputDevice.uniqueID;
        output.volume = 1.0;
        if([session canAddOutput: output])
            {
            [session addOutput: output];
            }
        }
    [[NSNotificationCenter defaultCenter] addObserver: self  selector: @selector(handleCaptureSessionError:) name: AVCaptureSessionRuntimeErrorNotification object: self.captureSession];
}

- (AVCaptureDevice *) deviceWithLocalizedName:(NSString *) name
{
    AVCaptureDevice * result = nil;
    NSArray * devices = [AVCaptureDevice devices];
    for(AVCaptureDevice * device in devices)
        {
        if([device.localizedName isCaseInsensitiveLike: name])
            {
            result = device;
            break;
            }
        }
    return result;
}

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
/* NOTE: latency does NOT reduce if the following are run on a background queue */
    [self setUpCaptureSession];
    [self.captureSession startRunning];
}

Upvotes: 1

Views: 877

Answers (1)

hotpaw2
hotpaw2

Reputation: 70703

For low latency audio, use Audio Units with short buffers for record and play, which may allow latencies of tens of milliseconds or less, depending on the hardware.

Upvotes: 3

Related Questions