Mercurial > hg > sv-dependency-builds
comparison src/libsndfile-1.0.25/tests/benchmark.c @ 0:c7265573341e
Import initial set of sources
author | Chris Cannam |
---|---|
date | Mon, 18 Mar 2013 14:12:14 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:c7265573341e |
---|---|
1 /* | |
2 ** Copyright (C) 2002-2011 Erik de Castro Lopo <erikd@mega-nerd.com> | |
3 ** | |
4 ** This program is free software; you can redistribute it and/or modify | |
5 ** it under the terms of the GNU General Public License as published by | |
6 ** the Free Software Foundation; either version 2 of the License, or | |
7 ** (at your option) any later version. | |
8 ** | |
9 ** This program is distributed in the hope that it will be useful, | |
10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 ** GNU General Public License for more details. | |
13 ** | |
14 ** You should have received a copy of the GNU General Public License | |
15 ** along with this program; if not, write to the Free Software | |
16 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
17 */ | |
18 | |
19 #include "sfconfig.h" | |
20 | |
21 #include <stdio.h> | |
22 #include <stdlib.h> | |
23 | |
24 #if HAVE_UNISTD_H | |
25 #include <unistd.h> | |
26 #endif | |
27 | |
28 #if (HAVE_DECL_S_IRGRP == 0) | |
29 #include <sf_unistd.h> | |
30 #endif | |
31 | |
32 #include <string.h> | |
33 #include <math.h> | |
34 #include <time.h> | |
35 #include <fcntl.h> | |
36 #include <sys/stat.h> | |
37 | |
38 #include <sndfile.h> | |
39 | |
40 #ifndef M_PI | |
41 #define M_PI 3.14159265358979323846264338 | |
42 #endif | |
43 | |
44 /* | |
45 ** Neat solution to the Win32/OS2 binary file flage requirement. | |
46 ** If O_BINARY isn't already defined by the inclusion of the system | |
47 ** headers, set it to zero. | |
48 */ | |
49 #ifndef O_BINARY | |
50 #define O_BINARY 0 | |
51 #endif | |
52 | |
53 #define WRITE_FLAGS (O_WRONLY | O_CREAT | O_TRUNC | O_BINARY) | |
54 #define READ_FLAGS (O_RDONLY | O_BINARY) | |
55 | |
56 #if (defined (WIN32) || defined (_WIN32) || defined (__OS2__)) | |
57 #define WRITE_PERMS 0777 | |
58 #else | |
59 #define WRITE_PERMS (S_IRUSR | S_IWUSR | S_IRGRP) | |
60 #endif | |
61 | |
62 #define BUFFER_SIZE (1<<18) | |
63 #define BLOCK_COUNT (30) | |
64 #define TEST_DURATION (5) /* 5 Seconds. */ | |
65 | |
66 typedef struct | |
67 { double write_rate ; | |
68 double read_rate ; | |
69 } PERF_STATS ; | |
70 | |
71 static void *data = NULL ; | |
72 | |
73 static void calc_raw_performance (PERF_STATS *stats) ; | |
74 | |
75 static void calc_short_performance (int format, double read_rate, double write_rate) ; | |
76 static void calc_int_performance (int format, double read_rate, double write_rate) ; | |
77 static void calc_float_performance (int format, double read_rate, double write_rate) ; | |
78 | |
79 | |
80 static int cpu_is_big_endian (void) ; | |
81 | |
82 static const char* get_subtype_str (int subtype) ; | |
83 | |
84 int | |
85 main (int argc, char *argv []) | |
86 { PERF_STATS stats ; | |
87 char buffer [256] = "Benchmarking " ; | |
88 int format_major ; | |
89 | |
90 if (! (data = malloc (BUFFER_SIZE * sizeof (double)))) | |
91 { perror ("Error : malloc failed") ; | |
92 exit (1) ; | |
93 } ; | |
94 | |
95 sf_command (NULL, SFC_GET_LIB_VERSION, buffer + strlen (buffer), sizeof (buffer) - strlen (buffer)) ; | |
96 | |
97 puts (buffer) ; | |
98 memset (buffer, '-', strlen (buffer)) ; | |
99 puts (buffer) ; | |
100 printf ("Each test takes a little over %d seconds.\n\n", TEST_DURATION) ; | |
101 | |
102 calc_raw_performance (&stats) ; | |
103 | |
104 if (argc < 2 || strcmp ("--native-only", argv [1]) == 0) | |
105 { puts ("\nNative endian I/O :") ; | |
106 format_major = cpu_is_big_endian () ? SF_FORMAT_AIFF : SF_FORMAT_WAV ; | |
107 | |
108 calc_short_performance (format_major | SF_FORMAT_PCM_16, stats.read_rate, stats.write_rate) ; | |
109 calc_int_performance (format_major | SF_FORMAT_PCM_24, stats.read_rate, stats.write_rate) ; | |
110 calc_int_performance (format_major | SF_FORMAT_PCM_32, stats.read_rate, stats.write_rate) ; | |
111 calc_float_performance (format_major | SF_FORMAT_PCM_16, stats.read_rate, stats.write_rate) ; | |
112 calc_float_performance (format_major | SF_FORMAT_PCM_24, stats.read_rate, stats.write_rate) ; | |
113 calc_float_performance (format_major | SF_FORMAT_PCM_32, stats.read_rate, stats.write_rate) ; | |
114 calc_float_performance (format_major | SF_FORMAT_FLOAT , stats.read_rate, stats.write_rate) ; | |
115 } ; | |
116 | |
117 if (argc < 2 || strcmp ("--swap-only", argv [1]) == 0) | |
118 { puts ("\nEndian swapped I/O :") ; | |
119 format_major = cpu_is_big_endian () ? SF_FORMAT_WAV : SF_FORMAT_AIFF ; | |
120 | |
121 calc_short_performance (format_major | SF_FORMAT_PCM_16, stats.read_rate, stats.write_rate) ; | |
122 calc_int_performance (format_major | SF_FORMAT_PCM_24, stats.read_rate, stats.write_rate) ; | |
123 calc_int_performance (format_major | SF_FORMAT_PCM_32, stats.read_rate, stats.write_rate) ; | |
124 calc_float_performance (format_major | SF_FORMAT_PCM_16, stats.read_rate, stats.write_rate) ; | |
125 calc_float_performance (format_major | SF_FORMAT_PCM_24, stats.read_rate, stats.write_rate) ; | |
126 calc_float_performance (format_major | SF_FORMAT_PCM_32, stats.read_rate, stats.write_rate) ; | |
127 calc_float_performance (format_major | SF_FORMAT_FLOAT , stats.read_rate, stats.write_rate) ; | |
128 } ; | |
129 | |
130 puts ("") ; | |
131 | |
132 free (data) ; | |
133 | |
134 return 0 ; | |
135 } /* main */ | |
136 | |
137 /*============================================================================== | |
138 */ | |
139 | |
140 static void | |
141 calc_raw_performance (PERF_STATS *stats) | |
142 { clock_t start_clock, clock_time ; | |
143 int fd, k, byte_count, retval, op_count ; | |
144 const char *filename ; | |
145 | |
146 filename = "benchmark.dat" ; | |
147 | |
148 byte_count = BUFFER_SIZE * sizeof (short) ; | |
149 | |
150 /* Collect write stats */ | |
151 printf (" Raw write PCM_16 : ") ; | |
152 fflush (stdout) ; | |
153 | |
154 clock_time = 0 ; | |
155 op_count = 0 ; | |
156 start_clock = clock () ; | |
157 | |
158 while (clock_time < (CLOCKS_PER_SEC * TEST_DURATION)) | |
159 { if ((fd = open (filename, WRITE_FLAGS, WRITE_PERMS)) < 0) | |
160 { printf ("Error : not able to open file : %s\n", filename) ; | |
161 perror ("") ; | |
162 exit (1) ; | |
163 } ; | |
164 | |
165 for (k = 0 ; k < BLOCK_COUNT ; k++) | |
166 { if ((retval = write (fd, data, byte_count)) != byte_count) | |
167 { printf ("Error : write returned %d (should have been %d)\n", retval, byte_count) ; | |
168 exit (1) ; | |
169 } ; | |
170 } ; | |
171 | |
172 close (fd) ; | |
173 | |
174 clock_time = clock () - start_clock ; | |
175 op_count ++ ; | |
176 } ; | |
177 | |
178 stats->write_rate = (1.0 * BUFFER_SIZE) * BLOCK_COUNT * op_count ; | |
179 stats->write_rate *= (1.0 * CLOCKS_PER_SEC) / clock_time ; | |
180 printf ("%10.0f samples per sec\n", stats->write_rate) ; | |
181 | |
182 /* Collect read stats */ | |
183 printf (" Raw read PCM_16 : ") ; | |
184 fflush (stdout) ; | |
185 | |
186 clock_time = 0 ; | |
187 op_count = 0 ; | |
188 start_clock = clock () ; | |
189 | |
190 while (clock_time < (CLOCKS_PER_SEC * TEST_DURATION)) | |
191 { if ((fd = open (filename, READ_FLAGS)) < 0) | |
192 { printf ("Error : not able to open file : %s\n", filename) ; | |
193 perror ("") ; | |
194 exit (1) ; | |
195 } ; | |
196 | |
197 for (k = 0 ; k < BLOCK_COUNT ; k++) | |
198 { if ((retval = read (fd, data, byte_count)) != byte_count) | |
199 { printf ("Error : write returned %d (should have been %d)\n", retval, byte_count) ; | |
200 exit (1) ; | |
201 } ; | |
202 } ; | |
203 | |
204 close (fd) ; | |
205 | |
206 clock_time = clock () - start_clock ; | |
207 op_count ++ ; | |
208 } ; | |
209 | |
210 stats->read_rate = (1.0 * BUFFER_SIZE) * BLOCK_COUNT * op_count ; | |
211 stats->read_rate *= (1.0 * CLOCKS_PER_SEC) / clock_time ; | |
212 printf ("%10.0f samples per sec\n", stats->read_rate) ; | |
213 | |
214 unlink (filename) ; | |
215 } /* calc_raw_performance */ | |
216 | |
217 /*------------------------------------------------------------------------------ | |
218 */ | |
219 | |
220 static void | |
221 calc_short_performance (int format, double read_rate, double write_rate) | |
222 { SNDFILE *file ; | |
223 SF_INFO sfinfo ; | |
224 clock_t start_clock, clock_time ; | |
225 double performance ; | |
226 int k, item_count, retval, op_count ; | |
227 const char* subtype ; | |
228 short *short_data ; | |
229 const char *filename ; | |
230 | |
231 filename = "benchmark.dat" ; | |
232 subtype = get_subtype_str (format & SF_FORMAT_SUBMASK) ; | |
233 | |
234 short_data = data ; | |
235 item_count = BUFFER_SIZE ; | |
236 for (k = 0 ; k < item_count ; k++) | |
237 short_data [k] = 32700.0 * sin (2 * M_PI * k / 32000.0) ; | |
238 | |
239 /* Collect write stats */ | |
240 printf (" Write %-5s to %s : ", "short", subtype) ; | |
241 fflush (stdout) ; | |
242 | |
243 sfinfo.channels = 1 ; | |
244 sfinfo.format = format ; | |
245 sfinfo.frames = 1 ; | |
246 sfinfo.samplerate = 32000 ; | |
247 | |
248 clock_time = 0 ; | |
249 op_count = 0 ; | |
250 start_clock = clock () ; | |
251 | |
252 while (clock_time < (CLOCKS_PER_SEC * TEST_DURATION)) | |
253 { if (! (file = sf_open (filename, SFM_WRITE, &sfinfo))) | |
254 { printf ("Error : not able to open file : %s\n", filename) ; | |
255 perror ("") ; | |
256 exit (1) ; | |
257 } ; | |
258 | |
259 /* Turn off the addition of a PEAK chunk. */ | |
260 sf_command (file, SFC_SET_ADD_PEAK_CHUNK, NULL, SF_FALSE) ; | |
261 | |
262 for (k = 0 ; k < BLOCK_COUNT ; k++) | |
263 { if ((retval = sf_write_short (file, short_data, item_count)) != item_count) | |
264 { printf ("Error : sf_write_short returned %d (should have been %d)\n", retval, item_count) ; | |
265 exit (1) ; | |
266 } ; | |
267 } ; | |
268 | |
269 sf_close (file) ; | |
270 | |
271 clock_time = clock () - start_clock ; | |
272 op_count ++ ; | |
273 } ; | |
274 | |
275 performance = (1.0 * BUFFER_SIZE) * BLOCK_COUNT * op_count ; | |
276 performance *= (1.0 * CLOCKS_PER_SEC) / clock_time ; | |
277 printf ("%6.2f%% of raw write\n", 100.0 * performance / write_rate) ; | |
278 | |
279 /* Collect read stats */ | |
280 printf (" Read %-5s from %s : ", "short", subtype) ; | |
281 fflush (stdout) ; | |
282 | |
283 clock_time = 0 ; | |
284 op_count = 0 ; | |
285 start_clock = clock () ; | |
286 | |
287 while (clock_time < (CLOCKS_PER_SEC * TEST_DURATION)) | |
288 { if (! (file = sf_open (filename, SFM_READ, &sfinfo))) | |
289 { printf ("Error : not able to open file : %s\n", filename) ; | |
290 perror ("") ; | |
291 exit (1) ; | |
292 } ; | |
293 | |
294 for (k = 0 ; k < BLOCK_COUNT ; k++) | |
295 { if ((retval = sf_read_short (file, short_data, item_count)) != item_count) | |
296 { printf ("Error : write returned %d (should have been %d)\n", retval, item_count) ; | |
297 exit (1) ; | |
298 } ; | |
299 } ; | |
300 | |
301 sf_close (file) ; | |
302 | |
303 clock_time = clock () - start_clock ; | |
304 op_count ++ ; | |
305 } ; | |
306 | |
307 performance = (1.0 * item_count) * BLOCK_COUNT * op_count ; | |
308 performance *= (1.0 * CLOCKS_PER_SEC) / clock_time ; | |
309 printf ("%6.2f%% of raw read\n", 100.0 * performance / read_rate) ; | |
310 | |
311 unlink (filename) ; | |
312 | |
313 } /* calc_short_performance */ | |
314 static void | |
315 calc_int_performance (int format, double read_rate, double write_rate) | |
316 { SNDFILE *file ; | |
317 SF_INFO sfinfo ; | |
318 clock_t start_clock, clock_time ; | |
319 double performance ; | |
320 int k, item_count, retval, op_count ; | |
321 const char* subtype ; | |
322 int *int_data ; | |
323 const char *filename ; | |
324 | |
325 filename = "benchmark.dat" ; | |
326 subtype = get_subtype_str (format & SF_FORMAT_SUBMASK) ; | |
327 | |
328 int_data = data ; | |
329 item_count = BUFFER_SIZE ; | |
330 for (k = 0 ; k < item_count ; k++) | |
331 int_data [k] = 32700.0 * (1<<16) * sin (2 * M_PI * k / 32000.0) ; | |
332 | |
333 /* Collect write stats */ | |
334 printf (" Write %-5s to %s : ", "int", subtype) ; | |
335 fflush (stdout) ; | |
336 | |
337 sfinfo.channels = 1 ; | |
338 sfinfo.format = format ; | |
339 sfinfo.frames = 1 ; | |
340 sfinfo.samplerate = 32000 ; | |
341 | |
342 clock_time = 0 ; | |
343 op_count = 0 ; | |
344 start_clock = clock () ; | |
345 | |
346 while (clock_time < (CLOCKS_PER_SEC * TEST_DURATION)) | |
347 { if (! (file = sf_open (filename, SFM_WRITE, &sfinfo))) | |
348 { printf ("Error : not able to open file : %s\n", filename) ; | |
349 perror ("") ; | |
350 exit (1) ; | |
351 } ; | |
352 | |
353 /* Turn off the addition of a PEAK chunk. */ | |
354 sf_command (file, SFC_SET_ADD_PEAK_CHUNK, NULL, SF_FALSE) ; | |
355 | |
356 for (k = 0 ; k < BLOCK_COUNT ; k++) | |
357 { if ((retval = sf_write_int (file, int_data, item_count)) != item_count) | |
358 { printf ("Error : sf_write_short returned %d (should have been %d)\n", retval, item_count) ; | |
359 exit (1) ; | |
360 } ; | |
361 } ; | |
362 | |
363 sf_close (file) ; | |
364 | |
365 clock_time = clock () - start_clock ; | |
366 op_count ++ ; | |
367 } ; | |
368 | |
369 performance = (1.0 * BUFFER_SIZE) * BLOCK_COUNT * op_count ; | |
370 performance *= (1.0 * CLOCKS_PER_SEC) / clock_time ; | |
371 printf ("%6.2f%% of raw write\n", 100.0 * performance / write_rate) ; | |
372 | |
373 /* Collect read stats */ | |
374 printf (" Read %-5s from %s : ", "int", subtype) ; | |
375 fflush (stdout) ; | |
376 | |
377 clock_time = 0 ; | |
378 op_count = 0 ; | |
379 start_clock = clock () ; | |
380 | |
381 while (clock_time < (CLOCKS_PER_SEC * TEST_DURATION)) | |
382 { if (! (file = sf_open (filename, SFM_READ, &sfinfo))) | |
383 { printf ("Error : not able to open file : %s\n", filename) ; | |
384 perror ("") ; | |
385 exit (1) ; | |
386 } ; | |
387 | |
388 for (k = 0 ; k < BLOCK_COUNT ; k++) | |
389 { if ((retval = sf_read_int (file, int_data, item_count)) != item_count) | |
390 { printf ("Error : write returned %d (should have been %d)\n", retval, item_count) ; | |
391 exit (1) ; | |
392 } ; | |
393 } ; | |
394 | |
395 sf_close (file) ; | |
396 | |
397 clock_time = clock () - start_clock ; | |
398 op_count ++ ; | |
399 } ; | |
400 | |
401 performance = (1.0 * item_count) * BLOCK_COUNT * op_count ; | |
402 performance *= (1.0 * CLOCKS_PER_SEC) / clock_time ; | |
403 printf ("%6.2f%% of raw read\n", 100.0 * performance / read_rate) ; | |
404 | |
405 unlink (filename) ; | |
406 | |
407 } /* calc_int_performance */ | |
408 static void | |
409 calc_float_performance (int format, double read_rate, double write_rate) | |
410 { SNDFILE *file ; | |
411 SF_INFO sfinfo ; | |
412 clock_t start_clock, clock_time ; | |
413 double performance ; | |
414 int k, item_count, retval, op_count ; | |
415 const char* subtype ; | |
416 float *float_data ; | |
417 const char *filename ; | |
418 | |
419 filename = "benchmark.dat" ; | |
420 subtype = get_subtype_str (format & SF_FORMAT_SUBMASK) ; | |
421 | |
422 float_data = data ; | |
423 item_count = BUFFER_SIZE ; | |
424 for (k = 0 ; k < item_count ; k++) | |
425 float_data [k] = 1.0 * sin (2 * M_PI * k / 32000.0) ; | |
426 | |
427 /* Collect write stats */ | |
428 printf (" Write %-5s to %s : ", "float", subtype) ; | |
429 fflush (stdout) ; | |
430 | |
431 sfinfo.channels = 1 ; | |
432 sfinfo.format = format ; | |
433 sfinfo.frames = 1 ; | |
434 sfinfo.samplerate = 32000 ; | |
435 | |
436 clock_time = 0 ; | |
437 op_count = 0 ; | |
438 start_clock = clock () ; | |
439 | |
440 while (clock_time < (CLOCKS_PER_SEC * TEST_DURATION)) | |
441 { if (! (file = sf_open (filename, SFM_WRITE, &sfinfo))) | |
442 { printf ("Error : not able to open file : %s\n", filename) ; | |
443 perror ("") ; | |
444 exit (1) ; | |
445 } ; | |
446 | |
447 /* Turn off the addition of a PEAK chunk. */ | |
448 sf_command (file, SFC_SET_ADD_PEAK_CHUNK, NULL, SF_FALSE) ; | |
449 | |
450 for (k = 0 ; k < BLOCK_COUNT ; k++) | |
451 { if ((retval = sf_write_float (file, float_data, item_count)) != item_count) | |
452 { printf ("Error : sf_write_short returned %d (should have been %d)\n", retval, item_count) ; | |
453 exit (1) ; | |
454 } ; | |
455 } ; | |
456 | |
457 sf_close (file) ; | |
458 | |
459 clock_time = clock () - start_clock ; | |
460 op_count ++ ; | |
461 } ; | |
462 | |
463 performance = (1.0 * BUFFER_SIZE) * BLOCK_COUNT * op_count ; | |
464 performance *= (1.0 * CLOCKS_PER_SEC) / clock_time ; | |
465 printf ("%6.2f%% of raw write\n", 100.0 * performance / write_rate) ; | |
466 | |
467 /* Collect read stats */ | |
468 printf (" Read %-5s from %s : ", "float", subtype) ; | |
469 fflush (stdout) ; | |
470 | |
471 clock_time = 0 ; | |
472 op_count = 0 ; | |
473 start_clock = clock () ; | |
474 | |
475 while (clock_time < (CLOCKS_PER_SEC * TEST_DURATION)) | |
476 { if (! (file = sf_open (filename, SFM_READ, &sfinfo))) | |
477 { printf ("Error : not able to open file : %s\n", filename) ; | |
478 perror ("") ; | |
479 exit (1) ; | |
480 } ; | |
481 | |
482 for (k = 0 ; k < BLOCK_COUNT ; k++) | |
483 { if ((retval = sf_read_float (file, float_data, item_count)) != item_count) | |
484 { printf ("Error : write returned %d (should have been %d)\n", retval, item_count) ; | |
485 exit (1) ; | |
486 } ; | |
487 } ; | |
488 | |
489 sf_close (file) ; | |
490 | |
491 clock_time = clock () - start_clock ; | |
492 op_count ++ ; | |
493 } ; | |
494 | |
495 performance = (1.0 * item_count) * BLOCK_COUNT * op_count ; | |
496 performance *= (1.0 * CLOCKS_PER_SEC) / clock_time ; | |
497 printf ("%6.2f%% of raw read\n", 100.0 * performance / read_rate) ; | |
498 | |
499 unlink (filename) ; | |
500 | |
501 } /* calc_float_performance */ | |
502 | |
503 | |
504 /*============================================================================== | |
505 */ | |
506 | |
507 static int | |
508 cpu_is_big_endian (void) | |
509 { unsigned char *cptr ; | |
510 int endtest ; | |
511 | |
512 endtest = 0x12345678 ; | |
513 | |
514 cptr = (unsigned char*) (&endtest) ; | |
515 | |
516 if (cptr [0] == 0x12 && cptr [1] == 0x34 && cptr [3] == 0x78) | |
517 return SF_TRUE ; | |
518 | |
519 return SF_FALSE ; | |
520 } /* cpu_is_big_endian */ | |
521 | |
522 static const char* | |
523 get_subtype_str (int subtype) | |
524 { switch (subtype) | |
525 { case SF_FORMAT_PCM_16 : | |
526 return "PCM_16" ; | |
527 | |
528 case SF_FORMAT_PCM_24 : | |
529 return "PCM_24" ; | |
530 | |
531 case SF_FORMAT_PCM_32 : | |
532 return "PCM_32" ; | |
533 | |
534 case SF_FORMAT_FLOAT : | |
535 return "FLOAT " ; | |
536 | |
537 case SF_FORMAT_DOUBLE : | |
538 return "DOUBLE" ; | |
539 | |
540 default : break ; | |
541 } ; | |
542 | |
543 return "UNKNOWN" ; | |
544 } /* get_subtype_str */ | |
545 |