我正在建立一个有关音乐的项目,并且正在使用AudioKit框架。 AudioKit非常有用,但是我现在需要导出在应用程序中创建的声音。
我正在使用AKSequencer顺序播放音符,并且还在声音上应用了一些过滤器,例如混响。
我找到了一个示例代码here,该示例代码可以从另一个音频文件中导出音频,但这不是我所需要的。实际上,我需要渲染包括过滤器在内的音符序列,并将其导出给用户。
我的代码:
class Sequencer {
let oscBank = AKOscillatorBank(waveform: AKTable(AKTableType.positiveReverseSawtooth))//1
let sequencer = AKSequencer()
init() {
setup()
}
func setup() {
// I instantiate a MIDI node with the oscillator bank to put it in the track output.
// It makes the oscillator's filters are recognized in the track output.
let midiNode = AKMIDINode(node: oscBank)
_ = sequencer.newTrack()
sequencer.tracks[0].setMIDIOutput(midiNode.midiIn)
generateSequence()
// Here I'm applying some filter, a reverb in this case.
let reverb = AKReverb(oscBank)
reverb.loadFactoryPreset(.plate)
// The Audiokit's output may be the last filter applyed. It is working to play.
AudioKit.output = AKMixer(reverb)
try? AudioKit.start()
}
func play() {
sequencer.play()
}
func stop() {
sequencer.stop()
}
/// Generates some melody (Sweet Child of Mine)
func generateSequence() {
for _ in 0..<2 {
sequencer.tracks[0].add(noteNumber: 62, velocity: 127, position: AKDuration(beats: 0), duration: AKDuration(beats: 0.5))
sequencer.tracks[0].add(noteNumber: 74, velocity: 127, position: AKDuration(beats: 0.5), duration: AKDuration(beats: 0.5))
sequencer.tracks[0].add(noteNumber: 69, velocity: 127, position: AKDuration(beats: 1), duration: AKDuration(beats: 0.5))
sequencer.tracks[0].add(noteNumber: 67, velocity: 127, position: AKDuration(beats: 1.5), duration: AKDuration(beats: 0.5))
sequencer.tracks[0].add(noteNumber: 79, velocity: 127, position: AKDuration(beats: 2), duration: AKDuration(beats: 0.5))
sequencer.tracks[0].add(noteNumber: 69, velocity: 127, position: AKDuration(beats: 2.5), duration: AKDuration(beats: 0.5))
sequencer.tracks[0].add(noteNumber: 78, velocity: 127, position: AKDuration(beats: 3), duration: AKDuration(beats: 0.5))
sequencer.tracks[0].add(noteNumber: 69, velocity: 127, position: AKDuration(beats: 3.5), duration: AKDuration(beats: 0.5))
sequencer.tracks[0].add(noteNumber: 62, velocity: 127, position: AKDuration(beats: 4), duration: AKDuration(beats: 0.5))
sequencer.tracks[0].add(noteNumber: 74, velocity: 127, position: AKDuration(beats: 4.5), duration: AKDuration(beats: 0.5))
sequencer.tracks[0].add(noteNumber: 69, velocity: 127, position: AKDuration(beats: 5), duration: AKDuration(beats: 0.5))
sequencer.tracks[0].add(noteNumber: 67, velocity: 127, position: AKDuration(beats: 5.5), duration: AKDuration(beats: 0.5))
sequencer.tracks[0].add(noteNumber: 79, velocity: 127, position: AKDuration(beats: 6), duration: AKDuration(beats: 0.5))
sequencer.tracks[0].add(noteNumber: 69, velocity: 127, position: AKDuration(beats: 6.5), duration: AKDuration(beats: 0.5))
sequencer.tracks[0].add(noteNumber: 78, velocity: 127, position: AKDuration(beats: 7), duration: AKDuration(beats: 0.5))
sequencer.tracks[0].add(noteNumber: 69, velocity: 127, position: AKDuration(beats: 7.5), duration: AKDuration(beats: 0.5))
}
}
// Here is my problem. I want to get the song and export it with the .wav extension exactly as it was played.
// This code is just one of my many attempts and it also does not works.
func saveFile() {
guard let auxiliarPlayer = try? AKAudioPlayer(file: AKAudioFile(readFileName: "bass.wav")) else { return }
guard let outputURL = try? FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false).appendingPathComponent("audio_file.m4a") else { return }
guard let output = try? AKAudioFile(forWriting: outputURL, settings: auxiliarPlayer.audioFile.fileFormat.settings) else { return }
try? AudioKit.renderToFile(output, seconds: sequencer.tracks[0].length, prerender: {
self.sequencer.play()
})
}
}
有人可以帮忙吗?
答案 0 :(得分:1)
据我所知,由于时序问题,脱机渲染不适用于MIDI。基本上,只能渲染处理音频的内容,而不能渲染依赖MIDI的内容。我认为这与MIDI时钟保持恒定有关,并且实际上无法“加速”以匹配音频渲染速度。