@@ -140,6 +140,9 @@ void port_i2s_allocate_init(i2s_t *self, bool left_justified) {
140140 if (err == ESP_ERR_NOT_FOUND ) {
141141 mp_raise_RuntimeError (MP_ERROR_TEXT ("Peripheral in use" ));
142142 }
143+ self -> playing = false;
144+ self -> paused = false;
145+ self -> stopping = false;
143146
144147 i2s_event_callbacks_t callbacks = {
145148 .on_recv = NULL ,
@@ -157,6 +160,8 @@ void port_i2s_deinit(i2s_t *self) {
157160}
158161
159162void port_i2s_play (i2s_t * self , mp_obj_t sample , bool loop ) {
163+ // Pause to disable the I2S channel so we can adjust the clock.
164+ port_i2s_pause (self );
160165 self -> sample = sample ;
161166 self -> loop = loop ;
162167 self -> bytes_per_sample = audiosample_bits_per_sample (sample ) / 8 ;
@@ -204,6 +209,9 @@ void port_i2s_play(i2s_t *self, mp_obj_t sample, bool loop) {
204209}
205210
206211bool port_i2s_playing (i2s_t * self ) {
212+ // TODO: Reason about stopping. This check leads to cases where the DMA is
213+ // "playing" but the common-hal thinks it isn't and skips pausing. Probably
214+ // best to move this functionality into I2SOut directly.
207215 return self -> playing && !self -> stopping ;
208216}
209217
@@ -219,14 +227,14 @@ void port_i2s_stop(i2s_t *self) {
219227}
220228
221229void port_i2s_pause (i2s_t * self ) {
222- if (!self -> paused ) {
230+ if (self -> playing && !self -> paused ) {
223231 self -> paused = true;
224232 CHECK_ESP_RESULT (i2s_channel_disable (self -> handle ));
225233 }
226234}
227235
228236void port_i2s_resume (i2s_t * self ) {
229- if (self -> paused ) {
237+ if (self -> playing && self -> paused ) {
230238 self -> paused = false;
231239 CHECK_ESP_RESULT (i2s_channel_enable (self -> handle ));
232240 }
0 commit comments