static void ProcessExtended(aecpc_t* self, const int16_t* near, const int16_t* near_high, int16_t* out, int16_t* out_high, int16_t num_samples, int16_t reported_delay_ms, int32_t skew) { int i; const int num_frames = num_samples / FRAME_LEN; #if defined(WEBRTC_UNTRUSTED_DELAY) const int delay_diff_offset = kDelayDiffOffsetSamples; reported_delay_ms = kFixedDelayMs; #else // This is the usual mode where we trust the reported system delay values. const int delay_diff_offset = 0; // Due to the longer filter, we no longer add 10 ms to the reported delay // to reduce chance of non-causality. Instead we apply a minimum here to avoid // issues with the read pointer jumping around needlessly. reported_delay_ms = reported_delay_ms < kMinTrustedDelayMs ? kMinTrustedDelayMs : reported_delay_ms; // If the reported delay appears to be bogus, we attempt to recover by using // the measured fixed delay values. We use >= here because higher layers // may already clamp to this maximum value, and we would otherwise not // detect it here. reported_delay_ms = reported_delay_ms >= kMaxTrustedDelayMs ? kFixedDelayMs : reported_delay_ms; #endif self->msInSndCardBuf = reported_delay_ms; if (!self->farend_started) { // Only needed if they don't already point to the same place. if (near != out) { memcpy(out, near, sizeof(short) * num_samples); } if (near_high != out_high) { memcpy(out_high, near_high, sizeof(short) * num_samples); } return; } if (self->startup_phase) { // In the extended mode, there isn't a startup "phase", just a special // action on the first frame. In the trusted delay case, we'll take the // current reported delay, unless it's less then our conservative // measurement. int startup_size_ms = reported_delay_ms < kFixedDelayMs ? kFixedDelayMs : reported_delay_ms; int overhead_elements = (WebRtcAec_system_delay(self->aec) - startup_size_ms / 2 * self->rate_factor * 8) / PART_LEN; WebRtcAec_MoveFarReadPtr(self->aec, overhead_elements); self->startup_phase = 0; } EstBufDelayExtended(self); { // |delay_diff_offset| gives us the option to manually rewind the delay on // very low delay platforms which can't be expressed purely through // |reported_delay_ms|. const int adjusted_known_delay = WEBRTC_SPL_MAX(0, self->knownDelay + delay_diff_offset); for (i = 0; i < num_frames; ++i) { WebRtcAec_ProcessFrame(self->aec, &near[FRAME_LEN * i], &near_high[FRAME_LEN * i], adjusted_known_delay, &out[FRAME_LEN * i], &out_high[FRAME_LEN * i]); } } }
static void ProcessExtended(Aec* self, const float* const* near, size_t num_bands, float* const* out, size_t num_samples, int16_t reported_delay_ms, int32_t skew) { size_t i; const int delay_diff_offset = kDelayDiffOffsetSamples; #if defined(WEBRTC_UNTRUSTED_DELAY) reported_delay_ms = kFixedDelayMs; #else // This is the usual mode where we trust the reported system delay values. // Due to the longer filter, we no longer add 10 ms to the reported delay // to reduce chance of non-causality. Instead we apply a minimum here to avoid // issues with the read pointer jumping around needlessly. reported_delay_ms = reported_delay_ms < kMinTrustedDelayMs ? kMinTrustedDelayMs : reported_delay_ms; // If the reported delay appears to be bogus, we attempt to recover by using // the measured fixed delay values. We use >= here because higher layers // may already clamp to this maximum value, and we would otherwise not // detect it here. reported_delay_ms = reported_delay_ms >= kMaxTrustedDelayMs ? kFixedDelayMs : reported_delay_ms; #endif self->msInSndCardBuf = reported_delay_ms; if (!self->farend_started) { for (i = 0; i < num_bands; ++i) { // Only needed if they don't already point to the same place. if (near[i] != out[i]) { memcpy(out[i], near[i], sizeof(near[i][0]) * num_samples); } } return; } if (self->startup_phase) { // In the extended mode, there isn't a startup "phase", just a special // action on the first frame. In the trusted delay case, we'll take the // current reported delay, unless it's less then our conservative // measurement. int startup_size_ms = reported_delay_ms < kFixedDelayMs ? kFixedDelayMs : reported_delay_ms; #if defined(WEBRTC_ANDROID) || defined(WEBRTC_GONK) int target_delay = startup_size_ms * self->rate_factor * 8; #else // To avoid putting the AEC in a non-causal state we're being slightly // conservative and scale by 2. On Android we use a fixed delay and // therefore there is no need to scale the target_delay. int target_delay = startup_size_ms * self->rate_factor * 8 / 2; #endif int overhead_elements = (WebRtcAec_system_delay(self->aec) - target_delay) / PART_LEN; WebRtcAec_MoveFarReadPtr(self->aec, overhead_elements); self->startup_phase = 0; } EstBufDelayExtended(self); { // |delay_diff_offset| gives us the option to manually rewind the delay on // very low delay platforms which can't be expressed purely through // |reported_delay_ms|. const int adjusted_known_delay = WEBRTC_SPL_MAX(0, self->knownDelay + delay_diff_offset); WebRtcAec_ProcessFrames(self->aec, near, num_bands, num_samples, adjusted_known_delay, out); } }