ao_pulse: support native mute control
[mplayer.git] / libao2 / ao_rsound.c
blob9a8b8cb4fcb014d5fc8afa3484562a644194ecab
1 /*
2 * RSound audio output driver
4 * Copyright (C) 2011 Hans-Kristian Arntzen
6 * This file is part of mplayer2.
8 * mplayer2 is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * mplayer2 is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with mplayer2; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include "config.h"
25 #include <stdlib.h>
26 #include <string.h>
27 #include <unistd.h>
28 #include <rsound.h>
30 #include "talloc.h"
32 #include "subopt-helper.h"
33 #include "osdep/timer.h"
34 #include "libaf/af_format.h"
35 #include "audio_out.h"
37 struct priv {
38 rsound_t *rd;
41 static int set_format(struct ao *ao)
43 int rsd_format;
45 switch (ao->format) {
46 case AF_FORMAT_U8:
47 rsd_format = RSD_U8;
48 break;
49 case AF_FORMAT_S8:
50 rsd_format = RSD_S8;
51 break;
52 case AF_FORMAT_S16_LE:
53 rsd_format = RSD_S16_LE;
54 break;
55 case AF_FORMAT_S16_BE:
56 rsd_format = RSD_S16_BE;
57 break;
58 case AF_FORMAT_U16_LE:
59 rsd_format = RSD_U16_LE;
60 break;
61 case AF_FORMAT_U16_BE:
62 rsd_format = RSD_U16_BE;
63 break;
64 case AF_FORMAT_S24_LE:
65 case AF_FORMAT_S24_BE:
66 case AF_FORMAT_U24_LE:
67 case AF_FORMAT_U24_BE:
68 rsd_format = RSD_S32_LE;
69 ao->format = AF_FORMAT_S32_LE;
70 break;
71 case AF_FORMAT_S32_LE:
72 rsd_format = RSD_S32_LE;
73 break;
74 case AF_FORMAT_S32_BE:
75 rsd_format = RSD_S32_BE;
76 break;
77 case AF_FORMAT_U32_LE:
78 rsd_format = RSD_U32_LE;
79 break;
80 case AF_FORMAT_U32_BE:
81 rsd_format = RSD_U32_BE;
82 break;
83 case AF_FORMAT_A_LAW:
84 rsd_format = RSD_ALAW;
85 break;
86 case AF_FORMAT_MU_LAW:
87 rsd_format = RSD_MULAW;
88 break;
89 default:
90 rsd_format = RSD_S16_LE;
91 ao->format = AF_FORMAT_S16_LE;
94 return rsd_format;
97 static int init(struct ao *ao, char *params)
99 struct priv *priv = talloc_zero(ao, struct priv);
100 ao->priv = priv;
102 char *host = NULL;
103 char *port = NULL;
105 const opt_t subopts[] = {
106 {"host", OPT_ARG_MSTRZ, &host, NULL},
107 {"port", OPT_ARG_MSTRZ, &port, NULL},
108 {NULL}
111 if (subopt_parse(params, subopts) != 0)
112 return -1;
114 if (rsd_init(&priv->rd) < 0) {
115 free(host);
116 free(port);
117 return -1;
120 if (host) {
121 rsd_set_param(priv->rd, RSD_HOST, host);
122 free(host);
125 if (port) {
126 rsd_set_param(priv->rd, RSD_PORT, port);
127 free(port);
130 rsd_set_param(priv->rd, RSD_SAMPLERATE, &ao->samplerate);
131 rsd_set_param(priv->rd, RSD_CHANNELS, &ao->channels);
133 int rsd_format = set_format(ao);
134 rsd_set_param(priv->rd, RSD_FORMAT, &rsd_format);
136 if (rsd_start(priv->rd) < 0) {
137 rsd_free(priv->rd);
138 return -1;
141 ao->bps = ao->channels * ao->samplerate * af_fmt2bits(ao->format) / 8;
143 return 0;
146 static void uninit(struct ao *ao, bool cut_audio)
148 struct priv *priv = ao->priv;
149 /* The API does not provide a direct way to explicitly wait until
150 * the last byte has been played server-side as this cannot be
151 * guaranteed by backend drivers, so we approximate this behavior.
153 if (!cut_audio)
154 usec_sleep(rsd_delay_ms(priv->rd) * 1000);
156 rsd_stop(priv->rd);
157 rsd_free(priv->rd);
160 static void reset(struct ao *ao)
162 struct priv *priv = ao->priv;
163 rsd_stop(priv->rd);
164 rsd_start(priv->rd);
167 static void audio_pause(struct ao *ao)
169 struct priv *priv = ao->priv;
170 rsd_pause(priv->rd, 1);
173 static void audio_resume(struct ao *ao)
175 struct priv *priv = ao->priv;
176 rsd_pause(priv->rd, 0);
179 static int get_space(struct ao *ao)
181 struct priv *priv = ao->priv;
182 return rsd_get_avail(priv->rd);
185 static int play(struct ao *ao, void *data, int len, int flags)
187 struct priv *priv = ao->priv;
188 return rsd_write(priv->rd, data, len);
191 static float get_delay(struct ao *ao)
193 struct priv *priv = ao->priv;
194 return rsd_delay_ms(priv->rd) / 1000.0;
197 const struct ao_driver audio_out_rsound = {
198 .is_new = true,
199 .info = &(const struct ao_info) {
200 .name = "RSound output driver",
201 .short_name = "rsound",
202 .author = "Hans-Kristian Arntzen",
203 .comment = "",
205 .init = init,
206 .uninit = uninit,
207 .reset = reset,
208 .get_space = get_space,
209 .play = play,
210 .get_delay = get_delay,
211 .pause = audio_pause,
212 .resume = audio_resume,