2 * Benchmark for selected parts of the library.
3 * Copyright (C) 2007 Krzysztof Foltman
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General
16 * Public License along with this program; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301 USA
21 #define BENCHMARK_PLUGINS
29 #include <calf/audio_fx.h>
31 #ifdef BENCHMARK_PLUGINS
32 #include <calf/giface.h>
33 #include <calf/modules.h>
34 #include <calf/modules_dev.h>
37 #include <calf/loudness.h>
38 #include <calf/benchmark.h>
46 #include <calf/osctl.h>
47 #include <calf/osctlnet.h>
48 #include <calf/osctlserv.h>
49 using namespace osctl
;
52 bool benchmark_globals::warned
= false;
54 template<int BUF_SIZE
>
55 struct empty_benchmark
63 double scaler() { return BUF_SIZE
; }
66 template<class filter_class
>
67 struct filter_lp24dB_benchmark
69 enum { BUF_SIZE
= 256 };
70 float buffer
[BUF_SIZE
];
72 filter_class biquad
, biquad2
;
75 for (int i
= 0; i
< BUF_SIZE
; i
++)
77 biquad
.set_lp_rbj(2000, 0.7, 44100);
78 biquad2
.set_lp_rbj(2000, 0.7, 44100);
81 void cleanup() { result
= buffer
[BUF_SIZE
- 1]; }
82 double scaler() { return BUF_SIZE
; }
85 struct filter_24dB_lp_twopass_d1
: public filter_lp24dB_benchmark
<biquad_d1
<> >
89 for (int i
= 0; i
< BUF_SIZE
; i
++)
90 buffer
[i
] = biquad
.process(buffer
[i
]);
91 for (int i
= 0; i
< BUF_SIZE
; i
++)
92 buffer
[i
] = biquad2
.process(buffer
[i
]);
96 struct filter_24dB_lp_onepass_d1
: public filter_lp24dB_benchmark
<biquad_d1
<> >
100 for (int i
= 0; i
< BUF_SIZE
; i
++)
101 buffer
[i
] = biquad2
.process(biquad
.process(buffer
[i
]));
105 struct filter_12dB_lp_d1
: public filter_lp24dB_benchmark
<biquad_d1
<> >
109 for (int i
= 0; i
< BUF_SIZE
; i
++)
110 buffer
[i
] = biquad
.process(buffer
[i
]);
114 struct filter_24dB_lp_twopass_d2
: public filter_lp24dB_benchmark
<biquad_d2
<> >
118 for (int i
= 0; i
< BUF_SIZE
; i
++)
119 buffer
[i
] = biquad
.process(buffer
[i
]);
120 for (int i
= 0; i
< BUF_SIZE
; i
++)
121 buffer
[i
] = biquad2
.process(buffer
[i
]);
125 struct filter_24dB_lp_onepass_d2
: public filter_lp24dB_benchmark
<biquad_d2
<> >
129 for (int i
= 0; i
< BUF_SIZE
; i
++)
130 buffer
[i
] = biquad2
.process(biquad
.process(buffer
[i
]));
134 struct filter_24dB_lp_onepass_d2_lp
: public filter_lp24dB_benchmark
<biquad_d2
<> >
138 for (int i
= 0; i
< BUF_SIZE
; i
++)
139 buffer
[i
] = biquad2
.process_lp(biquad
.process_lp(buffer
[i
]));
143 struct filter_12dB_lp_d2
: public filter_lp24dB_benchmark
<biquad_d2
<> >
147 for (int i
= 0; i
< BUF_SIZE
; i
++)
148 buffer
[i
] = biquad
.process(buffer
[i
]);
153 struct fft_test_class
155 typedef fft
<float, N
> fft_class
;
158 complex<float> data
[1 << N
], output
[1 << N
];
160 for (int i
= 0; i
< (1 << N
); i
++)
169 ffter
.calculate(data
, output
, false);
171 double scaler() { return 1 << N
; }
174 #define ALIGN_TEST_RUN 1024
176 struct __attribute__((aligned(8))) alignment_test
: public empty_benchmark
<ALIGN_TEST_RUN
>
178 char __attribute__((aligned(8))) data
[ALIGN_TEST_RUN
* sizeof(double) + sizeof(double)];
181 virtual double *get_ptr()=0;
182 virtual ~alignment_test() {}
185 memset(data
, 0, sizeof(data
));
191 double *p
= get_ptr();
192 for (int i
=0; i
< ALIGN_TEST_RUN
; i
++)
197 struct aligned_double
: public alignment_test
199 virtual double *get_ptr() { return (double *)data
; }
202 double *ptr
= (double *)data
;
203 for (int i
=0; i
< ALIGN_TEST_RUN
; i
++)
208 struct __attribute__((aligned(8))) misaligned_double
: public alignment_test
210 virtual double *get_ptr() { return (double *)(data
+4); }
213 double *ptr
= (double *)(data
+ 4);
214 for (int i
=0; i
< ALIGN_TEST_RUN
; i
++)
219 const char *unit
= NULL
;
221 static struct option long_options
[] = {
223 {"version", 0, 0, 'v'},
230 do_simple_benchmark
<filter_24dB_lp_twopass_d1
>();
231 do_simple_benchmark
<filter_24dB_lp_onepass_d1
>();
232 do_simple_benchmark
<filter_12dB_lp_d1
>();
233 do_simple_benchmark
<filter_24dB_lp_twopass_d2
>();
234 do_simple_benchmark
<filter_24dB_lp_onepass_d2
>();
235 do_simple_benchmark
<filter_24dB_lp_onepass_d2_lp
>();
236 do_simple_benchmark
<filter_12dB_lp_d2
>();
241 do_simple_benchmark
<fft_test_class
<17> >(5, 10);
244 void alignment_test()
246 do_simple_benchmark
<misaligned_double
>();
247 do_simple_benchmark
<aligned_double
>();
250 #ifdef BENCHMARK_PLUGINS
251 template<class Effect
>
252 void get_default_effect_params(float params
[Effect::param_count
], uint32_t &sr
);
255 void get_default_effect_params
<calf_plugins::reverb_audio_module
>(float params
[3], uint32_t &sr
)
257 typedef calf_plugins::reverb_audio_module mod
;
258 params
[mod::par_decay
] = 4;
259 params
[mod::par_hfdamp
] = 2000;
260 params
[mod::par_amount
] = 2;
265 void get_default_effect_params
<calf_plugins::filter_audio_module
>(float params
[4], uint32_t &sr
)
267 typedef calf_plugins::filter_audio_module mod
;
268 params
[mod::par_cutoff
] = 500;
269 params
[mod::par_resonance
] = 3;
270 params
[mod::par_mode
] = 2;
271 params
[mod::par_inertia
] = 16;
276 void get_default_effect_params
<calf_plugins::flanger_audio_module
>(float params
[5], uint32_t &sr
)
278 typedef calf_plugins::flanger_audio_module mod
;
279 params
[mod::par_delay
] = 1;
280 params
[mod::par_depth
] = 2;
281 params
[mod::par_rate
] = 1;
282 params
[mod::par_fb
] = 0.9;
283 params
[mod::par_amount
] = 0.9;
288 void get_default_effect_params
<calf_plugins::compressor_audio_module
>(float params
[], uint32_t &sr
)
290 typedef calf_plugins::compressor_audio_module mod
;
291 params
[mod::param_threshold
] = 10;
292 params
[mod::param_ratio
] = 2;
293 params
[mod::param_attack
] = 0.1;
294 params
[mod::param_release
] = 100;
295 params
[mod::param_makeup
] = 1;
296 params
[mod::param_stereo_link
] = 1;
297 params
[mod::param_detection
] = 0;
298 params
[mod::param_knee
] = 40000;
299 params
[mod::param_bypass
] = 0;
300 params
[mod::param_aweighting
] = 1;
305 void get_default_effect_params
<calf_plugins::multichorus_audio_module
>(float params
[], uint32_t &sr
)
307 typedef calf_plugins::multichorus_audio_module mod
;
308 params
[mod::par_delay
] = 10;
309 params
[mod::par_depth
] = 10;
310 params
[mod::par_rate
] = 1;
311 params
[mod::par_voices
] = 6;
312 params
[mod::par_stereo
] = 180;
313 params
[mod::par_vphase
] = 20;
314 params
[mod::par_amount
] = 0.9;
318 template<class Effect
, unsigned int bufsize
= 256>
319 class effect_benchmark
: public empty_benchmark
<bufsize
>
323 float inputs
[Effect::in_count
][bufsize
];
324 float outputs
[Effect::out_count
][bufsize
];
326 float params
[Effect::param_count
];
330 for (int b
= 0; b
< Effect::out_count
; b
++)
332 effect
.outs
[b
] = outputs
[b
];
333 dsp::zero(outputs
[b
], bufsize
);
335 for (int b
= 0; b
< Effect::in_count
; b
++)
337 effect
.ins
[b
] = inputs
[b
];
338 for (unsigned int i
= 0; i
< bufsize
; i
++)
339 inputs
[b
][i
] = (float)(10 + i
*0.3f
*(b
+1));
341 for (int i
= 0; i
< Effect::param_count
; i
++)
342 effect
.params
[i
] = ¶ms
[i
];
343 ::get_default_effect_params
<Effect
>(params
, effect
.srate
);
349 effect
.params_changed();
350 effect
.process(0, bufsize
, 3, 3);
354 for (int b
= 0; b
< Effect::out_count
; b
++)
356 for (unsigned int i
= 0; i
< bufsize
; i
++)
357 result
+= outputs
[b
][i
];
364 dsp::do_simple_benchmark
<effect_benchmark
<calf_plugins::flanger_audio_module
> >(5, 10000);
365 dsp::do_simple_benchmark
<effect_benchmark
<calf_plugins::reverb_audio_module
> >(5, 1000);
366 dsp::do_simple_benchmark
<effect_benchmark
<calf_plugins::filter_audio_module
> >(5, 10000);
367 dsp::do_simple_benchmark
<effect_benchmark
<calf_plugins::compressor_audio_module
> >(5, 10000);
368 dsp::do_simple_benchmark
<effect_benchmark
<calf_plugins::multichorus_audio_module
> >(5, 10000);
374 printf("Test temporarily removed due to refactoring\n");
379 enum { LEN
= 1048576 };
380 static float data
[2][LEN
];
382 for (int t
= 1; t
< 38; t
++)
384 dsp::reverb
<float> rvb
;
386 memset(data
, 0, sizeof(data
));
390 rvb
.set_cutoff(22000);
393 rvb
.set_fb(t
< 19 ? t
* 0.05 : 0.905 + (t
- 19) * 0.005);
395 for (int i
= 0; i
< LEN
; i
++)
396 rvb
.process(data
[0][i
], data
[1][i
]);
399 for (i
= LEN
- 1; i
> 0; i
--)
401 // printf("[%d]=%f\n", i, data[0][i]);
402 if (fabs(data
[0][i
]) < 0.001 && fabs(data
[1][i
]) < 0.001)
407 printf("%f\t%f\n", rvb
.get_fb(), i
/ 44100.0);
413 biquad_coeffs
<float> bqc
;
414 bqc
.set_lowshelf_rbj(2000, 2.0, 4.0, 10000);
415 for (int i
= 0; i
<= 5000; i
+= 100)
417 printf("%d %f\n", i
, bqc
.freq_gain(i
* 1.0, 10000));
421 void aweighting_calc()
426 for (int i
= 10; i
< 20000; i
+= 10)
428 printf("%d %f\n", i
, 20*log10(aw
.freq_gain(i
* 1.0, fs
)));
434 struct my_sink
: public osc_message_sink
<osc_strstream
>
437 osc_message_dump
<osc_strstream
, ostream
> dump
;
438 my_sink() : dump(cout
) {}
439 virtual void receive_osc_message(std::string address
, std::string type_tag
, osc_strstream
&buffer
)
441 dump
.receive_osc_message(address
, type_tag
, buffer
);
442 assert(address
== "/blah");
443 assert(type_tag
== "bsii");
448 buffer
>> blob
>> str
>> val1
>> val2
;
449 assert(blob
.data
== "123");
450 assert(str
== "test");
453 g_main_loop_quit(loop
);
460 string sdata
= string("\000\000\000\003123\000test\000\000\000\000\000\000\000\001\000\000\000\002", 24);
461 string_buffer
sb(sdata
);
462 osc_strstream
is(sb
);
463 osc_inline_typed_strstream os
;
468 is
>> blob
>> str
>> val1
>> val2
;
469 assert(blob
.data
== "123");
470 assert(str
== "test");
474 os
<< blob
<< str
<< val1
<< val2
;
475 assert(os
.buf_data
.data
== sdata
);
476 assert(os
.buf_types
.data
== "bsii");
478 GMainLoop
*main_loop
= g_main_loop_new(NULL
, FALSE
);
480 sink
.loop
= main_loop
;
483 srv
.bind("0.0.0.0", 4541);
486 cli
.bind("0.0.0.0", 0);
487 cli
.set_addr("0.0.0.0", 4541);
488 if (!cli
.send("/blah", os
))
490 g_error("Could not send the OSC message");
493 g_main_loop_run(main_loop
);
497 int main(int argc
, char *argv
[])
501 int c
= getopt_long(argc
, argv
, "u:hv", long_options
, &option_index
);
507 printf("Benchmark suite Calf plugin pack\nSyntax: %s [--help] [--version] [--unit biquad|alignment|effects]\n", argv
[0]);
510 printf("%s\n", PACKAGE_STRING
);
519 if (unit
&& !strcmp(unit
, "osc"))
523 if (!unit
|| !strcmp(unit
, "biquad"))
526 if (!unit
|| !strcmp(unit
, "alignment"))
529 if (!unit
|| !strcmp(unit
, "effects"))
532 if (unit
&& !strcmp(unit
, "reverbir"))
535 if (unit
&& !strcmp(unit
, "eq"))
538 if (unit
&& !strcmp(unit
, "aweighting"))
541 if (!unit
|| !strcmp(unit
, "fft"))