/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /*************************************************************************** * chresampler.cc * * Tue Sep 23 20:42:14 CEST 2014 * Copyright 2014 Bent Bisballe Nyeng * deva@aasimon.org ****************************************************************************/ /* * This file is part of DrumGizmo. * * DrumGizmo is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * DrumGizmo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with DrumGizmo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ #include "chresampler.h" #include #include #include #ifdef WITH_RESAMPLER #if defined(USE_ZITA) #include #elif defined(USE_SRC) #include #else #error "No resampler selected" #endif class CHResampler::Prv { public: #if defined(USE_ZITA) Resampler zita; #elif defined(USE_SRC) SRC_STATE *state; SRC_DATA data; #endif }; CHResampler::CHResampler() { input_fs = 44100; output_fs = 44100; prv = new Prv(); #if defined(SRC) prv->state = NULL; #endif } void CHResampler::setup(double input_fs, double output_fs) { int nchan = 1; // always mono this->input_fs = input_fs; this->output_fs = output_fs; #if defined(USE_ZITA) DEBUG(resampler, "Using zita-resampler (%d -> %d)", (int)input_fs, (int)output_fs); int hlen = 72; // 16 ≤ hlen ≤ 96 // delay is 2 * hlen, 72 corresponds to delay introduced by SRC. prv->zita.setup(input_fs, output_fs, nchan, hlen); #elif defined(USE_SRC) DEBUG(resampler, "Using libsamplerate (%d -> %d)", (int)input_fs, (int)output_fs); int err; prv->state = src_new(SRC_SINC_BEST_QUALITY, nchan, &err); (void)err; // printf("err: %d\n", err); src_set_ratio(prv->state, output_fs / input_fs); prv->data.src_ratio = output_fs / input_fs; prv->data.end_of_input = 0; #endif } CHResampler::~CHResampler() { #if defined(USE_ZITA) #elif defined(USE_SRC) if(prv->state) src_delete(prv->state); #endif delete prv; } void CHResampler::setInputSamples(float *samples, size_t count) { #if defined(USE_ZITA) prv->zita.inp_data = samples; prv->zita.inp_count = count; #elif defined(USE_SRC) prv->data.data_in = samples; prv->data.input_frames = count; #endif } void CHResampler::setOutputSamples(float *samples, size_t count) { #if defined(USE_ZITA) prv->zita.out_data = samples; prv->zita.out_count = count; #elif defined(USE_SRC) prv->data.data_out = samples; prv->data.output_frames = count; #endif } void CHResampler::process() { #if defined(USE_ZITA) prv->zita.process(); #elif defined(USE_SRC) src_process(prv->state, &prv->data); prv->data.output_frames -= prv->data.output_frames_gen; prv->data.data_out += prv->data.output_frames_gen; prv->data.input_frames -= prv->data.input_frames_used; prv->data.data_in += prv->data.input_frames_used; #endif } size_t CHResampler::getInputSampleCount() { #if defined(USE_ZITA) return prv->zita.inp_count; #elif defined(USE_SRC) return prv->data.input_frames; #endif } size_t CHResampler::getOutputSampleCount() { #if defined(USE_ZITA) return prv->zita.out_count; #elif defined(USE_SRC) return prv->data.output_frames; #endif } double CHResampler::ratio() { return input_fs / output_fs; } #else // Dummy implementation CHResampler::CHResampler() {} CHResampler::~CHResampler() {} void CHResampler::setup(double, double) {} void CHResampler::setInputSamples(float *, size_t) {} void CHResampler::setOutputSamples(float *, size_t) {} void CHResampler::process() {} size_t CHResampler::getInputSampleCount() { return 0; } size_t CHResampler::getOutputSampleCount() { return 0; } double CHResampler::ratio() { return 1; } #endif/*WITH_RESAMPLER*/