190 lines
3.7 KiB
Go
190 lines
3.7 KiB
Go
package main
|
|
|
|
import (
|
|
"github.com/faiface/beep"
|
|
"github.com/faiface/beep/effects"
|
|
"github.com/faiface/beep/speaker"
|
|
"github.com/faiface/beep/wav"
|
|
"github.com/tarm/serial"
|
|
"log"
|
|
"math"
|
|
"os"
|
|
"sync"
|
|
"time"
|
|
"fmt"
|
|
)
|
|
|
|
var sounds = []*beep.Buffer{
|
|
mustLoadStream("./default/001.wav"),
|
|
mustLoadStream("./default/002.wav"),
|
|
mustLoadStream("./default/003.wav"),
|
|
mustLoadStream("./default/004.wav"),
|
|
mustLoadStream("./default/005.wav"),
|
|
mustLoadStream("./default/006.wav"),
|
|
mustLoadStream("./default/007.wav"),
|
|
mustLoadStream("./default/008.wav"),
|
|
}
|
|
|
|
var counter int
|
|
|
|
func mustLoadStream(p string) *beep.Buffer {
|
|
counter++
|
|
log.Println("Loading: /media/usb/00" + fmt.Sprintf("%d", counter) + ".wav")
|
|
f, err := os.Open("/media/usb/00" + fmt.Sprintf("%d", counter) + ".wav")
|
|
if err != nil {
|
|
log.Println("Failed: /media/usb/00" + fmt.Sprintf("%d", counter) + ".wav")
|
|
log.Println("Loading " + p)
|
|
f, err = os.Open(p)
|
|
if err != nil {
|
|
// log.Fatal(err)
|
|
return nil
|
|
}
|
|
}
|
|
defer f.Close()
|
|
|
|
streamer, format, err := wav.Decode(f)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
defer streamer.Close()
|
|
|
|
newFormat := format
|
|
// newFormat.SampleRate = format.SampleRate / 4
|
|
// newFormat.SampleRate = format.SampleRate / 2
|
|
newFormat.SampleRate = format.SampleRate
|
|
resample := beep.Resample(4, format.SampleRate, newFormat.SampleRate, streamer)
|
|
|
|
buffer := beep.NewBuffer(newFormat)
|
|
buffer.Append(resample)
|
|
|
|
return buffer
|
|
}
|
|
|
|
type soundWorker struct {
|
|
buffer *beep.Buffer
|
|
ctrl *beep.Ctrl
|
|
volume *effects.Volume
|
|
isRunning bool
|
|
isStopping bool
|
|
forceEnd bool
|
|
mtx sync.Mutex
|
|
}
|
|
|
|
func (w *soundWorker) End() {
|
|
w.isStopping = true
|
|
w.mtx.Lock()
|
|
defer w.mtx.Unlock()
|
|
|
|
i := 1
|
|
for w.isRunning {
|
|
if i >= 80 || w.forceEnd {
|
|
break
|
|
}
|
|
|
|
w.volume.Volume = float64(1) / math.Pow(10, float64(i))
|
|
i++
|
|
}
|
|
w.isRunning = false
|
|
w.isStopping = false
|
|
w.forceEnd = false
|
|
w.ctrl.Paused = true
|
|
}
|
|
|
|
func (w *soundWorker) Start() {
|
|
if w.isRunning {
|
|
w.forceEnd = true
|
|
}
|
|
|
|
w.mtx.Lock()
|
|
defer w.mtx.Unlock()
|
|
|
|
w.isRunning = true
|
|
// w.ctrl.Streamer.(beep.StreamSeeker).Seek(0)
|
|
// log.Println("Buffer Start: " + fmt.Sprintf("%d", w.ctrl.Streamer))
|
|
w.ctrl.Streamer = beep.Seq(w.buffer.Streamer(0, w.buffer.Len()), beep.Silence(-1))
|
|
// w.ctrl.Streamer = w.buffer.Streamer(0, w.buffer.Len())
|
|
w.volume.Volume = 1
|
|
w.ctrl.Paused = false
|
|
}
|
|
|
|
func main() {
|
|
config := &serial.Config{
|
|
Name: "/dev/ttyS0",
|
|
Baud: 115200,
|
|
Size: 8,
|
|
}
|
|
|
|
stream, err := serial.OpenPort(config)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
format := sounds[0].Format()
|
|
// if err := speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/100)); err != nil {
|
|
if err := speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/100)); err != nil {
|
|
return
|
|
}
|
|
|
|
var soundWorkers []*soundWorker
|
|
|
|
mixer := beep.Mixer{}
|
|
for _, buffer := range sounds {
|
|
if buffer == nil {
|
|
continue
|
|
}
|
|
c := &beep.Ctrl{
|
|
// Streamer: buffer.Streamer(0, buffer.Len()),
|
|
Streamer: beep.Seq(buffer.Streamer(0, buffer.Len()), beep.Silence(-1)),
|
|
Paused: true,
|
|
}
|
|
|
|
volume := &effects.Volume{
|
|
Streamer: c,
|
|
// Streamer: beep.Seq(c, beep.Silence(-1)),
|
|
Base: 2,
|
|
Volume: 1,
|
|
}
|
|
|
|
mixer.Add(volume)
|
|
|
|
soundWorkers = append(soundWorkers, &soundWorker{
|
|
buffer: buffer,
|
|
ctrl: c,
|
|
volume: volume,
|
|
})
|
|
}
|
|
|
|
speaker.Play(&mixer)
|
|
|
|
c := make(chan byte)
|
|
|
|
// List das byte von serial ein und prueft die bits
|
|
go func() {
|
|
for b := range c {
|
|
for i, w := range soundWorkers {
|
|
setStop := (b&(1<<i))>>i == 0
|
|
|
|
if w.isRunning && !w.isStopping && setStop {
|
|
w.End()
|
|
}
|
|
|
|
if !w.isRunning && !setStop {
|
|
w.Start()
|
|
}
|
|
}
|
|
}
|
|
}()
|
|
|
|
// List das byte ein
|
|
for {
|
|
buf := make([]byte, 1)
|
|
_, err := stream.Read(buf)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
c <- buf[0]
|
|
}
|
|
|
|
}
|