mirror of
https://github.com/vsariola/sointu.git
synced 2025-07-23 15:34:52 -04:00
feat(tracker): rework the MIDI input and note event handling
This commit is contained in:
parent
7ef868a434
commit
283fbc1171
58
tracker/gioui/keyboard.go
Normal file
58
tracker/gioui/keyboard.go
Normal file
@ -0,0 +1,58 @@
|
||||
package gioui
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/vsariola/sointu/tracker"
|
||||
)
|
||||
|
||||
type (
|
||||
// Keyboard is used to associate the keys of a keyboard (e.g. computer or a
|
||||
// MIDI keyboard) to currently playing notes. You can use any type T to
|
||||
// identify each key; T should be a comparable type.
|
||||
Keyboard[T comparable] struct {
|
||||
broker *tracker.Broker
|
||||
pressed map[T]tracker.NoteEvent
|
||||
}
|
||||
)
|
||||
|
||||
func MakeKeyboard[T comparable](broker *tracker.Broker) Keyboard[T] {
|
||||
return Keyboard[T]{
|
||||
broker: broker,
|
||||
pressed: make(map[T]tracker.NoteEvent),
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Keyboard[T]) Press(key T, ev tracker.NoteEvent) {
|
||||
if _, ok := t.pressed[key]; ok {
|
||||
return // already playing a note with this key, do not send a new event
|
||||
}
|
||||
t.Release(key) // unset any previous note
|
||||
if ev.Note > 1 {
|
||||
ev.Source = t // set the source to this keyboard
|
||||
ev.On = true
|
||||
ev.Timestamp = t.now()
|
||||
if tracker.TrySend(t.broker.ToPlayer, any(ev)) {
|
||||
t.pressed[key] = ev
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Keyboard[T]) Release(key T) {
|
||||
if ev, ok := t.pressed[key]; ok {
|
||||
ev.Timestamp = t.now()
|
||||
ev.On = false // the pressed contains the event we need to send to release the note
|
||||
tracker.TrySend(t.broker.ToPlayer, any(ev))
|
||||
delete(t.pressed, key)
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Keyboard[T]) ReleaseAll() {
|
||||
for key := range t.pressed {
|
||||
t.Release(key)
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Keyboard[T]) now() int64 {
|
||||
return time.Now().UnixMilli() * 441 / 10 // convert to 44100Hz frames
|
||||
}
|
Reference in New Issue
Block a user