使用AKMIDISampler的计时不正确

时间:2018-07-23 19:44:00

标签: ios swift audio timing audiokit

我正在尝试使用AKSequenser和AKMIDISampler使用AudioKit创建一个简单的音序器项目。但是遇到时间问题。

如果我使用音序器的默认振荡器声音跳过AKMIDISampler,则计时非常准确。当我将音序器连接到采样器(使用sondfonts或wav文件)时,问题就开始了。

开头不稳定,在整个播放过程中仍然不准确。

我已经添加了代码。有人对解决方案有什么建议吗?

var baseDrumMidiNumber:UInt8 = 35
var snareDrumMidiNumber:UInt8 = 38
var hihatMidiNumber:UInt8 = 42

let sampler = AKMIDISampler()
let mixer = AKMixer()
var sequenser = AKSequencer()

var track1:AKMusicTrack?
var track2:AKMusicTrack?
var track3:AKMusicTrack?

override func viewDidLoad() {
    super.viewDidLoad()
    setupAudio()
}

func setupAudio(){

    AudioKit.output = mixer
    AKSettings.bufferLength = .short

    do{
        try AudioKit.start()
        try sampler.loadSoundFont("drums", preset: 0, bank: 0)
    }catch{
        AKLog("failed to load basics with error \(error)")
    }

    sampler.connect(to: mixer)

    track1 = sequenser.newTrack()
    track2 = sequenser.newTrack()
    track3 = sequenser.newTrack()

    sequenser.setLength(AKDuration(beats: Double(4)))
    sequenser.setTempo(90)
    sequenser.toggleLoop()
    sequenser.setGlobalMIDIOutput(sampler.midiIn)

    track1?.add(noteNumber: baseDrumMidiNumber, velocity: 100, position: AKDuration(beats: 0), duration: AKDuration(beats: 1))
    track1?.add(noteNumber: baseDrumMidiNumber, velocity: 100, position: AKDuration(beats: 2), duration: AKDuration(beats: 1))

    track2?.add(noteNumber: snareDrumMidiNumber, velocity: 100, position: AKDuration(beats: 1), duration: AKDuration(beats: 1))
    track2?.add(noteNumber: snareDrumMidiNumber, velocity: 100, position: AKDuration(beats: 3), duration: AKDuration(beats: 1))

    for i in 0...15{
        track3?.add(noteNumber: hihatMidiNumber, velocity: 90, position: AKDuration(beats: 0.25*i), duration: AKDuration(beats: 0.25))
    }

    mixer.play()
    sequenser.preroll()

}

@IBAction func play(_ sender: Any) {
    if sequenser.isPlaying{
        sequenser.stop()
        sequenser.preroll()
        playButton.setTitle("play", for: UIControlState())
    }else{
        sequenser.play()
        playButton.setTitle("pause", for: UIControlState())
    }
}

@IBAction func stop(_ sender: Any) {
    sequenser.stop()
    sequenser.rewind()
    sequenser.preroll()
    playButton.setTitle("play", for: UIControlState())
}

@IBOutlet weak var playButton: UIButton!
@IBOutlet weak var stopButton: UIButton!

}

0 个答案:

没有答案