@@ 25,6 25,7 @@ import (
"io"
"log"
"math"
+ "os"
"runtime"
"strings"
"time"
@@ 281,14 282,19 @@ var keyToIdx = map[string]int{
func keySet() key.Set {
baseKeys := maps.Keys(keyToIdx)
- chords := []string{}
- chords = append(chords, baseKeys...)
+ modifiers := []string{"Shift", "Ctrl", "Alt"}
+ modded := []string{}
+ for _, key := range modifiers {
+ baseKeys = append(baseKeys, key)
+ }
for _, key := range baseKeys {
- chords = append(chords, "Shift-"+key)
- chords = append(chords, "Ctrl-"+key)
- chords = append(chords, "Alt-"+key)
+ for _, mod := range modifiers {
+ modded = append(modded, mod+"-"+key)
+ }
}
- return key.Set(strings.Join(chords, "|"))
+ baseKeys = append(baseKeys, modded...)
+
+ return key.Set(strings.Join(baseKeys, "|"))
}
@@ 322,16 328,50 @@ func run(w *app.Window) error {
if err != nil {
return err
}
+ // Modifier key state
+ var (
+ shifted, ctrled, alted bool
+ )
players := make([]Pipe, len(freqs))
- toggleIndex := func(idx int, event key.Event, now time.Time) {
+
+ playing := make(map[string][]int)
+ startPlaying := make(map[string][]int)
+ stopPlaying := make(map[string]struct{})
+
+ toggleKey := func(event key.Event, now time.Time) {
+ var playingFrom [][]int
+ switch {
+ case shifted:
+ playingFrom = majChords
+ case ctrled:
+ playingFrom = majExtChords
+ case alted:
+ playingFrom = halfStepUp
+ default:
+ playingFrom = notes
+ }
+ idx, ok := keyToIdx[event.Name]
+ if !ok {
+ return
+ }
+
+ if idx >= len(playingFrom) {
+ return
+ }
if idx >= len(players) {
return
}
if event.State == key.Press {
- players[idx].Play(now)
+ if _, ok := stopPlaying[event.Name]; !ok {
+ if _, ok := playing[event.Name]; !ok {
+ startPlaying[event.Name] = playingFrom[idx]
+ }
+ }
} else {
- players[idx].Pause(now)
+ if _, ok := startPlaying[event.Name]; !ok {
+ stopPlaying[event.Name] = struct{}{}
+ }
}
}
@@ 372,29 412,35 @@ func run(w *app.Window) error {
default:
log.Printf("%#+v", event)
case key.Event:
- idx, ok := keyToIdx[event.Name]
- if !ok {
- continue
- }
- var playingFrom [][]int
switch {
- case event.Modifiers.Contain(key.ModShift):
- playingFrom = majChords
- case event.Modifiers.Contain(key.ModCtrl):
- playingFrom = majExtChords
- case event.Modifiers.Contain(key.ModAlt):
- playingFrom = halfStepUp
- default:
- playingFrom = notes
- }
- if idx >= len(playingFrom) {
- continue
- }
- for _, idx := range playingFrom[idx] {
- toggleIndex(idx, event, gtx.Now)
+ case event.Name == key.NameShift:
+ shifted = event.State == key.Press
+ case event.Name == key.NameCtrl:
+ ctrled = event.State == key.Press
+ case event.Name == key.NameAlt:
+ alted = event.State == key.Press
}
+ toggleKey(event, gtx.Now)
+ }
+ }
+ for key, indices := range startPlaying {
+ delete(startPlaying, key)
+ playing[key] = indices
+ for _, idx := range indices {
+ players[idx].Play(gtx.Now)
}
}
+ for key := range stopPlaying {
+ delete(stopPlaying, key)
+ indices, ok := playing[key]
+ if !ok {
+ continue
+ }
+ for _, idx := range indices {
+ players[idx].Pause(gtx.Now)
+ }
+ delete(playing, key)
+ }
key.InputOp{
Tag: w,
Keys: keySet,
@@ 477,8 523,11 @@ func run(w *app.Window) error {
func main() {
flag.Parse()
- if err := run(app.NewWindow(app.Title("Chipalee - Silly Chiptune Organ"))); err != nil {
- panic(err)
- }
+ go func() {
+ if err := run(app.NewWindow(app.Title("Chipalee - Silly Chiptune Organ"))); err != nil {
+ panic(err)
+ }
+ os.Exit(0)
+ }()
app.Main()
}