1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
5 An audio time-stretching and pitch-shifting library.
6 Copyright 2007-2008 Chris Cannam.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2 of the
11 License, or (at your option) any later version. See the file
12 COPYING included with this distribution for more information.
15 #include "Resampler.h"
25 #include <samplerate.h>
29 namespace RubberBand {
34 virtual ~ResamplerImpl() { }
36 virtual int resample(const float *const R__ *const R__ in,
37 float *const R__ *const R__ out,
42 virtual void reset() = 0;
45 namespace Resamplers {
49 class D_SRC : public ResamplerImpl
52 D_SRC(Resampler::Quality quality, int channels, int maxBufferSize,
56 int resample(const float *const R__ *const R__ in,
57 float *const R__ *const R__ out,
75 D_SRC::D_SRC(Resampler::Quality quality, int channels, int maxBufferSize,
84 m_debugLevel(debugLevel)
86 if (m_debugLevel > 0) {
87 std::cerr << "Resampler::Resampler: using libsamplerate implementation"
92 m_src = src_new(quality == Resampler::Best ? SRC_SINC_BEST_QUALITY :
93 quality == Resampler::Fastest ? SRC_LINEAR :
98 std::cerr << "Resampler::Resampler: failed to create libsamplerate resampler: "
99 << src_strerror(err) << std::endl;
100 throw Resampler::ImplementationError; //!!! of course, need to catch this!
103 if (maxBufferSize > 0 && m_channels > 1) {
104 m_iinsize = maxBufferSize * m_channels;
105 m_ioutsize = maxBufferSize * m_channels * 2;
106 m_iin = allocFloat(m_iinsize);
107 m_iout = allocFloat(m_ioutsize);
119 if (m_ioutsize > 0) {
125 D_SRC::resample(const float *const R__ *const R__ in,
126 float *const R__ *const R__ out,
133 int outcount = lrintf(ceilf(incount * ratio));
135 if (m_channels == 1) {
136 data.data_in = const_cast<float *>(*in); //!!!???
137 data.data_out = *out;
139 if (incount * m_channels > m_iinsize) {
140 m_iinsize = incount * m_channels;
141 m_iin = allocFloat(m_iin, m_iinsize);
143 if (outcount * m_channels > m_ioutsize) {
144 m_ioutsize = outcount * m_channels;
145 m_iout = allocFloat(m_iout, m_ioutsize);
147 for (int i = 0; i < incount; ++i) {
148 for (int c = 0; c < m_channels; ++c) {
149 m_iin[i * m_channels + c] = in[c][i];
152 data.data_in = m_iin;
153 data.data_out = m_iout;
156 data.input_frames = incount;
157 data.output_frames = outcount;
158 data.src_ratio = ratio;
159 data.end_of_input = (final ? 1 : 0);
162 err = src_process(m_src, &data);
165 std::cerr << "Resampler::process: libsamplerate error: "
166 << src_strerror(err) << std::endl;
167 throw Resampler::ImplementationError; //!!! of course, need to catch this!
170 if (m_channels > 1) {
171 for (int i = 0; i < data.output_frames_gen; ++i) {
172 for (int c = 0; c < m_channels; ++c) {
173 out[c][i] = m_iout[i * m_channels + c];
180 return data.output_frames_gen;
191 } /* end namespace Resamplers */
193 Resampler::Resampler(Resampler::Quality quality, int channels,
194 int maxBufferSize, int debugLevel)
200 case Resampler::Best:
204 case Resampler::FastestTolerable:
208 case Resampler::Fastest:
213 if (m_method == -1) {
214 std::cerr << "Resampler::Resampler(" << quality << ", " << channels
215 << ", " << maxBufferSize << "): No implementation available!"
222 std::cerr << "Resampler::Resampler(" << quality << ", " << channels
223 << ", " << maxBufferSize << "): No implementation available!"
229 d = new Resamplers::D_SRC(quality, channels, maxBufferSize, debugLevel);
233 std::cerr << "Resampler::Resampler(" << quality << ", " << channels
234 << ", " << maxBufferSize << "): No implementation available!"
241 Resampler::~Resampler()
247 Resampler::resample(const float *const R__ *const R__ in,
248 float *const R__ *const R__ out,
249 int incount, float ratio, bool final)
251 Profiler profiler("Resampler::resample");
252 return d->resample(in, out, incount, ratio, final);