OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include "webrtc/modules/audio_processing/aecm/echo_control_mobile.h" | 11 #include "webrtc/modules/audio_processing/aecm/echo_control_mobile.h" |
12 | 12 |
13 #ifdef AEC_DEBUG | 13 #ifdef AEC_DEBUG |
14 #include <stdio.h> | 14 #include <stdio.h> |
15 #endif | 15 #endif |
16 #include <stdlib.h> | 16 #include <stdlib.h> |
17 | 17 |
| 18 extern "C" { |
18 #include "webrtc/common_audio/ring_buffer.h" | 19 #include "webrtc/common_audio/ring_buffer.h" |
19 #include "webrtc/common_audio/signal_processing/include/signal_processing_librar
y.h" | 20 #include "webrtc/common_audio/signal_processing/include/signal_processing_librar
y.h" |
| 21 } |
20 #include "webrtc/modules/audio_processing/aecm/aecm_core.h" | 22 #include "webrtc/modules/audio_processing/aecm/aecm_core.h" |
21 | 23 |
22 #define BUF_SIZE_FRAMES 50 // buffer size (frames) | 24 #define BUF_SIZE_FRAMES 50 // buffer size (frames) |
23 // Maximum length of resampled signal. Must be an integer multiple of frames | 25 // Maximum length of resampled signal. Must be an integer multiple of frames |
24 // (ceil(1/(1 + MIN_SKEW)*2) + 1)*FRAME_LEN | 26 // (ceil(1/(1 + MIN_SKEW)*2) + 1)*FRAME_LEN |
25 // The factor of 2 handles wb, and the + 1 is as a safety margin | 27 // The factor of 2 handles wb, and the + 1 is as a safety margin |
26 #define MAX_RESAMP_LEN (5 * FRAME_LEN) | 28 #define MAX_RESAMP_LEN (5 * FRAME_LEN) |
27 | 29 |
28 static const size_t kBufSizeSamp = BUF_SIZE_FRAMES * FRAME_LEN; // buffer size (
samples) | 30 static const size_t kBufSizeSamp = BUF_SIZE_FRAMES * FRAME_LEN; // buffer size (
samples) |
29 static const int kSampMsNb = 8; // samples per ms in nb | 31 static const int kSampMsNb = 8; // samples per ms in nb |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 } AecMobile; | 74 } AecMobile; |
73 | 75 |
74 // Estimates delay to set the position of the farend buffer read pointer | 76 // Estimates delay to set the position of the farend buffer read pointer |
75 // (controlled by knownDelay) | 77 // (controlled by knownDelay) |
76 static int WebRtcAecm_EstBufDelay(AecMobile* aecmInst, short msInSndCardBuf); | 78 static int WebRtcAecm_EstBufDelay(AecMobile* aecmInst, short msInSndCardBuf); |
77 | 79 |
78 // Stuffs the farend buffer if the estimated delay is too large | 80 // Stuffs the farend buffer if the estimated delay is too large |
79 static int WebRtcAecm_DelayComp(AecMobile* aecmInst); | 81 static int WebRtcAecm_DelayComp(AecMobile* aecmInst); |
80 | 82 |
81 void* WebRtcAecm_Create() { | 83 void* WebRtcAecm_Create() { |
82 AecMobile* aecm = malloc(sizeof(AecMobile)); | 84 AecMobile* aecm = static_cast<AecMobile*>(malloc(sizeof(AecMobile))); |
83 | 85 |
84 WebRtcSpl_Init(); | 86 WebRtcSpl_Init(); |
85 | 87 |
86 aecm->aecmCore = WebRtcAecm_CreateCore(); | 88 aecm->aecmCore = WebRtcAecm_CreateCore(); |
87 if (!aecm->aecmCore) { | 89 if (!aecm->aecmCore) { |
88 WebRtcAecm_Free(aecm); | 90 WebRtcAecm_Free(aecm); |
89 return NULL; | 91 return NULL; |
90 } | 92 } |
91 | 93 |
92 aecm->farendBuf = WebRtc_CreateBuffer(kBufSizeSamp, | 94 aecm->farendBuf = WebRtc_CreateBuffer(kBufSizeSamp, |
(...skipping 14 matching lines...) Expand all Loading... |
107 | 109 |
108 aecm->bufFile = fopen("aecBuf.dat", "wb"); | 110 aecm->bufFile = fopen("aecBuf.dat", "wb"); |
109 aecm->delayFile = fopen("aecDelay.dat", "wb"); | 111 aecm->delayFile = fopen("aecDelay.dat", "wb"); |
110 aecm->preCompFile = fopen("preComp.pcm", "wb"); | 112 aecm->preCompFile = fopen("preComp.pcm", "wb"); |
111 aecm->postCompFile = fopen("postComp.pcm", "wb"); | 113 aecm->postCompFile = fopen("postComp.pcm", "wb"); |
112 #endif // AEC_DEBUG | 114 #endif // AEC_DEBUG |
113 return aecm; | 115 return aecm; |
114 } | 116 } |
115 | 117 |
116 void WebRtcAecm_Free(void* aecmInst) { | 118 void WebRtcAecm_Free(void* aecmInst) { |
117 AecMobile* aecm = aecmInst; | 119 AecMobile* aecm = static_cast<AecMobile*>(aecmInst); |
118 | 120 |
119 if (aecm == NULL) { | 121 if (aecm == NULL) { |
120 return; | 122 return; |
121 } | 123 } |
122 | 124 |
123 #ifdef AEC_DEBUG | 125 #ifdef AEC_DEBUG |
124 fclose(aecm->aecmCore->farFile); | 126 fclose(aecm->aecmCore->farFile); |
125 fclose(aecm->aecmCore->nearFile); | 127 fclose(aecm->aecmCore->nearFile); |
126 fclose(aecm->aecmCore->outFile); | 128 fclose(aecm->aecmCore->outFile); |
127 //fclose(aecm->aecmCore->outLpFile); | 129 //fclose(aecm->aecmCore->outLpFile); |
128 | 130 |
129 fclose(aecm->bufFile); | 131 fclose(aecm->bufFile); |
130 fclose(aecm->delayFile); | 132 fclose(aecm->delayFile); |
131 fclose(aecm->preCompFile); | 133 fclose(aecm->preCompFile); |
132 fclose(aecm->postCompFile); | 134 fclose(aecm->postCompFile); |
133 #endif // AEC_DEBUG | 135 #endif // AEC_DEBUG |
134 WebRtcAecm_FreeCore(aecm->aecmCore); | 136 WebRtcAecm_FreeCore(aecm->aecmCore); |
135 WebRtc_FreeBuffer(aecm->farendBuf); | 137 WebRtc_FreeBuffer(aecm->farendBuf); |
136 free(aecm); | 138 free(aecm); |
137 } | 139 } |
138 | 140 |
139 int32_t WebRtcAecm_Init(void *aecmInst, int32_t sampFreq) | 141 int32_t WebRtcAecm_Init(void *aecmInst, int32_t sampFreq) |
140 { | 142 { |
141 AecMobile* aecm = aecmInst; | 143 AecMobile* aecm = static_cast<AecMobile*>(aecmInst); |
142 AecmConfig aecConfig; | 144 AecmConfig aecConfig; |
143 | 145 |
144 if (aecm == NULL) | 146 if (aecm == NULL) |
145 { | 147 { |
146 return -1; | 148 return -1; |
147 } | 149 } |
148 | 150 |
149 if (sampFreq != 8000 && sampFreq != 16000) | 151 if (sampFreq != 8000 && sampFreq != 16000) |
150 { | 152 { |
151 return AECM_BAD_PARAMETER_ERROR; | 153 return AECM_BAD_PARAMETER_ERROR; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
189 return AECM_UNSPECIFIED_ERROR; | 191 return AECM_UNSPECIFIED_ERROR; |
190 } | 192 } |
191 | 193 |
192 return 0; | 194 return 0; |
193 } | 195 } |
194 | 196 |
195 // Returns any error that is caused when buffering the | 197 // Returns any error that is caused when buffering the |
196 // farend signal. | 198 // farend signal. |
197 int32_t WebRtcAecm_GetBufferFarendError(void *aecmInst, const int16_t *farend, | 199 int32_t WebRtcAecm_GetBufferFarendError(void *aecmInst, const int16_t *farend, |
198 size_t nrOfSamples) { | 200 size_t nrOfSamples) { |
199 AecMobile* aecm = aecmInst; | 201 AecMobile* aecm = static_cast<AecMobile*>(aecmInst); |
200 | 202 |
201 if (aecm == NULL) | 203 if (aecm == NULL) |
202 return -1; | 204 return -1; |
203 | 205 |
204 if (farend == NULL) | 206 if (farend == NULL) |
205 return AECM_NULL_POINTER_ERROR; | 207 return AECM_NULL_POINTER_ERROR; |
206 | 208 |
207 if (aecm->initFlag != kInitCheck) | 209 if (aecm->initFlag != kInitCheck) |
208 return AECM_UNINITIALIZED_ERROR; | 210 return AECM_UNINITIALIZED_ERROR; |
209 | 211 |
210 if (nrOfSamples != 80 && nrOfSamples != 160) | 212 if (nrOfSamples != 80 && nrOfSamples != 160) |
211 return AECM_BAD_PARAMETER_ERROR; | 213 return AECM_BAD_PARAMETER_ERROR; |
212 | 214 |
213 return 0; | 215 return 0; |
214 } | 216 } |
215 | 217 |
216 | 218 |
217 int32_t WebRtcAecm_BufferFarend(void *aecmInst, const int16_t *farend, | 219 int32_t WebRtcAecm_BufferFarend(void *aecmInst, const int16_t *farend, |
218 size_t nrOfSamples) { | 220 size_t nrOfSamples) { |
219 AecMobile* aecm = aecmInst; | 221 AecMobile* aecm = static_cast<AecMobile*>(aecmInst); |
220 | 222 |
221 const int32_t err = | 223 const int32_t err = |
222 WebRtcAecm_GetBufferFarendError(aecmInst, farend, nrOfSamples); | 224 WebRtcAecm_GetBufferFarendError(aecmInst, farend, nrOfSamples); |
223 | 225 |
224 if (err != 0) | 226 if (err != 0) |
225 return err; | 227 return err; |
226 | 228 |
227 // TODO(unknown): Is this really a good idea? | 229 // TODO(unknown): Is this really a good idea? |
228 if (!aecm->ECstartup) | 230 if (!aecm->ECstartup) |
229 { | 231 { |
230 WebRtcAecm_DelayComp(aecm); | 232 WebRtcAecm_DelayComp(aecm); |
231 } | 233 } |
232 | 234 |
233 WebRtc_WriteBuffer(aecm->farendBuf, farend, nrOfSamples); | 235 WebRtc_WriteBuffer(aecm->farendBuf, farend, nrOfSamples); |
234 | 236 |
235 return 0; | 237 return 0; |
236 } | 238 } |
237 | 239 |
238 int32_t WebRtcAecm_Process(void *aecmInst, const int16_t *nearendNoisy, | 240 int32_t WebRtcAecm_Process(void *aecmInst, const int16_t *nearendNoisy, |
239 const int16_t *nearendClean, int16_t *out, | 241 const int16_t *nearendClean, int16_t *out, |
240 size_t nrOfSamples, int16_t msInSndCardBuf) | 242 size_t nrOfSamples, int16_t msInSndCardBuf) |
241 { | 243 { |
242 AecMobile* aecm = aecmInst; | 244 AecMobile* aecm = static_cast<AecMobile*>(aecmInst); |
243 int32_t retVal = 0; | 245 int32_t retVal = 0; |
244 size_t i; | 246 size_t i; |
245 short nmbrOfFilledBuffers; | 247 short nmbrOfFilledBuffers; |
246 size_t nBlocks10ms; | 248 size_t nBlocks10ms; |
247 size_t nFrames; | 249 size_t nFrames; |
248 #ifdef AEC_DEBUG | 250 #ifdef AEC_DEBUG |
249 short msInAECBuf; | 251 short msInAECBuf; |
250 #endif | 252 #endif |
251 | 253 |
252 if (aecm == NULL) | 254 if (aecm == NULL) |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
428 (kSampMsNb * aecm->aecmCore->mult); | 430 (kSampMsNb * aecm->aecmCore->mult); |
429 fwrite(&msInAECBuf, 2, 1, aecm->bufFile); | 431 fwrite(&msInAECBuf, 2, 1, aecm->bufFile); |
430 fwrite(&(aecm->knownDelay), sizeof(aecm->knownDelay), 1, aecm->delayFile); | 432 fwrite(&(aecm->knownDelay), sizeof(aecm->knownDelay), 1, aecm->delayFile); |
431 #endif | 433 #endif |
432 | 434 |
433 return retVal; | 435 return retVal; |
434 } | 436 } |
435 | 437 |
436 int32_t WebRtcAecm_set_config(void *aecmInst, AecmConfig config) | 438 int32_t WebRtcAecm_set_config(void *aecmInst, AecmConfig config) |
437 { | 439 { |
438 AecMobile* aecm = aecmInst; | 440 AecMobile* aecm = static_cast<AecMobile*>(aecmInst); |
439 | 441 |
440 if (aecm == NULL) | 442 if (aecm == NULL) |
441 { | 443 { |
442 return -1; | 444 return -1; |
443 } | 445 } |
444 | 446 |
445 if (aecm->initFlag != kInitCheck) | 447 if (aecm->initFlag != kInitCheck) |
446 { | 448 { |
447 return AECM_UNINITIALIZED_ERROR; | 449 return AECM_UNINITIALIZED_ERROR; |
448 } | 450 } |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
509 - (SUPGAIN_ERROR_PARAM_D << 1); | 511 - (SUPGAIN_ERROR_PARAM_D << 1); |
510 } | 512 } |
511 | 513 |
512 return 0; | 514 return 0; |
513 } | 515 } |
514 | 516 |
515 int32_t WebRtcAecm_InitEchoPath(void* aecmInst, | 517 int32_t WebRtcAecm_InitEchoPath(void* aecmInst, |
516 const void* echo_path, | 518 const void* echo_path, |
517 size_t size_bytes) | 519 size_t size_bytes) |
518 { | 520 { |
519 AecMobile* aecm = aecmInst; | 521 AecMobile* aecm = static_cast<AecMobile*>(aecmInst); |
520 const int16_t* echo_path_ptr = echo_path; | 522 const int16_t* echo_path_ptr = static_cast<const int16_t*>(echo_path); |
521 | 523 |
522 if (aecmInst == NULL) { | 524 if (aecmInst == NULL) { |
523 return -1; | 525 return -1; |
524 } | 526 } |
525 if (echo_path == NULL) { | 527 if (echo_path == NULL) { |
526 return AECM_NULL_POINTER_ERROR; | 528 return AECM_NULL_POINTER_ERROR; |
527 } | 529 } |
528 if (size_bytes != WebRtcAecm_echo_path_size_bytes()) | 530 if (size_bytes != WebRtcAecm_echo_path_size_bytes()) |
529 { | 531 { |
530 // Input channel size does not match the size of AECM | 532 // Input channel size does not match the size of AECM |
531 return AECM_BAD_PARAMETER_ERROR; | 533 return AECM_BAD_PARAMETER_ERROR; |
532 } | 534 } |
533 if (aecm->initFlag != kInitCheck) | 535 if (aecm->initFlag != kInitCheck) |
534 { | 536 { |
535 return AECM_UNINITIALIZED_ERROR; | 537 return AECM_UNINITIALIZED_ERROR; |
536 } | 538 } |
537 | 539 |
538 WebRtcAecm_InitEchoPathCore(aecm->aecmCore, echo_path_ptr); | 540 WebRtcAecm_InitEchoPathCore(aecm->aecmCore, echo_path_ptr); |
539 | 541 |
540 return 0; | 542 return 0; |
541 } | 543 } |
542 | 544 |
543 int32_t WebRtcAecm_GetEchoPath(void* aecmInst, | 545 int32_t WebRtcAecm_GetEchoPath(void* aecmInst, |
544 void* echo_path, | 546 void* echo_path, |
545 size_t size_bytes) | 547 size_t size_bytes) |
546 { | 548 { |
547 AecMobile* aecm = aecmInst; | 549 AecMobile* aecm = static_cast<AecMobile*>(aecmInst); |
548 int16_t* echo_path_ptr = echo_path; | 550 int16_t* echo_path_ptr = static_cast<int16_t*>(echo_path); |
549 | 551 |
550 if (aecmInst == NULL) { | 552 if (aecmInst == NULL) { |
551 return -1; | 553 return -1; |
552 } | 554 } |
553 if (echo_path == NULL) { | 555 if (echo_path == NULL) { |
554 return AECM_NULL_POINTER_ERROR; | 556 return AECM_NULL_POINTER_ERROR; |
555 } | 557 } |
556 if (size_bytes != WebRtcAecm_echo_path_size_bytes()) | 558 if (size_bytes != WebRtcAecm_echo_path_size_bytes()) |
557 { | 559 { |
558 // Input channel size does not match the size of AECM | 560 // Input channel size does not match the size of AECM |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
637 nSampAdd = (int)(WEBRTC_SPL_MAX(((nSampSndCard >> 1) - nSampFar), | 639 nSampAdd = (int)(WEBRTC_SPL_MAX(((nSampSndCard >> 1) - nSampFar), |
638 FRAME_LEN)); | 640 FRAME_LEN)); |
639 nSampAdd = WEBRTC_SPL_MIN(nSampAdd, maxStuffSamp); | 641 nSampAdd = WEBRTC_SPL_MIN(nSampAdd, maxStuffSamp); |
640 | 642 |
641 WebRtc_MoveReadPtr(aecm->farendBuf, -nSampAdd); | 643 WebRtc_MoveReadPtr(aecm->farendBuf, -nSampAdd); |
642 aecm->delayChange = 1; // the delay needs to be updated | 644 aecm->delayChange = 1; // the delay needs to be updated |
643 } | 645 } |
644 | 646 |
645 return 0; | 647 return 0; |
646 } | 648 } |
OLD | NEW |