1*113ff2bcSMatthias Ringwald /* 2*113ff2bcSMatthias Ringwald * Copyright (C) 2023 BlueKitchen GmbH 3*113ff2bcSMatthias Ringwald * 4*113ff2bcSMatthias Ringwald * Redistribution and use in source and binary forms, with or without 5*113ff2bcSMatthias Ringwald * modification, are permitted provided that the following conditions 6*113ff2bcSMatthias Ringwald * are met: 7*113ff2bcSMatthias Ringwald * 8*113ff2bcSMatthias Ringwald * 1. Redistributions of source code must retain the above copyright 9*113ff2bcSMatthias Ringwald * notice, this list of conditions and the following disclaimer. 10*113ff2bcSMatthias Ringwald * 2. Redistributions in binary form must reproduce the above copyright 11*113ff2bcSMatthias Ringwald * notice, this list of conditions and the following disclaimer in the 12*113ff2bcSMatthias Ringwald * documentation and/or other materials provided with the distribution. 13*113ff2bcSMatthias Ringwald * 3. Neither the name of the copyright holders nor the names of 14*113ff2bcSMatthias Ringwald * contributors may be used to endorse or promote products derived 15*113ff2bcSMatthias Ringwald * from this software without specific prior written permission. 16*113ff2bcSMatthias Ringwald * 4. Any redistribution, use, or modification is done solely for 17*113ff2bcSMatthias Ringwald * personal benefit and not for any commercial purpose or for 18*113ff2bcSMatthias Ringwald * monetary gain. 19*113ff2bcSMatthias Ringwald * 20*113ff2bcSMatthias Ringwald * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 21*113ff2bcSMatthias Ringwald * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22*113ff2bcSMatthias Ringwald * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23*113ff2bcSMatthias Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN 24*113ff2bcSMatthias Ringwald * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25*113ff2bcSMatthias Ringwald * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26*113ff2bcSMatthias Ringwald * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 27*113ff2bcSMatthias Ringwald * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28*113ff2bcSMatthias Ringwald * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29*113ff2bcSMatthias Ringwald * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 30*113ff2bcSMatthias Ringwald * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31*113ff2bcSMatthias Ringwald * SUCH DAMAGE. 32*113ff2bcSMatthias Ringwald * 33*113ff2bcSMatthias Ringwald * Please inquire about commercial licensing options at 34*113ff2bcSMatthias Ringwald * [email protected] 35*113ff2bcSMatthias Ringwald * 36*113ff2bcSMatthias Ringwald */ 37*113ff2bcSMatthias Ringwald 38*113ff2bcSMatthias Ringwald #define BTSTACK_FILE__ "btstack_sbc_bluedroid.c" 39*113ff2bcSMatthias Ringwald 40*113ff2bcSMatthias Ringwald #include "btstack_sbc_bluedroid.h" 41*113ff2bcSMatthias Ringwald 42*113ff2bcSMatthias Ringwald #include "btstack_bool.h" 43*113ff2bcSMatthias Ringwald #include "btstack_config.h" 44*113ff2bcSMatthias Ringwald #include "btstack_debug.h" 45*113ff2bcSMatthias Ringwald 46*113ff2bcSMatthias Ringwald #include <stdint.h> 47*113ff2bcSMatthias Ringwald #include "bluetooth.h" 48*113ff2bcSMatthias Ringwald 49*113ff2bcSMatthias Ringwald static uint8_t btstack_sbc_encoder_bluedroid_configure(void * context, btstack_sbc_mode_t mode, 50*113ff2bcSMatthias Ringwald uint8_t blocks, uint8_t subbands, btstack_sbc_allocation_method_t allocation_method, 51*113ff2bcSMatthias Ringwald uint16_t sample_rate, uint8_t bitpool, btstack_sbc_channel_mode_t channel_mode){ 52*113ff2bcSMatthias Ringwald 53*113ff2bcSMatthias Ringwald btstack_sbc_encoder_bluedroid_t * instance = (btstack_sbc_encoder_bluedroid_t *) context; 54*113ff2bcSMatthias Ringwald 55*113ff2bcSMatthias Ringwald instance->mode = mode; 56*113ff2bcSMatthias Ringwald 57*113ff2bcSMatthias Ringwald switch (instance->mode){ 58*113ff2bcSMatthias Ringwald case SBC_MODE_STANDARD: 59*113ff2bcSMatthias Ringwald instance->params.s16NumOfBlocks = blocks; 60*113ff2bcSMatthias Ringwald instance->params.s16NumOfSubBands = subbands; 61*113ff2bcSMatthias Ringwald instance->params.s16AllocationMethod = (uint8_t)allocation_method; 62*113ff2bcSMatthias Ringwald instance->params.s16BitPool = bitpool; 63*113ff2bcSMatthias Ringwald instance->params.mSBCEnabled = 0; 64*113ff2bcSMatthias Ringwald instance->params.s16ChannelMode = (uint8_t)channel_mode; 65*113ff2bcSMatthias Ringwald instance->params.s16NumOfChannels = 2; 66*113ff2bcSMatthias Ringwald if (instance->params.s16ChannelMode == SBC_MONO){ 67*113ff2bcSMatthias Ringwald instance->params.s16NumOfChannels = 1; 68*113ff2bcSMatthias Ringwald } 69*113ff2bcSMatthias Ringwald switch(sample_rate){ 70*113ff2bcSMatthias Ringwald case 16000: instance->params.s16SamplingFreq = SBC_sf16000; break; 71*113ff2bcSMatthias Ringwald case 32000: instance->params.s16SamplingFreq = SBC_sf32000; break; 72*113ff2bcSMatthias Ringwald case 44100: instance->params.s16SamplingFreq = SBC_sf44100; break; 73*113ff2bcSMatthias Ringwald case 48000: instance->params.s16SamplingFreq = SBC_sf48000; break; 74*113ff2bcSMatthias Ringwald default: instance->params.s16SamplingFreq = 0; break; 75*113ff2bcSMatthias Ringwald } 76*113ff2bcSMatthias Ringwald break; 77*113ff2bcSMatthias Ringwald case SBC_MODE_mSBC: 78*113ff2bcSMatthias Ringwald instance->params.s16NumOfBlocks = 15; 79*113ff2bcSMatthias Ringwald instance->params.s16NumOfSubBands = 8; 80*113ff2bcSMatthias Ringwald instance->params.s16AllocationMethod = SBC_LOUDNESS; 81*113ff2bcSMatthias Ringwald instance->params.s16BitPool = 26; 82*113ff2bcSMatthias Ringwald instance->params.s16ChannelMode = SBC_MONO; 83*113ff2bcSMatthias Ringwald instance->params.s16NumOfChannels = 1; 84*113ff2bcSMatthias Ringwald instance->params.mSBCEnabled = 1; 85*113ff2bcSMatthias Ringwald instance->params.s16SamplingFreq = SBC_sf16000; 86*113ff2bcSMatthias Ringwald break; 87*113ff2bcSMatthias Ringwald default: 88*113ff2bcSMatthias Ringwald return ERROR_CODE_INVALID_HCI_COMMAND_PARAMETERS; 89*113ff2bcSMatthias Ringwald } 90*113ff2bcSMatthias Ringwald 91*113ff2bcSMatthias Ringwald SBC_Encoder_Init(&instance->params); 92*113ff2bcSMatthias Ringwald 93*113ff2bcSMatthias Ringwald return ERROR_CODE_SUCCESS; 94*113ff2bcSMatthias Ringwald } 95*113ff2bcSMatthias Ringwald 96*113ff2bcSMatthias Ringwald /** 97*113ff2bcSMatthias Ringwald * @brief Return number of audio frames required for one SBC packet 98*113ff2bcSMatthias Ringwald * @param context 99*113ff2bcSMatthias Ringwald * @note each audio frame contains 2 sample values in stereo modes 100*113ff2bcSMatthias Ringwald */ 101*113ff2bcSMatthias Ringwald static uint16_t btstack_sbc_encoder_bluedroid_num_audio_frames(void * context){ 102*113ff2bcSMatthias Ringwald btstack_sbc_encoder_bluedroid_t * instance = (btstack_sbc_encoder_bluedroid_t *) context; 103*113ff2bcSMatthias Ringwald return instance->params.s16NumOfSubBands * instance->params.s16NumOfBlocks; 104*113ff2bcSMatthias Ringwald } 105*113ff2bcSMatthias Ringwald 106*113ff2bcSMatthias Ringwald static uint16_t btstack_sbc_encoder_bluedroid_sbc_buffer_length(void * context){ 107*113ff2bcSMatthias Ringwald btstack_sbc_encoder_bluedroid_t * instance = (btstack_sbc_encoder_bluedroid_t *) context; 108*113ff2bcSMatthias Ringwald return instance->params.u16PacketLength; 109*113ff2bcSMatthias Ringwald } 110*113ff2bcSMatthias Ringwald 111*113ff2bcSMatthias Ringwald /** 112*113ff2bcSMatthias Ringwald * @brief Encode PCM data 113*113ff2bcSMatthias Ringwald * @param context 114*113ff2bcSMatthias Ringwald * @param pcm_in with samples in host endianess 115*113ff2bcSMatthias Ringwald * @param sbc_out 116*113ff2bcSMatthias Ringwald * @return status 117*113ff2bcSMatthias Ringwald */ 118*113ff2bcSMatthias Ringwald static uint8_t btstack_sbc_encoder_bluedroid_encode_signed_16(void * context, const int16_t* pcm_in, uint8_t * sbc_out){ 119*113ff2bcSMatthias Ringwald btstack_sbc_encoder_bluedroid_t * instance = (btstack_sbc_encoder_bluedroid_t *) context; 120*113ff2bcSMatthias Ringwald 121*113ff2bcSMatthias Ringwald instance->params.ps16PcmBuffer = (int16_t *) pcm_in; 122*113ff2bcSMatthias Ringwald instance->params.pu8Packet = sbc_out; 123*113ff2bcSMatthias Ringwald if (instance->params.mSBCEnabled){ 124*113ff2bcSMatthias Ringwald instance->params.pu8Packet[0] = 0xad; 125*113ff2bcSMatthias Ringwald } 126*113ff2bcSMatthias Ringwald SBC_Encoder(&instance->params); 127*113ff2bcSMatthias Ringwald return ERROR_CODE_SUCCESS; 128*113ff2bcSMatthias Ringwald } 129*113ff2bcSMatthias Ringwald 130*113ff2bcSMatthias Ringwald static const btstack_sbc_encoder_t btstack_sbc_encoder_bluedroid = { 131*113ff2bcSMatthias Ringwald .configure = btstack_sbc_encoder_bluedroid_configure, 132*113ff2bcSMatthias Ringwald .sbc_buffer_length = btstack_sbc_encoder_bluedroid_sbc_buffer_length, 133*113ff2bcSMatthias Ringwald .num_audio_frames = btstack_sbc_encoder_bluedroid_num_audio_frames, 134*113ff2bcSMatthias Ringwald .encode_signed_16 = btstack_sbc_encoder_bluedroid_encode_signed_16 135*113ff2bcSMatthias Ringwald }; 136*113ff2bcSMatthias Ringwald 137*113ff2bcSMatthias Ringwald const btstack_sbc_encoder_t * btstack_sbc_encoder_bluedroid_init_instance(btstack_sbc_encoder_bluedroid_t * context){ 138*113ff2bcSMatthias Ringwald return &btstack_sbc_encoder_bluedroid; 139*113ff2bcSMatthias Ringwald } 140