1/*** 2 This file is part of PulseAudio. 3 4 Copyright 2004-2006 Lennart Poettering 5 6 PulseAudio is free software; you can redistribute it and/or modify 7 it under the terms of the GNU Lesser General Public License as published 8 by the Free Software Foundation; either version 2.1 of the License, 9 or (at your option) any later version. 10 11 PulseAudio is distributed in the hope that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 General Public License for more details. 15 16 You should have received a copy of the GNU Lesser General Public License 17 along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. 18***/ 19 20#ifdef HAVE_CONFIG_H 21#include <config.h> 22#endif 23 24#include <pulse/xmalloc.h> 25 26#include <pulsecore/resampler.h> 27 28struct trivial_data { /* data specific to the trivial resampler */ 29 unsigned o_counter; 30 unsigned i_counter; 31}; 32 33static unsigned trivial_resample(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) { 34 unsigned i_index, o_index; 35 void *src, *dst; 36 struct trivial_data *trivial_data; 37 38 pa_assert(r); 39 pa_assert(input); 40 pa_assert(output); 41 pa_assert(out_n_frames); 42 43 trivial_data = r->impl.data; 44 45 src = pa_memblock_acquire_chunk(input); 46 dst = pa_memblock_acquire_chunk(output); 47 48 for (o_index = 0;; o_index++, trivial_data->o_counter++) { 49 i_index = ((uint64_t) trivial_data->o_counter * r->i_ss.rate) / r->o_ss.rate; 50 i_index = i_index > trivial_data->i_counter ? i_index - trivial_data->i_counter : 0; 51 52 if (i_index >= in_n_frames) 53 break; 54 55 pa_assert_fp(o_index * r->w_fz < pa_memblock_get_length(output->memblock)); 56 57 memcpy((uint8_t*) dst + r->w_fz * o_index, (uint8_t*) src + r->w_fz * i_index, (int) r->w_fz); 58 } 59 60 pa_memblock_release(input->memblock); 61 pa_memblock_release(output->memblock); 62 63 *out_n_frames = o_index; 64 65 trivial_data->i_counter += in_n_frames; 66 67 /* Normalize counters */ 68 while (trivial_data->i_counter >= r->i_ss.rate) { 69 pa_assert(trivial_data->o_counter >= r->o_ss.rate); 70 71 trivial_data->i_counter -= r->i_ss.rate; 72 trivial_data->o_counter -= r->o_ss.rate; 73 } 74 75 return 0; 76} 77 78static void trivial_update_rates_or_reset(pa_resampler *r) { 79 struct trivial_data *trivial_data; 80 pa_assert(r); 81 82 trivial_data = r->impl.data; 83 84 trivial_data->i_counter = 0; 85 trivial_data->o_counter = 0; 86} 87 88int pa_resampler_trivial_init(pa_resampler *r) { 89 struct trivial_data *trivial_data; 90 pa_assert(r); 91 92 trivial_data = pa_xnew0(struct trivial_data, 1); 93 94 r->impl.resample = trivial_resample; 95 r->impl.update_rates = trivial_update_rates_or_reset; 96 r->impl.reset = trivial_update_rates_or_reset; 97 r->impl.data = trivial_data; 98 99 return 0; 100} 101