Skip to content

Commit 342c4ae

Browse files
committed
Merge pull request #939 from me-no-dev/esp8266
I2S Optimizations
2 parents 2f474f0 + bd5b5d3 commit 342c4ae

File tree

2 files changed

+31
-6
lines changed

2 files changed

+31
-6
lines changed

cores/esp8266/core_esp8266_i2s.c

+25-3
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,16 @@ static uint32_t i2s_slc_queue[SLC_BUF_CNT-1];
5454
static uint8_t i2s_slc_queue_len;
5555
static uint32_t *i2s_slc_buf_pntr[SLC_BUF_CNT]; //Pointer to the I2S DMA buffer data
5656
static struct slc_queue_item i2s_slc_items[SLC_BUF_CNT]; //I2S DMA buffer descriptors
57+
static uint32_t *i2s_curr_slc_buf=NULL;//current buffer for writing
58+
static int i2s_curr_slc_buf_pos=0; //position in the current buffer
59+
60+
bool ICACHE_FLASH_ATTR i2s_is_full(){
61+
return (i2s_curr_slc_buf_pos==SLC_BUF_LEN || i2s_curr_slc_buf==NULL) && (i2s_slc_queue_len == 0);
62+
}
63+
64+
bool ICACHE_FLASH_ATTR i2s_is_empty(){
65+
return (i2s_slc_queue_len >= SLC_BUF_CNT-1);
66+
}
5767

5868
uint32_t ICACHE_FLASH_ATTR i2s_slc_queue_next_item(){ //pop the top off the queue
5969
uint8_t i;
@@ -73,7 +83,7 @@ void ICACHE_FLASH_ATTR i2s_slc_isr(void) {
7383
if (slc_intr_status & SLCIRXEOF) {
7484
ETS_SLC_INTR_DISABLE();
7585
struct slc_queue_item *finished_item = (struct slc_queue_item*)SLCRXEDA;
76-
86+
memset((void *)finished_item->buf_ptr, 0x00, SLC_BUF_LEN * 4);//zero the buffer so it is mute in case of underflow
7787
if (i2s_slc_queue_len >= SLC_BUF_CNT-1) { //All buffers are empty. This means we have an underflow
7888
i2s_slc_queue_next_item(); //free space for finished_item
7989
}
@@ -142,8 +152,6 @@ void ICACHE_FLASH_ATTR i2s_slc_end(){
142152
//at least the current sample rate. You can also call it quicker: it will suspend the calling
143153
//thread if the buffer is full and resume when there's room again.
144154

145-
static uint32_t *i2s_curr_slc_buf=NULL;
146-
static int i2s_curr_slc_buf_pos=0;
147155
bool ICACHE_FLASH_ATTR i2s_write_sample(uint32_t sample) {
148156
if (i2s_curr_slc_buf_pos==SLC_BUF_LEN || i2s_curr_slc_buf==NULL) {
149157
if(i2s_slc_queue_len == 0){
@@ -165,6 +173,20 @@ bool ICACHE_FLASH_ATTR i2s_write_sample(uint32_t sample) {
165173
return true;
166174
}
167175

176+
bool ICACHE_FLASH_ATTR i2s_write_sample_nb(uint32_t sample) {
177+
if (i2s_curr_slc_buf_pos==SLC_BUF_LEN || i2s_curr_slc_buf==NULL) {
178+
if(i2s_slc_queue_len == 0){
179+
return false;
180+
}
181+
ETS_SLC_INTR_DISABLE();
182+
i2s_curr_slc_buf = (uint32_t *)i2s_slc_queue_next_item();
183+
ETS_SLC_INTR_ENABLE();
184+
i2s_curr_slc_buf_pos=0;
185+
}
186+
i2s_curr_slc_buf[i2s_curr_slc_buf_pos++]=sample;
187+
return true;
188+
}
189+
168190
bool ICACHE_FLASH_ATTR i2s_write_lr(int16_t left, int16_t right){
169191
int sample = right & 0xFFFF;
170192
sample = sample << 16;

cores/esp8266/i2s.h

+6-3
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,12 @@ extern "C" {
4242

4343
void i2s_begin();
4444
void i2s_end();
45-
void i2s_set_rate(uint32_t rate);
46-
bool i2s_write_sample(uint32_t sample);
47-
bool i2s_write_lr(int16_t left, int16_t right);
45+
void i2s_set_rate(uint32_t rate);//Sample Rate in Hz (ex 44100, 48000)
46+
bool i2s_write_sample(uint32_t sample);//32bit sample with channels being upper and lower 16 bits (blocking when DMA is full)
47+
bool i2s_write_sample_nb(uint32_t sample);//same as above but does not block when DMA is full and returns false instead
48+
bool i2s_write_lr(int16_t left, int16_t right);//combines both channels and calls i2s_write_sample with the result
49+
bool i2s_is_full();//returns true if DMA is full and can not take more bytes (overflow)
50+
bool i2s_is_empty();//returns true if DMA is empty (underflow)
4851

4952
#ifdef __cplusplus
5053
}

0 commit comments

Comments
 (0)