2017-09-04 38 views
1

私は15チャンネルのWAVファイルを個々のチャンネルで順番に再生する必要があります。私は左/右のステレオ分離で動作する2つのファイルを取得しようとしています。複数のWAVファイルを複数のチャンネルで再生するAVAudioEngine

私は、オーディオエンジン、ミキサー、2つのAVAudioPlayerNodesを作成しています。オーディオファイルはモノラルで、PlayerAからファイルを取得して、左のチャンネルから、PlayerBから右のチャンネルからファイルを取得しようとしています。私が理解できないことは、AudioUnitSetPropertyがどのように動作するかです。 1つのファイルのみに関連しているようで、audioUnitあたり1つしかないようですね。ファイルをaudioUnitに関連付ける方法があるかどうか疑問に思っていますか?私は各トラックに関連付けられたaudioUnitオブジェクトを返すように見えません。

func testCode(){ 

    // get output hardware format 
    let output = engine.outputNode 
    let outputHWFormat = output.outputFormat(forBus: 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.attach(playerA) 
    engine.attach(playerB) 


    //find the audiofile 
    guard let audioFileURLA = Bundle.main.url(forResource: "test", withExtension: "wav") else { 
     fatalError("audio file is not in bundle.") 
    } 

    guard let audioFileURLB = Bundle.main.url(forResource: "test2", withExtension: "wav") else { 
     fatalError("audio file is not in bundle.") 
    } 

    var songFileA:AVAudioFile? 
    do { 
     songFileA = try AVAudioFile(forReading: audioFileURLA) 
     print(songFileA!.processingFormat) 

     // connect player to mixer 
     engine.connect(playerA, to: mixer, format: songFileA!.processingFormat) 

    } catch { 
     fatalError("canot create AVAudioFile \(error)") 
    } 


    let channelMap: [Int32] = [0, -1] //play channel in left 


    let propSize: UInt32 = UInt32(channelMap.count) * UInt32(MemoryLayout<sint32>.size) 

    print(propSize) 

    let code: OSStatus = AudioUnitSetProperty((engine.inputNode?.audioUnit)!, 
               kAudioOutputUnitProperty_ChannelMap, 
               kAudioUnitScope_Global, 
               1, 
               channelMap, 
               propSize); 
    print(code) 


    let channelMapB: [Int32] = [-1, 0] //play channel in left 

    var songFileB:AVAudioFile? 
    do { 
     songFileB = try AVAudioFile(forReading: audioFileURLB) 
     print(songFileB!.processingFormat) 

     // connect player to mixer 
     engine.connect(playerB, to: mixer, format: songFileB!.processingFormat) 

    } catch { 
     fatalError("canot create AVAudioFile \(error)") 
    } 

    let codeB: OSStatus = AudioUnitSetProperty((engine.inputNode?.audioUnit)!, 
               kAudioOutputUnitProperty_ChannelMap, 
               kAudioUnitScope_Global, 
               1, 
               channelMapB, 
               propSize); 

    print(codeB) 


    do { 
     try engine.start() 
    } catch { 
     fatalError("Could not start engine. error: \(error).") 
    } 

    playerA.scheduleFile(songFileA!, at: nil) { 
     print("done") 
     self.playerA.play() 
    } 
    playerB.scheduleFile(songFileA!, at: nil) { 
     print("done") 
     self.playerB.play() 
    } 

    playerA.play() 
    playerB.play() 

    print(playerA.isPlaying) 

} 

答えて

0

engine.connect(ミキサー、全出力、形式:outputHWFormat)

これは必要でないアクセスされたとき、ミキサは、暗黙的に接続されます。

パニングの場合:AudioUnitSetPropertyも必要ありません。 AVAudioPlayerNodeはAVAudioMixingに準拠し、そのプレイヤーから下流ミキサーノードがあるので、あなたがしなければならないすべてはこれです:提案デイブため

playerA.pan = -1 
playerB.pan = 1 
+0

感謝。私はパン機能を見ていましたが、最終的に15のファイルを15の別々のチャンネルに出力しようとしていますので、パンニングはそのアプリケーションでは機能しません。 – tsugua

関連する問題