]>
Commit | Line | Data |
---|---|---|
8cabb16f MB |
1 | /* |
2 | * jack output driver. This file is part of Shairport Sync. | |
3 | * Copyright (c) 2018 Mike Brady <mikebrady@iercom.net> | |
4 | * | |
5 | * All rights reserved. | |
6 | * | |
7 | * Permission to use, copy, modify, and distribute this software for any | |
8 | * purpose with or without fee is hereby granted, provided that the above | |
9 | * copyright notice and this permission notice appear in all copies. | |
10 | * | |
11 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
12 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
13 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
14 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
15 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
16 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
17 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
18 | */ | |
19 | ||
20 | #include "audio.h" | |
21 | #include "common.h" | |
22 | #include <errno.h> | |
23 | #include <getopt.h> | |
24 | #include <limits.h> | |
25 | #include <math.h> | |
26 | #include <pthread.h> | |
27 | #include <stdio.h> | |
28 | #include <stdlib.h> | |
29 | #include <string.h> | |
8cabb16f MB |
30 | #include <unistd.h> |
31 | ||
32 | #include <jack/jack.h> | |
33 | #include <jack/transport.h> | |
f07c16a6 | 34 | #include <jack/ringbuffer.h> |
8cabb16f MB |
35 | |
36 | enum ift_type { | |
37 | IFT_frame_left_sample = 0, | |
38 | IFT_frame_right_sample, | |
39 | } ift_type; | |
40 | ||
e99837f8 JN |
41 | // Two-channel, 16bit audio: |
42 | static const int bytes_per_frame = 4; | |
8cabb16f | 43 | // Four seconds buffer -- should be plenty |
e99837f8 | 44 | #define buffer_size 44100 * 4 * bytes_per_frame |
8cabb16f MB |
45 | |
46 | static pthread_mutex_t buffer_mutex = PTHREAD_MUTEX_INITIALIZER; | |
6c6dda9c | 47 | static pthread_mutex_t client_mutex = PTHREAD_MUTEX_INITIALIZER; |
8cabb16f | 48 | |
e99837f8 | 49 | /* |
8cabb16f | 50 | char *audio_lmb, *audio_umb, *audio_toq, *audio_eoq; |
e99837f8 | 51 | |
8cabb16f MB |
52 | size_t audio_occupancy; // this is in frames, not bytes. A frame is a left and |
53 | // right sample, each 16 bits, hence 4 bytes | |
e99837f8 | 54 | */ |
6c6dda9c MB |
55 | pthread_t *open_client_if_necessary_thread = NULL; |
56 | ||
c1d5815c | 57 | int jack_init(int, char **); |
959aa08b | 58 | void jack_deinit(void); |
8cabb16f MB |
59 | void jack_start(int, int); |
60 | int play(void *, int); | |
61 | void jack_stop(void); | |
62 | int jack_is_running(void); | |
8cabb16f MB |
63 | int jack_delay(long *); |
64 | void jack_flush(void); | |
65 | ||
66 | audio_output audio_jack = {.name = "jack", | |
67 | .help = NULL, | |
c1d5815c | 68 | .init = &jack_init, |
959aa08b | 69 | .deinit = &jack_deinit, |
8cabb16f MB |
70 | .start = &jack_start, |
71 | .stop = &jack_stop, | |
72 | .is_running = &jack_is_running, | |
73 | .flush = &jack_flush, | |
74 | .delay = &jack_delay, | |
75 | .play = &play, | |
76 | .volume = NULL, | |
77 | .parameters = NULL, | |
78 | .mute = NULL}; | |
79 | ||
8cabb16f MB |
80 | jack_port_t *left_port; |
81 | jack_port_t *right_port; | |
959aa08b | 82 | |
8cabb16f | 83 | long offset = 0; |
8cabb16f MB |
84 | |
85 | int client_is_open; | |
86 | jack_client_t *client; | |
87 | jack_nframes_t sample_rate; | |
c1d5815c | 88 | jack_nframes_t jack_latency; |
8cabb16f | 89 | |
f07c16a6 | 90 | static jack_ringbuffer_t *jackbuf; |
e99837f8 | 91 | static int flush_please = 0; |
f07c16a6 | 92 | |
39545cdf | 93 | jack_latency_range_t latest_left_latency_range, latest_right_latency_range; |
959aa08b | 94 | int64_t time_of_latest_transfer; |
8cabb16f MB |
95 | |
96 | int play(void *buf, int samples) { | |
97 | // debug(1,"jack_play of %d samples.",samples); | |
98 | // copy the samples into the queue | |
e99837f8 JN |
99 | size_t bytes_to_transfer, bytes_transferred; |
100 | bytes_to_transfer = samples * bytes_per_frame; | |
101 | pthread_mutex_lock(&buffer_mutex); // it's ok to lock here since we're not in the realtime callback | |
102 | bytes_transferred = jack_ringbuffer_write(jackbuf, buf, bytes_to_transfer); | |
7ab56696 JN |
103 | // semantics change: we now measure the last time audio was moved into the ringbuffer, not the jack output buffers. |
104 | time_of_latest_transfer = get_absolute_time_in_fp(); | |
e99837f8 JN |
105 | pthread_mutex_unlock(&buffer_mutex); |
106 | if (bytes_transferred < bytes_to_transfer) { | |
107 | debug(1, "JACK ringbuffer overrun. Only wrote %d of %d bytes.", bytes_transferred, bytes_to_transfer); | |
108 | } | |
8cabb16f MB |
109 | return 0; |
110 | } | |
111 | ||
e99837f8 JN |
112 | static inline jack_default_audio_sample_t sample_conv(short sample) { |
113 | return ((sample < 0) ? (-1.0 * sample / SHRT_MIN) : (1.0 * sample / SHRT_MAX)); | |
114 | } | |
115 | ||
116 | void deinterleave_and_convert(const char *interleaved_frames, | |
117 | jack_default_audio_sample_t * const jack_buffer_left, | |
118 | jack_default_audio_sample_t * const jack_buffer_right, | |
119 | jack_nframes_t nframes) { | |
120 | jack_nframes_t i; | |
121 | short *ifp = (short *)interleaved_frames; // we're dealing with 16bit audio here | |
122 | jack_default_audio_sample_t *fpl = jack_buffer_left; | |
123 | jack_default_audio_sample_t *fpr = jack_buffer_right; | |
124 | for (i=0; i<nframes; i++) { | |
125 | fpl[i] = sample_conv(*ifp++); | |
126 | fpr[i] = sample_conv(*ifp++); | |
127 | } | |
128 | } | |
129 | ||
8cabb16f MB |
130 | int jack_stream_write_cb(jack_nframes_t nframes, __attribute__((unused)) void *arg) { |
131 | ||
959aa08b MB |
132 | jack_default_audio_sample_t *left_buffer = |
133 | (jack_default_audio_sample_t *)jack_port_get_buffer(left_port, nframes); | |
134 | jack_default_audio_sample_t *right_buffer = | |
135 | (jack_default_audio_sample_t *)jack_port_get_buffer(right_port, nframes); | |
8cabb16f | 136 | |
e99837f8 JN |
137 | jack_ringbuffer_data_t v[2] = { 0 }; |
138 | jack_nframes_t i, thisbuf; | |
139 | int frames_written = 0; | |
140 | int frames_required = 0; | |
141 | ||
83c8857c | 142 | if (flush_please) { |
6104c580 | 143 | // we just move the read pointer ahead without doing anything with the data. |
83c8857c | 144 | jack_ringbuffer_read_advance(jackbuf, jack_ringbuffer_read_space(jackbuf)); |
3e6ef019 | 145 | flush_please = 0; |
6104c580 | 146 | // since we don't change nframes, the whole buffer will be zeroed later. |
83c8857c JN |
147 | } else { |
148 | jack_ringbuffer_get_read_vector(jackbuf, v); // an array of two elements because of possible ringbuffer wrap-around | |
149 | for (i=0; i<2; i++) { | |
150 | thisbuf = v[i].len / bytes_per_frame; | |
151 | if (thisbuf > nframes) { | |
152 | frames_required = nframes; | |
153 | } else { | |
154 | frames_required = thisbuf; | |
155 | } | |
156 | deinterleave_and_convert(v[i].buf, &left_buffer[frames_written], &right_buffer[frames_written], frames_required); | |
23d4ec2b JN |
157 | frames_written += frames_required; |
158 | nframes -= frames_required; | |
e99837f8 | 159 | } |
83c8857c | 160 | jack_ringbuffer_read_advance(jackbuf, frames_written * bytes_per_frame); |
e99837f8 | 161 | } |
e99837f8 JN |
162 | // debug(1,"transferring %u frames",written); |
163 | // Why are we doing this? The port latency should never change unless the JACK graph is reordered. Should happen on a graph reorder callback only. | |
3e6ef019 JN |
164 | jack_port_get_latency_range(left_port, JackPlaybackLatency, &latest_left_latency_range); |
165 | jack_port_get_latency_range(right_port, JackPlaybackLatency, &latest_right_latency_range); | |
e99837f8 JN |
166 | |
167 | // now, if there are any more frames to put into the buffer, fill them with | |
168 | // silence | |
169 | while (nframes > 0) { | |
170 | left_buffer[frames_written] = 0.0; | |
171 | right_buffer[frames_written] = 0.0; | |
172 | frames_written++; | |
173 | nframes--; | |
174 | } | |
8cabb16f MB |
175 | return 0; |
176 | } | |
177 | ||
e99837f8 JN |
178 | // FIXME: set_graph_order_callback(), recompute latencies here! |
179 | ||
959aa08b | 180 | void default_jack_error_callback(const char *desc) { debug(2, "jackd error: \"%s\"", desc); } |
8cabb16f | 181 | |
959aa08b | 182 | void default_jack_info_callback(const char *desc) { inform("jackd information: \"%s\"", desc); } |
8cabb16f MB |
183 | |
184 | int jack_is_running() { | |
76138873 | 185 | int reply = -1; // meaning jack is not running |
8cabb16f | 186 | if (client_is_open) { |
76138873 MB |
187 | |
188 | // check if the ports have a zero latency -- if they both have, then it's disconnected. | |
189 | ||
83472239 JN |
190 | // FIXME: this causes a segfault when shairport-sync is exited with CTRL-C, because |
191 | // the client_is_open flag is stale by then. Also, this test is not necessary. | |
192 | // shairport-sync should not worry what's reading its ports. As long as jack is alive, | |
193 | // deliver audio, even if nothing is connected. This behaviour probably stems from | |
194 | // the wish to not hog an audio device if not needed, which is no longer an issue with | |
195 | // jack. Moreover, don't "conserve" CPU this way, because in a realtime system you want | |
196 | // deterministic CPU load more than anything else. | |
197 | // jack_latency_range_t left_latency_range, right_latency_range; | |
198 | // jack_port_get_latency_range(left_port, JackPlaybackLatency, &left_latency_range); | |
199 | // jack_port_get_latency_range(right_port, JackPlaybackLatency, &right_latency_range); | |
76138873 | 200 | |
c1d5815c MB |
201 | // if ((left_latency_range.min == 0) && (left_latency_range.max == 0) && |
202 | // (right_latency_range.min == 0) && (right_latency_range.max == 0)) { | |
203 | // reply = -2; // meaning Shairport Sync is not connected | |
204 | // } else { | |
83472239 JN |
205 | |
206 | // FIXME: For now, we assume JACK is always running, as it should. | |
207 | // Still need to understand why shairport-sync needs this function. | |
c1d5815c MB |
208 | reply = 0; // meaning jack is open and Shairport Sync is connected to it |
209 | // } | |
8cabb16f MB |
210 | } |
211 | return reply; | |
212 | } | |
213 | ||
959aa08b | 214 | int jack_client_open_if_needed(void) { |
6c6dda9c | 215 | pthread_mutex_lock(&client_mutex); |
959aa08b MB |
216 | if (client_is_open == 0) { |
217 | jack_status_t status; | |
218 | client = jack_client_open(config.jack_client_name, JackNoStartServer, &status); | |
219 | if (client) { | |
220 | jack_set_process_callback(client, jack_stream_write_cb, 0); | |
221 | left_port = jack_port_register(client, config.jack_left_channel_name, JACK_DEFAULT_AUDIO_TYPE, | |
222 | JackPortIsOutput, 0); | |
223 | right_port = jack_port_register(client, config.jack_right_channel_name, | |
224 | JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); | |
225 | sample_rate = jack_get_sample_rate(client); | |
226 | // debug(1, "jackaudio sample rate = %" PRId32 ".", sample_rate); | |
227 | if (sample_rate == 44100) { | |
c1d5815c MB |
228 | if (jack_activate(client)) { |
229 | debug(1, "jackaudio cannot activate client"); | |
230 | } else { | |
231 | debug(2, "jackaudio client opened."); | |
232 | client_is_open = 1; | |
233 | } | |
959aa08b MB |
234 | } else { |
235 | inform( | |
236 | "jackaudio is running at the wrong speed (%d) for Shairport Sync, which must be 44100", | |
237 | sample_rate); | |
238 | } | |
239 | } | |
240 | } | |
6c6dda9c | 241 | pthread_mutex_unlock(&client_mutex); |
959aa08b MB |
242 | return client_is_open; |
243 | } | |
244 | ||
6c6dda9c MB |
245 | void jack_close(void) { |
246 | pthread_mutex_lock(&client_mutex); | |
959aa08b MB |
247 | if (client_is_open) { |
248 | if (jack_deactivate(client)) | |
249 | debug(1, "Error deactivating jack client"); | |
250 | if (jack_client_close(client)) | |
251 | debug(1, "Error closing jack client"); | |
6c6dda9c MB |
252 | client_is_open = 0; |
253 | } | |
254 | pthread_mutex_unlock(&client_mutex); | |
255 | } | |
256 | ||
257 | void jack_deinit() { | |
258 | jack_close(); | |
259 | if (open_client_if_necessary_thread) { | |
260 | pthread_cancel(*open_client_if_necessary_thread); | |
261 | free((char *)open_client_if_necessary_thread); | |
f07c16a6 JN |
262 | |
263 | jack_ringbuffer_free(jackbuf); | |
264 | ||
959aa08b MB |
265 | } |
266 | } | |
267 | ||
6c6dda9c MB |
268 | void *open_client_if_necessary_thread_function(void *arg) { |
269 | int *interval = (int *)arg; | |
270 | while (*interval != 0) { | |
271 | if (client_is_open == 0) { | |
272 | debug(1, "Try to open the jack client"); | |
273 | jack_client_open_if_needed(); | |
274 | } | |
275 | sleep(*interval); | |
39545cdf | 276 | } |
6c6dda9c MB |
277 | pthread_exit(NULL); |
278 | } | |
279 | ||
c1d5815c | 280 | int jack_init(__attribute__((unused)) int argc, __attribute__((unused)) char **argv) { |
8cabb16f | 281 | config.audio_backend_latency_offset = 0; |
76138873 | 282 | config.audio_backend_buffer_desired_length = 0.500; |
80f15e1f MB |
283 | config.audio_backend_buffer_interpolation_threshold_in_seconds = |
284 | 0.25; // below this, soxr interpolation will not occur -- it'll be basic interpolation | |
285 | // instead. | |
6c6dda9c | 286 | config.jack_auto_client_open_interval = 1; // check every second |
8cabb16f MB |
287 | |
288 | // get settings from settings file first, allow them to be overridden by | |
289 | // command line options | |
290 | ||
291 | // do the "general" audio options. Note, these options are in the "general" stanza! | |
292 | parse_general_audio_options(); | |
959aa08b | 293 | |
8cabb16f MB |
294 | // other options would be picked up here... |
295 | ||
959aa08b MB |
296 | // now the specific options |
297 | if (config.cfg != NULL) { | |
298 | const char *str; | |
6c6dda9c | 299 | int value; |
959aa08b MB |
300 | /* Get the Client Name. */ |
301 | if (config_lookup_string(config.cfg, "jack.client_name", &str)) { | |
302 | config.jack_client_name = (char *)str; | |
303 | } | |
304 | /* Get the Left Channel Name. */ | |
305 | if (config_lookup_string(config.cfg, "jack.left_channel_name", &str)) { | |
306 | config.jack_left_channel_name = (char *)str; | |
307 | } | |
308 | /* Get the Right Channel Name. */ | |
309 | if (config_lookup_string(config.cfg, "jack.right_channel_name", &str)) { | |
310 | config.jack_right_channel_name = (char *)str; | |
311 | } | |
39545cdf MB |
312 | |
313 | /* See if we should attempt to connect to the jack server automatically, and, if so, how often | |
314 | * we should try. */ | |
6c6dda9c MB |
315 | if (config_lookup_int(config.cfg, "jack.auto_client_open_interval", &value)) { |
316 | if ((value < 0) || (value > 300)) | |
2e442853 MB |
317 | debug(1, |
318 | "Invalid jack auto_client_open_interval \"%sd\". It should be between 0 and 300, " | |
319 | "default is %d.", | |
76138873 | 320 | value, config.jack_auto_client_open_interval); |
6c6dda9c MB |
321 | else |
322 | config.jack_auto_client_open_interval = value; | |
323 | } | |
324 | ||
325 | /* See if we should close the client at then end of a play session. */ | |
39545cdf MB |
326 | config_set_lookup_bool(config.cfg, "jack.auto_client_disconnect", |
327 | &config.jack_auto_client_disconnect); | |
959aa08b MB |
328 | } |
329 | ||
330 | if (config.jack_client_name == NULL) | |
331 | config.jack_client_name = strdup("Shairport Sync"); | |
332 | if (config.jack_left_channel_name == NULL) | |
333 | config.jack_left_channel_name = strdup("left"); | |
334 | if (config.jack_right_channel_name == NULL) | |
335 | config.jack_right_channel_name = strdup("right"); | |
336 | ||
f07c16a6 | 337 | jackbuf = jack_ringbuffer_create(buffer_size); // make the jack ringbuffer the same size as audio_lmb |
06504516 JN |
338 | if (jackbuf == NULL) |
339 | die("Can't allocate %d bytes for the JACK ringbuffer.", buffer_size); | |
f07c16a6 JN |
340 | jack_ringbuffer_mlock(jackbuf); // lock buffer into memory so that it never gets paged out |
341 | ||
959aa08b | 342 | jack_set_error_function(default_jack_error_callback); |
8cabb16f | 343 | jack_set_info_function(default_jack_info_callback); |
8cabb16f | 344 | |
959aa08b | 345 | client_is_open = 0; |
39545cdf | 346 | |
175d91a4 | 347 | // now, if selected, start a thread to automatically open a client when there is a server. |
6c6dda9c MB |
348 | if (config.jack_auto_client_open_interval != 0) { |
349 | open_client_if_necessary_thread = malloc(sizeof(pthread_t)); | |
175d91a4 | 350 | if (open_client_if_necessary_thread == NULL) { |
76138873 | 351 | debug(1, "Couldn't allocate space for jack server scanner thread"); |
175d91a4 MB |
352 | jack_client_open_if_needed(); |
353 | } else { | |
76138873 MB |
354 | pthread_create(open_client_if_necessary_thread, NULL, |
355 | open_client_if_necessary_thread_function, | |
356 | &config.jack_auto_client_open_interval); | |
175d91a4 | 357 | } |
6c6dda9c MB |
358 | } else { |
359 | jack_client_open_if_needed(); | |
360 | } | |
959aa08b | 361 | |
8cabb16f MB |
362 | return 0; |
363 | } | |
364 | ||
959aa08b MB |
365 | void jack_start(__attribute__((unused)) int i_sample_rate, |
366 | __attribute__((unused)) int i_sample_format) { | |
6c6dda9c | 367 | // debug(1, "jack start"); |
959aa08b MB |
368 | // see if the client is running. If not, try to open and initialise it |
369 | ||
370 | if (jack_client_open_if_needed() == 0) | |
371 | debug(1, "cannot open a jack client for a play session"); | |
8cabb16f MB |
372 | } |
373 | ||
374 | int jack_delay(long *the_delay) { | |
39545cdf | 375 | |
7ab56696 JN |
376 | // semantics change: we now look at the last transfer into the lock-free ringbuffer, not |
377 | // into the jack buffers directly (because locking those would violate real-time constraints). | |
378 | // on average, that should lead to just a constant additional latency. the old comment still applies: | |
379 | ||
959aa08b | 380 | // without the mutex, we could get the time of what is the last transfer of data to a jack buffer, |
39545cdf MB |
381 | // but then a transfer could occur and we would get the buffer occupancy after another transfer |
382 | // had occurred | |
383 | // so we could "lose" a full transfer (e.g. 1024 frames @ 44,100 fps ~ 23.2 milliseconds) | |
e99837f8 | 384 | |
39545cdf | 385 | pthread_mutex_lock(&buffer_mutex); |
e99837f8 JN |
386 | int64_t time_now = get_absolute_time_in_fp(); |
387 | // this is the time back to the last time data | |
388 | // was transferred into a jack buffer | |
389 | int64_t delta = time_now - time_of_latest_transfer; | |
390 | // this is the buffer occupancy before any | |
391 | // subsequent transfer because transfer is blocked | |
392 | // by the mutex | |
a238ac54 | 393 | size_t audio_occupancy_now = jack_ringbuffer_read_space(jackbuf) / bytes_per_frame; |
9c57fe43 | 394 | debug(1, "JN: audio_occupancy_now is %d.", audio_occupancy_now); |
959aa08b MB |
395 | pthread_mutex_unlock(&buffer_mutex); |
396 | ||
8cabb16f | 397 | int64_t frames_processed_since_latest_latency_check = (delta * 44100) >> 32; |
9c57fe43 JN |
398 | |
399 | // FIXME: this should only be done if there was an actual change, i.e. on the jack graph reorder | |
400 | // callback, to update a static variable which can be checked here. For now, use a fixed arbitrary value: | |
401 | jack_nframes_t base_latency = 0; | |
402 | ||
8cabb16f | 403 | // debug(1,"delta: %" PRId64 " frames.",frames_processed_since_latest_latency_check); |
9c57fe43 JN |
404 | |
405 | // jack_nframes_t base_latency = (latest_left_latency_range.min + latest_left_latency_range.max) / 2; | |
406 | // if (base_latency == 0) | |
407 | // base_latency = (latest_right_latency_range.min + latest_right_latency_range.max) / 2; | |
39545cdf | 408 | *the_delay = base_latency + audio_occupancy_now - frames_processed_since_latest_latency_check; |
9c57fe43 | 409 | debug(1,"reporting a delay of %d frames",*the_delay); |
8cabb16f MB |
410 | return 0; |
411 | } | |
412 | ||
413 | void jack_flush() { | |
7ab56696 | 414 | debug(1, "Only the consumer can safely flush a lock-free ringbuffer. Asking the process callback to do it..."); |
e99837f8 | 415 | flush_please = 1; |
8cabb16f MB |
416 | } |
417 | ||
6c6dda9c MB |
418 | void jack_stop(void) { |
419 | // debug(1, "jack stop"); | |
420 | if (config.jack_auto_client_disconnect) | |
421 | jack_close(); | |
aa5698fc | 422 | } |