如何使用AVFoundation访问1-2以外的其他音频硬件输出?我正在为Mac OS-X应用程序编写快速代码,该应用程序通过各种输出设备(USB接口,dante,soundflower)播放mp3文件,如下所示:
myPlayer = AVPlayer(URL: myFilePathURL)
myPlayer.audioOutputDeviceUniqueID = myAudioOutputDevices[1].deviceUID()
myPlayer.play()
但是,我不确定如何将音频文件播放到1-2以外的频道。例如,我想播放一个mp3输出3-4。
我可以通过AVPlayer执行此操作吗?或者我需要到别处寻找?也许AVAudioEngine和调音台节点一起?我浏览了AVAudioEngine示例,无法找到任何地方引用的硬件通道。谢谢你的帮助!
答案 0 :(得分:1)
我有一个快速版本,使用2个频道设置频道映射属性。我没有使用完整的多声道系统进行测试,但原则应该是相同的。
let engine = AVAudioEngine()
let player = AVAudioPlayerNode()
func testCode(){
// get output hardware format
let output = engine.outputNode
let outputHWFormat = output.outputFormatForBus(0)
// connect mixer to output
let mixer = engine.mainMixerNode
engine.connect(mixer, to: output, format: outputHWFormat)
//then work on the player end by first attaching the player to the engine
engine.attachNode(player)
//find the audiofile
guard let audioFileURL = NSBundle.mainBundle().URLForResource("tones", withExtension: "wav") else {
fatalError("audio file is not in bundle.")
}
var songFile:AVAudioFile?
do {
songFile = try AVAudioFile(forReading: audioFileURL)
print(songFile!.processingFormat)
// connect player to mixer
engine.connect(player, to: mixer, format: songFile!.processingFormat)
} catch {
fatalError("canot create AVAudioFile \(error)")
}
let channelMap: [Int32] = [0, 1] //left out left, right out right
//let channelMap: [Int32] = [1, 0] //right out left, left out right
let propSize: UInt32 = UInt32(channelMap.count) * UInt32(sizeof(sint32))
let code: OSStatus = AudioUnitSetProperty((engine.inputNode?.audioUnit)!,
kAudioOutputUnitProperty_ChannelMap,
kAudioUnitScope_Global,
1,
channelMap,
propSize);
print(code)
do {
try engine.start()
} catch {
fatalError("Could not start engine. error: \(error).")
}
player.scheduleFile(songFile!, atTime: nil) {
print("done")
self.player.play()
}
player.play()
}
答案 1 :(得分:1)
我随着时间的推移迭代了这段代码 - 但基本的大纲会起作用。这是我当前的设置代码,用于将音频发送到多通道设置。我目前正在使用带有16个立体声实例流的Dante Virtual Soundcard使用以下代码执行此操作:
func setupAudioPath(){
//print("setupAudioPath")
// get output hardware format
let output = engine.outputNode
outputHWFormat = output.outputFormat(forBus: 0)
//print("outputHWFormat = \(outputHWFormat)")
//print("outputHWFormat.channelCount = \(outputHWFormat.channelCount)")
// connect mixer to output
mixer = engine.mainMixerNode
//then work on the player end by first attaching the player to the engine
engine.attach(player)
engine.connect(mixer, to: output, format: outputHWFormat)
var channelMap: [sint32] = []
//UInt32 numOfChannels = fileFormat.NumberChannels();
let numOfChannels: UInt32 = UInt32(numberOfStreams) * UInt32(2); // Number of output device channels
let mapSize: UInt32 = numOfChannels * UInt32(MemoryLayout<sint32>.size);
for _ in 0...(numOfChannels-1) {
channelMap.append(-1)
}
//channelMap[desiredInputChannel] = deviceOutputChannel;
channelMap[leftChannel - 1] = 0;
channelMap[leftChannel] = 1;
//print(channelMap)
//print("number of channels in my map: \(channelMap.count)")
let code: OSStatus = AudioUnitSetProperty((engine.outputNode.audioUnit)!,
kAudioOutputUnitProperty_ChannelMap,
kAudioUnitScope_Global,
1,
channelMap,
mapSize);
print("osstatus = \(code)")
}