Reputation: 171
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
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