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