debug needed

This commit is contained in:
Sense T
2022-09-26 03:04:07 +00:00
parent 0ce8374276
commit 4c80f8a25e
39 changed files with 8233 additions and 0 deletions

131
lib/audiodriver/wavfifo.go Normal file
View File

@@ -0,0 +1,131 @@
package audiodriver
import (
"context"
"encoding/binary"
"errors"
"io"
"os"
"time"
"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 {
FIFOFile string
f *os.File
waveHeader *WavHeader
closed <-chan struct{}
cancel func()
}
func New(fifoname string) *WavFIFODriver {
return &WavFIFODriver{
FIFOFile: fifoname,
}
}
func (w *WavFIFODriver) Open() error {
ctx, cancel := context.WithCancel(context.Background())
w.closed = ctx.Done()
w.cancel = cancel
f, err := os.Open(w.FIFOFile)
if err != nil {
return err
}
w.f = f
w.waveHeader = &WavHeader{}
return w.waveHeader.Parse(f)
}
func (w *WavFIFODriver) Close() error {
defer w.cancel()
return w.f.Close()
}
func (w *WavFIFODriver) Properties() []prop.Media {
return []prop.Media{
{
Audio: prop.Audio{
SampleRate: int(w.waveHeader.SampleRate),
ChannelCount: int(w.waveHeader.NumChannels),
Latency: time.Millisecond * time.Duration(BufferSize) / time.Duration(w.waveHeader.SampleRate) / time.Duration(w.waveHeader.NumChannels),
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) {
offset := FmtHeaderOffset + FmtHeaderIDSize + FmtHeaderChunkSizeSize + int64(w.waveHeader.Size) + DataChunkIDSize + DataChunkSizeSize
if _, err := w.f.Seek(
offset,
io.SeekStart,
); err != nil {
return nil, err
}
var pcm <-chan [BufferSize]byte
go func() {
samples := make(chan [BufferSize]byte, BufferSize)
defer close(samples)
pcm = samples
for {
var b [BufferSize]byte
if _, err := w.f.Read(b[:]); err != nil {
if errors.Is(err, io.EOF) {
return
}
logrus.Errorf("read audio stream error: %v", err)
continue
}
samples <- b
}
}()
reader := func() (wave.Audio, func(), error) {
select {
case <-w.closed:
return nil, func() {}, io.EOF
case pcmData, ok := <-pcm:
if !ok {
return nil, func() {}, io.ErrClosedPipe
}
a := wave.NewInt16Interleaved(wave.ChunkInfo{
Len: BufferSize / int(w.waveHeader.BitsPerSample/BitsPerByte),
Channels: p.ChannelCount,
SamplingRate: p.SampleRate,
})
copy(a.Data, bytesTo16BitSamples(pcmData[:]))
return a, func() {}, nil
}
}
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
}

View File

@@ -0,0 +1,85 @@
package audiodriver
import (
"bytes"
"encoding/binary"
"errors"
"io"
)
// Skip riff header and `fmt ` just 16 bytes
const (
FmtHeaderOffset int64 = 0x0c
FmtHeaderIDSize int64 = 4
FmtHeaderChunkSizeSize int64 = 4
)
type WavHeader struct {
ID [4]byte
Size uint32
AudioFormat uint16
NumChannels uint16
SampleRate uint32
ByteRate uint32
BlockAlign uint16
BitsPerSample uint16
}
func (w *WavHeader) Parse(f io.ReadSeeker) error {
if _, err := f.Seek(FmtHeaderOffset, io.SeekStart); err != nil {
return err
}
var id [4]byte
if _, err := f.Read(id[:]); err != nil {
return err
}
if bytes.Equal(id[:], []byte{'f', 'm', 't', '0'}[:]) {
return errors.New("bad header")
}
w.ID = id
var size [4]byte
if _, err := f.Read(size[:]); err != nil {
return err
}
w.Size = binary.LittleEndian.Uint32(size[:])
var af [2]byte
if _, err := f.Read(af[:]); err != nil {
return err
}
w.AudioFormat = binary.LittleEndian.Uint16(af[:])
var nc [2]byte
if _, err := f.Read(nc[:]); err != nil {
return err
}
w.NumChannels = binary.LittleEndian.Uint16(nc[:])
var sr [4]byte
if _, err := f.Read(sr[:]); err != nil {
return err
}
w.SampleRate = binary.LittleEndian.Uint32(sr[:])
var br [4]byte
if _, err := f.Read(br[:]); err != nil {
return err
}
w.ByteRate = binary.LittleEndian.Uint32(br[:])
var ba [2]byte
if _, err := f.Read(ba[:]); err != nil {
return err
}
w.BlockAlign = binary.LittleEndian.Uint16(ba[:])
var bps [2]byte
if _, err := f.Read(ba[:]); err != nil {
return err
}
w.BitsPerSample = binary.LittleEndian.Uint16(bps[:])
return nil
}