@@ -113,18 +113,18 @@ bool i2s_rx_is_empty() {
113113 return _i2s_is_empty ( rx );
114114}
115115
116- static int16_t _i2s_available (const i2s_state_t * ch ) {
116+ static uint16_t _i2s_available (const i2s_state_t * ch ) {
117117 if (!ch ) {
118118 return 0 ;
119119 }
120120 return (SLC_BUF_CNT - ch -> slc_queue_len ) * SLC_BUF_LEN ;
121121}
122122
123- int16_t i2s_available (){
123+ uint16_t i2s_available (){
124124 return _i2s_available ( tx );
125125}
126126
127- int16_t i2s_rx_available (){
127+ uint16_t i2s_rx_available (){
128128 return _i2s_available ( rx );
129129}
130130
@@ -331,6 +331,74 @@ bool i2s_write_lr(int16_t left, int16_t right){
331331 return i2s_write_sample (sample );
332332}
333333
334+ // writes a buffer of frames into the DMA memory, returns the amount of frames written
335+ // A frame is just a int16_t for mono, for stereo a frame is two int16_t, one for each channel.
336+ static uint16_t _i2s_write_buffer (int16_t * frames , uint16_t frame_count , bool mono , bool nb ) {
337+ uint16_t frames_written = 0 ;
338+
339+ while (frame_count > 0 ) {
340+
341+ // make sure we have room in the current buffer
342+ if (tx -> curr_slc_buf_pos == SLC_BUF_LEN || tx -> curr_slc_buf == NULL ) {
343+ // no room in the current buffer? if there are no buffers available then exit
344+ if (tx -> slc_queue_len == 0 )
345+ {
346+ if (nb ) {
347+ // if nonblocking just return the number of frames written so far
348+ break ;
349+ }
350+ else {
351+ while (1 ) {
352+ if (tx -> slc_queue_len > 0 ) {
353+ break ;
354+ } else {
355+ optimistic_yield (10000 );
356+ }
357+ }
358+ }
359+ }
360+
361+ // get a new buffer
362+ ETS_SLC_INTR_DISABLE ();
363+ tx -> curr_slc_buf = (uint32_t * )i2s_slc_queue_next_item (tx );
364+ ETS_SLC_INTR_ENABLE ();
365+ tx -> curr_slc_buf_pos = 0 ;
366+ }
367+
368+ //space available in the current buffer
369+ uint16_t available = SLC_BUF_LEN - tx -> curr_slc_buf_pos ;
370+
371+ uint16_t fc = (available < frame_count ) ? available : frame_count ;
372+
373+ if (mono ) {
374+ for (uint16_t i = 0 ;i < fc ;i ++ ){
375+ uint16_t v = (uint16_t )(* frames ++ );
376+ tx -> curr_slc_buf [tx -> curr_slc_buf_pos ++ ] = (v << 16 ) | v ;
377+ }
378+ }
379+ else
380+ {
381+ for (uint16_t i = 0 ;i < fc ;i ++ ){
382+ uint16_t v1 = (uint16_t )(* frames ++ );
383+ uint16_t v2 = (uint16_t )(* frames ++ );
384+ tx -> curr_slc_buf [tx -> curr_slc_buf_pos ++ ] = (v1 << 16 ) | v2 ;
385+ }
386+ }
387+
388+ frame_count -= fc ;
389+ frames_written += fc ;
390+ }
391+ return frames_written ;
392+ }
393+
394+ uint16_t i2s_write_buffer_mono_nb (int16_t * frames , uint16_t frame_count ) { return _i2s_write_buffer (frames , frame_count , true, true); }
395+
396+ uint16_t i2s_write_buffer_mono (int16_t * frames , uint16_t frame_count ) { return _i2s_write_buffer (frames , frame_count , true, false); }
397+
398+ uint16_t i2s_write_buffer_nb (int16_t * frames , uint16_t frame_count ) { return _i2s_write_buffer (frames , frame_count , false, true); }
399+
400+ uint16_t i2s_write_buffer (int16_t * frames , uint16_t frame_count ) { return _i2s_write_buffer (frames , frame_count , false, false); }
401+
334402bool i2s_read_sample (int16_t * left , int16_t * right , bool blocking ) {
335403 if (!rx ) {
336404 return false;
0 commit comments