ace/lib/audiodriver/wavfifo.go

98 lines
2.1 KiB
Go
Raw Normal View History

2022-09-26 03:04:07 +00:00
package audiodriver
import (
"context"
"encoding/binary"
"io"
2022-09-27 04:34:57 +00:00
"time"
2022-09-26 03:04:07 +00:00
"github.com/pion/mediadevices/pkg/io/audio"
"github.com/pion/mediadevices/pkg/prop"
"github.com/pion/mediadevices/pkg/wave"
"github.com/sirupsen/logrus"
)
const (
DataChunkIDSize = 4
DataChunkSizeSize = 4
)
// BufferSize for pcm bytes
const BufferSize = 512
const BitsPerByte = 8
type WavFIFODriver struct {
2022-09-27 02:21:06 +00:00
PCM <-chan [BufferSize]byte
WaveHeader <-chan *WavHeader
2022-09-26 03:04:07 +00:00
closed <-chan struct{}
cancel func()
}
2022-09-27 02:21:06 +00:00
func New() *WavFIFODriver {
return &WavFIFODriver{}
2022-09-26 03:04:07 +00:00
}
func (w *WavFIFODriver) Open() error {
2022-09-27 02:21:06 +00:00
defer logrus.Debug("device opened")
2022-09-26 03:04:07 +00:00
ctx, cancel := context.WithCancel(context.Background())
w.closed = ctx.Done()
w.cancel = cancel
2022-09-27 02:21:06 +00:00
return nil
2022-09-26 03:04:07 +00:00
}
func (w *WavFIFODriver) Close() error {
defer w.cancel()
2022-09-27 02:21:06 +00:00
return nil
2022-09-26 03:04:07 +00:00
}
func (w *WavFIFODriver) Properties() []prop.Media {
2022-09-27 02:21:06 +00:00
waveHeader := <-w.WaveHeader
logrus.Debugf("wave header: %v", waveHeader)
2022-09-26 03:04:07 +00:00
return []prop.Media{
{
Audio: prop.Audio{
2022-09-27 02:21:06 +00:00
SampleRate: int(waveHeader.SampleRate),
ChannelCount: int(waveHeader.NumChannels),
Latency: waveHeader.GetLatnecy(),
2022-09-26 03:04:07 +00:00
IsFloat: false, // just 8bit or 16bit with qemu
IsBigEndian: false, // qemu should be little endian
IsInterleaved: true,
},
},
}
}
func (w *WavFIFODriver) AudioRecord(p prop.Media) (audio.Reader, error) {
2022-09-27 04:34:57 +00:00
a := wave.NewInt16Interleaved(wave.ChunkInfo{
Len: BufferSize / int(p.SampleSize/BitsPerByte),
Channels: p.ChannelCount,
SamplingRate: p.SampleRate,
})
2022-09-26 03:04:07 +00:00
reader := func() (wave.Audio, func(), error) {
select {
case <-w.closed:
return nil, func() {}, io.EOF
2022-09-27 02:21:06 +00:00
case pcmData, ok := <-w.PCM:
2022-09-26 06:54:32 +00:00
logrus.Debug("got %d bytes pcm data", len(pcmData))
2022-09-26 03:04:07 +00:00
if !ok {
return nil, func() {}, io.ErrClosedPipe
}
copy(a.Data, bytesTo16BitSamples(pcmData[:]))
2022-09-27 04:34:57 +00:00
case <-time.After(p.Latency):
2022-09-26 03:04:07 +00:00
}
2022-09-27 04:34:57 +00:00
return a, func() {}, nil
2022-09-26 03:04:07 +00:00
}
return audio.ReaderFunc(reader), nil
}
func bytesTo16BitSamples(b []byte) []int16 {
samples := make([]int16, 0)
for i := 0; i < len(b); i += 2 {
sample := binary.LittleEndian.Uint16(b[i : i+1])
samples = append(samples, int16(sample))
}
return samples
}