bananenkeyboard/Pi/main.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]
}
}