xref: /btstack/src/classic/hfp_codec.h (revision db88441f671cf9b797d1a7638cc0e38d13db6ac0)
1 /*
2  * Copyright (C) 2023 BlueKitchen GmbH
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the copyright holders nor the names of
14  *    contributors may be used to endorse or promote products derived
15  *    from this software without specific prior written permission.
16  * 4. Any redistribution, use, or modification is done solely for
17  *    personal benefit and not for any commercial purpose or for
18  *    monetary gain.
19  *
20  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN
24  * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  * Please inquire about commercial licensing options at
34  * [email protected]
35  *
36  */
37 
38 /**
39  * @title HFP Audio Encoder
40  * @brief Create SCO packet with H2 Synchronization Header and encoded audio samples
41  */
42 
43 #ifndef HFP_CODEC_H
44 #define HFP_CODEC_H
45 
46 #include "btstack_config.h"
47 
48 #include "classic/hfp.h"    // HFP_CODEC_xxx
49 
50 #ifdef ENABLE_HFP_WIDE_BAND_SPEECH
51 #include "classic/btstack_sbc.h"
52 #include "classic/btstack_sbc_bluedroid.h"
53 #endif
54 
55 #ifdef ENABLE_HFP_SUPER_WIDE_BAND_SPEECH
56 #include "btstack_lc3_google.h"
57 #endif
58 
59 #include <stdint.h>
60 
61 #if defined __cplusplus
62 extern "C" {
63 #endif
64 
65 #define SCO_FRAME_SIZE 60
66 
67 // HFP H2
68 
69 #define HFP_H2_SYNC_FRAME_SIZE 60
70 
71 // HFP H2 Framing
72 typedef struct {
73     uint8_t sequence_number;
74 } hfp_h2_framing_t;
75 
76 /**
77  * @brief Init HFP H2 Framing state
78  * @param hfp_h2_framing
79  */
80 void hfp_h2_framing_init(hfp_h2_framing_t * hfp_h2_framing);
81 
82 /**
83  * @brief Add next H2 Header
84  * @param hfp_h2_framing
85  * @param buffer [2]
86  */
87 void hfp_h2_framing_add_header(hfp_h2_framing_t * hfp_h2_framing, uint8_t * buffer);
88 
89 
90 struct hfp_codec {
91     // to allow for 24 byte USB payloads, we encode up to two SCO packets
92     uint8_t sco_packet[2*SCO_FRAME_SIZE];
93     uint16_t read_pos;
94     uint16_t write_pos;
95     uint16_t samples_per_frame;
96     hfp_h2_framing_t h2_framing;
97     void (*encode)(struct hfp_codec * hfp_codec, int16_t * pcm_samples);
98 #ifdef ENABLE_HFP_WIDE_BAND_SPEECH
99     // @deprecated interface
100     btstack_sbc_encoder_state_t * msbc_encoder_context;
101     // codec instance based interface
102     const btstack_sbc_encoder_t * sbc_encoder_instance;
103     void * sbc_encoder_context;
104 #endif
105 #ifdef ENABLE_HFP_SUPER_WIDE_BAND_SPEECH
106     const btstack_lc3_encoder_t * lc3_encoder;
107     void * lc3_encoder_context;
108 #endif
109 };
110 
111 /* API_START */
112 
113 typedef struct hfp_codec hfp_codec_t;
114 
115 #ifdef ENABLE_HFP_WIDE_BAND_SPEECH
116 /**
117  * @brief Initialize HFP Audio Codec for mSBC
118  * @param hfp_codec
119  * @param msbc_encoder_context for msbc encoder
120  * @return status
121  */
122 void hfp_codec_init_msbc_with_codec(hfp_codec_t * hfp_codec, const btstack_sbc_encoder_t * sbc_encoder, void * sbc_encoder_context);
123 
124 /**
125  * @brief Initialize HFP Audio Codec for mSBC
126  * @deprecated Please use hfp_codec_init_msbc_with_codec
127  * @param hfp_codec
128  * @param msbc_encoder_context for msbc encoder
129  * @return status
130  */
131 void hfp_codec_init_msbc(hfp_codec_t * hfp_codec, btstack_sbc_encoder_state_t * msbc_encoder_context);
132 #endif
133 
134 #ifdef ENABLE_HFP_SUPER_WIDE_BAND_SPEECH
135 /**
136  * @brief Initialize HFP Audio Codec for LC3-SWB
137  * @param hfp_codec
138  * @param lc3_encoder
139  * @param lc3_encoder_context for lc3_encoder
140  * @return status
141  */
142 void hfp_codec_init_lc3_swb(hfp_codec_t * hfp_codec, const btstack_lc3_encoder_t * lc3_encoder, void * lc3_encoder_context);
143 #endif
144 
145 /**
146  * @brief Get number of audio samples per HFP SCO frame
147  * @param hfp_codec
148  * @return num audio samples per 7.5ms SCO packet
149  */
150 uint16_t hfp_codec_num_audio_samples_per_frame(const hfp_codec_t * hfp_codec);
151 
152 /**
153  * @brief Checks if next frame can be encoded
154  * @param hfp_codec
155  */
156 bool hfp_codec_can_encode_audio_frame_now(const hfp_codec_t * hfp_codec);
157 
158 /**
159  * Get number of bytes ready for sending
160  * @param hfp_codec
161  * @return num bytes ready for current packet
162  */
163 uint16_t hfp_codec_num_bytes_available(const hfp_codec_t * hfp_codec);
164 
165 /**
166  * Encode audio samples for HFP SCO packet
167  * @param hfp_codec
168  * @param pcm_samples - complete audio frame of hfp_msbc_num_audio_samples_per_frame int16 samples
169  */
170 void hfp_codec_encode_audio_frame(hfp_codec_t * hfp_codec, int16_t * pcm_samples);
171 
172 /**
173  * Read from stream into SCO packet buffer
174  * @param hfp_codec
175  * @param buffer to store stream
176  * @param size num bytes to read from stream
177  */
178 void hfp_codec_read_from_stream(hfp_codec_t * hfp_codec, uint8_t * buffer, uint16_t size);
179 
180 /**
181  * @param hfp_codec
182  */
183 void hfp_codec_deinit(hfp_codec_t * hfp_codec);
184 
185 /* API_END */
186 
187 #if defined __cplusplus
188 }
189 #endif
190 
191 #endif
192