15b4ff0f7SMilanka Ringwald /*
25b4ff0f7SMilanka Ringwald * Copyright (C) 2014 BlueKitchen GmbH
35b4ff0f7SMilanka Ringwald *
45b4ff0f7SMilanka Ringwald * Redistribution and use in source and binary forms, with or without
55b4ff0f7SMilanka Ringwald * modification, are permitted provided that the following conditions
65b4ff0f7SMilanka Ringwald * are met:
75b4ff0f7SMilanka Ringwald *
85b4ff0f7SMilanka Ringwald * 1. Redistributions of source code must retain the above copyright
95b4ff0f7SMilanka Ringwald * notice, this list of conditions and the following disclaimer.
105b4ff0f7SMilanka Ringwald * 2. Redistributions in binary form must reproduce the above copyright
115b4ff0f7SMilanka Ringwald * notice, this list of conditions and the following disclaimer in the
125b4ff0f7SMilanka Ringwald * documentation and/or other materials provided with the distribution.
135b4ff0f7SMilanka Ringwald * 3. Neither the name of the copyright holders nor the names of
145b4ff0f7SMilanka Ringwald * contributors may be used to endorse or promote products derived
155b4ff0f7SMilanka Ringwald * from this software without specific prior written permission.
165b4ff0f7SMilanka Ringwald * 4. Any redistribution, use, or modification is done solely for
175b4ff0f7SMilanka Ringwald * personal benefit and not for any commercial purpose or for
185b4ff0f7SMilanka Ringwald * monetary gain.
195b4ff0f7SMilanka Ringwald *
205b4ff0f7SMilanka Ringwald * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
215b4ff0f7SMilanka Ringwald * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
225b4ff0f7SMilanka Ringwald * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23*2fca4dadSMilanka Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN
24*2fca4dadSMilanka Ringwald * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
255b4ff0f7SMilanka Ringwald * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
265b4ff0f7SMilanka Ringwald * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
275b4ff0f7SMilanka Ringwald * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
285b4ff0f7SMilanka Ringwald * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
295b4ff0f7SMilanka Ringwald * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
305b4ff0f7SMilanka Ringwald * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
315b4ff0f7SMilanka Ringwald * SUCH DAMAGE.
325b4ff0f7SMilanka Ringwald *
335b4ff0f7SMilanka Ringwald * Please inquire about commercial licensing options at
345b4ff0f7SMilanka Ringwald * [email protected]
355b4ff0f7SMilanka Ringwald *
365b4ff0f7SMilanka Ringwald */
37ab2c6ae4SMatthias Ringwald
38e501bae0SMatthias Ringwald #define BTSTACK_FILE__ "hfp_msbc.c"
395b4ff0f7SMilanka Ringwald
405b4ff0f7SMilanka Ringwald // *****************************************************************************
415b4ff0f7SMilanka Ringwald //
425b4ff0f7SMilanka Ringwald // HFP mSBC encoder wrapper
435b4ff0f7SMilanka Ringwald //
445b4ff0f7SMilanka Ringwald // *****************************************************************************
455b4ff0f7SMilanka Ringwald
465b4ff0f7SMilanka Ringwald #include "btstack_config.h"
475b4ff0f7SMilanka Ringwald
485b4ff0f7SMilanka Ringwald #include <string.h>
495b4ff0f7SMilanka Ringwald
505b4ff0f7SMilanka Ringwald #include "btstack_debug.h"
510c87db9eSMilanka Ringwald #include "btstack_sbc.h"
525b4ff0f7SMilanka Ringwald #include "hfp_msbc.h"
535b4ff0f7SMilanka Ringwald
545b4ff0f7SMilanka Ringwald #define MSBC_FRAME_SIZE 57
55469fc11aSMatthias Ringwald #define MSBC_HEADER_H2_SIZE 2
56469fc11aSMatthias Ringwald #define MSBC_PADDING_SIZE 1
57469fc11aSMatthias Ringwald #define MSBC_EXTRA_SIZE (MSBC_HEADER_H2_SIZE + MSBC_PADDING_SIZE)
58469fc11aSMatthias Ringwald
5920b2edb6SMatthias Ringwald // const
60aeb0f0feSMatthias Ringwald static const uint8_t hfp_msbc_header_h2_byte_0 = 1;
61aeb0f0feSMatthias Ringwald static const uint8_t hfp_msbc_header_h2_byte_1_table[] = {0x08, 0x38, 0xc8, 0xf8 };
625b4ff0f7SMilanka Ringwald
63aeb0f0feSMatthias Ringwald static btstack_sbc_encoder_state_t hfp_msbc_state;
64aeb0f0feSMatthias Ringwald static int hfp_msbc_msbc_sequence_number;
655b4ff0f7SMilanka Ringwald
66aeb0f0feSMatthias Ringwald static uint8_t hfp_msbc_buffer[2 * (MSBC_FRAME_SIZE + MSBC_EXTRA_SIZE)];
67aeb0f0feSMatthias Ringwald static int hfp_msbc_buffer_offset = 0;
685b4ff0f7SMilanka Ringwald
hfp_msbc_init(void)695b4ff0f7SMilanka Ringwald void hfp_msbc_init(void){
70aeb0f0feSMatthias Ringwald btstack_sbc_encoder_init(&hfp_msbc_state, SBC_MODE_mSBC, 16, 8, SBC_ALLOCATION_METHOD_LOUDNESS, 16000, 26, SBC_CHANNEL_MODE_MONO);
71aeb0f0feSMatthias Ringwald hfp_msbc_buffer_offset = 0;
72aeb0f0feSMatthias Ringwald hfp_msbc_msbc_sequence_number = 0;
735b4ff0f7SMilanka Ringwald }
745b4ff0f7SMilanka Ringwald
hfp_msbc_deinit(void)7520b2edb6SMatthias Ringwald void hfp_msbc_deinit(void){
76aeb0f0feSMatthias Ringwald (void) memset(&hfp_msbc_state, 0, sizeof(btstack_sbc_encoder_state_t));
77aeb0f0feSMatthias Ringwald hfp_msbc_msbc_sequence_number = 0;
78aeb0f0feSMatthias Ringwald hfp_msbc_buffer_offset = 0;
7920b2edb6SMatthias Ringwald }
8020b2edb6SMatthias Ringwald
hfp_msbc_can_encode_audio_frame_now(void)815b4ff0f7SMilanka Ringwald int hfp_msbc_can_encode_audio_frame_now(void){
82aeb0f0feSMatthias Ringwald return (sizeof(hfp_msbc_buffer) - hfp_msbc_buffer_offset) >= (MSBC_FRAME_SIZE + MSBC_EXTRA_SIZE);
835b4ff0f7SMilanka Ringwald }
845b4ff0f7SMilanka Ringwald
hfp_msbc_encode_audio_frame(int16_t * pcm_samples)855b4ff0f7SMilanka Ringwald void hfp_msbc_encode_audio_frame(int16_t * pcm_samples){
865b4ff0f7SMilanka Ringwald if (!hfp_msbc_can_encode_audio_frame_now()) return;
875b4ff0f7SMilanka Ringwald
88469fc11aSMatthias Ringwald // Synchronization Header H2
89aeb0f0feSMatthias Ringwald hfp_msbc_buffer[hfp_msbc_buffer_offset++] = hfp_msbc_header_h2_byte_0;
90aeb0f0feSMatthias Ringwald hfp_msbc_buffer[hfp_msbc_buffer_offset++] = hfp_msbc_header_h2_byte_1_table[hfp_msbc_msbc_sequence_number];
91aeb0f0feSMatthias Ringwald hfp_msbc_msbc_sequence_number = (hfp_msbc_msbc_sequence_number + 1) & 3;
92469fc11aSMatthias Ringwald
93469fc11aSMatthias Ringwald // SBC Frame
945b4ff0f7SMilanka Ringwald btstack_sbc_encoder_process_data(pcm_samples);
95aeb0f0feSMatthias Ringwald (void)memcpy(hfp_msbc_buffer + hfp_msbc_buffer_offset,
966535961aSMatthias Ringwald btstack_sbc_encoder_sbc_buffer(), MSBC_FRAME_SIZE);
97aeb0f0feSMatthias Ringwald hfp_msbc_buffer_offset += MSBC_FRAME_SIZE;
98469fc11aSMatthias Ringwald
99469fc11aSMatthias Ringwald // Final padding to use 60 bytes for 120 audio samples
100aeb0f0feSMatthias Ringwald hfp_msbc_buffer[hfp_msbc_buffer_offset++] = 0;
1015b4ff0f7SMilanka Ringwald }
1025b4ff0f7SMilanka Ringwald
hfp_msbc_read_from_stream(uint8_t * buf,int size)1035b4ff0f7SMilanka Ringwald void hfp_msbc_read_from_stream(uint8_t * buf, int size){
1045b4ff0f7SMilanka Ringwald int bytes_to_copy = size;
105aeb0f0feSMatthias Ringwald if (size > hfp_msbc_buffer_offset){
106aeb0f0feSMatthias Ringwald bytes_to_copy = hfp_msbc_buffer_offset;
1075b4ff0f7SMilanka Ringwald log_error("sbc frame storage is smaller then the output buffer");
1085b4ff0f7SMilanka Ringwald return;
1095b4ff0f7SMilanka Ringwald }
1105b4ff0f7SMilanka Ringwald
111aeb0f0feSMatthias Ringwald (void)memcpy(buf, hfp_msbc_buffer, bytes_to_copy);
112aeb0f0feSMatthias Ringwald memmove(hfp_msbc_buffer, hfp_msbc_buffer + bytes_to_copy, sizeof(hfp_msbc_buffer) - bytes_to_copy);
113aeb0f0feSMatthias Ringwald hfp_msbc_buffer_offset -= bytes_to_copy;
1145b4ff0f7SMilanka Ringwald }
1155b4ff0f7SMilanka Ringwald
hfp_msbc_num_bytes_in_stream(void)1165b4ff0f7SMilanka Ringwald int hfp_msbc_num_bytes_in_stream(void){
117aeb0f0feSMatthias Ringwald return hfp_msbc_buffer_offset;
1185b4ff0f7SMilanka Ringwald }
1195b4ff0f7SMilanka Ringwald
hfp_msbc_num_audio_samples_per_frame(void)1205b4ff0f7SMilanka Ringwald int hfp_msbc_num_audio_samples_per_frame(void){
121747ec646SMilanka Ringwald return btstack_sbc_encoder_num_audio_frames();
1225b4ff0f7SMilanka Ringwald }
1235b4ff0f7SMilanka Ringwald
1245b4ff0f7SMilanka Ringwald
125