Mercurial > hg > qm-dsp
comparison dsp/rateconversion/Resampler.cpp @ 139:7fe0da91e9c3
Save extra samples from one process to next (+ other fixes and debug out)
author | Chris Cannam |
---|---|
date | Mon, 14 Oct 2013 08:15:51 +0100 |
parents | e89d489af128 |
children | ce50eef47bdf |
comparison
equal
deleted
inserted
replaced
138:e89d489af128 | 139:7fe0da91e9c3 |
---|---|
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> |