录制带有附加效果的音频

Record audio with added effects

我读了很多 post 并尝试了很多不同的方法,最终得出了实际可行的解决方案,这是来自其他堆栈溢出 post 的休闲功能,可以发挥作用,增加效果并将其保存到文件中,它起到了附加效果并保存了但问题是保存的 caf.文件不可读。我看到它在主目录上创建了文件,但无法播放。任何想法导致问题的原因将不胜感激

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.mainMixerNode, format: nil)


    // Good practice to stop before starting
    audioPlayerNode.stop()

    // Play the audio file
    if(audioEngine != nil){
        audioEngine?.stop()
    }

    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.stringByAppendingPathComponent("dddeffefsdctedSoundf23f13.caf"))
    filteredOutputURL = tmpFileUrl

    do{
        print(dirPaths)
        print(tmpFileUrl)

        self.newAudio = try! AVAudioFile(forWriting: tmpFileUrl, settings:[
            AVFormatIDKey: NSNumber(unsignedInt:kAudioFormatAppleLossless),
            AVEncoderAudioQualityKey : AVAudioQuality.Medium.rawValue,
            AVEncoderBitRateKey : 12800,
            AVNumberOfChannelsKey: 2,
            AVSampleRateKey : 44100.0
            ])

        audioEngine.mainMixerNode.installTapOnBus(0, bufferSize: 2048, format: audioEngine.mainMixerNode.inputFormatForBus(0)) {
            (buffer: AVAudioPCMBuffer!, time: AVAudioTime!) -> Void in

            print(self.newAudio.length)
            print("=====================")
            print(self.audioFile.length)
            print("**************************")
            if (self.newAudio.length) < (self.audioFile.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

            }

        }
    }catch _{
        print("Problem")
    }

    audioPlayerNode.play()

您需要刷新并关闭文件音频文件,以便正确写出 caf 文件。

看到 AVAudioFile 没有明确的方法来做到这一点,您唯一的希望似乎是在完成后将 newAudio 设置为 nil 并希望在 [=11] 期间完成=]的dealloc

self.audioEngine.mainMixerNode.removeTapOnBus(0)
                print("finish?")
self.newAudio = nil   // hopefully flush & close, if there are no other strong references