Problem with volume control using MAX98357A and I2S on an ESP32

billys7
Posts: 2
Joined: Tue Feb 22, 2022 4:00 pm

Problem with volume control using MAX98357A and I2S on an ESP32

Postby billys7 » Tue Feb 22, 2022 4:31 pm

I use the following code to reproduce an audio file with ESP32 --> I2S --> MAX98357A with success.

I want to add a software volume, so i add the code in comments. When i uncomment this part of the code the result is very noisy.
Do you have any suggestions ?
  1. #include "driver/i2s.h"
  2. #include "freertos/queue.h"
  3. #include <pgmspace.h>
  4.  
  5. #include "soundsample.h"
  6.  
  7. uint16_t readData1, readData2;
  8. uint32_t readData, counter;
  9.  
  10. //i2s configuration
  11. const int i2s_num = 0;                                                                  
  12.  
  13. i2s_config_t i2s_config = {
  14.   .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX),
  15.   .sample_rate = 16000,                                                                
  16.   .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,                                        
  17.   .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
  18.   .communication_format = (i2s_comm_format_t)(I2S_COMM_FORMAT_STAND_I2S),
  19.   .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,                                          
  20.   .dma_buf_count = 8,                                                                  
  21.   .dma_buf_len = 1024,                                                                  
  22.   .use_apll = 0,
  23.   .tx_desc_auto_clear = true
  24. };
  25.  
  26.  
  27. i2s_pin_config_t pin_config = {
  28.   .bck_io_num = 26,                         //this is BCK pin
  29.   .ws_io_num = 25,                          // this is LRCK pin
  30.   .data_out_num = 22,                     // this is DATA output pin
  31.   .data_in_num = I2S_PIN_NO_CHANGE        
  32. //  .data_in_num = -1                      //Not used
  33. };
  34.  
  35. int i2s_write_sample_nb(uint32_t sample)
  36. {
  37.     size_t bytes_written;
  38.     i2s_write((i2s_port_t)i2s_num, (const char*)&sample, sizeof(uint32_t), &bytes_written, 100);  
  39.     return bytes_written;
  40. }
  41.  
  42. //Main function to play samples from PROGMEM
  43. void playPROGMEMsample(const uint32_t* audioSample)
  44. {
  45.   i2s_driver_install((i2s_port_t)i2s_num, &i2s_config, 0, NULL);    //initialize i2s with configurations above
  46.   i2s_set_pin((i2s_port_t)i2s_num, &pin_config);                          //initialize i2s with configurations above
  47.   i2s_set_sample_rates((i2s_port_t)i2s_num, 16000);                    //set sample rates of i2s to sample rate of wav file
  48.                                                  
  49.   while (audioSample)  
  50.       {
  51.         readData = pgm_read_dword(&audioSample[counter++]);        
  52.  
  53. readData = ((readData>>24)&0xff) |   // move byte 3 to byte 0       // Convert big endian to little endian in C
  54.            ((readData<<8)&0xff0000) |     // move byte 1 to byte 2
  55.            ((readData>>8)&0xff00) |         // move byte 2 to byte 1
  56.            ((readData<<24)&0xff000000); // byte 0 to byte 3
  57.  
  58. /*   Code for volume test
  59. readData1 = uint16_t(readData>>16);
  60. readData1 = readData1 /3;
  61. readData2 = uint16_t(readData);
  62. readData2 = readData2 /3;
  63. readData = uint32_t (readData1 << 16)+ readData2;
  64. */
  65.  
  66.         i2s_write_sample_nb(readData);
  67.         if(counter > 125252) break;
  68.       }
  69.   counter = 0;
  70.   readData = 0;
  71.   i2s_driver_uninstall((i2s_port_t)i2s_num);                        //stop & destroy i2s driver
  72. }
  73.  
  74. void setup()
  75. {
  76.   Serial.begin(115200);
  77.   Serial.println("Serial connection OK");
  78.   playPROGMEMsample(sample1);
  79.    Serial.println("End");
  80. }
  81.  
  82. void loop()
  83. {
  84.  
  85. }
Attachments
soundsample.h
(1.43 MiB) Downloaded 249 times

imanpakii
Posts: 3
Joined: Fri Jan 29, 2021 2:42 am

Re: Problem with volume control using MAX98357A and I2S on an ESP32

Postby imanpakii » Thu Mar 17, 2022 2:41 pm

Hello,

Did you Fix the problem?
I'm using driver/i2s.h and I would like to change the sound volume also.
Please give me your solution if you have it.

Thank you
Iman

billys7
Posts: 2
Joined: Tue Feb 22, 2022 4:00 pm

Re: Problem with volume control using MAX98357A and I2S on an ESP32

Postby billys7 » Tue Mar 22, 2022 10:45 pm

I have no solution yet. I think that i must include the i2s_write function in an interrupt - task, so i can use it, only when the buffer will be empty. I read in this forum that i can trigger an event when the buffer is empty but i couldn't understand it. i want to learn more about the function :

"i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL);"

i2s_num I2S device number
i2s_config I2S configurations - see i2s_config_t struct
queue_size I2S event queue size/depth. (what does that mean ? How can i know the value ?)
i2s_queue I2S event queue handle, if set NULL, driver will not use an event queue. (When the event will happend ?)

and especially about the last 2 parameters, and the way that i will do the interrupt - task.

Also, in the technical reference, i found the I2S_TX_REMPTY_INT interrupt. It is triggered when the transmit FIFO is empty. I think that this is what i am looking for, but i don't know how can i trigger it.

Unfortunately it is very difficult to find a guide, and the infos are limited.

Who is online

Users browsing this forum: No registered users and 76 guests