From 9b8d5e1c49f852493ccbb84f929cdef879402d64 Mon Sep 17 00:00:00 2001 From: Mr-Z-2697 <74594146+Mr-Z-2697@users.noreply.github.com> Date: Tue, 7 Oct 2025 21:44:07 +0800 Subject: [PATCH 1/2] encoder: remove mandatory dc_reject filter Restore this piece of code to before 0869829f343f85935fac22462d228a065d0ba320. The dc_reject itself is kept in the code, for possible future use. --- src/opus_encoder.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/opus_encoder.c b/src/opus_encoder.c index 24cda963e..dbb660dae 100644 --- a/src/opus_encoder.c +++ b/src/opus_encoder.c @@ -1924,12 +1924,8 @@ static opus_int32 opus_encode_frame_native(OpusEncoder *st, const opus_res *pcm, } #endif } else { -#ifdef ENABLE_QEXT - /* FIXME: Avoid glitching when we switch qext on/off dynamically. */ - if (st->enable_qext) OPUS_COPY(&pcm_buf[total_buffer*st->channels], pcm, frame_size*st->channels); - else -#endif - dc_reject(pcm, 3, &pcm_buf[total_buffer*st->channels], st->hp_mem, frame_size, st->channels, st->Fs); + for (i=0;ichannels;i++) + pcm_buf[total_buffer*st->channels + i] = pcm[i]; } #ifndef FIXED_POINT if (float_api) From fc2c229806d7cedff5e0cd59b94356c9da2b25ea Mon Sep 17 00:00:00 2001 From: Mr-Z-2697 <74594146+Mr-Z-2697@users.noreply.github.com> Date: Tue, 7 Oct 2025 23:06:24 +0800 Subject: [PATCH 2/2] encoder: add dc_reject filter control --- include/opus_defines.h | 10 ++++++++++ src/opus_demo.c | 8 ++++++++ src/opus_encoder.c | 33 +++++++++++++++++++++++++++++++-- 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/include/opus_defines.h b/include/opus_defines.h index f142a2697..6b1104cda 100644 --- a/include/opus_defines.h +++ b/include/opus_defines.h @@ -179,6 +179,8 @@ extern "C" { #define OPUS_GET_QEXT_REQUEST 4057 #define OPUS_SET_IGNORE_EXTENSIONS_REQUEST 4058 #define OPUS_GET_IGNORE_EXTENSIONS_REQUEST 4059 +#define OPUS_SET_DC_FILTER_REQUEST 4060 +#define OPUS_GET_DC_FILTER_REQUEST 4061 /** Defines for the presence of extended APIs. */ #define OPUS_HAVE_OPUS_PROJECTION_H @@ -662,6 +664,14 @@ extern "C" { * @hideinitializer */ #define OPUS_GET_QEXT(x) OPUS_GET_QEXT_REQUEST, __opus_check_int_ptr(x) +/** Configures the encoder's use of dc_reject filter. + * @hideinitializer */ +#define OPUS_SET_DC_FILTER(x) OPUS_SET_DC_FILTER_REQUEST, __opus_check_int(x) +/** Gets the encoder's configured dc_reject filter status. + * @hideinitializer */ +#define OPUS_GET_DC_FILTER(x) OPUS_GET_DC_FILTER_REQUEST, __opus_check_int(x) + + /**@}*/ /** @defgroup opus_genericctls Generic CTLs diff --git a/src/opus_demo.c b/src/opus_demo.c index 9285e1213..b8d34673f 100644 --- a/src/opus_demo.c +++ b/src/opus_demo.c @@ -131,6 +131,7 @@ void print_usage( char* argv[] ) fprintf(stderr, "-d : only runs the decoder (reads the bit-stream as input)\n" ); fprintf(stderr, "-cbr : enable constant bitrate; default: variable bitrate\n" ); fprintf(stderr, "-cvbr : enable constrained variable bitrate; default: unconstrained\n" ); + fprintf(stderr, "-dc_filter : enable dc reject filter; default: false\n" ); fprintf(stderr, "-delayed-decision : use look-ahead for speech/music detection (experts only); default: disabled\n" ); fprintf(stderr, "-bandwidth : audio bandwidth (from narrowband to fullband); default: sampling rate\n" ); fprintf(stderr, "-framesize <2.5|5|10|20|40|60|80|100|120> : frame size in ms; default: 20 \n" ); @@ -389,6 +390,7 @@ int main(int argc, char *argv[]) unsigned char *fbytes=NULL; opus_int32 sampling_rate; int use_vbr; + int dc_filter; int max_payload_bytes; int complexity; int dec_complexity; @@ -533,6 +535,7 @@ int main(int argc, char *argv[]) /* defaults: */ use_vbr = 1; + dc_filter = 0; max_payload_bytes = MAX_PACKET; complexity = 10; dec_complexity = 0; @@ -547,6 +550,10 @@ int main(int argc, char *argv[]) check_encoder_option(decode_only, "-cbr"); use_vbr = 0; args++; + } else if ( strcmp( argv[ args ], "-dc_filter" ) == 0 ) { + check_encoder_option(decode_only, "-dc_filter"); + dc_filter = 1; + ++args; } else if( strcmp( argv[ args ], "-bandwidth" ) == 0 ) { check_encoder_option(decode_only, "-bandwidth"); if (strcmp(argv[ args + 1 ], "NB")==0) @@ -782,6 +789,7 @@ int main(int argc, char *argv[]) opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate_bps)); opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(bandwidth)); opus_encoder_ctl(enc, OPUS_SET_VBR(use_vbr)); + opus_encoder_ctl(enc, OPUS_SET_DC_FILTER(dc_filter)); opus_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(cvbr)); opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(complexity)); opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(use_inbandfec)); diff --git a/src/opus_encoder.c b/src/opus_encoder.c index dbb660dae..0564306c7 100644 --- a/src/opus_encoder.c +++ b/src/opus_encoder.c @@ -144,6 +144,7 @@ struct OpusEncoder { #endif int nonfinal_frame; /* current frame is not the final in a packet */ opus_uint32 rangeFinal; + int dc_filter; }; /* Transition tables for the voice and music. First column is the @@ -298,6 +299,7 @@ int opus_encoder_init(OpusEncoder* st, opus_int32 Fs, int channels, int applicat st->first = 1; st->mode = MODE_HYBRID; st->bandwidth = OPUS_BANDWIDTH_FULLBAND; + st->dc_filter = 0; #ifndef DISABLE_FLOAT_API tonality_analysis_init(&st->analysis, st->Fs); @@ -1923,9 +1925,16 @@ static opus_int32 opus_encode_frame_native(OpusEncoder *st, const opus_res *pcm, } } #endif +#ifdef ENABLE_QEXT + /* FIXME: Avoid glitching when we switch qext on/off dynamically. */ + } else if (st->dc_filter && !st->enable_qext) { +#else + /* FIXME: Avoid glitching when we switch dc_filter on/off dynamically. */ + } else if (st->dc_filter) { +#endif + dc_reject(pcm, 3, &pcm_buf[total_buffer*st->channels], st->hp_mem, frame_size, st->channels, st->Fs); } else { - for (i=0;ichannels;i++) - pcm_buf[total_buffer*st->channels + i] = pcm[i]; + OPUS_COPY(&pcm_buf[total_buffer*st->channels], pcm, frame_size*st->channels); } #ifndef FIXED_POINT if (float_api) @@ -2916,6 +2925,26 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...) *value = st->use_vbr; } break; + case OPUS_SET_DC_FILTER_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + if(value<0 || value>1) + { + goto bad_arg; + } + st->dc_filter = value; + } + break; + case OPUS_GET_DC_FILTER_REQUEST: + { + opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } + *value = st->dc_filter; + } + break; case OPUS_SET_VOICE_RATIO_REQUEST: { opus_int32 value = va_arg(ap, opus_int32);