From aeb2ea11482f4ba2e3e4f47536d2398c68e61870 Mon Sep 17 00:00:00 2001
From: Matthias Ringwald <matthias@ringwald.ch>
Date: Thu, 25 May 2023 18:14:17 +0200
Subject: [PATCH] hfp_codec: split hfp_codec_init into individual functions for
 mSBC and LC3-SWB

---
 example/sco_demo_util.c |  6 ++++--
 src/classic/hfp_codec.c | 38 +++++++++++++++-----------------------
 src/classic/hfp_codec.h | 17 ++++++++++++-----
 3 files changed, 31 insertions(+), 30 deletions(-)

diff --git a/example/sco_demo_util.c b/example/sco_demo_util.c
index 6ee3bfddd..81598b7cd 100644
--- a/example/sco_demo_util.c
+++ b/example/sco_demo_util.c
@@ -148,6 +148,7 @@ static btstack_sbc_decoder_state_t msbc_decoder_state;
 #ifdef ENABLE_HFP_SUPER_WIDE_BAND_SPEECH
 static const btstack_lc3_decoder_t * lc3_decoder;
 static btstack_lc3_decoder_google_t lc3_decoder_context;
+static btstack_lc3_encoder_google_t lc3_encoder_context;
 static hfp_h2_sync_t    hfp_h2_sync;
 #endif
 
@@ -449,7 +450,7 @@ static void handle_pcm_data(int16_t * data, int num_samples, int num_channels, i
 static void sco_demo_msbc_init(void){
     printf("SCO Demo: Init mSBC\n");
     btstack_sbc_decoder_init(&msbc_decoder_state, SBC_MODE_mSBC, &handle_pcm_data, NULL);
-    hfp_codec_init(&hfp_codec, HFP_CODEC_MSBC);
+    hfp_codec_init_msbc(&hfp_codec);
 }
 
 static void sco_demo_msbc_receive(const uint8_t * packet, uint16_t size){
@@ -511,7 +512,8 @@ static void sco_demo_lc3swb_init(void){
 
     printf("SCO Demo: Init LC3-SWB\n");
 
-    hfp_codec_init(&hfp_codec, HFP_CODEC_LC3_SWB);
+    const btstack_lc3_encoder_t * lc3_encoder = btstack_lc3_encoder_google_init_instance((btstack_lc3_encoder_google_t *) hfp_codec.lc3_encoder_context);
+    hfp_codec_init_lc3_swb(&hfp_codec, lc3_encoder, &lc3_encoder_context);
 
     // init lc3 decoder
     lc3_decoder = btstack_lc3_decoder_google_init_instance(&lc3_decoder_context);
diff --git a/src/classic/hfp_codec.c b/src/classic/hfp_codec.c
index 438c7150d..41a4955a7 100644
--- a/src/classic/hfp_codec.c
+++ b/src/classic/hfp_codec.c
@@ -86,31 +86,23 @@ void hfp_h2_framing_add_header(hfp_h2_framing_t * hfp_h2_framing, uint8_t * buff
     hfp_h2_framing->sequence_number = (hfp_h2_framing->sequence_number + 1) & 3;
 }
 
-
-void hfp_codec_init(hfp_codec_t * hfp_codec, uint8_t codec_id){
+void hfp_codec_init_msbc(hfp_codec_t * hfp_codec){
     memset(hfp_codec, 0, sizeof(hfp_codec_t));
     hfp_h2_framing_init(&hfp_codec->h2_framing);
-    switch (codec_id){
-#ifdef ENABLE_HFP_WIDE_BAND_SPEECH
-        case HFP_CODEC_MSBC:
-            hfp_codec->samples_per_frame = 120;
-            hfp_codec->encode = &hfp_codec_encode_msbc;
-            btstack_sbc_encoder_init(&hfp_codec->msbc_state, SBC_MODE_mSBC, 16, 8, SBC_ALLOCATION_METHOD_LOUDNESS, 16000, 26, SBC_CHANNEL_MODE_MONO);
-            break;
-#endif
-#ifdef ENABLE_HFP_SUPER_WIDE_BAND_SPEECH
-        case HFP_CODEC_LC3_SWB:
-            hfp_codec->samples_per_frame = 240;
-            hfp_codec->encode = &hfp_codec_encode_lc3swb;
-            // init lc3 encoder
-            hfp_codec->lc3_encoder = btstack_lc3_encoder_google_init_instance(&hfp_codec->lc3_encoder_context);
-            hfp_codec->lc3_encoder->configure(&hfp_codec->lc3_encoder_context, 32000, BTSTACK_LC3_FRAME_DURATION_7500US, LC3_SWB_OCTETS_PER_FRAME);
-            break;
-#endif
-        default:
-            btstack_assert(false);
-            break;
-    }
+    hfp_codec->samples_per_frame = 120;
+    hfp_codec->encode = &hfp_codec_encode_msbc;
+    btstack_sbc_encoder_init(&hfp_codec->msbc_state, SBC_MODE_mSBC, 16, 8, SBC_ALLOCATION_METHOD_LOUDNESS, 16000, 26, SBC_CHANNEL_MODE_MONO);
+}
+
+void hfp_codec_init_lc3_swb(hfp_codec_t * hfp_codec, const btstack_lc3_encoder_t * lc3_encoder, void * lc3_encoder_context){
+    memset(hfp_codec, 0, sizeof(hfp_codec_t));
+    hfp_h2_framing_init(&hfp_codec->h2_framing);
+    hfp_codec->samples_per_frame = 240;
+    hfp_codec->encode = &hfp_codec_encode_lc3swb;
+    // init lc3 encoder
+    hfp_codec->lc3_encoder = lc3_encoder;
+    hfp_codec->lc3_encoder_context = lc3_encoder_context;
+    hfp_codec->lc3_encoder->configure(&hfp_codec->lc3_encoder_context, 32000, BTSTACK_LC3_FRAME_DURATION_7500US, LC3_SWB_OCTETS_PER_FRAME);
 }
 
 bool hfp_codec_can_encode_audio_frame_now(const hfp_codec_t * hfp_codec){
diff --git a/src/classic/hfp_codec.h b/src/classic/hfp_codec.h
index 2c9b578f5..3180127e8 100644
--- a/src/classic/hfp_codec.h
+++ b/src/classic/hfp_codec.h
@@ -99,7 +99,7 @@ struct hfp_codec {
 #endif
 #ifdef ENABLE_HFP_SUPER_WIDE_BAND_SPEECH
     const btstack_lc3_encoder_t * lc3_encoder;
-    btstack_lc3_encoder_google_t lc3_encoder_context;
+    void * lc3_encoder_context;
 #endif
 };
 
@@ -108,13 +108,20 @@ struct hfp_codec {
 typedef struct hfp_codec hfp_codec_t;
 
 /**
- * @brief Initialize HFP Audio Codec
- * @note  btstack_assert if codec_id is not supported
+ * @brief Initialize HFP Audio Codec for mSBC
  * @param hfp_codec
- * @param codec_id see HFP_CODEC_xxx in hfp.h
  * @return status
  */
-void hfp_codec_init(hfp_codec_t * hfp_codec, uint8_t codec_id);
+void hfp_codec_init_msbc(hfp_codec_t * hfp_codec);
+
+/**
+ * @brief Initialize HFP Audio Codec for LC3-SWB
+ * @param hfp_codec
+ * @param lc3_encoder
+ * @param lc3_encoder_context for lc3_encoder
+ * @return status
+ */
+void hfp_codec_init_lc3_swb(hfp_codec_t * hfp_codec, const btstack_lc3_encoder_t * lc3_encoder, void * lc3_encoder_context);
 
 /**
  * @brief Get number of audio samples per HFP SCO frame