@@ -140,6 +140,9 @@ void port_i2s_allocate_init(i2s_t *self, bool left_justified) {
140
140
if (err == ESP_ERR_NOT_FOUND ) {
141
141
mp_raise_RuntimeError (MP_ERROR_TEXT ("Peripheral in use" ));
142
142
}
143
+ self -> playing = false;
144
+ self -> paused = false;
145
+ self -> stopping = false;
143
146
144
147
i2s_event_callbacks_t callbacks = {
145
148
.on_recv = NULL ,
@@ -157,6 +160,8 @@ void port_i2s_deinit(i2s_t *self) {
157
160
}
158
161
159
162
void 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 );
160
165
self -> sample = sample ;
161
166
self -> loop = loop ;
162
167
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) {
204
209
}
205
210
206
211
bool 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.
207
215
return self -> playing && !self -> stopping ;
208
216
}
209
217
@@ -219,14 +227,14 @@ void port_i2s_stop(i2s_t *self) {
219
227
}
220
228
221
229
void port_i2s_pause (i2s_t * self ) {
222
- if (!self -> paused ) {
230
+ if (self -> playing && !self -> paused ) {
223
231
self -> paused = true;
224
232
CHECK_ESP_RESULT (i2s_channel_disable (self -> handle ));
225
233
}
226
234
}
227
235
228
236
void port_i2s_resume (i2s_t * self ) {
229
- if (self -> paused ) {
237
+ if (self -> playing && self -> paused ) {
230
238
self -> paused = false;
231
239
CHECK_ESP_RESULT (i2s_channel_enable (self -> handle ));
232
240
}
0 commit comments