我能够改变音频的音高和速度,但是我在改变音高和速度的过程中遇到了问题
//this is method which set the pitch
[self.audioEngine connect:audioPlayerNode
to:timePitchEffect
format:nil];
[self.audioEngine connect:timePitchEffect
to:self.audioEngine.outputNode
format:nil];
[audioPlayerNode scheduleFile:self.audioFile
atTime:nil
completionHandler:nil];
[self.audioEngine startAndReturnError:&audioEngineError];
NSLog(@"%@",self.audioFile.url);
if (audioEngineError) {
NSLog(@"%@",@"whats this!!!");
}
//按下按钮点击方法
[self playAudioWithEffect:EAudioEffectPitch effectValue:@-500.0];
我正在使用此功能更改音高,但如何使用更改的音高保存音量....请帮助......
答案 0 :(得分:-1)
您可以在AVAudioEngine
中启用离线手动渲染模式,在这种模式下,引擎的输入和输出节点与音频硬件断开连接,并且渲染由您的应用程序驱动。
准备源音频
let sourceFile: AVAudioFile
let format: AVAudioFormat
do {
let sourceFileURL = Bundle.main.url(forResource: "YOUR_AUDIO_NAME", withExtension: "caf")!
sourceFile = try AVAudioFile(forReading: sourceFileURL)
format = sourceFile.processingFormat
} catch {
fatalError("Unable to load the source audio file: \(error.localizedDescription).")
}
创建和配置音频引擎
let engine = AVAudioEngine()
let player = AVAudioPlayerNode()
let reverb = AVAudioUnitReverb()
engine.attach(player)
engine.attach(reverb)
// Set the desired reverb parameters.
reverb.loadFactoryPreset(.mediumHall)
reverb.wetDryMix = 50
// Connect the nodes.
engine.connect(player, to: reverb, format: format)
engine.connect(reverb, to: engine.mainMixerNode, format: format)
// Schedule the source file.
player.scheduleFile(sourceFile, at: nil)
启用离线手动渲染模式
do {
// The maximum number of frames the engine renders in any single render call.
let maxFrames: AVAudioFrameCount = 4096
try engine.enableManualRenderingMode(.offline, format: format,
maximumFrameCount: maxFrames)
} catch {
fatalError("Enabling manual rendering mode failed: \(error).")
}
//start the engine
do {
try engine.start()
player.play()
} catch {
fatalError("Unable to start audio engine: \(error).")
}
准备输出目标
// The output buffer to which the engine renders the processed data.
let buffer = AVAudioPCMBuffer(pcmFormat: engine.manualRenderingFormat,
frameCapacity: engine.manualRenderingMaximumFrameCount)!
let outputFile: AVAudioFile
do {
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
let outputURL = documentsURL.appendingPathComponent("Rhythm-processed.caf")
outputFile = try AVAudioFile(forWriting: outputURL, settings: sourceFile.fileFormat.settings)
} catch {
fatalError("Unable to open output audio file: \(error).")
}
手动渲染音频
while engine.manualRenderingSampleTime < sourceFile.length {
do {
let frameCount = sourceFile.length - engine.manualRenderingSampleTime
let framesToRender = min(AVAudioFrameCount(frameCount), buffer.frameCapacity)
let status = try engine.renderOffline(framesToRender, to: buffer)
switch status {
case .success:
// The data rendered successfully. Write it to the output file.
try outputFile.write(from: buffer)
case .insufficientDataFromInputNode:
// Applicable only when using the input node as one of the sources.
break
case .cannotDoInCurrentContext:
// The engine couldn't render in the current render call.
// Retry in the next iteration.
break
case .error:
// An error occurred while rendering the audio.
fatalError("The manual rendering failed.")
}
} catch {
fatalError("The manual rendering failed: \(error).")
}
}
// Stop the player node and engine.
player.stop()
engine.stop()