2 Copyright (C) 2005 Samuel TRACOL
3 Copyright (C) 2008 Grame
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (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
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 * @brief This client test the capacity for jackd to kick out a to heavy cpu client.
33 #include <jack/jack.h>
35 jack_port_t
*input_port
;
36 jack_port_t
*output_port
;
37 jack_client_t
*client
;
39 jack_nframes_t idle_time
= 0;
42 int time_before_run
= 0;
43 int time_before_exit
= 1;
44 jack_nframes_t cur_buffer_size
;
46 /* a simple state machine for this client */
51 } client_state
= Init
;
57 " [ --name OR -n client_name ]\n"
58 " [ --time OR -t time_to_run (in seconds) ]\n"
59 " [ --delay OR -d delay_before_cpuload__is_applied (in seconds) ]\n"
60 " --cpu OR -c percent_cpu_load (1-99)\n"
64 int update_buffer_size(jack_nframes_t nframes
, void *arg
)
66 cur_buffer_size
= nframes
;
67 printf("Buffer size = %d \n", cur_buffer_size
);
68 idle_time
= (jack_nframes_t
) (cur_buffer_size
* percent_cpu
/ 100);
69 printf("CPU load applies as %d sample delay.\n", idle_time
);
74 * The process callback for this JACK application is called in a
75 * special realtime thread once for each audio cycle.
79 int process(jack_nframes_t nframes
, void *arg
)
81 jack_default_audio_sample_t
*in
, *out
;
82 jack_nframes_t start_frame
= jack_frame_time(client
);
84 in
= (jack_default_audio_sample_t
*) jack_port_get_buffer (input_port
, nframes
);
85 out
= (jack_default_audio_sample_t
*) jack_port_get_buffer (output_port
, nframes
);
86 memset(out
, 0, sizeof (jack_default_audio_sample_t
) * nframes
);
88 while ((client_state
== Run
) && (jack_frame_time(client
) < (start_frame
+ idle_time
))) {}
93 * JACK calls this shutdown_callback if the server ever shuts down or
94 * decides to disconnect the client.
97 void jack_shutdown(void *arg
)
99 fprintf(stderr
, "JACK shut down, exiting ...\n");
103 int main(int argc
, char *argv
[])
106 const char *client_name
;
108 jack_status_t status
;
112 const char *options
= "t:t:d:c:";
113 struct option long_options
[] =
117 {"delay", 1, 0, 'd'},
122 client_name
= "jack-cpu";
123 while ((opt
= getopt_long (argc
, argv
, options
, long_options
, &option_index
)) != EOF
) {
126 client_name
= optarg
;
129 time_to_run
= atoi(optarg
);
132 time_before_run
= atoi(optarg
);
135 percent_cpu
= atoi(optarg
);
139 fprintf(stderr
, "unknown option %c\n", opt
);
145 fprintf(stderr
, "CPU load not specified ! See usage as following :\n");
150 if (time_to_run
!= 0)
151 printf("Running jack-cpu for %d seconds...\n", time_to_run
);
153 /* open a client connection to the JACK server */
155 client
= jack_client_open (client_name
, JackNoStartServer
, &status
);
157 if (client
== NULL
) {
158 fprintf(stderr
, "jack_client_open() failed : is jack server running ?\n");
162 cur_buffer_size
= jack_get_buffer_size(client
);
163 printf("engine buffer size = %d \n", cur_buffer_size
);
164 printf("engine sample rate: %d Hz\n", jack_get_sample_rate(client
));
165 idle_time
= (jack_nframes_t
) (cur_buffer_size
* percent_cpu
/ 100);
166 printf("CPU load applies as %d sample delay.\n", idle_time
);
168 /* tell the JACK server to call `process()' whenever
169 there is work to be done.
172 jack_set_process_callback(client
, process
, 0);
174 /* tell the JACK server to call `jack_shutdown()' if
175 it ever shuts down, either entirely, or if it
176 just decides to stop calling us.
179 jack_on_shutdown(client
, jack_shutdown
, 0);
181 /* create two ports */
183 input_port
= jack_port_register (client
, "input", JACK_DEFAULT_AUDIO_TYPE
, JackPortIsInput
, 0);
184 output_port
= jack_port_register (client
, "output", JACK_DEFAULT_AUDIO_TYPE
, JackPortIsOutput
, 0);
186 printf("registering ports...\n");
187 if ((input_port
== NULL
) || (output_port
== NULL
)) {
188 fprintf(stderr
, "no more JACK ports available\n");
192 if (jack_set_buffer_size_callback(client
, update_buffer_size
, 0) != 0) {
193 printf("Error when calling buffer_size_callback !");
197 /* Tell the JACK server that we are ready to roll. Our
198 * process() callback will start running now. */
200 printf("Activating as jackd client...\n");
201 if (jack_activate(client
)) {
202 fprintf(stderr
, "cannot activate client");
206 /* Connect the ports. You can't do this before the client is
207 * activated, because we can't make connections to clients
208 * that aren't running. Note the confusing (but necessary)
209 * orientation of the driver backend ports: playback ports are
210 * "input" to the backend, and capture ports are "output" from
214 ports
= jack_get_ports (client
, NULL
, NULL
, JackPortIsPhysical
|JackPortIsOutput
);
216 fprintf(stderr
, "no physical capture ports\n");
220 if (jack_connect(client
, ports
[0], jack_port_name(input_port
))) {
221 fprintf (stderr
, "cannot connect input ports\n");
225 ports
= jack_get_ports (client
, NULL
, NULL
, JackPortIsPhysical
|JackPortIsInput
);
227 fprintf(stderr
, "no physical playback ports\n");
231 if (jack_connect(client
, jack_port_name (output_port
), ports
[0])) {
232 fprintf(stderr
, "cannot connect output ports\n");
236 if (time_before_run
== 0) {
238 printf("Activating cpu load...\n");
242 time_before_exit
= time_to_run
+ time_before_run
;
244 while (client_state
!= Exit
) {
245 if ((time_before_run
> 0) && (client_state
== Init
))
248 if ((time_before_run
< 1) && (client_state
!= Run
)) {
250 printf("Activating cpu load...\n");
252 if (time_to_run
!= 0)
254 if (time_before_exit
< 1)
257 jack_client_close(client
);
258 printf("Exiting after a %d seconds run.\n", time_to_run
);