2017-05-28 5 views
0

J'ai utilisé avec succès AVAudioPlayerNode pour lire des fichiers stéréo et mono. Je voudrais utiliser des fichiers avec 3+ canaux (fichiers surround) et être capable de router l'audio de manière non linéaire. Par exemple, je pourrais assigner le canal de fichier 0 au canal de sortie 2, et le canal de fichier 4 au canal de sortie 1.Contrôle audio multicanal AVAudioPlayerNode

Le nombre de sorties de l'interface audio sera inconnu (2-40), et c'est pourquoi j'ai besoin être capable de permettre à l'utilisateur de router l'audio comme bon lui semble. Et la solution dans WWDC 2015 507 de demander à l'utilisateur de modifier le routage dans Audio Midi Setup n'est pas une solution viable.

Il y a seulement une possibilité que je peux penser (et je suis ouvert à d'autres): en créant un joueur par canal, et en chargeant chacun avec seulement une valeur de tampons de canaux similar to this post. Mais même par l'admission des affiches, il y a des problèmes.

Je suis à la recherche d'un moyen de copier chaque canal d'un fichier dans un AudioBuffer comme:

let file = try AVAudioFile(forReading: audioURL) 
let fullBuffer = AVAudioPCMBuffer(pcmFormat: file.processingFormat, 
            frameCapacity: AVAudioFrameCount(file.length)) 

try file.read(into: fullBuffer) 

// channel 0 
let buffer0 = AVAudioPCMBuffer(pcmFormat: file.processingFormat, 
           frameCapacity: AVAudioFrameCount(file.length)) 

// this doesn't work, unable to get fullBuffer channel and copy 
// error on subscripting mBuffers 
buffer0.audioBufferList.pointee.mBuffers.mData = fullBuffer.audioBufferList.pointee.mBuffers[0].mData 

// repeat above buffer code for each channel from the fullBuffer 

Répondre

0

j'ai pu comprendre, voici donc le code pour le faire fonctionner. Remarque: le code ci-dessous sépare un fichier stéréo (2 canaux). Cela pourrait facilement être étendu pour gérer un nombre inconnu de canaux.

let file = try AVAudioFile(forReading: audioURL) 

let formatL = AVAudioFormat(commonFormat: .pcmFormatFloat32, sampleRate: file.processingFormat.sampleRate, channels: 1, interleaved: false) 
let formatR = AVAudioFormat(commonFormat: .pcmFormatFloat32, sampleRate: file.processingFormat.sampleRate, channels: 1, interleaved: 

let fullBuffer = AVAudioPCMBuffer(pcmFormat: file.processingFormat, frameCapacity: AVAudioFrameCount(file.length)) 
let bufferLeft = AVAudioPCMBuffer(pcmFormat: formatL, frameCapacity: AVAudioFrameCount(file.length)) 
let bufferRight = AVAudioPCMBuffer(pcmFormat: formatR, frameCapacity: AVAudioFrameCount(file.length)) 

try file.read(into: fullBuffer) 
bufferLeft.frameLength = fullBuffer.frameLength 
bufferRight.frameLength = fullBuffer.frameLength 

for i in 0..<Int(file.length) { 
    bufferLeft.floatChannelData![0][i] = fullBuffer.floatChannelData![0][i] 
    bufferRight.floatChannelData![0][i] = fullBuffer.floatChannelData![1][i] 
}