-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcmd.go
111 lines (98 loc) · 2.42 KB
/
cmd.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package gosynth
import (
"container/heap"
"fmt"
"github.com/jcreedcmu/gosynth/service"
"log"
)
type CmdQueue []service.TimedCmd
type TimeResp struct {
Time int64 `json:"time"`
}
var aliases = make(map[int]int)
var queue = make(CmdQueue, 0)
func cmdHandle(cmd service.WsCmd) (interface{}, error) {
mutex.Lock()
defer mutex.Unlock()
return cmdHandleLocked(cmd)
}
func cmdHandleLocked(cmd service.WsCmd) (interface{}, error) {
switch cmd.Action {
case "load":
args := cmd.Args.(service.WsCmdLoad)
log.Printf("LOADING %s -> %s\n", args.Filename, args.Name)
err := LoadUgen(args.Filename, args.Name)
if err != nil {
log.Printf("Error loading ugen: %s\n", err)
}
case "unload":
args := cmd.Args.(service.WsCmdLoad)
log.Printf("UNLOADING %s\n", args.Name)
UnloadUgen(args.Name)
case "note":
args := cmd.Args.(service.WsCmdNote)
if args.On {
_, already := aliases[args.Id]
if !already {
aliases[args.Id] = genOn(args.UgenName, args.Priority, args.Pitch, args.Vel)
} else {
log.Printf("Trying to play note with duplicate external id %d\n", args.Id)
}
} else {
internal, ok := aliases[args.Id]
if ok {
genOff(internal)
delete(aliases, args.Id)
} else {
log.Printf("Trying to delete nonexistent note, external id %d\n", args.Id)
}
}
case "halt":
aliases = make(map[int]int)
queue = make(CmdQueue, 0)
genAllOff()
case "schedule":
args := cmd.Args.(service.WsCmdSchedule)
for _, tcmd := range args.Cmds {
if args.Relative {
tcmd.Time += globalTime
}
heap.Push(&queue, tcmd)
}
return TimeResp{Time: globalTime}, nil
case "set_params":
args := cmd.Args.(service.WsCmdSetParams)
resFreq = args.ResFreq
Q = args.Q
default:
return nil, fmt.Errorf("Unknown action %+v\n", cmd)
}
return "ok", nil
}
func (pq CmdQueue) Len() int { return len(pq) }
func (pq CmdQueue) Less(i, j int) bool {
return pq[i].Time < pq[j].Time
}
func (pq CmdQueue) Swap(i, j int) {
pq[i], pq[j] = pq[j], pq[i]
}
func (pq *CmdQueue) Push(x interface{}) {
*pq = append(*pq, x.(service.TimedCmd))
}
func (pq *CmdQueue) Pop() interface{} {
old := *pq
n := len(old)
item := old[n-1]
*pq = old[0 : n-1]
return item
}
// don't call if cmdqueue is empty
func (pq *CmdQueue) Least() int64 {
return (*pq)[0].Time
}
func FlushCmdQueueLocked(uptoTime int64) {
for len(queue) > 0 && queue.Least() <= globalTime {
tcmd := heap.Pop(&queue).(service.TimedCmd)
cmdHandleLocked(tcmd.Cmd)
}
}