@@ -87,7 +87,7 @@ LOG_MODULE_REGISTER(audio_datapath, CONFIG_AUDIO_DATAPATH_LOG_LEVEL);
87
87
#define JUST_IN_TIME_BOUND_US 2500
88
88
89
89
/* How often to print under-run warning */
90
- #define UNDERRUN_LOG_INTERVAL_BLKS 5000
90
+ #define LOG_INTERVAL_BLKS 5000
91
91
92
92
NET_BUF_POOL_FIXED_DEFINE (pool_i2s_rx , FIFO_NUM_BLKS , BLK_STEREO_SIZE_OCTETS ,
93
93
sizeof (struct audio_metadata ), NULL );
@@ -247,7 +247,7 @@ static void drift_comp_state_set(enum drift_comp_state new_state)
247
247
*
248
248
* @param frame_start_ts_us I2S frame start timestamp.
249
249
*/
250
- static void audio_datapath_drift_compensation (uint32_t frame_start_ts_us )
250
+ static inline void audio_datapath_drift_compensation (uint32_t frame_start_ts_us )
251
251
{
252
252
if (CONFIG_AUDIO_DEV == HEADSET ) {
253
253
/** For headsets we do not use the timestamp gotten from hci_tx_sync_get to adjust
@@ -580,7 +580,7 @@ static struct {
580
580
* @retval 0 if success.
581
581
* @retval -ENOMEM No available buffers.
582
582
*/
583
- static int alt_buffer_get (void * * p_buffer )
583
+ static inline int alt_buffer_get (void * * p_buffer )
584
584
{
585
585
if (!alt .buf_0_in_use ) {
586
586
alt .buf_0_in_use = true;
@@ -601,7 +601,7 @@ static int alt_buffer_get(void **p_buffer)
601
601
*
602
602
* @param p_buffer Buffer to free.
603
603
*/
604
- static void alt_buffer_free (void const * const p_buffer )
604
+ static inline void alt_buffer_free (void const * const p_buffer )
605
605
{
606
606
if (p_buffer == alt .buf_0 ) {
607
607
alt .buf_0_in_use = false;
@@ -619,6 +619,14 @@ static void alt_buffer_free_both(void)
619
619
alt .buf_1_in_use = false;
620
620
}
621
621
622
+ static struct audio_metadata i2s_meta = {.data_coding = PCM ,
623
+ .data_len_us = 1000 ,
624
+ .sample_rate_hz = CONFIG_AUDIO_SAMPLE_RATE_HZ ,
625
+ .bits_per_sample = CONFIG_AUDIO_BIT_DEPTH_BITS ,
626
+ .carried_bits_per_sample = CONFIG_AUDIO_BIT_DEPTH_BITS ,
627
+ .locations = BT_AUDIO_LOCATION_FRONT_LEFT |
628
+ BT_AUDIO_LOCATION_FRONT_RIGHT ,
629
+ .bad_data = false};
622
630
/*
623
631
* This handler function is called every time I2S needs new buffers for
624
632
* TX and RX data.
@@ -632,8 +640,10 @@ static void alt_buffer_free_both(void)
632
640
static void audio_datapath_i2s_blk_complete (uint32_t frame_start_ts_us , uint32_t * rx_buf_released ,
633
641
uint32_t const * tx_buf_released )
634
642
{
635
- int ret ;
636
- static bool underrun_condition ;
643
+ int ret = 0 ;
644
+ static uint32_t num_calls ;
645
+
646
+ num_calls ++ ;
637
647
638
648
alt_buffer_free (tx_buf_released );
639
649
@@ -645,83 +655,77 @@ static void audio_datapath_i2s_blk_complete(uint32_t frame_start_ts_us, uint32_t
645
655
static uint8_t * tx_buf ;
646
656
647
657
if (IS_ENABLED (CONFIG_STREAM_BIDIRECTIONAL ) || (CONFIG_AUDIO_DEV == HEADSET )) {
648
- if (tx_buf_released != NULL ) {
649
- /* Double buffered index */
650
- uint32_t next_out_blk_idx = NEXT_IDX (ctrl_blk .out .cons_blk_idx );
651
-
652
- if (next_out_blk_idx != ctrl_blk .out .prod_blk_idx ) {
653
- /* Only increment if not in under-run condition */
654
- ctrl_blk .out .cons_blk_idx = next_out_blk_idx ;
655
- if (underrun_condition ) {
656
- underrun_condition = false;
657
- LOG_WRN ("Data received, total under-runs: %d" ,
658
- ctrl_blk .out .total_blk_underruns );
659
- }
658
+ static bool underrun_condition ;
660
659
661
- tx_buf = (uint8_t * )& ctrl_blk .out
662
- .fifo [next_out_blk_idx * BLK_STEREO_NUM_SAMPS ];
660
+ if (tx_buf_released == NULL ) {
661
+ ERR_CHK_MSG (- ENOMEM , "No TX data available" );
662
+ }
663
663
664
- } else {
665
- if (stream_state_get () == STATE_STREAMING ) {
666
- underrun_condition = true;
667
- ctrl_blk .out .total_blk_underruns ++ ;
664
+ /* Double buffered index */
665
+ uint32_t next_out_blk_idx = NEXT_IDX (ctrl_blk .out .cons_blk_idx );
668
666
669
- if ((ctrl_blk .out .total_blk_underruns %
670
- UNDERRUN_LOG_INTERVAL_BLKS ) == 0 ) {
671
- LOG_WRN ("In I2S TX under-run condition, total: %d" ,
672
- ctrl_blk .out .total_blk_underruns );
673
- }
674
- }
667
+ if (next_out_blk_idx != ctrl_blk .out .prod_blk_idx ) {
668
+ /* Only increment if not in under-run condition */
669
+ ctrl_blk .out .cons_blk_idx = next_out_blk_idx ;
670
+ if (underrun_condition ) {
671
+ underrun_condition = false;
672
+ LOG_WRN ("Data received, total under-runs: %d" ,
673
+ ctrl_blk .out .total_blk_underruns );
674
+ }
675
675
676
- /*
677
- * No data available in out.fifo
678
- * use alternative buffers
679
- */
680
- ret = alt_buffer_get ((void * * )& tx_buf );
681
- ERR_CHK (ret );
676
+ tx_buf = (uint8_t * )& ctrl_blk .out
677
+ .fifo [next_out_blk_idx * BLK_STEREO_NUM_SAMPS ];
682
678
683
- memset (tx_buf , 0 , BLK_STEREO_SIZE_OCTETS );
684
- }
679
+ } else {
680
+ if (stream_state_get () == STATE_STREAMING ) {
681
+ underrun_condition = true;
682
+ ctrl_blk .out .total_blk_underruns ++ ;
685
683
686
- if (tone_active ) {
687
- tone_mix (tx_buf );
684
+ if ((ctrl_blk .out .total_blk_underruns % LOG_INTERVAL_BLKS ) == 0 ) {
685
+ LOG_WRN ("In I2S TX under-run condition, total: %d" ,
686
+ ctrl_blk .out .total_blk_underruns );
687
+ }
688
688
}
689
+
690
+ /*
691
+ * No data available in out.fifo
692
+ * use alternative buffers
693
+ */
694
+ ret = alt_buffer_get ((void * * )& tx_buf );
695
+ ERR_CHK (ret );
696
+
697
+ memset (tx_buf , 0 , BLK_STEREO_SIZE_OCTETS );
698
+ }
699
+
700
+ if (tone_active ) {
701
+ tone_mix (tx_buf );
689
702
}
690
703
}
691
704
692
705
/********** I2S RX **********/
693
- static int prev_ret ;
694
706
struct net_buf * rx_audio_block = NULL ;
707
+ static uint32_t num_overruns ;
708
+ static uint32_t num_overruns_last_printed ;
695
709
696
710
if (IS_ENABLED (CONFIG_STREAM_BIDIRECTIONAL ) || (CONFIG_AUDIO_DEV == GATEWAY )) {
697
711
if (rx_buf_released == NULL ) {
698
- /* No RX data available */
699
712
ERR_CHK_MSG (- ENOMEM , "No RX data available" );
700
713
}
701
714
702
715
if (k_msgq_num_free_get (ctrl_blk .in .audio_q ) == 0 || pool_i2s_rx .avail_count == 0 ) {
703
- ret = - ENOMEM ;
704
- } else {
705
- ret = 0 ;
706
- }
707
-
708
- /* If RX FIFO is filled up */
709
- if (ret == - ENOMEM ) {
716
+ /* If RX FIFO is filled up */
717
+ num_overruns ++ ;
710
718
struct net_buf * stale_i2s_data ;
711
-
712
- if (ret != prev_ret ) {
713
- LOG_WRN ("I2S RX overrun. Single msg" );
714
- prev_ret = ret ;
715
- }
716
-
717
719
ret = k_msgq_get (ctrl_blk .in .audio_q , (void * )& stale_i2s_data , K_NO_WAIT );
718
720
ERR_CHK (ret );
719
-
721
+ /* Discard data */
720
722
net_buf_unref (stale_i2s_data );
723
+ }
721
724
722
- } else if (ret == 0 && prev_ret == - ENOMEM ) {
723
- LOG_WRN ("I2S RX continuing stream" );
724
- prev_ret = ret ;
725
+ if ((num_calls % LOG_INTERVAL_BLKS == 0 ) &&
726
+ (num_overruns != num_overruns_last_printed )) {
727
+ LOG_WRN ("I2S RX overrun count: %d" , num_overruns );
728
+ num_overruns_last_printed = num_overruns ;
725
729
}
726
730
727
731
rx_audio_block = net_buf_alloc (& pool_i2s_rx , K_NO_WAIT );
@@ -732,16 +736,9 @@ static void audio_datapath_i2s_blk_complete(uint32_t frame_start_ts_us, uint32_t
732
736
/* Store RX buffer in net_buf */
733
737
net_buf_add_mem (rx_audio_block , rx_buf_released , BLK_STEREO_SIZE_OCTETS );
734
738
739
+ /* Store I2S related metadata */
735
740
struct audio_metadata * meta = net_buf_user_data (rx_audio_block );
736
-
737
- /* Add meta data */
738
- meta -> data_coding = PCM ;
739
- meta -> data_len_us = 1000 ;
740
- meta -> sample_rate_hz = CONFIG_AUDIO_SAMPLE_RATE_HZ ;
741
- meta -> bits_per_sample = CONFIG_AUDIO_BIT_DEPTH_BITS ;
742
- meta -> carried_bits_per_sample = CONFIG_AUDIO_BIT_DEPTH_BITS ;
743
- meta -> locations = BT_AUDIO_LOCATION_FRONT_LEFT | BT_AUDIO_LOCATION_FRONT_RIGHT ;
744
- meta -> bad_data = false;
741
+ * meta = i2s_meta ;
745
742
746
743
ret = k_msgq_put (ctrl_blk .in .audio_q , (void * )& rx_audio_block , K_NO_WAIT );
747
744
ERR_CHK_MSG (ret , "Unable to put RX audio block into queue" );
@@ -770,11 +767,11 @@ static void audio_datapath_i2s_start(void)
770
767
if (IS_ENABLED (CONFIG_STREAM_BIDIRECTIONAL ) || (CONFIG_AUDIO_DEV == HEADSET )) {
771
768
ctrl_blk .out .cons_blk_idx = PREV_IDX (ctrl_blk .out .cons_blk_idx );
772
769
tx_buf_0 = (uint8_t * )& ctrl_blk .out
773
- .fifo [ctrl_blk .out .cons_blk_idx * BLK_STEREO_NUM_SAMPS ];
770
+ .fifo [ctrl_blk .out .cons_blk_idx * BLK_STEREO_NUM_SAMPS ];
774
771
775
772
ctrl_blk .out .cons_blk_idx = PREV_IDX (ctrl_blk .out .cons_blk_idx );
776
773
tx_buf_1 = (uint8_t * )& ctrl_blk .out
777
- .fifo [ctrl_blk .out .cons_blk_idx * BLK_STEREO_NUM_SAMPS ];
774
+ .fifo [ctrl_blk .out .cons_blk_idx * BLK_STEREO_NUM_SAMPS ];
778
775
}
779
776
780
777
/* Start I2S */
0 commit comments