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 90*1ca61671SMatthias Ringwald typedef struct { 91*1ca61671SMatthias Ringwald /** 92*1ca61671SMatthias Ringwald * Configure Encoder 93*1ca61671SMatthias Ringwald * @param encoder_context 94*1ca61671SMatthias Ringwald * @param mode 95*1ca61671SMatthias Ringwald * @param blocks 96*1ca61671SMatthias Ringwald * @param subbands 97*1ca61671SMatthias Ringwald * @param allocation_method 98*1ca61671SMatthias Ringwald * @param sample_rate 99*1ca61671SMatthias Ringwald * @param bitpool 100*1ca61671SMatthias Ringwald * @param channel_mode 101*1ca61671SMatthias Ringwald * @return status 102*1ca61671SMatthias Ringwald */ 103*1ca61671SMatthias Ringwald uint8_t (*configure)(void * encoder_context, btstack_sbc_mode_t mode, 104*1ca61671SMatthias Ringwald uint8_t blocks, uint8_t subbands, btstack_sbc_allocation_method_t allocation_method, 105*1ca61671SMatthias Ringwald uint16_t sample_rate, uint8_t bitpool, btstack_sbc_channel_mode_t channel_mode); 106*1ca61671SMatthias Ringwald 107*1ca61671SMatthias Ringwald /** 108*1ca61671SMatthias Ringwald * @brief Return number of audio frames required for one SBC packet 109*1ca61671SMatthias Ringwald * @param encoder_context 110*1ca61671SMatthias Ringwald * @note each audio frame contains 2 sample values in stereo modes 111*1ca61671SMatthias Ringwald */ 112*1ca61671SMatthias Ringwald uint16_t (*num_audio_frames)(void * encoder_context); 113*1ca61671SMatthias Ringwald 114*1ca61671SMatthias Ringwald /** 115*1ca61671SMatthias Ringwald * @brief Return SBC frame length 116*1ca61671SMatthias Ringwald * @param encoder_context 117*1ca61671SMatthias Ringwald */ 118*1ca61671SMatthias Ringwald uint16_t (*sbc_buffer_length)(void * encoder_context); 119*1ca61671SMatthias Ringwald 120*1ca61671SMatthias Ringwald /** 121*1ca61671SMatthias Ringwald * @brief Encode PCM data 122*1ca61671SMatthias Ringwald * @param encoder_context 123*1ca61671SMatthias Ringwald * @param pcm_in with samples in host endianess 124*1ca61671SMatthias Ringwald * @param sbc_out 125*1ca61671SMatthias Ringwald * @return status 126*1ca61671SMatthias Ringwald */ 127*1ca61671SMatthias Ringwald uint8_t (*encode_signed_16)(void * encoder_context, const int16_t* pcm_in, uint8_t * sbc_out); 128*1ca61671SMatthias Ringwald 129*1ca61671SMatthias Ringwald } btstack_sbc_encoder_t; 130*1ca61671SMatthias Ringwald 131*1ca61671SMatthias Ringwald typedef struct { 132*1ca61671SMatthias Ringwald /** 133*1ca61671SMatthias Ringwald * @brief Init SBC decoder 134*1ca61671SMatthias Ringwald * @param decoder_context 135*1ca61671SMatthias Ringwald * @param mode 136*1ca61671SMatthias Ringwald * @param callback_handler for decoded PCM data in host endianess 137*1ca61671SMatthias Ringwald * @param callback_context provided as context in call to callback_handler 138*1ca61671SMatthias Ringwald */ 139*1ca61671SMatthias Ringwald void (*configure)(void * decoder_context, 140*1ca61671SMatthias Ringwald btstack_sbc_mode_t mode, 141*1ca61671SMatthias Ringwald void (*callback_handler)(int16_t * data, int num_samples, int num_channels, 142*1ca61671SMatthias Ringwald int sample_rate, void * context), 143*1ca61671SMatthias Ringwald void * callback_context); 144*1ca61671SMatthias Ringwald 145*1ca61671SMatthias Ringwald /** 146*1ca61671SMatthias Ringwald * @brief Process received SBC data and deliver pcm via context_callback 147*1ca61671SMatthias Ringwald * @param decoder_context 148*1ca61671SMatthias Ringwald * @param packet_status_flag from SCO packet: 0 = OK, 1 = possibly invalid data, 2 = no data received, 3 = data partially lost 149*1ca61671SMatthias Ringwald * @param buffer 150*1ca61671SMatthias Ringwald * @param size 151*1ca61671SMatthias Ringwald */ 152*1ca61671SMatthias Ringwald void (*decode_signed_16)(void * decoder_context, uint8_t packet_status_flag, const uint8_t * buffer, uint16_t size); 153*1ca61671SMatthias Ringwald 154*1ca61671SMatthias Ringwald } btstack_sbc_decoder_t; 155*1ca61671SMatthias Ringwald 1560c87db9eSMilanka Ringwald /* API_START */ 1570c87db9eSMilanka Ringwald 1580c87db9eSMilanka Ringwald /* BTstack SBC decoder */ 1590c87db9eSMilanka Ringwald /** 1600c87db9eSMilanka Ringwald * @brief Init SBC decoder 1610c87db9eSMilanka Ringwald * @param state 1620c87db9eSMilanka Ringwald * @param mode 163972807b1SMatthias Ringwald * @param callback for decoded PCM data in host endianess 1640c87db9eSMilanka Ringwald * @param context provided in callback 1650c87db9eSMilanka Ringwald */ 1660c87db9eSMilanka Ringwald 1670c87db9eSMilanka 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); 1680c87db9eSMilanka Ringwald 1690c87db9eSMilanka Ringwald /** 1706276d22aSMilanka Ringwald * @brief Process received SBC data 1710c87db9eSMilanka Ringwald * @param state 1720c87db9eSMilanka Ringwald * @param packet_status_flag from SCO packet: 0 = OK, 1 = possibly invalid data, 2 = no data received, 3 = data partially lost 1730c87db9eSMilanka Ringwald * @param buffer 1740c87db9eSMilanka Ringwald * @param size 1750c87db9eSMilanka Ringwald */ 176515a576fSMatthias Ringwald void btstack_sbc_decoder_process_data(btstack_sbc_decoder_state_t * state, int packet_status_flag, const uint8_t * buffer, int size); 1770c87db9eSMilanka Ringwald 1780c87db9eSMilanka Ringwald /** 1790c87db9eSMilanka Ringwald * @brief Get number of samples per SBC frame 1800c87db9eSMilanka Ringwald */ 1810c87db9eSMilanka Ringwald int btstack_sbc_decoder_num_samples_per_frame(btstack_sbc_decoder_state_t * state); 1820c87db9eSMilanka Ringwald 1830c87db9eSMilanka Ringwald /* 1840c87db9eSMilanka Ringwald * @brief Get number of channels 1850c87db9eSMilanka Ringwald */ 1860c87db9eSMilanka Ringwald int btstack_sbc_decoder_num_channels(btstack_sbc_decoder_state_t * state); 1870c87db9eSMilanka Ringwald 1880c87db9eSMilanka Ringwald /* 1890c87db9eSMilanka Ringwald * @brief Get sample rate in hz 1900c87db9eSMilanka Ringwald */ 1910c87db9eSMilanka Ringwald int btstack_sbc_decoder_sample_rate(btstack_sbc_decoder_state_t * state); 1920c87db9eSMilanka Ringwald 1930c87db9eSMilanka Ringwald 1940c87db9eSMilanka Ringwald /* BTstack SBC Encoder */ 1950c87db9eSMilanka Ringwald /** 1960c87db9eSMilanka Ringwald * @brief Init SBC encoder 1970c87db9eSMilanka Ringwald * @param state 1980c87db9eSMilanka Ringwald * @param mode 1990c87db9eSMilanka Ringwald * @param blocks 2000c87db9eSMilanka Ringwald * @param subbands 2010c87db9eSMilanka Ringwald * @param allocation_method 2020c87db9eSMilanka Ringwald * @param sample_rate 2030c87db9eSMilanka Ringwald * @param bitpool 20445f49b58SMilanka Ringwald * @param channel_mode 2050c87db9eSMilanka Ringwald */ 2060c87db9eSMilanka Ringwald void btstack_sbc_encoder_init(btstack_sbc_encoder_state_t * state, btstack_sbc_mode_t mode, 20779b02f79SMilanka Ringwald int blocks, int subbands, btstack_sbc_allocation_method_t allocation_method, 20879b02f79SMilanka Ringwald int sample_rate, int bitpool, btstack_sbc_channel_mode_t channel_mode); 2090c87db9eSMilanka Ringwald 2100c87db9eSMilanka Ringwald /** 211972807b1SMatthias Ringwald * @brief Encode PCM data 212972807b1SMatthias Ringwald * @param buffer with samples in host endianess 2130c87db9eSMilanka Ringwald */ 2140c87db9eSMilanka Ringwald void btstack_sbc_encoder_process_data(int16_t * input_buffer); 2150c87db9eSMilanka Ringwald 2160c87db9eSMilanka Ringwald /** 2170c87db9eSMilanka Ringwald * @brief Return SBC frame 2180c87db9eSMilanka Ringwald */ 2190c87db9eSMilanka Ringwald uint8_t * btstack_sbc_encoder_sbc_buffer(void); 2200c87db9eSMilanka Ringwald 2210c87db9eSMilanka Ringwald /** 2220c87db9eSMilanka Ringwald * @brief Return SBC frame length 2230c87db9eSMilanka Ringwald */ 2240c87db9eSMilanka Ringwald uint16_t btstack_sbc_encoder_sbc_buffer_length(void); 2250c87db9eSMilanka Ringwald 2260c87db9eSMilanka Ringwald /** 227747ec646SMilanka Ringwald * @brief Return number of audio frames required for one SBC packet 228747ec646SMilanka Ringwald * @note each audio frame contains 2 sample values in stereo modes 2290c87db9eSMilanka Ringwald */ 230747ec646SMilanka Ringwald int btstack_sbc_encoder_num_audio_frames(void); 2310c87db9eSMilanka Ringwald 2320c87db9eSMilanka Ringwald /* API_END */ 2330c87db9eSMilanka Ringwald 2340c87db9eSMilanka Ringwald // testing only 2359137e118SMatthias Ringwald void btstack_sbc_decoder_test_set_plc_enabled(int plc_enabled); 2360c87db9eSMilanka Ringwald void btstack_sbc_decoder_test_simulate_corrupt_frames(int period); 2370c87db9eSMilanka Ringwald 2384f0d422dSMilanka Ringwald #if defined __cplusplus 2394f0d422dSMilanka Ringwald } 2404f0d422dSMilanka Ringwald #endif 2414f0d422dSMilanka Ringwald 24280e33422SMatthias Ringwald #endif // BTSTACK_SBC_H 243