@@ -113,18 +113,18 @@ bool i2s_rx_is_empty() {
113
113
return _i2s_is_empty ( rx );
114
114
}
115
115
116
- static int16_t _i2s_available (const i2s_state_t * ch ) {
116
+ static uint16_t _i2s_available (const i2s_state_t * ch ) {
117
117
if (!ch ) {
118
118
return 0 ;
119
119
}
120
120
return (SLC_BUF_CNT - ch -> slc_queue_len ) * SLC_BUF_LEN ;
121
121
}
122
122
123
- int16_t i2s_available (){
123
+ uint16_t i2s_available (){
124
124
return _i2s_available ( tx );
125
125
}
126
126
127
- int16_t i2s_rx_available (){
127
+ uint16_t i2s_rx_available (){
128
128
return _i2s_available ( rx );
129
129
}
130
130
@@ -331,6 +331,74 @@ bool i2s_write_lr(int16_t left, int16_t right){
331
331
return i2s_write_sample (sample );
332
332
}
333
333
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
+
334
402
bool i2s_read_sample (int16_t * left , int16_t * right , bool blocking ) {
335
403
if (!rx ) {
336
404
return false;
0 commit comments