@@ -20,7 +20,7 @@ uint8_t rawBuffer1[RAW_BUFFER_SIZE];
2020uint8_t * rawBuffer[2 ] = {rawBuffer0, rawBuffer1};
2121volatile int rawBufferIndex = 0 ;
2222
23- int decimation = 64 ;
23+ int decimation = 128 ;
2424
2525// final buffer is the one to be filled with PCM data
2626int16_t * volatile finalBuffer;
@@ -45,6 +45,7 @@ PDMClass::PDMClass(int dinPin, int clkPin, int pwrPin) :
4545 _channels(-1 ),
4646 _samplerate(-1 ),
4747 _init(-1 ),
48+ _cutSamples(100 ),
4849 _dmaChannel(0 ),
4950 _pio(nullptr ),
5051 _smIdx(-1 ),
@@ -55,6 +56,12 @@ PDMClass::~PDMClass() {
5556}
5657
5758int PDMClass::begin (int channels, int sampleRate) {
59+
60+ if (_init == 1 ) {
61+ // ERROR: please call end first
62+ return 0 ;
63+ }
64+
5865 // _channels = channels; // only one channel available
5966
6067 // clear the final buffers
@@ -63,6 +70,18 @@ int PDMClass::begin(int channels, int sampleRate) {
6370 int finalBufferLength = _doubleBuffer.availableForWrite () / sizeof (int16_t );
6471 _doubleBuffer.swap (0 );
6572
73+ // The mic accepts an input clock from 1.2 to 3.25 Mhz
74+ // Setup the decimation factor accordingly
75+ if ((sampleRate * decimation * 2 ) > 3250000 ) {
76+ decimation = 64 ;
77+ }
78+
79+ // Sanity check, abort if still over 3.25Mhz
80+ if ((sampleRate * decimation * 2 ) > 3250000 ) {
81+ // ERROR: Sample rate too high, the mic would glitch
82+ return -1 ;
83+ }
84+
6685 int rawBufferLength = RAW_BUFFER_SIZE / (decimation / 8 );
6786 // Saturate number of samples. Remaining bytes are dropped.
6887 if (rawBufferLength > finalBufferLength) {
@@ -71,6 +90,7 @@ int PDMClass::begin(int channels, int sampleRate) {
7190
7291 /* Initialize Open PDM library */
7392 filter.Fs = sampleRate;
93+ filter.MaxVolume = 1 ;
7494 filter.nSamples = rawBufferLength;
7595 filter.LP_HZ = sampleRate / 2 ;
7696 filter.HP_HZ = 10 ;
@@ -88,7 +108,7 @@ int PDMClass::begin(int channels, int sampleRate) {
88108
89109 if (!_pdmPgm.prepare (&_pio, &_smIdx, &_pgmOffset)) {
90110 // ERROR, no free slots
91- return - 1 ;
111+ return 0 ;
92112 }
93113 pdm_pio_program_init (_pio, _smIdx, _pgmOffset, _clkPin, _dinPin, clkDiv);
94114
@@ -118,14 +138,29 @@ int PDMClass::begin(int channels, int sampleRate) {
118138 true // Start immediately
119139 );
120140
141+ _cutSamples = 100 ;
142+
121143 _init = 1 ;
122144
123145 return 1 ;
124146}
125147
126148void PDMClass::end () {
149+
150+ if (_init != 1 ) {
151+ return ;
152+ }
153+
154+ dma_channel_set_irq0_enabled (_dmaChannel, false );
127155 dma_channel_abort (_dmaChannel);
156+ dma_channel_unclaim (_dmaChannel);
157+ irq_remove_handler (DMA_IRQ_0, dmaHandler);
158+ pio_sm_unclaim (_pio, _smIdx);
128159 pinMode (_clkPin, INPUT);
160+ rawBufferIndex = 0 ;
161+ _pgmOffset = -1 ;
162+
163+ _init = 0 ;
129164}
130165
131166int PDMClass::available () {
@@ -163,32 +198,32 @@ void PDMClass::setBufferSize(int bufferSize) {
163198}
164199
165200void PDMClass::IrqHandler (bool halftranfer) {
166- static int cutSamples = 100 ;
167201
168202 // Clear the interrupt request.
169203 dma_hw->ints0 = 1u << _dmaChannel;
170204 // Restart dma pointing to the other buffer
171205 int shadowIndex = rawBufferIndex ^ 1 ;
172206 dma_channel_set_write_addr (_dmaChannel, rawBuffer[shadowIndex], true );
173207
174- if (_doubleBuffer.available ()) {
175- // buffer overflow, stop
176- return end ();
208+ if (!_doubleBuffer.available ()) {
209+ // fill final buffer with PCM samples
210+ if (filter.Decimation == 128 ) {
211+ Open_PDM_Filter_128 (rawBuffer[rawBufferIndex], finalBuffer, 1 , &filter);
212+ } else {
213+ Open_PDM_Filter_64 (rawBuffer[rawBufferIndex], finalBuffer, 1 , &filter);
214+ }
215+
216+ if (_cutSamples) {
217+ memset (finalBuffer, 0 , _cutSamples);
218+ _cutSamples = 0 ;
219+ }
220+
221+ // swap final buffer and raw buffers' indexes
222+ finalBuffer = (int16_t *)_doubleBuffer.data ();
223+ _doubleBuffer.swap (filter.nSamples * sizeof (int16_t ));
224+ rawBufferIndex = shadowIndex;
177225 }
178226
179- // fill final buffer with PCM samples
180- Open_PDM_Filter_64 (rawBuffer[rawBufferIndex], finalBuffer, 1 , &filter);
181-
182- if (cutSamples) {
183- memset (finalBuffer, 0 , cutSamples);
184- cutSamples = 0 ;
185- }
186-
187- // swap final buffer and raw buffers' indexes
188- finalBuffer = (int16_t *)_doubleBuffer.data ();
189- _doubleBuffer.swap (filter.nSamples * sizeof (int16_t ));
190- rawBufferIndex = shadowIndex;
191-
192227 if (_onReceive) {
193228 _onReceive ();
194229 }
0 commit comments