Add int32 stereo/mono converters
This commit is contained in:
parent
09f3cf3b56
commit
1d2effea75
|
@ -214,14 +214,24 @@ func (f StereoFilter) Process(source audio.Source) audio.Source {
|
|||
return source
|
||||
}
|
||||
|
||||
//TODO: make this for int16 and int32
|
||||
outSource := audio.NewSource[float32](source.GetBitDepth(), source.GetSampleRate(), 2)
|
||||
outSource := audio.NewTypedInterface(source, source.GetBitDepth(), source.GetSampleRate(), 2)
|
||||
|
||||
go func() {
|
||||
defer outSource.Close()
|
||||
for block := range source.ToFloat32().GetBlocks() {
|
||||
outSource.IngestFloat32(vector.MultipleChannelsToStereo(block, source.GetChannels()))
|
||||
if _, ok := source.(audio.TypedSource[int32]); ok {
|
||||
for block := range source.ToInt32(source.GetBitDepth()).GetBlocks() {
|
||||
outSource.IngestInt32(vector.MultipleChannelsToStereoInt32(block, source.GetChannels()), source.GetBitDepth())
|
||||
}
|
||||
} else if _, ok = source.(audio.TypedSource[int16]); ok {
|
||||
for block := range source.ToInt32(source.GetBitDepth()).GetBlocks() {
|
||||
outSource.IngestInt32(vector.MultipleChannelsToStereoInt32(block, source.GetChannels()), source.GetBitDepth())
|
||||
}
|
||||
} else {
|
||||
for block := range source.ToFloat32().GetBlocks() {
|
||||
outSource.IngestFloat32(vector.MultipleChannelsToStereoFloat32(block, source.GetChannels()))
|
||||
}
|
||||
}
|
||||
|
||||
}()
|
||||
|
||||
return outSource
|
||||
|
@ -235,14 +245,24 @@ func (f MonoFilter) Process(source audio.Source) audio.Source {
|
|||
return source
|
||||
}
|
||||
|
||||
//TODO: make this for int16 and int32
|
||||
outSource := audio.NewSource[float32](source.GetBitDepth(), source.GetSampleRate(), 1)
|
||||
outSource := audio.NewTypedInterface(source, source.GetBitDepth(), source.GetSampleRate(), 1)
|
||||
|
||||
go func() {
|
||||
defer outSource.Close()
|
||||
for block := range source.ToFloat32().GetBlocks() {
|
||||
outSource.IngestFloat32(vector.MultipleChannelsToMono(block, source.GetChannels()))
|
||||
if _, ok := source.(audio.TypedSource[int32]); ok {
|
||||
for block := range source.ToInt32(source.GetBitDepth()).GetBlocks() {
|
||||
outSource.IngestInt32(vector.MultipleChannelsToMonoInt32(block, source.GetChannels()), source.GetBitDepth())
|
||||
}
|
||||
} else if _, ok = source.(audio.TypedSource[int16]); ok {
|
||||
for block := range source.ToInt32(source.GetBitDepth()).GetBlocks() {
|
||||
outSource.IngestInt32(vector.MultipleChannelsToMonoInt32(block, source.GetChannels()), source.GetBitDepth())
|
||||
}
|
||||
} else {
|
||||
for block := range source.ToFloat32().GetBlocks() {
|
||||
outSource.IngestFloat32(vector.MultipleChannelsToMonoFloat32(block, source.GetChannels()))
|
||||
}
|
||||
}
|
||||
|
||||
}()
|
||||
|
||||
return outSource
|
||||
|
|
|
@ -38,12 +38,12 @@ func NewAnalyzerChannel(source audio.Source, err error) (audio.Source, AnalyzerC
|
|||
defer close(channel)
|
||||
|
||||
if _, ok := sources[1].(audio.TypedSource[float32]); ok {
|
||||
for block := range sources[1].ToInt32(32).GetBlocks() {
|
||||
for block := range sources[1].ToInt32(source.GetBitDepth()).GetBlocks() {
|
||||
channel <- &AnalyzerPacket{
|
||||
Samples: block,
|
||||
Channels: source.GetChannels(),
|
||||
SampleRate: source.GetSampleRate(),
|
||||
BitDepth: 32,
|
||||
BitDepth: source.GetBitDepth(),
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -53,6 +53,30 @@ func Split[T AllowedSourceTypes](s TypedSource[T], n int) (sources []Source) {
|
|||
return
|
||||
}
|
||||
|
||||
func NewTypedInterface(s Source, bitDepth, sampleRate, channels int) Source {
|
||||
if _, ok := s.(TypedSource[float32]); ok {
|
||||
return newFloat32Source(bitDepth, sampleRate, channels)
|
||||
} else if _, ok = s.(TypedSource[int16]); ok {
|
||||
return newInt16Source(bitDepth, sampleRate, channels)
|
||||
} else if _, ok = s.(TypedSource[int32]); ok {
|
||||
return newInt32Source(bitDepth, sampleRate, channels)
|
||||
} else {
|
||||
return newFloat32Source(bitDepth, sampleRate, channels)
|
||||
}
|
||||
}
|
||||
|
||||
func NewInterface(s Source) Source {
|
||||
if f32Source, ok := s.(TypedSource[float32]); ok {
|
||||
return f32Source.New()
|
||||
} else if i16Source, ok := s.(TypedSource[int16]); ok {
|
||||
return i16Source.New()
|
||||
} else if i32Source, ok := s.(TypedSource[int32]); ok {
|
||||
return i32Source.New()
|
||||
} else {
|
||||
return s.ToFloat32().New()
|
||||
}
|
||||
}
|
||||
|
||||
func GetBlocksInterface(s Source) interface{} {
|
||||
if f32Source, ok := s.(TypedSource[float32]); ok {
|
||||
return f32Source.GetBlocks()
|
||||
|
|
|
@ -23,8 +23,29 @@ void audio_multiple_channels_to_mono(float* restrict buffer, size_t buffer_len,
|
|||
}
|
||||
}
|
||||
|
||||
void audio_multiple_channels_to_mono_int32(int32_t* restrict buffer, size_t buffer_len, int32_t* restrict out, int channels) {
|
||||
int64_t s;
|
||||
switch(channels) {
|
||||
case 1:
|
||||
memcpy(out, buffer, sizeof(int32_t) * buffer_len);
|
||||
break;
|
||||
case 2:
|
||||
for (int i = 0; i < buffer_len; i += 2){
|
||||
out[i/2] = (int32_t)((((int64_t)buffer[i]) + ((int64_t)buffer[i+1])) / 2);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
for (int i = 0; i < buffer_len; i += channels){
|
||||
s = buffer[i];
|
||||
for (int j = 1; j < channels; ++j) {
|
||||
s += buffer[i + j];
|
||||
}
|
||||
out[i/channels] = (int32_t)(s / channels);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void audio_multiple_channels_to_stereo(float* restrict buffer, size_t buffer_len, float* restrict out, int channels) {
|
||||
float f;
|
||||
int samples = 0;
|
||||
float surroundMix = 1 / sqrt(2);
|
||||
switch(channels) {
|
||||
|
@ -53,6 +74,7 @@ void audio_multiple_channels_to_stereo(float* restrict buffer, size_t buffer_len
|
|||
int C = i+2;
|
||||
int RL = i+3;
|
||||
int RR = i+4;
|
||||
//TODO: this is wrong
|
||||
out[samples*2] = buffer[FL] + surroundMix * buffer[C] + surroundMix * buffer[RL];
|
||||
out[samples*2+1] = buffer[FR] + surroundMix * buffer[C] + surroundMix * buffer[RR];
|
||||
++samples;
|
||||
|
@ -65,6 +87,7 @@ void audio_multiple_channels_to_stereo(float* restrict buffer, size_t buffer_len
|
|||
int LFE = i+3;
|
||||
int RL = i+4;
|
||||
int RR = i+5;
|
||||
//TODO: this is wrong
|
||||
out[samples*2] = buffer[FL] + surroundMix * buffer[C] + surroundMix * buffer[RL];
|
||||
out[samples*2+1] = buffer[FR] + surroundMix * buffer[C] + surroundMix * buffer[RR];
|
||||
++samples;
|
||||
|
@ -79,6 +102,62 @@ void audio_multiple_channels_to_stereo(float* restrict buffer, size_t buffer_len
|
|||
}
|
||||
}
|
||||
|
||||
void audio_multiple_channels_to_stereo_int32(int32_t* restrict buffer, size_t buffer_len, int32_t* restrict out, int channels) {
|
||||
int samples = 0;
|
||||
float surroundMix = 1 / sqrt(2);
|
||||
switch(channels) {
|
||||
case 1: //mono, duplicate channels
|
||||
for (int i = 0; i < buffer_len; i++){
|
||||
out[i*2] = buffer[i];
|
||||
out[i*2+1] = buffer[i];
|
||||
}
|
||||
break;
|
||||
case 2: //copy
|
||||
memcpy(out, buffer, sizeof(int32_t) * buffer_len);
|
||||
break;
|
||||
case 3: //2.1, FL, FR, LFE
|
||||
for (int i = 0; i < buffer_len; i += 3){
|
||||
int FL = i;
|
||||
int FR = i+1;
|
||||
int LFE = i+2;
|
||||
out[samples*2] = buffer[FL];
|
||||
out[samples*2+1] = buffer[FR];
|
||||
++samples;
|
||||
}
|
||||
case 5: //5.0, FL, FR, FC, RL, RR
|
||||
for (int i = 0; i < buffer_len; i += 5){
|
||||
int FL = i;
|
||||
int FR = i+1;
|
||||
int C = i+2;
|
||||
int RL = i+3;
|
||||
int RR = i+4;
|
||||
//TODO: this is wrong
|
||||
out[samples*2] = ((int64_t)buffer[FL]) + (int64_t)(surroundMix * buffer[C] + surroundMix * buffer[RL]);
|
||||
out[samples*2+1] = ((int64_t)buffer[FR]) + (int64_t)(surroundMix * buffer[C] + surroundMix * buffer[RR]);
|
||||
++samples;
|
||||
}
|
||||
case 6: //5.1, FL, FR, FC, LFE, RL, RR
|
||||
for (int i = 0; i < buffer_len; i += 6){
|
||||
int FL = i;
|
||||
int FR = i+1;
|
||||
int C = i+2;
|
||||
int LFE = i+3;
|
||||
int RL = i+4;
|
||||
int RR = i+5;
|
||||
//TODO: this is wrong
|
||||
out[samples*2] = ((int64_t)buffer[FL]) + (int64_t)(surroundMix * buffer[C] + surroundMix * buffer[RL]);
|
||||
out[samples*2+1] = ((int64_t)buffer[FR]) + (int64_t)(surroundMix * buffer[C] + surroundMix * buffer[RR]);
|
||||
++samples;
|
||||
}
|
||||
break;
|
||||
default: //no known formula, just take stereo out of it
|
||||
for (int i = 0; i < buffer_len; i += channels){
|
||||
out[samples*2] = buffer[i];
|
||||
out[samples*2+1] = buffer[i+1];
|
||||
++samples;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void audio_int32_to_int16(int32_t* restrict data, size_t data_len, int16_t* restrict buffer, int bitDepth){
|
||||
switch(bitDepth) {
|
||||
|
|
|
@ -11,26 +11,46 @@ import (
|
|||
"unsafe"
|
||||
)
|
||||
|
||||
// MultipleChannelsToMono bring any number of channels to mono, equally weighted, reusing buffer backwards
|
||||
func MultipleChannelsToMono(buffer []float32, channels int) (buf []float32) {
|
||||
// MultipleChannelsToMonoFloat32 bring any number of channels to mono, equally weighted
|
||||
func MultipleChannelsToMonoFloat32(buffer []float32, channels int) (buf []float32) {
|
||||
buf = make([]float32, len(buffer)/channels)
|
||||
C.audio_multiple_channels_to_mono((*C.float)(&buffer[0]), C.size_t(len(buffer)), (*C.float)(&buf[0]), C.int(channels))
|
||||
return
|
||||
}
|
||||
|
||||
// MultipleChannelsToStereo bring any number of channels to stereo, using downmix formulas when necessary
|
||||
func MultipleChannelsToStereo(buffer []float32, channels int) (buf []float32) {
|
||||
// MultipleChannelsToStereoFloat32 bring any number of channels to stereo, using downmix formulas when necessary
|
||||
func MultipleChannelsToStereoFloat32(buffer []float32, channels int) (buf []float32) {
|
||||
buf = make([]float32, (len(buffer)/channels)*2)
|
||||
C.audio_multiple_channels_to_stereo((*C.float)(&buffer[0]), C.size_t(len(buffer)), (*C.float)(&buf[0]), C.int(channels))
|
||||
return
|
||||
}
|
||||
|
||||
// MultipleChannelsToMonoInt32 bring any number of channels to mono, equally weighted
|
||||
func MultipleChannelsToMonoInt32(buffer []int32, channels int) (buf []int32) {
|
||||
buf = make([]int32, len(buffer)/channels)
|
||||
C.audio_multiple_channels_to_mono_int32((*C.int32_t)(&buffer[0]), C.size_t(len(buffer)), (*C.int32_t)(&buf[0]), C.int(channels))
|
||||
return
|
||||
}
|
||||
|
||||
// MultipleChannelsToStereoInt32 bring any number of channels to stereo, using downmix formulas when necessary
|
||||
func MultipleChannelsToStereoInt32(buffer []int32, channels int) (buf []int32) {
|
||||
buf = make([]int32, (len(buffer)/channels)*2)
|
||||
C.audio_multiple_channels_to_stereo_int32((*C.int32_t)(&buffer[0]), C.size_t(len(buffer)), (*C.int32_t)(&buf[0]), C.int(channels))
|
||||
return
|
||||
}
|
||||
|
||||
func Int32ToInt16(data []int32, bitDepth int) (buf []int16) {
|
||||
buf = make([]int16, len(data))
|
||||
C.audio_int32_to_int16((*C.int32_t)(&data[0]), C.size_t(len(data)), (*C.int16_t)(unsafe.Pointer(&buf[0])), C.int(bitDepth))
|
||||
return
|
||||
}
|
||||
|
||||
func Int16ToInt32(data []int32, bitDepth int) (buf []int16) {
|
||||
buf = make([]int16, len(data))
|
||||
C.audio_int32_to_int16((*C.int32_t)(&data[0]), C.size_t(len(data)), (*C.int16_t)(unsafe.Pointer(&buf[0])), C.int(bitDepth))
|
||||
return
|
||||
}
|
||||
|
||||
func Int32ToBytes(data []int32, bitDepth int) (buf []byte) {
|
||||
buf = make([]byte, len(data)*(bitDepth/8))
|
||||
C.audio_int32_to_bytes((*C.int32_t)(&data[0]), C.size_t(len(data)), (*C.int8_t)(unsafe.Pointer(&buf[0])), C.int(bitDepth))
|
||||
|
|
|
@ -7,6 +7,10 @@ void audio_multiple_channels_to_mono(float* buffer, size_t buffer_len, float* ou
|
|||
|
||||
void audio_multiple_channels_to_stereo(float* buffer, size_t buffer_len, float* out, int channels);
|
||||
|
||||
void audio_multiple_channels_to_mono_int32(int32_t* buffer, size_t buffer_len, int32_t* out, int channels);
|
||||
|
||||
void audio_multiple_channels_to_stereo_int32(int32_t* buffer, size_t buffer_len, int32_t* out, int channels);
|
||||
|
||||
void audio_int32_to_int16(int32_t* restrict data, size_t data_len, int16_t* restrict buffer, int bitDepth);
|
||||
|
||||
void audio_int32_to_bytes(int32_t* restrict data, size_t data_len, int8_t* restrict buffer, int bitDepth);
|
||||
|
|
|
@ -12,8 +12,8 @@ func bitsToDiv(b int) float32 {
|
|||
return float32((int(1) << (b - 1)) - 1)
|
||||
}
|
||||
|
||||
// MultipleChannelsToMono bring any number of channels to mono, equally weighted, reusing buffer backwards
|
||||
func MultipleChannelsToMono(buffer []float32, channels int) (buf []float32) {
|
||||
// MultipleChannelsToMonoFloat32 bring any number of channels to mono, equally weighted
|
||||
func MultipleChannelsToMonoFloat32(buffer []float32, channels int) (buf []float32) {
|
||||
buf = make([]float32, len(buffer)/channels)
|
||||
for i := 0; i < len(buffer); i += channels {
|
||||
f := buffer[i]
|
||||
|
@ -26,8 +26,8 @@ func MultipleChannelsToMono(buffer []float32, channels int) (buf []float32) {
|
|||
return
|
||||
}
|
||||
|
||||
// MultipleChannelsToStereo bring any number of channels to stereo, using downmix formulas when necessary
|
||||
func MultipleChannelsToStereo(buffer []float32, channels int) (buf []float32) {
|
||||
// MultipleChannelsToStereoFloat32 bring any number of channels to stereo, using downmix formulas when necessary
|
||||
func MultipleChannelsToStereoFloat32(buffer []float32, channels int) (buf []float32) {
|
||||
buf = make([]float32, (len(buffer)/channels)*2)
|
||||
|
||||
var samples int
|
||||
|
@ -59,6 +59,7 @@ func MultipleChannelsToStereo(buffer []float32, channels int) (buf []float32) {
|
|||
C := i + 2
|
||||
RL := i + 3
|
||||
RR := i + 4
|
||||
//TODO: this is wrong
|
||||
buf[samples*2] = buffer[FL] + surroundMix*buffer[C] + surroundMix*buffer[RL]
|
||||
buf[samples*2+1] = buffer[FR] + surroundMix*buffer[C] + surroundMix*buffer[RR]
|
||||
samples++
|
||||
|
@ -71,6 +72,7 @@ func MultipleChannelsToStereo(buffer []float32, channels int) (buf []float32) {
|
|||
//LFE := i + 3
|
||||
RL := i + 4
|
||||
RR := i + 5
|
||||
//TODO: this is wrong
|
||||
buf[samples*2] = buffer[FL] + surroundMix*buffer[C] + surroundMix*buffer[RL]
|
||||
buf[samples*2+1] = buffer[FR] + surroundMix*buffer[C] + surroundMix*buffer[RR]
|
||||
samples++
|
||||
|
@ -87,6 +89,83 @@ func MultipleChannelsToStereo(buffer []float32, channels int) (buf []float32) {
|
|||
return
|
||||
}
|
||||
|
||||
// MultipleChannelsToMonoInt32 bring any number of channels to mono, equally weighted
|
||||
func MultipleChannelsToMonoInt32(buffer []int32, channels int) (buf []int32) {
|
||||
buf = make([]int32, len(buffer)/channels)
|
||||
for i := 0; i < len(buffer); i += channels {
|
||||
f := int64(buffer[i])
|
||||
for j := 1; j < channels; j++ {
|
||||
f += int64(buffer[i+j])
|
||||
}
|
||||
buf[i/channels] = int32(f / int64(channels))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// MultipleChannelsToStereoInt32 bring any number of channels to stereo, using downmix formulas when necessary
|
||||
func MultipleChannelsToStereoInt32(buffer []int32, channels int) (buf []int32) {
|
||||
buf = make([]int32, (len(buffer)/channels)*2)
|
||||
|
||||
var samples int
|
||||
surroundMix := 1 / float32(math.Sqrt(2))
|
||||
|
||||
switch channels {
|
||||
case 1: //mono, duplicate channels
|
||||
for i := 0; i < len(buffer); i++ {
|
||||
buf[i*2] = buffer[i]
|
||||
buf[i*2+1] = buffer[i]
|
||||
}
|
||||
break
|
||||
case 2: //copy
|
||||
copy(buf, buffer)
|
||||
break
|
||||
case 3: //2.1, FL, FR, LFE
|
||||
for i := 0; i < len(buffer); i += 3 {
|
||||
FL := i
|
||||
FR := i + 1
|
||||
//LFE := i + 2
|
||||
buf[samples*2] = buffer[FL]
|
||||
buf[samples*2+1] = buffer[FR]
|
||||
samples++
|
||||
}
|
||||
case 5: //5.0, FL, FR, FC, RL, RR
|
||||
for i := 0; i < len(buffer); i += 5 {
|
||||
FL := i
|
||||
FR := i + 1
|
||||
C := i + 2
|
||||
RL := i + 3
|
||||
RR := i + 4
|
||||
//TODO: this is wrong
|
||||
buf[samples*2] = int32(int64(buffer[FL]) + int64(surroundMix*float32(buffer[C])+surroundMix*float32(buffer[RL])))
|
||||
buf[samples*2+1] = int32(int64(buffer[FR]) + int64(surroundMix*float32(buffer[C])+surroundMix*float32(buffer[RR])))
|
||||
samples++
|
||||
}
|
||||
case 6: //5.1, FL, FR, FC, LFE, RL, RR
|
||||
for i := 0; i < len(buffer); i += 6 {
|
||||
FL := i
|
||||
FR := i + 1
|
||||
C := i + 2
|
||||
//LFE := i + 3
|
||||
RL := i + 4
|
||||
RR := i + 5
|
||||
//TODO: this is wrong
|
||||
buf[samples*2] = int32(int64(buffer[FL]) + int64(surroundMix*float32(buffer[C])+surroundMix*float32(buffer[RL])))
|
||||
buf[samples*2+1] = int32(int64(buffer[FR]) + int64(surroundMix*float32(buffer[C])+surroundMix*float32(buffer[RR])))
|
||||
samples++
|
||||
}
|
||||
break
|
||||
default: //no known formula, just take stereo out of it
|
||||
for i := 0; i < len(buffer); i += channels {
|
||||
buf[samples*2] = buffer[i]
|
||||
buf[samples*2+1] = buffer[i+1]
|
||||
samples++
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func Int32ToInt16(data []int32, bitDepth int) (buf []int16) {
|
||||
buf = make([]int16, len(data))
|
||||
diff := bitDepth - 16
|
||||
|
|
Loading…
Reference in a new issue