Any good souls out there that could help me modding the code in output_i2s2.cpp, to oversample the frequency to 88.2kHz effectively? I'm trying to improve how my NOS DAC analog reconstruction filter works. This is a 4xTDA1387 DAC with a 3rd pole LPF and doubling the frequency would very much help me reduce aliasing.
Simply setting I2S_TCR2_DIV((0)) shows the correct 88.2kHz WS and 5.645MHz BCLK with an oscilloscope. But this is clearly not enough. Do I also need to adjust the fs to 88.2kHz in the PLL section? Doing so in addition to I2S_TCR2_DIV((0)) brings BCLK to over 10MHz. I guess I also need to double each sample size, but this AI ISR code isn't really working and I'm not clear what should I do with block size. It is set to default 128 in AudioStream.h.
Any guidance is much much appreciated!
Regards,
Domingo
Simply setting I2S_TCR2_DIV((0)) shows the correct 88.2kHz WS and 5.645MHz BCLK with an oscilloscope. But this is clearly not enough. Do I also need to adjust the fs to 88.2kHz in the PLL section? Doing so in addition to I2S_TCR2_DIV((0)) brings BCLK to over 10MHz. I guess I also need to double each sample size, but this AI ISR code isn't really working and I'm not clear what should I do with block size. It is set to default 128 in AudioStream.h.
Code:
void AudioOutputI2S2::isr(void)
{
int16_t *dest;
audio_block_t *blockL, *blockR;
uint32_t saddr, offsetL, offsetR;
saddr = (uint32_t)(dma.TCD->SADDR);
dma.clearInterrupt();
if (saddr < (uint32_t)i2s2_tx_buffer + sizeof(i2s2_tx_buffer) / 2) {
// DMA is transmitting the first half of the buffer
dest = (int16_t *)&i2s2_tx_buffer[AUDIO_BLOCK_SAMPLES / 2];
if (AudioOutputI2S2::update_responsibility) AudioStream::update_all();
} else {
// DMA is transmitting the second half of the buffer
dest = (int16_t *)i2s2_tx_buffer;
}
blockL = AudioOutputI2S2::block_left_1st;
blockR = AudioOutputI2S2::block_right_1st;
offsetL = AudioOutputI2S2::block_left_offset;
offsetR = AudioOutputI2S2::block_right_offset;
// Manual oversampling: duplicate each sample
if (blockL && blockR) {
for (int i = 0; i < AUDIO_BLOCK_SAMPLES / 2; i++) {
// Left channel oversampling (duplicate each sample)
dest[2*i] = blockL->data[i + offsetL]; // First sample
dest[2*i + 1] = blockL->data[i + offsetL]; // Duplicate sample
// Right channel oversampling (duplicate each sample)
dest[2*i + AUDIO_BLOCK_SAMPLES] = blockR->data[i + offsetR]; // First sample
dest[2*i + 1 + AUDIO_BLOCK_SAMPLES] = blockR->data[i + offsetR]; // Duplicate sample
}
offsetL += AUDIO_BLOCK_SAMPLES / 2;
offsetR += AUDIO_BLOCK_SAMPLES / 2;
} else if (blockL) {
for (int i = 0; i < AUDIO_BLOCK_SAMPLES / 2; i++) {
// Left channel oversampling (duplicate each sample)
dest[2*i] = blockL->data[i + offsetL]; // First sample
dest[2*i + 1] = blockL->data[i + offsetL]; // Duplicate sample
}
offsetL += AUDIO_BLOCK_SAMPLES / 2;
} else if (blockR) {
for (int i = 0; i < AUDIO_BLOCK_SAMPLES / 2; i++) {
// Right channel oversampling (duplicate each sample)
dest[2*i + AUDIO_BLOCK_SAMPLES] = blockR->data[i + offsetR]; // First sample
dest[2*i + 1 + AUDIO_BLOCK_SAMPLES] = blockR->data[i + offsetR]; // Duplicate sample
}
offsetR += AUDIO_BLOCK_SAMPLES / 2;
} else {
memset(dest, 0, AUDIO_BLOCK_SAMPLES * 2); // Clear the buffer if no data
}
#if IMXRT_CACHE_ENABLED >= 2
arm_dcache_flush_delete(dest, sizeof(i2s2_tx_buffer) / 2);
#endif
// Update offsets and release blocks
if (offsetL < AUDIO_BLOCK_SAMPLES) {
AudioOutputI2S2::block_left_offset = offsetL;
} else {
AudioOutputI2S2::block_left_offset = 0;
AudioStream::release(blockL);
AudioOutputI2S2::block_left_1st = AudioOutputI2S2::block_left_2nd;
AudioOutputI2S2::block_left_2nd = NULL;
}
if (offsetR < AUDIO_BLOCK_SAMPLES) {
AudioOutputI2S2::block_right_offset = offsetR;
} else {
AudioOutputI2S2::block_right_offset = 0;
AudioStream::release(blockR);
AudioOutputI2S2::block_right_1st = AudioOutputI2S2::block_right_2nd;
AudioOutputI2S2::block_right_2nd = NULL;
}
}
Any guidance is much much appreciated!
Regards,
Domingo