svcore  1.9
Resampler.cpp
Go to the documentation of this file.
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2 /*
3  Sonic Visualiser
4  An audio file viewer and annotation editor.
5  Centre for Digital Music, Queen Mary, University of London.
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of the
10  License, or (at your option) any later version. See the file
11  COPYING included with this distribution for more information.
12 */
13 
14 /*
15  This is a modified version of a source file from the
16  Rubber Band audio timestretcher library.
17  This file copyright 2007 Chris Cannam.
18 */
19 
20 #include "Resampler.h"
21 
22 #include <cstdlib>
23 #include <cmath>
24 
25 #include <iostream>
26 
27 #include <samplerate.h>
28 
29 #include "Debug.h"
30 
32 {
33 public:
34  D(Quality quality, int channels, int chunkSize);
35  ~D();
36 
37  int resample(float **in, float **out,
38  int incount, float ratio,
39  bool final);
40 
41  int resampleInterleaved(float *in, float *out,
42  int incount, float ratio,
43  bool final);
44 
45  void reset();
46 
47 protected:
48  SRC_STATE *m_src;
49  float *m_iin;
50  float *m_iout;
52  int m_iinsize;
54 };
55 
56 Resampler::D::D(Quality quality, int channels, int chunkSize) :
57  m_src(0),
58  m_iin(0),
59  m_iout(0),
60  m_channels(channels),
61  m_iinsize(0),
62  m_ioutsize(0)
63 {
64  int err = 0;
65  m_src = src_new(quality == Best ? SRC_SINC_BEST_QUALITY :
66  quality == Fastest ? SRC_LINEAR :
67  SRC_SINC_FASTEST,
68  channels, &err);
69 
71 
72  if (chunkSize > 0 && m_channels > 1) {
74  m_iinsize = chunkSize * m_channels;
75  m_ioutsize = chunkSize * m_channels * 2;
76  m_iin = (float *)malloc(m_iinsize * sizeof(float));
77  m_iout = (float *)malloc(m_ioutsize * sizeof(float));
78  }
79 }
80 
82 {
83  src_delete(m_src);
84  if (m_iinsize > 0) {
85  free(m_iin);
86  }
87  if (m_ioutsize > 0) {
88  free(m_iout);
89  }
90 }
91 
92 int
93 Resampler::D::resample(float **in, float **out,
94  int incount, float ratio,
95  bool final)
96 {
97  if (m_channels == 1) {
98  return resampleInterleaved(*in, *out, incount, ratio, final);
99  }
100 
101  int outcount = lrintf(ceilf(incount * ratio));
102 
103  if (incount * m_channels > m_iinsize) {
104  m_iinsize = incount * m_channels;
105  m_iin = (float *)realloc(m_iin, m_iinsize * sizeof(float));
106  }
107  if (outcount * m_channels > m_ioutsize) {
108  m_ioutsize = outcount * m_channels;
109  m_iout = (float *)realloc(m_iout, m_ioutsize * sizeof(float));
110  }
111  for (int i = 0; i < incount; ++i) {
112  for (int c = 0; c < m_channels; ++c) {
113  m_iin[i * m_channels + c] = in[c][i];
114  }
115  }
116 
117  int gen = resampleInterleaved(m_iin, m_iout, incount, ratio, final);
118 
119  for (int i = 0; i < gen; ++i) {
120  for (int c = 0; c < m_channels; ++c) {
121  out[c][i] = m_iout[i * m_channels + c];
122  }
123  }
124 
125  return gen;
126 }
127 
128 int
129 Resampler::D::resampleInterleaved(float *in, float *out,
130  int incount, float ratio,
131  bool final)
132 {
133  SRC_DATA data;
134 
135  int outcount = lrintf(ceilf(incount * ratio));
136 
137  data.data_in = in;
138  data.data_out = out;
139  data.input_frames = incount;
140  data.output_frames = outcount;
141  data.src_ratio = ratio;
142  data.end_of_input = (final ? 1 : 0);
143 
144  int err = src_process(m_src, &data);
145 
146  if (err) {
147  cerr << "Resampler: ERROR: src_process returned error: " <<
148  src_strerror(err) << endl;
149  return 0;
150  }
151 
152  if (data.input_frames_used != (int)incount) {
153  cerr << "Resampler: NOTE: input_frames_used == " << data.input_frames_used << " (while incount = " << incount << ")" << endl;
154  }
155 
156  return data.output_frames_gen;
157 }
158 
159 void
161 {
162  src_reset(m_src);
163 }
164 
165 Resampler::Resampler(Quality quality, int channels, int chunkSize)
166 {
167  m_d = new D(quality, channels, chunkSize);
168 }
169 
171 {
172  delete m_d;
173 }
174 
175 int
176 Resampler::resample(float **in, float **out,
177  int incount, float ratio,
178  bool final)
179 {
180  return m_d->resample(in, out, incount, ratio, final);
181 }
182 
183 int
184 Resampler::resampleInterleaved(float *in, float *out,
185  int incount, float ratio,
186  bool final)
187 {
188  return m_d->resampleInterleaved(in, out, incount, ratio, final);
189 }
190 
191 void
193 {
194  m_d->reset();
195 }
196 
int resampleInterleaved(float *in, float *out, int incount, float ratio, bool final)
Definition: Resampler.cpp:129
int resampleInterleaved(float *in, float *out, int incount, float ratio, bool final=false)
Definition: Resampler.cpp:184
int resample(float **in, float **out, int incount, float ratio, bool final)
Definition: Resampler.cpp:93
D * m_d
Definition: Resampler.h:45
void reset()
Definition: Resampler.cpp:192
Resampler(Quality quality, int channels, int chunkSize=0)
Definition: Resampler.cpp:165
float * m_iin
Definition: Resampler.cpp:49
SRC_STATE * m_src
Definition: Resampler.cpp:48
void reset()
Definition: Resampler.cpp:160
float * m_iout
Definition: Resampler.cpp:50
int resample(float **in, float **out, int incount, float ratio, bool final=false)
Definition: Resampler.cpp:176
D(Quality quality, int channels, int chunkSize)
Definition: Resampler.cpp:56