annotate libao2/ao_pulse.c @ 29288:4a1c217a844b

In all demux_info_add calls change "name" to "title". Currently "name" and "title" are both used at random, this makes it consistent. "title" was chosen because it is less ambiguous and also the get_meta_title slave mode command uses that (there is no get_meta_name command).
author reimar
date Sat, 30 May 2009 13:18:57 +0000
parents aa06c29db609
children ae5d67d8ee95
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
24782
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
1 /*
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
2 * PulseAudio audio output driver.
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
3 * Copyright (C) 2006 Lennart Poettering
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
4 * Copyright (C) 2007 Reimar Doeffinger
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
5 *
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
6 * This file is part of MPlayer.
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
7 *
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
8 * MPlayer is free software; you can redistribute it and/or modify
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
9 * it under the terms of the GNU General Public License as published by
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
10 * the Free Software Foundation; either version 2 of the License, or
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
11 * (at your option) any later version.
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
12 *
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
13 * MPlayer is distributed in the hope that it will be useful,
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
16 * GNU General Public License for more details.
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
17 *
26743
0f42fb42843c Use standard license headers with standard formatting.
diego
parents: 26649
diff changeset
18 * You should have received a copy of the GNU General Public License along
0f42fb42843c Use standard license headers with standard formatting.
diego
parents: 26649
diff changeset
19 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
0f42fb42843c Use standard license headers with standard formatting.
diego
parents: 26649
diff changeset
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24782
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
21 */
26743
0f42fb42843c Use standard license headers with standard formatting.
diego
parents: 26649
diff changeset
22
24782
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
23 #include <string.h>
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
24
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
25 #include <pulse/pulseaudio.h>
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
26
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
27 #include "config.h"
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
28 #include "libaf/af_format.h"
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
29 #include "mp_msg.h"
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
30 #include "audio_out.h"
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
31 #include "audio_out_internal.h"
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
32
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
33 #define PULSE_CLIENT_NAME "MPlayer"
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
34
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
35 /** General driver info */
28823
9a5b8c2ed6de Make ao_info_t structs const.
reimar
parents: 28633
diff changeset
36 static const ao_info_t info = {
24782
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
37 "PulseAudio audio output",
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
38 "pulse",
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
39 "Lennart Poettering",
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
40 ""
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
41 };
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
42
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
43 /** PulseAudio playback stream object */
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
44 static struct pa_stream *stream;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
45
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
46 /** PulseAudio connection context */
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
47 static struct pa_context *context;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
48
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
49 /** Main event loop object */
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
50 static struct pa_threaded_mainloop *mainloop;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
51
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
52 /** A temporary variable to store the current volume */
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
53 static pa_cvolume volume;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
54
28633
28fe0787a67c Work around a PulseAudio bug that causes MPlayer to hang after unpausing.
reimar
parents: 26743
diff changeset
55 static int broken_pause;
28fe0787a67c Work around a PulseAudio bug that causes MPlayer to hang after unpausing.
reimar
parents: 26743
diff changeset
56
24782
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
57 LIBAO_EXTERN(pulse)
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
58
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
59 #define GENERIC_ERR_MSG(ctx, str) \
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
60 mp_msg(MSGT_AO, MSGL_ERR, "AO: [pulse] "str": %s\n", \
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
61 pa_strerror(pa_context_errno(ctx)))
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
62
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
63 static void context_state_cb(pa_context *c, void *userdata) {
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
64 switch (pa_context_get_state(c)) {
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
65 case PA_CONTEXT_READY:
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
66 case PA_CONTEXT_TERMINATED:
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
67 case PA_CONTEXT_FAILED:
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
68 pa_threaded_mainloop_signal(mainloop, 0);
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
69 break;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
70 }
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
71 }
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
72
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
73 static void stream_state_cb(pa_stream *s, void *userdata) {
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
74 switch (pa_stream_get_state(s)) {
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
75 case PA_STREAM_READY:
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
76 case PA_STREAM_FAILED:
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
77 case PA_STREAM_TERMINATED:
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
78 pa_threaded_mainloop_signal(mainloop, 0);
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
79 break;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
80 }
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
81 }
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
82
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
83 static void stream_request_cb(pa_stream *s, size_t length, void *userdata) {
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
84 pa_threaded_mainloop_signal(mainloop, 0);
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
85 }
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
86
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
87 static void stream_latency_update_cb(pa_stream *s, void *userdata) {
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
88 pa_threaded_mainloop_signal(mainloop, 0);
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
89 }
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
90
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
91 static void success_cb(pa_stream *s, int success, void *userdata) {
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
92 if (userdata)
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
93 *(int *)userdata = success;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
94 pa_threaded_mainloop_signal(mainloop, 0);
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
95 }
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
96
25383
9ca05492f9f3 Documentation for waitop function
reimar
parents: 24923
diff changeset
97 /**
9ca05492f9f3 Documentation for waitop function
reimar
parents: 24923
diff changeset
98 * \brief waits for a pulseaudio operation to finish, frees it and
9ca05492f9f3 Documentation for waitop function
reimar
parents: 24923
diff changeset
99 * unlocks the mainloop
9ca05492f9f3 Documentation for waitop function
reimar
parents: 24923
diff changeset
100 * \param op operation to wait for
9ca05492f9f3 Documentation for waitop function
reimar
parents: 24923
diff changeset
101 * \return 1 if operation has finished normally (DONE state), 0 otherwise
9ca05492f9f3 Documentation for waitop function
reimar
parents: 24923
diff changeset
102 */
24782
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
103 static int waitop(pa_operation *op) {
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
104 pa_operation_state_t state;
29117
010781e92294 Make sure waitop always unlocks the mainloop even if the operation could not
reimar
parents: 28823
diff changeset
105 if (!op) {
010781e92294 Make sure waitop always unlocks the mainloop even if the operation could not
reimar
parents: 28823
diff changeset
106 pa_threaded_mainloop_unlock(mainloop);
010781e92294 Make sure waitop always unlocks the mainloop even if the operation could not
reimar
parents: 28823
diff changeset
107 return 0;
010781e92294 Make sure waitop always unlocks the mainloop even if the operation could not
reimar
parents: 28823
diff changeset
108 }
24782
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
109 state = pa_operation_get_state(op);
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
110 while (state == PA_OPERATION_RUNNING) {
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
111 pa_threaded_mainloop_wait(mainloop);
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
112 state = pa_operation_get_state(op);
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
113 }
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
114 pa_operation_unref(op);
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
115 pa_threaded_mainloop_unlock(mainloop);
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
116 return state == PA_OPERATION_DONE;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
117 }
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
118
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
119 static const struct format_map_s {
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
120 int mp_format;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
121 pa_sample_format_t pa_format;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
122 } format_maps[] = {
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
123 {AF_FORMAT_S16_LE, PA_SAMPLE_S16LE},
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
124 {AF_FORMAT_S16_BE, PA_SAMPLE_S16BE},
26649
07d106323e5c Avoid dependency on newer pulseaudio version.
reimar
parents: 26603
diff changeset
125 #ifdef PA_SAMPLE_S32NE
26603
c07abb5a5bef Add support for 32 bit format to ao_pulse.
reimar
parents: 26602
diff changeset
126 {AF_FORMAT_S32_LE, PA_SAMPLE_S32LE},
c07abb5a5bef Add support for 32 bit format to ao_pulse.
reimar
parents: 26602
diff changeset
127 {AF_FORMAT_S32_BE, PA_SAMPLE_S32BE},
26649
07d106323e5c Avoid dependency on newer pulseaudio version.
reimar
parents: 26603
diff changeset
128 #endif
07d106323e5c Avoid dependency on newer pulseaudio version.
reimar
parents: 26603
diff changeset
129 #ifdef PA_SAMPLE_FLOAT32NE
24782
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
130 {AF_FORMAT_FLOAT_LE, PA_SAMPLE_FLOAT32LE},
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
131 {AF_FORMAT_FLOAT_BE, PA_SAMPLE_FLOAT32BE},
26649
07d106323e5c Avoid dependency on newer pulseaudio version.
reimar
parents: 26603
diff changeset
132 #endif
26602
d48e2d7191df Make ao_pulse fall back to s16le format instead of just failing.
reimar
parents: 25386
diff changeset
133 {AF_FORMAT_U8, PA_SAMPLE_U8},
24782
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
134 {AF_FORMAT_MU_LAW, PA_SAMPLE_ULAW},
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
135 {AF_FORMAT_A_LAW, PA_SAMPLE_ALAW},
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
136 {AF_FORMAT_UNKNOWN, 0}
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
137 };
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
138
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
139 static int init(int rate_hz, int channels, int format, int flags) {
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
140 struct pa_sample_spec ss;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
141 struct pa_channel_map map;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
142 const struct format_map_s *fmt_map;
24921
148ca265fcb6 Change parsing to allow host == NULL and sink != NULL
reimar
parents: 24920
diff changeset
143 char *devarg = NULL;
24782
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
144 char *host = NULL;
24919
51372a34bc7d Make sink variable local, it is only used in one place
reimar
parents: 24782
diff changeset
145 char *sink = NULL;
28633
28fe0787a67c Work around a PulseAudio bug that causes MPlayer to hang after unpausing.
reimar
parents: 26743
diff changeset
146 char *version = pa_get_library_version();
24782
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
147
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
148 if (ao_subdevice) {
24921
148ca265fcb6 Change parsing to allow host == NULL and sink != NULL
reimar
parents: 24920
diff changeset
149 devarg = strdup(ao_subdevice);
148ca265fcb6 Change parsing to allow host == NULL and sink != NULL
reimar
parents: 24920
diff changeset
150 sink = strchr(devarg, ':');
24920
12dc34b2e41c Simplify argument "parsing"
reimar
parents: 24919
diff changeset
151 if (sink) *sink++ = 0;
24921
148ca265fcb6 Change parsing to allow host == NULL and sink != NULL
reimar
parents: 24920
diff changeset
152 if (devarg[0]) host = devarg;
24782
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
153 }
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
154
28633
28fe0787a67c Work around a PulseAudio bug that causes MPlayer to hang after unpausing.
reimar
parents: 26743
diff changeset
155 broken_pause = 0;
29120
aa06c29db609 Disable pause-hack from PulseAudio 0.9.15 on, it should be fixed.
reimar
parents: 29119
diff changeset
156 // not sure which versions are affected, assume 0.9.11* to 0.9.14*
28633
28fe0787a67c Work around a PulseAudio bug that causes MPlayer to hang after unpausing.
reimar
parents: 26743
diff changeset
157 // known bad: 0.9.14, 0.9.13
29120
aa06c29db609 Disable pause-hack from PulseAudio 0.9.15 on, it should be fixed.
reimar
parents: 29119
diff changeset
158 // known good: 0.9.9, 0.9.10, 0.9.15
28633
28fe0787a67c Work around a PulseAudio bug that causes MPlayer to hang after unpausing.
reimar
parents: 26743
diff changeset
159 // to test: pause, wait ca. 5 seconds framestep and see if MPlayer hangs somewhen
29120
aa06c29db609 Disable pause-hack from PulseAudio 0.9.15 on, it should be fixed.
reimar
parents: 29119
diff changeset
160 if (strncmp(version, "0.9.1", 5) == 0 && version[5] >= '1' && version[5] <= '4') {
28633
28fe0787a67c Work around a PulseAudio bug that causes MPlayer to hang after unpausing.
reimar
parents: 26743
diff changeset
161 mp_msg(MSGT_AO, MSGL_WARN, "[pulse] working around probably broken pause functionality,\n"
28fe0787a67c Work around a PulseAudio bug that causes MPlayer to hang after unpausing.
reimar
parents: 26743
diff changeset
162 " see http://www.pulseaudio.org/ticket/440\n");
28fe0787a67c Work around a PulseAudio bug that causes MPlayer to hang after unpausing.
reimar
parents: 26743
diff changeset
163 broken_pause = 1;
28fe0787a67c Work around a PulseAudio bug that causes MPlayer to hang after unpausing.
reimar
parents: 26743
diff changeset
164 }
28fe0787a67c Work around a PulseAudio bug that causes MPlayer to hang after unpausing.
reimar
parents: 26743
diff changeset
165
24782
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
166 ss.channels = channels;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
167 ss.rate = rate_hz;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
168
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
169 ao_data.samplerate = rate_hz;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
170 ao_data.channels = channels;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
171
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
172 fmt_map = format_maps;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
173 while (fmt_map->mp_format != format) {
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
174 if (fmt_map->mp_format == AF_FORMAT_UNKNOWN) {
26602
d48e2d7191df Make ao_pulse fall back to s16le format instead of just failing.
reimar
parents: 25386
diff changeset
175 mp_msg(MSGT_AO, MSGL_V, "AO: [pulse] Unsupported format, using default\n");
d48e2d7191df Make ao_pulse fall back to s16le format instead of just failing.
reimar
parents: 25386
diff changeset
176 fmt_map = format_maps;
d48e2d7191df Make ao_pulse fall back to s16le format instead of just failing.
reimar
parents: 25386
diff changeset
177 break;
24782
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
178 }
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
179 fmt_map++;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
180 }
26602
d48e2d7191df Make ao_pulse fall back to s16le format instead of just failing.
reimar
parents: 25386
diff changeset
181 ao_data.format = fmt_map->mp_format;
24782
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
182 ss.format = fmt_map->pa_format;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
183
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
184 if (!pa_sample_spec_valid(&ss)) {
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
185 mp_msg(MSGT_AO, MSGL_ERR, "AO: [pulse] Invalid sample spec\n");
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
186 goto fail;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
187 }
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
188
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
189 pa_channel_map_init_auto(&map, ss.channels, PA_CHANNEL_MAP_ALSA);
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
190 ao_data.bps = pa_bytes_per_second(&ss);
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
191
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
192 pa_cvolume_reset(&volume, ss.channels);
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
193
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
194 if (!(mainloop = pa_threaded_mainloop_new())) {
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
195 mp_msg(MSGT_AO, MSGL_ERR, "AO: [pulse] Failed to allocate main loop\n");
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
196 goto fail;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
197 }
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
198
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
199 if (!(context = pa_context_new(pa_threaded_mainloop_get_api(mainloop), PULSE_CLIENT_NAME))) {
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
200 mp_msg(MSGT_AO, MSGL_ERR, "AO: [pulse] Failed to allocate context\n");
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
201 goto fail;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
202 }
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
203
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
204 pa_context_set_state_callback(context, context_state_cb, NULL);
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
205
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
206 if (pa_context_connect(context, host, 0, NULL) < 0)
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
207 goto fail;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
208
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
209 pa_threaded_mainloop_lock(mainloop);
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
210
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
211 if (pa_threaded_mainloop_start(mainloop) < 0)
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
212 goto unlock_and_fail;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
213
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
214 /* Wait until the context is ready */
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
215 pa_threaded_mainloop_wait(mainloop);
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
216
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
217 if (pa_context_get_state(context) != PA_CONTEXT_READY)
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
218 goto unlock_and_fail;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
219
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
220 if (!(stream = pa_stream_new(context, "audio stream", &ss, &map)))
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
221 goto unlock_and_fail;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
222
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
223 pa_stream_set_state_callback(stream, stream_state_cb, NULL);
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
224 pa_stream_set_write_callback(stream, stream_request_cb, NULL);
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
225 pa_stream_set_latency_update_callback(stream, stream_latency_update_cb, NULL);
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
226
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
227 if (pa_stream_connect_playback(stream, sink, NULL, PA_STREAM_INTERPOLATE_TIMING|PA_STREAM_AUTO_TIMING_UPDATE, &volume, NULL) < 0)
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
228 goto unlock_and_fail;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
229
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
230 /* Wait until the stream is ready */
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
231 pa_threaded_mainloop_wait(mainloop);
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
232
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
233 if (pa_stream_get_state(stream) != PA_STREAM_READY)
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
234 goto unlock_and_fail;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
235
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
236 pa_threaded_mainloop_unlock(mainloop);
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
237
24921
148ca265fcb6 Change parsing to allow host == NULL and sink != NULL
reimar
parents: 24920
diff changeset
238 free(devarg);
24782
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
239 return 1;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
240
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
241 unlock_and_fail:
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
242
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
243 if (mainloop)
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
244 pa_threaded_mainloop_unlock(mainloop);
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
245
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
246 fail:
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
247 if (context)
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
248 GENERIC_ERR_MSG(context, "Init failed");
24921
148ca265fcb6 Change parsing to allow host == NULL and sink != NULL
reimar
parents: 24920
diff changeset
249 free(devarg);
24782
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
250 uninit(1);
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
251 return 0;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
252 }
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
253
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
254 /** Destroy libao driver */
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
255 static void uninit(int immed) {
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
256 if (stream && !immed) {
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
257 pa_threaded_mainloop_lock(mainloop);
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
258 waitop(pa_stream_drain(stream, success_cb, NULL));
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
259 }
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
260
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
261 if (mainloop)
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
262 pa_threaded_mainloop_stop(mainloop);
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
263
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
264 if (stream) {
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
265 pa_stream_disconnect(stream);
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
266 pa_stream_unref(stream);
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
267 stream = NULL;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
268 }
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
269
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
270 if (context) {
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
271 pa_context_disconnect(context);
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
272 pa_context_unref(context);
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
273 context = NULL;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
274 }
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
275
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
276 if (mainloop) {
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
277 pa_threaded_mainloop_free(mainloop);
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
278 mainloop = NULL;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
279 }
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
280 }
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
281
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
282 /** Play the specified data to the pulseaudio server */
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
283 static int play(void* data, int len, int flags) {
25386
bd46b759fd35 pa_stream_write reportedly needs locking of the main loop
reimar
parents: 25385
diff changeset
284 pa_threaded_mainloop_lock(mainloop);
25385
52f6c42c43bb Fix indentation
reimar
parents: 25384
diff changeset
285 if (pa_stream_write(stream, data, len, NULL, 0, PA_SEEK_RELATIVE) < 0) {
52f6c42c43bb Fix indentation
reimar
parents: 25384
diff changeset
286 GENERIC_ERR_MSG(context, "pa_stream_write() failed");
25386
bd46b759fd35 pa_stream_write reportedly needs locking of the main loop
reimar
parents: 25385
diff changeset
287 len = -1;
25385
52f6c42c43bb Fix indentation
reimar
parents: 25384
diff changeset
288 }
25386
bd46b759fd35 pa_stream_write reportedly needs locking of the main loop
reimar
parents: 25385
diff changeset
289 pa_threaded_mainloop_unlock(mainloop);
24782
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
290 return len;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
291 }
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
292
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
293 static void cork(int b) {
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
294 int success = 0;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
295 pa_threaded_mainloop_lock(mainloop);
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
296 if (!waitop(pa_stream_cork(stream, b, success_cb, &success)) ||
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
297 !success)
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
298 GENERIC_ERR_MSG(context, "pa_stream_cork() failed");
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
299 }
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
300
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
301 /** Pause the audio stream by corking it on the server */
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
302 static void audio_pause(void) {
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
303 cork(1);
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
304 }
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
305
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
306 /** Resume the audio stream by uncorking it on the server */
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
307 static void audio_resume(void) {
28633
28fe0787a67c Work around a PulseAudio bug that causes MPlayer to hang after unpausing.
reimar
parents: 26743
diff changeset
308 // without this, certain versions will cause an infinite hang because
28fe0787a67c Work around a PulseAudio bug that causes MPlayer to hang after unpausing.
reimar
parents: 26743
diff changeset
309 // pa_stream_writable_size returns 0 always.
28fe0787a67c Work around a PulseAudio bug that causes MPlayer to hang after unpausing.
reimar
parents: 26743
diff changeset
310 // Note that this workaround causes A-V desync after pause
28fe0787a67c Work around a PulseAudio bug that causes MPlayer to hang after unpausing.
reimar
parents: 26743
diff changeset
311 if (broken_pause) reset();
24782
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
312 cork(0);
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
313 }
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
314
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
315 /** Reset the audio stream, i.e. flush the playback buffer on the server side */
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
316 static void reset(void) {
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
317 int success = 0;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
318 pa_threaded_mainloop_lock(mainloop);
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
319 if (!waitop(pa_stream_flush(stream, success_cb, &success)) ||
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
320 !success)
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
321 GENERIC_ERR_MSG(context, "pa_stream_flush() failed");
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
322 }
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
323
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
324 /** Return number of bytes that may be written to the server without blocking */
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
325 static int get_space(void) {
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
326 size_t l;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
327 pa_threaded_mainloop_lock(mainloop);
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
328 l = pa_stream_writable_size(stream);
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
329 pa_threaded_mainloop_unlock(mainloop);
24923
d0d04fe92bce Remove idiotic check that would always be false
reimar
parents: 24921
diff changeset
330 return l;
24782
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
331 }
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
332
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
333 /** Return the current latency in seconds */
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
334 static float get_delay(void) {
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
335 pa_usec_t latency = (pa_usec_t) -1;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
336 pa_threaded_mainloop_lock(mainloop);
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
337 while (pa_stream_get_latency(stream, &latency, NULL) < 0) {
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
338 if (pa_context_errno(context) != PA_ERR_NODATA) {
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
339 GENERIC_ERR_MSG(context, "pa_stream_get_latency() failed");
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
340 break;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
341 }
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
342 /* Wait until latency data is available again */
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
343 pa_threaded_mainloop_wait(mainloop);
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
344 }
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
345 pa_threaded_mainloop_unlock(mainloop);
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
346 return latency == (pa_usec_t) -1 ? 0 : latency / 1000000.0;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
347 }
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
348
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
349 /** A callback function that is called when the
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
350 * pa_context_get_sink_input_info() operation completes. Saves the
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
351 * volume field of the specified structure to the global variable volume. */
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
352 static void info_func(struct pa_context *c, const struct pa_sink_input_info *i, int is_last, void *userdata) {
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
353 if (is_last < 0) {
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
354 GENERIC_ERR_MSG(context, "Failed to get sink input info");
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
355 return;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
356 }
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
357 if (!i)
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
358 return;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
359 volume = i->volume;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
360 pa_threaded_mainloop_signal(mainloop, 0);
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
361 }
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
362
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
363 static int control(int cmd, void *arg) {
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
364 switch (cmd) {
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
365 case AOCONTROL_GET_VOLUME: {
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
366 ao_control_vol_t *vol = arg;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
367 uint32_t devidx = pa_stream_get_index(stream);
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
368 pa_threaded_mainloop_lock(mainloop);
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
369 if (!waitop(pa_context_get_sink_input_info(context, devidx, info_func, NULL))) {
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
370 GENERIC_ERR_MSG(context, "pa_stream_get_sink_input_info() failed");
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
371 return CONTROL_ERROR;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
372 }
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
373
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
374 if (volume.channels != 2)
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
375 vol->left = vol->right = pa_cvolume_avg(&volume)*100/PA_VOLUME_NORM;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
376 else {
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
377 vol->left = volume.values[0]*100/PA_VOLUME_NORM;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
378 vol->right = volume.values[1]*100/PA_VOLUME_NORM;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
379 }
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
380
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
381 return CONTROL_OK;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
382 }
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
383
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
384 case AOCONTROL_SET_VOLUME: {
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
385 const ao_control_vol_t *vol = arg;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
386 pa_operation *o;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
387
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
388 if (volume.channels != 2)
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
389 pa_cvolume_set(&volume, volume.channels, (pa_volume_t)vol->left*PA_VOLUME_NORM/100);
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
390 else {
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
391 volume.values[0] = (pa_volume_t)vol->left*PA_VOLUME_NORM/100;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
392 volume.values[1] = (pa_volume_t)vol->right*PA_VOLUME_NORM/100;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
393 }
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
394
29118
17c6a6c192a7 Also lock the mainloop when doing adjusting the volume for PulseAudio.
reimar
parents: 29117
diff changeset
395 pa_threaded_mainloop_lock(mainloop);
29119
52afd0fe451b Split oversized of "argument" onto a separate line.
reimar
parents: 29118
diff changeset
396 o = pa_context_set_sink_input_volume(context, pa_stream_get_index(stream), &volume, NULL, NULL);
52afd0fe451b Split oversized of "argument" onto a separate line.
reimar
parents: 29118
diff changeset
397 if (!o) {
29118
17c6a6c192a7 Also lock the mainloop when doing adjusting the volume for PulseAudio.
reimar
parents: 29117
diff changeset
398 pa_threaded_mainloop_unlock(mainloop);
24782
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
399 GENERIC_ERR_MSG(context, "pa_context_set_sink_input_volume() failed");
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
400 return CONTROL_ERROR;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
401 }
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
402 /* We don't wait for completion here */
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
403 pa_operation_unref(o);
29118
17c6a6c192a7 Also lock the mainloop when doing adjusting the volume for PulseAudio.
reimar
parents: 29117
diff changeset
404 pa_threaded_mainloop_unlock(mainloop);
24782
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
405 return CONTROL_OK;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
406 }
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
407
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
408 default:
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
409 return CONTROL_UNKNOWN;
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
410 }
6479c850fcfd Add missing ao_pulse.c
reimar
parents:
diff changeset
411 }