11
11
12
12
#include "driver/dac_continuous.h"
13
13
14
-
15
14
#if defined(CONFIG_IDF_TARGET_ESP32 )
16
15
#define pin_CHANNEL_0 pin_GPIO25
17
16
#define pin_CHANNEL_1 pin_GPIO26
@@ -304,6 +303,32 @@ static audioout_sample_convert_func_t audioout_get_samples_convert_func(
304
303
}
305
304
}
306
305
306
+ static void audioio_audioout_start (audioio_audioout_obj_t * self ) {
307
+ esp_err_t ret ;
308
+
309
+ self -> playing = true;
310
+ self -> paused = false;
311
+
312
+ ret = dac_continuous_start_async_writing (self -> handle );
313
+ if (ret != ESP_OK ) {
314
+ mp_raise_RuntimeError (MP_ERROR_TEXT ("Failed to start async audio" ));
315
+ }
316
+ }
317
+
318
+ static void audioio_audioout_stop (audioio_audioout_obj_t * self , bool full_stop ) {
319
+ dac_continuous_stop_async_writing (self -> handle );
320
+ if (full_stop ) {
321
+ self -> get_buffer_index = 0 ;
322
+ self -> put_buffer_index = 0 ;
323
+ self -> sample_buffer = NULL ;
324
+ self -> sample = NULL ;
325
+ self -> playing = false;
326
+ self -> paused = false;
327
+ } else {
328
+ self -> paused = true;
329
+ }
330
+ }
331
+
307
332
static bool audioout_fill_buffer (audioio_audioout_obj_t * self ) {
308
333
if (!self -> playing ) {
309
334
return false;
@@ -342,7 +367,7 @@ static bool audioout_fill_buffer(audioio_audioout_obj_t *self) {
342
367
& raw_sample_buf , & raw_sample_buf_size );
343
368
344
369
if (get_buffer_result == GET_BUFFER_ERROR ) {
345
- common_hal_audioio_audioout_stop (self );
370
+ audioio_audioout_stop (self , true );
346
371
return false;
347
372
}
348
373
@@ -390,7 +415,7 @@ static bool audioout_fill_buffer(audioio_audioout_obj_t *self) {
390
415
} else {
391
416
// TODO: figure out if it is ok to call this here or do we need
392
417
// to somehow wait for all of the samples to be flushed
393
- common_hal_audioio_audioout_stop (self );
418
+ audioio_audioout_stop (self , true );
394
419
return false;
395
420
}
396
421
}
@@ -492,24 +517,15 @@ void common_hal_audioio_audioout_construct(audioio_audioout_obj_t *self,
492
517
self -> paused = false;
493
518
self -> freq_hz = DEFAULT_SAMPLE_RATE ;
494
519
495
- /* espressif has two dac channels and it can support true stereo or
496
- * outputting the same signal to both channels (dual mono).
497
- * if different pins are supplied for left and right then use true stereo.
498
- * if the same pin is supplied for left and right then use dual mono.
499
- */
520
+ // The case of left_channel == right_channel is already disallowed in shared-bindings.
521
+
500
522
if ((left_channel_pin == & pin_CHANNEL_0 &&
501
523
right_channel_pin == & pin_CHANNEL_1 ) ||
502
524
(left_channel_pin == & pin_CHANNEL_1 &&
503
525
right_channel_pin == & pin_CHANNEL_0 )) {
504
526
self -> channel_mask = DAC_CHANNEL_MASK_ALL ;
505
527
self -> num_channels = 2 ;
506
528
self -> channel_mode = DAC_CHANNEL_MODE_ALTER ;
507
- } else if ((left_channel_pin == & pin_CHANNEL_0 ||
508
- left_channel_pin == & pin_CHANNEL_1 ) &&
509
- right_channel_pin == left_channel_pin ) {
510
- self -> channel_mask = DAC_CHANNEL_MASK_ALL ;
511
- self -> num_channels = 1 ;
512
- self -> channel_mode = DAC_CHANNEL_MODE_SIMUL ;
513
529
} else if (left_channel_pin == & pin_CHANNEL_0 &&
514
530
right_channel_pin == NULL ) {
515
531
self -> channel_mask = DAC_CHANNEL_MASK_CH0 ;
@@ -550,32 +566,6 @@ void common_hal_audioio_audioout_deinit(audioio_audioout_obj_t *self) {
550
566
_active_handle = NULL ;
551
567
}
552
568
553
- static void audioio_audioout_start (audioio_audioout_obj_t * self ) {
554
- esp_err_t ret ;
555
-
556
- self -> playing = true;
557
- self -> paused = false;
558
-
559
- ret = dac_continuous_start_async_writing (self -> handle );
560
- if (ret != ESP_OK ) {
561
- mp_raise_RuntimeError (MP_ERROR_TEXT ("Failed to start async audio" ));
562
- }
563
- }
564
-
565
- static void audioio_audioout_stop (audioio_audioout_obj_t * self , bool full_stop ) {
566
- dac_continuous_stop_async_writing (self -> handle );
567
- if (full_stop ) {
568
- self -> get_buffer_index = 0 ;
569
- self -> put_buffer_index = 0 ;
570
- self -> sample_buffer = NULL ;
571
- self -> sample = NULL ;
572
- self -> playing = false;
573
- self -> paused = false;
574
- } else {
575
- self -> paused = true;
576
- }
577
- }
578
-
579
569
void common_hal_audioio_audioout_play (audioio_audioout_obj_t * self ,
580
570
mp_obj_t sample , bool loop ) {
581
571
@@ -597,7 +587,11 @@ void common_hal_audioio_audioout_play(audioio_audioout_obj_t *self,
597
587
self -> looping = loop ;
598
588
freq_hz = audiosample_get_sample_rate (self -> sample );
599
589
600
- if (freq_hz != self -> freq_hz ) {
590
+ // Workaround: always reset the DAC completely between plays,
591
+ // due to a bug that causes the left and right channels to be swapped randomly.
592
+ // See https://github.com/espressif/esp-idf/issues/11425
593
+ // TODO: Remove the `true` when this issue is fixed.
594
+ if (true || freq_hz != self -> freq_hz ) {
601
595
common_hal_audioio_audioout_deinit (self );
602
596
self -> freq_hz = freq_hz ;
603
597
audioout_init (self );
0 commit comments