~ubuntu-branches/ubuntu/trusty/mpd/trusty

« back to all changes in this revision

Viewing changes to src/output_all.c

  • Committer: Bazaar Package Importer
  • Author(s): Angel Abad
  • Date: 2011-02-02 12:26:30 UTC
  • mfrom: (1.5.11 upstream)
  • Revision ID: james.westby@ubuntu.com-20110202122630-bdyx8w4k94doz4fs
Tags: 0.16.1-1ubuntu1
* Merge from debian unstable. Remaining changes:
  - debian/control:
    + Don't build-depend on libmikmod2-dev (Debian bug #510675).
    + Move avahi-daemon from Suggests field to Recommends field.
  - debian/mpd.init.d:
    + Read mpd user from mpd.conf.
  - debian/control, debian/rules:
    + Add libmp3lame-dev to the build dependencies and enable lame.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright (C) 2003-2009 The Music Player Daemon Project
 
2
 * Copyright (C) 2003-2010 The Music Player Daemon Project
3
3
 * http://www.musicpd.org
4
4
 *
5
5
 * This program is free software; you can redistribute it and/or modify
17
17
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18
18
 */
19
19
 
 
20
#include "config.h"
20
21
#include "output_all.h"
21
22
#include "output_internal.h"
22
23
#include "output_control.h"
25
26
#include "pipe.h"
26
27
#include "buffer.h"
27
28
#include "player_control.h"
 
29
#include "mpd_error.h"
28
30
 
29
31
#ifndef NDEBUG
30
32
#include "chunk.h"
52
54
 */
53
55
static struct music_pipe *g_mp;
54
56
 
 
57
/**
 
58
 * The "elapsed_time" stamp of the most recently finished chunk.
 
59
 */
 
60
static float audio_output_all_elapsed_time = -1.0;
 
61
 
55
62
unsigned int audio_output_count(void)
56
63
{
57
64
        return num_audio_outputs;
116
123
 
117
124
                if (!audio_output_init(output, param, &error)) {
118
125
                        if (param != NULL)
119
 
                                g_error("line %i: %s",
120
 
                                        param->line, error->message);
 
126
                                MPD_ERROR("line %i: %s",
 
127
                                          param->line, error->message);
121
128
                        else
122
 
                                g_error("%s", error->message);
 
129
                                MPD_ERROR("%s", error->message);
123
130
                }
124
131
 
125
132
                /* require output names to be unique: */
126
133
                for (j = 0; j < i; j++) {
127
134
                        if (!strcmp(output->name, audio_outputs[j].name)) {
128
 
                                g_error("output devices with identical "
129
 
                                        "names: %s\n", output->name);
 
135
                                MPD_ERROR("output devices with identical "
 
136
                                          "names: %s\n", output->name);
130
137
                        }
131
138
                }
132
139
        }
138
145
        unsigned int i;
139
146
 
140
147
        for (i = 0; i < num_audio_outputs; i++) {
 
148
                audio_output_disable(&audio_outputs[i]);
141
149
                audio_output_finish(&audio_outputs[i]);
142
150
        }
143
151
 
148
156
        notify_deinit(&audio_output_client_notify);
149
157
}
150
158
 
 
159
void
 
160
audio_output_all_enable_disable(void)
 
161
{
 
162
        for (unsigned i = 0; i < num_audio_outputs; i++) {
 
163
                struct audio_output *ao = &audio_outputs[i];
 
164
                bool enabled;
 
165
 
 
166
                g_mutex_lock(ao->mutex);
 
167
                enabled = ao->really_enabled;
 
168
                g_mutex_unlock(ao->mutex);
 
169
 
 
170
                if (ao->enabled != enabled) {
 
171
                        if (ao->enabled)
 
172
                                audio_output_enable(ao);
 
173
                        else
 
174
                                audio_output_disable(ao);
 
175
                }
 
176
        }
 
177
}
151
178
 
152
179
/**
153
180
 * Determine if all (active) outputs have finished the current
156
183
static bool
157
184
audio_output_all_finished(void)
158
185
{
159
 
        for (unsigned i = 0; i < num_audio_outputs; ++i)
160
 
                if (audio_output_is_open(&audio_outputs[i]) &&
161
 
                    !audio_output_command_is_finished(&audio_outputs[i]))
 
186
        for (unsigned i = 0; i < num_audio_outputs; ++i) {
 
187
                struct audio_output *ao = &audio_outputs[i];
 
188
                bool not_finished;
 
189
 
 
190
                g_mutex_lock(ao->mutex);
 
191
                not_finished = audio_output_is_open(ao) &&
 
192
                        !audio_output_command_is_finished(ao);
 
193
                g_mutex_unlock(ao->mutex);
 
194
 
 
195
                if (not_finished)
162
196
                        return false;
 
197
        }
163
198
 
164
199
        return true;
165
200
}
170
205
                notify_wait(&audio_output_client_notify);
171
206
}
172
207
 
 
208
/**
 
209
 * Signals the audio output if it is open.  This function locks the
 
210
 * mutex.
 
211
 */
 
212
static void
 
213
audio_output_lock_signal(struct audio_output *ao)
 
214
{
 
215
        g_mutex_lock(ao->mutex);
 
216
        if (audio_output_is_open(ao))
 
217
                g_cond_signal(ao->cond);
 
218
        g_mutex_unlock(ao->mutex);
 
219
}
 
220
 
 
221
/**
 
222
 * Signals all audio outputs which are open.
 
223
 */
 
224
static void
 
225
audio_output_signal_all(void)
 
226
{
 
227
        for (unsigned i = 0; i < num_audio_outputs; ++i)
 
228
                audio_output_lock_signal(&audio_outputs[i]);
 
229
}
 
230
 
173
231
static void
174
232
audio_output_reset_reopen(struct audio_output *ao)
175
233
{
237
295
        music_pipe_push(g_mp, chunk);
238
296
 
239
297
        for (i = 0; i < num_audio_outputs; ++i)
240
 
                if (audio_output_is_open(&audio_outputs[i]))
241
 
                        audio_output_play(&audio_outputs[i]);
 
298
                audio_output_play(&audio_outputs[i]);
242
299
 
243
300
        return true;
244
301
}
273
330
        input_audio_format = *audio_format;
274
331
 
275
332
        audio_output_all_reset_reopen();
 
333
        audio_output_all_enable_disable();
276
334
        audio_output_all_update();
277
335
 
278
336
        for (i = 0; i < num_audio_outputs; ++i) {
385
443
                           this chunk */
386
444
                        return music_pipe_size(g_mp);
387
445
 
 
446
                if (chunk->length > 0 && chunk->times >= 0.0)
 
447
                        /* only update elapsed_time if the chunk
 
448
                           provides a defined value */
 
449
                        audio_output_all_elapsed_time = chunk->times;
 
450
 
388
451
                is_tail = chunk->next == NULL;
389
452
                if (is_tail)
390
453
                        /* this is the tail of the pipe - clear the
412
475
bool
413
476
audio_output_all_wait(unsigned threshold)
414
477
{
415
 
        if (audio_output_all_check() < threshold)
 
478
        player_lock();
 
479
 
 
480
        if (audio_output_all_check() < threshold) {
 
481
                player_unlock();
416
482
                return true;
 
483
        }
417
484
 
418
 
        notify_wait(&pc.notify);
 
485
        player_wait();
 
486
        player_unlock();
419
487
 
420
488
        return audio_output_all_check() < threshold;
421
489
}
428
496
        audio_output_all_update();
429
497
 
430
498
        for (i = 0; i < num_audio_outputs; ++i)
431
 
                if (audio_output_is_open(&audio_outputs[i]))
432
 
                        audio_output_pause(&audio_outputs[i]);
 
499
                audio_output_pause(&audio_outputs[i]);
 
500
 
 
501
        audio_output_wait_all();
 
502
}
 
503
 
 
504
void
 
505
audio_output_all_drain(void)
 
506
{
 
507
        for (unsigned i = 0; i < num_audio_outputs; ++i)
 
508
                audio_output_drain_async(&audio_outputs[i]);
433
509
 
434
510
        audio_output_wait_all();
435
511
}
441
517
 
442
518
        /* send the cancel() command to all audio outputs */
443
519
 
444
 
        for (i = 0; i < num_audio_outputs; ++i) {
445
 
                if (audio_output_is_open(&audio_outputs[i]))
446
 
                        audio_output_cancel(&audio_outputs[i]);
447
 
        }
 
520
        for (i = 0; i < num_audio_outputs; ++i)
 
521
                audio_output_cancel(&audio_outputs[i]);
448
522
 
449
523
        audio_output_wait_all();
450
524
 
452
526
 
453
527
        if (g_mp != NULL)
454
528
                music_pipe_clear(g_mp, g_music_buffer);
 
529
 
 
530
        /* the audio outputs are now waiting for a signal, to
 
531
           synchronize the cleared music pipe */
 
532
 
 
533
        audio_output_signal_all();
 
534
 
 
535
        /* invalidate elapsed_time */
 
536
 
 
537
        audio_output_all_elapsed_time = -1.0;
455
538
}
456
539
 
457
540
void
473
556
        g_music_buffer = NULL;
474
557
 
475
558
        audio_format_clear(&input_audio_format);
 
559
 
 
560
        audio_output_all_elapsed_time = -1.0;
 
561
}
 
562
 
 
563
void
 
564
audio_output_all_release(void)
 
565
{
 
566
        unsigned int i;
 
567
 
 
568
        for (i = 0; i < num_audio_outputs; ++i)
 
569
                audio_output_release(&audio_outputs[i]);
 
570
 
 
571
        if (g_mp != NULL) {
 
572
                assert(g_music_buffer != NULL);
 
573
 
 
574
                music_pipe_clear(g_mp, g_music_buffer);
 
575
                music_pipe_free(g_mp);
 
576
                g_mp = NULL;
 
577
        }
 
578
 
 
579
        g_music_buffer = NULL;
 
580
 
 
581
        audio_format_clear(&input_audio_format);
 
582
 
 
583
        audio_output_all_elapsed_time = -1.0;
 
584
}
 
585
 
 
586
void
 
587
audio_output_all_song_border(void)
 
588
{
 
589
        /* clear the elapsed_time pointer at the beginning of a new
 
590
           song */
 
591
        audio_output_all_elapsed_time = 0.0;
 
592
}
 
593
 
 
594
float
 
595
audio_output_all_get_elapsed_time(void)
 
596
{
 
597
        return audio_output_all_elapsed_time;
476
598
}