Skip to content

Commit c66f5a8

Browse files
committed
nrf: i2s: rewrite without 'goto'
1 parent fe9605a commit c66f5a8

File tree

1 file changed

+18
-16
lines changed

1 file changed

+18
-16
lines changed

ports/nrf/common-hal/audiobusio/I2SOut.c

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -112,20 +112,7 @@ static void i2s_buffer_fill(audiobusio_i2sout_obj_t* self) {
112112
self->next_buffer = !self->next_buffer;
113113
size_t bytesleft = self->buffer_length;
114114

115-
if (self->paused || self->stopping) {
116-
if (self->stopping) {
117-
NRF_I2S->TASKS_STOP = 1;
118-
self->playing = false;
119-
}
120-
stopping: ;
121-
uint32_t *bp = (uint32_t*)buffer;
122-
uint32_t *be = (uint32_t*)(buffer + bytesleft);
123-
for (; bp != be; )
124-
*bp++ = self->hold_value;
125-
return;
126-
}
127-
128-
while (bytesleft) {
115+
while (!self->paused && !self->stopping && bytesleft) {
129116
if (self->sample_data == self->sample_end) {
130117
uint32_t sample_buffer_length;
131118
audioio_get_buffer_result_t get_buffer_result =
@@ -137,12 +124,12 @@ stopping: ;
137124
audiosample_reset_buffer(self->sample, false, 0);
138125
} else {
139126
self->stopping = true;
140-
goto stopping;
127+
break;
141128
}
142129
}
143130
if (get_buffer_result == GET_BUFFER_ERROR || sample_buffer_length == 0) {
144131
self->stopping = true;
145-
goto stopping;
132+
break;
146133
}
147134
}
148135
uint16_t bytecount = MIN(bytesleft, (size_t)(self->sample_end - self->sample_data));
@@ -180,6 +167,21 @@ stopping: ;
180167
// For 8-bit stereo and 16-bit mono, 2 copies of the final sample are required
181168
self->hold_value = 0x00010001 * *(uint16_t*)(buffer-2);
182169
}
170+
171+
// Emulate pausing and stopping by filling the DMA buffer with copies of
172+
// the last sample. This includes the case where this iteration of
173+
// i2s_buffer_fill exhausted a non-looping sample.
174+
if (self->paused || self->stopping) {
175+
if (self->stopping) {
176+
NRF_I2S->TASKS_STOP = 1;
177+
self->playing = false;
178+
}
179+
uint32_t *bp = (uint32_t*)buffer;
180+
uint32_t *be = (uint32_t*)(buffer + bytesleft);
181+
for (; bp != be; )
182+
*bp++ = self->hold_value;
183+
return;
184+
}
183185
}
184186

185187
void common_hal_audiobusio_i2sout_construct(audiobusio_i2sout_obj_t* self,

0 commit comments

Comments
 (0)