From: Kevin Caffrey Date: Wed, 7 Jun 2023 23:13:10 +0000 (-0400) Subject: feat: Implement InDTX for Encoder X-Git-Tag: v2.0.0~3 X-Git-Url: http://www.git.stargrave.org/?a=commitdiff_plain;h=edec55a8f5dadfcc155bd5d194fae5cbc95ff0fa;p=go-opus.git feat: Implement InDTX for Encoder --- diff --git a/encoder.go b/encoder.go index 0939168..e873887 100644 --- a/encoder.go +++ b/encoder.go @@ -25,6 +25,12 @@ bridge_encoder_get_dtx(OpusEncoder *st, opus_int32 *dtx) return opus_encoder_ctl(st, OPUS_GET_DTX(dtx)); } +int +bridge_encoder_get_in_dtx(OpusEncoder *st, opus_int32 *in_dtx) +{ + return opus_encoder_ctl(st, OPUS_GET_IN_DTX(in_dtx)); +} + int bridge_encoder_get_sample_rate(OpusEncoder *st, opus_int32 *sample_rate) { @@ -239,6 +245,17 @@ func (enc *Encoder) DTX() (bool, error) { return dtx != 0, nil } +// InDTX returns whether the last encoded frame was either a comfort noise update +// during DTX or not encoded because of DTX. +func (enc *Encoder) InDTX() (bool, error) { + var inDTX C.opus_int32 + res := C.bridge_encoder_get_in_dtx(enc.p, &inDTX) + if res != C.OPUS_OK { + return false, Error(res) + } + return inDTX != 0, nil +} + // SampleRate returns the encoder sample rate in Hz. func (enc *Encoder) SampleRate() (int, error) { var sr C.opus_int32 diff --git a/encoder_test.go b/encoder_test.go index 68f7af9..0795cae 100644 --- a/encoder_test.go +++ b/encoder_test.go @@ -50,6 +50,50 @@ func TestEncoderDTX(t *testing.T) { } } +func TestEncoderInDTX(t *testing.T) { + // Create bogus input sound + const G4 = 391.995 + const SAMPLE_RATE = 48000 + const FRAME_SIZE_MS = 60 + const FRAME_SIZE = SAMPLE_RATE * FRAME_SIZE_MS / 1000 + pcm := make([]int16, FRAME_SIZE) + silentPCM := make([]int16, FRAME_SIZE) + out := make([]byte, FRAME_SIZE*4) + addSine(pcm, SAMPLE_RATE, G4) + + vals := []bool{true, false} + for _, dtx := range vals { + enc, err := NewEncoder(SAMPLE_RATE, 1, AppVoIP) + if err != nil || enc == nil { + t.Fatalf("Error creating new encoder: %v", err) + } + enc.SetDTX(dtx) + if _, err = enc.Encode(pcm, out); err != nil { + t.Fatalf("Error encoding non-silent frame: %v", err) + } + gotDTX, err := enc.InDTX() + if err != nil { + t.Fatalf("Error getting in DTX (%t): %v", dtx, err) + } + if gotDTX { + t.Fatalf("Error get in dtx: expect in dtx=false, got=true") + } + // Encode a few frames to let DTX kick in + for i := 0; i < 5; i++ { + if _, err = enc.Encode(silentPCM, out); err != nil { + t.Fatalf("Error encoding silent frame: %v", err) + } + } + gotDTX, err = enc.InDTX() + if err != nil { + t.Fatalf("Error getting in DTX (%t): %v", dtx, err) + } + if gotDTX != dtx { + t.Errorf("Error set dtx: expect in dtx=%v, got in dtx=%v", dtx, gotDTX) + } + } +} + func TestEncoderSampleRate(t *testing.T) { sample_rates := []int{8000, 12000, 16000, 24000, 48000} for _, f := range sample_rates {