Skip to content

Instantly share code, notes, and snippets.

@tomnz
Created November 9, 2020 17:47
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tomnz/856406dc56c741b52f45a7cf4e3299fd to your computer and use it in GitHub Desktop.
Save tomnz/856406dc56c741b52f45a7cf4e3299fd to your computer and use it in GitHub Desktop.
void Audio::initI2SDac() {
adc1_config_channel_atten(I2S_ADC_CHANNEL, ADC_ATTEN_11db);
i2s_config_t i2s_config = {
.mode = static_cast<i2s_mode_t>(I2S_MODE_MASTER | I2S_MODE_RX |
I2S_MODE_ADC_BUILT_IN),
.sample_rate = I2S_SAMPLE_RATE,
.bits_per_sample = static_cast<i2s_bits_per_sample_t>(I2S_SAMPLE_BITS),
.channel_format = static_cast<i2s_channel_fmt_t>(I2S_FORMAT),
.communication_format =
static_cast<i2s_comm_format_t>(I2S_COMM_FORMAT_I2S_MSB),
.intr_alloc_flags = 0,
.dma_buf_count = 2,
.dma_buf_len = SAMPLES,
.use_apll = false,
.tx_desc_auto_clear = false,
.fixed_mclk = 0};
i2s_driver_install(I2S_NUM, &i2s_config, 0, NULL);
i2s_set_adc_mode(I2S_ADC_UNIT, I2S_ADC_CHANNEL);
}
void Audio::audioTask() {
size_t bytes_read;
uint32_t dac_value = 0;
int fftFrames = 0;
int chain = 0;
bool clipping = false;
char* i2s_read_buff = (char*)calloc(SAMPLE_BYTES, sizeof(char));
i2s_adc_enable(I2S_NUM);
i2s_read(I2S_NUM, (void*)i2s_read_buff, SAMPLE_BYTES, &bytes_read, 2);
while (1) {
// read data from I2S bus, in this case, from ADC.
i2s_read(I2S_NUM, (void*)i2s_read_buff, SAMPLE_BYTES, &bytes_read, 2);
if (bytes_read == SAMPLE_BYTES) {
int clips = 0;
for (size_t i = 0; i < bytes_read / 2; i++) {
dac_value =
((((uint16_t)(i2s_read_buff[i * 2 + 1] & 0xf) << 8) |
((i2s_read_buff[i * 2]))));
if (dac_value < 2 || dac_value > 4094) {
clips++;
}
vReal[chain][i] = ((float)dac_value - MIDPOINT) / DIVISOR;
vImag[chain][i] = 0;
}
chain = (chain + 1) % SAMPLE_CHAIN_NUM;
if (clips > SAMPLES / 8) {
audioClipping = true;
clipping = true;
} else {
audioClipping = false;
}
// Build sample chain from all chunks
for (size_t i = 0; i < SAMPLE_CHAIN_NUM; i++) {
int chainNum = (chain + i) % SAMPLE_CHAIN_NUM;
std::copy_n(vReal[chainNum], SAMPLES, vRealChain + i * SAMPLES);
std::copy_n(vImag[chainNum], SAMPLES, vImagChain + i * SAMPLES);
}
arduinoFFT fft(vRealChain, vImagChain, TOTAL_CHAIN,
I2S_SAMPLE_RATE);
fft.Windowing(FFT_WIN_TYP_BLACKMAN, FFT_FORWARD);
fft.Compute(FFT_FORWARD);
fft.ComplexToMagnitude();
for (size_t i = 0; i < FFT_BUCKETS; i++) {
if (vRealChain[i] > vMax[i]) {
vMax[i] = vRealChain[i];
}
vRealChain[i] =
(vRealChain[i] - noiseFloor[i]) / (vMax[i] - noiseFloor[i]);
}
for (size_t i = 0; i < bands.size(); i++) {
bands[i]->update(vRealChain);
}
} else {
ESP_LOGE(tagAudio, "DIDN'T GET ALL SAMPLES!!!");
}
vTaskDelay(0);
}
i2s_adc_disable(I2S_NUM);
free(i2s_read_buff);
i2s_read_buff = NULL;
vTaskDelete(NULL);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment