mirror of
https://github.com/pion/mediadevices.git
synced 2025-09-26 20:41:46 +08:00
90 lines
2.2 KiB
Go
90 lines
2.2 KiB
Go
package audio
|
|
|
|
import (
|
|
"errors"
|
|
|
|
"github.com/pion/mediadevices/pkg/wave"
|
|
)
|
|
|
|
var errUnsupported = errors.New("unsupported audio format")
|
|
|
|
// NewBuffer creates audio transform to buffer signal to have exact nSample samples.
|
|
func NewBuffer(nSamples int) TransformFunc {
|
|
var inBuff wave.Audio
|
|
|
|
return func(r Reader) Reader {
|
|
return ReaderFunc(func() (wave.Audio, func(), error) {
|
|
for {
|
|
if inBuff != nil && inBuff.ChunkInfo().Len >= nSamples {
|
|
break
|
|
}
|
|
|
|
buff, _, err := r.Read()
|
|
if err != nil {
|
|
return nil, func() {}, err
|
|
}
|
|
switch b := buff.(type) {
|
|
case *wave.Float32Interleaved:
|
|
ib, ok := inBuff.(*wave.Float32Interleaved)
|
|
if !ok || ib.Size.Channels != b.Size.Channels {
|
|
ib = wave.NewFloat32Interleaved(
|
|
wave.ChunkInfo{
|
|
SamplingRate: b.Size.SamplingRate,
|
|
Channels: b.Size.Channels,
|
|
Len: nSamples,
|
|
},
|
|
)
|
|
ib.Data = ib.Data[:0]
|
|
ib.Size.Len = 0
|
|
inBuff = ib
|
|
}
|
|
ib.Data = append(ib.Data, b.Data...)
|
|
ib.Size.Len += b.Size.Len
|
|
|
|
case *wave.Int16Interleaved:
|
|
ib, ok := inBuff.(*wave.Int16Interleaved)
|
|
if !ok || ib.Size.Channels != b.Size.Channels {
|
|
ib = wave.NewInt16Interleaved(
|
|
wave.ChunkInfo{
|
|
SamplingRate: b.Size.SamplingRate,
|
|
Channels: b.Size.Channels,
|
|
Len: nSamples,
|
|
},
|
|
)
|
|
ib.Data = ib.Data[:0]
|
|
ib.Size.Len = 0
|
|
inBuff = ib
|
|
}
|
|
ib.Data = append(ib.Data, b.Data...)
|
|
ib.Size.Len += b.Size.Len
|
|
|
|
default:
|
|
return nil, func() {}, errUnsupported
|
|
}
|
|
}
|
|
switch ib := inBuff.(type) {
|
|
case *wave.Int16Interleaved:
|
|
ibCopy := *ib
|
|
ibCopy.Size.Len = nSamples
|
|
n := nSamples * ib.Size.Channels
|
|
ibCopy.Data = make([]int16, n)
|
|
copy(ibCopy.Data, ib.Data)
|
|
ib.Data = ib.Data[n:]
|
|
ib.Size.Len -= nSamples
|
|
return &ibCopy, func() {}, nil
|
|
|
|
case *wave.Float32Interleaved:
|
|
ibCopy := *ib
|
|
ibCopy.Size.Len = nSamples
|
|
n := nSamples * ib.Size.Channels
|
|
ibCopy.Data = make([]float32, n)
|
|
copy(ibCopy.Data, ib.Data)
|
|
ib.Data = ib.Data[n:]
|
|
ib.Size.Len -= nSamples
|
|
return &ibCopy, func() {}, nil
|
|
}
|
|
return nil, func() {}, errUnsupported
|
|
})
|
|
}
|
|
}
|