使用AudioKit AKOfflineRenderNode保存的文件不对

时间:2017-11-02 13:36:15

标签: ios audiokit

我正在使用AudioKit将WAV个文件与MIDI个文件混合在一起。 我还需要将结果保存在单独的文件中。

要混合使用WAV和MIDI,我使用AKMIDISampler AKSequencer,如下所示:

func add(track: MixerTrack) -> Bool {
    do{
        let trackSampler = AKMIDISampler()
        try trackSampler.loadWav(track.instrument.fileName)
        trackSampler.connect(to: mixer)

        let sequencer = AKSequencer(filename: track.midi.fileName)
        sequencer.setTempo(Double(tempo))
        sequencer.setRate(rate)
        sequencer.setGlobalMIDIOutput(trackSampler.midiIn)
        sequencer.enableLooping()
        sequencer.enableLooping()
        sequencers.append(sequencer)
        tracks.append(track)

        return true
    } catch {
        return false
    }
}

我正在使用AudioKit示例中的SongProcessor示例,了解如何使用AKOfflineRenderNode

这个例子适用于AKAudioPlayer个实例而不是我正在使用的序列发生器。我相信我不能使用播放器,因为我需要混合WAV和MIDI文件,而我只能使用音序器来实现。

我的第一个问题是:是否可以像使用播放器的SongProcessor一样从顺控程序创建文件?

我能够保存m4a文件,但结果很奇怪。首先,如果我没有手动将速率设置为40,那么播放所有音符的速度都很慢。当我将ti设置为这样的值时,我可以听到序列播放但速度错误。在某些时刻,节拍正常播放,但它们通常在不同时间开始播放太慢或太快。

我做错了吗?这是AKOfflineRenderNode的错误还是不是故意这样使用?

以下是我用于将混音保存到磁盘的代码:

    func saveMixToDisk() -> URL? {
    do {
        let fileManager = FileManager.default
        let name = UUID().uuidString.appending(".m4a")
        let documentDirectory = try fileManager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor:nil, create:false)
        let fileURL = documentDirectory.appendingPathComponent(name)

        offlineRender.internalRenderEnabled = false

        let duration = sequencers.first!.length.seconds
        for sequencer in sequencers {
            sequencer.stop()
            sequencer.setTime(AKDuration(seconds: 0).musicTimeStamp)
            sequencer.rewind()
        }

        for sequencer in sequencers {
            sequencer.setRate(40) // I would like to find a way to avoid having to set this, since this value is hardcoded and I don't know how to find the correct one. (When I only play through the sequencer inside the app the rate is perfect, but it gets messed up when rendering to URL)
            sequencer.play()
        }

        try offlineRender.renderToURL(fileURL, seconds: duration * 10)

        for sequencer in sequencers {
            sequencer.stop()
            sequencer.setTime(AKDuration(seconds: 0).musicTimeStamp)
            sequencer.rewind()
        }

        offlineRender.internalRenderEnabled = true

        return fileURL
    } catch let error {
        print(error)
        return nil
    }
}

非常感谢任何帮助。我似乎无法让它工作,遗憾的是我不知道iOS中的任何其他选项可以实现我的需要。

2 个答案:

答案 0 :(得分:1)

不要使用AKOfflineRender,而是在AudioKit 4.0.4中尝试新的AudioKit.renderToFile:https://github.com/AudioKit/AudioKit/commit/09aedf7c119a399ab00026ddfb91ae6778570176

答案 1 :(得分:0)

我认为您需要在iOS11中使用此方法

[AudioKit renderToFile:file持续时间:自我-> _ audioDurationSeconds错误:&错误预呈现:^ {                 [self.voicePlayer开始]; }];