AudioKit ios AKSamplerMetronome

В настоящее время я использую AudioKSit AKSamplerMetronome для генерации и воспроизведения звуков метронома, теперь мне нужно реализовать обратный вызов, чтобы получить текущий ритм. Предположим, если у меня 5 ударов, мне нужно получить текущий воспроизводимый ритм, чтобы я мог добавить еще несколько функций на основе количества ударов, есть ли обратный вызов для достижения этого??

Это мой текущий код

 // 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 ответ

Решение

Вы можете сделать это достаточно легко с AKSequencer (я сделал что-то подобное). Я назначил одну дорожку секвенсора для AKMIDISampler, генерирующего звук метронома, и вторую дорожку, которая пошла в AKCallbackInstrument.
В треке, отправляемом в AKCallbackInstrument, я произвольно кодировал информацию о ритме в MIDI-данных, поэтому, например, данные MIDI для первого такта имеют MIDINote 1, второго - MIDINote 2 (вы можете сделать это со скоростью). Тогда функция обратного вызова могла бы просто просмотреть все сообщения noteOn, получить текущий удар по номеру MIDI Note и ответить соответствующим образом. Это немного косвенно, но это работает.

// 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()
Другие вопросы по тегам