14f0d422dSMilanka Ringwald /* 24f0d422dSMilanka Ringwald * Copyright (C) 2014 BlueKitchen GmbH 34f0d422dSMilanka Ringwald * 44f0d422dSMilanka Ringwald * Redistribution and use in source and binary forms, with or without 54f0d422dSMilanka Ringwald * modification, are permitted provided that the following conditions 64f0d422dSMilanka Ringwald * are met: 74f0d422dSMilanka Ringwald * 84f0d422dSMilanka Ringwald * 1. Redistributions of source code must retain the above copyright 94f0d422dSMilanka Ringwald * notice, this list of conditions and the following disclaimer. 104f0d422dSMilanka Ringwald * 2. Redistributions in binary form must reproduce the above copyright 114f0d422dSMilanka Ringwald * notice, this list of conditions and the following disclaimer in the 124f0d422dSMilanka Ringwald * documentation and/or other materials provided with the distribution. 134f0d422dSMilanka Ringwald * 3. Neither the name of the copyright holders nor the names of 144f0d422dSMilanka Ringwald * contributors may be used to endorse or promote products derived 154f0d422dSMilanka Ringwald * from this software without specific prior written permission. 164f0d422dSMilanka Ringwald * 4. Any redistribution, use, or modification is done solely for 174f0d422dSMilanka Ringwald * personal benefit and not for any commercial purpose or for 184f0d422dSMilanka Ringwald * monetary gain. 194f0d422dSMilanka Ringwald * 204f0d422dSMilanka Ringwald * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 214f0d422dSMilanka Ringwald * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 224f0d422dSMilanka Ringwald * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 232fca4dadSMilanka Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN 242fca4dadSMilanka Ringwald * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 254f0d422dSMilanka Ringwald * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 264f0d422dSMilanka Ringwald * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 274f0d422dSMilanka Ringwald * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 284f0d422dSMilanka Ringwald * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 294f0d422dSMilanka Ringwald * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 304f0d422dSMilanka Ringwald * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 314f0d422dSMilanka Ringwald * SUCH DAMAGE. 324f0d422dSMilanka Ringwald * 334f0d422dSMilanka Ringwald * Please inquire about commercial licensing options at 344f0d422dSMilanka Ringwald * [email protected] 354f0d422dSMilanka Ringwald * 364f0d422dSMilanka Ringwald */ 374f0d422dSMilanka Ringwald 38fe5a6c4eSMilanka Ringwald /** 39fe5a6c4eSMilanka Ringwald * SBC 404f0d422dSMilanka Ringwald * 414f0d422dSMilanka Ringwald */ 424f0d422dSMilanka Ringwald 4380e33422SMatthias Ringwald #ifndef BTSTACK_SBC_H 4480e33422SMatthias Ringwald #define BTSTACK_SBC_H 454f0d422dSMilanka Ringwald 464f0d422dSMilanka Ringwald #include <stdint.h> 470c87db9eSMilanka Ringwald #include "btstack_sbc_plc.h" 484f0d422dSMilanka Ringwald 494a1feeddSMatthias Ringwald #if defined __cplusplus 504a1feeddSMatthias Ringwald extern "C" { 514a1feeddSMatthias Ringwald #endif 524a1feeddSMatthias Ringwald 534f0d422dSMilanka Ringwald typedef enum { 5479b02f79SMilanka Ringwald SBC_MODE_STANDARD = 0, 554f0d422dSMilanka Ringwald SBC_MODE_mSBC 56e7a41128SMilanka Ringwald } btstack_sbc_mode_t; 574f0d422dSMilanka Ringwald 5879b02f79SMilanka Ringwald typedef enum { 5979b02f79SMilanka Ringwald SBC_CHANNEL_MODE_MONO = 0, 6079b02f79SMilanka Ringwald SBC_CHANNEL_MODE_DUAL_CHANNEL, 6179b02f79SMilanka Ringwald SBC_CHANNEL_MODE_STEREO, 6279b02f79SMilanka Ringwald SBC_CHANNEL_MODE_JOINT_STEREO 6379b02f79SMilanka Ringwald } btstack_sbc_channel_mode_t; 6479b02f79SMilanka Ringwald 6579b02f79SMilanka Ringwald typedef enum { 6679b02f79SMilanka Ringwald SBC_ALLOCATION_METHOD_LOUDNESS = 0, 6779b02f79SMilanka Ringwald SBC_ALLOCATION_METHOD_SNR 6879b02f79SMilanka Ringwald } btstack_sbc_allocation_method_t; 6979b02f79SMilanka Ringwald 700c87db9eSMilanka Ringwald typedef struct { 710c87db9eSMilanka Ringwald void * context; 720c87db9eSMilanka Ringwald void (*handle_pcm_data)(int16_t * data, int num_samples, int num_channels, int sample_rate, void * context); 730c87db9eSMilanka Ringwald // private 740c87db9eSMilanka Ringwald void * decoder_state; 750c87db9eSMilanka Ringwald btstack_sbc_plc_state_t plc_state; 760c87db9eSMilanka Ringwald btstack_sbc_mode_t mode; 770c87db9eSMilanka Ringwald 780c87db9eSMilanka Ringwald // summary of processed good, bad and zero frames 790c87db9eSMilanka Ringwald int good_frames_nr; 800c87db9eSMilanka Ringwald int bad_frames_nr; 810c87db9eSMilanka Ringwald int zero_frames_nr; 820c87db9eSMilanka Ringwald } btstack_sbc_decoder_state_t; 830c87db9eSMilanka Ringwald 840c87db9eSMilanka Ringwald typedef struct { 850c87db9eSMilanka Ringwald // private 860c87db9eSMilanka Ringwald void * encoder_state; 870c87db9eSMilanka Ringwald btstack_sbc_mode_t mode; 880c87db9eSMilanka Ringwald } btstack_sbc_encoder_state_t; 890c87db9eSMilanka Ringwald 901ca61671SMatthias Ringwald typedef struct { 911ca61671SMatthias Ringwald /** 921ca61671SMatthias Ringwald * Configure Encoder 931ca61671SMatthias Ringwald * @param encoder_context 941ca61671SMatthias Ringwald * @param mode 951ca61671SMatthias Ringwald * @param blocks 961ca61671SMatthias Ringwald * @param subbands 971ca61671SMatthias Ringwald * @param allocation_method 981ca61671SMatthias Ringwald * @param sample_rate 991ca61671SMatthias Ringwald * @param bitpool 1001ca61671SMatthias Ringwald * @param channel_mode 1011ca61671SMatthias Ringwald * @return status 1021ca61671SMatthias Ringwald */ 1031ca61671SMatthias Ringwald uint8_t (*configure)(void * encoder_context, btstack_sbc_mode_t mode, 1041ca61671SMatthias Ringwald uint8_t blocks, uint8_t subbands, btstack_sbc_allocation_method_t allocation_method, 1051ca61671SMatthias Ringwald uint16_t sample_rate, uint8_t bitpool, btstack_sbc_channel_mode_t channel_mode); 1061ca61671SMatthias Ringwald 1071ca61671SMatthias Ringwald /** 1081ca61671SMatthias Ringwald * @brief Return number of audio frames required for one SBC packet 1091ca61671SMatthias Ringwald * @param encoder_context 1101ca61671SMatthias Ringwald * @note each audio frame contains 2 sample values in stereo modes 1111ca61671SMatthias Ringwald */ 1121ca61671SMatthias Ringwald uint16_t (*num_audio_frames)(void * encoder_context); 1131ca61671SMatthias Ringwald 1141ca61671SMatthias Ringwald /** 1151ca61671SMatthias Ringwald * @brief Return SBC frame length 1161ca61671SMatthias Ringwald * @param encoder_context 1171ca61671SMatthias Ringwald */ 1181ca61671SMatthias Ringwald uint16_t (*sbc_buffer_length)(void * encoder_context); 1191ca61671SMatthias Ringwald 1201ca61671SMatthias Ringwald /** 1211ca61671SMatthias Ringwald * @brief Encode PCM data 1221ca61671SMatthias Ringwald * @param encoder_context 1231ca61671SMatthias Ringwald * @param pcm_in with samples in host endianess 1241ca61671SMatthias Ringwald * @param sbc_out 1251ca61671SMatthias Ringwald * @return status 1261ca61671SMatthias Ringwald */ 1271ca61671SMatthias Ringwald uint8_t (*encode_signed_16)(void * encoder_context, const int16_t* pcm_in, uint8_t * sbc_out); 1281ca61671SMatthias Ringwald 1291ca61671SMatthias Ringwald } btstack_sbc_encoder_t; 1301ca61671SMatthias Ringwald 1311ca61671SMatthias Ringwald typedef struct { 1321ca61671SMatthias Ringwald /** 1331ca61671SMatthias Ringwald * @brief Init SBC decoder 1341ca61671SMatthias Ringwald * @param decoder_context 1351ca61671SMatthias Ringwald * @param mode 1361ca61671SMatthias Ringwald * @param callback_handler for decoded PCM data in host endianess 1371ca61671SMatthias Ringwald * @param callback_context provided as context in call to callback_handler 1381ca61671SMatthias Ringwald */ 1391ca61671SMatthias Ringwald void (*configure)(void * decoder_context, 1401ca61671SMatthias Ringwald btstack_sbc_mode_t mode, 1411ca61671SMatthias Ringwald void (*callback_handler)(int16_t * data, int num_samples, int num_channels, 1421ca61671SMatthias Ringwald int sample_rate, void * context), 1431ca61671SMatthias Ringwald void * callback_context); 1441ca61671SMatthias Ringwald 1451ca61671SMatthias Ringwald /** 1461ca61671SMatthias Ringwald * @brief Process received SBC data and deliver pcm via context_callback 1471ca61671SMatthias Ringwald * @param decoder_context 1481ca61671SMatthias Ringwald * @param packet_status_flag from SCO packet: 0 = OK, 1 = possibly invalid data, 2 = no data received, 3 = data partially lost 1491ca61671SMatthias Ringwald * @param buffer 1501ca61671SMatthias Ringwald * @param size 1511ca61671SMatthias Ringwald */ 1521ca61671SMatthias Ringwald void (*decode_signed_16)(void * decoder_context, uint8_t packet_status_flag, const uint8_t * buffer, uint16_t size); 1531ca61671SMatthias Ringwald 1541ca61671SMatthias Ringwald } btstack_sbc_decoder_t; 1551ca61671SMatthias Ringwald 1560c87db9eSMilanka Ringwald /* API_START */ 1570c87db9eSMilanka Ringwald 1580c87db9eSMilanka Ringwald /* BTstack SBC decoder */ 159*a267701aSMatthias Ringwald 1600c87db9eSMilanka Ringwald /** 1610c87db9eSMilanka Ringwald * @brief Init SBC decoder 162*a267701aSMatthias Ringwald * @deprecated Please use btstack_sbc_decoder_bluedroid_init_instance() from btstack_sbc_bluedroid.h and call btstack_sbc_decoder->configure() instead 1630c87db9eSMilanka Ringwald * @param state 1640c87db9eSMilanka Ringwald * @param mode 165972807b1SMatthias Ringwald * @param callback for decoded PCM data in host endianess 1660c87db9eSMilanka Ringwald * @param context provided in callback 1670c87db9eSMilanka Ringwald */ 1680c87db9eSMilanka Ringwald 1690c87db9eSMilanka Ringwald void btstack_sbc_decoder_init(btstack_sbc_decoder_state_t * state, btstack_sbc_mode_t mode, void (*callback)(int16_t * data, int num_samples, int num_channels, int sample_rate, void * context), void * context); 1700c87db9eSMilanka Ringwald 1710c87db9eSMilanka Ringwald /** 1726276d22aSMilanka Ringwald * @brief Process received SBC data 173*a267701aSMatthias Ringwald * @deprecated Please use btstack_sbc_decoder->decode_signed_16() instead 1740c87db9eSMilanka Ringwald * @param state 1750c87db9eSMilanka Ringwald * @param packet_status_flag from SCO packet: 0 = OK, 1 = possibly invalid data, 2 = no data received, 3 = data partially lost 1760c87db9eSMilanka Ringwald * @param buffer 1770c87db9eSMilanka Ringwald * @param size 1780c87db9eSMilanka Ringwald */ 179515a576fSMatthias Ringwald void btstack_sbc_decoder_process_data(btstack_sbc_decoder_state_t * state, int packet_status_flag, const uint8_t * buffer, int size); 1800c87db9eSMilanka Ringwald 1810c87db9eSMilanka Ringwald /** 1820c87db9eSMilanka Ringwald * @brief Get number of samples per SBC frame 183*a267701aSMatthias Ringwald * @deprecated Please use btstack_sbc_decoder->num_samples_per_frame() instead 1840c87db9eSMilanka Ringwald */ 1850c87db9eSMilanka Ringwald int btstack_sbc_decoder_num_samples_per_frame(btstack_sbc_decoder_state_t * state); 1860c87db9eSMilanka Ringwald 187*a267701aSMatthias Ringwald /** 1880c87db9eSMilanka Ringwald * @brief Get number of channels 189*a267701aSMatthias Ringwald * @deprecated Please use btstack_sbc_decoder->num_channels() instead 1900c87db9eSMilanka Ringwald */ 1910c87db9eSMilanka Ringwald int btstack_sbc_decoder_num_channels(btstack_sbc_decoder_state_t * state); 1920c87db9eSMilanka Ringwald 193*a267701aSMatthias Ringwald /** 1940c87db9eSMilanka Ringwald * @brief Get sample rate in hz 195*a267701aSMatthias Ringwald * @deprecated Please use btstack_sbc_decoder->sample_rate() instead 1960c87db9eSMilanka Ringwald */ 1970c87db9eSMilanka Ringwald int btstack_sbc_decoder_sample_rate(btstack_sbc_decoder_state_t * state); 1980c87db9eSMilanka Ringwald 1990c87db9eSMilanka Ringwald 2000c87db9eSMilanka Ringwald /* BTstack SBC Encoder */ 2010c87db9eSMilanka Ringwald /** 2020c87db9eSMilanka Ringwald * @brief Init SBC encoder 203*a267701aSMatthias Ringwald * @deprecated Please use btstack_sbc_encoder_bluedroid_init_instance() from btstack_sbc_bluedroid.h and call btstack_sbc_encoder->configure() instead 2040c87db9eSMilanka Ringwald * @param state 2050c87db9eSMilanka Ringwald * @param mode 2060c87db9eSMilanka Ringwald * @param blocks 2070c87db9eSMilanka Ringwald * @param subbands 2080c87db9eSMilanka Ringwald * @param allocation_method 2090c87db9eSMilanka Ringwald * @param sample_rate 2100c87db9eSMilanka Ringwald * @param bitpool 21145f49b58SMilanka Ringwald * @param channel_mode 2120c87db9eSMilanka Ringwald */ 2130c87db9eSMilanka Ringwald void btstack_sbc_encoder_init(btstack_sbc_encoder_state_t * state, btstack_sbc_mode_t mode, 21479b02f79SMilanka Ringwald int blocks, int subbands, btstack_sbc_allocation_method_t allocation_method, 21579b02f79SMilanka Ringwald int sample_rate, int bitpool, btstack_sbc_channel_mode_t channel_mode); 2160c87db9eSMilanka Ringwald 2170c87db9eSMilanka Ringwald /** 218972807b1SMatthias Ringwald * @brief Encode PCM data 219*a267701aSMatthias Ringwald * @deprecated Please use btstack_sbc_encoder->encode_signed_16() instead 220972807b1SMatthias Ringwald * @param buffer with samples in host endianess 2210c87db9eSMilanka Ringwald */ 2220c87db9eSMilanka Ringwald void btstack_sbc_encoder_process_data(int16_t * input_buffer); 2230c87db9eSMilanka Ringwald 2240c87db9eSMilanka Ringwald /** 2250c87db9eSMilanka Ringwald * @brief Return SBC frame 226*a267701aSMatthias Ringwald * @deprecated not needed when using the codeec instance interface 2270c87db9eSMilanka Ringwald */ 2280c87db9eSMilanka Ringwald uint8_t * btstack_sbc_encoder_sbc_buffer(void); 2290c87db9eSMilanka Ringwald 2300c87db9eSMilanka Ringwald /** 2310c87db9eSMilanka Ringwald * @brief Return SBC frame length 232*a267701aSMatthias Ringwald * @deprecated Please use btstack_sbc_encoder->encode_signed_16() instead 2330c87db9eSMilanka Ringwald */ 2340c87db9eSMilanka Ringwald uint16_t btstack_sbc_encoder_sbc_buffer_length(void); 2350c87db9eSMilanka Ringwald 2360c87db9eSMilanka Ringwald /** 237747ec646SMilanka Ringwald * @brief Return number of audio frames required for one SBC packet 238*a267701aSMatthias Ringwald * @deprecated Please use btstack_sbc_encoder->encode_signed_16() instead 239747ec646SMilanka Ringwald * @note each audio frame contains 2 sample values in stereo modes 2400c87db9eSMilanka Ringwald */ 241747ec646SMilanka Ringwald int btstack_sbc_encoder_num_audio_frames(void); 2420c87db9eSMilanka Ringwald 2430c87db9eSMilanka Ringwald /* API_END */ 2440c87db9eSMilanka Ringwald 2450c87db9eSMilanka Ringwald // testing only 2469137e118SMatthias Ringwald void btstack_sbc_decoder_test_set_plc_enabled(int plc_enabled); 2470c87db9eSMilanka Ringwald void btstack_sbc_decoder_test_simulate_corrupt_frames(int period); 2480c87db9eSMilanka Ringwald 2494f0d422dSMilanka Ringwald #if defined __cplusplus 2504f0d422dSMilanka Ringwald } 2514f0d422dSMilanka Ringwald #endif 2524f0d422dSMilanka Ringwald 25380e33422SMatthias Ringwald #endif // BTSTACK_SBC_H 254