AudioKit ios AKSamplerMetronome

2019-01-19 07:19发布

I'm currently using AudioKit's AKSamplerMetronome to generate and play Metronome sounds , now I need implement an callback to get current beat suppose If I'm having 5 beats I need to get current beat that is being played so that I can add some more functions based on the beat count , is there any callback available to achieve It ??

This is my current code

 // using AKSamplerMetronome
var metronome1 = AKSamplerMetronome()
var mixer = AKMixer()
// first sound called
let beatstart = Bundle.main.url(forResource: "mybeat", withExtension: "wav")
 // other sounds based on beat count
let beaten = Bundle.main.url(forResource: "others", withExtension: "wav")
// setting first sound and other beat sounds
metronome1.sound = McountSoundUrl
metronome1.downBeatSound = MoneSoundUrl
metronome1 >>> mixer
AudioKit.output = mixer
AudioKit.start()

1条回答
女痞
2楼-- · 2019-01-19 07:31

You could do this easily enough with AKSequencer (I did something similar). I assigned one track of the sequencer to an AKMIDISampler, generating the metronome sound, and a second track that went to an AKCallbackInstrument.
In the track being sent to the AKCallbackInstrument, I encoded the beat information arbitrarily in the MIDI data, so for example, the MIDI data for the first beat has a MIDINote of 1, the second, MIDINote 2 (you could do this with the velocity). Then the callback function could would just look at all of the noteOn messages and get the current beat from the MIDI Note number, and respond accordingly. It's a little indirect, but it works.

// create the sequencer before hand (e.g., at init); calling play() immediately after creating it causes some odd behaviour
    let sequencer = AKSequencer()

    // set up the sampler and callbackInst
    let sampler = AKSynthSnare()
    // or for your own sample:
    // let sampler = AKMIDISampler()
    // sampler.loadWav("myMetronomeSound)
    let callbackInst = AKCallbackInstrument()
    AudioKit.output = sampler
    AudioKit.start()

    // create two tracks for the sequencer
    let metronomeTrack = sequencer.newTrack()
    metronomeTrack?.setMIDIOutput(sampler.midiIn)
    let callbackTrack = sequencer.newTrack()
    callbackTrack?.setMIDIOutput(callbackInst.midiIn)

    // create the MIDI data
    for i in 0 ..< 4 {
        // this will trigger the sampler on the four down beats
        metronomeTrack?.add(noteNumber: 60, velocity: 100, position: AKDuration(beats: Double(i)), duration: AKDuration(beats: 0.5))

        // set the midiNote number to the current beat number
        callbackTrack?.add(noteNumber: MIDINoteNumber(i), velocity: 100, position: AKDuration(beats: Double(i)), duration: AKDuration(beats: 0.5))
    }

    // set the callback
    callbackInst.callback = {status, noteNumber, velocity in
        guard status == .noteOn else { return }
        print("beat number: \(noteNumber + 1)")
        // e.g., resondToBeat(beatNum: noteNumber)
    }

    // get the sequencer ready
    sequencer.enableLooping(AKDuration(beats: 4))
    sequencer.setTempo(60)
    sequencer.play()
查看更多
登录 后发表回答