From db0c1911921d253f1156ca9961c11ca85cc2bfb0 Mon Sep 17 00:00:00 2001 From: WeebDataHoarder <57538841+WeebDataHoarder@users.noreply.github.com> Date: Wed, 20 Jul 2022 18:34:21 +0200 Subject: [PATCH] Support Double, Int input types --- libebur128.go | 16 ++++++ libebur128_test.go | 140 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 156 insertions(+) diff --git a/libebur128.go b/libebur128.go index bb355b7..6f76b05 100644 --- a/libebur128.go +++ b/libebur128.go @@ -168,6 +168,14 @@ func (s *State) AddFloat(src []float32) error { return nil } +func (s *State) AddDouble(src []float64) error { + ret := C.ebur128_add_frames_double(s.p, (*C.double)(&src[0]), C.size_t(len(src)/s.channels)) + if ret != C.EBUR128_SUCCESS { + return fmt.Errorf("error adding frames: %d", ret) + } + return nil +} + func (s *State) AddShort(src []int16) error { ret := C.ebur128_add_frames_short(s.p, (*C.short)(&src[0]), C.size_t(len(src)/s.channels)) if ret != C.EBUR128_SUCCESS { @@ -176,6 +184,14 @@ func (s *State) AddShort(src []int16) error { return nil } +func (s *State) AddInt(src []int32) error { + ret := C.ebur128_add_frames_int(s.p, (*C.int)(&src[0]), C.size_t(len(src)/s.channels)) + if ret != C.EBUR128_SUCCESS { + return fmt.Errorf("error adding frames: %d", ret) + } + return nil +} + func (s *State) Close() { if s.p != nil { C.ebur128_destroy(&s.p) diff --git a/libebur128_test.go b/libebur128_test.go index 604b07e..cee107e 100644 --- a/libebur128_test.go +++ b/libebur128_test.go @@ -73,6 +73,76 @@ func TestFloat(t *testing.T) { } } +func TestDouble(t *testing.T) { + t.Parallel() + state := NewState(2, 44100, LoudnessGlobalMomentary|SamplePeak) + if state == nil { + t.Error(errors.New("could not create state")) + return + } + defer state.Close() + + f, err := os.Open("sample/test_f32.raw") + if err != nil { + t.Error(err) + return + } + + data, err := ioutil.ReadAll(f) + if err != nil { + t.Error(err) + return + } + + const blockSize = 1024 + + floatData := unsafe.Slice((*float32)(unsafe.Pointer(&data[0])), len(data)/4) + + doubleData := make([]float64, len(floatData)) + for i := range floatData { + doubleData[i] = float64(floatData[i]) + } + + for len(doubleData) >= blockSize { + if err = state.AddDouble(doubleData[:blockSize]); err != nil { + t.Error(err) + return + } + doubleData = doubleData[blockSize:] + } + + if len(doubleData) > 0 { + if err = state.AddDouble(doubleData); err != nil { + t.Error(err) + return + } + } + var loudness float64 + var peak []float64 + + if loudness, err = state.GetLoudnessGlobal(); err != nil { + t.Error(err) + return + } + if peak, err = state.GetSamplePeak(); err != nil { + t.Error(err) + return + } + + var maxPeak float64 + for _, p := range peak { + if p > maxPeak { + maxPeak = p + } + } + + result := fmt.Sprintf("%f dB, %f", loudness, maxPeak) + expected := "-15.060377 dB, 0.666256" + if result != expected { + t.Errorf("expected %s, got %s", expected, result) + } +} + func TestShort(t *testing.T) { t.Parallel() state := NewState(2, 44100, LoudnessGlobalMomentary|SamplePeak) @@ -136,3 +206,73 @@ func TestShort(t *testing.T) { t.Errorf("expected %s, got %s", expected, result) } } + +func TestInt(t *testing.T) { + t.Parallel() + state := NewState(2, 44100, LoudnessGlobalMomentary|SamplePeak) + if state == nil { + t.Error(errors.New("could not create state")) + return + } + defer state.Close() + + f, err := os.Open("sample/test_s16.raw") + if err != nil { + t.Error(err) + return + } + + data, err := ioutil.ReadAll(f) + if err != nil { + t.Error(err) + return + } + + const blockSize = 1024 + + shortData := unsafe.Slice((*int16)(unsafe.Pointer(&data[0])), len(data)/2) + + intData := make([]int32, len(shortData)) + for i := range shortData { + intData[i] = int32(shortData[i]) << 16 + } + + for len(intData) >= blockSize { + if err = state.AddInt(intData[:blockSize]); err != nil { + t.Error(err) + return + } + intData = intData[blockSize:] + } + + if len(intData) > 0 { + if err = state.AddInt(intData); err != nil { + t.Error(err) + return + } + } + var loudness float64 + var peak []float64 + + if loudness, err = state.GetLoudnessGlobal(); err != nil { + t.Error(err) + return + } + if peak, err = state.GetSamplePeak(); err != nil { + t.Error(err) + return + } + + var maxPeak float64 + for _, p := range peak { + if p > maxPeak { + maxPeak = p + } + } + + result := fmt.Sprintf("%f dB, %f", loudness, maxPeak) + expected := "-15.060377 dB, 0.666260" + if result != expected { + t.Errorf("expected %s, got %s", expected, result) + } +}