Экспортировать аудиофайл после добавления эффекта
У меня есть аудиофайл, который я хочу обработать с использованием некоторых эффектов (например, эффект тангажа), а затем записать окончательный результат в файл.
Прежде чем обрабатывать файл и сохранять его на диск, я позволяю пользователю играть с эффектом тангажа и слушать изменения в реальном времени.
вот как я делаю вещи в реальном времени:
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
Так как использование AVAudioSession
не является явным требованием в заголовке вопроса, есть два возможных ответа:
Проиграйте через node (с AVAudioSession)
Установите кран на node. См. Справочник по основам AV Foundation.
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
требует воспроизведения. Подробнее о записи во время воспроизведения ответа с помощью @matt.
Использовать AudioUnit (без AVAudioSession)
Инициализируйте AudioSession
с помощью AudioSessionInitialize
, чтобы воспроизвести и записать, настроить поток чтения и записи и передать AURenderCallbackStruct
, указывая на ваш код обработки данных. Это, однако, не позволяет вам извлечь выгоду из AVAudioUnitTimePitch
. Вы можете узнать больше об этом решении в Как сделать запись в реальном времени с обработкой эффекта в iOS.