| 1 | From 17e72f00831a36da387ceafe7f3076ffa8f66aba Mon Sep 17 00:00:00 2001
|
| 2 | From: Clemence Him <[email protected]>
|
| 3 | Date: Fri, 22 Sep 2023 14:28:02 +0200
|
| 4 | Subject: [PATCH] Base64 functions refactoring
|
| 5 |
|
| 6 | ---
|
| 7 | aec.c | 781 +++++++++++++++++++++++++++++-----------------------------
|
| 8 | 1 file changed, 394 insertions(+), 387 deletions(-)
|
| 9 |
|
| 10 | diff --git a/aec.c b/aec.c
|
| 11 | index 271f370..995f655 100644
|
| 12 | |
| 13 | |
| 14 | @@ -24,19 +24,18 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
| 15 | #include "mediastreamer2/msfilter.h"
|
| 16 | #include "mediastreamer2/msticker.h"
|
| 17 | #ifdef BUILD_AEC
|
| 18 | -#include "echo_cancellation.h"
|
| 19 | #include "aec_splitting_filter.h"
|
| 20 | +#include "echo_cancellation.h"
|
| 21 | #endif
|
| 22 | #ifdef BUILD_AECM
|
| 23 | #include "echo_control_mobile.h"
|
| 24 | #endif
|
| 25 | -#include "ortp/b64.h"
|
| 26 |
|
| 27 | #ifdef _WIN32
|
| 28 | #include <malloc.h> /* for alloca */
|
| 29 | #endif
|
| 30 |
|
| 31 | -//#define EC_DUMP 1
|
| 32 | +// #define EC_DUMP 1
|
| 33 | #ifdef ANDROID
|
| 34 | #define EC_DUMP_PREFIX "/sdcard"
|
| 35 | #else
|
| 36 | @@ -48,466 +47,485 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
| 37 | static const float smooth_factor = 0.05f;
|
| 38 | static const int framesize = 80;
|
| 39 |
|
| 40 | -
|
| 41 | typedef enum _WebRTCAECType {
|
| 42 | - WebRTCAECTypeNormal,
|
| 43 | - WebRTCAECTypeMobile
|
| 44 | + WebRTCAECTypeNormal,
|
| 45 | + WebRTCAECTypeMobile
|
| 46 | } WebRTCAECType;
|
| 47 |
|
| 48 | typedef struct WebRTCAECState {
|
| 49 | - void *aecInst;
|
| 50 | - MSBufferizer delayed_ref;
|
| 51 | - MSFlowControlledBufferizer ref;
|
| 52 | - MSBufferizer echo;
|
| 53 | - int framesize;
|
| 54 | - int samplerate;
|
| 55 | - int delay_ms;
|
| 56 | - int nominal_ref_samples;
|
| 57 | - char *state_str;
|
| 58 | + void *aecInst;
|
| 59 | + MSBufferizer delayed_ref;
|
| 60 | + MSFlowControlledBufferizer ref;
|
| 61 | + MSBufferizer echo;
|
| 62 | + int framesize;
|
| 63 | + int samplerate;
|
| 64 | + int delay_ms;
|
| 65 | + int nominal_ref_samples;
|
| 66 | + char *state_str;
|
| 67 | #ifdef EC_DUMP
|
| 68 | - FILE *echofile;
|
| 69 | - FILE *reffile;
|
| 70 | - FILE *cleanfile;
|
| 71 | + FILE *echofile;
|
| 72 | + FILE *reffile;
|
| 73 | + FILE *cleanfile;
|
| 74 | #endif
|
| 75 | - bool_t echostarted;
|
| 76 | - bool_t bypass_mode;
|
| 77 | - bool_t using_zeroes;
|
| 78 | - WebRTCAECType aec_type;
|
| 79 | + bool_t echostarted;
|
| 80 | + bool_t bypass_mode;
|
| 81 | + bool_t using_zeroes;
|
| 82 | + WebRTCAECType aec_type;
|
| 83 | #ifdef BUILD_AEC
|
| 84 | - MSWebRtcAecSplittingFilter *splitting_filter;
|
| 85 | + MSWebRtcAecSplittingFilter *splitting_filter;
|
| 86 | #endif
|
| 87 | } WebRTCAECState;
|
| 88 |
|
| 89 | static void webrtc_aecgeneric_init(MSFilter *f, WebRTCAECType aec_type) {
|
| 90 | - WebRTCAECState *s = (WebRTCAECState *) ms_new0(WebRTCAECState, 1);
|
| 91 | -
|
| 92 | - s->samplerate = 8000;
|
| 93 | - ms_bufferizer_init(&s->delayed_ref);
|
| 94 | - ms_bufferizer_init(&s->echo);
|
| 95 | - ms_flow_controlled_bufferizer_init(&s->ref, f, s->samplerate, 1);
|
| 96 | - s->delay_ms = 0;
|
| 97 | - s->aecInst = NULL;
|
| 98 | - s->framesize = framesize;
|
| 99 | - s->state_str = NULL;
|
| 100 | - s->using_zeroes = FALSE;
|
| 101 | - s->echostarted = FALSE;
|
| 102 | - s->bypass_mode = FALSE;
|
| 103 | - s->aec_type = aec_type;
|
| 104 | + WebRTCAECState *s = (WebRTCAECState *)ms_new0(WebRTCAECState, 1);
|
| 105 | +
|
| 106 | + s->samplerate = 8000;
|
| 107 | + ms_bufferizer_init(&s->delayed_ref);
|
| 108 | + ms_bufferizer_init(&s->echo);
|
| 109 | + ms_flow_controlled_bufferizer_init(&s->ref, f, s->samplerate, 1);
|
| 110 | + s->delay_ms = 0;
|
| 111 | + s->aecInst = NULL;
|
| 112 | + s->framesize = framesize;
|
| 113 | + s->state_str = NULL;
|
| 114 | + s->using_zeroes = FALSE;
|
| 115 | + s->echostarted = FALSE;
|
| 116 | + s->bypass_mode = FALSE;
|
| 117 | + s->aec_type = aec_type;
|
| 118 |
|
| 119 | #ifdef EC_DUMP
|
| 120 | - {
|
| 121 | - char *fname = ms_strdup_printf("%s/mswebrtcaec-%p-echo.raw", EC_DUMP_PREFIX, f);
|
| 122 | - s->echofile = fopen(fname, "w");
|
| 123 | - ms_free(fname);
|
| 124 | - fname = ms_strdup_printf("%s/mswebrtcaec-%p-ref.raw", EC_DUMP_PREFIX, f);
|
| 125 | - s->reffile = fopen(fname, "w");
|
| 126 | - ms_free(fname);
|
| 127 | - fname = ms_strdup_printf("%s/mswebrtcaec-%p-clean.raw", EC_DUMP_PREFIX, f);
|
| 128 | - s->cleanfile = fopen(fname, "w");
|
| 129 | - ms_free(fname);
|
| 130 | - }
|
| 131 | + {
|
| 132 | + char *fname =
|
| 133 | + ms_strdup_printf("%s/mswebrtcaec-%p-echo.raw", EC_DUMP_PREFIX, f);
|
| 134 | + s->echofile = fopen(fname, "w");
|
| 135 | + ms_free(fname);
|
| 136 | + fname = ms_strdup_printf("%s/mswebrtcaec-%p-ref.raw", EC_DUMP_PREFIX, f);
|
| 137 | + s->reffile = fopen(fname, "w");
|
| 138 | + ms_free(fname);
|
| 139 | + fname = ms_strdup_printf("%s/mswebrtcaec-%p-clean.raw", EC_DUMP_PREFIX, f);
|
| 140 | + s->cleanfile = fopen(fname, "w");
|
| 141 | + ms_free(fname);
|
| 142 | + }
|
| 143 | #endif
|
| 144 |
|
| 145 | - f->data = s;
|
| 146 | + f->data = s;
|
| 147 | }
|
| 148 |
|
| 149 | #ifdef BUILD_AEC
|
| 150 | static void webrtc_aec_init(MSFilter *f) {
|
| 151 | - webrtc_aecgeneric_init(f, WebRTCAECTypeNormal);
|
| 152 | + webrtc_aecgeneric_init(f, WebRTCAECTypeNormal);
|
| 153 | }
|
| 154 | #endif
|
| 155 |
|
| 156 | #ifdef BUILD_AECM
|
| 157 | static void webrtc_aecm_init(MSFilter *f) {
|
| 158 | - webrtc_aecgeneric_init(f, WebRTCAECTypeMobile);
|
| 159 | + webrtc_aecgeneric_init(f, WebRTCAECTypeMobile);
|
| 160 | }
|
| 161 | #endif
|
| 162 |
|
| 163 | static void webrtc_aec_uninit(MSFilter *f) {
|
| 164 | - WebRTCAECState *s = (WebRTCAECState *) f->data;
|
| 165 | - if (s->state_str) ms_free(s->state_str);
|
| 166 | - ms_bufferizer_uninit(&s->delayed_ref);
|
| 167 | + WebRTCAECState *s = (WebRTCAECState *)f->data;
|
| 168 | + if (s->state_str)
|
| 169 | + ms_free(s->state_str);
|
| 170 | + ms_bufferizer_uninit(&s->delayed_ref);
|
| 171 | #ifdef EC_DUMP
|
| 172 | - if (s->echofile)
|
| 173 | - fclose(s->echofile);
|
| 174 | - if (s->reffile)
|
| 175 | - fclose(s->reffile);
|
| 176 | + if (s->echofile)
|
| 177 | + fclose(s->echofile);
|
| 178 | + if (s->reffile)
|
| 179 | + fclose(s->reffile);
|
| 180 | #endif
|
| 181 | - ms_free(s);
|
| 182 | + ms_free(s);
|
| 183 | }
|
| 184 |
|
| 185 | static void configure_flow_controlled_bufferizer(WebRTCAECState *s) {
|
| 186 | - ms_flow_controlled_bufferizer_set_samplerate(&s->ref, s->samplerate);
|
| 187 | - ms_flow_controlled_bufferizer_set_max_size_ms(&s->ref, s->delay_ms);
|
| 188 | - ms_flow_controlled_bufferizer_set_granularity_ms(&s->ref, (s->framesize * 1000) / s->samplerate);
|
| 189 | + ms_flow_controlled_bufferizer_set_samplerate(&s->ref, s->samplerate);
|
| 190 | + ms_flow_controlled_bufferizer_set_max_size_ms(&s->ref, s->delay_ms);
|
| 191 | + ms_flow_controlled_bufferizer_set_granularity_ms(
|
| 192 | + &s->ref, (s->framesize * 1000) / s->samplerate);
|
| 193 | }
|
| 194 |
|
| 195 | static void webrtc_aec_preprocess(MSFilter *f) {
|
| 196 | - WebRTCAECState *s = (WebRTCAECState *) f->data;
|
| 197 | + WebRTCAECState *s = (WebRTCAECState *)f->data;
|
| 198 | #ifdef BUILD_AEC
|
| 199 | - AecConfig aec_config;
|
| 200 | + AecConfig aec_config;
|
| 201 | #endif
|
| 202 | #ifdef BUILD_AECM
|
| 203 | - AecmConfig aecm_config;
|
| 204 | - int error_code;
|
| 205 | + AecmConfig aecm_config;
|
| 206 | + int error_code;
|
| 207 | #endif
|
| 208 | - int delay_samples = 0;
|
| 209 | - mblk_t *m;
|
| 210 | + int delay_samples = 0;
|
| 211 | + mblk_t *m;
|
| 212 |
|
| 213 | - s->echostarted = FALSE;
|
| 214 | - delay_samples = s->delay_ms * s->samplerate / 1000;
|
| 215 | - s->framesize=(framesize*s->samplerate)/8000;
|
| 216 | - ms_message("Initializing WebRTC echo canceler with framesize=%i, delay_ms=%i, delay_samples=%i", s->framesize, s->delay_ms, delay_samples);
|
| 217 | - configure_flow_controlled_bufferizer(s);
|
| 218 | + s->echostarted = FALSE;
|
| 219 | + delay_samples = s->delay_ms * s->samplerate / 1000;
|
| 220 | + s->framesize = (framesize * s->samplerate) / 8000;
|
| 221 | + ms_message("Initializing WebRTC echo canceler with framesize=%i, "
|
| 222 | + "delay_ms=%i, delay_samples=%i",
|
| 223 | + s->framesize, s->delay_ms, delay_samples);
|
| 224 | + configure_flow_controlled_bufferizer(s);
|
| 225 |
|
| 226 | #ifdef BUILD_AEC
|
| 227 | - if (s->aec_type == WebRTCAECTypeNormal) {
|
| 228 | - if ((s->aecInst = WebRtcAec_Create()) == NULL) {
|
| 229 | - s->bypass_mode = TRUE;
|
| 230 | - ms_error("WebRtcAec_Create(): error, entering bypass mode");
|
| 231 | - return;
|
| 232 | - }
|
| 233 | - if ((WebRtcAec_Init(s->aecInst, MIN(48000, s->samplerate), s->samplerate)) < 0) {
|
| 234 | - ms_error("WebRtcAec_Init(): WebRTC echo canceller does not support %d samplerate", s->samplerate);
|
| 235 | - s->bypass_mode = TRUE;
|
| 236 | - ms_error("Entering bypass mode");
|
| 237 | - return;
|
| 238 | - }
|
| 239 | - aec_config.nlpMode = kAecNlpAggressive;
|
| 240 | - aec_config.skewMode = kAecFalse;
|
| 241 | - aec_config.metricsMode = kAecFalse;
|
| 242 | - aec_config.delay_logging = kAecFalse;
|
| 243 | - if (WebRtcAec_set_config(s->aecInst, aec_config) != 0) {
|
| 244 | - ms_error("WebRtcAec_set_config(): failed.");
|
| 245 | - }
|
| 246 | - }
|
| 247 | + if (s->aec_type == WebRTCAECTypeNormal) {
|
| 248 | + if ((s->aecInst = WebRtcAec_Create()) == NULL) {
|
| 249 | + s->bypass_mode = TRUE;
|
| 250 | + ms_error("WebRtcAec_Create(): error, entering bypass mode");
|
| 251 | + return;
|
| 252 | + }
|
| 253 | + if ((WebRtcAec_Init(s->aecInst, MIN(48000, s->samplerate), s->samplerate)) <
|
| 254 | + 0) {
|
| 255 | + ms_error("WebRtcAec_Init(): WebRTC echo canceller does not support %d "
|
| 256 | + "samplerate",
|
| 257 | + s->samplerate);
|
| 258 | + s->bypass_mode = TRUE;
|
| 259 | + ms_error("Entering bypass mode");
|
| 260 | + return;
|
| 261 | + }
|
| 262 | + aec_config.nlpMode = kAecNlpAggressive;
|
| 263 | + aec_config.skewMode = kAecFalse;
|
| 264 | + aec_config.metricsMode = kAecFalse;
|
| 265 | + aec_config.delay_logging = kAecFalse;
|
| 266 | + if (WebRtcAec_set_config(s->aecInst, aec_config) != 0) {
|
| 267 | + ms_error("WebRtcAec_set_config(): failed.");
|
| 268 | + }
|
| 269 | + }
|
| 270 | #endif
|
| 271 | #ifdef BUILD_AECM
|
| 272 | - if (s->aec_type == WebRTCAECTypeMobile) {
|
| 273 | - if ((s->aecInst = WebRtcAecm_Create()) == NULL) {
|
| 274 | - s->bypass_mode = TRUE;
|
| 275 | - ms_error("WebRtcAecm_Create(): error, entering bypass mode");
|
| 276 | - return;
|
| 277 | - }
|
| 278 | - if ((error_code = WebRtcAecm_Init(s->aecInst, s->samplerate)) < 0) {
|
| 279 | - if (error_code == AECM_BAD_PARAMETER_ERROR) {
|
| 280 | - ms_error("WebRtcAecm_Init(): WebRTC echo canceller does not support %d samplerate", s->samplerate);
|
| 281 | - }
|
| 282 | - s->bypass_mode = TRUE;
|
| 283 | - ms_error("Entering bypass mode");
|
| 284 | - return;
|
| 285 | - }
|
| 286 | - aecm_config.cngMode = TRUE;
|
| 287 | - aecm_config.echoMode = 3;
|
| 288 | - if (WebRtcAecm_set_config(s->aecInst, aecm_config)!=0){
|
| 289 | - ms_error("WebRtcAecm_set_config(): failed.");
|
| 290 | - }
|
| 291 | - }
|
| 292 | + if (s->aec_type == WebRTCAECTypeMobile) {
|
| 293 | + if ((s->aecInst = WebRtcAecm_Create()) == NULL) {
|
| 294 | + s->bypass_mode = TRUE;
|
| 295 | + ms_error("WebRtcAecm_Create(): error, entering bypass mode");
|
| 296 | + return;
|
| 297 | + }
|
| 298 | + if ((error_code = WebRtcAecm_Init(s->aecInst, s->samplerate)) < 0) {
|
| 299 | + if (error_code == AECM_BAD_PARAMETER_ERROR) {
|
| 300 | + ms_error("WebRtcAecm_Init(): WebRTC echo canceller does not support %d "
|
| 301 | + "samplerate",
|
| 302 | + s->samplerate);
|
| 303 | + }
|
| 304 | + s->bypass_mode = TRUE;
|
| 305 | + ms_error("Entering bypass mode");
|
| 306 | + return;
|
| 307 | + }
|
| 308 | + aecm_config.cngMode = TRUE;
|
| 309 | + aecm_config.echoMode = 3;
|
| 310 | + if (WebRtcAecm_set_config(s->aecInst, aecm_config) != 0) {
|
| 311 | + ms_error("WebRtcAecm_set_config(): failed.");
|
| 312 | + }
|
| 313 | + }
|
| 314 | #endif
|
| 315 |
|
| 316 | - /* fill with zeroes for the time of the delay*/
|
| 317 | - m = allocb(delay_samples * 2, 0);
|
| 318 | - m->b_wptr += delay_samples * 2;
|
| 319 | - ms_bufferizer_put(&s->delayed_ref, m);
|
| 320 | - s->nominal_ref_samples = delay_samples;
|
| 321 | + /* fill with zeroes for the time of the delay*/
|
| 322 | + m = allocb(delay_samples * 2, 0);
|
| 323 | + m->b_wptr += delay_samples * 2;
|
| 324 | + ms_bufferizer_put(&s->delayed_ref, m);
|
| 325 | + s->nominal_ref_samples = delay_samples;
|
| 326 | }
|
| 327 |
|
| 328 | /* inputs[0]= reference signal from far end (sent to soundcard)
|
| 329 | * inputs[1]= near speech & echo signal (read from soundcard)
|
| 330 | * outputs[0]= is a copy of inputs[0] to be sent to soundcard
|
| 331 | * outputs[1]= near end speech, echo removed - towards far end
|
| 332 | -*/
|
| 333 | + */
|
| 334 | static void webrtc_aec_process(MSFilter *f) {
|
| 335 | - WebRTCAECState *s = (WebRTCAECState *) f->data;
|
| 336 | - int nbytes = s->framesize * sizeof(int16_t);
|
| 337 | - mblk_t *refm;
|
| 338 | - int16_t *ref, *echo;
|
| 339 | - int nbands = 1;
|
| 340 | - int bandsize = s->framesize;
|
| 341 | -
|
| 342 | - if (s->bypass_mode) {
|
| 343 | - while ((refm = ms_queue_get(f->inputs[0])) != NULL) {
|
| 344 | - ms_queue_put(f->outputs[0], refm);
|
| 345 | - }
|
| 346 | - while ((refm = ms_queue_get(f->inputs[1])) != NULL) {
|
| 347 | - ms_queue_put(f->outputs[1], refm);
|
| 348 | - }
|
| 349 | - return;
|
| 350 | - }
|
| 351 | -
|
| 352 | - if (f->inputs[0] != NULL) {
|
| 353 | - if (s->echostarted) {
|
| 354 | - while ((refm = ms_queue_get(f->inputs[0])) != NULL) {
|
| 355 | - mblk_t *cp=dupmsg(refm);
|
| 356 | - ms_bufferizer_put(&s->delayed_ref,cp);
|
| 357 | - ms_flow_controlled_bufferizer_put(&s->ref,refm);
|
| 358 | - }
|
| 359 | - } else {
|
| 360 | - ms_warning("Getting reference signal but no echo to synchronize on.");
|
| 361 | - ms_queue_flush(f->inputs[0]);
|
| 362 | - }
|
| 363 | - }
|
| 364 | -
|
| 365 | - ms_bufferizer_put_from_queue(&s->echo, f->inputs[1]);
|
| 366 | -
|
| 367 | - ref = (int16_t *) alloca(nbytes);
|
| 368 | - echo = (int16_t *) alloca(nbytes);
|
| 369 | + WebRTCAECState *s = (WebRTCAECState *)f->data;
|
| 370 | + int nbytes = s->framesize * sizeof(int16_t);
|
| 371 | + mblk_t *refm;
|
| 372 | + int16_t *ref, *echo;
|
| 373 | + int nbands = 1;
|
| 374 | + int bandsize = s->framesize;
|
| 375 | +
|
| 376 | + if (s->bypass_mode) {
|
| 377 | + while ((refm = ms_queue_get(f->inputs[0])) != NULL) {
|
| 378 | + ms_queue_put(f->outputs[0], refm);
|
| 379 | + }
|
| 380 | + while ((refm = ms_queue_get(f->inputs[1])) != NULL) {
|
| 381 | + ms_queue_put(f->outputs[1], refm);
|
| 382 | + }
|
| 383 | + return;
|
| 384 | + }
|
| 385 | +
|
| 386 | + if (f->inputs[0] != NULL) {
|
| 387 | + if (s->echostarted) {
|
| 388 | + while ((refm = ms_queue_get(f->inputs[0])) != NULL) {
|
| 389 | + mblk_t *cp = dupmsg(refm);
|
| 390 | + ms_bufferizer_put(&s->delayed_ref, cp);
|
| 391 | + ms_flow_controlled_bufferizer_put(&s->ref, refm);
|
| 392 | + }
|
| 393 | + } else {
|
| 394 | + ms_warning("Getting reference signal but no echo to synchronize on.");
|
| 395 | + ms_queue_flush(f->inputs[0]);
|
| 396 | + }
|
| 397 | + }
|
| 398 | +
|
| 399 | + ms_bufferizer_put_from_queue(&s->echo, f->inputs[1]);
|
| 400 | +
|
| 401 | + ref = (int16_t *)alloca(nbytes);
|
| 402 | + echo = (int16_t *)alloca(nbytes);
|
| 403 | #ifdef BUILD_AEC
|
| 404 | - if (s->aec_type == WebRTCAECTypeNormal) {
|
| 405 | - if (s->samplerate > 16000) {
|
| 406 | - nbands = s->samplerate / 16000;
|
| 407 | - bandsize = 160;
|
| 408 | - }
|
| 409 | - if (!s->splitting_filter) {
|
| 410 | - s->splitting_filter = mswebrtc_aec_splitting_filter_create(nbands, bandsize);
|
| 411 | - }
|
| 412 | - }
|
| 413 | + if (s->aec_type == WebRTCAECTypeNormal) {
|
| 414 | + if (s->samplerate > 16000) {
|
| 415 | + nbands = s->samplerate / 16000;
|
| 416 | + bandsize = 160;
|
| 417 | + }
|
| 418 | + if (!s->splitting_filter) {
|
| 419 | + s->splitting_filter =
|
| 420 | + mswebrtc_aec_splitting_filter_create(nbands, bandsize);
|
| 421 | + }
|
| 422 | + }
|
| 423 | #endif
|
| 424 | - while (ms_bufferizer_read(&s->echo, (uint8_t *)echo, (size_t)nbytes) >= (size_t)nbytes) {
|
| 425 | - mblk_t *oecho = allocb(nbytes, 0);
|
| 426 | - int avail;
|
| 427 | - int avail_samples;
|
| 428 | -
|
| 429 | - if (!s->echostarted) s->echostarted = TRUE;
|
| 430 | - if ((avail = ms_bufferizer_get_avail(&s->delayed_ref)) < ((s->nominal_ref_samples * 2) + nbytes)) {
|
| 431 | - /*we don't have enough to read in a reference signal buffer, inject silence instead*/
|
| 432 | - refm = allocb(nbytes, 0);
|
| 433 | - memset(refm->b_wptr, 0, nbytes);
|
| 434 | - refm->b_wptr += nbytes;
|
| 435 | - ms_bufferizer_put(&s->delayed_ref, refm);
|
| 436 | - /*
|
| 437 | - * However, we don't inject this silence buffer to the sound card, in order to break the following bad loop:
|
| 438 | - * - the sound playback filter detects it has too many pending samples, then triggers an event to request samples to be dropped upstream.
|
| 439 | - * - the upstream MSFlowControl filter is requested to drop samples, which it starts to do.
|
| 440 | - * - necessarily shortly after the AEC goes into a situation where it has not enough reference samples while processing an audio buffer from mic.
|
| 441 | - * - if the AEC injects a silence buffer as output, then it will RECREATE a situation where the sound playback filter has too many pending samples.
|
| 442 | - * That's why we should not do this.
|
| 443 | - * By not doing this, we will create a discrepancy between what we really injected to the soundcard, and what we told to the
|
| 444 | - * echo canceller about the samples we injected. This shifts the echo. The echo canceller will re-converge quickly to take into
|
| 445 | - * account the situation.
|
| 446 | - *
|
| 447 | - */
|
| 448 | - //ms_queue_put(f->outputs[0], dupmsg(refm));
|
| 449 | - if (!s->using_zeroes) {
|
| 450 | - ms_warning("Not enough ref samples, using zeroes");
|
| 451 | - s->using_zeroes = TRUE;
|
| 452 | - }
|
| 453 | - } else {
|
| 454 | - if (s->using_zeroes) {
|
| 455 | - ms_message("Samples are back.");
|
| 456 | - s->using_zeroes = FALSE;
|
| 457 | - }
|
| 458 | - /* read from our no-delay buffer and output */
|
| 459 | - refm = allocb(nbytes, 0);
|
| 460 | - if (ms_flow_controlled_bufferizer_read(&s->ref, refm->b_wptr, nbytes) == 0) {
|
| 461 | - ms_fatal("Should never happen");
|
| 462 | - }
|
| 463 | - refm->b_wptr += nbytes;
|
| 464 | - ms_queue_put(f->outputs[0], refm);
|
| 465 | - }
|
| 466 | -
|
| 467 | - /*now read a valid buffer of delayed ref samples*/
|
| 468 | - if (ms_bufferizer_read(&s->delayed_ref, (uint8_t *)ref, nbytes) == 0) {
|
| 469 | - ms_fatal("Should never happen");
|
| 470 | - }
|
| 471 | - avail -= nbytes;
|
| 472 | - avail_samples = avail / 2;
|
| 473 | + while (ms_bufferizer_read(&s->echo, (uint8_t *)echo, (size_t)nbytes) >=
|
| 474 | + (size_t)nbytes) {
|
| 475 | + mblk_t *oecho = allocb(nbytes, 0);
|
| 476 | + int avail;
|
| 477 | + int avail_samples;
|
| 478 | +
|
| 479 | + if (!s->echostarted)
|
| 480 | + s->echostarted = TRUE;
|
| 481 | + if ((avail = ms_bufferizer_get_avail(&s->delayed_ref)) <
|
| 482 | + ((s->nominal_ref_samples * 2) + nbytes)) {
|
| 483 | + /*we don't have enough to read in a reference signal buffer, inject
|
| 484 | + * silence instead*/
|
| 485 | + refm = allocb(nbytes, 0);
|
| 486 | + memset(refm->b_wptr, 0, nbytes);
|
| 487 | + refm->b_wptr += nbytes;
|
| 488 | + ms_bufferizer_put(&s->delayed_ref, refm);
|
| 489 | + /*
|
| 490 | + * However, we don't inject this silence buffer to the sound card, in
|
| 491 | + * order to break the following bad loop:
|
| 492 | + * - the sound playback filter detects it has too many pending samples,
|
| 493 | + * then triggers an event to request samples to be dropped upstream.
|
| 494 | + * - the upstream MSFlowControl filter is requested to drop samples, which
|
| 495 | + * it starts to do.
|
| 496 | + * - necessarily shortly after the AEC goes into a situation where it has
|
| 497 | + * not enough reference samples while processing an audio buffer from mic.
|
| 498 | + * - if the AEC injects a silence buffer as output, then it will RECREATE
|
| 499 | + * a situation where the sound playback filter has too many pending
|
| 500 | + * samples. That's why we should not do this. By not doing this, we will
|
| 501 | + * create a discrepancy between what we really injected to the soundcard,
|
| 502 | + * and what we told to the echo canceller about the samples we injected.
|
| 503 | + * This shifts the echo. The echo canceller will re-converge quickly to
|
| 504 | + * take into account the situation.
|
| 505 | + *
|
| 506 | + */
|
| 507 | + // ms_queue_put(f->outputs[0], dupmsg(refm));
|
| 508 | + if (!s->using_zeroes) {
|
| 509 | + ms_warning("Not enough ref samples, using zeroes");
|
| 510 | + s->using_zeroes = TRUE;
|
| 511 | + }
|
| 512 | + } else {
|
| 513 | + if (s->using_zeroes) {
|
| 514 | + ms_message("Samples are back.");
|
| 515 | + s->using_zeroes = FALSE;
|
| 516 | + }
|
| 517 | + /* read from our no-delay buffer and output */
|
| 518 | + refm = allocb(nbytes, 0);
|
| 519 | + if (ms_flow_controlled_bufferizer_read(&s->ref, refm->b_wptr, nbytes) ==
|
| 520 | + 0) {
|
| 521 | + ms_fatal("Should never happen");
|
| 522 | + }
|
| 523 | + refm->b_wptr += nbytes;
|
| 524 | + ms_queue_put(f->outputs[0], refm);
|
| 525 | + }
|
| 526 | +
|
| 527 | + /*now read a valid buffer of delayed ref samples*/
|
| 528 | + if (ms_bufferizer_read(&s->delayed_ref, (uint8_t *)ref, nbytes) == 0) {
|
| 529 | + ms_fatal("Should never happen");
|
| 530 | + }
|
| 531 | + avail -= nbytes;
|
| 532 | + avail_samples = avail / 2;
|
| 533 |
|
| 534 | #ifdef EC_DUMP
|
| 535 | - if (s->reffile)
|
| 536 | - fwrite(ref, nbytes, 1, s->reffile);
|
| 537 | - if (s->echofile)
|
| 538 | - fwrite(echo, nbytes, 1, s->echofile);
|
| 539 | + if (s->reffile)
|
| 540 | + fwrite(ref, nbytes, 1, s->reffile);
|
| 541 | + if (s->echofile)
|
| 542 | + fwrite(echo, nbytes, 1, s->echofile);
|
| 543 | #endif
|
| 544 | #ifdef BUILD_AEC
|
| 545 | - if (s->aec_type == WebRTCAECTypeNormal) {
|
| 546 | - mswebrtc_aec_splitting_filter_analysis(s->splitting_filter, ref, echo);
|
| 547 | - if (WebRtcAec_BufferFarend(s->aecInst,
|
| 548 | - mswebrtc_aec_splitting_filter_get_ref(s->splitting_filter),
|
| 549 | - (size_t)mswebrtc_aec_splitting_filter_get_bandsize(s->splitting_filter)) != 0)
|
| 550 | - ms_error("WebRtcAec_BufferFarend() failed.");
|
| 551 | - if (WebRtcAec_Process(s->aecInst,
|
| 552 | - mswebrtc_aec_splitting_filter_get_echo_bands(s->splitting_filter),
|
| 553 | - mswebrtc_aec_splitting_filter_get_number_of_bands(s->splitting_filter),
|
| 554 | - mswebrtc_aec_splitting_filter_get_output_bands(s->splitting_filter),
|
| 555 | - (size_t)mswebrtc_aec_splitting_filter_get_bandsize(s->splitting_filter), 0, 0) != 0)
|
| 556 | - ms_error("WebRtcAec_Process() failed.");
|
| 557 | - mswebrtc_aec_splitting_filter_synthesis(s->splitting_filter, (int16_t *)oecho->b_wptr);
|
| 558 | - }
|
| 559 | + if (s->aec_type == WebRTCAECTypeNormal) {
|
| 560 | + mswebrtc_aec_splitting_filter_analysis(s->splitting_filter, ref, echo);
|
| 561 | + if (WebRtcAec_BufferFarend(
|
| 562 | + s->aecInst,
|
| 563 | + mswebrtc_aec_splitting_filter_get_ref(s->splitting_filter),
|
| 564 | + (size_t)mswebrtc_aec_splitting_filter_get_bandsize(
|
| 565 | + s->splitting_filter)) != 0)
|
| 566 | + ms_error("WebRtcAec_BufferFarend() failed.");
|
| 567 | + if (WebRtcAec_Process(
|
| 568 | + s->aecInst,
|
| 569 | + mswebrtc_aec_splitting_filter_get_echo_bands(s->splitting_filter),
|
| 570 | + mswebrtc_aec_splitting_filter_get_number_of_bands(
|
| 571 | + s->splitting_filter),
|
| 572 | + mswebrtc_aec_splitting_filter_get_output_bands(
|
| 573 | + s->splitting_filter),
|
| 574 | + (size_t)mswebrtc_aec_splitting_filter_get_bandsize(
|
| 575 | + s->splitting_filter),
|
| 576 | + 0, 0) != 0)
|
| 577 | + ms_error("WebRtcAec_Process() failed.");
|
| 578 | + mswebrtc_aec_splitting_filter_synthesis(s->splitting_filter,
|
| 579 | + (int16_t *)oecho->b_wptr);
|
| 580 | + }
|
| 581 | #endif
|
| 582 | #ifdef BUILD_AECM
|
| 583 | - if (s->aec_type == WebRTCAECTypeMobile) {
|
| 584 | - if (WebRtcAecm_BufferFarend(s->aecInst, ref, (size_t)s->framesize) != 0)
|
| 585 | - ms_error("WebRtcAecm_BufferFarend() failed.");
|
| 586 | - if (WebRtcAecm_Process(s->aecInst, echo, NULL, (int16_t *)oecho->b_wptr, (size_t)s->framesize, 0) != 0)
|
| 587 | - ms_error("WebRtcAecm_Process() failed.");
|
| 588 | - }
|
| 589 | + if (s->aec_type == WebRTCAECTypeMobile) {
|
| 590 | + if (WebRtcAecm_BufferFarend(s->aecInst, ref, (size_t)s->framesize) != 0)
|
| 591 | + ms_error("WebRtcAecm_BufferFarend() failed.");
|
| 592 | + if (WebRtcAecm_Process(s->aecInst, echo, NULL, (int16_t *)oecho->b_wptr,
|
| 593 | + (size_t)s->framesize, 0) != 0)
|
| 594 | + ms_error("WebRtcAecm_Process() failed.");
|
| 595 | + }
|
| 596 | #endif
|
| 597 | #ifdef EC_DUMP
|
| 598 | - if (s->cleanfile)
|
| 599 | - fwrite(oecho->b_wptr, nbytes, 1, s->cleanfile);
|
| 600 | + if (s->cleanfile)
|
| 601 | + fwrite(oecho->b_wptr, nbytes, 1, s->cleanfile);
|
| 602 | #endif
|
| 603 | - oecho->b_wptr += nbytes;
|
| 604 | - ms_queue_put(f->outputs[1], oecho);
|
| 605 | - }
|
| 606 | + oecho->b_wptr += nbytes;
|
| 607 | + ms_queue_put(f->outputs[1], oecho);
|
| 608 | + }
|
| 609 | }
|
| 610 |
|
| 611 | static void webrtc_aec_postprocess(MSFilter *f) {
|
| 612 | - WebRTCAECState *s = (WebRTCAECState *) f->data;
|
| 613 | + WebRTCAECState *s = (WebRTCAECState *)f->data;
|
| 614 |
|
| 615 | - ms_bufferizer_flush(&s->delayed_ref);
|
| 616 | - ms_bufferizer_flush(&s->echo);
|
| 617 | - ms_flow_controlled_bufferizer_flush(&s->ref);
|
| 618 | + ms_bufferizer_flush(&s->delayed_ref);
|
| 619 | + ms_bufferizer_flush(&s->echo);
|
| 620 | + ms_flow_controlled_bufferizer_flush(&s->ref);
|
| 621 | #ifdef BUILD_AEC
|
| 622 | - if (s->splitting_filter) {
|
| 623 | - mswebrtc_aec_splitting_filter_destroy(s->splitting_filter);
|
| 624 | - s->splitting_filter = NULL;
|
| 625 | - }
|
| 626 | + if (s->splitting_filter) {
|
| 627 | + mswebrtc_aec_splitting_filter_destroy(s->splitting_filter);
|
| 628 | + s->splitting_filter = NULL;
|
| 629 | + }
|
| 630 | #endif
|
| 631 | - if (s->aecInst != NULL) {
|
| 632 | + if (s->aecInst != NULL) {
|
| 633 | #ifdef BUILD_AEC
|
| 634 | - if (s->aec_type == WebRTCAECTypeNormal) {
|
| 635 | - WebRtcAec_Free(s->aecInst);
|
| 636 | - }
|
| 637 | + if (s->aec_type == WebRTCAECTypeNormal) {
|
| 638 | + WebRtcAec_Free(s->aecInst);
|
| 639 | + }
|
| 640 | #endif
|
| 641 | #ifdef BUILD_AECM
|
| 642 | - if (s->aec_type == WebRTCAECTypeMobile) {
|
| 643 | - WebRtcAecm_Free(s->aecInst);
|
| 644 | - }
|
| 645 | + if (s->aec_type == WebRTCAECTypeMobile) {
|
| 646 | + WebRtcAecm_Free(s->aecInst);
|
| 647 | + }
|
| 648 | #endif
|
| 649 | - s->aecInst = NULL;
|
| 650 | - }
|
| 651 | + s->aecInst = NULL;
|
| 652 | + }
|
| 653 | }
|
| 654 |
|
| 655 | static int webrtc_aec_set_sr(MSFilter *f, void *arg) {
|
| 656 | - WebRTCAECState *s = (WebRTCAECState *) f->data;
|
| 657 | - int requested_sr = *(int *) arg;
|
| 658 | - int sr = requested_sr;
|
| 659 | -
|
| 660 | - if ((s->aec_type == WebRTCAECTypeNormal) && (requested_sr >= 48000)) {
|
| 661 | - sr = 48000;
|
| 662 | - } else if ((s->aec_type == WebRTCAECTypeNormal) && (requested_sr >= 32000)) {
|
| 663 | - sr = 32000;
|
| 664 | - } else if (requested_sr >= 16000) {
|
| 665 | - sr = 16000;
|
| 666 | - } else {
|
| 667 | - sr = 8000;
|
| 668 | - }
|
| 669 | - if (sr != requested_sr)
|
| 670 | - ms_message("Webrtc %s does not support sampling rate %i, using %i instead", ((s->aec_type == WebRTCAECTypeNormal)?"aec":"aecm"),requested_sr, sr);
|
| 671 | -
|
| 672 | - s->samplerate = sr;
|
| 673 | - configure_flow_controlled_bufferizer(s);
|
| 674 | - return 0;
|
| 675 | + WebRTCAECState *s = (WebRTCAECState *)f->data;
|
| 676 | + int requested_sr = *(int *)arg;
|
| 677 | + int sr = requested_sr;
|
| 678 | +
|
| 679 | + if ((s->aec_type == WebRTCAECTypeNormal) && (requested_sr >= 48000)) {
|
| 680 | + sr = 48000;
|
| 681 | + } else if ((s->aec_type == WebRTCAECTypeNormal) && (requested_sr >= 32000)) {
|
| 682 | + sr = 32000;
|
| 683 | + } else if (requested_sr >= 16000) {
|
| 684 | + sr = 16000;
|
| 685 | + } else {
|
| 686 | + sr = 8000;
|
| 687 | + }
|
| 688 | + if (sr != requested_sr)
|
| 689 | + ms_message("Webrtc %s does not support sampling rate %i, using %i instead",
|
| 690 | + ((s->aec_type == WebRTCAECTypeNormal) ? "aec" : "aecm"),
|
| 691 | + requested_sr, sr);
|
| 692 | +
|
| 693 | + s->samplerate = sr;
|
| 694 | + configure_flow_controlled_bufferizer(s);
|
| 695 | + return 0;
|
| 696 | }
|
| 697 |
|
| 698 | static int webrtc_aec_get_sr(MSFilter *f, void *arg) {
|
| 699 | - WebRTCAECState *s = (WebRTCAECState *) f->data;
|
| 700 | - *(int *) arg=s->samplerate;
|
| 701 | - return 0;
|
| 702 | + WebRTCAECState *s = (WebRTCAECState *)f->data;
|
| 703 | + *(int *)arg = s->samplerate;
|
| 704 | + return 0;
|
| 705 | }
|
| 706 |
|
| 707 | static int webrtc_aec_set_framesize(MSFilter *f, void *arg) {
|
| 708 | - /* Do nothing because the WebRTC echo canceller only accept specific values: 80 and 160. We use 80 at 8khz, and 160 at 16khz */
|
| 709 | - return 0;
|
| 710 | + /* Do nothing because the WebRTC echo canceller only accept specific values:
|
| 711 | + * 80 and 160. We use 80 at 8khz, and 160 at 16khz */
|
| 712 | + return 0;
|
| 713 | }
|
| 714 |
|
| 715 | static int webrtc_aec_set_delay(MSFilter *f, void *arg) {
|
| 716 | - WebRTCAECState *s = (WebRTCAECState *) f->data;
|
| 717 | - s->delay_ms = *(int *) arg;
|
| 718 | - configure_flow_controlled_bufferizer(s);
|
| 719 | - return 0;
|
| 720 | + WebRTCAECState *s = (WebRTCAECState *)f->data;
|
| 721 | + s->delay_ms = *(int *)arg;
|
| 722 | + configure_flow_controlled_bufferizer(s);
|
| 723 | + return 0;
|
| 724 | }
|
| 725 |
|
| 726 | static int webrtc_aec_set_tail_length(MSFilter *f, void *arg) {
|
| 727 | - /* Do nothing because this is not needed by the WebRTC echo canceller. */
|
| 728 | - return 0;
|
| 729 | + /* Do nothing because this is not needed by the WebRTC echo canceller. */
|
| 730 | + return 0;
|
| 731 | }
|
| 732 | static int webrtc_aec_set_bypass_mode(MSFilter *f, void *arg) {
|
| 733 | - WebRTCAECState *s = (WebRTCAECState *) f->data;
|
| 734 | - s->bypass_mode = *(bool_t *) arg;
|
| 735 | - ms_message("set EC bypass mode to [%i]", s->bypass_mode);
|
| 736 | - return 0;
|
| 737 | + WebRTCAECState *s = (WebRTCAECState *)f->data;
|
| 738 | + s->bypass_mode = *(bool_t *)arg;
|
| 739 | + ms_message("set EC bypass mode to [%i]", s->bypass_mode);
|
| 740 | + return 0;
|
| 741 | }
|
| 742 | static int webrtc_aec_get_bypass_mode(MSFilter *f, void *arg) {
|
| 743 | - WebRTCAECState *s = (WebRTCAECState *) f->data;
|
| 744 | - *(bool_t *) arg = s->bypass_mode;
|
| 745 | - return 0;
|
| 746 | + WebRTCAECState *s = (WebRTCAECState *)f->data;
|
| 747 | + *(bool_t *)arg = s->bypass_mode;
|
| 748 | + return 0;
|
| 749 | }
|
| 750 |
|
| 751 | static int webrtc_aec_set_state(MSFilter *f, void *arg) {
|
| 752 | - WebRTCAECState *s = (WebRTCAECState *) f->data;
|
| 753 | - s->state_str = ms_strdup((const char *) arg);
|
| 754 | - return 0;
|
| 755 | + WebRTCAECState *s = (WebRTCAECState *)f->data;
|
| 756 | + s->state_str = ms_strdup((const char *)arg);
|
| 757 | + return 0;
|
| 758 | }
|
| 759 |
|
| 760 | static int webrtc_aec_get_state(MSFilter *f, void *arg) {
|
| 761 | - WebRTCAECState *s = (WebRTCAECState *) f->data;
|
| 762 | - *(char **) arg = s->state_str;
|
| 763 | - return 0;
|
| 764 | + WebRTCAECState *s = (WebRTCAECState *)f->data;
|
| 765 | + *(char **)arg = s->state_str;
|
| 766 | + return 0;
|
| 767 | }
|
| 768 |
|
| 769 | static MSFilterMethod webrtc_aec_methods[] = {
|
| 770 | - { MS_FILTER_SET_SAMPLE_RATE , webrtc_aec_set_sr },
|
| 771 | - { MS_FILTER_GET_SAMPLE_RATE , webrtc_aec_get_sr },
|
| 772 | - { MS_ECHO_CANCELLER_SET_TAIL_LENGTH , webrtc_aec_set_tail_length },
|
| 773 | - { MS_ECHO_CANCELLER_SET_DELAY , webrtc_aec_set_delay },
|
| 774 | - { MS_ECHO_CANCELLER_SET_FRAMESIZE , webrtc_aec_set_framesize },
|
| 775 | - { MS_ECHO_CANCELLER_SET_BYPASS_MODE , webrtc_aec_set_bypass_mode },
|
| 776 | - { MS_ECHO_CANCELLER_GET_BYPASS_MODE , webrtc_aec_get_bypass_mode },
|
| 777 | - { MS_ECHO_CANCELLER_GET_STATE_STRING , webrtc_aec_get_state },
|
| 778 | - { MS_ECHO_CANCELLER_SET_STATE_STRING , webrtc_aec_set_state },
|
| 779 | - { 0, NULL }
|
| 780 | -};
|
| 781 | -
|
| 782 | + {MS_FILTER_SET_SAMPLE_RATE, webrtc_aec_set_sr},
|
| 783 | + {MS_FILTER_GET_SAMPLE_RATE, webrtc_aec_get_sr},
|
| 784 | + {MS_ECHO_CANCELLER_SET_TAIL_LENGTH, webrtc_aec_set_tail_length},
|
| 785 | + {MS_ECHO_CANCELLER_SET_DELAY, webrtc_aec_set_delay},
|
| 786 | + {MS_ECHO_CANCELLER_SET_FRAMESIZE, webrtc_aec_set_framesize},
|
| 787 | + {MS_ECHO_CANCELLER_SET_BYPASS_MODE, webrtc_aec_set_bypass_mode},
|
| 788 | + {MS_ECHO_CANCELLER_GET_BYPASS_MODE, webrtc_aec_get_bypass_mode},
|
| 789 | + {MS_ECHO_CANCELLER_GET_STATE_STRING, webrtc_aec_get_state},
|
| 790 | + {MS_ECHO_CANCELLER_SET_STATE_STRING, webrtc_aec_set_state},
|
| 791 | + {0, NULL}};
|
| 792 |
|
| 793 | #ifdef BUILD_AEC
|
| 794 |
|
| 795 | -#define MS_WEBRTC_AEC_NAME "MSWebRTCAEC"
|
| 796 | +#define MS_WEBRTC_AEC_NAME "MSWebRTCAEC"
|
| 797 | #define MS_WEBRTC_AEC_DESCRIPTION "Echo canceller using WebRTC library."
|
| 798 | -#define MS_WEBRTC_AEC_CATEGORY MS_FILTER_OTHER
|
| 799 | -#define MS_WEBRTC_AEC_ENC_FMT NULL
|
| 800 | -#define MS_WEBRTC_AEC_NINPUTS 2
|
| 801 | -#define MS_WEBRTC_AEC_NOUTPUTS 2
|
| 802 | -#define MS_WEBRTC_AEC_FLAGS 0
|
| 803 | +#define MS_WEBRTC_AEC_CATEGORY MS_FILTER_OTHER
|
| 804 | +#define MS_WEBRTC_AEC_ENC_FMT NULL
|
| 805 | +#define MS_WEBRTC_AEC_NINPUTS 2
|
| 806 | +#define MS_WEBRTC_AEC_NOUTPUTS 2
|
| 807 | +#define MS_WEBRTC_AEC_FLAGS 0
|
| 808 |
|
| 809 | #ifdef _MSC_VER
|
| 810 |
|
| 811 | MSFilterDesc ms_webrtc_aec_desc = {
|
| 812 | - MS_FILTER_PLUGIN_ID,
|
| 813 | - MS_WEBRTC_AEC_NAME,
|
| 814 | - MS_WEBRTC_AEC_DESCRIPTION,
|
| 815 | - MS_WEBRTC_AEC_CATEGORY,
|
| 816 | - MS_WEBRTC_AEC_ENC_FMT,
|
| 817 | - MS_WEBRTC_AEC_NINPUTS,
|
| 818 | - MS_WEBRTC_AEC_NOUTPUTS,
|
| 819 | - webrtc_aec_init,
|
| 820 | - webrtc_aec_preprocess,
|
| 821 | - webrtc_aec_process,
|
| 822 | - webrtc_aec_postprocess,
|
| 823 | - webrtc_aec_uninit,
|
| 824 | - webrtc_aec_methods,
|
| 825 | - MS_WEBRTC_AEC_FLAGS
|
| 826 | -};
|
| 827 | + MS_FILTER_PLUGIN_ID, MS_WEBRTC_AEC_NAME, MS_WEBRTC_AEC_DESCRIPTION,
|
| 828 | + MS_WEBRTC_AEC_CATEGORY, MS_WEBRTC_AEC_ENC_FMT, MS_WEBRTC_AEC_NINPUTS,
|
| 829 | + MS_WEBRTC_AEC_NOUTPUTS, webrtc_aec_init, webrtc_aec_preprocess,
|
| 830 | + webrtc_aec_process, webrtc_aec_postprocess, webrtc_aec_uninit,
|
| 831 | + webrtc_aec_methods, MS_WEBRTC_AEC_FLAGS};
|
| 832 |
|
| 833 | #else
|
| 834 |
|
| 835 | -MSFilterDesc ms_webrtc_aec_desc = {
|
| 836 | - .id = MS_FILTER_PLUGIN_ID,
|
| 837 | - .name = MS_WEBRTC_AEC_NAME,
|
| 838 | - .text = MS_WEBRTC_AEC_DESCRIPTION,
|
| 839 | - .category = MS_WEBRTC_AEC_CATEGORY,
|
| 840 | - .enc_fmt = MS_WEBRTC_AEC_ENC_FMT,
|
| 841 | - .ninputs = MS_WEBRTC_AEC_NINPUTS,
|
| 842 | - .noutputs = MS_WEBRTC_AEC_NOUTPUTS,
|
| 843 | - .init = webrtc_aec_init,
|
| 844 | - .preprocess = webrtc_aec_preprocess,
|
| 845 | - .process = webrtc_aec_process,
|
| 846 | - .postprocess = webrtc_aec_postprocess,
|
| 847 | - .uninit = webrtc_aec_uninit,
|
| 848 | - .methods = webrtc_aec_methods,
|
| 849 | - .flags = MS_WEBRTC_AEC_FLAGS
|
| 850 | -};
|
| 851 | +MSFilterDesc ms_webrtc_aec_desc = {.id = MS_FILTER_PLUGIN_ID,
|
| 852 | + .name = MS_WEBRTC_AEC_NAME,
|
| 853 | + .text = MS_WEBRTC_AEC_DESCRIPTION,
|
| 854 | + .category = MS_WEBRTC_AEC_CATEGORY,
|
| 855 | + .enc_fmt = MS_WEBRTC_AEC_ENC_FMT,
|
| 856 | + .ninputs = MS_WEBRTC_AEC_NINPUTS,
|
| 857 | + .noutputs = MS_WEBRTC_AEC_NOUTPUTS,
|
| 858 | + .init = webrtc_aec_init,
|
| 859 | + .preprocess = webrtc_aec_preprocess,
|
| 860 | + .process = webrtc_aec_process,
|
| 861 | + .postprocess = webrtc_aec_postprocess,
|
| 862 | + .uninit = webrtc_aec_uninit,
|
| 863 | + .methods = webrtc_aec_methods,
|
| 864 | + .flags = MS_WEBRTC_AEC_FLAGS};
|
| 865 |
|
| 866 | #endif
|
| 867 |
|
| 868 | @@ -517,51 +535,40 @@ MS_FILTER_DESC_EXPORT(ms_webrtc_aec_desc)
|
| 869 |
|
| 870 | #ifdef BUILD_AECM
|
| 871 |
|
| 872 | -#define MS_WEBRTC_AECM_NAME "MSWebRTCAECM"
|
| 873 | -#define MS_WEBRTC_AECM_DESCRIPTION "Echo canceller for mobile using WebRTC library."
|
| 874 | -#define MS_WEBRTC_AECM_CATEGORY MS_FILTER_OTHER
|
| 875 | -#define MS_WEBRTC_AECM_ENC_FMT NULL
|
| 876 | -#define MS_WEBRTC_AECM_NINPUTS 2
|
| 877 | -#define MS_WEBRTC_AECM_NOUTPUTS 2
|
| 878 | -#define MS_WEBRTC_AECM_FLAGS 0
|
| 879 | +#define MS_WEBRTC_AECM_NAME "MSWebRTCAECM"
|
| 880 | +#define MS_WEBRTC_AECM_DESCRIPTION \
|
| 881 | + "Echo canceller for mobile using WebRTC library."
|
| 882 | +#define MS_WEBRTC_AECM_CATEGORY MS_FILTER_OTHER
|
| 883 | +#define MS_WEBRTC_AECM_ENC_FMT NULL
|
| 884 | +#define MS_WEBRTC_AECM_NINPUTS 2
|
| 885 | +#define MS_WEBRTC_AECM_NOUTPUTS 2
|
| 886 | +#define MS_WEBRTC_AECM_FLAGS 0
|
| 887 |
|
| 888 | #ifdef _MSC_VER
|
| 889 |
|
| 890 | MSFilterDesc ms_webrtc_aecm_desc = {
|
| 891 | - MS_FILTER_PLUGIN_ID,
|
| 892 | - MS_WEBRTC_AECM_NAME,
|
| 893 | - MS_WEBRTC_AECM_DESCRIPTION,
|
| 894 | - MS_WEBRTC_AECM_CATEGORY,
|
| 895 | - MS_WEBRTC_AECM_ENC_FMT,
|
| 896 | - MS_WEBRTC_AECM_NINPUTS,
|
| 897 | - MS_WEBRTC_AECM_NOUTPUTS,
|
| 898 | - webrtc_aecm_init,
|
| 899 | - webrtc_aec_preprocess,
|
| 900 | - webrtc_aec_process,
|
| 901 | - webrtc_aec_postprocess,
|
| 902 | - webrtc_aec_uninit,
|
| 903 | - webrtc_aec_methods,
|
| 904 | - MS_WEBRTC_AECM_FLAGS
|
| 905 | -};
|
| 906 | + MS_FILTER_PLUGIN_ID, MS_WEBRTC_AECM_NAME, MS_WEBRTC_AECM_DESCRIPTION,
|
| 907 | + MS_WEBRTC_AECM_CATEGORY, MS_WEBRTC_AECM_ENC_FMT, MS_WEBRTC_AECM_NINPUTS,
|
| 908 | + MS_WEBRTC_AECM_NOUTPUTS, webrtc_aecm_init, webrtc_aec_preprocess,
|
| 909 | + webrtc_aec_process, webrtc_aec_postprocess, webrtc_aec_uninit,
|
| 910 | + webrtc_aec_methods, MS_WEBRTC_AECM_FLAGS};
|
| 911 |
|
| 912 | #else
|
| 913 |
|
| 914 | -MSFilterDesc ms_webrtc_aecm_desc = {
|
| 915 | - .id = MS_FILTER_PLUGIN_ID,
|
| 916 | - .name = MS_WEBRTC_AECM_NAME,
|
| 917 | - .text = MS_WEBRTC_AECM_DESCRIPTION,
|
| 918 | - .category = MS_WEBRTC_AECM_CATEGORY,
|
| 919 | - .enc_fmt = MS_WEBRTC_AECM_ENC_FMT,
|
| 920 | - .ninputs = MS_WEBRTC_AECM_NINPUTS,
|
| 921 | - .noutputs = MS_WEBRTC_AECM_NOUTPUTS,
|
| 922 | - .init = webrtc_aecm_init,
|
| 923 | - .preprocess = webrtc_aec_preprocess,
|
| 924 | - .process = webrtc_aec_process,
|
| 925 | - .postprocess = webrtc_aec_postprocess,
|
| 926 | - .uninit = webrtc_aec_uninit,
|
| 927 | - .methods = webrtc_aec_methods,
|
| 928 | - .flags = MS_WEBRTC_AECM_FLAGS
|
| 929 | -};
|
| 930 | +MSFilterDesc ms_webrtc_aecm_desc = {.id = MS_FILTER_PLUGIN_ID,
|
| 931 | + .name = MS_WEBRTC_AECM_NAME,
|
| 932 | + .text = MS_WEBRTC_AECM_DESCRIPTION,
|
| 933 | + .category = MS_WEBRTC_AECM_CATEGORY,
|
| 934 | + .enc_fmt = MS_WEBRTC_AECM_ENC_FMT,
|
| 935 | + .ninputs = MS_WEBRTC_AECM_NINPUTS,
|
| 936 | + .noutputs = MS_WEBRTC_AECM_NOUTPUTS,
|
| 937 | + .init = webrtc_aecm_init,
|
| 938 | + .preprocess = webrtc_aec_preprocess,
|
| 939 | + .process = webrtc_aec_process,
|
| 940 | + .postprocess = webrtc_aec_postprocess,
|
| 941 | + .uninit = webrtc_aec_uninit,
|
| 942 | + .methods = webrtc_aec_methods,
|
| 943 | + .flags = MS_WEBRTC_AECM_FLAGS};
|
| 944 |
|
| 945 | #endif
|
| 946 |
|
| 947 | --
|
| 948 | GitLab
|
| 949 |
|