summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--player/player.go154
1 files changed, 150 insertions, 4 deletions
diff --git a/player/player.go b/player/player.go
index 5328475..f9b5335 100644
--- a/player/player.go
+++ b/player/player.go
@@ -34,10 +34,48 @@ func init() {
gst.Init(nil)
}
+type loadResult struct {
+ err error
+}
+
+type loadRequest struct {
+ cart uint
+ cut uint
+ response chan<- loadResult
+}
+
+type playResult struct {
+ err error
+}
+
+type playRequest struct {
+ response chan<- playResult
+}
+
+type pauseResult struct {
+ err error
+}
+
+type pauseRequest struct {
+ response chan<- pauseResult
+}
+
+type stopResult struct {
+ err error
+}
+
+type stopRequest struct {
+ response chan<- stopResult
+}
+
type Player struct {
- pipe *gst.Element
- bus *gst.Bus
- basepath string
+ pipe *gst.Element
+ bus *gst.Bus
+ basepath string
+ loadChan chan loadRequest
+ playChan chan playRequest
+ pauseChan chan pauseRequest
+ stopChan chan stopRequest
}
func (p *Player) onMessage(bus *gst.Bus, msg *gst.Message) {
@@ -65,16 +103,123 @@ func (p *Player) onMessage(bus *gst.Bus, msg *gst.Message) {
}
}
-func (p *Player) Play(cart, cut uint) (err error) {
+func (p *Player) load(cart, cut uint) (resp loadResult) {
filename := path.Join(p.basepath, fmt.Sprintf("%06d_%03d.wav", cart, cut))
p.pipe.SetProperty("uri", "file://"+filename)
+ p.pipe.SetState(gst.STATE_PAUSED)
+ return
+}
+
+func (p *Player) play() (resp playResult) {
p.pipe.SetState(gst.STATE_PLAYING)
return
}
+func (p *Player) pause() (resp pauseResult) {
+ p.pipe.SetState(gst.STATE_PAUSED)
+ return
+}
+
+func (p *Player) stop() (resp stopResult) {
+ p.pipe.SetState(gst.STATE_NULL)
+ return
+}
+
+func (p *Player) dispatchRequests() {
+ for {
+ select {
+ case req := <-p.loadChan:
+ req.response <- p.load(req.cart, req.cut)
+ case req := <-p.playChan:
+ req.response <- p.play()
+ case req := <-p.pauseChan:
+ req.response <- p.pause()
+ case req := <-p.stopChan:
+ req.response <- p.stop()
+ }
+ }
+}
+
+// *********************************************************
+// Public Interface
+
+type PlayerChan struct {
+ load chan<- loadRequest
+ play chan<- playRequest
+ pause chan<- pauseRequest
+ stop chan<- stopRequest
+}
+
+func (p *PlayerChan) Load(cart, cut uint) error {
+ resCh := make(chan loadResult)
+ req := loadRequest{}
+ req.cart = cart
+ req.cut = cut
+ req.response = resCh
+ p.load <- req
+
+ res := <-resCh
+ if res.err != nil {
+ return res.err
+ }
+ return nil
+}
+
+func (p *PlayerChan) Play() error {
+ resCh := make(chan playResult)
+ req := playRequest{}
+ req.response = resCh
+ p.play <- req
+
+ res := <-resCh
+ if res.err != nil {
+ return res.err
+ }
+ return nil
+}
+
+func (p *PlayerChan) Pause() error {
+ resCh := make(chan pauseResult)
+ req := pauseRequest{}
+ req.response = resCh
+ p.pause <- req
+
+ res := <-resCh
+ if res.err != nil {
+ return res.err
+ }
+ return nil
+}
+
+func (p *PlayerChan) Stop() error {
+ resCh := make(chan stopResult)
+ req := stopRequest{}
+ req.response = resCh
+ p.stop <- req
+
+ res := <-resCh
+ if res.err != nil {
+ return res.err
+ }
+ return nil
+}
+
+func (p *Player) GetInterface() *PlayerChan {
+ ch := &PlayerChan{}
+ ch.load = p.loadChan
+ ch.play = p.playChan
+ ch.pause = p.pauseChan
+ ch.stop = p.stopChan
+ return ch
+}
+
func NewPlayer(basepath string) (p *Player, err error) {
p = &Player{}
p.basepath = path.Clean(basepath)
+ p.loadChan = make(chan loadRequest)
+ p.playChan = make(chan playRequest)
+ p.pauseChan = make(chan pauseRequest)
+ p.stopChan = make(chan stopRequest)
if p.pipe, err = gst.ElementFactoryMake("playbin", "autoplay"); err != nil {
return
@@ -86,5 +231,6 @@ func NewPlayer(basepath string) (p *Player, err error) {
p.bus.AddSignalWatch()
p.bus.Connect("message", func(bus *gst.Bus, msg *gst.Message) { p.onMessage(bus, msg) })
+ go p.dispatchRequests()
return
}