summaryrefslogtreecommitdiff
path: root/src/chresampler.cc
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2014-10-12 21:15:56 +0200
committerBent Bisballe Nyeng <deva@aasimon.org>2014-10-12 21:15:56 +0200
commitfafc815d3b2f525e703ab9482a008201097ab90d (patch)
treef16a60541eefd32ac3a22138765a47425e156034 /src/chresampler.cc
parent484eb4f976568ba058c91a36f6482a404e35d486 (diff)
Add new resampler class and use it in engine.
Diffstat (limited to 'src/chresampler.cc')
-rw-r--r--src/chresampler.cc170
1 files changed, 170 insertions, 0 deletions
diff --git a/src/chresampler.cc b/src/chresampler.cc
new file mode 100644
index 0000000..301e650
--- /dev/null
+++ b/src/chresampler.cc
@@ -0,0 +1,170 @@
+/* -*- 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 2 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 <config.h>
+#include <hugin.hpp>
+#include <stdio.h>
+
+#ifdef WITH_RESAMPLER
+
+#if defined(USE_ZITA)
+ #include <zita-resampler/resampler.h>
+#elif defined(USE_SRC)
+ #include <samplerate.h>
+#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*/