2 #ifndef __PANDA_RESAMPLER_HH__
3 #define __PANDA_RESAMPLER_HH__
17 namespace PandaResampler {
19 typedef unsigned int uint;
22 check (
bool value,
const char *file,
int line,
const char *func,
const char *what)
25 fprintf (stderr,
"%s:%d:%s: PANDA_RESAMPLER_CHECK FAILED: %s\n", file, line, func, what);
29 #define PANDA_RESAMPLER_CHECK(expr) (PandaResampler::check (expr, __FILE__, __LINE__, __func__, #expr))
33 unsigned char *unaligned_mem;
38 allocate_aligned_data()
43 const size_t cache_line_size = 64;
45 unaligned_mem = (
unsigned char *) malloc (n_elements *
sizeof (T) + 2 * (cache_line_size - 1));
46 unsigned char *aligned_mem = unaligned_mem;
47 if ((ptrdiff_t) aligned_mem % cache_line_size)
48 aligned_mem += cache_line_size - (ptrdiff_t) aligned_mem % cache_line_size;
50 data =
reinterpret_cast<T *
> (aligned_mem);
54 n_elements (n_elements)
56 allocate_aligned_data();
57 for (
size_t i = 0; i < n_elements; i++)
63 std::copy (elements.begin(), elements.end(), data);
69 data[--n_elements].~T();
73 operator[] (
size_t pos)
78 operator[] (
size_t pos)
const
92 return &data[n_elements];
103 virtual void process_block (
const float *input, uint n_input_samples,
float *output) = 0;
104 virtual uint
order()
const = 0;
105 virtual double delay()
const = 0;
106 virtual void reset() = 0;
113 std::unique_ptr<Impl> impl_x2;
114 std::unique_ptr<Impl> impl_x4;
115 std::unique_ptr<Impl> impl_x8;
118 template<u
int ORDER,
bool USE_SSE>
120 template<u
int ORDER,
bool USE_SSE>
127 class IIRUpsampler2SSE;
129 class IIRDownsampler2SSE;
149 Precision precision_;
150 bool use_sse_if_available_;
159 bool use_sse_if_available =
true,
160 Filter filter = FILTER_FIR);
185 impl_x2->process_block (input, n_input_samples, output);
187 else if (ratio_ == 1)
189 std::copy (input, input + n_input_samples, output);
193 while (n_input_samples)
195 const uint block_size = 1024;
196 const uint n_todo_samples = std::min (block_size, n_input_samples);
198 float tmp[block_size * 4];
199 float tmp2[block_size * 4];
205 impl_x2->process_block (input, n_todo_samples, tmp);
206 impl_x4->process_block (tmp, n_todo_samples * 2, output);
210 impl_x2->process_block (input, n_todo_samples, tmp);
211 impl_x4->process_block (tmp, n_todo_samples * 2, tmp2);
212 impl_x8->process_block (tmp2, n_todo_samples * 4, output);
214 output += n_todo_samples * ratio_;
220 impl_x4->process_block (input, n_todo_samples, tmp);
221 impl_x2->process_block (tmp, n_todo_samples / 2, output);
225 impl_x8->process_block (input, n_todo_samples, tmp);
226 impl_x4->process_block (tmp, n_todo_samples / 2, tmp2);
227 impl_x2->process_block (tmp2, n_todo_samples / 4, output);
229 output += n_todo_samples / ratio_;
231 input += n_todo_samples;
232 n_input_samples -= n_todo_samples;
242 return impl_x2->order();
263 d += impl_x2->delay();
265 d += d + impl_x4->delay();
267 d += d + impl_x8->delay();
272 d += impl_x2->delay();
274 d += impl_x4->delay() / 2;
276 d += impl_x8->delay() / 4;
299 return impl_x2->sse_enabled();
307 template<
class Filter>
static inline Impl*
308 create_impl_with_coeffs (
const double *d,
313 for (uint i = 0; i <
order; i++)
314 taps[i] = d[i] * scaling;
316 Resampler2::Impl *filter =
new Filter (taps);
317 if (!PANDA_RESAMPLER_CHECK (
order == filter->order()))
328 template<
bool USE_SSE>
inline Impl*
329 create_impl (uint stage_ratio);
331 template<
bool USE_SSE>
inline Impl*
332 create_impl_iir (uint stage_ratio);
334 template<
class CArray>
336 create_impl_iir_with_coeffs (
const CArray& carray,
double group_delay);
339 init_stage (std::unique_ptr<Impl>& impl,
346 #if defined(PANDA_RESAMPLER_HEADER_ONLY) && !defined(PANDA_RESAMPLER_SOURCE)
347 # define PANDA_RESAMPLER_SOURCE "pandaresampler.cc"
348 # include PANDA_RESAMPLER_SOURCE
Definition: smpandaresampler.hh:32
Definition: smpandaresampler.cc:494
Definition: smpandaresampler.cc:1067
Definition: smpandaresampler.cc:1106
Definition: smpandaresampler.cc:353
Definition: smpandaresampler.hh:99
static const char * precision_name(Precision precision)
Definition: smpandaresampler.cc:148
Resampler2(Mode mode, uint ratio, Precision precision, bool use_sse_if_available=true, Filter filter=FILTER_FIR)
Definition: smpandaresampler.cc:64
void process_block(const float *input, uint n_input_samples, float *output)
Definition: smpandaresampler.hh:181
void reset()
Definition: smpandaresampler.hh:284
static bool test_filter_impl(bool verbose)
Definition: smpandaresampler.cc:1387
static bool sse_available()
Definition: smpandaresampler.cc:116
bool sse_enabled() const
Definition: smpandaresampler.hh:297
double delay() const
Definition: smpandaresampler.hh:257
static Precision find_precision_for_bits(uint bits)
Definition: smpandaresampler.cc:127
uint order() const
Definition: smpandaresampler.hh:240