replace ::cast_dynamic() with relevant ActionManager::get_*_action() calls
[ardour.git] / tools / jacktest.c
1 #include <stdio.h>
2 #include <errno.h>
3 #include <unistd.h>
4 #include <stdlib.h>
5 #include <string.h>
6
7 #include <jack/jack.h>
8
9 jack_port_t *input_port;
10 jack_port_t *output_port;
11 jack_client_t *client;
12 int loopsize = 25000;
13 int xrun_occurred = 0;
14 int consecutive_xruns = 0;
15 float first_xrun = 0.0f;
16 float last_load = 0.0f;
17 int at_loop = 0;
18 int at_loop_size;
19 char *thechunk;
20 int chunksize = 1024 * 1024 * 10;
21
22 void
23 fooey (jack_nframes_t n)
24 {
25         volatile int x;
26         thechunk[random()%chunksize] = n;
27 }
28
29 int
30 process (jack_nframes_t nframes, void *arg)
31 {
32         jack_default_audio_sample_t *in, *out;
33         int i;
34
35         in = jack_port_get_buffer (input_port, nframes);
36         out = jack_port_get_buffer (output_port, nframes);
37
38         memcpy (out, in, sizeof (jack_default_audio_sample_t) * nframes);
39
40         for (i = 0; i < loopsize; ++i) {
41                 fooey (nframes);
42         }
43
44         last_load = jack_cpu_load (client);
45
46         if ((at_loop += nframes) >= at_loop_size) {
47                 if (last_load < 25.0f) {
48                         loopsize *= 2;
49                 } else if (last_load < 50.0f) {
50                         loopsize = (int) (1.5 * loopsize);
51                 } else if (last_load < 90.0f) {
52                         loopsize += (int) (0.10 * loopsize);
53                 } else if (last_load < 95.0f) {
54                         loopsize += (int) (0.05 * loopsize);
55                 } else {
56                         loopsize += (int) (0.001 * loopsize);
57                 }
58                 at_loop = 0;
59                 printf ("loopsize = %d\n", loopsize);
60         }
61
62         if (xrun_occurred) {
63                 if (consecutive_xruns == 0) {
64                         first_xrun = last_load;
65                 }
66                 consecutive_xruns++;
67         }
68
69         xrun_occurred = 0;
70
71         if (consecutive_xruns >= 10) {
72                 fprintf (stderr, "Stopping with load = %f (first xrun at %f)\n", last_load, first_xrun);
73                 exit (0);
74         }
75
76         return 0;
77 }
78
79 /**
80  * JACK calls this shutdown_callback if the server ever shuts down or
81  * decides to disconnect the client.
82  */
83 void
84 jack_shutdown (void *arg)
85 {
86         fprintf (stderr, "shutdown with load = %f\n", last_load);
87         exit (1);
88 }
89
90 int
91 jack_xrun (void *arg)
92 {
93         fprintf (stderr, "xrun occurred with loop size = %d\n", loopsize);
94         xrun_occurred = 1;
95         return 0;
96 }
97
98 int
99 main (int argc, char *argv[])
100 {
101         const char **ports;
102         const char *client_name;
103         const char *server_name = NULL;
104         jack_options_t options = JackNullOption;
105         jack_status_t status;
106
107         client_name = "jacktester";
108         if (argc > 1) {
109                 chunksize = atoi (argv[1]);
110                 printf ("using chunksize of %d\n", chunksize);
111         }
112
113         /* open a client connection to the JACK server */
114
115         client = jack_client_open (client_name, options, &status, server_name);
116         if (client == NULL) {
117                 fprintf (stderr, "jack_client_open() failed, status = 0x%x\n",
118                          status);
119                 if (status & JackServerFailed) {
120                         fprintf (stderr, "Unable to connect to JACK server\n");
121                 }
122                 exit (1);
123         }
124         if (status & JackServerStarted) {
125                 fprintf (stderr, "JACK server started\n");
126         }
127         if (status & JackNameNotUnique) {
128                 client_name = jack_get_client_name(client);
129                 fprintf (stderr, "unique name `%s' assigned\n", client_name);
130         }
131
132         /* tell the JACK server to call `process()' whenever
133            there is work to be done.
134         */
135
136         jack_set_process_callback (client, process, 0);
137         jack_set_xrun_callback (client, jack_xrun, 0);
138         jack_on_shutdown (client, jack_shutdown, 0);
139
140         /* create two ports */
141
142         input_port = jack_port_register (client, "input",
143                                          JACK_DEFAULT_AUDIO_TYPE,
144                                          JackPortIsInput, 0);
145         output_port = jack_port_register (client, "output",
146                                           JACK_DEFAULT_AUDIO_TYPE,
147                                           JackPortIsOutput, 0);
148
149         if ((input_port == NULL) || (output_port == NULL)) {
150                 fprintf(stderr, "no more JACK ports available\n");
151                 exit (1);
152         }
153
154         at_loop_size = jack_get_sample_rate (client) * 2;
155         if ((thechunk = (char *) malloc (chunksize)) == NULL) {
156                 fprintf (stderr, "cannot allocate chunk\n");
157                 exit (1);
158         }
159
160         /* Tell the JACK server that we are ready to roll.  Our
161          * process() callback will start running now. */
162
163         if (jack_activate (client)) {
164                 fprintf (stderr, "cannot activate client");
165                 exit (1);
166         }
167
168         /* connect the ports. Note: you can't do this before the
169            client is activated, because we can't allow connections to
170            be made to clients that aren't running.
171         */
172
173         ports = jack_get_ports (client, NULL, NULL,
174                                 JackPortIsPhysical|JackPortIsOutput);
175         if (ports == NULL) {
176                 fprintf(stderr, "no physical capture ports\n");
177                 exit (1);
178         }
179
180         if (jack_connect (client, ports[0], jack_port_name (input_port))) {
181                 fprintf (stderr, "cannot connect input ports\n");
182         }
183
184         free (ports);
185
186         ports = jack_get_ports (client, NULL, NULL,
187                                 JackPortIsPhysical|JackPortIsInput);
188         if (ports == NULL) {
189                 fprintf(stderr, "no physical playback ports\n");
190                 exit (1);
191         }
192
193         if (jack_connect (client, jack_port_name (output_port), ports[0])) {
194                 fprintf (stderr, "cannot connect output ports\n");
195         }
196
197         free (ports);
198
199         while (1) {
200                 sleep (1);
201         }
202
203         jack_client_close (client);
204         exit (0);
205 }