116 lines
2.4 KiB
Go
116 lines
2.4 KiB
Go
package spdif
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"os/exec"
|
|
"path"
|
|
|
|
"git.nemunai.re/nemunaire/hathoris/sources"
|
|
)
|
|
|
|
type SPDIFSource struct {
|
|
processRec *exec.Cmd
|
|
processPlay *exec.Cmd
|
|
DeviceIn string
|
|
DeviceOut string
|
|
Bitrate int64
|
|
Channels int64
|
|
Format string
|
|
}
|
|
|
|
func init() {
|
|
if dirs, err := os.ReadDir("/sys/class/sound"); err == nil {
|
|
for _, dir := range dirs {
|
|
thisdir := path.Join("/sys/class/sound", dir.Name())
|
|
if s, err := os.Stat(thisdir); err == nil && s.IsDir() {
|
|
idfile := path.Join(thisdir, "id")
|
|
if fd, err := os.Open(idfile); err == nil {
|
|
if cnt, err := io.ReadAll(fd); err == nil && string(cnt) == "imxspdif\n" {
|
|
sources.SoundSources["imxspdif"] = &SPDIFSource{
|
|
DeviceIn: "imxspdif",
|
|
DeviceOut: "is31ap2121",
|
|
Bitrate: 48000,
|
|
Channels: 2,
|
|
Format: "S24_LE",
|
|
}
|
|
}
|
|
fd.Close()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func (s *SPDIFSource) GetName() string {
|
|
return "S/PDIF"
|
|
}
|
|
|
|
func (s *SPDIFSource) IsActive() bool {
|
|
return s.processRec != nil
|
|
}
|
|
|
|
func (s *SPDIFSource) IsEnabled() bool {
|
|
return s.processRec != nil
|
|
}
|
|
|
|
func (s *SPDIFSource) Enable() error {
|
|
if s.processRec != nil {
|
|
return fmt.Errorf("Already running")
|
|
}
|
|
if s.processPlay != nil {
|
|
s.processPlay.Process.Kill()
|
|
}
|
|
|
|
pipeR, pipeW, err := os.Pipe()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
s.processPlay = exec.Command("aplay", "-c", fmt.Sprintf("%d", s.Channels), "-D", "hw:"+s.DeviceOut, "--period-size=512", "-B0", "--buffer-size=512")
|
|
s.processPlay.Stdin = pipeR
|
|
if err := s.processPlay.Start(); err != nil {
|
|
return err
|
|
}
|
|
|
|
go func() {
|
|
err := s.processPlay.Wait()
|
|
if err != nil {
|
|
s.processPlay.Process.Kill()
|
|
pipeR.Close()
|
|
pipeW.Close()
|
|
}
|
|
|
|
s.processPlay = nil
|
|
}()
|
|
|
|
s.processRec = exec.Command("arecord", "-t", "wav", "-f", s.Format, fmt.Sprintf("-r%d", s.Bitrate), fmt.Sprintf("-c%d", s.Channels), "-D", "hw:"+s.DeviceIn, "-B0", "--buffer-size=512")
|
|
s.processRec.Stdout = pipeW
|
|
if err := s.processRec.Start(); err != nil {
|
|
s.processPlay.Process.Kill()
|
|
return err
|
|
}
|
|
|
|
go func() {
|
|
err := s.processRec.Wait()
|
|
if err != nil {
|
|
s.processRec.Process.Kill()
|
|
}
|
|
|
|
s.processRec = nil
|
|
}()
|
|
|
|
return nil
|
|
}
|
|
|
|
func (s *SPDIFSource) Disable() error {
|
|
if s.processRec != nil && s.processRec.Process != nil {
|
|
s.processRec.Process.Kill()
|
|
}
|
|
if s.processPlay != nil && s.processPlay.Process != nil {
|
|
s.processPlay.Process.Kill()
|
|
}
|
|
|
|
return nil
|
|
}
|