]> git.ipfire.org Git - thirdparty/shairport-sync.git/blame - audio_alsa.c
Update check_classic_systemd_full.yml
[thirdparty/shairport-sync.git] / audio_alsa.c
CommitLineData
95035f33
M
1/*
2 * libalsa output driver. This file is part of Shairport.
3 * Copyright (c) Muffinman, Skaman 2013
129343c1 4 * Copyright (c) Mike Brady 2014 -- 2022
95035f33
M
5 * All rights reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person
8 * obtaining a copy of this software and associated documentation
9 * files (the "Software"), to deal in the Software without
10 * restriction, including without limitation the rights to use,
11 * copy, modify, merge, publish, distribute, sublicense, and/or
12 * sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be
16 * included in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25 * OTHER DEALINGS IN THE SOFTWARE.
26 */
27
28#define ALSA_PCM_NEW_HW_PARAMS_API
29
064bd293 30#include <alsa/asoundlib.h>
76c5dd92 31#include <inttypes.h>
ba02dee4 32#include <math.h>
064bd293 33#include <memory.h>
689063ce 34#include <pthread.h>
064bd293
MB
35#include <stdio.h>
36#include <unistd.h>
95035f33 37
8b589879
MB
38#include "config.h"
39
8b589879
MB
40#include "activity_monitor.h"
41#include "audio.h"
c8b0be30 42#include "common.h"
8b589879 43
bd81e733
MB
44enum alsa_backend_mode {
45 abm_disconnected,
46 abm_connected,
47 abm_playing
48} alsa_backend_state; // under the control of alsa_mutex
49
83c0405d 50typedef struct {
c8b0be30
MB
51 snd_pcm_format_t alsa_code;
52 int frame_size;
83c0405d
MB
53} format_record;
54
fd880056
MB
55int output_method_signalled = 0; // for reporting whether it's using mmap or not
56int delay_type_notified = -1; // for controlling the reporting of whether the output device can do
57 // precision delays (e.g. alsa->pulsaudio virtual devices can't)
58int use_monotonic_clock = 0; // this value will be set when the hardware is initialised
59
95035f33 60static void help(void);
c56a9ee2 61static int init(int argc, char **argv);
95035f33 62static void deinit(void);
01e51285 63static void start(int i_sample_rate, int i_sample_format);
fd880056
MB
64static int play(void *buf, int samples, __attribute__((unused)) int sample_type,
65 __attribute__((unused)) uint32_t timestamp,
66 __attribute__((unused)) uint64_t playtime);
95035f33 67static void stop(void);
2c40f23f 68static void flush(void);
fd880056
MB
69static int delay(long *the_delay);
70static int stats(uint64_t *raw_measurement_time, uint64_t *corrected_measurement_time,
71 uint64_t *the_delay, uint64_t *frames_sent_to_dac);
56bef8e7 72
fd880056 73static void *alsa_buffer_monitor_thread_code(void *arg);
2915e667 74
95035f33 75static void volume(double vol);
fd880056
MB
76static void do_volume(double vol);
77static int prepare(void);
78static int do_play(void *buf, int samples);
fc492bea 79
87a0475c 80static void parameters(audio_parameters *info);
fd880056 81static int mute(int do_mute); // returns true if it actually is allowed to use the mute
c1316621 82static double set_volume;
e513e533
MB
83audio_output audio_alsa = {
84 .name = "alsa",
85 .help = &help,
86 .init = &init,
87 .deinit = &deinit,
83c0405d 88 .prepare = &prepare,
e513e533
MB
89 .start = &start,
90 .stop = &stop,
8cabb16f 91 .is_running = NULL,
e513e533
MB
92 .flush = &flush,
93 .delay = &delay,
94 .play = &play,
14bfba27
MB
95 .stats = &stats, // will also include frames of silence sent to stop
96 // standby mode
97 // .rate_info = NULL,
555bb97a
MB
98 .mute = NULL, // a function will be provided if it can, and is allowed to,
99 // do hardware mute
100 .volume = NULL, // a function will be provided if it can do hardware volume
2737222b 101 .parameters = NULL}; // a function will be provided if it can do hardware volume
95035f33 102
fd880056
MB
103pthread_mutex_t alsa_mutex = PTHREAD_MUTEX_INITIALIZER;
104pthread_mutex_t alsa_mixer_mutex = PTHREAD_MUTEX_INITIALIZER;
689063ce 105
7cc434e9
MB
106pthread_t alsa_buffer_monitor_thread;
107
555bb97a
MB
108// for deciding when to activate mute
109// there are two sources of requests to mute -- the backend itself, e.g. when it
110// is flushing
111// and the player, e.g. when volume goes down to -144, i.e. mute.
112
113// we may not be allowed to use hardware mute, so we must reflect that too.
114
115int mute_requested_externally = 0;
116int mute_requested_internally = 0;
117
46a13dce 118// for tracking how long the output device has stalled
555bb97a
MB
119uint64_t stall_monitor_start_time; // zero if not initialised / not started /
120 // zeroed by flush
121long stall_monitor_frame_count; // set to delay at start of time, incremented by
122 // any writes
123uint64_t stall_monitor_error_threshold; // if the time is longer than this, it's
124 // an error
46a13dce 125
fd880056 126snd_output_t *output = NULL;
7cc434e9 127int frame_size; // in bytes for interleaved stereo
83504880 128
555bb97a
MB
129int alsa_device_initialised; // boolean to ensure the initialisation is only
130 // done once
cd9982c4 131
f7717745 132yndk_type precision_delay_available_status =
c8b0be30
MB
133 YNDK_DONT_KNOW; // initially, we don't know if the device can do precision delay
134
9fb37e42 135snd_pcm_t *alsa_handle = NULL;
449e024c
MB
136int alsa_handle_status =
137 ENODEV; // if alsa_handle is NULL, this should say why with a unix error code
fd880056
MB
138snd_pcm_hw_params_t *alsa_params = NULL;
139snd_pcm_sw_params_t *alsa_swparams = NULL;
140snd_ctl_t *ctl = NULL;
141snd_ctl_elem_id_t *elem_id = NULL;
142snd_mixer_t *alsa_mix_handle = NULL;
143snd_mixer_elem_t *alsa_mix_elem = NULL;
144snd_mixer_selem_id_t *alsa_mix_sid = NULL;
145long alsa_mix_minv, alsa_mix_maxv;
146long alsa_mix_mindb, alsa_mix_maxdb;
147
148char *alsa_out_dev = "default";
149char *alsa_mix_dev = NULL;
150char *alsa_mix_ctrl = NULL;
151int alsa_mix_index = 0;
152int has_softvol = 0;
8a4bfb03 153
4046c0e7 154int64_t dither_random_number_store = 0;
8a4bfb03 155
fd880056 156int volume_set_request = 0; // set when an external request is made to set the volume.
555bb97a
MB
157
158int mixer_volume_setting_gives_mute = 0; // set when it is discovered that
159 // particular mixer volume setting
160 // causes a mute.
161long alsa_mix_mute; // setting the volume to this value mutes output, if
162 // mixer_volume_setting_gives_mute is true
e0aa75a8
MB
163int volume_based_mute_is_active =
164 0; // set when muting is being done by a setting the volume to a magic value
95035f33 165
aac57c9c 166// use this to allow the use of snd_pcm_writei or snd_pcm_mmap_writei
c8b0be30 167snd_pcm_sframes_t (*alsa_pcm_write)(snd_pcm_t *, const void *, snd_pcm_uframes_t) = snd_pcm_writei;
8e847aa4 168
76387f82
MB
169void handle_unfixable_error(int errorCode) {
170 if (config.unfixable_error_reported == 0) {
171 config.unfixable_error_reported = 1;
172 char messageString[1024];
173 messageString[0] = '\0';
174 snprintf(messageString, sizeof(messageString), "output_device_error_%d", errorCode);
175 if (config.cmd_unfixable) {
176 command_execute(config.cmd_unfixable, messageString, 1);
177 } else {
178 die("An unrecoverable error, \"output_device_error_%d\", has been "
b7d9c22d
MB
179 "detected. Doing an emergency exit, as no run_this_if_an_unfixable_error_is_detected "
180 "program.",
76387f82
MB
181 errorCode);
182 }
183 }
184}
185
fd880056
MB
186static int precision_delay_and_status(snd_pcm_state_t *state, snd_pcm_sframes_t *delay,
187 yndk_type *using_update_timestamps);
188static int standard_delay_and_status(snd_pcm_state_t *state, snd_pcm_sframes_t *delay,
189 yndk_type *using_update_timestamps);
aac57c9c 190
c8b0be30
MB
191// use this to allow the use of standard or precision delay calculations, with standard the, uh,
192// standard.
193int (*delay_and_status)(snd_pcm_state_t *state, snd_pcm_sframes_t *delay,
f7717745 194 yndk_type *using_update_timestamps) = standard_delay_and_status;
aac57c9c 195
dbea82c2
MB
196// this will return true if the DAC can return precision delay information and false if not
197// if it is not yet known, it will test the output device to find out
198
199// note -- once it has done the test, it decides -- even if the delay comes back with
200// "don't know", it will take that as a "No" and remember it.
201// If you want it to check again, set precision_delay_available_status to YNDK_DONT_KNOW
202// first.
203
fd880056 204static int precision_delay_available() {
dbea82c2 205 if (precision_delay_available_status == YNDK_DONT_KNOW) {
c8b0be30
MB
206 // this is very crude -- if the device is a hardware device, then it's assumed the delay is
207 // precise
7013b0cc 208 const char *output_device_name = snd_pcm_name(alsa_handle);
0b03f237 209 int is_a_real_hardware_device = 0;
210 if (output_device_name != NULL)
211 is_a_real_hardware_device = (strstr(output_device_name, "hw:") == output_device_name);
7013b0cc
MB
212
213 // The criteria as to whether precision delay is available
dbea82c2 214 // is whether the device driver returns non-zero update timestamps
1ca92262 215 // If it does, and the device is a hardware device (i.e. its name begins with "hw:"),
c8b0be30
MB
216 // it is considered that precision delay is available. Otherwise, it's considered to be
217 // unavailable.
218
dbea82c2 219 // To test, we play a silence buffer (fairly large to avoid underflow)
c8b0be30 220 // and then we check the delay return. It will tell us if it
dbea82c2 221 // was able to use the (non-zero) update timestamps
c8b0be30 222
dbea82c2
MB
223 int frames_of_silence = 4410;
224 size_t size_of_silence_buffer = frames_of_silence * frame_size;
225 void *silence = malloc(size_of_silence_buffer);
226 if (silence == NULL) {
227 debug(1, "alsa: precision_delay_available -- failed to "
228 "allocate memory for a "
229 "silent frame buffer.");
230 } else {
231 pthread_cleanup_push(malloc_cleanup, silence);
232 int use_dither = 0;
e8a92d3c 233 if ((alsa_mix_ctrl == NULL) && (config.ignore_volume_control == 0) &&
dbea82c2
MB
234 (config.airplay_volume != 0.0))
235 use_dither = 1;
236 dither_random_number_store =
237 generate_zero_frames(silence, frames_of_silence, config.output_format,
238 use_dither, // i.e. with dither
239 dither_random_number_store);
dbea82c2
MB
240 do_play(silence, frames_of_silence);
241 pthread_cleanup_pop(1);
242 // now we can get the delay, and we'll note if it uses update timestamps
f7717745 243 yndk_type uses_update_timestamps;
dbea82c2 244 snd_pcm_state_t state;
c8b0be30 245 snd_pcm_sframes_t delay;
9199bf24 246 int ret = precision_delay_and_status(&state, &delay, &uses_update_timestamps);
c8b0be30
MB
247 // debug(3,"alsa: precision_delay_available asking for delay and status with a return status
248 // of %d, a delay of %ld and a uses_update_timestamps of %d.", ret, delay,
249 // uses_update_timestamps);
dbea82c2 250 if (ret == 0) {
7013b0cc 251 if ((uses_update_timestamps == YNDK_YES) && (is_a_real_hardware_device)) {
dbea82c2 252 precision_delay_available_status = YNDK_YES;
c8b0be30 253 debug(2, "alsa: precision delay timing is available.");
dbea82c2 254 } else {
7013b0cc 255 if ((uses_update_timestamps == YNDK_YES) && (!is_a_real_hardware_device)) {
c8b0be30
MB
256 debug(2, "alsa: precision delay timing is not available because it's not definitely a "
257 "hardware device.");
7013b0cc 258 } else {
c8b0be30
MB
259 debug(2, "alsa: precision delay timing is not available.");
260 }
261 precision_delay_available_status = YNDK_NO;
dbea82c2
MB
262 }
263 }
264 }
265 }
266 return (precision_delay_available_status == YNDK_YES);
1d32976d
MB
267}
268
cbc4caa6
MB
269int alsa_characteristics_already_listed = 0;
270
fd880056
MB
271snd_pcm_uframes_t period_size_requested, buffer_size_requested;
272int set_period_size_request, set_buffer_size_request;
2c40f23f 273
fd880056 274uint64_t frames_sent_for_playing;
136071a6 275
dc5b8f1a
MB
276// set to true if there has been a discontinuity between the last reported frames_sent_for_playing
277// and the present reported frames_sent_for_playing
850fda10 278// Note that it will be set when the device is opened, as any previous figures for
dc5b8f1a 279// frames_sent_for_playing (which Shairport Sync might hold) would be invalid.
fd880056 280int frames_sent_break_occurred;
c85e7e05 281
95035f33 282static void help(void) {
552218ab
MB
283 printf(" -d output-device set the output device, default is \"default\".\n"
284 " -c mixer-control set the mixer control name, default is to use no mixer.\n"
285 " -m mixer-device set the mixer device, default is the output device.\n"
286 " -i mixer-index set the mixer index, default is 0.\n");
c8b0be30
MB
287 int r = system("if [ -d /proc/asound ] ; then echo \" hardware output devices:\" ; ls -al "
288 "/proc/asound/ 2>/dev/null | grep '\\->' | tr -s ' ' | cut -d ' ' -f 9 | while "
289 "read line; do echo \" \\\"hw:$line\\\"\" ; done ; fi");
4bafe1c9
MB
290 if (r != 0)
291 debug(2, "error %d executing a script to list alsa hardware device names", r);
95035f33
M
292}
293
fd880056 294void set_alsa_out_dev(char *dev) { alsa_out_dev = dev; } // ugh -- not static!
3e9e2285 295
277d401d 296// assuming pthread cancellation is disabled
76387f82 297// returns zero of all is okay, a Unx error code if there's a problem
fd880056 298static int open_mixer() {
ea20840d 299 int response = 0;
e8a92d3c 300 if (alsa_mix_ctrl != NULL) {
2efab6ee 301 debug(3, "Open Mixer");
d414c07e
MB
302 snd_mixer_selem_id_alloca(&alsa_mix_sid);
303 snd_mixer_selem_id_set_index(alsa_mix_sid, alsa_mix_index);
304 snd_mixer_selem_id_set_name(alsa_mix_sid, alsa_mix_ctrl);
305
76387f82 306 if ((response = snd_mixer_open(&alsa_mix_handle, 0)) < 0) {
76c5dd92 307 debug(1, "Failed to open mixer");
ea20840d
MB
308 } else {
309 debug(3, "Mixer device name is \"%s\".", alsa_mix_dev);
76387f82 310 if ((response = snd_mixer_attach(alsa_mix_handle, alsa_mix_dev)) < 0) {
76c5dd92 311 debug(1, "Failed to attach mixer");
ea20840d 312 } else {
76387f82 313 if ((response = snd_mixer_selem_register(alsa_mix_handle, NULL, NULL)) < 0) {
76c5dd92 314 debug(1, "Failed to register mixer element");
ea20840d 315 } else {
76387f82 316 if ((response = snd_mixer_load(alsa_mix_handle)) < 0) {
76c5dd92 317 debug(1, "Failed to load mixer element");
ea20840d 318 } else {
6ced6bc6 319 debug(3, "Mixer control is \"%s\",%d.", alsa_mix_ctrl, alsa_mix_index);
ea20840d
MB
320 alsa_mix_elem = snd_mixer_find_selem(alsa_mix_handle, alsa_mix_sid);
321 if (!alsa_mix_elem) {
6ced6bc6 322 warn("failed to find mixer control \"%s\",%d.", alsa_mix_ctrl, alsa_mix_index);
76387f82 323 response = -ENXIO; // don't let this be ENODEV!
ea20840d
MB
324 }
325 }
326 }
327 }
328 }
d414c07e 329 }
ea20840d 330 return response;
ae0c9745
MB
331}
332
277d401d 333// assuming pthread cancellation is disabled
76387f82
MB
334static int close_mixer() {
335 int ret = 0;
e513e533 336 if (alsa_mix_handle) {
76387f82 337 ret = snd_mixer_close(alsa_mix_handle);
e513e533
MB
338 alsa_mix_handle = NULL;
339 }
76387f82 340 return ret;
eb1b7c37
MB
341}
342
277d401d 343// assuming pthread cancellation is disabled
76387f82
MB
344static int do_snd_mixer_selem_set_playback_dB_all(snd_mixer_elem_t *mix_elem, double vol) {
345 int response = 0;
346 if ((response = snd_mixer_selem_set_playback_dB_all(mix_elem, vol, 0)) != 0) {
8a4bfb03 347 debug(1, "Can't set playback volume accurately to %f dB.", vol);
76387f82
MB
348 if ((response = snd_mixer_selem_set_playback_dB_all(mix_elem, vol, -1)) != 0)
349 if ((response = snd_mixer_selem_set_playback_dB_all(mix_elem, vol, 1)) != 0)
8a4bfb03
MB
350 debug(1, "Could not set playback dB volume on the mixer.");
351 }
76387f82 352 return response;
8a4bfb03 353}
f7077e70 354
c8b0be30
MB
355// This array is a sequence of the output rates to be tried if automatic speed selection is
356// requested.
83c0405d
MB
357// There is no benefit to upconverting the frame rate, other than for compatibility.
358// The lowest rate that the DAC is capable of is chosen.
359
360unsigned int auto_speed_output_rates[] = {
54d761ff
MB
361 44100,
362 88200,
363 176400,
364 352800,
83c0405d
MB
365};
366
c8b0be30
MB
367// This array is of all the formats known to Shairport Sync, in order of the SPS_FORMAT definitions,
368// with their equivalent alsa codes and their frame sizes.
369// If just one format is requested, then its entry is searched for in the array and checked on the
370// device
83c0405d
MB
371// If auto format is requested, then each entry in turn is tried until a working format is found.
372// So, it should be in the search order.
c8b0be30
MB
373
374format_record fr[] = {
375 {SND_PCM_FORMAT_UNKNOWN, 0}, // unknown
376 {SND_PCM_FORMAT_S8, 2}, {SND_PCM_FORMAT_U8, 2}, {SND_PCM_FORMAT_S16, 4},
aeb46892 377 {SND_PCM_FORMAT_S16_LE, 4}, {SND_PCM_FORMAT_S16_BE, 4}, {SND_PCM_FORMAT_S24, 8},
c8b0be30
MB
378 {SND_PCM_FORMAT_S24_LE, 8}, {SND_PCM_FORMAT_S24_BE, 8}, {SND_PCM_FORMAT_S24_3LE, 6},
379 {SND_PCM_FORMAT_S24_3BE, 6}, {SND_PCM_FORMAT_S32, 8}, {SND_PCM_FORMAT_S32_LE, 8},
380 {SND_PCM_FORMAT_S32_BE, 8}, {SND_PCM_FORMAT_UNKNOWN, 0}, // auto
381 {SND_PCM_FORMAT_UNKNOWN, 0}, // illegal
382};
383
384// This array is the sequence of formats to be tried if automatic selection of the format is
385// requested.
386// Ideally, audio should pass through Shairport Sync unaltered, apart from occasional interpolation.
387// If the user chooses a hardware mixer, then audio could go straight through, unaltered, as signed
388// 16 bit stereo.
389// However, the user might, at any point, select an option that requires modification, such as
390// stereo to mono mixing,
391// additional volume attenuation, convolution, and so on. For this reason,
392// we look for the greatest depth the DAC is capable of, since upconverting it is completely
393// lossless.
394// If audio processing is required, then the dither that must be added will
395// be added at the lowest possible level.
396// Hence, selecting the greatest bit depth is always either beneficial or neutral.
397
f7717745 398sps_format_t auto_format_check_sequence[] = {
c8b0be30
MB
399 SPS_FORMAT_S32, SPS_FORMAT_S32_LE, SPS_FORMAT_S32_BE, SPS_FORMAT_S24, SPS_FORMAT_S24_LE,
400 SPS_FORMAT_S24_BE, SPS_FORMAT_S24_3LE, SPS_FORMAT_S24_3BE, SPS_FORMAT_S16, SPS_FORMAT_S16_LE,
401 SPS_FORMAT_S16_BE, SPS_FORMAT_S8, SPS_FORMAT_U8,
402};
83c0405d 403
4046c0e7 404// assuming pthread cancellation is disabled
83c0405d
MB
405// if do_auto_setting is true and auto format or auto speed has been requested,
406// select the settings as appropriate and store them
fd880056 407static int actual_open_alsa_device(int do_auto_setup) {
4046c0e7
MB
408 // the alsa mutex is already acquired when this is called
409 const snd_pcm_uframes_t minimal_buffer_headroom =
410 352 * 2; // we accept this much headroom in the hardware buffer, but we'll
411 // accept less
412 /*
413 const snd_pcm_uframes_t requested_buffer_headroom =
414 minimal_buffer_headroom + 2048; // we ask for this much headroom in the
555bb97a
MB
415 // hardware buffer, but we'll accept
416 less
4046c0e7 417 */
87a0475c 418
4046c0e7 419 int ret, dir = 0;
c8b0be30
MB
420 unsigned int
421 actual_sample_rate; // this will be given the rate requested and will be given the actual rate
4046c0e7
MB
422 // snd_pcm_uframes_t frames = 441 * 10;
423 snd_pcm_uframes_t actual_buffer_length;
424 snd_pcm_access_t access;
e5452e51 425
555bb97a
MB
426 // ensure no calls are made to the alsa device enquiring about the buffer
427 // length if
4046c0e7
MB
428 // synchronisation is disabled.
429 if (config.no_sync != 0)
430 audio_alsa.delay = NULL;
e513e533 431
555bb97a
MB
432 // ensure no calls are made to the alsa device enquiring about the buffer
433 // length if
4046c0e7
MB
434 // synchronisation is disabled.
435 if (config.no_sync != 0)
436 audio_alsa.delay = NULL;
c56a9ee2 437
4046c0e7 438 ret = snd_pcm_open(&alsa_handle, alsa_out_dev, SND_PCM_STREAM_PLAYBACK, 0);
449e024c
MB
439 // EHOSTDOWN seems to signify that it's a PipeWire pseudo device that can't be accessed by this
440 // user. So, try the first device ALSA device and log it.
441 if ((ret == -EHOSTDOWN) && (strcmp(alsa_out_dev, "default") == 0)) {
442 ret = snd_pcm_open(&alsa_handle, "hw:0", SND_PCM_STREAM_PLAYBACK, 0);
443 if ((ret == 0) || (ret == -EBUSY)) {
444 // being busy should be okay
445 inform("the default ALSA device is inaccessible -- \"hw:0\" used instead.", alsa_out_dev);
446 set_alsa_out_dev("hw:0");
447 }
448 }
129343c1
MB
449 if (ret == 0) {
450 if (alsa_handle_status == -EBUSY)
449e024c
MB
451 warn("The output device \"%s\" is no longer busy and will be used by Shairport Sync.",
452 alsa_out_dev);
129343c1
MB
453 alsa_handle_status = ret; // all cool
454 } else {
455 alsa_handle = NULL; // to be sure to be sure
456 if (ret == -EBUSY) {
457 if (alsa_handle_status != -EBUSY)
449e024c
MB
458 warn("The output device \"%s\" is busy and can't be used by Shairport Sync at present.",
459 alsa_out_dev);
129343c1 460 debug(2, "the alsa output_device \"%s\" is busy.", alsa_out_dev);
84eecaf7 461 }
129343c1
MB
462 alsa_handle_status = ret;
463 frames_sent_break_occurred = 1;
1d32976d 464 return ret;
d3072ae8 465 }
5a8241c7 466
4046c0e7
MB
467 snd_pcm_hw_params_alloca(&alsa_params);
468 snd_pcm_sw_params_alloca(&alsa_swparams);
87a0475c 469
4046c0e7
MB
470 ret = snd_pcm_hw_params_any(alsa_handle, alsa_params);
471 if (ret < 0) {
449a9be5 472 die("audio_alsa: Broken configuration for device \"%s\": no configurations "
c8b0be30
MB
473 "available",
474 alsa_out_dev);
284cb9d3 475 return ret;
4046c0e7 476 }
312bcd03 477
4046c0e7
MB
478 if ((config.no_mmap == 0) &&
479 (snd_pcm_hw_params_set_access(alsa_handle, alsa_params, SND_PCM_ACCESS_MMAP_INTERLEAVED) >=
480 0)) {
481 if (output_method_signalled == 0) {
482 debug(3, "Output written using MMAP");
483 output_method_signalled = 1;
87a0475c 484 }
4046c0e7
MB
485 access = SND_PCM_ACCESS_MMAP_INTERLEAVED;
486 alsa_pcm_write = snd_pcm_mmap_writei;
487 } else {
488 if (output_method_signalled == 0) {
489 debug(3, "Output written with RW");
490 output_method_signalled = 1;
87a0475c 491 }
4046c0e7
MB
492 access = SND_PCM_ACCESS_RW_INTERLEAVED;
493 alsa_pcm_write = snd_pcm_writei;
494 }
744214df 495
4046c0e7
MB
496 ret = snd_pcm_hw_params_set_access(alsa_handle, alsa_params, access);
497 if (ret < 0) {
1ca4ebcf 498 die("audio_alsa: Access type not available for device \"%s\": %s", alsa_out_dev,
c0a3dacf 499 snd_strerror(ret));
284cb9d3 500 return ret;
4046c0e7 501 }
064bd293 502
4046c0e7
MB
503 ret = snd_pcm_hw_params_set_channels(alsa_handle, alsa_params, 2);
504 if (ret < 0) {
1ca4ebcf 505 die("audio_alsa: Channels count (2) not available for device \"%s\": %s", alsa_out_dev,
c0a3dacf 506 snd_strerror(ret));
284cb9d3 507 return ret;
4046c0e7 508 }
e513e533 509
042d9404 510 snd_pcm_format_t sf;
c8b0be30 511
83c0405d 512 if ((do_auto_setup == 0) || (config.output_format_auto_requested == 0)) { // no auto format
c8b0be30
MB
513 if ((config.output_format > SPS_FORMAT_UNKNOWN) && (config.output_format < SPS_FORMAT_AUTO)) {
514 sf = fr[config.output_format].alsa_code;
515 frame_size = fr[config.output_format].frame_size;
516 } else {
517 warn("alsa: unexpected output format %d. Set to S16_LE.", config.output_format);
518 config.output_format = SPS_FORMAT_S16_LE;
519 sf = fr[config.output_format].alsa_code;
520 frame_size = fr[config.output_format].frame_size;
521 }
522 ret = snd_pcm_hw_params_set_format(alsa_handle, alsa_params, sf);
523 if (ret < 0) {
c5dafbd2
MB
524 die("audio_alsa: Alsa sample format %d not available for device \"%s\": %s", sf, alsa_out_dev,
525 snd_strerror(ret));
c8b0be30
MB
526 return ret;
527 }
83c0405d 528 } else { // auto format
c8b0be30 529 int number_of_formats_to_try;
f7717745 530 sps_format_t *formats;
c8b0be30
MB
531 formats = auto_format_check_sequence;
532 number_of_formats_to_try = sizeof(auto_format_check_sequence) / sizeof(sps_format_t);
533 int i = 0;
534 int format_found = 0;
f7717745 535 sps_format_t trial_format = SPS_FORMAT_UNKNOWN;
c8b0be30
MB
536 while ((i < number_of_formats_to_try) && (format_found == 0)) {
537 trial_format = formats[i];
538 sf = fr[trial_format].alsa_code;
539 frame_size = fr[trial_format].frame_size;
540 ret = snd_pcm_hw_params_set_format(alsa_handle, alsa_params, sf);
541 if (ret == 0)
542 format_found = 1;
543 else
544 i++;
545 }
546 if (ret == 0) {
547 config.output_format = trial_format;
3b4a21f0 548 debug(2, "alsa: output format chosen is \"%s\".",
c8b0be30
MB
549 sps_format_description_string(config.output_format));
550 } else {
1ca4ebcf 551 die("audio_alsa: Could not automatically set the output format for device \"%s\": %s",
c0a3dacf 552 alsa_out_dev, snd_strerror(ret));
c8b0be30
MB
553 return ret;
554 }
20967812 555 }
c8b0be30 556
83c0405d 557 if ((do_auto_setup == 0) || (config.output_rate_auto_requested == 0)) { // no auto format
c8b0be30
MB
558 actual_sample_rate =
559 config.output_rate; // this is the requested rate -- it'll be changed to the actual rate
560 ret = snd_pcm_hw_params_set_rate_near(alsa_handle, alsa_params, &actual_sample_rate, &dir);
561 if (ret < 0) {
c0a3dacf
MB
562 die("audio_alsa: The frame rate of %i frames per second is not available for playback: %s",
563 config.output_rate, snd_strerror(ret));
c8b0be30
MB
564 return ret;
565 }
566 } else {
567 int number_of_speeds_to_try;
568 unsigned int *speeds;
569
570 speeds = auto_speed_output_rates;
571 number_of_speeds_to_try = sizeof(auto_speed_output_rates) / sizeof(int);
572
573 int i = 0;
574 int speed_found = 0;
575
576 while ((i < number_of_speeds_to_try) && (speed_found == 0)) {
577 actual_sample_rate = speeds[i];
578 ret = snd_pcm_hw_params_set_rate_near(alsa_handle, alsa_params, &actual_sample_rate, &dir);
579 if (ret == 0) {
580 speed_found = 1;
581 if (actual_sample_rate != speeds[i])
c0a3dacf
MB
582 die("The output DAC can not be set to %d frames per second (fps). The nearest speed "
583 "available is %d fps.",
584 speeds[i], actual_sample_rate);
c8b0be30
MB
585 } else {
586 i++;
587 }
588 }
589 if (ret == 0) {
590 config.output_rate = actual_sample_rate;
3b4a21f0 591 debug(2, "alsa: output speed chosen is %d.", config.output_rate);
c8b0be30 592 } else {
1ca4ebcf 593 die("audio_alsa: Could not automatically set the output rate for device \"%s\": %s",
c0a3dacf 594 alsa_out_dev, snd_strerror(ret));
c8b0be30
MB
595 return ret;
596 }
597 }
598
4046c0e7 599 if (set_period_size_request != 0) {
854942df 600 debug(1, "Attempting to set the period size to %lu", period_size_requested);
4046c0e7
MB
601 ret = snd_pcm_hw_params_set_period_size_near(alsa_handle, alsa_params, &period_size_requested,
602 &dir);
603 if (ret < 0) {
604 warn("audio_alsa: cannot set period size of %lu: %s", period_size_requested,
605 snd_strerror(ret));
284cb9d3 606 return ret;
4046c0e7
MB
607 } else {
608 snd_pcm_uframes_t actual_period_size;
609 snd_pcm_hw_params_get_period_size(alsa_params, &actual_period_size, &dir);
610 if (actual_period_size != period_size_requested)
555bb97a
MB
611 inform("Actual period size set to a different value than requested. "
612 "Requested: %lu, actual "
4046c0e7
MB
613 "setting: %lu",
614 period_size_requested, actual_period_size);
fc492bea 615 }
4046c0e7 616 }
e513e533 617
4046c0e7
MB
618 if (set_buffer_size_request != 0) {
619 debug(1, "Attempting to set the buffer size to %lu", buffer_size_requested);
620 ret = snd_pcm_hw_params_set_buffer_size_near(alsa_handle, alsa_params, &buffer_size_requested);
621 if (ret < 0) {
622 warn("audio_alsa: cannot set buffer size of %lu: %s", buffer_size_requested,
623 snd_strerror(ret));
284cb9d3 624 return ret;
4046c0e7
MB
625 } else {
626 snd_pcm_uframes_t actual_buffer_size;
627 snd_pcm_hw_params_get_buffer_size(alsa_params, &actual_buffer_size);
628 if (actual_buffer_size != buffer_size_requested)
555bb97a
MB
629 inform("Actual period size set to a different value than requested. "
630 "Requested: %lu, actual "
4046c0e7
MB
631 "setting: %lu",
632 buffer_size_requested, actual_buffer_size);
01e51285 633 }
4046c0e7 634 }
01e51285 635
4046c0e7
MB
636 ret = snd_pcm_hw_params(alsa_handle, alsa_params);
637 if (ret < 0) {
1ca4ebcf 638 die("audio_alsa: Unable to set hw parameters for device \"%s\": %s.", alsa_out_dev,
c0a3dacf 639 snd_strerror(ret));
284cb9d3 640 return ret;
f7077e70 641 }
ae0c9745 642
bd81e733 643 // check parameters after attempting to set them
ea20840d 644
4046c0e7
MB
645 if (set_period_size_request != 0) {
646 snd_pcm_uframes_t actual_period_size;
647 snd_pcm_hw_params_get_period_size(alsa_params, &actual_period_size, &dir);
648 if (actual_period_size != period_size_requested)
555bb97a
MB
649 inform("Actual period size set to a different value than requested. "
650 "Requested: %lu, actual "
4046c0e7
MB
651 "setting: %lu",
652 period_size_requested, actual_period_size);
0f14aad8 653 }
277d401d 654
4046c0e7
MB
655 if (set_buffer_size_request != 0) {
656 snd_pcm_uframes_t actual_buffer_size;
657 snd_pcm_hw_params_get_buffer_size(alsa_params, &actual_buffer_size);
658 if (actual_buffer_size != buffer_size_requested)
555bb97a
MB
659 inform("Actual period size set to a different value than requested. "
660 "Requested: %lu, actual "
4046c0e7
MB
661 "setting: %lu",
662 buffer_size_requested, actual_buffer_size);
22a8664d 663 }
ae0c9745 664
f13f22d8 665 if (actual_sample_rate != config.output_rate) {
0f1118c1 666 die("Can't set the output DAC to the requested frame rate of %d fps.", config.output_rate);
284cb9d3 667 return -EINVAL;
8e847aa4 668 }
c8b0be30
MB
669
670 use_monotonic_clock = snd_pcm_hw_params_is_monotonic(alsa_params);
8e847aa4 671
4046c0e7 672 ret = snd_pcm_hw_params_get_buffer_size(alsa_params, &actual_buffer_length);
22a8664d 673 if (ret < 0) {
4046c0e7 674 warn("audio_alsa: Unable to get hw buffer length for device \"%s\": %s.", alsa_out_dev,
76c5dd92 675 snd_strerror(ret));
284cb9d3 676 return ret;
0499743b 677 }
4046c0e7
MB
678
679 ret = snd_pcm_sw_params_current(alsa_handle, alsa_swparams);
22a8664d 680 if (ret < 0) {
555bb97a
MB
681 warn("audio_alsa: Unable to get current sw parameters for device \"%s\": "
682 "%s.",
683 alsa_out_dev, snd_strerror(ret));
284cb9d3 684 return ret;
ae0c9745
MB
685 }
686
4046c0e7 687 ret = snd_pcm_sw_params_set_tstamp_mode(alsa_handle, alsa_swparams, SND_PCM_TSTAMP_ENABLE);
22a8664d 688 if (ret < 0) {
4046c0e7 689 warn("audio_alsa: Can't enable timestamp mode of device: \"%s\": %s.", alsa_out_dev,
76c5dd92 690 snd_strerror(ret));
284cb9d3 691 return ret;
ae0c9745 692 }
22a8664d 693
4046c0e7
MB
694 /* write the sw parameters */
695 ret = snd_pcm_sw_params(alsa_handle, alsa_swparams);
22a8664d 696 if (ret < 0) {
1d32976d 697 warn("audio_alsa: Unable to set software parameters of device: \"%s\": %s.", alsa_out_dev,
76c5dd92 698 snd_strerror(ret));
284cb9d3 699 return ret;
ae0c9745 700 }
c8b0be30 701
06e9f370
MB
702 ret = snd_pcm_prepare(alsa_handle);
703 if (ret < 0) {
c8b0be30 704 warn("audio_alsa: Unable to prepare the device: \"%s\": %s.", alsa_out_dev, snd_strerror(ret));
06e9f370
MB
705 return ret;
706 }
ae0c9745 707
4046c0e7
MB
708 if (actual_buffer_length < config.audio_backend_buffer_desired_length + minimal_buffer_headroom) {
709 /*
710 // the dac buffer is too small, so let's try to set it
711 buffer_size =
712 config.audio_backend_buffer_desired_length + requested_buffer_headroom;
713 ret = snd_pcm_hw_params_set_buffer_size_near(alsa_handle, alsa_params,
714 &buffer_size);
715 if (ret < 0)
716 die("audio_alsa: Unable to set hw buffer size to %lu for device \"%s\": "
717 "%s.",
718 config.audio_backend_buffer_desired_length +
719 requested_buffer_headroom,
720 alsa_out_dev, snd_strerror(ret));
721 if (config.audio_backend_buffer_desired_length + minimal_buffer_headroom >
722 buffer_size) {
723 die("audio_alsa: Can't set hw buffer size to %lu or more for device "
724 "\"%s\". Requested size: %lu, granted size: %lu.",
725 config.audio_backend_buffer_desired_length + minimal_buffer_headroom,
726 alsa_out_dev, config.audio_backend_buffer_desired_length +
727 requested_buffer_headroom,
728 buffer_size);
064bd293 729 }
4046c0e7 730 */
54d761ff
MB
731 debug(1,
732 "The alsa buffer is smaller (%lu bytes) than the desired backend "
733 "buffer "
734 "length (%ld) you have chosen.",
4046c0e7 735 actual_buffer_length, config.audio_backend_buffer_desired_length);
cbc4caa6 736 }
c8b0be30
MB
737
738 if (config.use_precision_timing == YNA_YES)
986f2fb4
MB
739 delay_and_status = precision_delay_and_status;
740 else if (config.use_precision_timing == YNA_AUTO) {
1d32976d 741 if (precision_delay_available()) {
986f2fb4 742 delay_and_status = precision_delay_and_status;
c8b0be30 743 debug(2, "alsa: precision timing selected for \"auto\" mode");
986f2fb4
MB
744 }
745 }
cbc4caa6 746
4046c0e7
MB
747 if (alsa_characteristics_already_listed == 0) {
748 alsa_characteristics_already_listed = 1;
749 int log_level = 2; // the level at which debug information should be output
750 // int rc;
751 snd_pcm_access_t access_type;
752 snd_pcm_format_t format_type;
753 snd_pcm_subformat_t subformat_type;
754 // unsigned int val, val2;
755 unsigned int uval, uval2;
756 int sval;
757 int dir;
758 snd_pcm_uframes_t frames;
759
760 debug(log_level, "PCM handle name = '%s'", snd_pcm_name(alsa_handle));
761
60487c86
MB
762 // ret = snd_pcm_hw_params_any(alsa_handle, alsa_params);
763 // if (ret < 0) {
764 // die("audio_alsa: Cannpot get configuration for
555bb97a
MB
765 // device
766 //\"%s\":
767 // no
4046c0e7
MB
768 // configurations
769 //"
60487c86
MB
770 // "available",
771 // alsa_out_dev);
772 // }
4046c0e7
MB
773
774 debug(log_level, "alsa device parameters:");
775
776 snd_pcm_hw_params_get_access(alsa_params, &access_type);
777 debug(log_level, " access type = %s", snd_pcm_access_name(access_type));
778
779 snd_pcm_hw_params_get_format(alsa_params, &format_type);
780 debug(log_level, " format = '%s' (%s)", snd_pcm_format_name(format_type),
781 snd_pcm_format_description(format_type));
782
783 snd_pcm_hw_params_get_subformat(alsa_params, &subformat_type);
784 debug(log_level, " subformat = '%s' (%s)", snd_pcm_subformat_name(subformat_type),
785 snd_pcm_subformat_description(subformat_type));
786
787 snd_pcm_hw_params_get_channels(alsa_params, &uval);
788 debug(log_level, " number of channels = %u", uval);
789
790 sval = snd_pcm_hw_params_get_sbits(alsa_params);
791 debug(log_level, " number of significant bits = %d", sval);
792
793 snd_pcm_hw_params_get_rate(alsa_params, &uval, &dir);
794 switch (dir) {
795 case -1:
796 debug(log_level, " rate = %u frames per second (<).", uval);
797 break;
798 case 0:
799 debug(log_level, " rate = %u frames per second (precisely).", uval);
800 break;
801 case 1:
802 debug(log_level, " rate = %u frames per second (>).", uval);
803 break;
064bd293 804 }
ae0c9745 805
c0a3dacf
MB
806 if ((snd_pcm_hw_params_get_rate_numden(alsa_params, &uval, &uval2) == 0) && (uval2 != 0))
807 // watch for a divide by zero too!
4046c0e7 808 debug(log_level, " precise (rational) rate = %.3f frames per second (i.e. %u/%u).", uval,
14bfba27
MB
809 uval2, ((double)uval) / uval2);
810 else
4046c0e7
MB
811 debug(log_level, " precise (rational) rate information unavailable.");
812
813 snd_pcm_hw_params_get_period_time(alsa_params, &uval, &dir);
814 switch (dir) {
815 case -1:
816 debug(log_level, " period_time = %u us (<).", uval);
817 break;
818 case 0:
819 debug(log_level, " period_time = %u us (precisely).", uval);
820 break;
821 case 1:
822 debug(log_level, " period_time = %u us (>).", uval);
823 break;
824 }
825
826 snd_pcm_hw_params_get_period_size(alsa_params, &frames, &dir);
827 switch (dir) {
828 case -1:
829 debug(log_level, " period_size = %lu frames (<).", frames);
830 break;
831 case 0:
832 debug(log_level, " period_size = %lu frames (precisely).", frames);
833 break;
834 case 1:
835 debug(log_level, " period_size = %lu frames (>).", frames);
836 break;
837 }
838
839 snd_pcm_hw_params_get_buffer_time(alsa_params, &uval, &dir);
840 switch (dir) {
841 case -1:
842 debug(log_level, " buffer_time = %u us (<).", uval);
843 break;
844 case 0:
845 debug(log_level, " buffer_time = %u us (precisely).", uval);
846 break;
847 case 1:
848 debug(log_level, " buffer_time = %u us (>).", uval);
849 break;
850 }
851
852 snd_pcm_hw_params_get_buffer_size(alsa_params, &frames);
853 switch (dir) {
854 case -1:
855 debug(log_level, " buffer_size = %lu frames (<).", frames);
856 break;
857 case 0:
858 debug(log_level, " buffer_size = %lu frames (precisely).", frames);
859 break;
860 case 1:
861 debug(log_level, " buffer_size = %lu frames (>).", frames);
862 break;
863 }
864
865 snd_pcm_hw_params_get_periods(alsa_params, &uval, &dir);
866 switch (dir) {
867 case -1:
868 debug(log_level, " periods_per_buffer = %u (<).", uval);
869 break;
870 case 0:
871 debug(log_level, " periods_per_buffer = %u (precisely).", uval);
872 break;
873 case 1:
874 debug(log_level, " periods_per_buffer = %u (>).", uval);
875 break;
064bd293 876 }
2c40f23f 877 }
4046c0e7
MB
878 return 0;
879}
880
fd880056 881static int open_alsa_device(int do_auto_setup) {
4046c0e7
MB
882 int result;
883 int oldState;
884 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState); // make this un-cancellable
83c0405d 885 result = actual_open_alsa_device(do_auto_setup);
4046c0e7
MB
886 pthread_setcancelstate(oldState, NULL);
887 return result;
888}
ae0c9745 889
fd880056 890static int prepare_mixer() {
c5ff0dfe 891 int response = 0;
e8a92d3c 892 // do any alsa device initialisation (general case)
c5ff0dfe 893 // at present, this is only needed if a hardware mixer is being used
e8a92d3c 894 // if there's a hardware mixer, it needs to be initialised before use
54d761ff
MB
895 if (alsa_mix_ctrl == NULL) {
896 audio_alsa.volume = NULL;
897 audio_alsa.parameters = NULL;
898 audio_alsa.mute = NULL;
899 } else {
900 debug(2, "alsa: hardware mixer prepare");
901 int oldState;
902 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState); // make this un-cancellable
903
904 if (alsa_mix_dev == NULL)
905 alsa_mix_dev = alsa_out_dev;
906
907 // Now, start trying to initialise the alsa device with the settings
908 // obtained
909 pthread_cleanup_debug_mutex_lock(&alsa_mixer_mutex, 1000, 1);
76387f82 910 if (open_mixer() == 0) {
54d761ff 911 if (snd_mixer_selem_get_playback_volume_range(alsa_mix_elem, &alsa_mix_minv, &alsa_mix_maxv) <
76387f82 912 0) {
54d761ff 913 debug(1, "Can't read mixer's [linear] min and max volumes.");
76387f82 914 } else {
54d761ff
MB
915 if (snd_mixer_selem_get_playback_dB_range(alsa_mix_elem, &alsa_mix_mindb,
916 &alsa_mix_maxdb) == 0) {
917
918 audio_alsa.volume = &volume; // insert the volume function now we
919 // know it can do dB stuff
920 audio_alsa.parameters = &parameters; // likewise the parameters stuff
921 if (alsa_mix_mindb == SND_CTL_TLV_DB_GAIN_MUTE) {
922 // For instance, the Raspberry Pi does this
00bc837b 923 debug(2, "Lowest dB value is a mute");
54d761ff
MB
924 mixer_volume_setting_gives_mute = 1;
925 alsa_mix_mute = SND_CTL_TLV_DB_GAIN_MUTE; // this may not be
926 // necessary -- it's
927 // always
928 // going to be SND_CTL_TLV_DB_GAIN_MUTE, right?
929 // debug(1, "Try minimum volume + 1 as lowest true attenuation
930 // value");
931 if (snd_mixer_selem_ask_playback_vol_dB(alsa_mix_elem, alsa_mix_minv + 1,
932 &alsa_mix_mindb) != 0)
933 debug(1, "Can't get dB value corresponding to a minimum volume "
934 "+ 1.");
935 }
936 debug(3, "Hardware mixer has dB volume from %f to %f.", (1.0 * alsa_mix_mindb) / 100.0,
937 (1.0 * alsa_mix_maxdb) / 100.0);
938 } else {
939 // use the linear scale and do the db conversion ourselves
940 warn("The hardware mixer specified -- \"%s\" -- does not have "
941 "a dB volume scale.",
942 alsa_mix_ctrl);
943
76387f82 944 if ((response = snd_ctl_open(&ctl, alsa_mix_dev, 0)) < 0) {
54d761ff 945 warn("Cannot open control \"%s\"", alsa_mix_dev);
54d761ff 946 }
76387f82 947 if ((response = snd_ctl_elem_id_malloc(&elem_id)) < 0) {
54d761ff
MB
948 debug(1, "Cannot allocate memory for control \"%s\"", alsa_mix_dev);
949 elem_id = NULL;
c5ff0dfe 950 } else {
54d761ff
MB
951 snd_ctl_elem_id_set_interface(elem_id, SND_CTL_ELEM_IFACE_MIXER);
952 snd_ctl_elem_id_set_name(elem_id, alsa_mix_ctrl);
953
954 if (snd_ctl_get_dB_range(ctl, elem_id, &alsa_mix_mindb, &alsa_mix_maxdb) == 0) {
955 debug(1,
956 "alsa: hardware mixer \"%s\" selected, with dB volume "
957 "from %f to %f.",
958 alsa_mix_ctrl, (1.0 * alsa_mix_mindb) / 100.0, (1.0 * alsa_mix_maxdb) / 100.0);
959 has_softvol = 1;
960 audio_alsa.volume = &volume; // insert the volume function now
961 // we know it can do dB stuff
962 audio_alsa.parameters = &parameters; // likewise the parameters stuff
c5ff0dfe 963 } else {
54d761ff 964 debug(1, "Cannot get the dB range from the volume control \"%s\"", alsa_mix_ctrl);
c5ff0dfe
MB
965 }
966 }
c5ff0dfe
MB
967 }
968 }
54d761ff
MB
969 if (((config.alsa_use_hardware_mute == 1) &&
970 (snd_mixer_selem_has_playback_switch(alsa_mix_elem))) ||
971 mixer_volume_setting_gives_mute) {
972 audio_alsa.mute = &mute; // insert the mute function now we know it
973 // can do muting stuff
974 // debug(1, "Has mixer and mute ability we will use.");
975 } else {
976 // debug(1, "Has mixer but not using hardware mute.");
977 }
76387f82
MB
978 if (response == 0)
979 response = close_mixer();
555bb97a 980 }
54d761ff
MB
981 debug_mutex_unlock(&alsa_mixer_mutex, 3); // release the mutex
982 pthread_cleanup_pop(0);
983 pthread_setcancelstate(oldState, NULL);
984 }
c5ff0dfe
MB
985 return response;
986}
987
fd880056 988static int alsa_device_init() { return prepare_mixer(); }
e8a92d3c 989
4046c0e7
MB
990static int init(int argc, char **argv) {
991 // for debugging
992 snd_output_stdio_attach(&output, stdout, 0);
754155ce 993
4046c0e7
MB
994 // debug(2,"audio_alsa init called.");
995 int response = 0; // this will be what we return to the caller.
c5ff0dfe 996 alsa_device_initialised = 0;
4046c0e7
MB
997 const char *str;
998 int value;
999 // double dvalue;
754155ce 1000
4046c0e7 1001 // set up default values first
bd81e733
MB
1002
1003 alsa_backend_state = abm_disconnected; // startup state
56bf8862 1004 debug(2, "alsa: init() -- alsa_backend_state => abm_disconnected.");
4046c0e7
MB
1005 set_period_size_request = 0;
1006 set_buffer_size_request = 0;
1007 config.alsa_use_hardware_mute = 0; // don't use it by default
ab1f55fe 1008
4046c0e7 1009 config.audio_backend_latency_offset = 0;
c958d506 1010 config.audio_backend_buffer_desired_length = 0.200;
80f15e1f 1011 config.audio_backend_buffer_interpolation_threshold_in_seconds =
c958d506 1012 0.120; // below this, basic interpolation will be used to save time.
4046c0e7 1013 config.alsa_maximum_stall_time = 0.200; // 200 milliseconds -- if it takes longer, it's a problem
a8faacd3 1014 config.disable_standby_mode_silence_threshold =
2e442853 1015 0.040; // start sending silent frames if the delay goes below this time
a8faacd3 1016 config.disable_standby_mode_silence_scan_interval = 0.004; // check silence threshold this often
4613ee6b 1017
48043a81
MB
1018 stall_monitor_error_threshold =
1019 (uint64_t)1000000 * config.alsa_maximum_stall_time; // stall time max to microseconds;
1020 stall_monitor_error_threshold = (stall_monitor_error_threshold << 32) / 1000000; // now in fp form
a8faacd3 1021 debug(1, "alsa: alsa_maximum_stall_time of %f sec.", config.alsa_maximum_stall_time);
48043a81
MB
1022
1023 stall_monitor_start_time = 0;
1024 stall_monitor_frame_count = 0;
c8b0be30 1025
aac57c9c
MB
1026 config.disable_standby_mode = disable_standby_off;
1027 config.keep_dac_busy = 0;
1028 config.use_precision_timing = YNA_AUTO;
ae0c9745 1029
4046c0e7
MB
1030 // get settings from settings file first, allow them to be overridden by
1031 // command line options
ae0c9745 1032
555bb97a
MB
1033 // do the "general" audio options. Note, these options are in the "general"
1034 // stanza!
4046c0e7 1035 parse_general_audio_options();
e7f70fba 1036
4046c0e7
MB
1037 if (config.cfg != NULL) {
1038 double dvalue;
ae0c9745 1039
4046c0e7
MB
1040 /* Get the Output Device Name. */
1041 if (config_lookup_string(config.cfg, "alsa.output_device", &str)) {
1042 alsa_out_dev = (char *)str;
1043 }
e7f70fba 1044
4046c0e7 1045 /* Get the Mixer Type setting. */
e7f70fba 1046
4046c0e7
MB
1047 if (config_lookup_string(config.cfg, "alsa.mixer_type", &str)) {
1048 inform("The alsa mixer_type setting is deprecated and has been ignored. "
1049 "FYI, using the \"mixer_control_name\" setting automatically "
1050 "chooses a hardware mixer.");
d5881f63 1051 }
e7f70fba 1052
4046c0e7
MB
1053 /* Get the Mixer Device Name. */
1054 if (config_lookup_string(config.cfg, "alsa.mixer_device", &str)) {
1055 alsa_mix_dev = (char *)str;
1056 }
064bd293 1057
4046c0e7
MB
1058 /* Get the Mixer Control Name. */
1059 if (config_lookup_string(config.cfg, "alsa.mixer_control_name", &str)) {
1060 alsa_mix_ctrl = (char *)str;
4046c0e7 1061 }
064bd293 1062
6ced6bc6
MB
1063 // Get the Mixer Control Index
1064 if (config_lookup_int(config.cfg, "alsa.mixer_control_index", &value)) {
1065 alsa_mix_index = value;
1066 }
1067
4046c0e7
MB
1068 /* Get the disable_synchronization setting. */
1069 if (config_lookup_string(config.cfg, "alsa.disable_synchronization", &str)) {
1070 if (strcasecmp(str, "no") == 0)
1071 config.no_sync = 0;
1072 else if (strcasecmp(str, "yes") == 0)
1073 config.no_sync = 1;
1074 else {
555bb97a
MB
1075 warn("Invalid disable_synchronization option choice \"%s\". It should "
1076 "be \"yes\" or "
4046c0e7
MB
1077 "\"no\". It is set to \"no\".");
1078 config.no_sync = 0;
1079 }
1080 }
064bd293 1081
4046c0e7
MB
1082 /* Get the mute_using_playback_switch setting. */
1083 if (config_lookup_string(config.cfg, "alsa.mute_using_playback_switch", &str)) {
1084 inform("The alsa \"mute_using_playback_switch\" setting is deprecated. "
1085 "Please use the \"use_hardware_mute_if_available\" setting instead.");
1086 if (strcasecmp(str, "no") == 0)
1087 config.alsa_use_hardware_mute = 0;
1088 else if (strcasecmp(str, "yes") == 0)
1089 config.alsa_use_hardware_mute = 1;
1090 else {
555bb97a
MB
1091 warn("Invalid mute_using_playback_switch option choice \"%s\". It "
1092 "should be \"yes\" or "
4046c0e7
MB
1093 "\"no\". It is set to \"no\".");
1094 config.alsa_use_hardware_mute = 0;
1095 }
1096 }
064bd293 1097
4046c0e7
MB
1098 /* Get the use_hardware_mute_if_available setting. */
1099 if (config_lookup_string(config.cfg, "alsa.use_hardware_mute_if_available", &str)) {
1100 if (strcasecmp(str, "no") == 0)
1101 config.alsa_use_hardware_mute = 0;
1102 else if (strcasecmp(str, "yes") == 0)
1103 config.alsa_use_hardware_mute = 1;
1104 else {
555bb97a
MB
1105 warn("Invalid use_hardware_mute_if_available option choice \"%s\". It "
1106 "should be \"yes\" or "
4046c0e7
MB
1107 "\"no\". It is set to \"no\".");
1108 config.alsa_use_hardware_mute = 0;
1109 }
1110 }
064bd293 1111
4046c0e7
MB
1112 /* Get the output format, using the same names as aplay does*/
1113 if (config_lookup_string(config.cfg, "alsa.output_format", &str)) {
c8b0be30
MB
1114 int temp_output_format_auto_requested = config.output_format_auto_requested;
1115 config.output_format_auto_requested = 0; // assume a valid format will be given.
4046c0e7
MB
1116 if (strcasecmp(str, "S16") == 0)
1117 config.output_format = SPS_FORMAT_S16;
1d32976d
MB
1118 else if (strcasecmp(str, "S16_LE") == 0)
1119 config.output_format = SPS_FORMAT_S16_LE;
1120 else if (strcasecmp(str, "S16_BE") == 0)
1121 config.output_format = SPS_FORMAT_S16_BE;
4046c0e7
MB
1122 else if (strcasecmp(str, "S24") == 0)
1123 config.output_format = SPS_FORMAT_S24;
1d32976d
MB
1124 else if (strcasecmp(str, "S24_LE") == 0)
1125 config.output_format = SPS_FORMAT_S24_LE;
1126 else if (strcasecmp(str, "S24_BE") == 0)
1127 config.output_format = SPS_FORMAT_S24_BE;
4046c0e7
MB
1128 else if (strcasecmp(str, "S24_3LE") == 0)
1129 config.output_format = SPS_FORMAT_S24_3LE;
1130 else if (strcasecmp(str, "S24_3BE") == 0)
1131 config.output_format = SPS_FORMAT_S24_3BE;
1132 else if (strcasecmp(str, "S32") == 0)
1133 config.output_format = SPS_FORMAT_S32;
1d32976d
MB
1134 else if (strcasecmp(str, "S32_LE") == 0)
1135 config.output_format = SPS_FORMAT_S32_LE;
1136 else if (strcasecmp(str, "S32_BE") == 0)
1137 config.output_format = SPS_FORMAT_S32_BE;
4046c0e7
MB
1138 else if (strcasecmp(str, "U8") == 0)
1139 config.output_format = SPS_FORMAT_U8;
1140 else if (strcasecmp(str, "S8") == 0)
1141 config.output_format = SPS_FORMAT_S8;
83c0405d
MB
1142 else if (strcasecmp(str, "auto") == 0)
1143 config.output_format_auto_requested = 1;
4046c0e7 1144 else {
c8b0be30
MB
1145 config.output_format_auto_requested =
1146 temp_output_format_auto_requested; // format was invalid; recall the original setting
76ad4e6a 1147 warn("Invalid output format \"%s\". It should be \"auto\", \"U8\", \"S8\", "
1d32976d 1148 "\"S16\", \"S24\", \"S24_LE\", \"S24_BE\", "
4046c0e7 1149 "\"S24_3LE\", \"S24_3BE\" or "
c8b0be30 1150 "\"S32\", \"S32_LE\", \"S32_BE\". It remains set to \"%s\".",
54d761ff
MB
1151 str,
1152 config.output_format_auto_requested == 1
1153 ? "auto"
1154 : sps_format_description_string(config.output_format));
4046c0e7
MB
1155 }
1156 }
064bd293 1157
83c0405d 1158 if (config_lookup_string(config.cfg, "alsa.output_rate", &str)) {
c8b0be30
MB
1159 if (strcasecmp(str, "auto") == 0) {
1160 config.output_rate_auto_requested = 1;
1161 } else {
1162 if (config.output_rate_auto_requested == 1)
1163 warn("Invalid output rate \"%s\". It should be \"auto\", 44100, 88200, 176400 or 352800. "
1164 "It remains set to \"auto\". Note: numbers should not be placed in quotes.",
1165 str);
1166 else
1167 warn("Invalid output rate \"%s\". It should be \"auto\", 44100, 88200, 176400 or 352800. "
1168 "It remains set to %d. Note: numbers should not be placed in quotes.",
1169 str, config.output_rate);
1170 }
1171 }
1172
1173 /* Get the output rate, which must be a multiple of 44,100*/
1174 if (config_lookup_int(config.cfg, "alsa.output_rate", &value)) {
1175 debug(1, "alsa output rate is %d frames per second", value);
1176 switch (value) {
1177 case 44100:
1178 case 88200:
1179 case 176400:
1180 case 352800:
1181 config.output_rate = value;
1182 config.output_rate_auto_requested = 0;
1183 break;
1184 default:
1185 if (config.output_rate_auto_requested == 1)
1186 warn("Invalid output rate \"%d\". It should be \"auto\", 44100, 88200, 176400 or 352800. "
1187 "It remains set to \"auto\".",
1188 value);
1189 else
1190 warn("Invalid output rate \"%d\".It should be \"auto\", 44100, 88200, 176400 or 352800. "
1191 "It remains set to %d.",
1192 value, config.output_rate);
1193 }
1194 }
064bd293 1195
4046c0e7
MB
1196 /* Get the use_mmap_if_available setting. */
1197 if (config_lookup_string(config.cfg, "alsa.use_mmap_if_available", &str)) {
1198 if (strcasecmp(str, "no") == 0)
1199 config.no_mmap = 1;
1200 else if (strcasecmp(str, "yes") == 0)
1201 config.no_mmap = 0;
1202 else {
555bb97a
MB
1203 warn("Invalid use_mmap_if_available option choice \"%s\". It should be "
1204 "\"yes\" or \"no\". "
76ad4e6a 1205 "It remains set to \"yes\".");
4046c0e7
MB
1206 config.no_mmap = 0;
1207 }
1208 }
1209 /* Get the optional period size value */
1210 if (config_lookup_int(config.cfg, "alsa.period_size", &value)) {
1211 set_period_size_request = 1;
1212 debug(1, "Value read for period size is %d.", value);
1213 if (value < 0) {
1214 warn("Invalid alsa period size setting \"%d\". It "
1215 "must be greater than 0. No setting is made.",
1216 value);
1217 set_period_size_request = 0;
1218 } else {
1219 period_size_requested = value;
1220 }
1221 }
064bd293 1222
4046c0e7
MB
1223 /* Get the optional buffer size value */
1224 if (config_lookup_int(config.cfg, "alsa.buffer_size", &value)) {
1225 set_buffer_size_request = 1;
1226 debug(1, "Value read for buffer size is %d.", value);
1227 if (value < 0) {
1228 warn("Invalid alsa buffer size setting \"%d\". It "
1229 "must be greater than 0. No setting is made.",
1230 value);
1231 set_buffer_size_request = 0;
1232 } else {
1233 buffer_size_requested = value;
1234 }
1235 }
064bd293 1236
4046c0e7
MB
1237 /* Get the optional alsa_maximum_stall_time setting. */
1238 if (config_lookup_float(config.cfg, "alsa.maximum_stall_time", &dvalue)) {
1239 if (dvalue < 0.0) {
1240 warn("Invalid alsa maximum write time setting \"%f\". It "
1241 "must be greater than 0. Default is \"%f\". No setting is made.",
1242 dvalue, config.alsa_maximum_stall_time);
1243 } else {
1244 config.alsa_maximum_stall_time = dvalue;
1245 }
064bd293
MB
1246 }
1247
a8faacd3
MB
1248 /* Get the optional disable_standby_mode_silence_threshold setting. */
1249 if (config_lookup_float(config.cfg, "alsa.disable_standby_mode_silence_threshold", &dvalue)) {
1250 if (dvalue < 0.0) {
1251 warn("Invalid alsa disable_standby_mode_silence_threshold setting \"%f\". It "
1252 "must be greater than 0. Default is \"%f\". No setting is made.",
1253 dvalue, config.disable_standby_mode_silence_threshold);
1254 } else {
1255 config.disable_standby_mode_silence_threshold = dvalue;
1256 }
1257 }
1258
1259 /* Get the optional disable_standby_mode_silence_scan_interval setting. */
1260 if (config_lookup_float(config.cfg, "alsa.disable_standby_mode_silence_scan_interval",
1261 &dvalue)) {
1262 if (dvalue < 0.0) {
1263 warn("Invalid alsa disable_standby_mode_silence_scan_interval setting \"%f\". It "
1264 "must be greater than 0. Default is \"%f\". No setting is made.",
1265 dvalue, config.disable_standby_mode_silence_scan_interval);
1266 } else {
1267 config.disable_standby_mode_silence_scan_interval = dvalue;
1268 }
1269 }
1270
c86823c3 1271 /* Get the optional disable_standby_mode setting. */
c86823c3 1272 if (config_lookup_string(config.cfg, "alsa.disable_standby_mode", &str)) {
c8b0be30
MB
1273 if ((strcasecmp(str, "no") == 0) || (strcasecmp(str, "off") == 0) ||
1274 (strcasecmp(str, "never") == 0))
c86823c3 1275 config.disable_standby_mode = disable_standby_off;
c8b0be30
MB
1276 else if ((strcasecmp(str, "yes") == 0) || (strcasecmp(str, "on") == 0) ||
1277 (strcasecmp(str, "always") == 0)) {
8b589879 1278 config.disable_standby_mode = disable_standby_always;
c86823c3 1279 config.keep_dac_busy = 1;
83c0405d
MB
1280 } else if (strcasecmp(str, "auto") == 0)
1281 config.disable_standby_mode = disable_standby_auto;
c86823c3
MB
1282 else {
1283 warn("Invalid disable_standby_mode option choice \"%s\". It should be "
83c0405d 1284 "\"always\", \"auto\" or \"never\". "
c8b0be30
MB
1285 "It remains set to \"never\".",
1286 str);
c86823c3 1287 }
4ba0947d 1288 }
c86823c3 1289
aac57c9c 1290 if (config_lookup_string(config.cfg, "alsa.use_precision_timing", &str)) {
c8b0be30
MB
1291 if ((strcasecmp(str, "no") == 0) || (strcasecmp(str, "off") == 0) ||
1292 (strcasecmp(str, "never") == 0))
aac57c9c 1293 config.use_precision_timing = YNA_NO;
c8b0be30
MB
1294 else if ((strcasecmp(str, "yes") == 0) || (strcasecmp(str, "on") == 0) ||
1295 (strcasecmp(str, "always") == 0)) {
aac57c9c
MB
1296 config.use_precision_timing = YNA_YES;
1297 config.keep_dac_busy = 1;
1298 } else if (strcasecmp(str, "auto") == 0)
1299 config.use_precision_timing = YNA_AUTO;
1300 else {
1301 warn("Invalid use_precision_timing option choice \"%s\". It should be "
1302 "\"yes\", \"auto\" or \"no\". "
c8b0be30 1303 "It remains set to \"%s\".",
c0a3dacf
MB
1304 config.use_precision_timing == YNA_NO ? "no"
1305 : config.use_precision_timing == YNA_AUTO ? "auto"
1306 : "yes");
aac57c9c
MB
1307 }
1308 }
1309
c8b0be30 1310 debug(1, "alsa: disable_standby_mode is \"%s\".",
c0a3dacf
MB
1311 config.disable_standby_mode == disable_standby_off ? "never"
1312 : config.disable_standby_mode == disable_standby_always ? "always"
1313 : "auto");
a8faacd3
MB
1314 debug(1, "alsa: disable_standby_mode_silence_threshold is %f seconds.",
1315 config.disable_standby_mode_silence_threshold);
1316 debug(1, "alsa: disable_standby_mode_silence_scan_interval is %f seconds.",
1317 config.disable_standby_mode_silence_scan_interval);
4046c0e7 1318 }
064bd293 1319
4046c0e7
MB
1320 optind = 1; // optind=0 is equivalent to optind=1 plus special behaviour
1321 argv--; // so we shift the arguments to satisfy getopt()
1322 argc++;
1323 // some platforms apparently require optreset = 1; - which?
1324 int opt;
1325 while ((opt = getopt(argc, argv, "d:t:m:c:i:")) > 0) {
1326 switch (opt) {
1327 case 'd':
1328 alsa_out_dev = optarg;
064bd293 1329 break;
064bd293 1330
4046c0e7
MB
1331 case 't':
1332 inform("The alsa backend -t option is deprecated and has been ignored. "
1333 "FYI, using the -c option automatically chooses a hardware "
1334 "mixer.");
064bd293 1335 break;
064bd293 1336
4046c0e7
MB
1337 case 'm':
1338 alsa_mix_dev = optarg;
064bd293 1339 break;
4046c0e7
MB
1340 case 'c':
1341 alsa_mix_ctrl = optarg;
064bd293 1342 break;
4046c0e7
MB
1343 case 'i':
1344 alsa_mix_index = strtol(optarg, NULL, 10);
064bd293 1345 break;
4046c0e7
MB
1346 default:
1347 warn("Invalid audio option \"-%c\" specified -- ignored.", opt);
1348 help();
064bd293 1349 }
4046c0e7 1350 }
064bd293 1351
4046c0e7
MB
1352 if (optind < argc) {
1353 warn("Invalid audio argument: \"%s\" -- ignored", argv[optind]);
1354 }
064bd293 1355
4046c0e7 1356 debug(1, "alsa: output device name is \"%s\".", alsa_out_dev);
555bb97a 1357
555bb97a
MB
1358 // so, now, if the option to keep the DAC running has been selected, start a
1359 // thread to monitor the
4046c0e7
MB
1360 // length of the queue
1361 // if the queue gets too short, stuff it with silence
1362
4ba0947d 1363 pthread_create(&alsa_buffer_monitor_thread, NULL, &alsa_buffer_monitor_thread_code, NULL);
4046c0e7
MB
1364
1365 return response;
83504880
MB
1366}
1367
4046c0e7 1368static void deinit(void) {
3b4654df
MB
1369 int oldState;
1370 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState); // make this un-cancellable
4046c0e7
MB
1371 // debug(2,"audio_alsa deinit called.");
1372 stop();
405a028f 1373 debug(2, "Cancel buffer monitor thread.");
ad6c721d 1374 pthread_cancel(alsa_buffer_monitor_thread);
405a028f 1375 debug(3, "Join buffer monitor thread.");
ad6c721d 1376 pthread_join(alsa_buffer_monitor_thread, NULL);
3b4654df 1377 pthread_setcancelstate(oldState, NULL);
3b4654df
MB
1378}
1379
fd880056 1380static int set_mute_state() {
60487c86 1381 int response = 1; // some problem expected, e.g. no mixer or not allowed to use it or disconnected
bfc7b9b7
MB
1382 int oldState;
1383 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState); // make this un-cancellable
0c552148 1384 pthread_cleanup_debug_mutex_lock(&alsa_mixer_mutex, 10000, 0);
2c0250b3 1385 if ((alsa_backend_state != abm_disconnected) && (config.alsa_use_hardware_mute == 1) &&
76387f82 1386 (open_mixer() == 0)) {
60487c86 1387 response = 0; // okay if actually using the mute facility
bfc7b9b7 1388 debug(2, "alsa: actually set_mute_state");
555bb97a
MB
1389 int mute = 0;
1390 if ((mute_requested_externally != 0) || (mute_requested_internally != 0))
2c0250b3 1391 mute = 1;
60487c86 1392 if (mute == 1) {
bfc7b9b7 1393 debug(2, "alsa: hardware mute switched on");
60487c86
MB
1394 if (snd_mixer_selem_has_playback_switch(alsa_mix_elem))
1395 snd_mixer_selem_set_playback_switch_all(alsa_mix_elem, 0);
1396 else {
1397 volume_based_mute_is_active = 1;
1398 do_snd_mixer_selem_set_playback_dB_all(alsa_mix_elem, alsa_mix_mute);
1399 }
1400 } else {
bfc7b9b7 1401 debug(2, "alsa: hardware mute switched off");
60487c86
MB
1402 if (snd_mixer_selem_has_playback_switch(alsa_mix_elem))
1403 snd_mixer_selem_set_playback_switch_all(alsa_mix_elem, 1);
1404 else {
1405 volume_based_mute_is_active = 0;
1406 do_snd_mixer_selem_set_playback_dB_all(alsa_mix_elem, set_volume);
555bb97a 1407 }
555bb97a 1408 }
60487c86 1409 close_mixer();
555bb97a 1410 }
0c552148 1411 debug_mutex_unlock(&alsa_mixer_mutex, 3); // release the mutex
c8b0be30 1412 pthread_cleanup_pop(0); // release the mutex
bfc7b9b7 1413 pthread_setcancelstate(oldState, NULL);
555bb97a
MB
1414 return response;
1415}
60487c86 1416
c8b0be30
MB
1417static void start(__attribute__((unused)) int i_sample_rate,
1418 __attribute__((unused)) int i_sample_format) {
60487c86 1419 debug(3, "audio_alsa start called.");
c8b0be30 1420
99c66385
MB
1421 // frame_index = 0;
1422 // measurement_data_is_valid = 0;
9d5ff22f 1423
46a13dce
MB
1424 stall_monitor_start_time = 0;
1425 stall_monitor_frame_count = 0;
c5ff0dfe 1426 if (alsa_device_initialised == 0) {
e8a92d3c
MB
1427 debug(1, "alsa: start() calling alsa_device_init.");
1428 alsa_device_init();
1429 alsa_device_initialised = 1;
c5ff0dfe 1430 }
2c40f23f
MB
1431}
1432
fd880056
MB
1433static int standard_delay_and_status(snd_pcm_state_t *state, snd_pcm_sframes_t *delay,
1434 yndk_type *using_update_timestamps) {
129343c1 1435 int ret = alsa_handle_status;
60c2bf27
MB
1436 if (using_update_timestamps)
1437 *using_update_timestamps = YNDK_NO;
713492a7
MB
1438
1439 snd_pcm_state_t state_temp = SND_PCM_STATE_DISCONNECTED;
1440 snd_pcm_sframes_t delay_temp = 0;
1441 if (alsa_handle != NULL) {
1442 state_temp = snd_pcm_state(alsa_handle);
1443 if ((state_temp == SND_PCM_STATE_RUNNING) || (state_temp == SND_PCM_STATE_DRAINING)) {
1444 ret = snd_pcm_delay(alsa_handle, &delay_temp);
1445 } else {
1446 // not running, thus no delay information, thus can't check for frame
1447 // rates
1448 // frame_index = 0; // we'll be starting over...
1449 // measurement_data_is_valid = 0;
1450 // delay_temp = 0;
1451 ret = 0;
1452 }
30510e72
MB
1453 } // else {
1454 // debug(1, "alsa_handle is NULL in standard_delay_and_status.");
1455 // }
c8b0be30 1456
60c2bf27
MB
1457 stall_monitor_start_time = 0; // zero if not initialised / not started / zeroed by flush
1458 stall_monitor_frame_count = 0; // set to delay at start of time, incremented by any writes
1459
9bac04e2
MB
1460 if (delay != NULL)
1461 *delay = delay_temp;
1462 if (state != NULL)
1463 *state = state_temp;
60c2bf27
MB
1464 return ret;
1465}
1466
fd880056
MB
1467static int precision_delay_and_status(snd_pcm_state_t *state, snd_pcm_sframes_t *delay,
1468 yndk_type *using_update_timestamps) {
8476e5ef
MB
1469 snd_pcm_state_t state_temp = SND_PCM_STATE_DISCONNECTED;
1470 snd_pcm_sframes_t delay_temp = 0;
1471 if (using_update_timestamps)
1472 *using_update_timestamps = YNDK_DONT_KNOW;
129343c1 1473 int ret = alsa_handle_status;
9bac04e2 1474
59d26918
MB
1475 snd_pcm_status_t *alsa_snd_pcm_status;
1476 snd_pcm_status_alloca(&alsa_snd_pcm_status);
c8b0be30 1477
59d26918
MB
1478 struct timespec tn; // time now
1479 snd_htimestamp_t update_timestamp; // actually a struct timespec
8476e5ef
MB
1480 if (alsa_handle != NULL) {
1481 ret = snd_pcm_status(alsa_handle, alsa_snd_pcm_status);
1482 if (ret == 0) {
1483 snd_pcm_status_get_htstamp(alsa_snd_pcm_status, &update_timestamp);
1484
1485 /*
1486 // must be 1.1 or later to use snd_pcm_status_get_driver_htstamp
1487 #if SND_LIB_MINOR != 0
1488 snd_htimestamp_t driver_htstamp;
1489 snd_pcm_status_get_driver_htstamp(alsa_snd_pcm_status, &driver_htstamp);
1490 uint64_t driver_htstamp_ns = driver_htstamp.tv_sec;
1491 driver_htstamp_ns = driver_htstamp_ns * 1000000000;
1492 driver_htstamp_ns = driver_htstamp_ns + driver_htstamp.tv_nsec;
1493 debug(1,"driver_htstamp: %f.", driver_htstamp_ns * 0.000000001);
1494 #endif
1495 */
1496
1497 state_temp = snd_pcm_status_get_state(alsa_snd_pcm_status);
1498
1499 if ((state_temp == SND_PCM_STATE_RUNNING) || (state_temp == SND_PCM_STATE_DRAINING)) {
1500
1501 // uint64_t update_timestamp_ns =
1502 // update_timestamp.tv_sec * (uint64_t)1000000000 + update_timestamp.tv_nsec;
1503
1504 uint64_t update_timestamp_ns = update_timestamp.tv_sec;
1505 update_timestamp_ns = update_timestamp_ns * 1000000000;
1506 update_timestamp_ns = update_timestamp_ns + update_timestamp.tv_nsec;
1507
1508 // if the update_timestamp is zero, we take this to mean that the device doesn't report
1509 // interrupt timings. (It could be that it's not a real hardware device.)
1510 // so we switch to getting the delay the regular way
1511 // i.e. using snd_pcm_delay ()
1512 if (using_update_timestamps) {
1513 if (update_timestamp_ns == 0)
1514 *using_update_timestamps = YNDK_NO;
1515 else
1516 *using_update_timestamps = YNDK_YES;
1517 }
59d26918 1518
8476e5ef
MB
1519 // user information
1520 if (update_timestamp_ns == 0) {
1521 if (delay_type_notified != 1) {
1522 debug(2, "alsa: update timestamps unavailable");
1523 delay_type_notified = 1;
1524 }
1525 } else {
1526 // diagnostic
1527 if (delay_type_notified != 0) {
1528 debug(2, "alsa: update timestamps available");
1529 delay_type_notified = 0;
1530 }
1531 }
0e37f7e7 1532
8476e5ef
MB
1533 if (update_timestamp_ns == 0) {
1534 ret = snd_pcm_delay(alsa_handle, &delay_temp);
1535 } else {
1536 delay_temp = snd_pcm_status_get_delay(alsa_snd_pcm_status);
f10fb93e 1537
8476e5ef
MB
1538 /*
1539 // It seems that the alsa library uses CLOCK_REALTIME before 1.0.28, even though
1540 // the check for monotonic returns true. Might have to watch out for this.
1541 #if SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR < 28
1542 clock_gettime(CLOCK_REALTIME, &tn);
1543 #else
1544 clock_gettime(CLOCK_MONOTONIC, &tn);
1545 #endif
1546 */
f10fb93e 1547
8476e5ef
MB
1548 if (use_monotonic_clock)
1549 clock_gettime(CLOCK_MONOTONIC, &tn);
1550 else
1551 clock_gettime(CLOCK_REALTIME, &tn);
1552
1553 // uint64_t time_now_ns = tn.tv_sec * (uint64_t)1000000000 + tn.tv_nsec;
1554 uint64_t time_now_ns = tn.tv_sec;
1555 time_now_ns = time_now_ns * 1000000000;
1556 time_now_ns = time_now_ns + tn.tv_nsec;
1557
1558 // see if it's stalled
1559
1560 if ((stall_monitor_start_time != 0) && (stall_monitor_frame_count == delay_temp)) {
1561 // hasn't outputted anything since the last call to delay()
1562
1563 if (((update_timestamp_ns - stall_monitor_start_time) >
1564 stall_monitor_error_threshold) ||
1565 ((time_now_ns - stall_monitor_start_time) > stall_monitor_error_threshold)) {
1566 debug(2,
1567 "DAC seems to have stalled with time_now_ns: %" PRIX64
1568 ", update_timestamp_ns: %" PRIX64 ", stall_monitor_start_time %" PRIX64
1569 ", stall_monitor_error_threshold %" PRIX64 ".",
1570 time_now_ns, update_timestamp_ns, stall_monitor_start_time,
1571 stall_monitor_error_threshold);
1572 debug(2,
1573 "DAC seems to have stalled with time_now: %lx,%lx"
1574 ", update_timestamp: %lx,%lx, stall_monitor_start_time %" PRIX64
1575 ", stall_monitor_error_threshold %" PRIX64 ".",
1576 tn.tv_sec, tn.tv_nsec, update_timestamp.tv_sec, update_timestamp.tv_nsec,
1577 stall_monitor_start_time, stall_monitor_error_threshold);
1578 ret = sps_extra_code_output_stalled;
1579 }
1580 } else {
1581 stall_monitor_start_time = update_timestamp_ns;
1582 stall_monitor_frame_count = delay_temp;
1583 }
fd4c429b 1584
8476e5ef
MB
1585 if (ret == 0) {
1586 uint64_t delta = time_now_ns - update_timestamp_ns;
fd4c429b 1587
8476e5ef
MB
1588 // uint64_t frames_played_since_last_interrupt =
1589 // ((uint64_t)config.output_rate * delta) / 1000000000;
c8b0be30 1590
8476e5ef
MB
1591 uint64_t frames_played_since_last_interrupt = config.output_rate;
1592 frames_played_since_last_interrupt = frames_played_since_last_interrupt * delta;
1593 frames_played_since_last_interrupt = frames_played_since_last_interrupt / 1000000000;
5e143fe6 1594
8476e5ef
MB
1595 snd_pcm_sframes_t frames_played_since_last_interrupt_sized =
1596 frames_played_since_last_interrupt;
1597 if ((frames_played_since_last_interrupt_sized < 0) ||
1598 ((uint64_t)frames_played_since_last_interrupt_sized !=
1599 frames_played_since_last_interrupt))
1600 debug(1,
1601 "overflow resizing frames_played_since_last_interrupt %" PRIx64
1602 " to frames_played_since_last_interrupt %lx.",
1603 frames_played_since_last_interrupt, frames_played_since_last_interrupt_sized);
1604 delay_temp = delay_temp - frames_played_since_last_interrupt_sized;
ecee220b 1605 }
ecee220b 1606 }
8476e5ef
MB
1607 } else { // not running, thus no delay information, thus can't check for
1608 // stall
1609 delay_temp = 0;
1610 stall_monitor_start_time = 0; // zero if not initialised / not started / zeroed by flush
1611 stall_monitor_frame_count = 0; // set to delay at start of time, incremented by any writes
1612
1613 // not running, thus no delay information, thus can't check for frame
1614 // rates
1615 // frame_index = 0; // we'll be starting over...
1616 // measurement_data_is_valid = 0;
6f8b35d1 1617 }
8476e5ef
MB
1618 } else {
1619 debug(1, "alsa: can't get device's status.");
6f8b35d1 1620 }
8476e5ef 1621
48043a81 1622 } else {
129343c1 1623 debug(2, "alsa_handle is NULL in precision_delay_and_status!");
59d26918 1624 }
9bac04e2
MB
1625 if (delay != NULL)
1626 *delay = delay_temp;
1627 if (state != NULL)
1628 *state = state_temp;
59d26918
MB
1629 return ret;
1630}
1631
fd880056 1632static int delay(long *the_delay) {
555bb97a
MB
1633 // returns 0 if the device is in a valid state -- SND_PCM_STATE_RUNNING or
1634 // SND_PCM_STATE_PREPARED
59d26918
MB
1635 // or SND_PCM_STATE_DRAINING
1636 // and returns the actual delay if running or 0 if prepared in *the_delay
1637
1638 // otherwise return an error code
1639 // the error code could be a Unix errno code or a snderror code, or
555bb97a
MB
1640 // the sps_extra_code_output_stalled or the
1641 // sps_extra_code_output_state_cannot_make_ready codes
59d26918 1642 int ret = 0;
9bac04e2 1643 snd_pcm_sframes_t my_delay = 0;
59d26918 1644
561a1296
MB
1645 int oldState;
1646
1647 snd_pcm_state_t state;
59d26918 1648
561a1296
MB
1649 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState); // make this un-cancellable
1650 pthread_cleanup_debug_mutex_lock(&alsa_mutex, 10000, 0);
59d26918 1651
129343c1 1652 ret = delay_and_status(&state, &my_delay, NULL);
59d26918 1653
561a1296
MB
1654 debug_mutex_unlock(&alsa_mutex, 0);
1655 pthread_cleanup_pop(0);
1656 pthread_setcancelstate(oldState, NULL);
1657
8476e5ef 1658 if (the_delay != NULL) // can't imagine why this might happen
9bac04e2 1659 *the_delay = my_delay; // note: snd_pcm_sframes_t is a long
59d26918 1660
6f8b35d1
MB
1661 return ret;
1662}
1663
fd880056
MB
1664static int stats(uint64_t *raw_measurement_time, uint64_t *corrected_measurement_time,
1665 uint64_t *the_delay, uint64_t *frames_sent_to_dac) {
5f8e6e39
MB
1666 // returns 0 if the device is in a valid state -- SND_PCM_STATE_RUNNING or
1667 // SND_PCM_STATE_PREPARED
136071a6
MB
1668 // or SND_PCM_STATE_DRAINING.
1669 // returns the actual delay if running or 0 if prepared in *the_delay
1670 // returns the present value of frames_sent_for_playing
1671 // otherwise return a non-zero value
5f8e6e39
MB
1672 int ret = 0;
1673 *the_delay = 0;
1674
1675 int oldState;
1676
1677 snd_pcm_state_t state;
1678 snd_pcm_sframes_t my_delay = 0; // this initialisation is to silence a clang warning
1679
1680 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState); // make this un-cancellable
1681 pthread_cleanup_debug_mutex_lock(&alsa_mutex, 10000, 0);
1682
1683 if (alsa_handle == NULL) {
129343c1 1684 ret = alsa_handle_status;
5f8e6e39 1685 } else {
56bef8e7
MB
1686 *raw_measurement_time =
1687 get_absolute_time_in_ns(); // this is not conditioned ("disciplined") by NTP
1688 *corrected_measurement_time = get_monotonic_time_in_ns(); // this is ("disciplined") by NTP
5f8e6e39
MB
1689 ret = delay_and_status(&state, &my_delay, NULL);
1690 }
1691 if (ret == 0)
136071a6
MB
1692 ret = frames_sent_break_occurred; // will be zero unless an error like an underrun occurred
1693 else
dc5b8f1a
MB
1694 ret = 1; // just indicate there was some kind of a break
1695 frames_sent_break_occurred = 0; // reset it.
5f8e6e39
MB
1696 if (frames_sent_to_dac != NULL)
1697 *frames_sent_to_dac = frames_sent_for_playing;
1698 debug_mutex_unlock(&alsa_mutex, 0);
1699 pthread_cleanup_pop(0);
1700 pthread_setcancelstate(oldState, NULL);
1701 uint64_t hd = my_delay; // note: snd_pcm_sframes_t is a long
1702 *the_delay = hd;
1703 return ret;
1704}
c85e7e05 1705
fd880056 1706static int do_play(void *buf, int samples) {
bd81e733 1707 // assuming the alsa_mutex has been acquired
76387f82
MB
1708 int ret = 0;
1709 if ((samples != 0) && (buf != NULL)) {
59d26918 1710
76387f82
MB
1711 int oldState;
1712 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState); // make this un-cancellable
59d26918 1713
76387f82
MB
1714 snd_pcm_state_t state;
1715 snd_pcm_sframes_t my_delay;
1716 ret = delay_and_status(&state, &my_delay, NULL);
59d26918 1717
76387f82 1718 if (ret == 0) { // will be non-zero if an error or a stall
e4c82b77 1719 // just check the state of the DAC
59d26918 1720
bd81e733
MB
1721 if ((state != SND_PCM_STATE_PREPARED) && (state != SND_PCM_STATE_RUNNING) &&
1722 (state != SND_PCM_STATE_XRUN)) {
1723 debug(1, "alsa: DAC in odd SND_PCM_STATE_* %d prior to writing.", state);
1724 }
80f15e1f 1725
e4c82b77 1726 snd_pcm_state_t prior_state = state; // keep this for afterwards....
f058d118 1727 // debug(3, "alsa: write %d frames.", samples);
bd81e733 1728 ret = alsa_pcm_write(alsa_handle, buf, samples);
8490c4c1
MB
1729 if (ret > 0)
1730 frames_sent_for_playing += ret; // this is the number of frames accepted
bd81e733
MB
1731 if (ret == samples) {
1732 stall_monitor_frame_count += samples;
bd81e733 1733 } else {
136071a6 1734 frames_sent_break_occurred = 1; // note than an output error has occurred
dc5b8f1a 1735 if (ret == -EPIPE) { /* underrun */
e4c82b77
MB
1736
1737 // It could be that the DAC was in the SND_PCM_STATE_XRUN state before
1738 // sending the samples to be output. If so, it will still be in
1739 // the SND_PCM_STATE_XRUN state after the call and it needs to be recovered.
1740
1741 // The underrun occurred in the past, so flagging an
1742 // error at this point is misleading.
1743
1744 // In fact, having put samples in the buffer, we are about to fix it by now
1745 // issuing a snd_pcm_recover().
1746
1747 // So, if state is SND_PCM_STATE_XRUN now, only report it if the state was
1748 // not SND_PCM_STATE_XRUN prior to the call, i.e. report it only
1749 // if we are not trying to recover from a previous underrun.
1750
1751 if (prior_state == SND_PCM_STATE_XRUN)
0c7d385f 1752 debug(1, "alsa: recovering from a previous underrun.");
e4c82b77
MB
1753 else
1754 debug(1, "alsa: underrun while writing %d samples to alsa device.", samples);
76387f82 1755 ret = snd_pcm_recover(alsa_handle, ret, 1);
bd81e733 1756 } else if (ret == -ESTRPIPE) { /* suspended */
76387f82
MB
1757 if (state != prior_state)
1758 debug(1, "alsa: suspended while writing %d samples to alsa device.", samples);
1759 if ((ret = snd_pcm_resume(alsa_handle)) == -ENOSYS)
1760 ret = snd_pcm_prepare(alsa_handle);
1761 } else if (ret >= 0) {
1762 debug(1, "alsa: only %d of %d samples output.", ret, samples);
59d26918 1763 }
59d26918
MB
1764 }
1765 }
76387f82
MB
1766 pthread_setcancelstate(oldState, NULL);
1767 if (ret < 0) {
1768 char errorstring[1024];
1769 strerror_r(-ret, (char *)errorstring, sizeof(errorstring));
1770 debug(1, "alsa: SND_PCM_STATE_* %d, error %d (\"%s\") writing %d samples to alsa device.",
1771 state, ret, (char *)errorstring, samples);
1772 }
b5bb2fef 1773 if ((ret == -ENOENT) || (ret == -ENODEV)) // if the device isn't there...
76387f82 1774 handle_unfixable_error(-ret);
59d26918 1775 }
59d26918
MB
1776 return ret;
1777}
1778
fd880056 1779static int do_open(int do_auto_setup) {
bd81e733
MB
1780 int ret = 0;
1781 if (alsa_backend_state != abm_disconnected)
555bb97a
MB
1782 debug(1, "alsa: do_open() -- opening the output device when it is already "
1783 "connected");
bd81e733
MB
1784 if (alsa_handle == NULL) {
1785 // debug(1,"alsa: do_open() -- opening the output device");
83c0405d 1786 ret = open_alsa_device(do_auto_setup);
bd81e733 1787 if (ret == 0) {
555bb97a 1788 mute_requested_internally = 0;
bd81e733
MB
1789 if (audio_alsa.volume)
1790 do_volume(set_volume);
555bb97a 1791 if (audio_alsa.mute) {
60487c86 1792 debug(2, "do_open() set_mute_state");
555bb97a
MB
1793 set_mute_state(); // the mute_requested_externally flag will have been
1794 // set accordingly
1795 // do_mute(0); // complete unmute
1796 }
136071a6 1797 frames_sent_break_occurred = 1; // there is a discontinuity with
dc5b8f1a 1798 // any previously-reported frame count
99c66385 1799 frames_sent_for_playing = 0;
b02e5d9f 1800 alsa_backend_state = abm_connected; // only do this if it really opened it.
76387f82 1801 } else {
b5bb2fef 1802 if ((ret == -ENOENT) || (ret == -ENODEV)) // if the device isn't there...
76387f82 1803 handle_unfixable_error(-ret);
bd81e733 1804 }
bd81e733
MB
1805 } else {
1806 debug(1, "alsa: do_open() -- output device already open.");
1807 }
1808 return ret;
1809}
1810
fd880056 1811static int do_close() {
a382ac66 1812 debug(2, "alsa: do_close()");
bd81e733 1813 if (alsa_backend_state == abm_disconnected)
555bb97a
MB
1814 debug(1, "alsa: do_close() -- closing the output device when it is already "
1815 "disconnected");
bd81e733
MB
1816 int derr = 0;
1817 if (alsa_handle) {
1818 // debug(1,"alsa: do_close() -- closing the output device");
1819 if ((derr = snd_pcm_drop(alsa_handle)))
1820 debug(1, "Error %d (\"%s\") dropping output device.", derr, snd_strerror(derr));
2bc62c7d
MB
1821 usleep(10000); // wait for the hardware to do its trick. BTW, this make the function pthread
1822 // cancellable
bd81e733
MB
1823 if ((derr = snd_pcm_hw_free(alsa_handle)))
1824 debug(1, "Error %d (\"%s\") freeing the output device hardware.", derr, snd_strerror(derr));
c8075134 1825 debug(2, "alsa: do_close() -- closing alsa handle");
bd81e733
MB
1826 if ((derr = snd_pcm_close(alsa_handle)))
1827 debug(1, "Error %d (\"%s\") closing the output device.", derr, snd_strerror(derr));
1828 alsa_handle = NULL;
129343c1 1829 alsa_handle_status = ENODEV; // no device open
bd81e733
MB
1830 } else {
1831 debug(1, "alsa: do_close() -- output device already closed.");
1832 }
1833 alsa_backend_state = abm_disconnected;
1834 return derr;
1835}
1836
fd880056 1837static int sub_flush() {
70ef99e9
MB
1838 if (alsa_backend_state == abm_disconnected)
1839 debug(1, "alsa: do_flush() -- closing the output device when it is already "
1840 "disconnected");
1841 int derr = 0;
1842 if (alsa_handle) {
9bac04e2 1843 debug(2, "alsa: do_flush() -- flushing the output device");
70ef99e9
MB
1844 frames_sent_break_occurred = 1;
1845 if ((derr = snd_pcm_drop(alsa_handle)))
1846 debug(1, "Error %d (\"%s\") dropping output device.", derr, snd_strerror(derr));
1847 if ((derr = snd_pcm_prepare(alsa_handle)))
1848 debug(1, "Error %d (\"%s\") preparing output device after flush.", derr, snd_strerror(derr));
0b4b4a73 1849 alsa_backend_state = abm_connected;
70ef99e9
MB
1850 } else {
1851 debug(1, "alsa: do_flush() -- output device already closed.");
1852 }
1853 return derr;
1854}
1855
fd880056
MB
1856static int play(void *buf, int samples, __attribute__((unused)) int sample_type,
1857 __attribute__((unused)) uint32_t timestamp,
1858 __attribute__((unused)) uint64_t playtime) {
bd81e733
MB
1859
1860 // play() will change the state of the alsa_backend_mode to abm_playing
555bb97a
MB
1861 // also, if the present alsa_backend_state is abm_disconnected, then first the
1862 // DAC must be
bd81e733
MB
1863 // connected
1864
1865 // debug(3,"audio_alsa play called.");
1866 int ret = 0;
1867
14aa9d41 1868 pthread_cleanup_debug_mutex_lock(&alsa_mutex, 50000, 0);
bd81e733
MB
1869
1870 if (alsa_backend_state == abm_disconnected) {
83c0405d 1871 ret = do_open(0); // don't try to auto setup
b02e5d9f 1872 if (ret == 0)
c8075134 1873 debug(2, "alsa: play() -- opened output device");
555bb97a 1874 }
bd81e733
MB
1875
1876 if (ret == 0) {
1877 if (alsa_backend_state != abm_playing) {
c8075134 1878 debug(2, "alsa: play() -- alsa_backend_state => abm_playing");
bd81e733 1879 alsa_backend_state = abm_playing;
c8b0be30 1880
0c552148 1881 // mute_requested_internally = 0; // stop requesting a mute for backend's own
c8b0be30
MB
1882 // reasons, which might have been a flush
1883 // debug(2, "play() set_mute_state");
1884 // set_mute_state(); // try to action the request and return a status
555bb97a 1885 // do_mute(0); // unmute for backend's reason
bd81e733
MB
1886 }
1887 ret = do_play(buf, samples);
1888 }
1889
1890 debug_mutex_unlock(&alsa_mutex, 0);
1891 pthread_cleanup_pop(0); // release the mutex
1892 return ret;
1893}
1894
fd880056 1895static int prepare(void) {
c8b0be30 1896 // this will leave the DAC open / connected.
83c0405d
MB
1897 int ret = 0;
1898
1899 pthread_cleanup_debug_mutex_lock(&alsa_mutex, 50000, 0);
1900
1901 if (alsa_backend_state == abm_disconnected) {
e8a92d3c 1902 if (alsa_device_initialised == 0) {
1b4c9b17 1903 // debug(1, "alsa: prepare() calling alsa_device_init.");
e8a92d3c
MB
1904 alsa_device_init();
1905 alsa_device_initialised = 1;
1906 }
c8b0be30 1907 ret = do_open(1); // do auto setup
83c0405d
MB
1908 if (ret == 0)
1909 debug(2, "alsa: prepare() -- opened output device");
83c0405d
MB
1910 }
1911
1912 debug_mutex_unlock(&alsa_mutex, 0);
1913 pthread_cleanup_pop(0); // release the mutex
1914 return ret;
1915}
1916
2c40f23f 1917static void flush(void) {
fff33fe6 1918 // debug(2,"audio_alsa flush called.");
ea20840d 1919 pthread_cleanup_debug_mutex_lock(&alsa_mutex, 10000, 1);
bd81e733 1920 if (alsa_backend_state != abm_disconnected) { // must be playing or connected...
a295c2a2 1921 // do nothing for a flush if config.keep_dac_busy is true
70ef99e9
MB
1922 if (config.keep_dac_busy == 0) {
1923 sub_flush();
7cc434e9 1924 }
a295c2a2 1925 } else {
c8075134 1926 debug(3, "alsa: flush() -- called on a disconnected alsa backend");
a295c2a2 1927 }
93f41059 1928 debug_mutex_unlock(&alsa_mutex, 3);
ea20840d 1929 pthread_cleanup_pop(0); // release the mutex
95035f33
M
1930}
1931
1932static void stop(void) {
0b4b4a73
MB
1933 pthread_cleanup_debug_mutex_lock(&alsa_mutex, 10000, 1);
1934 if (alsa_backend_state != abm_disconnected) { // must be playing or connected...
1935 if (config.keep_dac_busy == 0) {
1936 do_close();
1937 }
1938 } else
1939 debug(3, "alsa: stop() -- called on a disconnected alsa backend");
1940 debug_mutex_unlock(&alsa_mutex, 3);
1941 pthread_cleanup_pop(0); // release the mutex
95035f33
M
1942}
1943
87a0475c 1944static void parameters(audio_parameters *info) {
87a0475c
MB
1945 info->minimum_volume_dB = alsa_mix_mindb;
1946 info->maximum_volume_dB = alsa_mix_maxdb;
a2790fc1
MB
1947}
1948
fd880056
MB
1949static void do_volume(double vol) { // caller is assumed to have the alsa_mutex when
1950 // using this function
5dd9fbc4 1951 debug(3, "Setting volume db to %f.", vol);
3b4654df
MB
1952 int oldState;
1953 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState); // make this un-cancellable
b0bfbdc0 1954 set_volume = vol;
0c552148 1955 pthread_cleanup_debug_mutex_lock(&alsa_mixer_mutex, 1000, 1);
76387f82 1956 if (volume_set_request && (open_mixer() == 0)) {
f3dcf8d6
JK
1957 if (has_softvol) {
1958 if (ctl && elem_id) {
1959 snd_ctl_elem_value_t *value;
1960 long raw;
1961
90f779dc 1962 if (snd_ctl_convert_from_dB(ctl, elem_id, vol, &raw, 0) < 0)
064bd293
MB
1963 debug(1, "Failed converting dB gain to raw volume value for the "
1964 "software volume control.");
f3dcf8d6
JK
1965
1966 snd_ctl_elem_value_alloca(&value);
1967 snd_ctl_elem_value_set_id(value, elem_id);
1968 snd_ctl_elem_value_set_integer(value, 0, raw);
1969 snd_ctl_elem_value_set_integer(value, 1, raw);
1970 if (snd_ctl_elem_write(ctl, value) < 0)
064bd293
MB
1971 debug(1, "Failed to set playback dB volume for the software volume "
1972 "control.");
f3dcf8d6
JK
1973 }
1974 } else {
e0aa75a8 1975 if (volume_based_mute_is_active == 0) {
6d792fa0 1976 // debug(1,"Set alsa volume.");
8a4bfb03 1977 do_snd_mixer_selem_set_playback_dB_all(alsa_mix_elem, vol);
6d792fa0 1978 } else {
69b3b5d7 1979 debug(2, "Not setting volume because volume-based mute is active");
f3dcf8d6 1980 }
ae0c9745 1981 }
fc492bea 1982 volume_set_request = 0; // any external request that has been made is now satisfied
eb1b7c37 1983 close_mixer();
4e395ff3 1984 }
0c552148
MB
1985 debug_mutex_unlock(&alsa_mixer_mutex, 3);
1986 pthread_cleanup_pop(0); // release the mutex
3b4654df 1987 pthread_setcancelstate(oldState, NULL);
fc492bea
MB
1988}
1989
fd880056 1990static void volume(double vol) {
fc492bea
MB
1991 volume_set_request = 1; // an external request has been made to set the volume
1992 do_volume(vol);
95035f33 1993}
ba02dee4 1994
eb1b7c37 1995/*
ba02dee4 1996static void linear_volume(double vol) {
ae0c9745
MB
1997 debug(2, "Setting linear volume to %f.", vol);
1998 set_volume = vol;
e8a92d3c 1999 if ((alsa_mix_ctrl == NULL) && alsa_mix_handle) {
ae0c9745
MB
2000 double linear_volume = pow(10, vol);
2001 // debug(1,"Linear volume is %f.",linear_volume);
555bb97a
MB
2002 long int_vol = alsa_mix_minv + (alsa_mix_maxv - alsa_mix_minv) *
2003linear_volume;
ae0c9745
MB
2004 // debug(1,"Setting volume to %ld, for volume input of %f.",int_vol,vol);
2005 if (alsa_mix_handle) {
2006 if (snd_mixer_selem_set_playback_volume_all(alsa_mix_elem, int_vol) != 0)
2007 die("Failed to set playback volume");
eb1b7c37 2008
ae0c9745
MB
2009 }
2010 }
4c70223f 2011}
eb1b7c37 2012*/
4c70223f 2013
fd880056 2014static int mute(int mute_state_requested) { // these would be for external reasons, not
2c0250b3
MB
2015 // because of the
2016 // state of the backend.
555bb97a 2017 mute_requested_externally = mute_state_requested; // request a mute for external reasons
60487c86 2018 debug(2, "mute(%d) set_mute_state", mute_state_requested);
555bb97a 2019 return set_mute_state();
fc492bea 2020}
bd81e733 2021/*
fd880056 2022static void alsa_buffer_monitor_thread_cleanup_function(__attribute__((unused)) void
555bb97a 2023*arg) {
7cc434e9
MB
2024 debug(1, "alsa: alsa_buffer_monitor_thread_cleanup_function called.");
2025}
bd81e733 2026*/
7cc434e9 2027
fd880056 2028static void *alsa_buffer_monitor_thread_code(__attribute__((unused)) void *arg) {
cd9982c4
MB
2029 int frame_count = 0;
2030 int error_count = 0;
a8faacd3 2031 int error_detected = 0;
97a4766e 2032 int okb = -1;
2bc62c7d
MB
2033 // if too many play errors occur early on, we will turn off the disable standby mode
2034 while (error_detected == 0) {
2035 int keep_dac_busy_has_just_gone_off = 0;
97a4766e 2036 if (okb != config.keep_dac_busy) {
2bc62c7d
MB
2037 if ((okb != 0) && (config.keep_dac_busy == 0))
2038 keep_dac_busy_has_just_gone_off = 1;
c8b0be30 2039 debug(2, "keep_dac_busy is now \"%s\"", config.keep_dac_busy == 0 ? "no" : "yes");
97a4766e
MB
2040 okb = config.keep_dac_busy;
2041 }
c5ff0dfe 2042 if ((config.keep_dac_busy != 0) && (alsa_device_initialised == 0)) {
60487c86 2043 debug(2, "alsa: alsa_buffer_monitor_thread_code() calling "
e8a92d3c
MB
2044 "alsa_device_init.");
2045 alsa_device_init();
2046 alsa_device_initialised = 1;
c5ff0dfe 2047 }
67e9b1b6 2048 int sleep_time_us = (int)(config.disable_standby_mode_silence_scan_interval * 1000000);
f3865d77 2049 pthread_cleanup_debug_mutex_lock(&alsa_mutex, 200000, 0);
fd08511f 2050 // check possible state transitions here
9fb37e42
MB
2051 if ((alsa_backend_state == abm_disconnected) && (config.keep_dac_busy != 0)) {
2052 // open the dac and move to abm_connected mode
83c0405d 2053 if (do_open(1) == 0) // no automatic setup of rate and speed if necessary
555bb97a
MB
2054 debug(2, "alsa: alsa_buffer_monitor_thread_code() -- output device opened; "
2055 "alsa_backend_state => abm_connected");
2bc62c7d 2056 } else if ((alsa_backend_state != abm_disconnected) && (keep_dac_busy_has_just_gone_off != 0)) {
9fb37e42 2057 stall_monitor_start_time = 0;
99c66385
MB
2058 // frame_index = 0;
2059 // measurement_data_is_valid = 0;
555bb97a
MB
2060 debug(2, "alsa: alsa_buffer_monitor_thread_code() -- closing the output "
2061 "device");
9fb37e42 2062 do_close();
555bb97a
MB
2063 debug(2, "alsa: alsa_buffer_monitor_thread_code() -- alsa_backend_state "
2064 "=> abm_disconnected");
9fb37e42
MB
2065 }
2066 // now, if the backend is not in the abm_disconnected state
555bb97a
MB
2067 // and config.keep_dac_busy is true (at the present, this has to be the case
2068 // to be in the
2069 // abm_connected state in the first place...) then do the silence-filling
dbea82c2 2070 // thing, if needed /* only if the output device is capable of precision delay */.
c8b0be30
MB
2071 if ((alsa_backend_state != abm_disconnected) &&
2072 (config.keep_dac_busy != 0) /* && precision_delay_available() */) {
9fb37e42
MB
2073 int reply;
2074 long buffer_size = 0;
2075 snd_pcm_state_t state;
67e9b1b6
MB
2076 reply = delay_and_status(&state, &buffer_size, NULL);
2077 if (reply != 0) {
2078 buffer_size = 0;
2079 char errorstring[1024];
2080 strerror_r(-reply, (char *)errorstring, sizeof(errorstring));
2081 debug(1, "alsa: alsa_buffer_monitor_thread_code delay error %d: \"%s\".", reply,
2082 (char *)errorstring);
2083 }
2084 long buffer_size_threshold =
2085 (long)(config.disable_standby_mode_silence_threshold * config.output_rate);
2086 size_t size_of_silence_buffer;
2087 if (buffer_size < buffer_size_threshold) {
2088 int frames_of_silence = 1024;
2089 size_of_silence_buffer = frames_of_silence * frame_size;
2090 void *silence = malloc(size_of_silence_buffer);
2091 if (silence == NULL) {
2092 warn("disable_standby_mode has been turned off because a memory allocation error "
2093 "occurred.");
2094 error_detected = 1;
2095 } else {
2096 int ret;
2097 pthread_cleanup_push(malloc_cleanup, silence);
2098 int use_dither = 0;
2099 if ((alsa_mix_ctrl == NULL) && (config.ignore_volume_control == 0) &&
2100 (config.airplay_volume != 0.0))
2101 use_dither = 1;
2102 dither_random_number_store =
2103 generate_zero_frames(silence, frames_of_silence, config.output_format,
2104 use_dither, // i.e. with dither
2105 dither_random_number_store);
2106 ret = do_play(silence, frames_of_silence);
2107 frame_count++;
2108 pthread_cleanup_pop(1); // free malloced buffer
2109 if (ret < 0) {
2110 error_count++;
2111 char errorstring[1024];
2112 strerror_r(-ret, (char *)errorstring, sizeof(errorstring));
54d761ff
MB
2113 debug(2,
2114 "alsa: alsa_buffer_monitor_thread_code error %d (\"%s\") writing %d samples "
2115 "to alsa device -- %d errors in %d trials.",
67e9b1b6
MB
2116 ret, (char *)errorstring, frames_of_silence, error_count, frame_count);
2117 if ((error_count > 40) && (frame_count < 100)) {
2118 warn("disable_standby_mode has been turned off because too many underruns "
2119 "occurred. Is Shairport Sync outputting to a virtual device or running in a "
2120 "virtual machine?");
2121 error_detected = 1;
cd9982c4 2122 }
ad6c721d 2123 }
4613ee6b 2124 }
ad6c721d 2125 }
7cc434e9 2126 }
f3865d77 2127 debug_mutex_unlock(&alsa_mutex, 0);
54d761ff
MB
2128 pthread_cleanup_pop(0); // release the mutex
2129 usleep(sleep_time_us); // has a cancellation point in it
7cc434e9 2130 }
7cc434e9 2131 pthread_exit(NULL);
c8075134 2132}