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 |
(...skipping 968 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
979 memcpy(e_extended + PART_LEN, e, sizeof(float) * PART_LEN); | 979 memcpy(e_extended + PART_LEN, e, sizeof(float) * PART_LEN); |
980 Fft(e_extended, e_fft); | 980 Fft(e_extended, e_fft); |
981 | 981 |
982 // Scale error signal inversely with far power. | 982 // Scale error signal inversely with far power. |
983 WebRtcAec_ScaleErrorSignal(filter_step_size, error_threshold, x_pow, e_fft); | 983 WebRtcAec_ScaleErrorSignal(filter_step_size, error_threshold, x_pow, e_fft); |
984 WebRtcAec_FilterAdaptation(num_partitions, *x_fft_buf_block_pos, x_fft_buf, | 984 WebRtcAec_FilterAdaptation(num_partitions, *x_fft_buf_block_pos, x_fft_buf, |
985 e_fft, h_fft_buf); | 985 e_fft, h_fft_buf); |
986 memcpy(echo_subtractor_output, e, sizeof(float) * PART_LEN); | 986 memcpy(echo_subtractor_output, e, sizeof(float) * PART_LEN); |
987 } | 987 } |
988 | 988 |
989 static void EchoSuppression(AecCore* aec, | 989 static void FormSuppressionGain(AecCore* aec, |
990 float farend[PART_LEN2], | 990 float cohde[PART_LEN1], |
991 float* echo_subtractor_output, | 991 float cohxd[PART_LEN1], |
992 float* output, | 992 float hNl[PART_LEN1]) { |
993 float* const* outputH) { | |
994 float efw[2][PART_LEN1]; | |
995 float xfw[2][PART_LEN1]; | |
996 float dfw[2][PART_LEN1]; | |
997 float comfortNoiseHband[2][PART_LEN1]; | |
998 float fft[PART_LEN2]; | |
999 float nlpGainHband; | |
1000 int i; | |
1001 size_t j; | |
1002 | |
1003 // Coherence and non-linear filter | |
1004 float cohde[PART_LEN1], cohxd[PART_LEN1]; | |
1005 float hNlDeAvg, hNlXdAvg; | 993 float hNlDeAvg, hNlXdAvg; |
1006 float hNl[PART_LEN1]; | |
1007 float hNlPref[kPrefBandSize]; | 994 float hNlPref[kPrefBandSize]; |
1008 float hNlFb = 0, hNlFbLow = 0; | 995 float hNlFb = 0, hNlFbLow = 0; |
| 996 const int prefBandSize = kPrefBandSize / aec->mult; |
1009 const float prefBandQuant = 0.75f, prefBandQuantLow = 0.5f; | 997 const float prefBandQuant = 0.75f, prefBandQuantLow = 0.5f; |
1010 const int prefBandSize = kPrefBandSize / aec->mult; | |
1011 const int minPrefBand = 4 / aec->mult; | 998 const int minPrefBand = 4 / aec->mult; |
1012 // Power estimate smoothing coefficients. | 999 // Power estimate smoothing coefficients. |
1013 const float* min_overdrive = aec->extended_filter_enabled | 1000 const float* min_overdrive = aec->extended_filter_enabled |
1014 ? kExtendedMinOverDrive | 1001 ? kExtendedMinOverDrive |
1015 : kNormalMinOverDrive; | 1002 : kNormalMinOverDrive; |
1016 | 1003 |
1017 // Filter energy | |
1018 const int delayEstInterval = 10 * aec->mult; | |
1019 | |
1020 float* xfw_ptr = NULL; | |
1021 | |
1022 // Update eBuf with echo subtractor output. | |
1023 memcpy(aec->eBuf + PART_LEN, echo_subtractor_output, | |
1024 sizeof(float) * PART_LEN); | |
1025 | |
1026 // Analysis filter banks for the echo suppressor. | |
1027 // Windowed near-end ffts. | |
1028 WindowData(fft, aec->dBuf); | |
1029 aec_rdft_forward_128(fft); | |
1030 StoreAsComplex(fft, dfw); | |
1031 | |
1032 // Windowed echo suppressor output ffts. | |
1033 WindowData(fft, aec->eBuf); | |
1034 aec_rdft_forward_128(fft); | |
1035 StoreAsComplex(fft, efw); | |
1036 | |
1037 // NLP | |
1038 | |
1039 // Convert far-end partition to the frequency domain with windowing. | |
1040 WindowData(fft, farend); | |
1041 Fft(fft, xfw); | |
1042 xfw_ptr = &xfw[0][0]; | |
1043 | |
1044 // Buffer far. | |
1045 memcpy(aec->xfwBuf, xfw_ptr, sizeof(float) * 2 * PART_LEN1); | |
1046 | |
1047 aec->delayEstCtr++; | |
1048 if (aec->delayEstCtr == delayEstInterval) { | |
1049 aec->delayEstCtr = 0; | |
1050 aec->delayIdx = WebRtcAec_PartitionDelay(aec->num_partitions, aec->wfBuf); | |
1051 } | |
1052 | |
1053 // Use delayed far. | |
1054 memcpy(xfw, aec->xfwBuf + aec->delayIdx * PART_LEN1, | |
1055 sizeof(xfw[0][0]) * 2 * PART_LEN1); | |
1056 | |
1057 WebRtcAec_UpdateCoherenceSpectra(aec->mult, aec->extended_filter_enabled == 1, | |
1058 efw, dfw, xfw, &aec->coherence_state, | |
1059 &aec->divergeState, | |
1060 &aec->extreme_filter_divergence); | |
1061 | |
1062 WebRtcAec_ComputeCoherence(&aec->coherence_state, cohde, cohxd); | |
1063 | |
1064 // Select the microphone signal as output if the filter is deemed to have | |
1065 // diverged. | |
1066 if (aec->divergeState) { | |
1067 memcpy(efw, dfw, sizeof(efw[0][0]) * 2 * PART_LEN1); | |
1068 } | |
1069 | |
1070 hNlXdAvg = 0; | 1004 hNlXdAvg = 0; |
1071 for (i = minPrefBand; i < prefBandSize + minPrefBand; i++) { | 1005 for (int i = minPrefBand; i < prefBandSize + minPrefBand; ++i) { |
1072 hNlXdAvg += cohxd[i]; | 1006 hNlXdAvg += cohxd[i]; |
1073 } | 1007 } |
1074 hNlXdAvg /= prefBandSize; | 1008 hNlXdAvg /= prefBandSize; |
1075 hNlXdAvg = 1 - hNlXdAvg; | 1009 hNlXdAvg = 1 - hNlXdAvg; |
1076 | 1010 |
1077 hNlDeAvg = 0; | 1011 hNlDeAvg = 0; |
1078 for (i = minPrefBand; i < prefBandSize + minPrefBand; i++) { | 1012 for (int i = minPrefBand; i < prefBandSize + minPrefBand; ++i) { |
1079 hNlDeAvg += cohde[i]; | 1013 hNlDeAvg += cohde[i]; |
1080 } | 1014 } |
1081 hNlDeAvg /= prefBandSize; | 1015 hNlDeAvg /= prefBandSize; |
1082 | 1016 |
1083 if (hNlXdAvg < 0.75f && hNlXdAvg < aec->hNlXdAvgMin) { | 1017 if (hNlXdAvg < 0.75f && hNlXdAvg < aec->hNlXdAvgMin) { |
1084 aec->hNlXdAvgMin = hNlXdAvg; | 1018 aec->hNlXdAvgMin = hNlXdAvg; |
1085 } | 1019 } |
1086 | 1020 |
1087 if (hNlDeAvg > 0.98f && hNlXdAvg > 0.9f) { | 1021 if (hNlDeAvg > 0.98f && hNlXdAvg > 0.9f) { |
1088 aec->stNearState = 1; | 1022 aec->stNearState = 1; |
1089 } else if (hNlDeAvg < 0.95f || hNlXdAvg < 0.8f) { | 1023 } else if (hNlDeAvg < 0.95f || hNlXdAvg < 0.8f) { |
1090 aec->stNearState = 0; | 1024 aec->stNearState = 0; |
1091 } | 1025 } |
1092 | 1026 |
1093 if (aec->hNlXdAvgMin == 1) { | 1027 if (aec->hNlXdAvgMin == 1) { |
1094 aec->echoState = 0; | 1028 aec->echoState = 0; |
1095 aec->overDrive = min_overdrive[aec->nlp_mode]; | 1029 aec->overDrive = min_overdrive[aec->nlp_mode]; |
1096 | 1030 |
1097 if (aec->stNearState == 1) { | 1031 if (aec->stNearState == 1) { |
1098 memcpy(hNl, cohde, sizeof(hNl)); | 1032 memcpy(hNl, cohde, sizeof(hNl[0]) * PART_LEN1); |
1099 hNlFb = hNlDeAvg; | 1033 hNlFb = hNlDeAvg; |
1100 hNlFbLow = hNlDeAvg; | 1034 hNlFbLow = hNlDeAvg; |
1101 } else { | 1035 } else { |
1102 for (i = 0; i < PART_LEN1; i++) { | 1036 for (int i = 0; i < PART_LEN1; ++i) { |
1103 hNl[i] = 1 - cohxd[i]; | 1037 hNl[i] = 1 - cohxd[i]; |
1104 } | 1038 } |
1105 hNlFb = hNlXdAvg; | 1039 hNlFb = hNlXdAvg; |
1106 hNlFbLow = hNlXdAvg; | 1040 hNlFbLow = hNlXdAvg; |
1107 } | 1041 } |
1108 } else { | 1042 } else { |
1109 if (aec->stNearState == 1) { | 1043 if (aec->stNearState == 1) { |
1110 aec->echoState = 0; | 1044 aec->echoState = 0; |
1111 memcpy(hNl, cohde, sizeof(hNl)); | 1045 memcpy(hNl, cohde, sizeof(hNl[0]) * PART_LEN1); |
1112 hNlFb = hNlDeAvg; | 1046 hNlFb = hNlDeAvg; |
1113 hNlFbLow = hNlDeAvg; | 1047 hNlFbLow = hNlDeAvg; |
1114 } else { | 1048 } else { |
1115 aec->echoState = 1; | 1049 aec->echoState = 1; |
1116 for (i = 0; i < PART_LEN1; i++) { | 1050 for (int i = 0; i < PART_LEN1; ++i) { |
1117 hNl[i] = WEBRTC_SPL_MIN(cohde[i], 1 - cohxd[i]); | 1051 hNl[i] = WEBRTC_SPL_MIN(cohde[i], 1 - cohxd[i]); |
1118 } | 1052 } |
1119 | 1053 |
1120 // Select an order statistic from the preferred bands. | 1054 // Select an order statistic from the preferred bands. |
1121 // TODO(peah): Using quicksort now, but a selection algorithm may be | 1055 // TODO(peah): Using quicksort now, but a selection algorithm may be |
1122 // preferred. | 1056 // preferred. |
1123 memcpy(hNlPref, &hNl[minPrefBand], sizeof(float) * prefBandSize); | 1057 memcpy(hNlPref, &hNl[minPrefBand], sizeof(float) * prefBandSize); |
1124 qsort(hNlPref, prefBandSize, sizeof(float), CmpFloat); | 1058 qsort(hNlPref, prefBandSize, sizeof(float), CmpFloat); |
1125 hNlFb = hNlPref[static_cast<int>(floor(prefBandQuant * | 1059 hNlFb = hNlPref[static_cast<int>(floor(prefBandQuant * |
1126 (prefBandSize - 1)))]; | 1060 (prefBandSize - 1)))]; |
(...skipping 27 matching lines...) Expand all Loading... |
1154 | 1088 |
1155 // Smooth the overdrive. | 1089 // Smooth the overdrive. |
1156 if (aec->overDrive < aec->overdrive_scaling) { | 1090 if (aec->overDrive < aec->overdrive_scaling) { |
1157 aec->overdrive_scaling = | 1091 aec->overdrive_scaling = |
1158 0.99f * aec->overdrive_scaling + 0.01f * aec->overDrive; | 1092 0.99f * aec->overdrive_scaling + 0.01f * aec->overDrive; |
1159 } else { | 1093 } else { |
1160 aec->overdrive_scaling = | 1094 aec->overdrive_scaling = |
1161 0.9f * aec->overdrive_scaling + 0.1f * aec->overDrive; | 1095 0.9f * aec->overdrive_scaling + 0.1f * aec->overDrive; |
1162 } | 1096 } |
1163 | 1097 |
| 1098 // Apply the overdrive. |
1164 WebRtcAec_Overdrive(aec->overdrive_scaling, hNlFb, hNl); | 1099 WebRtcAec_Overdrive(aec->overdrive_scaling, hNlFb, hNl); |
| 1100 } |
| 1101 |
| 1102 static void EchoSuppression(AecCore* aec, |
| 1103 float farend[PART_LEN2], |
| 1104 float* echo_subtractor_output, |
| 1105 float* output, |
| 1106 float* const* outputH) { |
| 1107 float efw[2][PART_LEN1]; |
| 1108 float xfw[2][PART_LEN1]; |
| 1109 float dfw[2][PART_LEN1]; |
| 1110 float comfortNoiseHband[2][PART_LEN1]; |
| 1111 float fft[PART_LEN2]; |
| 1112 float nlpGainHband; |
| 1113 int i; |
| 1114 size_t j; |
| 1115 |
| 1116 // Coherence and non-linear filter |
| 1117 float cohde[PART_LEN1], cohxd[PART_LEN1]; |
| 1118 float hNl[PART_LEN1]; |
| 1119 |
| 1120 // Filter energy |
| 1121 const int delayEstInterval = 10 * aec->mult; |
| 1122 |
| 1123 float* xfw_ptr = NULL; |
| 1124 |
| 1125 // Update eBuf with echo subtractor output. |
| 1126 memcpy(aec->eBuf + PART_LEN, echo_subtractor_output, |
| 1127 sizeof(float) * PART_LEN); |
| 1128 |
| 1129 // Analysis filter banks for the echo suppressor. |
| 1130 // Windowed near-end ffts. |
| 1131 WindowData(fft, aec->dBuf); |
| 1132 aec_rdft_forward_128(fft); |
| 1133 StoreAsComplex(fft, dfw); |
| 1134 |
| 1135 // Windowed echo suppressor output ffts. |
| 1136 WindowData(fft, aec->eBuf); |
| 1137 aec_rdft_forward_128(fft); |
| 1138 StoreAsComplex(fft, efw); |
| 1139 |
| 1140 // NLP |
| 1141 |
| 1142 // Convert far-end partition to the frequency domain with windowing. |
| 1143 WindowData(fft, farend); |
| 1144 Fft(fft, xfw); |
| 1145 xfw_ptr = &xfw[0][0]; |
| 1146 |
| 1147 // Buffer far. |
| 1148 memcpy(aec->xfwBuf, xfw_ptr, sizeof(float) * 2 * PART_LEN1); |
| 1149 |
| 1150 aec->delayEstCtr++; |
| 1151 if (aec->delayEstCtr == delayEstInterval) { |
| 1152 aec->delayEstCtr = 0; |
| 1153 aec->delayIdx = WebRtcAec_PartitionDelay(aec->num_partitions, aec->wfBuf); |
| 1154 } |
| 1155 |
| 1156 // Use delayed far. |
| 1157 memcpy(xfw, aec->xfwBuf + aec->delayIdx * PART_LEN1, |
| 1158 sizeof(xfw[0][0]) * 2 * PART_LEN1); |
| 1159 |
| 1160 WebRtcAec_UpdateCoherenceSpectra(aec->mult, aec->extended_filter_enabled == 1, |
| 1161 efw, dfw, xfw, &aec->coherence_state, |
| 1162 &aec->divergeState, |
| 1163 &aec->extreme_filter_divergence); |
| 1164 |
| 1165 WebRtcAec_ComputeCoherence(&aec->coherence_state, cohde, cohxd); |
| 1166 |
| 1167 // Select the microphone signal as output if the filter is deemed to have |
| 1168 // diverged. |
| 1169 if (aec->divergeState) { |
| 1170 memcpy(efw, dfw, sizeof(efw[0][0]) * 2 * PART_LEN1); |
| 1171 } |
| 1172 |
| 1173 FormSuppressionGain(aec, cohde, cohxd, hNl); |
| 1174 |
1165 WebRtcAec_Suppress(hNl, efw); | 1175 WebRtcAec_Suppress(hNl, efw); |
1166 | 1176 |
1167 // Add comfort noise. | 1177 // Add comfort noise. |
1168 ComfortNoise(aec, efw, comfortNoiseHband, aec->noisePow, hNl); | 1178 ComfortNoise(aec, efw, comfortNoiseHband, aec->noisePow, hNl); |
1169 | 1179 |
1170 // Inverse error fft. | 1180 // Inverse error fft. |
1171 ScaledInverseFft(efw, fft, 2.0f, 1); | 1181 ScaledInverseFft(efw, fft, 2.0f, 1); |
1172 | 1182 |
1173 // Overlap and add to obtain output. | 1183 // Overlap and add to obtain output. |
1174 for (i = 0; i < PART_LEN; i++) { | 1184 for (i = 0; i < PART_LEN; i++) { |
(...skipping 782 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1957 | 1967 |
1958 int WebRtcAec_system_delay(AecCore* self) { | 1968 int WebRtcAec_system_delay(AecCore* self) { |
1959 return self->system_delay; | 1969 return self->system_delay; |
1960 } | 1970 } |
1961 | 1971 |
1962 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { | 1972 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { |
1963 assert(delay >= 0); | 1973 assert(delay >= 0); |
1964 self->system_delay = delay; | 1974 self->system_delay = delay; |
1965 } | 1975 } |
1966 } // namespace webrtc | 1976 } // namespace webrtc |
OLD | NEW |