For my opinion have 2 problem:
1) when inizialize i2s use a PHILIPS schema with this configuration (input and output):
void init_microphone(void)
{
i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER);
ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, NULL, &rx_handle));
i2s_std_config_t std_rx_cfg = {
.clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(CONFIG_EXAMPLE_MIC_SAMPLE_RATE),
.slot_cfg = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(CONFIG_EXAMPLE_MIC_BIT_SAMPLE, CONFIG_EXAMPLE_MIC_NUM_CHANNELS),
.gpio_cfg = {
.mclk = I2S_GPIO_UNUSED,
.bclk = CONFIG_EXAMPLE_I2S_MIC_BCLK_GPIO,
.ws = CONFIG_EXAMPLE_I2S_MIC_WS_GPIO,
.din = CONFIG_EXAMPLE_I2S_MIC_DATA_GPIO,
.invert_flags = {
.mclk_inv = false,
.bclk_inv = false,
.ws_inv = false,
},
},
};
ESP_ERROR_CHECK(i2s_channel_init_std_mode(rx_handle, &std_rx_cfg));
ESP_ERROR_CHECK(i2s_channel_enable(rx_handle));
}
Philips schema is perfect for edit buffer.
Second point is use 32bit data buffer
this function is for apply gain with test for top gain available.
void apply_volume_control(wave_info_t *wave_info, bool Normalize)
{
// Se Normalize è TRUE, imposta la scala del volume a 1.0 per normalizzare il segnale
float volume_scale = Normalize ? 1.0f : wave_info->volume_level / 9.0f;
// Trova il picco massimo del segnale e applica la trasformazione del volume in un solo ciclo
int16_t max_sample = 0;
for (size_t i = 0; i < wave_info->buffer_size / sizeof(int16_t); i++) {
// Step 1: Scala il volume in base all'impostazione utente o la normalizzazione
int32_t sample = (int32_t)(wave_info->buffer
* volume_scale);
// Trova il picco massimo attuale
if (abs(sample) > max_sample) {
max_sample = abs(sample);
}
// Sovrascrive temporaneamente il campione nel buffer
wave_info->buffer = (int16_t)sample;
}
// Se Normalize è TRUE, calcola un fattore di amplificazione per normalizzare il segnale
float amplification_factor = 1.0f;
if (Normalize && max_sample > 0) {
// Normalizza il segnale audio facendo sì che il picco più alto raggiunga INT16_MAX
amplification_factor = (float)INT16_MAX / max_sample;
} else if (!Normalize && max_sample > 0) {
// Se non si sta normalizzando, applica il fattore di amplificazione solo se il segnale è basso
amplification_factor = (float)INT16_MAX / max_sample;
}
// Applica l'amplificazione e il soft clipping
for (size_t i = 0; i < wave_info->buffer_size / sizeof(int16_t); i++) {
int32_t sample = wave_info->buffer;
// Step 2: Applica l'amplificazione
sample = (int32_t)(sample * amplification_factor);
// Step 3: Applica il soft clipping per evitare distorsioni
if (sample > INT16_MAX) {
sample = INT16_MAX - ((sample - INT16_MAX) / 2); // Soft clipping sopra INT16_MAX
} else if (sample < INT16_MIN) {
sample = INT16_MIN + ((sample - INT16_MIN) / 2); // Soft clipping sotto INT16_MIN
}
// Step 4: Aggiorna il buffer con il campione modificato
wave_info->buffer = (int16_t)sample;
}
}
i have same problem ![Smile :-)](./images/smilies/icon_e_smile.gif)
in this moment i try to convert a 48khz to a 44100hz ![Smile :-)](./images/smilies/icon_e_smile.gif)
Best Regards.