设置AVAudioEngine输入和输出设备

时间:2015-02-28 11:40:36

标签: objective-c avfoundation avaudioengine

我一直在玩Apple的闪亮的新AVFoundation库,但到目前为止,我还无法设置使用的输入或输出设备(例如USB声卡)通过AVAudioEngine,我似乎无法在文档中找到任何内容,甚至可以说它。

有没有人有这方面的经验?

2 个答案:

答案 0 :(得分:3)

好的,在第10次重新阅读文档后,我注意到AVAudioEngine有成员inputNodeoutputNode(不确定我是怎么错过的!)。

以下代码似乎可以完成这项工作:

AudioDeviceID inputDeviceID = 53; // get this using AudioObjectGetPropertyData
AVAudioEngine *engine = [[AVAudioEngine alloc] init];
AudioUnit audioUnit = [[engine inputNode] audioUnit];

OSStatus error = AudioUnitSetProperty(audioUnit,
                                      kAudioOutputUnitProperty_CurrentDevice,
                                      kAudioUnitScope_Global,
                                      0,
                                      &inputDeviceID,
                                      sizeof(inputDeviceID));

我从CAPlayThrough示例中借用了非AVFoundation C代码。

答案 1 :(得分:3)

这是一个完整的,如果有点粗糙的功能,它将播放一些音频用于测试目的(当然,如果你没有安装GarageBand,请选择不同的文件)。为了避免对设备ID进行硬编码,它会切换到您可以在“系统偏好设置”中设置的警报(“音效”)设备。

AVAudioEngine *engine = [[AVAudioEngine alloc] init];
AudioUnit outputUnit = engine.outputNode.audioUnit;

OSStatus err = noErr;
AudioDeviceID outputDeviceID;
UInt32 propertySize;

AudioObjectPropertyAddress propertyAddress = {
    kAudioHardwarePropertyDefaultSystemOutputDevice,
    kAudioObjectPropertyScopeGlobal,
    kAudioObjectPropertyElementMaster };
propertySize = sizeof(outputDeviceID);
err = AudioObjectGetPropertyData(kAudioObjectSystemObject, &propertyAddress, 0, NULL, &propertySize, &outputDeviceID);
if (err) { NSLog(@"AudioHardwareGetProperty: %d", (int)err); return; }

err = AudioUnitSetProperty(outputUnit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &outputDeviceID, sizeof(outputDeviceID));
if (err) { NSLog(@"AudioUnitSetProperty: %d", (int)err); return; }

NSURL *url = [NSURL URLWithString:@"/Applications/GarageBand.app/Contents/Frameworks/MAAlchemy.framework/Versions/A/Resources/Libraries/WaveNoise/Liquid.wav"];
NSError *error = nil;
AVAudioFile *file = [[AVAudioFile alloc] initForReading:url error:&error];
if (file == nil) { NSLog(@"AVAudioFile error: %@", error); return; }

AVAudioPlayerNode *player = [[AVAudioPlayerNode alloc] init];
[engine attachNode:player];
[engine connect:player to:engine.outputNode format:nil];

NSLog(@"engine: %@", engine);

if (![engine startAndReturnError:&error]) {
    NSLog(@"engine failed to start: %@", error);
    return;
}

[player scheduleFile:file atTime:[AVAudioTime timeWithHostTime:mach_absolute_time()] completionHandler:^{
    NSLog(@"complete");
}];
[player play];