0

This is my code use AVAudioEngine for change voice in my app. Can anyone point out what's wrong in this code of mine and help me get rid of the error message?

extension AudioPlayer {

    func setupAudio(){
        // initialize (recording) audio file
        do{
            audioFile = try AVAudioFile(forReading: recordedAudioURL as URL)
        }catch{
            print("Audio File Error ")
        }
    }
    func playSound(rate: Float? = nil, pitch: Float? = nil, echo: Bool = false,reverb:Bool = false){
         // initialize audio engine components
        audioFile = AVAudioFile()
        audioEngine = AVAudioEngine()
        // node for playing audio
        audioPlayerNode = AVAudioPlayerNode()
        audioEngine.attach(audioPlayerNode)//attach the player node to the audio engine
        
        audioMixer = AVAudioMixerNode()
        audioEngine.attach(audioMixer)// attach a single output to the audio engine
        
        //node for the adjusting rate/pitch
        let changeRatePitchNode = AVAudioUnitTimePitch()
        if let pitch = pitch {
            changeRatePitchNode.pitch = pitch
        }
        if let rate = rate {
            changeRatePitchNode.rate = rate
        }
        audioEngine.attach(changeRatePitchNode)
        
        
        //node for the echo
        let echoNode = AVAudioUnitDistortion()
        echoNode.loadFactoryPreset(.multiEcho1)
        audioEngine.attach(echoNode)
        
        //node for the reverb
        let reverbNode = AVAudioUnitReverb()
        reverbNode.loadFactoryPreset(.cathedral)
        reverbNode.wetDryMix = 50
        audioEngine.attach(reverbNode)
        
        //connect the player node to the output node
        if echo == true && reverb == true{
            connectAudioNode(audioPlayerNode,changeRatePitchNode,echoNode,reverbNode,audioMixer,audioEngine.outputNode)
        }else if echo == true{
            connectAudioNode(audioPlayerNode, changeRatePitchNode, echoNode,audioMixer,audioEngine.outputNode)
        }else if reverb == true{
            connectAudioNode(audioPlayerNode, changeRatePitchNode, echoNode, audioMixer, audioEngine.outputNode)
        }else{
            connectAudioNode(audioPlayerNode, changeRatePitchNode,audioMixer,audioEngine.outputNode)
        }
        //schedule to replay the entire audio file- phat lai toan bo tep am thanh
        audioPlayerNode.stop()
        audioPlayerNode.scheduleFile(audioFile, at: nil)
        
        do{
            try audioEngine.start()
        }catch{
            print("Not OutPut")
        }
        //generate media resource modeling assets at the specified URL
        let audioAsset = AVURLAsset.init(url: recordedAudioURL)
       
        // returns the representation t/g = (s)
        let durationInSeconds = CMTimeGetSeconds(audioAsset.duration)
        
        let length = 4000
        let buffer = AVAudioPCMBuffer(pcmFormat: audioPlayerNode.outputFormat(forBus: 0), frameCapacity: AVAudioFrameCount(length))
        
        buffer!.frameLength = AVAudioFrameCount(durationInSeconds)//bộ đêmj âm thanh cho định dạng PCM
        
        // MARK: Create a new path after adding effects to the file
        let dirPath: AnyObject = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory,FileManager.SearchPathDomainMask.userDomainMask, true)[0] as AnyObject
        let tmpFileURL : NSURL = NSURL.fileURL(withPath: dirPath.appendingPathComponent("NewVoice.m4a")) as NSURL
        
        filteredOutputURL = tmpFileURL
        //setting for new file
        
        do{
            print(dirPath)
            let settings = [AVFormatIDKey:  kAudioFormatLinearPCM,
                         AVSampleRateKey:  44100,
                   AVNumberOfChannelsKey:  1]
            self.newAudio = try AVAudioFile(forWriting: tmpFileURL as URL, settings: settings)
            
            //setting for output
            self.audioMixer.installTap(onBus: 0, bufferSize: (AVAudioFrameCount(durationInSeconds)), format: self.audioPlayerNode.outputFormat(forBus: 0)) { [self](buffer: AVAudioPCMBuffer!, time: AVAudioTime!) in
                print(self.newAudio!.length)
                
                print(self.audioFile.length)
                
                if (self.newAudio!.length) < (self.audioFile.length){
                    do{
                        try self.newAudio!.write(from: buffer)
                    }catch {
                        print("error writing")
                    }
                }else{
                    audioPlayerNode.removeTap(onBus: 0)
                }
            }
        }catch _{
            print("problem")
        }
        // MARK: Play Sound Effect
            audioPlayerNode.play()
    }
    func connectAudioNode(_ nodes:AVAudioNode...){
        for i in 0..<nodes.count-1{
            audioEngine.connect(nodes[i], to: nodes[i + 1], format: audioFile.processingFormat)
        }//*error here "processingFormat"*
    }
}

error: "processingFormat" I don't know if it's because the link to read the file is wrong or what's wrong with my settings

  • I use AVAudioEngine to transform the sound, how or is there any documentation on how to transform that sound like existing applications: eg robots, old men, kids, aliens,.. .. – Duy Trần Sep 12 '22 at 09:59

0 Answers0