1a602f23dSMatthias Ringwald /* 2a602f23dSMatthias Ringwald * Copyright (C) 2023 BlueKitchen GmbH 3a602f23dSMatthias Ringwald * 4a602f23dSMatthias Ringwald * Redistribution and use in source and binary forms, with or without 5a602f23dSMatthias Ringwald * modification, are permitted provided that the following conditions 6a602f23dSMatthias Ringwald * are met: 7a602f23dSMatthias Ringwald * 8a602f23dSMatthias Ringwald * 1. Redistributions of source code must retain the above copyright 9a602f23dSMatthias Ringwald * notice, this list of conditions and the following disclaimer. 10a602f23dSMatthias Ringwald * 2. Redistributions in binary form must reproduce the above copyright 11a602f23dSMatthias Ringwald * notice, this list of conditions and the following disclaimer in the 12a602f23dSMatthias Ringwald * documentation and/or other materials provided with the distribution. 13a602f23dSMatthias Ringwald * 3. Neither the name of the copyright holders nor the names of 14a602f23dSMatthias Ringwald * contributors may be used to endorse or promote products derived 15a602f23dSMatthias Ringwald * from this software without specific prior written permission. 16a602f23dSMatthias Ringwald * 4. Any redistribution, use, or modification is done solely for 17a602f23dSMatthias Ringwald * personal benefit and not for any commercial purpose or for 18a602f23dSMatthias Ringwald * monetary gain. 19a602f23dSMatthias Ringwald * 20a602f23dSMatthias Ringwald * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 21a602f23dSMatthias Ringwald * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22a602f23dSMatthias Ringwald * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23a602f23dSMatthias Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN 24a602f23dSMatthias Ringwald * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25a602f23dSMatthias Ringwald * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26a602f23dSMatthias Ringwald * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 27a602f23dSMatthias Ringwald * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28a602f23dSMatthias Ringwald * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29a602f23dSMatthias Ringwald * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 30a602f23dSMatthias Ringwald * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31a602f23dSMatthias Ringwald * SUCH DAMAGE. 32a602f23dSMatthias Ringwald * 33a602f23dSMatthias Ringwald * Please inquire about commercial licensing options at 34a602f23dSMatthias Ringwald * [email protected] 35a602f23dSMatthias Ringwald * 36a602f23dSMatthias Ringwald */ 37a602f23dSMatthias Ringwald 38a602f23dSMatthias Ringwald /** 39a602f23dSMatthias Ringwald * @title HFP Audio Encoder 40a602f23dSMatthias Ringwald * @brief Create SCO packet with H2 Synchronization Header and encoded audio samples 41a602f23dSMatthias Ringwald */ 42a602f23dSMatthias Ringwald 43a602f23dSMatthias Ringwald #ifndef HFP_CODEC_H 44a602f23dSMatthias Ringwald #define HFP_CODEC_H 45a602f23dSMatthias Ringwald 46a602f23dSMatthias Ringwald #include "btstack_config.h" 47a602f23dSMatthias Ringwald #include "hfp.h" // hfp_h2_framing 48a602f23dSMatthias Ringwald 49a602f23dSMatthias Ringwald #include <stdint.h> 50a602f23dSMatthias Ringwald 51a602f23dSMatthias Ringwald #ifdef ENABLE_HFP_WIDE_BAND_SPEECH 52a602f23dSMatthias Ringwald #include "btstack_sbc.h" 53a602f23dSMatthias Ringwald #endif 54a602f23dSMatthias Ringwald 5516527ed5SMatthias Ringwald #ifdef ENABLE_HFP_SUPER_WIDE_BAND_SPEECH 5616527ed5SMatthias Ringwald #include "btstack_lc3_google.h" 5716527ed5SMatthias Ringwald #endif 5816527ed5SMatthias Ringwald 59a602f23dSMatthias Ringwald #if defined __cplusplus 60a602f23dSMatthias Ringwald extern "C" { 61a602f23dSMatthias Ringwald #endif 62a602f23dSMatthias Ringwald 63*f789a318SMatthias Ringwald #define SCO_FRAME_SIZE 60 64*f789a318SMatthias Ringwald 65a602f23dSMatthias Ringwald struct hfp_codec { 66*f789a318SMatthias Ringwald // to allow for 24 byte USB payloads, we encode up to two SCO packets 67*f789a318SMatthias Ringwald uint8_t sco_packet[2*SCO_FRAME_SIZE]; 68a602f23dSMatthias Ringwald uint16_t read_pos; 69a602f23dSMatthias Ringwald uint16_t write_pos; 70a602f23dSMatthias Ringwald uint16_t samples_per_frame; 71a602f23dSMatthias Ringwald hfp_h2_framing_t h2_framing; 72a602f23dSMatthias Ringwald void (*encode)(struct hfp_codec * hfp_codec, int16_t * pcm_samples); 73a602f23dSMatthias Ringwald #ifdef ENABLE_HFP_WIDE_BAND_SPEECH 74a602f23dSMatthias Ringwald btstack_sbc_encoder_state_t msbc_state; 75a602f23dSMatthias Ringwald #endif 7616527ed5SMatthias Ringwald #ifdef ENABLE_HFP_SUPER_WIDE_BAND_SPEECH 7716527ed5SMatthias Ringwald const btstack_lc3_encoder_t * lc3_encoder; 7816527ed5SMatthias Ringwald btstack_lc3_encoder_google_t lc3_encoder_context; 7916527ed5SMatthias Ringwald #endif 80a602f23dSMatthias Ringwald }; 81a602f23dSMatthias Ringwald 82a602f23dSMatthias Ringwald /* API_START */ 83a602f23dSMatthias Ringwald 84a602f23dSMatthias Ringwald typedef struct hfp_codec hfp_codec_t; 85a602f23dSMatthias Ringwald 86a602f23dSMatthias Ringwald /** 87a602f23dSMatthias Ringwald * @brief Initialize HFP Audio Codec 88a602f23dSMatthias Ringwald * @note btstack_assert if codec_id is not supported 89a602f23dSMatthias Ringwald * @param hfp_codec 90a602f23dSMatthias Ringwald * @param codec_id see HFP_CODEC_xxx in hfp.h 91a602f23dSMatthias Ringwald * @return status 92a602f23dSMatthias Ringwald */ 93a602f23dSMatthias Ringwald void hfp_codec_init(hfp_codec_t * hfp_codec, uint8_t codec_id); 94a602f23dSMatthias Ringwald 95a602f23dSMatthias Ringwald /** 96a602f23dSMatthias Ringwald * @brief Get number of audio samples per HFP SCO frame 97a602f23dSMatthias Ringwald * @param hfp_codec 98a602f23dSMatthias Ringwald * @return num audio samples per 7.5ms SCO packet 99a602f23dSMatthias Ringwald */ 100a602f23dSMatthias Ringwald uint16_t hfp_codec_num_audio_samples_per_frame(const hfp_codec_t * hfp_codec); 101a602f23dSMatthias Ringwald 102a602f23dSMatthias Ringwald /** 103a602f23dSMatthias Ringwald * @brief Checks if next frame can be encoded 104a602f23dSMatthias Ringwald * @param hfp_codec 105a602f23dSMatthias Ringwald */ 106a602f23dSMatthias Ringwald bool hfp_codec_can_encode_audio_frame_now(const hfp_codec_t * hfp_codec); 107a602f23dSMatthias Ringwald 108a602f23dSMatthias Ringwald /** 109a602f23dSMatthias Ringwald * Get number of bytes ready for sending 110a602f23dSMatthias Ringwald * @param hfp_codec 111a602f23dSMatthias Ringwald * @return num bytes ready for current packet 112a602f23dSMatthias Ringwald */ 113a602f23dSMatthias Ringwald uint16_t hfp_codec_num_bytes_available(const hfp_codec_t * hfp_codec); 114a602f23dSMatthias Ringwald 115a602f23dSMatthias Ringwald /** 116a602f23dSMatthias Ringwald * Encode audio samples for HFP SCO packet 117a602f23dSMatthias Ringwald * @param hfp_codec 118a602f23dSMatthias Ringwald * @param pcm_samples - complete audio frame of hfp_msbc_num_audio_samples_per_frame int16 samples 119a602f23dSMatthias Ringwald */ 120a602f23dSMatthias Ringwald void hfp_codec_encode_audio_frame(hfp_codec_t * hfp_codec, int16_t * pcm_samples); 121a602f23dSMatthias Ringwald 122a602f23dSMatthias Ringwald /** 123a602f23dSMatthias Ringwald * Read from stream into SCO packet buffer 124a602f23dSMatthias Ringwald * @param hfp_codec 125a602f23dSMatthias Ringwald * @param buffer to store stream 126a602f23dSMatthias Ringwald * @param size num bytes to read from stream 127a602f23dSMatthias Ringwald */ 128a602f23dSMatthias Ringwald void hfp_codec_read_from_stream(hfp_codec_t * hfp_codec, uint8_t * buffer, uint16_t size); 129a602f23dSMatthias Ringwald 130a602f23dSMatthias Ringwald /** 131a602f23dSMatthias Ringwald * @param hfp_codec 132a602f23dSMatthias Ringwald */ 133a602f23dSMatthias Ringwald void hfp_codec_deinit(hfp_codec_t * hfp_codec); 134a602f23dSMatthias Ringwald 135a602f23dSMatthias Ringwald /* API_END */ 136a602f23dSMatthias Ringwald 137a602f23dSMatthias Ringwald #if defined __cplusplus 138a602f23dSMatthias Ringwald } 139a602f23dSMatthias Ringwald #endif 140a602f23dSMatthias Ringwald 141a602f23dSMatthias Ringwald #endif 142