configure.ac: Don't allow UNIX IPC to be configured for a native Windows build.
[mpd-mk.git] / src / output_all.c
blobdbd5a6ce608269d10766da16dca14068dbee85b8
1 /*
2 * Copyright (C) 2003-2010 The Music Player Daemon Project
3 * http://www.musicpd.org
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "config.h"
21 #include "output_all.h"
22 #include "output_internal.h"
23 #include "output_control.h"
24 #include "chunk.h"
25 #include "conf.h"
26 #include "pipe.h"
27 #include "buffer.h"
28 #include "player_control.h"
30 #ifndef NDEBUG
31 #include "chunk.h"
32 #endif
34 #include <assert.h>
35 #include <string.h>
37 #undef G_LOG_DOMAIN
38 #define G_LOG_DOMAIN "output"
40 static struct audio_format input_audio_format;
42 static struct audio_output *audio_outputs;
43 static unsigned int num_audio_outputs;
45 /**
46 * The #music_buffer object where consumed chunks are returned.
48 static struct music_buffer *g_music_buffer;
50 /**
51 * The #music_pipe object which feeds all audio outputs. It is filled
52 * by audio_output_all_play().
54 static struct music_pipe *g_mp;
56 /**
57 * The "elapsed_time" stamp of the most recently finished chunk.
59 static float audio_output_all_elapsed_time = -1.0;
61 unsigned int audio_output_count(void)
63 return num_audio_outputs;
66 struct audio_output *
67 audio_output_get(unsigned i)
69 assert(i < num_audio_outputs);
71 return &audio_outputs[i];
74 struct audio_output *
75 audio_output_find(const char *name)
77 for (unsigned i = 0; i < num_audio_outputs; ++i) {
78 struct audio_output *ao = audio_output_get(i);
80 if (strcmp(ao->name, name) == 0)
81 return ao;
84 /* name not found */
85 return NULL;
88 static unsigned
89 audio_output_config_count(void)
91 unsigned int nr = 0;
92 const struct config_param *param = NULL;
94 while ((param = config_get_next_param(CONF_AUDIO_OUTPUT, param)))
95 nr++;
96 if (!nr)
97 nr = 1; /* we'll always have at least one device */
98 return nr;
101 void
102 audio_output_all_init(void)
104 const struct config_param *param = NULL;
105 unsigned int i;
106 GError *error = NULL;
108 notify_init(&audio_output_client_notify);
110 num_audio_outputs = audio_output_config_count();
111 audio_outputs = g_new(struct audio_output, num_audio_outputs);
113 for (i = 0; i < num_audio_outputs; i++)
115 struct audio_output *output = &audio_outputs[i];
116 unsigned int j;
118 param = config_get_next_param(CONF_AUDIO_OUTPUT, param);
120 /* only allow param to be NULL if there just one audioOutput */
121 assert(param || (num_audio_outputs == 1));
123 if (!audio_output_init(output, param, &error)) {
124 if (param != NULL)
125 g_error("line %i: %s",
126 param->line, error->message);
127 else
128 g_error("%s", error->message);
131 /* require output names to be unique: */
132 for (j = 0; j < i; j++) {
133 if (!strcmp(output->name, audio_outputs[j].name)) {
134 g_error("output devices with identical "
135 "names: %s\n", output->name);
141 void
142 audio_output_all_finish(void)
144 unsigned int i;
146 for (i = 0; i < num_audio_outputs; i++) {
147 audio_output_finish(&audio_outputs[i]);
150 g_free(audio_outputs);
151 audio_outputs = NULL;
152 num_audio_outputs = 0;
154 notify_deinit(&audio_output_client_notify);
157 void
158 audio_output_all_enable_disable(void)
160 for (unsigned i = 0; i < num_audio_outputs; i++) {
161 struct audio_output *ao = &audio_outputs[i];
162 bool enabled;
164 g_mutex_lock(ao->mutex);
165 enabled = ao->really_enabled;
166 g_mutex_unlock(ao->mutex);
168 if (ao->enabled != enabled) {
169 if (ao->enabled)
170 audio_output_enable(ao);
171 else
172 audio_output_disable(ao);
178 * Determine if all (active) outputs have finished the current
179 * command.
181 static bool
182 audio_output_all_finished(void)
184 for (unsigned i = 0; i < num_audio_outputs; ++i) {
185 struct audio_output *ao = &audio_outputs[i];
186 bool not_finished;
188 g_mutex_lock(ao->mutex);
189 not_finished = audio_output_is_open(ao) &&
190 !audio_output_command_is_finished(ao);
191 g_mutex_unlock(ao->mutex);
193 if (not_finished)
194 return false;
197 return true;
200 static void audio_output_wait_all(void)
202 while (!audio_output_all_finished())
203 notify_wait(&audio_output_client_notify);
207 * Signals the audio output if it is open. This function locks the
208 * mutex.
210 static void
211 audio_output_lock_signal(struct audio_output *ao)
213 g_mutex_lock(ao->mutex);
214 if (audio_output_is_open(ao))
215 g_cond_signal(ao->cond);
216 g_mutex_unlock(ao->mutex);
220 * Signals all audio outputs which are open.
222 static void
223 audio_output_signal_all(void)
225 for (unsigned i = 0; i < num_audio_outputs; ++i)
226 audio_output_lock_signal(&audio_outputs[i]);
229 static void
230 audio_output_reset_reopen(struct audio_output *ao)
232 g_mutex_lock(ao->mutex);
234 if (!ao->open && ao->fail_timer != NULL) {
235 g_timer_destroy(ao->fail_timer);
236 ao->fail_timer = NULL;
239 g_mutex_unlock(ao->mutex);
243 * Resets the "reopen" flag on all audio devices. MPD should
244 * immediately retry to open the device instead of waiting for the
245 * timeout when the user wants to start playback.
247 static void
248 audio_output_all_reset_reopen(void)
250 for (unsigned i = 0; i < num_audio_outputs; ++i) {
251 struct audio_output *ao = &audio_outputs[i];
253 audio_output_reset_reopen(ao);
258 * Opens all output devices which are enabled, but closed.
260 * @return true if there is at least open output device which is open
262 static bool
263 audio_output_all_update(void)
265 unsigned int i;
266 bool ret = false;
268 if (!audio_format_defined(&input_audio_format))
269 return false;
271 for (i = 0; i < num_audio_outputs; ++i)
272 ret = audio_output_update(&audio_outputs[i],
273 &input_audio_format, g_mp) || ret;
275 return ret;
278 bool
279 audio_output_all_play(struct music_chunk *chunk)
281 bool ret;
282 unsigned int i;
284 assert(g_music_buffer != NULL);
285 assert(g_mp != NULL);
286 assert(chunk != NULL);
287 assert(music_chunk_check_format(chunk, &input_audio_format));
289 ret = audio_output_all_update();
290 if (!ret)
291 return false;
293 music_pipe_push(g_mp, chunk);
295 for (i = 0; i < num_audio_outputs; ++i)
296 audio_output_play(&audio_outputs[i]);
298 return true;
301 bool
302 audio_output_all_open(const struct audio_format *audio_format,
303 struct music_buffer *buffer)
305 bool ret = false, enabled = false;
306 unsigned int i;
308 assert(audio_format != NULL);
309 assert(buffer != NULL);
310 assert(g_music_buffer == NULL || g_music_buffer == buffer);
311 assert((g_mp == NULL) == (g_music_buffer == NULL));
313 g_music_buffer = buffer;
315 /* the audio format must be the same as existing chunks in the
316 pipe */
317 assert(g_mp == NULL || music_pipe_check_format(g_mp, audio_format));
319 if (g_mp == NULL)
320 g_mp = music_pipe_new();
321 else
322 /* if the pipe hasn't been cleared, the the audio
323 format must not have changed */
324 assert(music_pipe_size(g_mp) == 0 ||
325 audio_format_equals(audio_format,
326 &input_audio_format));
328 input_audio_format = *audio_format;
330 audio_output_all_reset_reopen();
331 audio_output_all_enable_disable();
332 audio_output_all_update();
334 for (i = 0; i < num_audio_outputs; ++i) {
335 if (audio_outputs[i].enabled)
336 enabled = true;
338 if (audio_outputs[i].open)
339 ret = true;
342 if (!enabled)
343 g_warning("All audio outputs are disabled");
345 if (!ret)
346 /* close all devices if there was an error */
347 audio_output_all_close();
349 return ret;
353 * Has the specified audio output already consumed this chunk?
355 static bool
356 chunk_is_consumed_in(const struct audio_output *ao,
357 const struct music_chunk *chunk)
359 if (!ao->open)
360 return true;
362 if (ao->chunk == NULL)
363 return false;
365 assert(chunk == ao->chunk || music_pipe_contains(g_mp, ao->chunk));
367 if (chunk != ao->chunk) {
368 assert(chunk->next != NULL);
369 return true;
372 return ao->chunk_finished && chunk->next == NULL;
376 * Has this chunk been consumed by all audio outputs?
378 static bool
379 chunk_is_consumed(const struct music_chunk *chunk)
381 for (unsigned i = 0; i < num_audio_outputs; ++i) {
382 const struct audio_output *ao = &audio_outputs[i];
383 bool consumed;
385 g_mutex_lock(ao->mutex);
386 consumed = chunk_is_consumed_in(ao, chunk);
387 g_mutex_unlock(ao->mutex);
389 if (!consumed)
390 return false;
393 return true;
397 * There's only one chunk left in the pipe (#g_mp), and all audio
398 * outputs have consumed it already. Clear the reference.
400 static void
401 clear_tail_chunk(G_GNUC_UNUSED const struct music_chunk *chunk, bool *locked)
403 assert(chunk->next == NULL);
404 assert(music_pipe_contains(g_mp, chunk));
406 for (unsigned i = 0; i < num_audio_outputs; ++i) {
407 struct audio_output *ao = &audio_outputs[i];
409 /* this mutex will be unlocked by the caller when it's
410 ready */
411 g_mutex_lock(ao->mutex);
412 locked[i] = ao->open;
414 if (!locked[i]) {
415 g_mutex_unlock(ao->mutex);
416 continue;
419 assert(ao->chunk == chunk);
420 assert(ao->chunk_finished);
421 ao->chunk = NULL;
425 unsigned
426 audio_output_all_check(void)
428 const struct music_chunk *chunk;
429 bool is_tail;
430 struct music_chunk *shifted;
431 bool locked[num_audio_outputs];
433 assert(g_music_buffer != NULL);
434 assert(g_mp != NULL);
436 while ((chunk = music_pipe_peek(g_mp)) != NULL) {
437 assert(music_pipe_size(g_mp) > 0);
439 if (!chunk_is_consumed(chunk))
440 /* at least one output is not finished playing
441 this chunk */
442 return music_pipe_size(g_mp);
444 if (chunk->length > 0 && chunk->times >= 0.0)
445 /* only update elapsed_time if the chunk
446 provides a defined value */
447 audio_output_all_elapsed_time = chunk->times;
449 is_tail = chunk->next == NULL;
450 if (is_tail)
451 /* this is the tail of the pipe - clear the
452 chunk reference in all outputs */
453 clear_tail_chunk(chunk, locked);
455 /* remove the chunk from the pipe */
456 shifted = music_pipe_shift(g_mp);
457 assert(shifted == chunk);
459 if (is_tail)
460 /* unlock all audio outputs which were locked
461 by clear_tail_chunk() */
462 for (unsigned i = 0; i < num_audio_outputs; ++i)
463 if (locked[i])
464 g_mutex_unlock(audio_outputs[i].mutex);
466 /* return the chunk to the buffer */
467 music_buffer_return(g_music_buffer, shifted);
470 return 0;
473 bool
474 audio_output_all_wait(unsigned threshold)
476 player_lock();
478 if (audio_output_all_check() < threshold) {
479 player_unlock();
480 return true;
483 player_wait();
484 player_unlock();
486 return audio_output_all_check() < threshold;
489 void
490 audio_output_all_pause(void)
492 unsigned int i;
494 audio_output_all_update();
496 for (i = 0; i < num_audio_outputs; ++i)
497 audio_output_pause(&audio_outputs[i]);
499 audio_output_wait_all();
502 void
503 audio_output_all_drain(void)
505 for (unsigned i = 0; i < num_audio_outputs; ++i)
506 audio_output_drain_async(&audio_outputs[i]);
508 audio_output_wait_all();
511 void
512 audio_output_all_cancel(void)
514 unsigned int i;
516 /* send the cancel() command to all audio outputs */
518 for (i = 0; i < num_audio_outputs; ++i)
519 audio_output_cancel(&audio_outputs[i]);
521 audio_output_wait_all();
523 /* clear the music pipe and return all chunks to the buffer */
525 if (g_mp != NULL)
526 music_pipe_clear(g_mp, g_music_buffer);
528 /* the audio outputs are now waiting for a signal, to
529 synchronize the cleared music pipe */
531 audio_output_signal_all();
533 /* invalidate elapsed_time */
535 audio_output_all_elapsed_time = -1.0;
538 void
539 audio_output_all_close(void)
541 unsigned int i;
543 for (i = 0; i < num_audio_outputs; ++i)
544 audio_output_close(&audio_outputs[i]);
546 if (g_mp != NULL) {
547 assert(g_music_buffer != NULL);
549 music_pipe_clear(g_mp, g_music_buffer);
550 music_pipe_free(g_mp);
551 g_mp = NULL;
554 g_music_buffer = NULL;
556 audio_format_clear(&input_audio_format);
558 audio_output_all_elapsed_time = -1.0;
561 void
562 audio_output_all_release(void)
564 unsigned int i;
566 for (i = 0; i < num_audio_outputs; ++i)
567 audio_output_release(&audio_outputs[i]);
569 if (g_mp != NULL) {
570 assert(g_music_buffer != NULL);
572 music_pipe_clear(g_mp, g_music_buffer);
573 music_pipe_free(g_mp);
574 g_mp = NULL;
577 g_music_buffer = NULL;
579 audio_format_clear(&input_audio_format);
581 audio_output_all_elapsed_time = -1.0;
584 void
585 audio_output_all_song_border(void)
587 /* clear the elapsed_time pointer at the beginning of a new
588 song */
589 audio_output_all_elapsed_time = 0.0;
592 float
593 audio_output_all_get_elapsed_time(void)
595 return audio_output_all_elapsed_time;