[audio] Refactor audio driver to simplify interface

Signed-off-by: deadprogram <ron@hybridgroup.com>
This commit is contained in:
deadprogram 2016-05-24 21:01:16 -07:00
parent 151403aa9b
commit 31881bca81
5 changed files with 38 additions and 36 deletions

View File

@ -11,11 +11,11 @@ func main() {
gbot := gobot.NewGobot()
e := audio.NewAudioAdaptor("sound")
laser := audio.NewAudioDriver(e, "laser", nil)
laser := audio.NewAudioDriver(e, "laser", "./examples/laser.mp3")
work := func() {
gobot.Every(1*time.Second, func() {
laser.Sound("./examples/laser.mp3")
gobot.Every(2 * time.Second, func() {
laser.Play()
})
}

View File

@ -6,6 +6,8 @@ import (
"runtime"
"strings"
"testing"
"os"
"os/exec"
)
var errFunc = func(t *testing.T, message string) {
@ -33,3 +35,11 @@ func Refute(t *testing.T, a interface{}, b interface{}) {
a, reflect.TypeOf(a), b, reflect.TypeOf(b)))
}
}
func ExecCommand(command string, args ...string) *exec.Cmd {
cs := []string{"-test.run=TestHelperProcess", "--", command}
cs = append(cs, args...)
cmd := exec.Command(os.Args[0], cs...)
cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1"}
return cmd
}

View File

@ -2,7 +2,6 @@
package audio
import (
"os"
"os/exec"
"testing"
@ -49,16 +48,8 @@ func TestAudioAdaptorSoundWithNonexistingFilename(t *testing.T) {
gobottest.Assert(t, errors[0].Error(), "stat doesnotexist.mp3: no such file or directory")
}
func fakeExecCommand(command string, args ...string) *exec.Cmd {
cs := []string{"-test.run=TestHelperProcess", "--", command}
cs = append(cs, args...)
cmd := exec.Command(os.Args[0], cs...)
cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1"}
return cmd
}
func TestAudioAdaptorSoundWithValidMP3Filename(t *testing.T) {
execCommand = fakeExecCommand
execCommand = gobottest.ExecCommand
a := NewAudioAdaptor("tester")
defer func() { execCommand = exec.Command }()

View File

@ -3,7 +3,6 @@
package audio
import (
"fmt"
"github.com/hybridgroup/gobot"
"time"
)
@ -17,15 +16,15 @@ type AudioDriver struct {
halt chan bool
gobot.Eventer
gobot.Commander
queue chan string
filename string
}
func NewAudioDriver(a *AudioAdaptor, name string, queue chan string) *AudioDriver {
func NewAudioDriver(a *AudioAdaptor, name string, filename string) *AudioDriver {
d := &AudioDriver{
name: name,
connection: a,
interval: 500 * time.Millisecond,
queue: queue,
filename: filename,
halt: make(chan bool, 0),
Eventer: gobot.NewEventer(),
Commander: gobot.NewCommander(),
@ -35,6 +34,8 @@ func NewAudioDriver(a *AudioAdaptor, name string, queue chan string) *AudioDrive
func (d *AudioDriver) Name() string { return d.name }
func (d *AudioDriver) Filename() string { return d.filename }
func (d *AudioDriver) Connection() gobot.Connection {
return d.connection
}
@ -43,31 +44,18 @@ func (d *AudioDriver) Sound(fileName string) []error {
return d.Connection().(*AudioAdaptor).Sound(fileName)
}
func (d *AudioDriver) Play() []error {
return d.Sound(d.Filename())
}
func (d *AudioDriver) adaptor() *AudioAdaptor {
return d.Connection().(*AudioAdaptor)
}
func (d *AudioDriver) Start() (err []error) {
go d.serve(d.queue)
return
}
func (d *AudioDriver) Halt() (err []error) {
return
}
// Use semaphore to control how many sounds might be playing at a time
var sem = make(chan int, 1)
// See example at https://golang.org/doc/effective_go.html#concurrency
// Purpose: receive messages on channel, but throttle execution of playing
func (d *AudioDriver) serve(queue chan string) {
for req := range queue {
sem <- 1
go func(req string) {
fmt.Printf("Playing sound %v\n", req)
d.Sound(req)
<-sem
}(req)
}
}

View File

@ -4,14 +4,17 @@ package audio
import (
"testing"
"os/exec"
"github.com/hybridgroup/gobot/gobottest"
)
func TestAudioDriver(t *testing.T) {
d := NewAudioDriver(NewAudioAdaptor("conn"), "dev", nil)
d := NewAudioDriver(NewAudioAdaptor("conn"), "dev", "../../examples/laser.mp3")
gobottest.Assert(t, d.Name(), "dev")
gobottest.Assert(t, d.Filename(), "../../examples/laser.mp3")
gobottest.Assert(t, d.Connection().Name(), "conn")
gobottest.Assert(t, len(d.Start()), 0)
@ -20,8 +23,18 @@ func TestAudioDriver(t *testing.T) {
}
func TestAudioDriverSoundWithNoFilename(t *testing.T) {
d := NewAudioDriver(NewAudioAdaptor("conn"), "dev", nil)
d := NewAudioDriver(NewAudioAdaptor("conn"), "dev", "")
errors := d.Sound("")
gobottest.Assert(t, errors[0].Error(), "Requires filename for audio file.")
}
func TestAudioDriverSoundWithDefaultFilename(t *testing.T) {
execCommand = gobottest.ExecCommand
defer func() { execCommand = exec.Command }()
d := NewAudioDriver(NewAudioAdaptor("conn"), "dev", "../../examples/laser.mp3")
errors := d.Play()
gobottest.Assert(t, len(errors), 0)
}