summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjepler <jepler@gmail.com>2019-09-09 19:26:18 -0500
committerjepler <jepler@gmail.com>2019-09-09 19:26:18 -0500
commitc66f5a853644c0bc2bade243b1e7a9e9a69c1b4b (patch)
tree448d4c73993db5eb98657f0914dd3ad4d48ce12b
parentfe9605a6a39e92f368658fb731f38ce0830ebe68 (diff)
nrf: i2s: rewrite without 'goto'
-rw-r--r--ports/nrf/common-hal/audiobusio/I2SOut.c34
1 files changed, 18 insertions, 16 deletions
diff --git a/ports/nrf/common-hal/audiobusio/I2SOut.c b/ports/nrf/common-hal/audiobusio/I2SOut.c
index e18ed9269..e167e964f 100644
--- a/ports/nrf/common-hal/audiobusio/I2SOut.c
+++ b/ports/nrf/common-hal/audiobusio/I2SOut.c
@@ -112,20 +112,7 @@ static void i2s_buffer_fill(audiobusio_i2sout_obj_t* self) {
self->next_buffer = !self->next_buffer;
size_t bytesleft = self->buffer_length;
- if (self->paused || self->stopping) {
- if (self->stopping) {
- NRF_I2S->TASKS_STOP = 1;
- self->playing = false;
- }
-stopping: ;
- uint32_t *bp = (uint32_t*)buffer;
- uint32_t *be = (uint32_t*)(buffer + bytesleft);
- for (; bp != be; )
- *bp++ = self->hold_value;
- return;
- }
-
- while (bytesleft) {
+ while (!self->paused && !self->stopping && bytesleft) {
if (self->sample_data == self->sample_end) {
uint32_t sample_buffer_length;
audioio_get_buffer_result_t get_buffer_result =
@@ -137,12 +124,12 @@ stopping: ;
audiosample_reset_buffer(self->sample, false, 0);
} else {
self->stopping = true;
- goto stopping;
+ break;
}
}
if (get_buffer_result == GET_BUFFER_ERROR || sample_buffer_length == 0) {
self->stopping = true;
- goto stopping;
+ break;
}
}
uint16_t bytecount = MIN(bytesleft, (size_t)(self->sample_end - self->sample_data));
@@ -180,6 +167,21 @@ stopping: ;
// For 8-bit stereo and 16-bit mono, 2 copies of the final sample are required
self->hold_value = 0x00010001 * *(uint16_t*)(buffer-2);
}
+
+ // Emulate pausing and stopping by filling the DMA buffer with copies of
+ // the last sample. This includes the case where this iteration of
+ // i2s_buffer_fill exhausted a non-looping sample.
+ if (self->paused || self->stopping) {
+ if (self->stopping) {
+ NRF_I2S->TASKS_STOP = 1;
+ self->playing = false;
+ }
+ uint32_t *bp = (uint32_t*)buffer;
+ uint32_t *be = (uint32_t*)(buffer + bytesleft);
+ for (; bp != be; )
+ *bp++ = self->hold_value;
+ return;
+ }
}
void common_hal_audiobusio_i2sout_construct(audiobusio_i2sout_obj_t* self,