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
23 #ifdef BENCHMARK_PLUGINS
24 #include <calf/giface.h>
25 #include <calf/modules_tools.h>
26 #include <calf/modules_delay.h>
27 #include <calf/modules_comp.h>
28 #include <calf/modules_dev.h>
29 #include <calf/modules_filter.h>
30 #include <calf/modules_mod.h>
35 #include <calf/audio_fx.h>
37 #include <calf/loudness.h>
38 #include <calf/benchmark.h>
47 #include <calf/osctl.h>
48 #include <calf/osctlnet.h>
49 #include <calf/osctl_glib.h>
50 using namespace osctl
;
53 bool benchmark_globals::warned
= false;
55 template<int BUF_SIZE
>
56 struct empty_benchmark
64 double scaler() { return BUF_SIZE
; }
67 template<class filter_class
>
68 struct filter_lp24dB_benchmark
70 enum { BUF_SIZE
= 256 };
71 float buffer
[BUF_SIZE
];
73 filter_class biquad
, biquad2
;
76 for (int i
= 0; i
< BUF_SIZE
; i
++)
78 biquad
.set_lp_rbj(2000, 0.7, 44100);
79 biquad2
.set_lp_rbj(2000, 0.7, 44100);
82 void cleanup() { result
= buffer
[BUF_SIZE
- 1]; }
83 double scaler() { return BUF_SIZE
; }
86 struct filter_24dB_lp_twopass_d1
: public filter_lp24dB_benchmark
<biquad_d1
>
90 for (int i
= 0; i
< BUF_SIZE
; i
++)
91 buffer
[i
] = biquad
.process(buffer
[i
]);
92 for (int i
= 0; i
< BUF_SIZE
; i
++)
93 buffer
[i
] = biquad2
.process(buffer
[i
]);
97 struct filter_24dB_lp_onepass_d1
: public filter_lp24dB_benchmark
<biquad_d1
>
101 for (int i
= 0; i
< BUF_SIZE
; i
++)
102 buffer
[i
] = biquad2
.process(biquad
.process(buffer
[i
]));
106 struct filter_12dB_lp_d1
: public filter_lp24dB_benchmark
<biquad_d1
>
110 for (int i
= 0; i
< BUF_SIZE
; i
++)
111 buffer
[i
] = biquad
.process(buffer
[i
]);
115 struct filter_24dB_lp_twopass_d2
: public filter_lp24dB_benchmark
<biquad_d2
>
119 for (int i
= 0; i
< BUF_SIZE
; i
++)
120 buffer
[i
] = biquad
.process(buffer
[i
]);
121 for (int i
= 0; i
< BUF_SIZE
; i
++)
122 buffer
[i
] = biquad2
.process(buffer
[i
]);
126 struct filter_24dB_lp_onepass_d2
: public filter_lp24dB_benchmark
<biquad_d2
>
130 for (int i
= 0; i
< BUF_SIZE
; i
++)
131 buffer
[i
] = biquad2
.process(biquad
.process(buffer
[i
]));
135 struct filter_24dB_lp_onepass_d2_lp
: public filter_lp24dB_benchmark
<biquad_d2
>
139 for (int i
= 0; i
< BUF_SIZE
; i
++)
140 buffer
[i
] = biquad2
.process_lp(biquad
.process_lp(buffer
[i
]));
144 struct filter_12dB_lp_d2
: public filter_lp24dB_benchmark
<biquad_d2
>
148 for (int i
= 0; i
< BUF_SIZE
; i
++)
149 buffer
[i
] = biquad
.process(buffer
[i
]);
154 struct fft_test_class
156 typedef fft
<float, N
> fft_class
;
159 complex<float> data
[1 << N
], output
[1 << N
];
161 for (int i
= 0; i
< (1 << N
); i
++)
170 ffter
.calculate(data
, output
, false);
172 double scaler() { return 1 << N
; }
175 #define ALIGN_TEST_RUN 1024
177 struct __attribute__((aligned(8))) alignment_test
: public empty_benchmark
<ALIGN_TEST_RUN
>
179 char __attribute__((aligned(8))) data
[ALIGN_TEST_RUN
* sizeof(double) + sizeof(double)];
182 virtual double *get_ptr()=0;
183 virtual ~alignment_test() {}
186 memset(data
, 0, sizeof(data
));
192 double *p
= get_ptr();
193 for (int i
=0; i
< ALIGN_TEST_RUN
; i
++)
198 struct aligned_double
: public alignment_test
200 virtual double *get_ptr() { return (double *)data
; }
203 double *ptr
= (double *)data
;
204 for (int i
=0; i
< ALIGN_TEST_RUN
; i
++)
209 struct __attribute__((aligned(8))) misaligned_double
: public alignment_test
211 virtual double *get_ptr() { return (double *)(data
+4); }
214 double *ptr
= (double *)(data
+ 4);
215 for (int i
=0; i
< ALIGN_TEST_RUN
; i
++)
220 const char *unit
= NULL
;
222 static struct option long_options
[] = {
224 {"version", 0, 0, 'v'},
231 do_simple_benchmark
<filter_24dB_lp_twopass_d1
>();
232 do_simple_benchmark
<filter_24dB_lp_onepass_d1
>();
233 do_simple_benchmark
<filter_12dB_lp_d1
>();
234 do_simple_benchmark
<filter_24dB_lp_twopass_d2
>();
235 do_simple_benchmark
<filter_24dB_lp_onepass_d2
>();
236 do_simple_benchmark
<filter_24dB_lp_onepass_d2_lp
>();
237 do_simple_benchmark
<filter_12dB_lp_d2
>();
242 do_simple_benchmark
<fft_test_class
<17> >(5, 10);
245 void alignment_test()
247 do_simple_benchmark
<misaligned_double
>();
248 do_simple_benchmark
<aligned_double
>();
251 #ifdef BENCHMARK_PLUGINS
252 template<class Effect
>
253 void get_default_effect_params(float params
[Effect::param_count
], uint32_t &sr
);
256 void get_default_effect_params
<calf_plugins::reverb_audio_module
>(float params
[3], uint32_t &sr
)
258 typedef calf_plugins::reverb_audio_module mod
;
259 params
[mod::par_decay
] = 4;
260 params
[mod::par_hfdamp
] = 2000;
261 params
[mod::par_amount
] = 2;
266 void get_default_effect_params
<calf_plugins::filter_audio_module
>(float params
[4], uint32_t &sr
)
268 typedef calf_plugins::filter_audio_module mod
;
269 params
[mod::par_cutoff
] = 500;
270 params
[mod::par_resonance
] = 3;
271 params
[mod::par_mode
] = 2;
272 params
[mod::par_inertia
] = 16;
277 void get_default_effect_params
<calf_plugins::flanger_audio_module
>(float params
[5], uint32_t &sr
)
279 typedef calf_plugins::flanger_audio_module mod
;
280 params
[mod::par_delay
] = 1;
281 params
[mod::par_depth
] = 2;
282 params
[mod::par_rate
] = 1;
283 params
[mod::par_fb
] = 0.9;
284 params
[mod::par_amount
] = 0.9;
289 void get_default_effect_params
<calf_plugins::compressor_audio_module
>(float params
[], uint32_t &sr
)
291 typedef calf_plugins::compressor_audio_module mod
;
292 params
[mod::param_threshold
] = 10;
293 params
[mod::param_ratio
] = 2;
294 params
[mod::param_attack
] = 0.1;
295 params
[mod::param_release
] = 100;
296 params
[mod::param_makeup
] = 1;
297 params
[mod::param_stereo_link
] = 1;
298 params
[mod::param_detection
] = 0;
299 params
[mod::param_knee
] = 40000;
300 params
[mod::param_bypass
] = 0;
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
++)
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);
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"))