xref: /btstack/src/classic/btstack_sbc_bluedroid.c (revision 113ff2bc0af39c4454c5c239318755ec65070fce)
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