Make calls command concurrent, also update README

This commit is contained in:
Daniel 2024-08-05 14:42:38 -04:00
parent 0f3684223a
commit 2bfc87a36d
3 changed files with 59 additions and 13 deletions

View file

@ -1,3 +1,10 @@
# stillbox # stillbox
A Golang scanner call server, with the Calls webapp. A Golang scanner call server (`gordio`), with the Calls webapp.
**NOTE**
If this message is still here, the database schema *initial migration* and protobuf definitions are **still subject to change**.
Once `gordio` is actually usable (but not necessarily feature-complete), I will remove this note, and start using DB migrations and
protobuf best practices (i.e. not changing field numbers).

View file

@ -2,6 +2,7 @@ package main
import ( import (
"fmt" "fmt"
"log"
"time" "time"
"dynatron.me/x/go-minimp3" "dynatron.me/x/go-minimp3"
@ -9,17 +10,24 @@ import (
) )
type Player struct { type Player struct {
c chan playReq
ctx *oto.Context ctx *oto.Context
sampleRate int sampleRate int
channels int channels int
} }
func NewPlayer() *Player { func NewPlayer() *Player {
p := &Player{} p := &Player{
c: make(chan playReq, 256),
}
return p return p
} }
func (p *Player) Queue() int {
return len(p.c)
}
func (p *Player) initOto(samp, channels int) error { func (p *Player) initOto(samp, channels int) error {
if samp != p.sampleRate || channels != p.channels { if samp != p.sampleRate || channels != p.channels {
if p.ctx != nil { if p.ctx != nil {
@ -64,15 +72,45 @@ func (p *Player) playMP3(audio []byte) error {
return nil return nil
} }
func (p *Player) Play(audio []byte, mimeType string) error { type playReq struct {
switch mimeType { audio []byte
mimeType string
}
func (p *Player) Play(audio []byte, mimeType string) {
p.c <- playReq{audio, mimeType}
}
func (p *Player) play(req playReq) error {
switch req.mimeType {
case "audio/mpeg": case "audio/mpeg":
return p.playMP3(audio) return p.playMP3(req.audio)
case "audio/wav": case "audio/wav":
panic("wav not implemented yet") panic("wav not implemented yet")
default: default:
return fmt.Errorf("unknown format %s", mimeType) return fmt.Errorf("unknown format %s", req.mimeType)
}
}
func (p *Player) Go(done <-chan struct{}) {
for {
select {
case <-done:
close(p.c)
p.ctx.Close()
return
case r, ok := <-p.c:
if !ok {
p.ctx.Close()
return
}
fmt.Printf("> [Q: %d]\r", p.Queue())
err := p.play(r)
fmt.Printf("\033[2K")
if err != nil {
log.Println(err)
}
}
} }
return nil
} }

View file

@ -81,6 +81,10 @@ func main() {
log.Printf("connected") log.Printf("connected")
done := make(chan struct{}) done := make(chan struct{})
playDone := make(chan struct{})
go play.Go(playDone)
defer close(playDone)
go func() { go func() {
defer close(done) defer close(done)
@ -101,11 +105,8 @@ func main() {
switch v := m.ToClientMessage.(type) { switch v := m.ToClientMessage.(type) {
case *pb.Message_Call: case *pb.Message_Call:
log.Printf("call tg %d", v.Call.Talkgroup) log.Printf("call tg %d [Q: %d]", v.Call.Talkgroup, play.Queue())
err := play.Play(v.Call.Audio, v.Call.AudioType) play.Play(v.Call.Audio, v.Call.AudioType)
if err != nil {
log.Println(err)
}
case *pb.Message_Notification: case *pb.Message_Notification:
log.Println(v.Notification.Msg) log.Println(v.Notification.Msg)
default: default: