@@ -334,7 +334,7 @@ uint32_t common_hal_audiobusio_pdmin_record_to_buffer(audiobusio_pdmin_obj_t* se
334
334
buffer = second_buffer ;
335
335
descriptor = & second_descriptor ;
336
336
}
337
- // Decimate and filter the last buffer
337
+ // Decimate and filter the buffer that was just filled.
338
338
uint32_t samples_gathered = descriptor -> BTCNT .reg / words_per_sample ;
339
339
// Don't run off the end of output buffer. Process only as many as needed.
340
340
uint32_t samples_to_process = min (remaining_samples_needed , samples_gathered );
@@ -352,10 +352,28 @@ uint32_t common_hal_audiobusio_pdmin_record_to_buffer(audiobusio_pdmin_obj_t* se
352
352
353
353
buffers_processed ++ ;
354
354
355
- // We might need fewer than an entire of samples, but we won't try to alter the
356
- // last DMA, which might already be in progress, so we'll just throw away some
357
- // samples at the end.
355
+ // Compute how many more samples we need, and if the last buffer is the last
356
+ // set of samples needed, adjust the DMA count to only fetch as necessary.
358
357
remaining_samples_needed = output_buffer_length - values_output ;
358
+ if (remaining_samples_needed <= samples_per_buffer * 2 &&
359
+ remaining_samples_needed > samples_per_buffer ) {
360
+ // Adjust the DMA settings for the current buffer, which will be processed
361
+ // after the other buffer, which is now receiving samples via DMA.
362
+ // We don't adjust the DMA in progress, but the one after that.
363
+ // Timeline:
364
+ // 1. current buffer (already processed)
365
+ // 2. alternate buffer (DMA in progress)
366
+ // 3. current buffer (last set of samples needed)
367
+
368
+ // Set up to receive the last set of samples (don't include the alternate buffer, now in use).
369
+ uint32_t samples_needed_for_last_buffer = remaining_samples_needed - samples_per_buffer ;
370
+ descriptor -> BTCNT .reg = samples_needed_for_last_buffer * words_per_sample ;
371
+ descriptor -> DSTADDR .reg = ((uint32_t ) buffer )
372
+ + samples_needed_for_last_buffer * words_per_sample * sizeof (buffer [0 ]);
373
+
374
+ // Break chain to alternate buffer.
375
+ descriptor -> DESCADDR .reg = 0 ;
376
+ }
359
377
}
360
378
361
379
stop_dma (self );
0 commit comments