]> Sergey Matveev's repositories - go-opus.git/commitdiff
feat: Implement InDTX for Encoder
authorKevin Caffrey <kcaffrey@gmail.com>
Wed, 7 Jun 2023 23:13:10 +0000 (19:13 -0400)
committerHraban Luyat <hraban@0brg.net>
Thu, 6 Jul 2023 20:57:04 +0000 (16:57 -0400)
encoder.go
encoder_test.go

index 09391682f231281ac9531ae4bde8e86d98f88444..e87388781281152cb4b23886220f1a44bf9fd8b6 100644 (file)
@@ -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
index 68f7af9b00dd2abe264f16af093506301c6c342a..0795caecbfc55408fed51d5782b8bbe2d7b61579 100644 (file)
@@ -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 {