mirror of
https://github.com/espruino/Espruino.git
synced 2026-02-01 15:55:37 +00:00
Ensure STM32_I2S_AddSamples starts playback if there isn't enough space,
fix issue where calling AddSamples with too big a buffer would always cause failure
This commit is contained in:
parent
0a8ad236b5
commit
acf9482c1d
@ -244,10 +244,13 @@ int STM32_I2S_GetFreeSamples() {
|
||||
|
||||
// Add samples to the ringbuffer
|
||||
void STM32_I2S_AddSamples(int16_t *data, unsigned int count) {
|
||||
int timeout = 1000000;
|
||||
while ((STM32_I2S_GetFreeSamples() < (int)count+32) && --timeout); // wait here for space
|
||||
|
||||
// Try and fill until ringbuffer is full
|
||||
unsigned int freeSamples = STM32_I2S_GetFreeSamples();
|
||||
unsigned int c = count;
|
||||
if (c > freeSamples) {
|
||||
c = freeSamples;
|
||||
count -= freeSamples;
|
||||
} else count = 0;
|
||||
while (c--) {
|
||||
audioRingBuf[audioRingIdxIn] = *(data++)
|
||||
+ (audioRingIdxIn&1); // add 1 bit of noise to stop DAC from turning off!
|
||||
@ -255,8 +258,8 @@ void STM32_I2S_AddSamples(int16_t *data, unsigned int count) {
|
||||
}
|
||||
|
||||
//jsiConsolePrintf("add %d %d %d %d\n", i2sDMAidx, i2sStatus, count, audioRingBufGetSamples());
|
||||
// start playback when we have enough
|
||||
if (i2sStatus == STM32_I2S_STOPPED && audioRingBufGetSamples()>I2S_DMA_BUFFER_SIZE*3) {
|
||||
// start playback if we have enough
|
||||
if (i2sStatus == STM32_I2S_STOPPED && audioRingBufGetSamples()>=I2S_DMA_BUFFER_SIZE*3) {
|
||||
// if audioRingBufGetSamples()>I2S_DMA_BUFFER_SIZE*3 we should have enough here to fill 6 buffers
|
||||
i2sDMAidx = !DMA_GetCurrentMemoryTarget(DMA1_Stream4);
|
||||
fillDMAFromRingBuffer(); // fill the first buffer with what we're currently reading from!
|
||||
@ -264,6 +267,21 @@ void STM32_I2S_AddSamples(int16_t *data, unsigned int count) {
|
||||
fillDMAFromRingBuffer(); // fill the second buffer
|
||||
STM32_I2S_Start();
|
||||
}
|
||||
|
||||
if (!count) return;
|
||||
// otherwise we still have more to put in - try and wait a bit
|
||||
if (STM32_I2S_GetFreeSamples() < (int)count) {
|
||||
// wait until we have space
|
||||
int timeout = 1000000;
|
||||
while ((STM32_I2S_GetFreeSamples() < (int)count) && --timeout); // wait here for space
|
||||
}
|
||||
// now attempt to put in the rest but drop any we don't have space for
|
||||
c = count;
|
||||
while (c-- && STM32_I2S_GetFreeSamples()) {
|
||||
audioRingBuf[audioRingIdxIn] = *(data++)
|
||||
+ (audioRingIdxIn&1); // add 1 bit of noise to stop DAC from turning off!
|
||||
audioRingIdxIn = (audioRingIdxIn+1) & (I2S_RING_BUFFER_SIZE-1);
|
||||
}
|
||||
}
|
||||
|
||||
void STM32_I2S_Start() {
|
||||
|
||||
@ -22,6 +22,12 @@
|
||||
#define I2S_RING_BUFFER_SIZE 8192 // size of ringbuffer used for audio input in u16
|
||||
// 8192 seems fine to use - still enough for 8 DMA packets worth/0.5sec...
|
||||
|
||||
/* jswrap_pb_audioFrame sends data in 2048 byte chunks and STM32_I2S_AddSamples
|
||||
starts playback at 3*I2S_DMA_BUFFER_SIZE. So I2S_RING_BUFFER_SIZE=8192
|
||||
is the least we can use, since any less and 3*I2S_DMA_BUFFER_SIZE would be
|
||||
big enough that the next sample from jswrap_pb_audioFrame would fill the buffer */
|
||||
|
||||
|
||||
typedef enum {
|
||||
STM32_I2S_STOPPED,
|
||||
STM32_I2S_PLAYING
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user