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