For a school project, I would like to get a bass-amplifier up-and-running with an ESP32. My idea for doing this is as follows:
I want to sample audio from AUX via I2S reading. Then I want to filter out the bass frequencies via a low-pass-filter. Next I will add a multiple of these frequency values to the original sample, and I will output them once again via I2S. I think I have the reading part down, however, I'm kind of stuck on writing with I2S. My code is as follows:
Code: Untitled.c Select all
// Global defines
#define SERIAL_BAUDRATE 9600
// I2S variables
#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0])) // Set the array size for the samples
#define ADC_INPUT_PIN ADC1_CHANNEL_4 // Pin we want to input from, this is pin 32
#define ADC_OUTPUT_PIN ADC1_CHANNEL_5 // Pin we want to output to, this is pin 33
const i2s_port_t I2S_PORT = I2S_NUM_0; // I2S port used (we use I2S_NUM_0 because this supports ADC and DAC)
const double SAMPLING_FREQUENCY = 41000; // Sampling frequency
const int SAMPLE_BLOCK = 512; // Amount of samples we want to store in one block
const uint16_t OFFSET = (int)ADC_INPUT_PIN * 0x1000; // Offset for the input pin
// Setup part
I2SManager::I2SManager() {
Serial.println("Configuring I2S...");
esp_err_t err;
// The I2S configuration
const i2s_config_t i2s_config = {
.mode = i2s_mode_t(I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_TX | I2S_MODE_ADC_BUILT_IN),
.sample_rate = SAMPLING_FREQUENCY,
.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
.communication_format = I2S_COMM_FORMAT_I2S_MSB,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
.dma_buf_count = 4,
.dma_buf_len = SAMPLE_BLOCK
};
// Set the driver for the I2S port
err = i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL);
if (err != ESP_OK) {
Serial.printf("Failed installing driver: %d\n", err);
while (true)
;
}
static const i2s_pin_config_t pin_config = {
.bck_io_num = -1,
.ws_io_num = -1,
.data_out_num = ADC_OUTPUT_PIN,
.data_in_num = ADC_INPUT_PIN
};
// Set pin config
i2s_set_pin(I2S_PORT, &pin_config);
// Enable DAC mode
i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN);
// Set input pin to ADC mode
err = i2s_set_adc_mode(ADC_UNIT_1, ADC_INPUT_PIN);
if (err != ESP_OK) {
Serial.printf("Failed setting up adc mode: %d\n", err);
while (true)
;
}
Serial.println("I2S driver installed.");
}
// Loop part
void I2SManager::getSamples() {
// Read samples from I2S buffer
size_t bytesRead = 0;
i2s_read(I2S_PORT, (void*)samples, sizeof(samples), &bytesRead, portMAX_DELAY);
// Check if all samples are filled
if (bytesRead != sizeof(samples)) {
Serial.printf("Could only read %u bytes of %u in FillBufferI2S()\n", bytesRead, sizeof(samples));
return;
}
// This prints some data, I don't know if its correct because I can't check it yet
for (uint16_t i = 0; i < ARRAYSIZE(samples); i++) {
Serial.printf("%7d\n", samples[i]);
}
int bytesWritten;
i2s_write(I2S_PORT, (void*)samples, sizeof(samples), (size_t*)&bytesWritten, portMAX_DELAY);
}
Thanks in advance and kind regards,
Thom