diff --git a/libraries/PDM/src/PDM.h b/libraries/PDM/src/PDM.h index 5d4eed0cd..c73082250 100644 --- a/libraries/PDM/src/PDM.h +++ b/libraries/PDM/src/PDM.h @@ -30,7 +30,7 @@ class PDMClass PDMClass(int dinPin, int clkPin, int pwrPin); virtual ~PDMClass(); - int begin(int channels, long sampleRate); + int begin(int channels, int sampleRate); void end(); virtual int available(); @@ -38,6 +38,8 @@ class PDMClass void onReceive(void(*)(void)); + //PORTENTA_H7 min -12 max 51 + //NANO 33 BLE SENSe min 0 max 80 void setGain(int gain); void setBufferSize(int bufferSize); @@ -50,7 +52,11 @@ class PDMClass int _pwrPin; int _channels; - + int _samplerate; + + int _gain; + int _init; + PDMDoubleBuffer _doubleBuffer; void (*_onReceive)(void); diff --git a/libraries/PDM/src/nrf52/PDM.cpp b/libraries/PDM/src/nrf52/PDM.cpp index 8b65fa568..57de67e0c 100644 --- a/libraries/PDM/src/nrf52/PDM.cpp +++ b/libraries/PDM/src/nrf52/PDM.cpp @@ -39,7 +39,11 @@ PDMClass::PDMClass(int dinPin, int clkPin, int pwrPin) : _dinPin(dinPin), _clkPin(clkPin), _pwrPin(pwrPin), - _onReceive(NULL) + _onReceive(NULL), + _gain(-1), + _channels(-1), + _samplerate(-1), + _init(-1) { } @@ -47,9 +51,10 @@ PDMClass::~PDMClass() { } -int PDMClass::begin(int channels, long sampleRate) +int PDMClass::begin(int channels, int sampleRate) { _channels = channels; + _samplerate = sampleRate; // Enable high frequency oscillator if not already enabled if (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0) { @@ -83,7 +88,10 @@ int PDMClass::begin(int channels, long sampleRate) return 0; // unsupported } - setGain(DEFAULT_PDM_GAIN); + if(_gain == -1) { + _gain = DEFAULT_PDM_GAIN; + } + nrf_pdm_gain_set(_gain, _gain); // configure the I/O and mux pinMode(_clkPin, OUTPUT); @@ -175,7 +183,8 @@ void PDMClass::onReceive(void(*function)(void)) void PDMClass::setGain(int gain) { - nrf_pdm_gain_set(gain, gain); + _gain = gain; + nrf_pdm_gain_set(_gain, _gain); } void PDMClass::setBufferSize(int bufferSize) diff --git a/libraries/PDM/src/rp2040/OpenPDMFilter.c b/libraries/PDM/src/rp2040/OpenPDMFilter.c index cff64300f..e2f409ac0 100644 --- a/libraries/PDM/src/rp2040/OpenPDMFilter.c +++ b/libraries/PDM/src/rp2040/OpenPDMFilter.c @@ -193,7 +193,7 @@ void Open_PDM_Filter_Init(TPDMFilter_InitStruct *Param) } sub_const = sum >> 1; - div_const = sub_const * Param->MaxVolume / 32768 / filterGain; + div_const = sub_const * Param->MaxVolume / 32768 / Param->filterGain; div_const = (div_const == 0 ? 1 : div_const); #ifdef USE_LUT diff --git a/libraries/PDM/src/rp2040/OpenPDMFilter.h b/libraries/PDM/src/rp2040/OpenPDMFilter.h index ba41febfe..d57ddf077 100644 --- a/libraries/PDM/src/rp2040/OpenPDMFilter.h +++ b/libraries/PDM/src/rp2040/OpenPDMFilter.h @@ -54,10 +54,6 @@ #define SINCN 3 #define DECIMATION_MAX 128 -//#define FILTER_GAIN 16 -extern uint16_t filterGain; - - #define HTONS(A) ((((uint16_t)(A) & 0xff00) >> 8) | \ (((uint16_t)(A) & 0x00ff) << 8)) #define RoundDiv(a, b) (((a)>0)?(((a)+(b)/2)/(b)):(((a)-(b)/2)/(b))) @@ -84,6 +80,7 @@ typedef struct { uint16_t HP_ALFA; uint16_t bit[5]; uint16_t byte; + uint16_t filterGain; } TPDMFilter_InitStruct; diff --git a/libraries/PDM/src/rp2040/PDM.cpp b/libraries/PDM/src/rp2040/PDM.cpp index f11efd0c9..1d135e21f 100644 --- a/libraries/PDM/src/rp2040/PDM.cpp +++ b/libraries/PDM/src/rp2040/PDM.cpp @@ -32,8 +32,6 @@ int16_t* volatile finalBuffer; // OpenPDM filter used to convert PDM into PCM #define FILTER_GAIN 16 TPDMFilter_InitStruct filter; -uint16_t filterGain = FILTER_GAIN; - extern "C" { __attribute__((__used__)) void dmaHandler(void) @@ -47,7 +45,11 @@ PDMClass::PDMClass(int dinPin, int clkPin, int pwrPin) : _dinPin(dinPin), _clkPin(clkPin), _pwrPin(pwrPin), - _onReceive(NULL) + _onReceive(NULL), + _gain(-1), + _channels(-1), + _samplerate(-1), + _init(-1) { } @@ -55,7 +57,7 @@ PDMClass::~PDMClass() { } -int PDMClass::begin(int channels, long sampleRate) +int PDMClass::begin(int channels, int sampleRate) { //_channels = channels; // only one channel available @@ -71,15 +73,19 @@ int PDMClass::begin(int channels, long sampleRate) rawBufferLength = finalBufferLength; } - /* Initialize Open PDM library */ - filter.Fs = sampleRate; - filter.nSamples = rawBufferLength; - filter.LP_HZ = sampleRate/2; - filter.HP_HZ = 10; - filter.In_MicChannels = 1; - filter.Out_MicChannels = 1; - filter.Decimation = decimation; - Open_PDM_Filter_Init(&filter); + /* Initialize Open PDM library */ + filter.Fs = sampleRate; + filter.nSamples = rawBufferLength; + filter.LP_HZ = sampleRate/2; + filter.HP_HZ = 10; + filter.In_MicChannels = 1; + filter.Out_MicChannels = 1; + filter.Decimation = decimation; + if(_gain == -1) { + _gain = FILTER_GAIN; + } + filter.filterGain = _gain; + Open_PDM_Filter_Init(&filter); // Configure PIO state machine float clkDiv = (float)clock_get_hz(clk_sys) / sampleRate / decimation / 2; @@ -110,6 +116,8 @@ int PDMClass::begin(int channels, long sampleRate) true // Start immediately ); + _init = 1; + return 1; } @@ -142,7 +150,11 @@ void PDMClass::onReceive(void(*function)(void)) void PDMClass::setGain(int gain) { - filterGain = gain; + _gain = gain; + if(_init == 1) { + filter.filterGain = _gain; + Open_PDM_Filter_Init(&filter); + } } void PDMClass::setBufferSize(int bufferSize) @@ -185,4 +197,4 @@ void PDMClass::IrqHandler(bool halftranfer) PDMClass PDM(PIN_PDM_DIN, PIN_PDM_CLK, -1); -#endif \ No newline at end of file +#endif diff --git a/libraries/PDM/src/stm32/PDM.cpp b/libraries/PDM/src/stm32/PDM.cpp index f34fbc5f4..69ce30b6b 100644 --- a/libraries/PDM/src/stm32/PDM.cpp +++ b/libraries/PDM/src/stm32/PDM.cpp @@ -34,7 +34,11 @@ PDMClass::PDMClass(int dinPin, int clkPin, int pwrPin) : _dinPin(dinPin), _clkPin(clkPin), _pwrPin(pwrPin), - _onReceive(NULL) + _onReceive(NULL), + _gain(-1), + _channels(-1), + _samplerate(-1), + _init(-1) { } @@ -42,10 +46,7 @@ PDMClass::~PDMClass() { } -static int gain_db = -1; -static int _samplerate = -1; - -int PDMClass::begin(int channels, long sampleRate) { +int PDMClass::begin(int channels, int sampleRate) { if (isBoardRev2()) { mbed::I2C i2c(PB_7, PB_6); @@ -65,14 +66,13 @@ int PDMClass::begin(int channels, long sampleRate) { _channels = channels; _samplerate = sampleRate; - if (gain_db == -1) { - gain_db = 24; + if (_gain == -1) { + _gain = 24; } - //g_pcmbuf = (uint16_t*)_doubleBuffer.data(); - - if(py_audio_init(channels, sampleRate, gain_db, 0.9883f)) { + if(py_audio_init(channels, sampleRate, _gain, 0.9883f)) { py_audio_start_streaming(); + _init = 1; return 1; } return 0; @@ -103,9 +103,10 @@ void PDMClass::onReceive(void(*function)(void)) void PDMClass::setGain(int gain) { - gain_db = gain; - //end(); - //begin(_channels, _samplerate); + _gain = gain; + if(_init == 1) { + py_audio_gain_set(gain); + } } void PDMClass::setBufferSize(int bufferSize) diff --git a/libraries/PDM/src/stm32/audio.c b/libraries/PDM/src/stm32/audio.c index f52aaa6e8..8d8d037ce 100644 --- a/libraries/PDM/src/stm32/audio.c +++ b/libraries/PDM/src/stm32/audio.c @@ -309,6 +309,18 @@ int py_audio_init(size_t channels, uint32_t frequency, int gain_db, float highpa return 1; } +void py_audio_gain_set(int gain_db) +{ + // Configure PDM filters + for (int i=0; i