@@ -38,24 +38,83 @@ typedef struct {
3838 esp_codec_dev_sample_info_t  in_fs ;
3939 esp_codec_dev_sample_info_t  out_fs ;
4040 esp_codec_dev_sample_info_t  fs ;
41-  esp_codec_dev_mutex_handle_t  lock ;
4241} i2s_data_t ;
4342
4443typedef  struct  i2s_data_keep_t  i2s_data_keep_t ;
4544struct  i2s_data_keep_t  {
46-  i2s_data_t  * i2s_data ;
47-  i2s_data_keep_t  * next ;
45+  i2s_data_t  * i2s_data ;
46+  esp_codec_dev_mutex_handle_t  mutex ;
47+  i2s_data_keep_t  * next ;
4848};
4949
5050static  i2s_data_keep_t  * i2s_data_list  =  NULL ;
5151
52+ static  esp_codec_dev_mutex_handle_t  try_alloc_mutex (uint8_t  port )
53+ {
54+  i2s_data_keep_t  * cur  =  i2s_data_list ;
55+  while  (cur  !=  NULL ) {
56+  if  (cur -> i2s_data -> port  ==  port ) {
57+  return  cur -> mutex ;
58+  }
59+  cur  =  cur -> next ;
60+  }
61+  return  esp_codec_dev_mutex_create ();
62+ }
63+ 
64+ static  esp_codec_dev_mutex_handle_t  get_mutex (i2s_data_t  * i2s_data )
65+ {
66+  i2s_data_keep_t  * cur  =  i2s_data_list ;
67+  while  (cur  !=  NULL ) {
68+  if  (cur -> i2s_data  ==  i2s_data ) {
69+  return  cur -> mutex ;
70+  }
71+  cur  =  cur -> next ;
72+  }
73+  return  NULL ;
74+ }
75+ 
76+ static  void  try_free_mutex (uint8_t  port , esp_codec_dev_mutex_handle_t  mutex )
77+ {
78+  uint8_t  ref_count  =  0 ;
79+  i2s_data_keep_t  * cur  =  i2s_data_list ;
80+  while  (cur  !=  NULL ) {
81+  if  (cur -> i2s_data -> port  ==  port ) {
82+  ref_count ++ ;
83+  }
84+  cur  =  cur -> next ;
85+  }
86+  if  (ref_count  ==  0 ) {
87+  esp_codec_dev_mutex_destroy (mutex );
88+  }
89+ }
90+ 
91+ static  void  _i2s_lock (i2s_data_t  * i2s_data , const  char  * func )
92+ {
93+  esp_codec_dev_mutex_handle_t  mutex  =  get_mutex (i2s_data );
94+  if  (mutex ) {
95+  int  ret  =  esp_codec_dev_mutex_lock (mutex , DEFAULT_WAIT_TIMEOUT );
96+  if  (ret  !=  ESP_CODEC_DEV_OK ) {
97+  ESP_LOGE (TAG , "Lock failed in %s" , func );
98+  }
99+  }
100+ }
101+ 
102+ static  void  _i2s_unlock (i2s_data_t  * i2s_data )
103+ {
104+  esp_codec_dev_mutex_handle_t  mutex  =  get_mutex (i2s_data );
105+  if  (mutex ) {
106+  esp_codec_dev_mutex_unlock (mutex );
107+  }
108+ }
109+ 
52110static  void  add_to_keeper (i2s_data_t  * i2s_data )
53111{
54112 i2s_data_keep_t  * keep_info  =  (i2s_data_keep_t  * ) calloc (1 , sizeof (i2s_data_keep_t ));
55113 if  (keep_info  ==  NULL ) {
56114 ESP_LOGE (TAG , "Out of memory for keeper" );
57115 return ;
58116 }
117+  keep_info -> mutex  =  try_alloc_mutex (i2s_data -> port );
59118 keep_info -> i2s_data  =  i2s_data ;
60119 if  (i2s_data_list  ==  NULL ) {
61120 i2s_data_list  =  keep_info ;
@@ -76,6 +135,7 @@ static void remove_from_keeper(i2s_data_t *i2s_data)
76135 } else  {
77136 pre -> next  =  cur -> next ;
78137 }
138+  try_free_mutex (i2s_data -> port , cur -> mutex );
79139 free (cur );
80140 break ;
81141 }
@@ -408,9 +468,6 @@ static int _i2s_data_open(const audio_codec_data_if_t *h, void *data_cfg, int cf
408468 i2s_data -> port  =  i2s_cfg -> port ;
409469 i2s_data -> out_handle  =  i2s_cfg -> tx_handle ;
410470 i2s_data -> in_handle  =  i2s_cfg -> rx_handle ;
411-  if  (i2s_data -> out_handle  !=  NULL  &&  i2s_data -> in_handle  !=  NULL ) {
412-  i2s_data -> lock  =  esp_codec_dev_mutex_create ();
413-  }
414471 add_to_keeper (i2s_data );
415472 return  ESP_CODEC_DEV_OK ;
416473}
@@ -434,12 +491,7 @@ static int _i2s_data_enable(const audio_codec_data_if_t *h, esp_codec_dev_type_t
434491 return  ESP_CODEC_DEV_WRONG_STATE ;
435492 }
436493 int  ret  =  ESP_CODEC_DEV_OK ;
437-  if  (i2s_data -> lock ) {
438-  ret  =  esp_codec_dev_mutex_lock (i2s_data -> lock , DEFAULT_WAIT_TIMEOUT );
439-  if  (ret  !=  ESP_CODEC_DEV_OK ) {
440-  ESP_LOGW (TAG , "Enable wait lock timeout" );
441-  }
442-  }
494+  _i2s_lock (i2s_data , __func__ );
443495 if  (dev_type  ==  ESP_CODEC_DEV_TYPE_IN_OUT ) {
444496 ret  =  _i2s_drv_enable (i2s_data , true, enable );
445497 ret  =  _i2s_drv_enable (i2s_data , false, enable );
@@ -486,9 +538,7 @@ static int _i2s_data_enable(const audio_codec_data_if_t *h, esp_codec_dev_type_t
486538 if  (dev_type  &  ESP_CODEC_DEV_TYPE_OUT ) {
487539 i2s_data -> out_enable  =  enable ;
488540 }
489-  if  (i2s_data -> lock ) {
490-  esp_codec_dev_mutex_unlock (i2s_data -> lock );
491-  }
541+  _i2s_unlock (i2s_data );
492542 return  ret ;
493543}
494544
@@ -524,12 +574,7 @@ static int _i2s_data_set_fmt(const audio_codec_data_if_t *h, esp_codec_dev_type_
524574 }
525575#if  ESP_IDF_VERSION  >= ESP_IDF_VERSION_VAL (5 , 0 , 0 )
526576 int  ret ;
527-  if  (i2s_data -> lock ) {
528-  ret  =  esp_codec_dev_mutex_lock (i2s_data -> lock , DEFAULT_WAIT_TIMEOUT );
529-  if  (ret  !=  ESP_CODEC_DEV_OK ) {
530-  ESP_LOGW (TAG , "Set format wait lock timeout" );
531-  }
532-  }
577+  _i2s_lock (i2s_data , __func__ );
533578 // disable internally 
534579 if  (dev_type  &  ESP_CODEC_DEV_TYPE_OUT ) {
535580 _i2s_drv_enable (i2s_data , true, false);
@@ -548,9 +593,7 @@ static int _i2s_data_set_fmt(const audio_codec_data_if_t *h, esp_codec_dev_type_
548593 } else  {
549594 ret  =  check_fs_compatible (i2s_data , dev_type  &  ESP_CODEC_DEV_TYPE_OUT  ? true : false, fs );
550595 }
551-  if  (i2s_data -> lock ) {
552-  esp_codec_dev_mutex_unlock (i2s_data -> lock );
553-  }
596+  _i2s_unlock (i2s_data );
554597 return  ret ;
555598#else 
556599 // When use multichannel data 
@@ -638,10 +681,6 @@ static int _i2s_data_close(const audio_codec_data_if_t *h)
638681 memset (& i2s_data -> fs , 0 , sizeof (esp_codec_dev_sample_info_t ));
639682 memset (& i2s_data -> in_fs , 0 , sizeof (esp_codec_dev_sample_info_t ));
640683 memset (& i2s_data -> out_fs , 0 , sizeof (esp_codec_dev_sample_info_t ));
641-  if  (i2s_data -> lock ) {
642-  esp_codec_dev_mutex_destroy (i2s_data -> lock );
643-  i2s_data -> lock  =  NULL ;
644-  }
645684 i2s_data -> is_open  =  false;
646685 remove_from_keeper (i2s_data );
647686 return  ESP_CODEC_DEV_OK ;
0 commit comments