1919#define I2S_DMA_BUFFER_MAX_SIZE 4092
2020// The number of DMA buffers to allocate
2121#define CIRCUITPY_BUFFER_COUNT (3)
22+
23+ #ifdef CIRCUITPY_AUDIOBUSIO_PDMOUT
24+ // The maximum DMA buffer size in frames (at mono 16-bit)
25+ #define CIRCUITPY_BUFFER_SIZE (I2S_DMA_BUFFER_MAX_SIZE / 8)
26+ // The number of output channels is fixed at 1
27+ #define CIRCUITPY_OUTPUT_SLOTS (1)
28+ #else
2229// The maximum DMA buffer size in frames (at stereo 16-bit)
2330#define CIRCUITPY_BUFFER_SIZE (I2S_DMA_BUFFER_MAX_SIZE / 4)
2431// The number of output channels is fixed at 2
2532#define CIRCUITPY_OUTPUT_SLOTS (2)
33+ #endif
2634
2735static void i2s_fill_buffer (i2s_t * self ) {
2836 if (self -> next_buffer_size == 0 ) {
@@ -31,7 +39,7 @@ static void i2s_fill_buffer(i2s_t *self) {
3139 }
3240 int16_t * output_buffer = (int16_t * )self -> next_buffer ;
3341 size_t output_buffer_size = self -> next_buffer_size ;
34- const size_t bytes_per_output_frame = 4 ;
42+ const size_t bytes_per_output_frame = CIRCUITPY_OUTPUT_SLOTS * 2 ;
3543 size_t bytes_per_input_frame = self -> channel_count * self -> bytes_per_sample ;
3644 if (!self -> playing || self -> paused || !self -> sample || self -> stopping ) {
3745 memset (output_buffer , 0 , self -> next_buffer_size );
@@ -62,7 +70,8 @@ static void i2s_fill_buffer(i2s_t *self) {
6270 size_t sample_bytecount = self -> sample_end - self -> sample_data ;
6371 // The framecount is the minimum of space left in the output buffer or left in the incoming sample.
6472 size_t framecount = MIN (output_buffer_size / bytes_per_output_frame , sample_bytecount / bytes_per_input_frame );
65- if (self -> samples_signed && self -> channel_count == 2 ) {
73+
74+ if (self -> samples_signed && self -> channel_count == CIRCUITPY_OUTPUT_SLOTS ) {
6675 if (self -> bytes_per_sample == 2 ) {
6776 memcpy (output_buffer , self -> sample_data , framecount * bytes_per_output_frame );
6877 } else {
@@ -165,8 +174,16 @@ void port_i2s_play(i2s_t *self, mp_obj_t sample, bool loop) {
165174 audiosample_reset_buffer (self -> sample , false, 0 );
166175
167176 uint32_t sample_rate = audiosample_get_sample_rate (sample );
177+
178+ #ifdef CIRCUITPY_AUDIOBUSIO_PDMOUT
179+ i2s_pdm_tx_clk_config_t clk_config = I2S_PDM_TX_CLK_DEFAULT_CONFIG (sample_rate );
180+ CHECK_ESP_RESULT (i2s_channel_reconfig_pdm_tx_clock (self -> handle , & clk_config ));
181+ size_t frame_size = sizeof (uint16_t );
182+ #else
168183 i2s_std_clk_config_t clk_config = I2S_STD_CLK_DEFAULT_CONFIG (sample_rate );
169184 CHECK_ESP_RESULT (i2s_channel_reconfig_std_clock (self -> handle , & clk_config ));
185+ size_t frame_size = sizeof (uint32_t );
186+ #endif
170187
171188 // preload the data
172189 self -> playing = true;
@@ -183,12 +200,12 @@ void port_i2s_play(i2s_t *self, mp_obj_t sample, bool loop) {
183200 self -> next_buffer = & starting_frame ;
184201 self -> next_buffer_size = sizeof (starting_frame );
185202 i2s_fill_buffer (self );
186- i2s_channel_preload_data (self -> handle , & starting_frame , sizeof ( uint32_t ) , & bytes_loaded );
203+ i2s_channel_preload_data (self -> handle , & starting_frame , frame_size , & bytes_loaded );
187204 preloaded += bytes_loaded ;
188205 }
189206
190207 // enable the channel
191- i2s_channel_enable (self -> handle );
208+ CHECK_ESP_RESULT ( i2s_channel_enable (self -> handle ) );
192209
193210 // The IDF will call us back when there is a free DMA buffer.
194211}
0 commit comments