comparison dsp/rateconversion/Resampler.cpp @ 364:01d7da967123

Save extra samples from one process to next (+ other fixes and debug out)
author Chris Cannam <c.cannam@qmul.ac.uk>
date Mon, 14 Oct 2013 08:15:51 +0100
parents 2fe2ab316c8e
children ce50eef47bdf
comparison
equal deleted inserted replaced
363:2fe2ab316c8e 364:01d7da967123
18 initialise(); 18 initialise();
19 } 19 }
20 20
21 Resampler::~Resampler() 21 Resampler::~Resampler()
22 { 22 {
23 delete[] m_buffer;
24 delete[] m_phaseData; 23 delete[] m_phaseData;
25 } 24 }
26 25
27 void 26 void
28 Resampler::initialise() 27 Resampler::initialise()
53 int inputSpacing = m_targetRate / m_gcd; 52 int inputSpacing = m_targetRate / m_gcd;
54 int outputSpacing = m_sourceRate / m_gcd; 53 int outputSpacing = m_sourceRate / m_gcd;
55 54
56 m_latency = int((m_filterLength / 2) / outputSpacing); 55 m_latency = int((m_filterLength / 2) / outputSpacing);
57 56
58 m_bufferLength = 0; 57 int bufferLength = 0;
59 58
60 m_phaseData = new Phase[inputSpacing]; 59 m_phaseData = new Phase[inputSpacing];
61 60
62 for (int phase = 0; phase < inputSpacing; ++phase) { 61 for (int phase = 0; phase < inputSpacing; ++phase) {
63 62
71 p.take = int((outputSpacing + 70 p.take = int((outputSpacing +
72 ((m_filterLength - 1 - phase) % inputSpacing)) 71 ((m_filterLength - 1 - phase) % inputSpacing))
73 / outputSpacing); 72 / outputSpacing);
74 73
75 int filtZipLength = int(ceil((m_filterLength - phase) / inputSpacing)); 74 int filtZipLength = int(ceil((m_filterLength - phase) / inputSpacing));
76 if (filtZipLength > m_bufferLength) { 75 if (filtZipLength > bufferLength) {
77 m_bufferLength = filtZipLength; 76 bufferLength = filtZipLength;
78 } 77 }
79 78
80 for (int i = 0; i < filtZipLength; ++i) { 79 for (int i = 0; i < filtZipLength; ++i) {
81 p.filter.push_back(filter[i * inputSpacing + phase]); 80 p.filter.push_back(filter[i * inputSpacing + phase]);
82 } 81 }
102 // until the filter fills, then half the filter length at once) or 101 // until the filter fills, then half the filter length at once) or
103 // else have a lengthy declared latency on the output. We do the 102 // else have a lengthy declared latency on the output. We do the
104 // latter. (What do other implementations do?) 103 // latter. (What do other implementations do?)
105 104
106 m_phase = m_filterLength % inputSpacing; 105 m_phase = m_filterLength % inputSpacing;
107 m_buffer = new double[m_bufferLength]; 106 m_buffer = vector<double>(bufferLength, 0);
108 for (int i = 0; i < m_bufferLength; ++i) m_buffer[i] = 0.0;
109 } 107 }
110 108
111 double 109 double
112 Resampler::reconstructOne(const double **srcptr) 110 Resampler::reconstructOne(const double *src)
113 { 111 {
114 Phase &pd = m_phaseData[m_phase]; 112 Phase &pd = m_phaseData[m_phase];
115 double *filt = pd.filter.data(); 113 double *filt = pd.filter.data();
116 int n = pd.filter.size(); 114 int n = pd.filter.size();
117 double v = 0.0; 115 double v = 0.0;
118 for (int i = 0; i < n; ++i) { 116 for (int i = 0; i < n; ++i) {
119 v += m_buffer[i] * filt[i]; 117 v += m_buffer[i] * filt[i];
120 } 118 }
121 for (int i = pd.drop; i < n; ++i) { 119 m_buffer = vector<double>(m_buffer.begin() + pd.drop, m_buffer.end());
122 m_buffer[i - pd.drop] = m_buffer[i]; 120 for (int i = 0; i < pd.take; ++i) {
121 m_buffer.push_back(src[i]);
123 } 122 }
124 for (int i = 0; i < pd.take; ++i) {
125 m_buffer[n - pd.drop + i] = **srcptr;
126 ++ *srcptr;
127 }
128 m_phase = pd.nextPhase;
129 return v; 123 return v;
130 } 124 }
131 125
132 int 126 int
133 Resampler::process(const double *src, double *dst, int n) 127 Resampler::process(const double *src, double *dst, int remaining)
134 { 128 {
135 int m = 0; 129 int m = 0;
136 const double *srcptr = src; 130 int offset = 0;
137 131
138 while (n > m_phaseData[m_phase].take) { 132 while (remaining >= m_phaseData[m_phase].take) {
139 std::cerr << "n = " << n << ", m = " << m << ", take = " << m_phaseData[m_phase].take << std::endl; 133 std::cerr << "remaining = " << remaining << ", m = " << m << ", take = " << m_phaseData[m_phase].take << std::endl;
140 n -= m_phaseData[m_phase].take; 134 int advance = m_phaseData[m_phase].take;
141 dst[m] = reconstructOne(&srcptr); 135 dst[m] = reconstructOne(src + offset);
142 std::cerr << "n -> " << n << std::endl; 136 offset += advance;
137 remaining -= advance;
138 m_phase = m_phaseData[m_phase].nextPhase;
139 std::cerr << "remaining -> " << remaining << ", new phase has advance " << m_phaseData[m_phase].take << std::endl;
143 ++m; 140 ++m;
144 } 141 }
145 142
146 //!!! save any excess 143 if (remaining > 0) {
144 std::cerr << "have " << remaining << " spare, pushing to buffer" << std::endl;
145 }
146
147 for (int i = 0; i < remaining; ++i) {
148 m_buffer.push_back(src[offset + i]);
149 }
147 150
148 return m; 151 return m;
149 } 152 }
150 153
151 std::vector<double> 154 std::vector<double>