133 lines
2.6 KiB
Go
133 lines
2.6 KiB
Go
|
package audio
|
||
|
|
||
|
import (
|
||
|
"git.gammaspectra.live/S.O.N.G/Kirika/vector"
|
||
|
)
|
||
|
|
||
|
type float32Source struct {
|
||
|
BitDepth int
|
||
|
SampleRate int
|
||
|
Channels int
|
||
|
Blocks chan []float32
|
||
|
locked bool
|
||
|
}
|
||
|
|
||
|
func newFloat32Source(bitDepth, sampleRate, channels int) TypedSource[float32] {
|
||
|
return &float32Source{
|
||
|
BitDepth: bitDepth,
|
||
|
SampleRate: sampleRate,
|
||
|
Channels: channels,
|
||
|
Blocks: make(chan []float32),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (s *float32Source) Split(n int) []Source {
|
||
|
return Split[float32](s, n)
|
||
|
}
|
||
|
|
||
|
func (s *float32Source) New() TypedSource[float32] {
|
||
|
return newFloat32Source(s.BitDepth, s.SampleRate, s.Channels)
|
||
|
}
|
||
|
|
||
|
func (s *float32Source) GetBlocks() chan []float32 {
|
||
|
if s.Locked() {
|
||
|
return nil
|
||
|
}
|
||
|
s.locked = true
|
||
|
return s.Blocks
|
||
|
}
|
||
|
|
||
|
func (s *float32Source) Close() {
|
||
|
close(s.Blocks)
|
||
|
}
|
||
|
|
||
|
func (s *float32Source) GetSampleRate() int {
|
||
|
return s.SampleRate
|
||
|
}
|
||
|
|
||
|
func (s *float32Source) GetChannels() int {
|
||
|
return s.Channels
|
||
|
}
|
||
|
|
||
|
func (s *float32Source) GetBitDepth() int {
|
||
|
return s.BitDepth
|
||
|
}
|
||
|
|
||
|
func (s *float32Source) Locked() bool {
|
||
|
return s.locked
|
||
|
}
|
||
|
|
||
|
func (s *float32Source) Unlock() {
|
||
|
s.locked = false
|
||
|
}
|
||
|
|
||
|
func (s *float32Source) SwapBlocks(blocks chan []float32) chan []float32 {
|
||
|
oldBlocks := s.Blocks
|
||
|
s.Blocks = blocks
|
||
|
return oldBlocks
|
||
|
}
|
||
|
|
||
|
func (s *float32Source) GetFormat() SourceFormat {
|
||
|
return SourceFloat32
|
||
|
}
|
||
|
|
||
|
func (s *float32Source) ToFloat32() TypedSource[float32] {
|
||
|
return s
|
||
|
}
|
||
|
|
||
|
func (s *float32Source) ToInt16() TypedSource[int16] {
|
||
|
if s.Locked() {
|
||
|
return nil
|
||
|
}
|
||
|
source := newInt16Source(16, s.SampleRate, s.Channels)
|
||
|
|
||
|
go func() {
|
||
|
defer source.Close()
|
||
|
for block := range s.GetBlocks() {
|
||
|
source.IngestInt16(vector.Float32ToInt16(block), 16)
|
||
|
}
|
||
|
}()
|
||
|
|
||
|
return source
|
||
|
}
|
||
|
|
||
|
func (s *float32Source) ToInt32(bitDepth int) TypedSource[int32] {
|
||
|
if s.Locked() {
|
||
|
return nil
|
||
|
}
|
||
|
source := newInt32Source(bitDepth, s.SampleRate, s.Channels)
|
||
|
|
||
|
go func() {
|
||
|
defer source.Close()
|
||
|
for block := range s.GetBlocks() {
|
||
|
source.IngestInt32(vector.Float32ToInt32(block, bitDepth), bitDepth)
|
||
|
}
|
||
|
}()
|
||
|
|
||
|
return source
|
||
|
}
|
||
|
|
||
|
func (s *float32Source) IngestFloat32(buf []float32) {
|
||
|
s.Blocks <- buf
|
||
|
}
|
||
|
|
||
|
func (s *float32Source) IngestInt8(buf []int8, bitDepth int) {
|
||
|
s.Blocks <- vector.Int8ToFloat32(buf, bitDepth)
|
||
|
}
|
||
|
|
||
|
func (s *float32Source) IngestInt16(buf []int16, bitDepth int) {
|
||
|
s.Blocks <- vector.Int16ToFloat32(buf, bitDepth)
|
||
|
}
|
||
|
|
||
|
func (s *float32Source) IngestInt24(buf []byte, bitDepth int) {
|
||
|
s.Blocks <- vector.Int24ToFloat32(buf, bitDepth)
|
||
|
}
|
||
|
|
||
|
func (s *float32Source) IngestInt32(buf []int32, bitDepth int) {
|
||
|
s.Blocks <- vector.Int32ToFloat32(buf, bitDepth)
|
||
|
}
|
||
|
|
||
|
func (s *float32Source) IngestNative(buf []float32, bitDepth int) {
|
||
|
s.IngestFloat32(buf)
|
||
|
}
|