1 // AudioResampler.cpp -- custom audio resampler
3 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 3 of the License, or
9 // (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 #include "AudioResampler.h"
29 AudioResampler::convert_raw_data(
30 boost::int16_t** adjusted_data
,
33 int sample_count
, // A stereo pair counts as one
34 int sample_size
, // Should now always == 2
35 // sample_rate and stereo are those of the incoming sample
38 // m_sample_rate, m_stereo are the format we must convert to.
43 assert(sample_size
== 2); // at least it seems the code relies on this...
45 // simple hack to handle dup'ing mono to stereo
46 if ( !stereo
&& m_stereo
)
51 // simple hack to lose half the samples to get mono from stereo
52 if ( stereo
&& !m_stereo
)
57 // Brain-dead sample-rate conversion: duplicate or
58 // skip input samples an integral number of times.
59 int inc
= 1; // increment
60 int dup
= 1; // duplicate
61 if (sample_rate
> m_sample_rate
)
63 inc
= sample_rate
/ m_sample_rate
;
65 else if (sample_rate
< m_sample_rate
)
67 dup
= m_sample_rate
/ sample_rate
;
70 int output_sample_count
= (sample_count
* dup
* (stereo
? 2 : 1)) / inc
;
71 boost::int16_t* out_data
= new boost::int16_t[output_sample_count
];
72 *adjusted_data
= out_data
;
73 *adjusted_size
= output_sample_count
* sizeof(boost::int16_t); // in bytes
75 // Either inc > 1 (decimate the audio)
76 // or dup > 1 (repeat samples)
77 // or both == 1 (no transformation required)
78 if (inc
== 1 && dup
== 1)
80 // No tranformation required
81 std::memcpy(out_data
, data
, output_sample_count
* sizeof(boost::int16_t));
85 // Downsample by skipping samples from the input
86 boost::int16_t* in
= (boost::int16_t*) data
;
87 for (int i
= output_sample_count
; i
> 0; i
--)
95 // Upsample by duplicating input samples in the output.
97 // The straight sample-replication code handles mono-to-stereo (sort of)
98 // and upsampling of mono but would make a botch of stereo-to-stereo
99 // upsampling, giving the left sample in both channels
100 // then the right sample in both channels alternately.
101 // So for stereo-stereo transforms we have a stereo routine.
103 boost::int16_t* in
= (boost::int16_t*) data
;
105 if (stereo
&& m_stereo
) {
106 // Stereo-to-stereo upsampling: Replicate pairs of samples
107 for (int i
= output_sample_count
/ dup
/ 2; i
> 0; i
--)
109 for (int j
= dup
; j
> 0; j
--)
119 // Linear upsampling, either to increase a sample rate
120 // or to convert a mono file to stereo or both:
121 // replicate each sample several times.
125 for (int i
= output_sample_count
/ dup
; i
> 0; i
--)
133 for (int i
= output_sample_count
/ dup
; i
> 0; i
--)
143 for (int i
= output_sample_count
/ dup
; i
> 0; i
--)
145 for (int j
= dup
; j
> 0; j
--)
162 // indent-tabs-mode: t