1*c21cc0ebSMatthias Ringwald /* 2*c21cc0ebSMatthias Ringwald * Copyright (C) 2018 BlueKitchen GmbH 3*c21cc0ebSMatthias Ringwald * 4*c21cc0ebSMatthias Ringwald * Redistribution and use in source and binary forms, with or without 5*c21cc0ebSMatthias Ringwald * modification, are permitted provided that the following conditions 6*c21cc0ebSMatthias Ringwald * are met: 7*c21cc0ebSMatthias Ringwald * 8*c21cc0ebSMatthias Ringwald * 1. Redistributions of source code must retain the above copyright 9*c21cc0ebSMatthias Ringwald * notice, this list of conditions and the following disclaimer. 10*c21cc0ebSMatthias Ringwald * 2. Redistributions in binary form must reproduce the above copyright 11*c21cc0ebSMatthias Ringwald * notice, this list of conditions and the following disclaimer in the 12*c21cc0ebSMatthias Ringwald * documentation and/or other materials provided with the distribution. 13*c21cc0ebSMatthias Ringwald * 3. Neither the name of the copyright holders nor the names of 14*c21cc0ebSMatthias Ringwald * contributors may be used to endorse or promote products derived 15*c21cc0ebSMatthias Ringwald * from this software without specific prior written permission. 16*c21cc0ebSMatthias Ringwald * 4. Any redistribution, use, or modification is done solely for 17*c21cc0ebSMatthias Ringwald * personal benefit and not for any commercial purpose or for 18*c21cc0ebSMatthias Ringwald * monetary gain. 19*c21cc0ebSMatthias Ringwald * 20*c21cc0ebSMatthias Ringwald * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 21*c21cc0ebSMatthias Ringwald * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22*c21cc0ebSMatthias Ringwald * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23*c21cc0ebSMatthias Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS 24*c21cc0ebSMatthias Ringwald * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25*c21cc0ebSMatthias Ringwald * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26*c21cc0ebSMatthias Ringwald * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 27*c21cc0ebSMatthias Ringwald * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28*c21cc0ebSMatthias Ringwald * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29*c21cc0ebSMatthias Ringwald * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 30*c21cc0ebSMatthias Ringwald * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31*c21cc0ebSMatthias Ringwald * SUCH DAMAGE. 32*c21cc0ebSMatthias Ringwald * 33*c21cc0ebSMatthias Ringwald * Please inquire about commercial licensing options at 34*c21cc0ebSMatthias Ringwald * [email protected] 35*c21cc0ebSMatthias Ringwald * 36*c21cc0ebSMatthias Ringwald */ 37*c21cc0ebSMatthias Ringwald 38*c21cc0ebSMatthias Ringwald #include "btstack_resample.h" 39*c21cc0ebSMatthias Ringwald 40*c21cc0ebSMatthias Ringwald void btstack_resample_init(btstack_resample_t * context, int num_channels){ 41*c21cc0ebSMatthias Ringwald context->src_pos = 0; 42*c21cc0ebSMatthias Ringwald context->src_step = 0x10000; // default resampling 1.0 43*c21cc0ebSMatthias Ringwald context->last_sample[0] = 0; 44*c21cc0ebSMatthias Ringwald context->last_sample[1] = 0; 45*c21cc0ebSMatthias Ringwald context->num_channels = num_channels; 46*c21cc0ebSMatthias Ringwald } 47*c21cc0ebSMatthias Ringwald 48*c21cc0ebSMatthias Ringwald void btstack_resample_set_factor(btstack_resample_t * context, uint32_t src_step){ 49*c21cc0ebSMatthias Ringwald context->src_step = src_step; 50*c21cc0ebSMatthias Ringwald } 51*c21cc0ebSMatthias Ringwald 52*c21cc0ebSMatthias Ringwald uint16_t btstack_resample_block(btstack_resample_t * context, const int16_t * input_buffer, uint32_t num_frames, int16_t * output_buffer){ 53*c21cc0ebSMatthias Ringwald uint16_t dest_frames = 0; 54*c21cc0ebSMatthias Ringwald uint16_t dest_samples = 0; 55*c21cc0ebSMatthias Ringwald // samples between last sample of previous block and first sample in current block 56*c21cc0ebSMatthias Ringwald while (context->src_pos >= 0xffff0000){ 57*c21cc0ebSMatthias Ringwald const uint16_t t = context->src_pos & 0xffff; 58*c21cc0ebSMatthias Ringwald int i; 59*c21cc0ebSMatthias Ringwald for (i=0;i<context->num_channels;i++){ 60*c21cc0ebSMatthias Ringwald int s1 = context->last_sample[i]; 61*c21cc0ebSMatthias Ringwald int s2 = input_buffer[i]; 62*c21cc0ebSMatthias Ringwald int os = (s1*(0x10000 - t) + s2*t) >> 16; 63*c21cc0ebSMatthias Ringwald output_buffer[dest_samples++] = os; 64*c21cc0ebSMatthias Ringwald } 65*c21cc0ebSMatthias Ringwald dest_frames++; 66*c21cc0ebSMatthias Ringwald context->src_pos += context->src_step; 67*c21cc0ebSMatthias Ringwald } 68*c21cc0ebSMatthias Ringwald // process current block 69*c21cc0ebSMatthias Ringwald while (1){ 70*c21cc0ebSMatthias Ringwald const uint16_t src_pos = context->src_pos >> 16; 71*c21cc0ebSMatthias Ringwald const uint16_t t = context->src_pos & 0xffff; 72*c21cc0ebSMatthias Ringwald int index = src_pos * context->num_channels; 73*c21cc0ebSMatthias Ringwald int i; 74*c21cc0ebSMatthias Ringwald if (src_pos >= (num_frames - 1)){ 75*c21cc0ebSMatthias Ringwald // store last sample 76*c21cc0ebSMatthias Ringwald for (i=0;i<context->num_channels;i++){ 77*c21cc0ebSMatthias Ringwald context->last_sample[i] = input_buffer[index++]; 78*c21cc0ebSMatthias Ringwald } 79*c21cc0ebSMatthias Ringwald // samples processed 80*c21cc0ebSMatthias Ringwald context->src_pos -= num_frames << 16; 81*c21cc0ebSMatthias Ringwald break; 82*c21cc0ebSMatthias Ringwald } 83*c21cc0ebSMatthias Ringwald for (i=0;i<context->num_channels;i++){ 84*c21cc0ebSMatthias Ringwald int s1 = input_buffer[index]; 85*c21cc0ebSMatthias Ringwald int s2 = input_buffer[index+context->num_channels]; 86*c21cc0ebSMatthias Ringwald int os = (s1*(0x10000 - t) + s2*t) >> 16; 87*c21cc0ebSMatthias Ringwald output_buffer[dest_samples++] = os; 88*c21cc0ebSMatthias Ringwald index++; 89*c21cc0ebSMatthias Ringwald } 90*c21cc0ebSMatthias Ringwald dest_frames++; 91*c21cc0ebSMatthias Ringwald context->src_pos += context->src_step; 92*c21cc0ebSMatthias Ringwald } 93*c21cc0ebSMatthias Ringwald return dest_frames; 94*c21cc0ebSMatthias Ringwald } 95