首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用AVFoundation和Swift访问多个音频硬件输出/通道

使用AVFoundation和Swift访问多个音频硬件输出/通道
EN

Stack Overflow用户
提问于 2016-07-27 07:55:00
回答 2查看 3.2K关注 0票数 1

如何使用AVFoundation访问1-2以外的其他音频硬件输出?我正在为Mac X应用程序编写swift代码,该应用程序通过各种输出设备(USB接口、但丁、音花)播放mp3文件,如下所示:

代码语言:javascript
复制
myPlayer = AVPlayer(URL: myFilePathURL)
myPlayer.audioOutputDeviceUniqueID = myAudioOutputDevices[1].deviceUID()
myPlayer.play()

但是,我不确定如何将音频文件播放到1-2以外的其他通道。例如,我想播放输出3-4的mp3。

我可以通过AVPlayer来做这件事吗?或者我需要去别的地方看看?也许可以使用AVAudioEngine和mixer节点?我查看了AVAudioEngine示例,但找不到任何地方引用的硬件通道。谢谢你的帮助!

EN

回答 2

Stack Overflow用户

发布于 2017-08-27 04:39:21

我已经在一段时间内迭代了这段代码--但是基本的大纲是可以工作的。这是我的当前设置代码,用于将音频发送到多声道设置。我目前正在使用以下代码对具有16个立体声实例化流的但丁虚拟声卡执行此操作:

代码语言:javascript
复制
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)")
}
票数 2
EN

Stack Overflow用户

发布于 2016-08-02 21:46:34

我有一个快速的版本,正在与2个频道设置频道映射属性。我还没有用一个完整的多通道系统来测试它,但是原理应该是一样的。

代码语言:javascript
复制
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
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38601656

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档