J'ai 15 fichiers WAV que j'ai besoin de lire en séquence sur des canaux individuels. Je commence à essayer d'obtenir deux fichiers fonctionnant avec une séparation stéréo gauche/droite.Lecture de plusieurs canaux WAV multiples AVAudioEngine
Je crée un moteur audio, une table de mixage et deux AVAudioPlayerNodes. Les fichiers audio sont mono et j'essaie d'obtenir le fichier de PlayerA pour sortir le canal gauche et le fichier de PlayerB pour sortir le bon canal. Ce que j'ai de la difficulté à comprendre, c'est comment fonctionne AudioUnitSetProperty. Il semble se rapporter à un seul fichier et semble être seulement en mesure d'en avoir un par audioUnit? Je me demande s'il y a un moyen que je peux associer un fichier avec un audioUnit? Je n'arrive pas à retourner l'objet audioUnit associé à chaque piste.
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)
}
Merci pour la suggestion dave. J'avais regardé la fonction de panoramique, mais j'essaie en fin de compte de sortir 15 fichiers sur 15 canaux différents, donc le panoramique ne fonctionnera pas dans cette application. – tsugua