问题
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:
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()
来源:https://stackoverflow.com/questions/47629637/audiokit-ios-aksamplermetronome