Récupérer l'audioOut d'un AudioUnit, ou bien copier un AVAudioPCMBuffer
Bonjour
Je travaille avec AVFoundation partie audio et CoreAudio.
J'ai l'habitude d'utiliser AVAudioEngine pour connecter mes applis avec les entrées et sorties audio par défaut du Mac ou de l'iPad.
Dans mes projets qui fonctionnent déjà, pour travailler avec l'entrée microphone, je fais un OSStatus dans lequel j'enregistre (ou copie) dans un AudioBufferList l'entrée. Puis lorsque j'instancie le AVAudioEngine, je fais :
AURenderCallbackStruct callbackStruct;
callbackStruct.inputProc = recordingCallback; //mon OSStatus
callbackStruct.inputProcRefCon = (__bridge void * _Nullable)(self); //ma classe audio
AudioUnitSetProperty(inputUnit, //inputUnit = audioEngine.inputNode.audioUnit;
kAudioOutputUnitProperty_SetInputCallback,
kAudioUnitScope_Global,
kInputBus, //= 0 , la sortie
&callbackStruct,
sizeof(callbackStruct));
De même je dérive l'audioUnit de la sortie pour écrire mon synthé (ou vocoder dans ce cas) en code C
(AudioUnit remoteIOUnit = audioEngine.outputNode.audioUnit; //puis j'écris l'OSStatus de mon synthé dans lequel je récupère les valeurs du AudioBufferList)
Là, je voudrais récupérer l'audioOut du AVAudioMixerNode pour récupérer le son de deux samplers dans mon render audio perso (qui sous-classe audioEngine.outputNode.audioUnit donc).
J'ai essayé une méthode similaire à partie des AVAudioUnitSampler (les deux samplers fonctionnent bien, je les ai testé à part) le OSStatus de sortie du mixer ou des samplers n'est pas appelé : mais que mettre à la place de kAudioOutputUnitProperty_SetInputCallback ou de kAudioUnitProperty_SetRenderCallback???
J'ai essayé de récupérer l'entrée du audioEngine.outputNode, cela ne fonctionne pas non plus. J'ai essayé
[audioMixerNode installTapOnBus: ...]
mais d'une part la méthode n'est pas appelée, et d'autre part je ne sais pas comment copier le buffer généré par la méthode vers le AVAudioPCMBuffer de la classe pour que je récupère les données dans mon OSStatus de sortie.
Je crains de n'être pas très clair, mais bon. Résumons :
1 - je récupère l'audio in pour faire un vocoder (cela fonctionne très bien)
2 - pour mixer le son de un ou deux samplers à l'entrée synthèse du vocoder, je joins au AVAudioEngine deux AVAudioUnitSampler
3 - je crée un OSStatus pour écrire mon vocoder (cela fonctionne TB aussi)
mais comment retrouver dans l'OSStatus de sortie la sortie audio des samplers?
Merci pas avance si vous pouvez m'aider. Nous sommes assez peu nombreux à nous poser ce genre de question je sais...
Réponses
Je passais voir à tout hasard si il y avait des réponses, mais l'audio est peu discutée ici.
La solution était la méthode "installTapOnBus ...", avec toutefois un petit problème d'horloge à régler. Les AudioUnit dans AVAudioEngine travaillent le plus souvent par paquets de 512 frames tandis que cette méthode travaille par paquets de 8192 (elle est surtout conçu pour enregistrer des fichiers audio). Il faut copier dedans huit blocs de 512 frames qui seront exploités ailleurs.
Il y a des nouveautés intéressantes dans le système audio AVAudioEngine. Le AVAudioSinkNode pour copier dans une AudioList l'entrée microphone ou bien les AVAudioSourceNode qui permettent d'écrire son synthétiseur pour en mixer la sortie avec les autres éléments. AVAudioEngine devient peu à peu un système modulaire. A suivre donc pour ceux qui travaillent sur ce sujet.