mirror of
https://github.com/esp8266/Arduino.git
synced 2025-04-21 10:26:06 +03:00
commit
342c4ae6fb
@ -54,6 +54,16 @@ static uint32_t i2s_slc_queue[SLC_BUF_CNT-1];
|
|||||||
static uint8_t i2s_slc_queue_len;
|
static uint8_t i2s_slc_queue_len;
|
||||||
static uint32_t *i2s_slc_buf_pntr[SLC_BUF_CNT]; //Pointer to the I2S DMA buffer data
|
static uint32_t *i2s_slc_buf_pntr[SLC_BUF_CNT]; //Pointer to the I2S DMA buffer data
|
||||||
static struct slc_queue_item i2s_slc_items[SLC_BUF_CNT]; //I2S DMA buffer descriptors
|
static struct slc_queue_item i2s_slc_items[SLC_BUF_CNT]; //I2S DMA buffer descriptors
|
||||||
|
static uint32_t *i2s_curr_slc_buf=NULL;//current buffer for writing
|
||||||
|
static int i2s_curr_slc_buf_pos=0; //position in the current buffer
|
||||||
|
|
||||||
|
bool ICACHE_FLASH_ATTR i2s_is_full(){
|
||||||
|
return (i2s_curr_slc_buf_pos==SLC_BUF_LEN || i2s_curr_slc_buf==NULL) && (i2s_slc_queue_len == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ICACHE_FLASH_ATTR i2s_is_empty(){
|
||||||
|
return (i2s_slc_queue_len >= SLC_BUF_CNT-1);
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t ICACHE_FLASH_ATTR i2s_slc_queue_next_item(){ //pop the top off the queue
|
uint32_t ICACHE_FLASH_ATTR i2s_slc_queue_next_item(){ //pop the top off the queue
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
@ -73,7 +83,7 @@ void ICACHE_FLASH_ATTR i2s_slc_isr(void) {
|
|||||||
if (slc_intr_status & SLCIRXEOF) {
|
if (slc_intr_status & SLCIRXEOF) {
|
||||||
ETS_SLC_INTR_DISABLE();
|
ETS_SLC_INTR_DISABLE();
|
||||||
struct slc_queue_item *finished_item = (struct slc_queue_item*)SLCRXEDA;
|
struct slc_queue_item *finished_item = (struct slc_queue_item*)SLCRXEDA;
|
||||||
|
memset((void *)finished_item->buf_ptr, 0x00, SLC_BUF_LEN * 4);//zero the buffer so it is mute in case of underflow
|
||||||
if (i2s_slc_queue_len >= SLC_BUF_CNT-1) { //All buffers are empty. This means we have an underflow
|
if (i2s_slc_queue_len >= SLC_BUF_CNT-1) { //All buffers are empty. This means we have an underflow
|
||||||
i2s_slc_queue_next_item(); //free space for finished_item
|
i2s_slc_queue_next_item(); //free space for finished_item
|
||||||
}
|
}
|
||||||
@ -142,8 +152,6 @@ void ICACHE_FLASH_ATTR i2s_slc_end(){
|
|||||||
//at least the current sample rate. You can also call it quicker: it will suspend the calling
|
//at least the current sample rate. You can also call it quicker: it will suspend the calling
|
||||||
//thread if the buffer is full and resume when there's room again.
|
//thread if the buffer is full and resume when there's room again.
|
||||||
|
|
||||||
static uint32_t *i2s_curr_slc_buf=NULL;
|
|
||||||
static int i2s_curr_slc_buf_pos=0;
|
|
||||||
bool ICACHE_FLASH_ATTR i2s_write_sample(uint32_t sample) {
|
bool ICACHE_FLASH_ATTR i2s_write_sample(uint32_t sample) {
|
||||||
if (i2s_curr_slc_buf_pos==SLC_BUF_LEN || i2s_curr_slc_buf==NULL) {
|
if (i2s_curr_slc_buf_pos==SLC_BUF_LEN || i2s_curr_slc_buf==NULL) {
|
||||||
if(i2s_slc_queue_len == 0){
|
if(i2s_slc_queue_len == 0){
|
||||||
@ -165,6 +173,20 @@ bool ICACHE_FLASH_ATTR i2s_write_sample(uint32_t sample) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ICACHE_FLASH_ATTR i2s_write_sample_nb(uint32_t sample) {
|
||||||
|
if (i2s_curr_slc_buf_pos==SLC_BUF_LEN || i2s_curr_slc_buf==NULL) {
|
||||||
|
if(i2s_slc_queue_len == 0){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ETS_SLC_INTR_DISABLE();
|
||||||
|
i2s_curr_slc_buf = (uint32_t *)i2s_slc_queue_next_item();
|
||||||
|
ETS_SLC_INTR_ENABLE();
|
||||||
|
i2s_curr_slc_buf_pos=0;
|
||||||
|
}
|
||||||
|
i2s_curr_slc_buf[i2s_curr_slc_buf_pos++]=sample;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool ICACHE_FLASH_ATTR i2s_write_lr(int16_t left, int16_t right){
|
bool ICACHE_FLASH_ATTR i2s_write_lr(int16_t left, int16_t right){
|
||||||
int sample = right & 0xFFFF;
|
int sample = right & 0xFFFF;
|
||||||
sample = sample << 16;
|
sample = sample << 16;
|
||||||
|
@ -42,9 +42,12 @@ extern "C" {
|
|||||||
|
|
||||||
void i2s_begin();
|
void i2s_begin();
|
||||||
void i2s_end();
|
void i2s_end();
|
||||||
void i2s_set_rate(uint32_t rate);
|
void i2s_set_rate(uint32_t rate);//Sample Rate in Hz (ex 44100, 48000)
|
||||||
bool i2s_write_sample(uint32_t sample);
|
bool i2s_write_sample(uint32_t sample);//32bit sample with channels being upper and lower 16 bits (blocking when DMA is full)
|
||||||
bool i2s_write_lr(int16_t left, int16_t right);
|
bool i2s_write_sample_nb(uint32_t sample);//same as above but does not block when DMA is full and returns false instead
|
||||||
|
bool i2s_write_lr(int16_t left, int16_t right);//combines both channels and calls i2s_write_sample with the result
|
||||||
|
bool i2s_is_full();//returns true if DMA is full and can not take more bytes (overflow)
|
||||||
|
bool i2s_is_empty();//returns true if DMA is empty (underflow)
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user