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:
- // 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