sidneivl
sidneivl

Reputation: 244

A show pressed key on AudioKit Keyboard

I'm studying AudioKit and I don't know how I show on AudioKit Keyboard a key pressed in a MIDI keyboard.

In my code I get the MIDI key pressed and show the keyboard, but how can I pass the key pressed to AudioKit Keyboard?

My simple code:

//
//  ContentView.swift
//  ProjectScoreSwift
//
//  Created by Sidnei Vladisauskis on 03/07/20.
//  Copyright © 2020 Sidnei Vladisauskis. All rights reserved.
//

import SwiftUI
import AudioKit
import CoreMIDI
import Keyboard
import Tonic

struct MIDIMonitorData {
    var noteOn = 0
    var velocity = 0
    var noteOff = 0
    var channel = 0
    var afterTouch = 0
    var afterTouchNoteNumber = 0
    var programChange = 0
    var pitchWheelValue = 0
    var controllerNumber = 0
    var controllerValue = 0
}

enum MIDIEventType {
    case none
    case noteOn
    case noteOff
    case continuousControl
    case programChange
}

class MIDIMonitorConductor: ObservableObject, MIDIListener {
    let midi = MIDI()
    @Published var data = MIDIMonitorData()
    @Published var midiEventType: MIDIEventType = .none
    
    init() {}
    
    func start() {
        midi.openInput(name: "Bluetooth")
        midi.openInput()
        midi.addListener(self)
    }
    
    func stop() {
        midi.closeAllInputs()
    }
    
    func receivedMIDINoteOn(noteNumber: MIDINoteNumber,
                            velocity: MIDIVelocity,
                            channel: MIDIChannel,
                            portID _: MIDIUniqueID?,
                            timeStamp _: MIDITimeStamp?)
    {
        DispatchQueue.main.async {
            self.midiEventType = .noteOn
            self.data.noteOn = Int(noteNumber)
            self.data.velocity = Int(velocity)
            self.data.channel = Int(channel)
            
            print(Int(noteNumber))
        }
    }
    
    func receivedMIDINoteOff(noteNumber: MIDINoteNumber,
                             velocity: MIDIVelocity,
                             channel: MIDIChannel,
                             portID _: MIDIUniqueID?,
                             timeStamp _: MIDITimeStamp?)
    {
        DispatchQueue.main.async {
            self.midiEventType = .noteOff
            self.data.noteOff = Int(noteNumber)
            self.data.velocity = Int(velocity)
            self.data.channel = Int(channel)
        }
    }
    
    func receivedMIDIController(_ controller: MIDIByte,
                                value: MIDIByte,
                                channel: MIDIChannel,
                                portID _: MIDIUniqueID?,
                                timeStamp _: MIDITimeStamp?)
    {
        DispatchQueue.main.async {
            self.midiEventType = .continuousControl
            self.data.controllerNumber = Int(controller)
            self.data.controllerValue = Int(value)
            self.data.channel = Int(channel)
            
            print(Int(controller))
        }
    }
    
    func receivedMIDIAftertouch(_ pressure: MIDIByte,
                                channel: MIDIChannel,
                                portID _: MIDIUniqueID?,
                                timeStamp _: MIDITimeStamp?)
    {
        DispatchQueue.main.async {
            self.data.afterTouch = Int(pressure)
            self.data.channel = Int(channel)
        }
    }
    
    func receivedMIDIAftertouch(noteNumber: MIDINoteNumber,
                                pressure: MIDIByte,
                                channel: MIDIChannel,
                                portID _: MIDIUniqueID?,
                                timeStamp _: MIDITimeStamp?)
    {
        DispatchQueue.main.async {
            self.data.afterTouchNoteNumber = Int(noteNumber)
            self.data.afterTouch = Int(pressure)
            self.data.channel = Int(channel)
        }
    }
    
    func receivedMIDIPitchWheel(_ pitchWheelValue: MIDIWord,
                                channel: MIDIChannel,
                                portID _: MIDIUniqueID?,
                                timeStamp _: MIDITimeStamp?)
    {
        DispatchQueue.main.async {
            self.data.pitchWheelValue = Int(pitchWheelValue)
            self.data.channel = Int(channel)
        }
    }
    
    func receivedMIDIProgramChange(_ program: MIDIByte,
                                   channel: MIDIChannel,
                                   portID _: MIDIUniqueID?,
                                   timeStamp _: MIDITimeStamp?)
    {
        DispatchQueue.main.async {
            self.midiEventType = .programChange
            self.data.programChange = Int(program)
            self.data.channel = Int(channel)
        }
    }
    
    func receivedMIDISystemCommand(_: [MIDIByte],
                                   portID _: MIDIUniqueID?,
                                   timeStamp _: MIDITimeStamp?)
    {
        // print("sysex")
    }
    
    func receivedMIDISetupChange() {
        // Do nothing
    }
    
    func receivedMIDIPropertyChange(propertyChangeInfo _: MIDIObjectPropertyChangeNotification) {
        // Do nothing
    }
    
    func receivedMIDINotification(notification _: MIDINotification) {
        // Do nothing
    }
    
}

struct ContentView: View {
    @StateObject private var conductor = MIDIMonitorConductor()
    
    var body: some View {
        HStack {
            VStack {
                Keyboard(
                    layout: .verticalPiano(pitchRange: Pitch(intValue: 21) ... Pitch(intValue: 108))
                ).frame(width: 150)
            }
        } .onAppear {
            conductor.start()
        }
        .onDisappear {
            conductor.stop()
        }
        
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

I think was easier if there is a method on keyboard like keyPress, keyUnpress, or something else.

Regards

Upvotes: 2

Views: 80

Answers (1)

sridhar_rajagopal
sridhar_rajagopal

Reputation: 180

This demo in this example does something similar : https://github.com/AudioKit/Tonic/tree/main

It utilizes isActivatedExternally of KeyboardKey

I see you had raised this question in AudioKit GitHub - https://github.com/AudioKit/Keyboard/issues/23 (from where I'm referencing this answer).

I had a similar question, which brought me here, so I'm adding this answer here for others who have a similar question.

Upvotes: 0

Related Questions