1ef026fa8SDirk Helbig /* 2ef026fa8SDirk Helbig * Copyright (C) 2023 BlueKitchen GmbH 3ef026fa8SDirk Helbig * 4ef026fa8SDirk Helbig * Redistribution and use in source and binary forms, with or without 5ef026fa8SDirk Helbig * modification, are permitted provided that the following conditions 6ef026fa8SDirk Helbig * are met: 7ef026fa8SDirk Helbig * 8ef026fa8SDirk Helbig * 1. Redistributions of source code must retain the above copyright 9ef026fa8SDirk Helbig * notice, this list of conditions and the following disclaimer. 10ef026fa8SDirk Helbig * 2. Redistributions in binary form must reproduce the above copyright 11ef026fa8SDirk Helbig * notice, this list of conditions and the following disclaimer in the 12ef026fa8SDirk Helbig * documentation and/or other materials provided with the distribution. 13ef026fa8SDirk Helbig * 3. Neither the name of the copyright holders nor the names of 14ef026fa8SDirk Helbig * contributors may be used to endorse or promote products derived 15ef026fa8SDirk Helbig * from this software without specific prior written permission. 16ef026fa8SDirk Helbig * 4. Any redistribution, use, or modification is done solely for 17ef026fa8SDirk Helbig * personal benefit and not for any commercial purpose or for 18ef026fa8SDirk Helbig * monetary gain. 19ef026fa8SDirk Helbig * 20ef026fa8SDirk Helbig * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 21ef026fa8SDirk Helbig * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22ef026fa8SDirk Helbig * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23ef026fa8SDirk Helbig * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN 24ef026fa8SDirk Helbig * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25ef026fa8SDirk Helbig * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26ef026fa8SDirk Helbig * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 27ef026fa8SDirk Helbig * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28ef026fa8SDirk Helbig * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29ef026fa8SDirk Helbig * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 30ef026fa8SDirk Helbig * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31ef026fa8SDirk Helbig * SUCH DAMAGE. 32ef026fa8SDirk Helbig * 33ef026fa8SDirk Helbig * Please inquire about commercial licensing options at 34ef026fa8SDirk Helbig * [email protected] 35ef026fa8SDirk Helbig * 36ef026fa8SDirk Helbig */ 37ef026fa8SDirk Helbig 38*0d212321SDirk Helbig /** 39*0d212321SDirk Helbig * @title Sample rate compensation 40*0d212321SDirk Helbig * 41*0d212321SDirk Helbig * Prevents buffer over/under-run at the audio receiver by compensating for varying/different playback/receiving sample rates. 42*0d212321SDirk Helbig * 43*0d212321SDirk Helbig * Intended to measure the L2CAP packet sample rate and with the provided playback sample rate calculates a compensation ratio 44*0d212321SDirk Helbig * which compensates for drift between playback and reception. 45*0d212321SDirk Helbig * 46*0d212321SDirk Helbig * Requires the audio interface to provide the current playback sample rate. 47*0d212321SDirk Helbig * 48*0d212321SDirk Helbig */ 49ef026fa8SDirk Helbig 50ef026fa8SDirk Helbig #ifndef BTSTACK_SAMPLE_RATE_COMPENSATION_H_ 51ef026fa8SDirk Helbig #define BTSTACK_SAMPLE_RATE_COMPENSATION_H_ 52ef026fa8SDirk Helbig 53ef026fa8SDirk Helbig #include <stdint.h> 54ef026fa8SDirk Helbig 55ef026fa8SDirk Helbig #if defined __cplusplus 56ef026fa8SDirk Helbig extern "C" { 57ef026fa8SDirk Helbig #endif 58ef026fa8SDirk Helbig 59*0d212321SDirk Helbig /* API_START */ 60*0d212321SDirk Helbig 61ef026fa8SDirk Helbig #define FLOAT_TO_Q15(a) ((signed)((a)*(UINT16_C(1)<<15)+0.5f)) 62ef026fa8SDirk Helbig #define FLOAT_TO_Q8(a) ((signed)((a)*(UINT16_C(1)<<8)+0.5f)) 63ef026fa8SDirk Helbig #define FLOAT_TO_Q7(a) ((signed)((a)*(UINT16_C(1)<<7)+0.5f)) 64ef026fa8SDirk Helbig 65ef026fa8SDirk Helbig #define Q16_TO_FLOAT(a) ((float)(a)/(UINT32_C(1)<<16)) 66ef026fa8SDirk Helbig #define Q15_TO_FLOAT(a) ((float)(a)/(UINT32_C(1)<<15)) 67ef026fa8SDirk Helbig #define Q8_TO_FLOAT(a) ((float)(a)/(UINT32_C(1)<<8)) 68ef026fa8SDirk Helbig #define Q7_TO_FLOAT(a) ((float)(a)/(UINT32_C(1)<<7)) 69ef026fa8SDirk Helbig 70ef026fa8SDirk Helbig //#define DEBUG_RATIO_CALCULATION 71ef026fa8SDirk Helbig 72ef026fa8SDirk Helbig typedef struct { 73ef026fa8SDirk Helbig uint32_t count; // 17bit are usable to count samples, recommended for max 96kHz 74ef026fa8SDirk Helbig uint32_t last; // time stamp of last measurement 75ef026fa8SDirk Helbig uint32_t rate_state; // unsigned Q17.8 76ef026fa8SDirk Helbig uint32_t ratio_state; // unsigned Q16.16 77ef026fa8SDirk Helbig uint32_t constant_playback_sample_rate; // playback sample rate if no real one is available 78ef026fa8SDirk Helbig #ifdef DEBUG_RATIO_CALCULATION 79ef026fa8SDirk Helbig double sample_rate; 80ef026fa8SDirk Helbig double ratio; 81ef026fa8SDirk Helbig #endif 82ef026fa8SDirk Helbig } btstack_sample_rate_compensation_t; 83ef026fa8SDirk Helbig 84*0d212321SDirk Helbig /** 85*0d212321SDirk Helbig * @brief Initialize sample rate compensation 86*0d212321SDirk Helbig * @param self pointer to current instance 87*0d212321SDirk Helbig * @param time stamp at which to start sample rate measurement 88*0d212321SDirk Helbig */ 89ef026fa8SDirk Helbig void btstack_sample_rate_compensation_init( btstack_sample_rate_compensation_t *self, uint32_t timestamp_ms, uint32_t sample_rate, uint32_t ratioQ15 ); 90*0d212321SDirk Helbig 91*0d212321SDirk Helbig /** 92*0d212321SDirk Helbig * @brief reset sample rate compensation 93*0d212321SDirk Helbig * @param self pointer to current instance 94*0d212321SDirk Helbig * @param time stamp at which to start sample rate measurement 95*0d212321SDirk Helbig */ 96*0d212321SDirk Helbig void btstack_sample_rate_compensation_reset( btstack_sample_rate_compensation_t *self, uint32_t timestamp_ms ); 97*0d212321SDirk Helbig 98*0d212321SDirk Helbig /** 99*0d212321SDirk Helbig * @brief update sample rate compensation with the current playback sample rate decoded samples 100*0d212321SDirk Helbig * @param self pointer to current instance 101*0d212321SDirk Helbig * @param time stamp for current samples 102*0d212321SDirk Helbig * @param samples for current time stamp 103*0d212321SDirk Helbig * @param playback sample rate 104*0d212321SDirk Helbig */ 105ef026fa8SDirk Helbig uint32_t btstack_sample_rate_compensation_update( btstack_sample_rate_compensation_t *self, uint32_t timestamp_ms, uint32_t samples, uint32_t playback_sample_rate ); 106ef026fa8SDirk Helbig 107*0d212321SDirk Helbig /* API_END */ 108*0d212321SDirk Helbig 109ef026fa8SDirk Helbig #if defined __cplusplus 110ef026fa8SDirk Helbig } 111ef026fa8SDirk Helbig #endif 112ef026fa8SDirk Helbig 113ef026fa8SDirk Helbig #endif /* BTSTACK_SAMPLE_RATE_COMPENSATION_H_ */ 114