Files
sointu/tracker/gioui/keyboard.go
2025-06-11 19:14:11 +03:00

59 lines
1.4 KiB
Go

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
}