1 /*****************************************************************************
2
3 Downsampler2xFpuTpl.hpp
4 Author: Laurent de Soras, 2005
5
6 --- Legal stuff ---
7
8 This program is free software. It comes without any warranty, to
9 the extent permitted by applicable law. You can redistribute it
10 and/or modify it under the terms of the Do What The Fuck You Want
11 To Public License, Version 2, as published by Sam Hocevar. See
12 http://sam.zoy.org/wtfpl/COPYING for more details.
13
14 *Tab=3***********************************************************************/
15
16
17
18 #if defined (hiir_Downsampler2xFpuTpl_CURRENT_CODEHEADER)
19 #error Recursive inclusion of Downsampler2xFpuTpl code header.
20 #endif
21 #define hiir_Downsampler2xFpuTpl_CURRENT_CODEHEADER
22
23 #if ! defined (hiir_Downsampler2xFpuTpl_CODEHEADER_INCLUDED)
24 #define hiir_Downsampler2xFpuTpl_CODEHEADER_INCLUDED
25
26
27
28 /*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
29
30 #include "hiir/StageProcFpu.h"
31
32 #include <cassert>
33
34
35
36 namespace hiir
37 {
38
39
40
41 /*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
42
43
44
45 /*
46 ==============================================================================
47 Name: set_coefs
48 Description:
49 Sets filter coefficients. Generate them with the PolyphaseIir2Designer
50 class.
51 Call this function before doing any processing.
52 Input parameters:
53 - coef_arr: Array of coefficients. There should be as many coefficients as
54 mentioned in the class template parameter.
55 Throws: Nothing
56 ==============================================================================
57 */
58
59 template <int NC, typename DT>
set_coefs(const double coef_arr[])60 void Downsampler2xFpuTpl <NC, DT>::set_coefs (const double coef_arr [])
61 {
62 assert (coef_arr != nullptr);
63
64 for (int i = 0; i < NBR_COEFS; ++i)
65 {
66 _filter [i + 2]._coef = DataType (coef_arr [i]);
67 }
68 }
69
70
71
72 /*
73 ==============================================================================
74 Name: process_sample
75 Description:
76 Downsamples (x2) one pair of samples, to generate one output sample.
77 Input parameters:
78 - in_ptr: pointer on the two samples to decimate
79 Returns: Samplerate-reduced sample.
80 Throws: Nothing
81 ==============================================================================
82 */
83
84 template <int NC, typename DT>
process_sample(const DataType in_ptr[2])85 typename Downsampler2xFpuTpl <NC, DT>::DataType Downsampler2xFpuTpl <NC, DT>::process_sample (const DataType in_ptr [2])
86 {
87 assert (in_ptr != nullptr);
88
89 DataType spl_0 (in_ptr [1]);
90 DataType spl_1 (in_ptr [0]);
91
92 StageProcFpu <NBR_COEFS, DataType>::process_sample_pos (
93 NBR_COEFS, spl_0, spl_1, _filter.data ()
94 );
95
96 return 0.5f * (spl_0 + spl_1);
97 }
98
99
100
101 /*
102 ==============================================================================
103 Name: process_block
104 Description:
105 Downsamples (x2) a block of samples.
106 Input and output blocks may overlap, see assert() for details.
107 Input parameters:
108 - in_ptr: Input array, containing nbr_spl * 2 samples.
109 - nbr_spl: Number of samples to output, > 0
110 Output parameters:
111 - out_ptr: Array for the output samples, capacity: nbr_spl samples.
112 Throws: Nothing
113 ==============================================================================
114 */
115
116 template <int NC, typename DT>
process_block(DataType out_ptr[],const DataType in_ptr[],long nbr_spl)117 void Downsampler2xFpuTpl <NC, DT>::process_block (DataType out_ptr [], const DataType in_ptr [], long nbr_spl)
118 {
119 assert (in_ptr != nullptr);
120 assert (out_ptr != nullptr);
121 assert (out_ptr <= in_ptr || out_ptr >= in_ptr + nbr_spl * 2);
122 assert (nbr_spl > 0);
123
124 long pos = 0;
125 do
126 {
127 out_ptr [pos] = process_sample (&in_ptr [pos * 2]);
128 ++pos;
129 }
130 while (pos < nbr_spl);
131 }
132
133
134
135 /*
136 ==============================================================================
137 Name: process_sample_split
138 Description:
139 Split (spectrum-wise) in half a pair of samples. The lower part of the
140 spectrum is a classic downsampling, equivalent to the output of
141 process_sample().
142 The higher part is the complementary signal: original filter response
143 is flipped from left to right, becoming a high-pass filter with the same
144 cutoff frequency. This signal is then critically sampled (decimation by 2),
145 flipping the spectrum: Fs/4...Fs/2 becomes Fs/4...0.
146 Input parameters:
147 - in_ptr: pointer on the pair of input samples
148 Output parameters:
149 - low: output sample, lower part of the spectrum (downsampling)
150 - high: output sample, higher part of the spectrum.
151 Throws: Nothing
152 ==============================================================================
153 */
154
155 template <int NC, typename DT>
process_sample_split(DataType & low,DataType & high,const DataType in_ptr[2])156 void Downsampler2xFpuTpl <NC, DT>::process_sample_split (DataType &low, DataType &high, const DataType in_ptr [2])
157 {
158 assert (in_ptr != nullptr);
159
160 DataType spl_0 = in_ptr [1];
161 DataType spl_1 = in_ptr [0];
162
163 StageProcFpu <NBR_COEFS, DataType>::process_sample_pos (
164 NBR_COEFS, spl_0, spl_1, _filter.data ()
165 );
166
167 low = (spl_0 + spl_1) * 0.5f;
168 high = spl_0 - low; // (spl_0 - spl_1) * 0.5f;
169 }
170
171
172
173 /*
174 ==============================================================================
175 Name: process_block_split
176 Description:
177 Split (spectrum-wise) in half a block of samples. The lower part of the
178 spectrum is a classic downsampling, equivalent to the output of
179 process_block().
180 The higher part is the complementary signal: original filter response
181 is flipped from left to right, becoming a high-pass filter with the same
182 cutoff frequency. This signal is then critically sampled (decimation by 2),
183 flipping the spectrum: Fs/4...Fs/2 becomes Fs/4...0.
184 Input and output blocks may overlap, see assert() for details.
185 Input parameters:
186 - in_ptr: Input array, containing nbr_spl * 2 samples.
187 - nbr_spl: Number of samples for each output, > 0
188 Output parameters:
189 - out_l_ptr: Array for the output samples, lower part of the spectrum
190 (downsampling). Capacity: nbr_spl samples.
191 - out_h_ptr: Array for the output samples, higher part of the spectrum.
192 Capacity: nbr_spl samples.
193 Throws: Nothing
194 ==============================================================================
195 */
196
197 template <int NC, typename DT>
process_block_split(DataType out_l_ptr[],DataType out_h_ptr[],const DataType in_ptr[],long nbr_spl)198 void Downsampler2xFpuTpl <NC, DT>::process_block_split (DataType out_l_ptr [], DataType out_h_ptr [], const DataType in_ptr [], long nbr_spl)
199 {
200 assert (in_ptr != nullptr);
201 assert (out_l_ptr != nullptr);
202 assert (out_l_ptr <= in_ptr || out_l_ptr >= in_ptr + nbr_spl * 2);
203 assert (out_h_ptr != nullptr);
204 assert (out_h_ptr <= in_ptr || out_h_ptr >= in_ptr + nbr_spl * 2);
205 assert (out_h_ptr != out_l_ptr);
206 assert (nbr_spl > 0);
207
208 long pos = 0;
209 do
210 {
211 process_sample_split (
212 out_l_ptr [pos],
213 out_h_ptr [pos],
214 &in_ptr [pos * 2]
215 );
216 ++pos;
217 }
218 while (pos < nbr_spl);
219 }
220
221
222
223 /*
224 ==============================================================================
225 Name: clear_buffers
226 Description:
227 Clears filter memory, as if it processed silence since an infinite amount
228 of time.
229 Throws: Nothing
230 ==============================================================================
231 */
232
233 template <int NC, typename DT>
clear_buffers()234 void Downsampler2xFpuTpl <NC, DT>::clear_buffers ()
235 {
236 for (int i = 0; i < NBR_COEFS + 2; ++i)
237 {
238 _filter [i]._mem = 0;
239 }
240 }
241
242
243
244 /*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
245
246
247
248 /*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
249
250
251
252 } // namespace hiir
253
254
255
256 #endif // hiir_Downsampler2xFpuTpl_CODEHEADER_INCLUDED
257
258 #undef hiir_Downsampler2xFpuTpl_CURRENT_CODEHEADER
259
260
261
262 /*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
263