2022-06-25 20:11:15 +01:00
|
|
|
package voicemeeter
|
|
|
|
|
2022-06-30 23:20:15 +01:00
|
|
|
import (
|
|
|
|
"time"
|
2022-10-10 18:51:30 +01:00
|
|
|
|
|
|
|
log "github.com/sirupsen/logrus"
|
2022-06-30 23:20:15 +01:00
|
|
|
)
|
|
|
|
|
2022-12-08 10:50:00 +00:00
|
|
|
// publisher defines the list of observer channels
|
2022-06-26 01:41:05 +01:00
|
|
|
type publisher struct {
|
2022-12-08 10:50:00 +00:00
|
|
|
observers []chan string
|
2022-06-25 20:11:15 +01:00
|
|
|
}
|
|
|
|
|
2022-12-08 10:50:00 +00:00
|
|
|
// Register adds an observer channel to the channelList
|
|
|
|
func (p *publisher) Register(channel chan string) {
|
|
|
|
p.observers = append(p.observers, channel)
|
2022-06-25 20:11:15 +01:00
|
|
|
}
|
|
|
|
|
2022-08-22 22:29:30 +01:00
|
|
|
type event struct {
|
|
|
|
pdirty bool
|
|
|
|
mdirty bool
|
|
|
|
midi bool
|
|
|
|
ldirty bool
|
|
|
|
}
|
|
|
|
|
|
|
|
func newEvent() *event {
|
|
|
|
return &event{true, true, true, false}
|
|
|
|
}
|
|
|
|
|
2022-10-10 18:51:30 +01:00
|
|
|
func (e *event) Add(events ...string) {
|
|
|
|
for _, event := range events {
|
|
|
|
switch event {
|
|
|
|
case "pdirty":
|
|
|
|
e.pdirty = true
|
|
|
|
case "mdirty":
|
|
|
|
e.mdirty = true
|
|
|
|
case "midi":
|
|
|
|
e.midi = true
|
|
|
|
case "ldirty":
|
|
|
|
e.ldirty = true
|
|
|
|
}
|
|
|
|
log.Info(event, " added to the pooler")
|
2022-08-22 22:29:30 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-10 18:51:30 +01:00
|
|
|
func (e *event) Remove(events ...string) {
|
|
|
|
for _, event := range events {
|
|
|
|
switch event {
|
|
|
|
case "pdirty":
|
|
|
|
e.pdirty = false
|
|
|
|
case "mdirty":
|
|
|
|
e.mdirty = false
|
|
|
|
case "midi":
|
|
|
|
e.midi = false
|
|
|
|
case "ldirty":
|
|
|
|
e.ldirty = false
|
|
|
|
}
|
|
|
|
log.Info(event, " removed from the pooler")
|
2022-08-22 22:29:30 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-08 10:50:00 +00:00
|
|
|
var p *pooler
|
|
|
|
|
|
|
|
// pooler continuously polls the dirty parameters
|
2022-06-26 01:36:32 +01:00
|
|
|
// it is expected to be run in a goroutine
|
2022-06-26 01:41:05 +01:00
|
|
|
type pooler struct {
|
2022-12-08 10:50:00 +00:00
|
|
|
k *kind
|
|
|
|
run bool
|
|
|
|
event *event
|
|
|
|
pdirtyDone chan bool
|
|
|
|
mdirtyDone chan bool
|
|
|
|
midiDone chan bool
|
|
|
|
ldirtyDone chan bool
|
2022-06-26 01:41:05 +01:00
|
|
|
publisher
|
2022-06-25 20:11:15 +01:00
|
|
|
}
|
|
|
|
|
2022-07-09 19:01:58 +01:00
|
|
|
func newPooler(k *kind) *pooler {
|
2022-12-15 00:00:20 +00:00
|
|
|
p = &pooler{
|
|
|
|
k: k,
|
|
|
|
run: true,
|
|
|
|
event: newEvent(),
|
|
|
|
pdirtyDone: make(chan bool),
|
|
|
|
mdirtyDone: make(chan bool),
|
|
|
|
midiDone: make(chan bool),
|
|
|
|
ldirtyDone: make(chan bool),
|
2022-06-25 20:11:15 +01:00
|
|
|
}
|
2022-12-15 00:00:20 +00:00
|
|
|
go p.done()
|
|
|
|
go p.parameters()
|
|
|
|
go p.macrobuttons()
|
|
|
|
go p.midi()
|
|
|
|
go p.levels()
|
2022-06-25 20:11:15 +01:00
|
|
|
return p
|
|
|
|
}
|
|
|
|
|
2022-12-08 10:50:00 +00:00
|
|
|
func (p *pooler) done() {
|
|
|
|
for {
|
|
|
|
select {
|
|
|
|
case _, ok := <-p.pdirtyDone:
|
|
|
|
if !ok {
|
|
|
|
p.pdirtyDone = nil
|
|
|
|
}
|
|
|
|
case _, ok := <-p.mdirtyDone:
|
|
|
|
if !ok {
|
|
|
|
p.mdirtyDone = nil
|
|
|
|
}
|
|
|
|
case _, ok := <-p.midiDone:
|
|
|
|
if !ok {
|
|
|
|
p.midiDone = nil
|
|
|
|
}
|
|
|
|
case _, ok := <-p.ldirtyDone:
|
|
|
|
if !ok {
|
|
|
|
p.ldirtyDone = nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if p.pdirtyDone == nil && p.mdirtyDone == nil && p.midiDone == nil && p.ldirtyDone == nil {
|
|
|
|
for _, ch := range p.observers {
|
|
|
|
close(ch)
|
|
|
|
}
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-22 22:29:30 +01:00
|
|
|
func (p *pooler) parameters() {
|
2022-06-26 01:36:32 +01:00
|
|
|
for p.run {
|
2022-12-08 10:50:00 +00:00
|
|
|
pdirty, err := pdirty()
|
|
|
|
if err != nil {
|
|
|
|
close(p.pdirtyDone)
|
|
|
|
break
|
|
|
|
}
|
|
|
|
if p.event.pdirty && pdirty {
|
|
|
|
for _, ch := range p.observers {
|
|
|
|
ch <- "pdirty"
|
|
|
|
}
|
2022-06-25 20:11:15 +01:00
|
|
|
}
|
2022-08-22 22:29:30 +01:00
|
|
|
time.Sleep(33 * time.Millisecond)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *pooler) macrobuttons() {
|
|
|
|
for p.run {
|
2022-12-08 10:50:00 +00:00
|
|
|
mdirty, err := mdirty()
|
|
|
|
if err != nil {
|
|
|
|
close(p.mdirtyDone)
|
|
|
|
break
|
|
|
|
}
|
|
|
|
if p.event.mdirty && mdirty {
|
|
|
|
for _, ch := range p.observers {
|
|
|
|
ch <- "mdirty"
|
|
|
|
}
|
2022-06-25 20:11:15 +01:00
|
|
|
}
|
2022-06-30 23:20:15 +01:00
|
|
|
time.Sleep(33 * time.Millisecond)
|
2022-06-25 20:11:15 +01:00
|
|
|
}
|
|
|
|
}
|
2022-07-09 19:01:58 +01:00
|
|
|
|
2022-08-22 22:29:30 +01:00
|
|
|
func (p *pooler) midi() {
|
|
|
|
for p.run {
|
2022-12-08 10:50:00 +00:00
|
|
|
midi, err := getMidiMessage()
|
|
|
|
if err != nil {
|
|
|
|
close(p.midiDone)
|
|
|
|
break
|
|
|
|
}
|
|
|
|
if p.event.midi && midi {
|
|
|
|
for _, ch := range p.observers {
|
|
|
|
ch <- "midi"
|
|
|
|
}
|
2022-08-22 22:29:30 +01:00
|
|
|
}
|
|
|
|
time.Sleep(33 * time.Millisecond)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-09 19:01:58 +01:00
|
|
|
func (p *pooler) levels() {
|
|
|
|
_levelCache = newLevelCache(p.k)
|
|
|
|
|
|
|
|
for p.run {
|
2022-12-08 10:50:00 +00:00
|
|
|
ldirty, err := ldirty(p.k)
|
|
|
|
if err != nil {
|
|
|
|
close(p.ldirtyDone)
|
|
|
|
break
|
|
|
|
}
|
|
|
|
if p.event.ldirty && ldirty {
|
2022-07-18 16:23:15 +01:00
|
|
|
update(_levelCache.stripLevels, _levelCache.stripLevelsBuff, (2*p.k.PhysIn)+(8*p.k.VirtIn))
|
|
|
|
update(_levelCache.busLevels, _levelCache.busLevelsBuff, 8*p.k.NumBus())
|
2022-12-08 10:50:00 +00:00
|
|
|
for _, ch := range p.observers {
|
|
|
|
ch <- "ldirty"
|
|
|
|
}
|
2022-07-09 19:01:58 +01:00
|
|
|
}
|
|
|
|
time.Sleep(33 * time.Millisecond)
|
|
|
|
}
|
|
|
|
}
|