tierneytim / btAudio

Bluetooth Audio for Arduino
196 stars 29 forks source link

Please tell me to use the DRC filter in A2dp Bluetooth sink #32

Open gauravacad opened 10 months ago

gauravacad commented 10 months ago

Hello Sir , M studying your Code and find it useful. Please help in one regard to use the dynamic filter for High and low pass. the code is given Below. ****code** // Gaurav

include "sos-iir-filter.h"

include "Arduino.h"

include "a2dp_source.h"

include <driver/i2s.h>

// SCK 5 = bit clock line (BCLK) // FS 25 = WS PIN //* DIN 35 MIC

define RX_I2S_DIN 35 // connect with I2S microphone pin SO (signal out)

define RX_I2S_BCLK 5 // connect with I2S microphone pin SCK (bit clock)

define RX_I2S_LRC 33 // connect with I2S microphone pin WS (word select)

//#define RX_I2S_DIN 33 // connect with I2S microphone pin SO (signal out) //#define RX_I2S_BCLK 15 // connect with I2S microphone pin SCK (bit clock) //#define RX_I2S_LRC 14 // connect with I2S microphone pin WS (word select) char BT_SINK_NAME[] = "Airdopes 141"; //"Infinity Glide 120, Nirvana Ion, Airdopes 141/boAt Rockerz 510";Smartbuy EB4MVBT // set your sink devicename here char BT_SINK_PIN[] = "0000"; // sink pincode char BT_DEVICE_NAME[] = "ESP_A2DP_SRC"; // source devicename const i2s_port_t I2S_PORT_RX = I2S_NUM_0; const uint32_t sample_rate = 44100; //44100; //43945; const uint16_t buf_len = 1024; size_t bytes_written = 0; char readBuff[buf_len]; uint16_t buffSize; uint8_t buffStat; uint8_t gain = 12; // reduce volume -> increase gain

enum : uint8_t {BUFF_FULL, BUFF_EMPTY};

// DC-Blocker filter - removes DC component from I2S data // See: https://www.dsprelated.com/freebooks/filters/DC_Blocker.html // a1 = -0.9992 should heavily attenuate frequencies below 10Hz //SOS_IIR_Filter DC_BLOCKER = { //gain: 1.0, //sos: {{-1.0, 0.0, +0.9992, 0}} //};

// TDK/InvenSense INMP441 // Datasheet: https://www.invensense.com/wp-content/uploads/2015/02/INMP441.pdf // B ~= [1.00198, -1.99085, 0.98892] // A ~= [1.0, -1.99518, 0.99518] //SOS_IIR_Filter INMP441 = { //gain: 1.00197834654696, //sos: { // Second-Order Sections {b1, b2, -a1, -a2} //{-1.986920458344451, +0.986963226946616, +1.995178510504166, -0.995184322194091} //} //}; //--------------------------------------------------------------------------------------------------------------------- void i2s_install(){ / RX: I2S_NUM_1 / i2s_config_t i2s_config_rx = { .mode = (i2s_mode_t) (I2S_MODE_MASTER | I2S_MODE_RX), // Only TX I2S_COMM_FORMAT_STAND_PCM_SHORT .sample_rate = sample_rate, .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT, // Only 8-bit DAC support .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,//I2S_CHANNEL_FMT_ALL_RIGHT, //I2S_CHANNEL_FMT_RIGHT_LEFT, // 2-channels .communication_format = (i2s_comm_format_t) I2S_COMM_FORMAT_STAND_I2S, // I2S_COMM_FORMAT_STAND_I2S, //I2S_COMM_FORMAT_STAND_PCM_SHORT, .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, // Interrupt level 1 .dma_buf_count = 5, // number of buffers, 128 max. .dma_buf_len = buf_len, // size of each buffer60 60 pe good hain // 4-512; .use_apll = false, .tx_desc_auto_clear = true, // new in V1.0.1 .fixed_mclk = I2S_PIN_NO_CHANGE, .mclk_multiple = I2S_MCLK_MULTIPLE_DEFAULT };

    i2s_pin_config_t pin_config_rx = {
        .bck_io_num   = RX_I2S_BCLK,
        .ws_io_num    = RX_I2S_LRC,
        .data_out_num = I2S_PIN_NO_CHANGE,
        .data_in_num  = RX_I2S_DIN
    };

    i2s_driver_install(I2S_PORT_RX, &i2s_config_rx, 0, NULL);
    i2s_set_pin(I2S_PORT_RX, &pin_config_rx);

} //---------------------------------------------SETUP-------------------------------------------------------------------- void setup(){ Serial.begin(115200); i2s_install(); buffStat = BUFF_EMPTY; log_i("free heap %i", esp_get_free_heap_size()); a2dp_source_init(BT_SINK_NAME, BT_SINK_PIN); log_i("free heap %i", esp_get_free_heap_size()); }

//----------------------------------------------LOOP-------------------------------------------------------------------- void loop() {

//char *buf_ptr_read1  = readBuff + 4; // connect L/R with VDD
char *buf_ptr_read1  = readBuff;     // connect L/R with GND
char *buf_ptr_write1 = readBuff;

if(buffStat == BUFF_EMPTY) {
    size_t bytes_read = 0;
    while(bytes_read == 0) {
        i2s_read(I2S_PORT_RX, readBuff, buf_len, &bytes_read, portMAX_DELAY);
    }
    uint32_t samples_read = bytes_read / 2 / (I2S_BITS_PER_SAMPLE_32BIT / 8);

    //  convert 2x 32 bit stereo -> 1 x 16 bit mono
    for(int i = 0; i < samples_read; i++) {

        // left channel
        //int32_t sample = (buf_ptr_read1[3] << 24) + (buf_ptr_read1[2] << 16) + (buf_ptr_read1[1] << 8); //(buf_ptr_read1[4] << 32)+
        //sample = sample >> gain;
        int32_t sample = (buf_ptr_read1[3] << 24) + (buf_ptr_read1[2]<<16);
        //sample = sample >> gain;
        sample = sample >> (gain); 
        buf_ptr_write1[0] = sample & 0x00FF;
        buf_ptr_write1[1] = (sample >>8) & 0x00FF;

        // right channel
        buf_ptr_write1[2] = buf_ptr_write1[0]; // mid
        buf_ptr_write1[3] = buf_ptr_write1[1]; // high

        buf_ptr_write1 += 2 * (I2S_BITS_PER_SAMPLE_16BIT / 8);
        buf_ptr_read1 += 2 * (I2S_BITS_PER_SAMPLE_32BIT / 8);

        buffSize = samples_read * 2 * (I2S_BITS_PER_SAMPLE_16BIT / 8);
    }
    buffStat = BUFF_FULL;
}
 bt_loop();

} //---------------------------------------------EVENTS------------------------------------------------------------------- int32_t bt_data(uint8_t data, int32_t len, uint32_t sr){ // BT data event sr = 44100; if (len < 0 || data == NULL) { buffStat = BUFF_EMPTY; return 0; } if(!buffSize) return 0; memcpy(data, readBuff, buffSize); buffStat = BUFF_EMPTY; return buffSize; } void bt_info(const char info){ Serial.printf("bt_info: %s\n", info); }

gauravacad commented 10 months ago

I am little issue in using the filter to plug and play in my code.

tierneytim commented 10 months ago

Hello. You may have to expand a little bit on what you want. From what I can see your code doesn't use any of my code

gauravacad commented 10 months ago

Sir I want to use your code in my exisiting code from which main file is posted. In the above code I am using INMP441 stereo with esp32 wroom dev board. The above code works well with stereo sound. Also A2dp I have a latency while streaming upto 62mn managable for music. But I have a background white noise. Frequency I dont have idea. But in the above code how can I use DRC filter so that on low freq, minimum and high freq. max it can agjust the signal.

gauravacad commented 10 months ago

I try adjusting // DC-Blocker filter - removes DC component from I2S data // See: https://www.dsprelated.com/freebooks/filters/DC_Blocker.html // a1 = -0.9992 should heavily attenuate frequencies below 10Hz //SOS_IIR_Filter DC_BLOCKER = { //gain: 1.0, //sos: {{-1.0, 0.0, +0.9992, 0}} //};

// TDK/InvenSense INMP441 // Datasheet: https://www.invensense.com/wp-content/uploads/2015/02/INMP441.pdf // B ~= [1.00198, -1.99085, 0.98892] // A ~= [1.0, -1.99518, 0.99518] //SOS_IIR_Filter INMP441 = { //gain: 1.00197834654696, //sos: { // Second-Order Sections {b1, b2, -a1, -a2} //{-1.986920458344451, +0.986963226946616, +1.995178510504166, -0.995184322194091} //} //};

but unable to use it in my code so read your git repo. thought to ask you