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., 59 Temple Place, Suite 330,
18 * Boston, MA 02111-1307, USA.
25 #include <calf/audio_fx.h>
26 //#include <calf/giface.h>
27 //#include <calf/modules.h>
28 //#include <calf/modules_dev.h>
29 #include <calf/loudness.h>
30 #include <calf/benchmark.h>
38 #include <calf/osctl.h>
39 #include <calf/osctlnet.h>
40 using namespace osctl
;
43 bool benchmark_globals::warned
= false;
45 template<int BUF_SIZE
>
46 struct empty_benchmark
54 double scaler() { return BUF_SIZE
; }
57 template<class filter_class
>
58 struct filter_lp24dB_benchmark
60 enum { BUF_SIZE
= 256 };
61 float buffer
[BUF_SIZE
];
63 filter_class biquad
, biquad2
;
66 for (int i
= 0; i
< BUF_SIZE
; i
++)
68 biquad
.set_lp_rbj(2000, 0.7, 44100);
69 biquad2
.set_lp_rbj(2000, 0.7, 44100);
72 void cleanup() { result
= buffer
[BUF_SIZE
- 1]; }
73 double scaler() { return BUF_SIZE
; }
76 struct filter_24dB_lp_twopass_d1
: public filter_lp24dB_benchmark
<biquad_d1
<> >
80 for (int i
= 0; i
< BUF_SIZE
; i
++)
81 buffer
[i
] = biquad
.process(buffer
[i
]);
82 for (int i
= 0; i
< BUF_SIZE
; i
++)
83 buffer
[i
] = biquad2
.process(buffer
[i
]);
87 struct filter_24dB_lp_onepass_d1
: public filter_lp24dB_benchmark
<biquad_d1
<> >
91 for (int i
= 0; i
< BUF_SIZE
; i
++)
92 buffer
[i
] = biquad2
.process(biquad
.process(buffer
[i
]));
96 struct filter_12dB_lp_d1
: public filter_lp24dB_benchmark
<biquad_d1
<> >
100 for (int i
= 0; i
< BUF_SIZE
; i
++)
101 buffer
[i
] = biquad
.process(buffer
[i
]);
105 struct filter_24dB_lp_twopass_d2
: public filter_lp24dB_benchmark
<biquad_d2
<> >
109 for (int i
= 0; i
< BUF_SIZE
; i
++)
110 buffer
[i
] = biquad
.process(buffer
[i
]);
111 for (int i
= 0; i
< BUF_SIZE
; i
++)
112 buffer
[i
] = biquad2
.process(buffer
[i
]);
116 struct filter_24dB_lp_onepass_d2
: public filter_lp24dB_benchmark
<biquad_d2
<> >
120 for (int i
= 0; i
< BUF_SIZE
; i
++)
121 buffer
[i
] = biquad2
.process(biquad
.process(buffer
[i
]));
125 struct filter_24dB_lp_onepass_d2_lp
: public filter_lp24dB_benchmark
<biquad_d2
<> >
129 for (int i
= 0; i
< BUF_SIZE
; i
++)
130 buffer
[i
] = biquad2
.process_lp(biquad
.process_lp(buffer
[i
]));
134 struct filter_12dB_lp_d2
: public filter_lp24dB_benchmark
<biquad_d2
<> >
138 for (int i
= 0; i
< BUF_SIZE
; i
++)
139 buffer
[i
] = biquad
.process(buffer
[i
]);
143 #define ALIGN_TEST_RUN 1024
145 struct __attribute__((aligned(8))) alignment_test
: public empty_benchmark
<ALIGN_TEST_RUN
>
147 char __attribute__((aligned(8))) data
[ALIGN_TEST_RUN
* sizeof(double) + sizeof(double)];
150 virtual double *get_ptr()=0;
151 virtual ~alignment_test() {}
154 memset(data
, 0, sizeof(data
));
160 double *p
= get_ptr();
161 for (int i
=0; i
< ALIGN_TEST_RUN
; i
++)
166 struct aligned_double
: public alignment_test
168 virtual double *get_ptr() { return (double *)data
; }
171 double *ptr
= (double *)data
;
172 for (int i
=0; i
< ALIGN_TEST_RUN
; i
++)
177 struct __attribute__((aligned(8))) misaligned_double
: public alignment_test
179 virtual double *get_ptr() { return (double *)(data
+4); }
182 double *ptr
= (double *)(data
+ 4);
183 for (int i
=0; i
< ALIGN_TEST_RUN
; i
++)
188 const char *unit
= NULL
;
190 static struct option long_options
[] = {
192 {"version", 0, 0, 'v'},
199 do_simple_benchmark
<filter_24dB_lp_twopass_d1
>();
200 do_simple_benchmark
<filter_24dB_lp_onepass_d1
>();
201 do_simple_benchmark
<filter_12dB_lp_d1
>();
202 do_simple_benchmark
<filter_24dB_lp_twopass_d2
>();
203 do_simple_benchmark
<filter_24dB_lp_onepass_d2
>();
204 do_simple_benchmark
<filter_24dB_lp_onepass_d2_lp
>();
205 do_simple_benchmark
<filter_12dB_lp_d2
>();
208 void alignment_test()
210 do_simple_benchmark
<misaligned_double
>();
211 do_simple_benchmark
<aligned_double
>();
215 template<class Effect
>
216 void get_default_effect_params(float params
[Effect::param_count
], uint32_t &sr
);
219 void get_default_effect_params
<synth::reverb_audio_module
>(float params
[3], uint32_t &sr
)
221 typedef synth::reverb_audio_module mod
;
222 params
[mod::par_decay
] = 4;
223 params
[mod::par_hfdamp
] = 2000;
224 params
[mod::par_amount
] = 2;
229 void get_default_effect_params
<synth::filter_audio_module
>(float params
[4], uint32_t &sr
)
231 typedef synth::filter_audio_module mod
;
232 params
[mod::par_cutoff
] = 500;
233 params
[mod::par_resonance
] = 3;
234 params
[mod::par_mode
] = 2;
235 params
[mod::par_inertia
] = 16;
240 void get_default_effect_params
<synth::flanger_audio_module
>(float params
[5], uint32_t &sr
)
242 typedef synth::flanger_audio_module mod
;
243 params
[mod::par_delay
] = 1;
244 params
[mod::par_depth
] = 2;
245 params
[mod::par_rate
] = 1;
246 params
[mod::par_fb
] = 0.9;
247 params
[mod::par_amount
] = 0.9;
251 template<class Effect
, unsigned int bufsize
= 256>
252 class effect_benchmark
: public empty_benchmark
<bufsize
>
256 float inputs
[Effect::in_count
][bufsize
];
257 float outputs
[Effect::out_count
][bufsize
];
259 float params
[Effect::param_count
];
263 for (int b
= 0; b
< Effect::out_count
; b
++)
265 effect
.outs
[b
] = outputs
[b
];
266 dsp::zero(outputs
[b
], bufsize
);
268 for (int b
= 0; b
< Effect::in_count
; b
++)
270 effect
.ins
[b
] = inputs
[b
];
271 for (unsigned int i
= 0; i
< bufsize
; i
++)
272 inputs
[b
][i
] = (float)(10 + i
*0.3f
*(b
+1));
274 for (int i
= 0; i
< Effect::param_count
; i
++)
275 effect
.params
[i
] = ¶ms
[i
];
276 ::get_default_effect_params
<Effect
>(params
, effect
.srate
);
282 effect
.params_changed();
283 effect
.process(0, bufsize
, 3, 3);
287 for (int b
= 0; b
< Effect::out_count
; b
++)
289 for (unsigned int i
= 0; i
< bufsize
; i
++)
290 result
+= outputs
[b
][i
];
297 dsp::do_simple_benchmark
<effect_benchmark
<synth::flanger_audio_module
> >(5, 10000);
298 dsp::do_simple_benchmark
<effect_benchmark
<synth::reverb_audio_module
> >(5, 1000);
299 dsp::do_simple_benchmark
<effect_benchmark
<synth::filter_audio_module
> >(5, 10000);
305 printf("Test temporarily removed due to refactoring\n");
310 enum { LEN
= 1048576 };
311 static float data
[2][LEN
];
313 for (int t
= 1; t
< 38; t
++)
315 dsp::reverb
<float> rvb
;
317 memset(data
, 0, sizeof(data
));
321 rvb
.set_cutoff(22000);
324 rvb
.set_fb(t
< 19 ? t
* 0.05 : 0.905 + (t
- 19) * 0.005);
326 for (int i
= 0; i
< LEN
; i
++)
327 rvb
.process(data
[0][i
], data
[1][i
]);
330 for (i
= LEN
- 1; i
> 0; i
--)
332 // printf("[%d]=%f\n", i, data[0][i]);
333 if (fabs(data
[0][i
]) < 0.001 && fabs(data
[1][i
]) < 0.001)
338 printf("%f\t%f\n", rvb
.get_fb(), i
/ 44100.0);
344 biquad_coeffs
<float> bqc
;
345 bqc
.set_lowshelf_rbj(2000, 2.0, 4.0, 10000);
346 for (int i
= 0; i
<= 5000; i
+= 100)
348 printf("%d %f\n", i
, bqc
.freq_gain(i
* 1.0, 10000));
352 void aweighting_calc()
357 for (int i
= 10; i
< 20000; i
+= 10)
359 printf("%d %f\n", i
, 20*log10(aw
.freq_gain(i
* 1.0, fs
)));
365 struct my_sink
: public osc_message_sink
<osc_strstream
>
368 osc_message_dump
<osc_strstream
, ostream
> dump
;
369 my_sink() : dump(cout
) {}
370 virtual void receive_osc_message(std::string address
, std::string type_tag
, osc_strstream
&buffer
)
372 dump
.receive_osc_message(address
, type_tag
, buffer
);
373 assert(address
== "/blah");
374 assert(type_tag
== "bsii");
379 buffer
>> blob
>> str
>> val1
>> val2
;
380 assert(blob
.data
== "123");
381 assert(str
== "test");
384 g_main_loop_quit(loop
);
391 string sdata
= string("\000\000\000\003123\000test\000\000\000\000\000\000\000\001\000\000\000\002", 24);
392 string_buffer
sb(sdata
);
393 osc_strstream
is(sb
);
394 osc_inline_typed_strstream os
;
399 is
>> blob
>> str
>> val1
>> val2
;
400 assert(blob
.data
== "123");
401 assert(str
== "test");
405 os
<< blob
<< str
<< val1
<< val2
;
406 assert(os
.buf_data
.data
== sdata
);
407 assert(os
.buf_types
.data
== "bsii");
409 GMainLoop
*main_loop
= g_main_loop_new(NULL
, FALSE
);
411 sink
.loop
= main_loop
;
414 srv
.bind("0.0.0.0", 4541);
417 cli
.bind("0.0.0.0", 0);
418 cli
.set_addr("0.0.0.0", 4541);
419 if (!cli
.send("/blah", os
))
421 g_error("Could not send the OSC message");
424 g_main_loop_run(main_loop
);
428 int main(int argc
, char *argv
[])
432 int c
= getopt_long(argc
, argv
, "u:hv", long_options
, &option_index
);
438 printf("Benchmark suite Calf plugin pack\nSyntax: %s [--help] [--version] [--unit biquad|alignment|effects]\n", argv
[0]);
441 printf("%s\n", PACKAGE_STRING
);
450 if (unit
&& !strcmp(unit
, "osc"))
454 if (!unit
|| !strcmp(unit
, "biquad"))
457 if (!unit
|| !strcmp(unit
, "alignment"))
460 if (!unit
|| !strcmp(unit
, "effects"))
463 if (unit
&& !strcmp(unit
, "reverbir"))
466 if (unit
&& !strcmp(unit
, "eq"))
469 if (unit
&& !strcmp(unit
, "aweighting"))