The application is for interfacing the Bluetooth HF protocol to a traditional POTS telephone line using a SLIC (Subscriber Line Interface Circuit aka "Hybrid"). Because of the way the SLIC works some of the audio sent to it from the DAC is always reflected back to the ADC so I have to implement a Line Echo Cancellation algorithm (LEC) or the person at the other end of the conversation will hear themselves echoed back a few hundred milliseconds later (over the cellular connection). I'm attempting to use the proven open source OSLEC library which was designed to handle just this case. This is different than an Acoustic Echo Cancellation algorithm used for a speakerphone or headphone. It requires a non-changing relationship in time between the TX data sent to the codec and the RX data received from the codec a little later (the echoed data).
Ideal pseudo-code for the task looks like
Code: Select all
// Sample rate is 8000 Hz so we pick a number of samples equal to one FreeRTOS tick (10 mSec)
#define NUM_SAMPLES 80
int16_t tx_buf[NUM_SAMPLES];
int16_t rx_buf[NUM_SAMPLES];
int bytes_written, bytes_read; // In the real code these are checked to make sure all data was sent or received
while (true) {
get_tx_data(NUM_SAMPLES, tx_buf); // tx_buf holds data to write to DAC (2 bytes per sample: one channel, 16-bit data)
i2s_write(I2S_NUM_0, (void*) tx_buf, NUM_SAMPLES * 2, &bytes_written, portMAX_DELAY);
i2s_read(I2S_NUM_0, (void*) rx_buf, NUM_SAMPLES * 2, &bytes_read, portMAX_DELAY);
// Execute the LEC
for (int i=0; i<NUM_SAMPLES; i++) {
// Echo cancellation machine works sample by sample
// Output is echo cancelled rx input
// tx_buf data leads rx_buf data in time by some number of samples (< ~50 or 60) but that relationship must remain fixed
rx_buf[i] = echo_can_update(tx_buf[i], rx_buf[i]);
}
put_rx_data(NUM_SAMPLES, rx_buf);
}
Does anyone know a mechanism to fix the relationship in time between the TX and RX buffers being handed to the I2S driver? In a way it doesn't matter what that relationship is (within reasonable audio bounds) as I can implement additional buffering on the TX stream to bring the TX and RX data close together when the data is handed to the LEC.