replace ::cast_dynamic() with relevant ActionManager::get_*_action() calls
[ardour.git] / tools / sfrtest.cc
1 /* g++ -o sfrtest sfrtest.cc `pkg-config --cflags --libs sndfile` `pkg-config --cflags --libs glibmm-2.4` */
2
3 #include <vector>
4 #include <iostream>
5 #include <iomanip>
6 #include <sstream>
7 #include <cstdlib>
8 #include <cerrno>
9
10 #include <unistd.h>
11 #include <sndfile.h>
12 #include <stdint.h>
13 #include <string.h>
14 #include <getopt.h>
15 #include <fcntl.h>
16
17 #include <glibmm/miscutils.h>
18 #include <glibmm/fileutils.h>
19
20 using namespace std;
21
22 SF_INFO format_info;
23 float* data = 0;
24 int
25 read_one (SNDFILE* sf, uint32_t nframes)
26 {
27         if (sf_read_float (sf, (float*) data, nframes) != nframes) {
28                 return -1;
29         }
30
31         if (with_sync) {
32                 sf_write_sync (sf);
33         }
34
35         return 0;
36 }
37
38 void
39 usage ()
40 {
41         cout << "sfrtest [ -n NFILES ] [ -b BLOCKSIZE ] [ -s ] [ -D ] filename-template" << endl;
42 }
43
44 int
45 main (int argc, char* argv[])
46 {
47         vector<SNDFILE*> sndfiles;
48         uint32_t sample_size = sizeof (float);
49         char optstring[] = "n:b:sD";
50         uint32_t block_size = 64 * 1024;
51         uint32_t nfiles = 100;
52         bool direct = false;
53         const struct option longopts[] = {
54                 { "nfiles", 1, 0, 'n' },
55                 { "blocksize", 1, 0, 'b' },
56                 { "direct", 0, 0, 'D' },
57                 { 0, 0, 0, 0 }
58         };
59
60         int option_index = 0;
61         int c = 0;
62         char const * name_template = 0;
63         int samplerate;
64
65         while (1) {
66                 if ((c = getopt_long (argc, argv, optstring, longopts, &option_index)) == -1) {
67                         break;
68                 }
69
70                 switch (c) {
71                 case 'n':
72                         nfiles = atoi (optarg);
73                         break;
74                 case 'b':
75                         block_size = atoi (optarg);
76                         break;
77                 case 'D':
78                         direct = true;
79                         break;
80                 default:
81                         usage ();
82                         return 0;
83                 }
84         }
85
86         if (optind < argc) {
87                 name_template = argv[optind];
88         } else {
89                 usage ();
90                 return 1;
91         }
92
93         for (uint32_t n = 1; n <= nfiles; ++n) {
94                 SNDFILE* sf;
95                 char path[PATH_MAX+1];
96
97                 snprintf (path, sizeof (path), name_template, n);
98
99                 if (!Glib::file_test (path, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_REGULAR)) {
100                         break;
101                 }
102
103                 int flags = O_RDONLY;
104                 int fd = open (path, flags, 0644);
105
106                 if (fd < 0) {
107                         cerr << "Could not open file #" << n << " @ " << path << " (" << strerror (errno) << ")" << endl;
108                         return 1;
109                 }
110
111 #ifdef __APPLE__
112                 if (direct) {
113                         /* Apple man pages say only that it returns "a value other than -1 on success",
114                            which probably means zero, but you just can't be too careful with
115                            those guys.
116                         */
117                         if (fcntl (fd, F_NOCACHE, 1) == -1) {
118                                 cerr << "Cannot set F_NOCACHE on file # " << n << endl;
119                         }
120                 }
121 #endif
122
123                 if ((sf = sf_open_fd (fd, SFM_READ, &format_info, true)) == 0) {
124                         cerr << "Could not open SNDFILE #" << n << " @ " << path << " (" << sf_strerror (0) << ")" << endl;
125                         return 1;
126                 }
127
128                 samplerate = format_info.samplerate;
129
130                 sndfiles.push_back (sf);
131         }
132
133         cout << "Discovered " << sndfiles.size() << " files using " << name_template << endl;
134
135         data = new float[block_size];
136         uint64_t read = 0;
137
138         while (true) {
139                 gint64 before;
140                 before = g_get_monotonic_time();
141                 for (vector<SNDFILE*>::iterator s = sndfiles.begin(); s != sndfiles.end(); ++s) {
142                         if (read_one (*s, block_size)) {
143                                 cerr << "Read failed for file #" << distance (sndfiles.begin(), s) << endl;
144                                 return 1;
145                         }
146                 }
147                 read += block_size;
148                 gint64 elapsed = g_get_monotonic_time() - before;
149                 double bandwidth = ((sndfiles.size() * block_size * sample_size)/1048576.0) / (elapsed/1000000.0);
150
151                 printf ("BW @ %Lu %.3f seconds bandwidth %.4f MB/sec\n", read, elapsed/1000000.0, bandwidth);
152         }
153
154         return 0;
155 }
156
157