dndmusicbot/queue.go

112 lines
2.0 KiB
Go
Raw Normal View History

2022-11-18 12:29:39 +00:00
package main
import (
"log"
"github.com/faiface/beep"
"github.com/kataras/go-events"
discordspeaker "dndmusicbot/speaker"
)
type Ambiance struct {
Type string
URL string
}
func init() {
app.ambiance = new(Queue)
app.ambiance.Events = app.events
discordspeaker.Play(app.ambiance)
app.queue = new(Queue)
app.queue.Events = app.events
discordspeaker.Play(app.queue)
log.Println("queue.go done.")
}
type Queue struct {
streamers []beep.StreamSeekCloser
Events events.EventEmmiter
playing bool
}
func (q Queue) IsPlaying() bool {
return q.playing
}
func (q *Queue) Add(streamers ...beep.StreamSeekCloser) {
q.playing = true
q.streamers = append(q.streamers, streamers...)
}
func (q Queue) QLen() int {
return len(q.streamers)
}
func (q Queue) Len() int {
if len(q.streamers) > 0 {
return q.streamers[0].Len()
} else {
return 0
}
}
func (q Queue) Current() beep.StreamSeekCloser {
if len(q.streamers) > 0 {
return q.streamers[0]
} else {
return nil
}
}
func (q *Queue) Reset() {
q.playing = false
for _, stream := range q.streamers {
stream.Close()
}
q.streamers = nil
}
func (q *Queue) Stream(samples [][2]float64) (n int, ok bool) {
// We use the filled variable to track how many samples we've
// successfully filled already. We loop until all samples are filled.
filled := 0
for filled < len(samples) {
// There are no streamers in the queue, so we stream silence.
if len(q.streamers) == 0 {
for i := range samples[filled:] {
samples[i][0] = 0
samples[i][1] = 0
}
break
}
// We stream from the first streamer in the queue.
n, ok := q.streamers[0].Stream(samples[filled:])
// If it's drained, we pop it from the queue, thus continuing with
// the next streamer.
if !ok {
q.streamers = q.streamers[1:]
q.Events.Emit("song_over", nil)
}
// We update the number of filled samples.
filled += n
}
return len(samples), true
}
func (q *Queue) Err() error {
return nil
}
func (q *Queue) Position() int {
if len(q.streamers) > 0 {
return q.streamers[0].Position()
} else {
return 0
}
}