Enregistrement de l'audio après l'effet dans iOS

Je développe un applicatoin afin que les gens puissent save et changer leurs voix à travers l'application et le partager. Fondamentalement, j'ai tellement de choses et maintenant il est time de vous requestr d'aider. Voici ma fonction de lecture qui lit le file audio enregistré et ajoute des effets sur celui-ci.

private func playAudio(pitch : Float, rate: Float, reverb: Float, echo: Float) { // Initialize variables audioEngine = AVAudioEngine() audioPlayerNode = AVAudioPlayerNode() audioEngine.attachNode(audioPlayerNode) // Setting the pitch let pitchEffect = AVAudioUnitTimePitch() pitchEffect.pitch = pitch audioEngine.attachNode(pitchEffect) // Setting the platback-rate let playbackRateEffect = AVAudioUnitVarispeed() playbackRateEffect.rate = rate audioEngine.attachNode(playbackRateEffect) // Setting the reverb effect let reverbEffect = AVAudioUnitReverb() reverbEffect.loadFactoryPreset(AVAudioUnitReverbPreset.Cathedral) reverbEffect.wetDryMix = reverb audioEngine.attachNode(reverbEffect) // Setting the echo effect on a specific interval let echoEffect = AVAudioUnitDelay() echoEffect.delayTime = NSTimeInterval(echo) audioEngine.attachNode(echoEffect) // Chain all these up, ending with the output audioEngine.connect(audioPlayerNode, to: playbackRateEffect, format: nil) audioEngine.connect(playbackRateEffect, to: pitchEffect, format: nil) audioEngine.connect(pitchEffect, to: reverbEffect, format: nil) audioEngine.connect(reverbEffect, to: echoEffect, format: nil) audioEngine.connect(echoEffect, to: audioEngine.outputNode, format: nil) audioPlayerNode.stop() let length = 4000 let buffer = AVAudioPCMBuffer(PCMFormat: audioPlayerNode.outputFormatForBus(0),frameCapacity:AVAudioFrameCount(length)) buffer.frameLength = AVAudioFrameCount(length) try! audioEngine.start() let dirPaths: AnyObject = NSSearchPathForDirectoriesInDomains( NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)[0] let tmpFileUrl: NSURL = NSURL.fileURLWithPath(dirPaths.ssortingngByAppendingPathComponent("effectedSound.m4a")) do{ print(dirPaths) let settings = [AVFormatIDKey: NSNumber(unsignedInt: kAudioFormatMPEG4AAC), AVSampleRateKey: NSNumber(integer: 44100), AVNumberOfChannelsKey: NSNumber(integer: 2)] self.newAudio = try AVAudioFile(forWriting: tmpFileUrl, settings: settings) audioEngine.outputNode.installTapOnBus(0, bufferSize: (AVAudioFrameCount(self.player!.duration)), format: self.audioPlayerNode.outputFormatForBus(0)){ (buffer: AVAudioPCMBuffer!, time: AVAudioTime!) in print(self.newAudio.length) print("=====================") print(self.audioFile.length) print("**************************") if (self.newAudio.length) < (self.audioFile.length){ do{ //print(buffer) try self.newAudio.writeFromBuffer(buffer) }catch _{ print("Problem Writing Buffer") } }else{ self.audioPlayerNode.removeTapOnBus(0) } } }catch _{ print("Problem") } audioPlayerNode.play() } 

Je suppose que le problème est que je suis installTapOnBus à audioPlayerNode mais l'audio affecté est sur audioEngine.outputNode. Cependant, j'ai essayé d'installerTapOnBus à audioEngine.outputNode mais il me donne l'erreur. Aussi j'ai essayé de connecter des effets à audioEngine.mixerNode mais aussi pas une solution. Donc, avez-vous des expériences sur l'logging de files audio? Comment puis-je get cet audio effectué?

Toute aide est appréciée

Je vous remercie

Cela ne semble pas être connecté correctement. Je suis en train d'apprendre tout cela moi-même, mais j'ai trouvé que les effets sont correctement ajoutés lorsque vous les connectez à un nœud de table de mixage. En outre, vous devrez appuyer sur le mélangeur, pas sur le noeud de sortie du moteur. Je viens de copyr votre code et j'ai fait quelques modifications pour en tenir count.

 private func playAudio(pitch : Float, rate: Float, reverb: Float, echo: Float) { // Initialize variables audioEngine = AVAudioEngine() audioPlayerNode = AVAudioPlayerNode() audioEngine.attachNode(audioPlayerNode) // Setting the pitch let pitchEffect = AVAudioUnitTimePitch() pitchEffect.pitch = pitch audioEngine.attachNode(pitchEffect) // Setting the playback-rate let playbackRateEffect = AVAudioUnitVarispeed() playbackRateEffect.rate = rate audioEngine.attachNode(playbackRateEffect) // Setting the reverb effect let reverbEffect = AVAudioUnitReverb() reverbEffect.loadFactoryPreset(AVAudioUnitReverbPreset.Cathedral) reverbEffect.wetDryMix = reverb audioEngine.attachNode(reverbEffect) // Setting the echo effect on a specific interval let echoEffect = AVAudioUnitDelay() echoEffect.delayTime = NSTimeInterval(echo) audioEngine.attachNode(echoEffect) // Set up a mixer node let audioMixer = AVAudioMixerNode() audioEngine.attachNode(audioMixer) // Chain all these up, ending with the output audioEngine.connect(audioPlayerNode, to: playbackRateEffect, format: nil) audioEngine.connect(playbackRateEffect, to: pitchEffect, format: nil) audioEngine.connect(pitchEffect, to: reverbEffect, format: nil) audioEngine.connect(reverbEffect, to: echoEffect, format: nil) audioEngine.connect(echoEffect, to: audioMixer, format: nil) audioEngine.connect(audioMixer, to: audioEngine.outputNode, format: nil) audioPlayerNode.stop() let length = 4000 let buffer = AVAudioPCMBuffer(PCMFormat: audioPlayerNode.outputFormatForBus(0),frameCapacity:AVAudioFrameCount(length)) buffer.frameLength = AVAudioFrameCount(length) try! audioEngine.start() let dirPaths: AnyObject = NSSearchPathForDirectoriesInDomains( NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)[0] let tmpFileUrl: NSURL = NSURL.fileURLWithPath(dirPaths.ssortingngByAppendingPathComponent("effectedSound.m4a")) do{ print(dirPaths) let settings = [AVFormatIDKey: NSNumber(unsignedInt: kAudioFormatMPEG4AAC), AVSampleRateKey: NSNumber(integer: 44100), AVNumberOfChannelsKey: NSNumber(integer: 2)] self.newAudio = try AVAudioFile(forWriting: tmpFileUrl, settings: settings) audioMixer.installTapOnBus(0, bufferSize: (AVAudioFrameCount(self.player!.duration)), format: self.audioMixer.outputFormatForBus(0)){ (buffer: AVAudioPCMBuffer!, time: AVAudioTime!) in print(self.newAudio.length) print("=====================") print(self.audioFile.length) print("**************************") if (self.newAudio.length) < (self.audioFile.length){ do{ //print(buffer) try self.newAudio.writeFromBuffer(buffer) }catch _{ print("Problem Writing Buffer") } }else{ self.audioMixer.removeTapOnBus(0) } } }catch _{ print("Problem") } audioPlayerNode.play() } 

J'ai également eu du mal à get le formatting du file correctement. J'ai finalement réussi à travailler quand j'ai changé mon path du file de sortie de m4a à caf . Une autre suggestion est de ne pas avoir nil pour le paramètre de format . J'ai utilisé le audioFile.processingFormat . J'espère que ça aide. Mes effets audio / mixage sont fonctionnels, bien que je n'ai pas enchaîné mes effets. Alors n'hésitez pas à poser des questions.

Voici ma solution à la question:

 func playAndRecord(pitch : Float, rate: Float, reverb: Float, echo: Float) { // Initialize variables // These are global variables . if you want you can just (let audioEngine = etc ..) init here these variables audioEngine = AVAudioEngine() audioPlayerNode = AVAudioPlayerNode() audioEngine.attachNode(audioPlayerNode) playerB = AVAudioPlayerNode() audioEngine.attachNode(playerB) // Setting the pitch let pitchEffect = AVAudioUnitTimePitch() pitchEffect.pitch = pitch audioEngine.attachNode(pitchEffect) // Setting the platback-rate let playbackRateEffect = AVAudioUnitVarispeed() playbackRateEffect.rate = rate audioEngine.attachNode(playbackRateEffect) // Setting the reverb effect let reverbEffect = AVAudioUnitReverb() reverbEffect.loadFactoryPreset(AVAudioUnitReverbPreset.Cathedral) reverbEffect.wetDryMix = reverb audioEngine.attachNode(reverbEffect) // Setting the echo effect on a specific interval let echoEffect = AVAudioUnitDelay() echoEffect.delayTime = NSTimeInterval(echo) audioEngine.attachNode(echoEffect) // Chain all these up, ending with the output audioEngine.connect(audioPlayerNode, to: playbackRateEffect, format: nil) audioEngine.connect(playbackRateEffect, to: pitchEffect, format: nil) audioEngine.connect(pitchEffect, to: reverbEffect, format: nil) audioEngine.connect(reverbEffect, to: echoEffect, format: nil) audioEngine.connect(echoEffect, to: audioEngine.mainMixerNode, format: nil) // Good practice to stop before starting audioPlayerNode.stop() // Play the audio file // this player is also a global variable AvAudioPlayer if(player != nil){ player?.stop() } // audioFile here is our original audio audioPlayerNode.scheduleFile(audioFile, atTime: nil, completionHandler: { print("Complete") }) try! audioEngine.start() let dirPaths: AnyObject = NSSearchPathForDirectoriesInDomains( NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)[0] let tmpFileUrl: NSURL = NSURL.fileURLWithPath(dirPaths.ssortingngByAppendingPathComponent("effectedSound2.m4a")) //Save the tmpFileUrl into global varibale to not lose it (not important if you want to do something else) filteredOutputURL = tmpFileUrl do{ print(dirPaths) self.newAudio = try! AVAudioFile(forWriting: tmpFileUrl, settings: [ AVFormatIDKey: NSNumber(unsignedInt:kAudioFormatAppleLossless), AVEncoderAudioQualityKey : AVAudioQuality.Low.rawValue, AVEncoderBitRateKey : 320000, AVNumberOfChannelsKey: 2, AVSampleRateKey : 44100.0 ]) let length = self.audioFile.length audioEngine.mainMixerNode.installTapOnBus(0, bufferSize: 1024, format: self.audioEngine.mainMixerNode.inputFormatForBus(0)) { (buffer: AVAudioPCMBuffer!, time: AVAudioTime!) -> Void in print(self.newAudio.length) print("=====================") print(length) print("**************************") if (self.newAudio.length) < length {//Let us know when to stop saving the file, otherwise saving infinitely do{ //print(buffer) try self.newAudio.writeFromBuffer(buffer) }catch _{ print("Problem Writing Buffer") } }else{ self.audioEngine.mainMixerNode.removeTapOnBus(0)//if we dont remove it, will keep on tapping infinitely //DO WHAT YOU WANT TO DO HERE WITH EFFECTED AUDIO } } }catch _{ print("Problem") } audioPlayerNode.play() } 

Pour ceux qui ont le problème d'avoir à jouer le file audio DEUX FOIS pour le sauvegarder, j'ai juste ajouté la ligne suivante à l'endroit respectif et cela a résolu mon problème. pourrait aider quelqu'un dans le futur.

PS: J'ai utilisé le même code EXACT que la réponse cochée ci-dessus, j'ai juste ajouté cette ligne et résolu mon problème.

 //Do what you want to do here with effected Audio self.newAudio = try! AVAudioFile(forReading: tmpFileUrl)