添加音效后导出音频文件

14

我有一个音频文件,想要使用一些特效(例如音高特效)进行处理,然后将最终结果写入文件。

在处理文件和保存到磁盘之前,我会让用户实时调整音高特效并听取变化。

这是我实时处理的方法:

let audioSession = AVAudioSession.sharedInstance()
audioSession.setCategory(AVAudioSessionCategoryPlayback, error: nil)
audioSession.setActive(true, error: nil)

audioEngine = AVAudioEngine()
audioFile = AVAudioFile(forReading: audioUrl!, error: nil)

audioPlayerNode = AVAudioPlayerNode()
audioEngine.attachNode(audioPlayerNode)

changePitchEffect = AVAudioUnitTimePitch()
changePitchEffect.pitch = 1.0 // default
audioEngine.attachNode(changePitchEffect)

audioEngine.connect(audioPlayerNode, to: changePitchEffect, format: nil)
audioEngine.connect(changePitchEffect, to: audioEngine.outputNode, format: nil)

let frameCapacity = UInt32(audioFile.length)
let buffer = AVAudioPCMBuffer(PCMFormat: audioFile.processingFormat, frameCapacity: frameCapacity)
if audioFile.readIntoBuffer(buffer, error: nil) {

    audioEngine.startAndReturnError(nil)

    audioPlayerNode.scheduleBuffer(buffer, atTime: nil, options: .Loops, completionHandler: nil)

    audioPlayerNode.play() // start playing in a loop
}

然后使用UISlider让用户在循环播放音频时更改音高值。

因此,当用户完成更改音高并点击下一个按钮时,我需要保存带有所选音高值的音频文件。

我的问题是,如何创建具有音高效果的新音频文件?

我不想在用户听取音频并使用音高效果时进行录制,我只想导出最终结果(当然不播放文件)。

1个回答

6

由于问题标题中并没有明确要求使用AVAudioSession,因此有两种可能的答案:

通过节点播放(使用AVAudioSession)

在节点上安装一个tap。请参见AV Foundation Framework Reference

audioPlayerNode.installTapOnBus(0, bufferSize:frameLength, format: audioInputNode.outputFormatForBus(0), block: {(buffer, time) in
    let channels = UnsafeArray(start: buffer.floatChannelData, length: Int(buffer.format.channelCount))
    let floats = UnsafeArray(start: channels[0], length: Int(buffer.frameLength))

    for var i = 0; i < Int(self.audioBuffer.frameLength); i+=Int(self.audioMixerNode.outputFormatForBus(0).channelCount)
    {
        // process
    }
})
AVAudioSession 的记录机制需要播放。更多关于在Stack Overflow answer中的@matt所述“边播边录”的信息。

使用 AudioUnit(不使用 AVAudioSession)

使用AudioSessionInitialize初始化 AudioSession以进行播放和录制,设置读写流并传递一个指向数据处理代码的 AURenderCallbackStruct。但是,这将使您无法利用AVAudioUnitTimePitch。您可以在本文的iOS上如何进行实时录音及特效处理文章中了解更多有关此解决方案的信息。


1
感谢您的评论,但关于第一种选择,正如我所写的,我不想在演奏时录制。第二个选项对我来说不太清楚,我明白我将无法使用音高效果。 - Eyal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接