Mercurial > mplayer.hg
annotate libao2/ao_alsa.c @ 33457:a5ffcb4be6bd
Add X-GNOME-FullName entries to desktop file.
According to the Desktop Entry Specification, the "full name" should be built
from Name and GenericName. While some desktop environments do this (like KDE),
GNOME doesn't and uses its own key instead.
This closes Bugzilla #1680.
author | ib |
---|---|
date | Fri, 03 Jun 2011 14:12:59 +0000 |
parents | f60b1fd07712 |
children | febe300dbfc0 |
rev | line source |
---|---|
12465 | 1 /* |
28343 | 2 * ALSA 0.9.x-1.x audio output driver |
3 * | |
4 * Copyright (C) 2004 Alex Beregszaszi | |
5 * | |
6 * modified for real ALSA 0.9.0 support by Zsolt Barat <joy@streamminister.de> | |
7 * additional AC-3 passthrough support by Andy Lo A Foe <andy@alsaplayer.org> | |
8 * 08/22/2002 iec958-init rewritten and merged with common init, zsolt | |
9 * 04/13/2004 merged with ao_alsa1.x, fixes provided by Jindrich Makovicka | |
10 * 04/25/2004 printfs converted to mp_msg, Zsolt. | |
11 * | |
12 * This file is part of MPlayer. | |
13 * | |
14 * MPlayer is free software; you can redistribute it and/or modify | |
15 * it under the terms of the GNU General Public License as published by | |
16 * the Free Software Foundation; either version 2 of the License, or | |
17 * (at your option) any later version. | |
18 * | |
19 * MPlayer is distributed in the hope that it will be useful, | |
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
22 * GNU General Public License for more details. | |
23 * | |
24 * You should have received a copy of the GNU General Public License along | |
25 * with MPlayer; if not, write to the Free Software Foundation, Inc., | |
26 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
27 */ | |
12465 | 28 |
29 #include <errno.h> | |
30 #include <sys/time.h> | |
31 #include <stdlib.h> | |
17691
b73103a82416
Output error messages from the ALSA library through mp_msg() instead of
cladisch
parents:
17690
diff
changeset
|
32 #include <stdarg.h> |
22166
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
33 #include <ctype.h> |
12465 | 34 #include <math.h> |
35 #include <string.h> | |
27281
e47193172586
Our ALSA code needs alloca, so check for it in configure and include alloca.h
reimar
parents:
26757
diff
changeset
|
36 #include <alloca.h> |
12465 | 37 |
14123 | 38 #include "config.h" |
14328 | 39 #include "subopt-helper.h" |
14123 | 40 #include "mixer.h" |
41 #include "mp_msg.h" | |
20764 | 42 #include "help_mp.h" |
12465 | 43 |
44 #define ALSA_PCM_NEW_HW_PARAMS_API | |
45 #define ALSA_PCM_NEW_SW_PARAMS_API | |
46 | |
28362
f0a0d87b7c56
1) HAVE_SYS_ASOUNDLIB_H/HAVE_ALSA_ASOUNDLIB_H are defined/undefined,
diego
parents:
28343
diff
changeset
|
47 #ifdef HAVE_SYS_ASOUNDLIB_H |
12465 | 48 #include <sys/asoundlib.h> |
28362
f0a0d87b7c56
1) HAVE_SYS_ASOUNDLIB_H/HAVE_ALSA_ASOUNDLIB_H are defined/undefined,
diego
parents:
28343
diff
changeset
|
49 #elif defined(HAVE_ALSA_ASOUNDLIB_H) |
12465 | 50 #include <alsa/asoundlib.h> |
51 #else | |
52 #error "asoundlib.h is not in sys/ or alsa/ - please bugreport" | |
53 #endif | |
54 | |
55 | |
56 #include "audio_out.h" | |
57 #include "audio_out_internal.h" | |
14245 | 58 #include "libaf/af_format.h" |
12465 | 59 |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
60 static const ao_info_t info = |
12465 | 61 { |
62 "ALSA-0.9.x-1.x audio output", | |
63 "alsa", | |
64 "Alex Beregszaszi, Zsolt Barat <joy@streamminister.de>", | |
31834
64ba1daa147a
various spelling fixes, found by the Debian QA tool 'lintian'
siretart
parents:
30410
diff
changeset
|
65 "under development" |
12465 | 66 }; |
67 | |
68 LIBAO_EXTERN(alsa) | |
69 | |
70 static snd_pcm_t *alsa_handler; | |
71 static snd_pcm_format_t alsa_format; | |
72 static snd_pcm_hw_params_t *alsa_hwparams; | |
73 static snd_pcm_sw_params_t *alsa_swparams; | |
74 | |
17619
9b619133f11a
Using non-blocking writes makes sense when the program wants to do other
cladisch
parents:
17618
diff
changeset
|
75 static size_t bytes_per_sample; |
12465 | 76 |
30399 | 77 static int alsa_can_pause; |
12465 | 78 |
12747 | 79 #define ALSA_DEVICE_SIZE 256 |
12465 | 80 |
17691
b73103a82416
Output error messages from the ALSA library through mp_msg() instead of
cladisch
parents:
17690
diff
changeset
|
81 static void alsa_error_handler(const char *file, int line, const char *function, |
b73103a82416
Output error messages from the ALSA library through mp_msg() instead of
cladisch
parents:
17690
diff
changeset
|
82 int err, const char *format, ...) |
b73103a82416
Output error messages from the ALSA library through mp_msg() instead of
cladisch
parents:
17690
diff
changeset
|
83 { |
b73103a82416
Output error messages from the ALSA library through mp_msg() instead of
cladisch
parents:
17690
diff
changeset
|
84 char tmp[0xc00]; |
b73103a82416
Output error messages from the ALSA library through mp_msg() instead of
cladisch
parents:
17690
diff
changeset
|
85 va_list va; |
b73103a82416
Output error messages from the ALSA library through mp_msg() instead of
cladisch
parents:
17690
diff
changeset
|
86 |
b73103a82416
Output error messages from the ALSA library through mp_msg() instead of
cladisch
parents:
17690
diff
changeset
|
87 va_start(va, format); |
b73103a82416
Output error messages from the ALSA library through mp_msg() instead of
cladisch
parents:
17690
diff
changeset
|
88 vsnprintf(tmp, sizeof tmp, format, va); |
b73103a82416
Output error messages from the ALSA library through mp_msg() instead of
cladisch
parents:
17690
diff
changeset
|
89 va_end(va); |
b73103a82416
Output error messages from the ALSA library through mp_msg() instead of
cladisch
parents:
17690
diff
changeset
|
90 tmp[sizeof tmp - 1] = '\0'; |
b73103a82416
Output error messages from the ALSA library through mp_msg() instead of
cladisch
parents:
17690
diff
changeset
|
91 |
b73103a82416
Output error messages from the ALSA library through mp_msg() instead of
cladisch
parents:
17690
diff
changeset
|
92 if (err) |
20764 | 93 mp_msg(MSGT_AO, MSGL_ERR, "[AO_ALSA] alsa-lib: %s:%i:(%s) %s: %s\n", |
17691
b73103a82416
Output error messages from the ALSA library through mp_msg() instead of
cladisch
parents:
17690
diff
changeset
|
94 file, line, function, tmp, snd_strerror(err)); |
b73103a82416
Output error messages from the ALSA library through mp_msg() instead of
cladisch
parents:
17690
diff
changeset
|
95 else |
20764 | 96 mp_msg(MSGT_AO, MSGL_ERR, "[AO_ALSA] alsa-lib: %s:%i:(%s) %s\n", |
17691
b73103a82416
Output error messages from the ALSA library through mp_msg() instead of
cladisch
parents:
17690
diff
changeset
|
97 file, line, function, tmp); |
b73103a82416
Output error messages from the ALSA library through mp_msg() instead of
cladisch
parents:
17690
diff
changeset
|
98 } |
b73103a82416
Output error messages from the ALSA library through mp_msg() instead of
cladisch
parents:
17690
diff
changeset
|
99 |
12465 | 100 /* to set/get/query special features/parameters */ |
101 static int control(int cmd, void *arg) | |
102 { | |
103 switch(cmd) { | |
104 case AOCONTROL_QUERY_FORMAT: | |
105 return CONTROL_TRUE; | |
106 case AOCONTROL_GET_VOLUME: | |
107 case AOCONTROL_SET_VOLUME: | |
108 { | |
109 ao_control_vol_t *vol = (ao_control_vol_t *)arg; | |
110 | |
111 int err; | |
112 snd_mixer_t *handle; | |
113 snd_mixer_elem_t *elem; | |
114 snd_mixer_selem_id_t *sid; | |
115 | |
30400 | 116 char *mix_name = "PCM"; |
117 char *card = "default"; | |
118 int mix_index = 0; | |
12465 | 119 |
120 long pmin, pmax; | |
121 long get_vol, set_vol; | |
12805
0b154063a3ca
fixes provided by reimar d«Órfinger. mixer, subdevice parsing, alsa#help,
joyping
parents:
12747
diff
changeset
|
122 float f_multi; |
12465 | 123 |
30234 | 124 if(AF_FORMAT_IS_AC3(ao_data.format)) |
28118
4455edd2be89
100l, reorder check for AC3 format to avoid a possible memleak
reimar
parents:
27706
diff
changeset
|
125 return CONTROL_TRUE; |
4455edd2be89
100l, reorder check for AC3 format to avoid a possible memleak
reimar
parents:
27706
diff
changeset
|
126 |
13434 | 127 if(mixer_channel) { |
128 char *test_mix_index; | |
129 | |
130 mix_name = strdup(mixer_channel); | |
17097 | 131 if ((test_mix_index = strchr(mix_name, ','))){ |
13434 | 132 *test_mix_index = 0; |
133 test_mix_index++; | |
134 mix_index = strtol(test_mix_index, &test_mix_index, 0); | |
135 | |
136 if (*test_mix_index){ | |
137 mp_msg(MSGT_AO,MSGL_ERR, | |
20764 | 138 MSGTR_AO_ALSA_InvalidMixerIndexDefaultingToZero); |
13434 | 139 mix_index = 0 ; |
140 } | |
141 } | |
142 } | |
12747 | 143 if(mixer_device) card = mixer_device; |
12465 | 144 |
145 //allocate simple id | |
146 snd_mixer_selem_id_alloca(&sid); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
147 |
12465 | 148 //sets simple-mixer index and name |
13434 | 149 snd_mixer_selem_id_set_index(sid, mix_index); |
12465 | 150 snd_mixer_selem_id_set_name(sid, mix_name); |
151 | |
13434 | 152 if (mixer_channel) { |
153 free(mix_name); | |
154 mix_name = NULL; | |
155 } | |
156 | |
12465 | 157 if ((err = snd_mixer_open(&handle, 0)) < 0) { |
20764 | 158 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_MixerOpenError, snd_strerror(err)); |
12465 | 159 return CONTROL_ERROR; |
160 } | |
161 | |
162 if ((err = snd_mixer_attach(handle, card)) < 0) { | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
163 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_MixerAttachError, |
12465 | 164 card, snd_strerror(err)); |
165 snd_mixer_close(handle); | |
166 return CONTROL_ERROR; | |
167 } | |
168 | |
169 if ((err = snd_mixer_selem_register(handle, NULL, NULL)) < 0) { | |
20764 | 170 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_MixerRegisterError, snd_strerror(err)); |
12465 | 171 snd_mixer_close(handle); |
172 return CONTROL_ERROR; | |
173 } | |
174 err = snd_mixer_load(handle); | |
175 if (err < 0) { | |
20764 | 176 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_MixerLoadError, snd_strerror(err)); |
12465 | 177 snd_mixer_close(handle); |
178 return CONTROL_ERROR; | |
179 } | |
180 | |
181 elem = snd_mixer_find_selem(handle, sid); | |
182 if (!elem) { | |
20764 | 183 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToFindSimpleControl, |
12465 | 184 snd_mixer_selem_id_get_name(sid), snd_mixer_selem_id_get_index(sid)); |
185 snd_mixer_close(handle); | |
186 return CONTROL_ERROR; | |
187 } | |
188 | |
189 snd_mixer_selem_get_playback_volume_range(elem,&pmin,&pmax); | |
12811
d5f8efddac6c
volume calc fixes for mixer, by reimar d«Óffinger, 10l reverse by me
joyping
parents:
12805
diff
changeset
|
190 f_multi = (100 / (float)(pmax - pmin)); |
12465 | 191 |
192 if (cmd == AOCONTROL_SET_VOLUME) { | |
193 | |
12811
d5f8efddac6c
volume calc fixes for mixer, by reimar d«Óffinger, 10l reverse by me
joyping
parents:
12805
diff
changeset
|
194 set_vol = vol->left / f_multi + pmin + 0.5; |
12465 | 195 |
196 //setting channels | |
27706 | 197 if ((err = snd_mixer_selem_set_playback_volume(elem, SND_MIXER_SCHN_FRONT_LEFT, set_vol)) < 0) { |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
198 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_ErrorSettingLeftChannel, |
12465 | 199 snd_strerror(err)); |
29436
4537ed655f0b
Do not leak the mixer handle if setting of a volume fails.
cladisch
parents:
29401
diff
changeset
|
200 snd_mixer_close(handle); |
12465 | 201 return CONTROL_ERROR; |
202 } | |
12805
0b154063a3ca
fixes provided by reimar d«Órfinger. mixer, subdevice parsing, alsa#help,
joyping
parents:
12747
diff
changeset
|
203 mp_msg(MSGT_AO,MSGL_DBG2,"left=%li, ", set_vol); |
0b154063a3ca
fixes provided by reimar d«Órfinger. mixer, subdevice parsing, alsa#help,
joyping
parents:
12747
diff
changeset
|
204 |
12811
d5f8efddac6c
volume calc fixes for mixer, by reimar d«Óffinger, 10l reverse by me
joyping
parents:
12805
diff
changeset
|
205 set_vol = vol->right / f_multi + pmin + 0.5; |
12805
0b154063a3ca
fixes provided by reimar d«Órfinger. mixer, subdevice parsing, alsa#help,
joyping
parents:
12747
diff
changeset
|
206 |
27706 | 207 if ((err = snd_mixer_selem_set_playback_volume(elem, SND_MIXER_SCHN_FRONT_RIGHT, set_vol)) < 0) { |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
208 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_ErrorSettingRightChannel, |
12465 | 209 snd_strerror(err)); |
29436
4537ed655f0b
Do not leak the mixer handle if setting of a volume fails.
cladisch
parents:
29401
diff
changeset
|
210 snd_mixer_close(handle); |
12465 | 211 return CONTROL_ERROR; |
212 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
213 mp_msg(MSGT_AO,MSGL_DBG2,"right=%li, pmin=%li, pmax=%li, mult=%f\n", |
12805
0b154063a3ca
fixes provided by reimar d«Órfinger. mixer, subdevice parsing, alsa#help,
joyping
parents:
12747
diff
changeset
|
214 set_vol, pmin, pmax, f_multi); |
17194
cd527e59d128
use snd_mixer_selem_set_playback_switch when muting ALSA, patch by Matthias Lederhofer <matled -at- gmx dot net>
wanderer
parents:
17097
diff
changeset
|
215 |
cd527e59d128
use snd_mixer_selem_set_playback_switch when muting ALSA, patch by Matthias Lederhofer <matled -at- gmx dot net>
wanderer
parents:
17097
diff
changeset
|
216 if (snd_mixer_selem_has_playback_switch(elem)) { |
cd527e59d128
use snd_mixer_selem_set_playback_switch when muting ALSA, patch by Matthias Lederhofer <matled -at- gmx dot net>
wanderer
parents:
17097
diff
changeset
|
217 int lmute = (vol->left == 0.0); |
cd527e59d128
use snd_mixer_selem_set_playback_switch when muting ALSA, patch by Matthias Lederhofer <matled -at- gmx dot net>
wanderer
parents:
17097
diff
changeset
|
218 int rmute = (vol->right == 0.0); |
cd527e59d128
use snd_mixer_selem_set_playback_switch when muting ALSA, patch by Matthias Lederhofer <matled -at- gmx dot net>
wanderer
parents:
17097
diff
changeset
|
219 if (snd_mixer_selem_has_playback_switch_joined(elem)) { |
cd527e59d128
use snd_mixer_selem_set_playback_switch when muting ALSA, patch by Matthias Lederhofer <matled -at- gmx dot net>
wanderer
parents:
17097
diff
changeset
|
220 lmute = rmute = lmute && rmute; |
cd527e59d128
use snd_mixer_selem_set_playback_switch when muting ALSA, patch by Matthias Lederhofer <matled -at- gmx dot net>
wanderer
parents:
17097
diff
changeset
|
221 } else { |
cd527e59d128
use snd_mixer_selem_set_playback_switch when muting ALSA, patch by Matthias Lederhofer <matled -at- gmx dot net>
wanderer
parents:
17097
diff
changeset
|
222 snd_mixer_selem_set_playback_switch(elem, SND_MIXER_SCHN_FRONT_RIGHT, !rmute); |
cd527e59d128
use snd_mixer_selem_set_playback_switch when muting ALSA, patch by Matthias Lederhofer <matled -at- gmx dot net>
wanderer
parents:
17097
diff
changeset
|
223 } |
cd527e59d128
use snd_mixer_selem_set_playback_switch when muting ALSA, patch by Matthias Lederhofer <matled -at- gmx dot net>
wanderer
parents:
17097
diff
changeset
|
224 snd_mixer_selem_set_playback_switch(elem, SND_MIXER_SCHN_FRONT_LEFT, !lmute); |
cd527e59d128
use snd_mixer_selem_set_playback_switch when muting ALSA, patch by Matthias Lederhofer <matled -at- gmx dot net>
wanderer
parents:
17097
diff
changeset
|
225 } |
12465 | 226 } |
227 else { | |
27706 | 228 snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_FRONT_LEFT, &get_vol); |
12811
d5f8efddac6c
volume calc fixes for mixer, by reimar d«Óffinger, 10l reverse by me
joyping
parents:
12805
diff
changeset
|
229 vol->left = (get_vol - pmin) * f_multi; |
27706 | 230 snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_FRONT_RIGHT, &get_vol); |
12811
d5f8efddac6c
volume calc fixes for mixer, by reimar d«Óffinger, 10l reverse by me
joyping
parents:
12805
diff
changeset
|
231 vol->right = (get_vol - pmin) * f_multi; |
12465 | 232 |
12805
0b154063a3ca
fixes provided by reimar d«Órfinger. mixer, subdevice parsing, alsa#help,
joyping
parents:
12747
diff
changeset
|
233 mp_msg(MSGT_AO,MSGL_DBG2,"left=%f, right=%f\n",vol->left,vol->right); |
12465 | 234 } |
235 snd_mixer_close(handle); | |
236 return CONTROL_OK; | |
237 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
238 |
12465 | 239 } //end switch |
26757
0fdf04b07ecb
cosmetics: Remove pointless parentheses from return statements.
diego
parents:
24590
diff
changeset
|
240 return CONTROL_UNKNOWN; |
12465 | 241 } |
242 | |
14328 | 243 static void parse_device (char *dest, const char *src, int len) |
12805
0b154063a3ca
fixes provided by reimar d«Órfinger. mixer, subdevice parsing, alsa#help,
joyping
parents:
12747
diff
changeset
|
244 { |
0b154063a3ca
fixes provided by reimar d«Órfinger. mixer, subdevice parsing, alsa#help,
joyping
parents:
12747
diff
changeset
|
245 char *tmp; |
14328 | 246 memmove(dest, src, len); |
247 dest[len] = 0; | |
12805
0b154063a3ca
fixes provided by reimar d«Órfinger. mixer, subdevice parsing, alsa#help,
joyping
parents:
12747
diff
changeset
|
248 while ((tmp = strrchr(dest, '.'))) |
0b154063a3ca
fixes provided by reimar d«Órfinger. mixer, subdevice parsing, alsa#help,
joyping
parents:
12747
diff
changeset
|
249 tmp[0] = ','; |
12919
aba44b58dea7
Use = instead if # in ALSA device name, as # irritates our config-parser.
reimar
parents:
12819
diff
changeset
|
250 while ((tmp = strrchr(dest, '='))) |
12805
0b154063a3ca
fixes provided by reimar d«Órfinger. mixer, subdevice parsing, alsa#help,
joyping
parents:
12747
diff
changeset
|
251 tmp[0] = ':'; |
0b154063a3ca
fixes provided by reimar d«Órfinger. mixer, subdevice parsing, alsa#help,
joyping
parents:
12747
diff
changeset
|
252 } |
0b154063a3ca
fixes provided by reimar d«Órfinger. mixer, subdevice parsing, alsa#help,
joyping
parents:
12747
diff
changeset
|
253 |
17566
f580a7755ac5
Patch by Stefan Huehner / stefan % huehner ! org \
rathann
parents:
17366
diff
changeset
|
254 static void print_help (void) |
12805
0b154063a3ca
fixes provided by reimar d«Órfinger. mixer, subdevice parsing, alsa#help,
joyping
parents:
12747
diff
changeset
|
255 { |
0b154063a3ca
fixes provided by reimar d«Órfinger. mixer, subdevice parsing, alsa#help,
joyping
parents:
12747
diff
changeset
|
256 mp_msg (MSGT_AO, MSGL_FATAL, |
20764 | 257 MSGTR_AO_ALSA_CommandlineHelp); |
12805
0b154063a3ca
fixes provided by reimar d«Órfinger. mixer, subdevice parsing, alsa#help,
joyping
parents:
12747
diff
changeset
|
258 } |
12465 | 259 |
30122
1772a5171ac7
Fix function declarations to avoid casting function pointers.
reimar
parents:
29826
diff
changeset
|
260 static int str_maxlen(void *strp) { |
1772a5171ac7
Fix function declarations to avoid casting function pointers.
reimar
parents:
29826
diff
changeset
|
261 strarg_t *str = strp; |
30123
0f5f75b4a015
Simplify range-checking functions for subopt parsing.
reimar
parents:
30122
diff
changeset
|
262 return str->len <= ALSA_DEVICE_SIZE; |
14328 | 263 } |
264 | |
22166
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
265 static int try_open_device(const char *device, int open_mode, int try_ac3) |
19889
d4bb39d65f87
When the hardware sample format is AC3, do not force using an hardcoded
cladisch
parents:
19887
diff
changeset
|
266 { |
22166
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
267 int err, len; |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
268 char *ac3_device, *args; |
19889
d4bb39d65f87
When the hardware sample format is AC3, do not force using an hardcoded
cladisch
parents:
19887
diff
changeset
|
269 |
22166
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
270 if (try_ac3) { |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
271 /* to set the non-audio bit, use AES0=6 */ |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
272 len = strlen(device); |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
273 ac3_device = malloc(len + 7 + 1); |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
274 if (!ac3_device) |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
275 return -ENOMEM; |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
276 strcpy(ac3_device, device); |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
277 args = strchr(ac3_device, ':'); |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
278 if (!args) { |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
279 /* no existing parameters: add it behind device name */ |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
280 strcat(ac3_device, ":AES0=6"); |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
281 } else { |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
282 do |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
283 ++args; |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
284 while (isspace(*args)); |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
285 if (*args == '\0') { |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
286 /* ":" but no parameters */ |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
287 strcat(ac3_device, "AES0=6"); |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
288 } else if (*args != '{') { |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
289 /* a simple list of parameters: add it at the end of the list */ |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
290 strcat(ac3_device, ",AES0=6"); |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
291 } else { |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
292 /* parameters in config syntax: add it inside the { } block */ |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
293 do |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
294 --len; |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
295 while (len > 0 && isspace(ac3_device[len])); |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
296 if (ac3_device[len] == '}') |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
297 strcpy(ac3_device + len, " AES0=6}"); |
19889
d4bb39d65f87
When the hardware sample format is AC3, do not force using an hardcoded
cladisch
parents:
19887
diff
changeset
|
298 } |
d4bb39d65f87
When the hardware sample format is AC3, do not force using an hardcoded
cladisch
parents:
19887
diff
changeset
|
299 } |
22166
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
300 err = snd_pcm_open(&alsa_handler, ac3_device, SND_PCM_STREAM_PLAYBACK, |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
301 open_mode); |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
302 free(ac3_device); |
33347
f60b1fd07712
Simplify code and avoid an incorrect "may be used initialized"
reimar
parents:
31834
diff
changeset
|
303 if (err >= 0) |
f60b1fd07712
Simplify code and avoid an incorrect "may be used initialized"
reimar
parents:
31834
diff
changeset
|
304 return err; |
19889
d4bb39d65f87
When the hardware sample format is AC3, do not force using an hardcoded
cladisch
parents:
19887
diff
changeset
|
305 } |
33347
f60b1fd07712
Simplify code and avoid an incorrect "may be used initialized"
reimar
parents:
31834
diff
changeset
|
306 return snd_pcm_open(&alsa_handler, device, SND_PCM_STREAM_PLAYBACK, open_mode); |
19889
d4bb39d65f87
When the hardware sample format is AC3, do not force using an hardcoded
cladisch
parents:
19887
diff
changeset
|
307 } |
d4bb39d65f87
When the hardware sample format is AC3, do not force using an hardcoded
cladisch
parents:
19887
diff
changeset
|
308 |
12465 | 309 /* |
310 open & setup audio device | |
311 return: 1=success 0=fail | |
312 */ | |
313 static int init(int rate_hz, int channels, int format, int flags) | |
314 { | |
30398 | 315 unsigned int alsa_buffer_time = 500000; /* 0.5 s */ |
316 unsigned int alsa_fragcount = 16; | |
12465 | 317 int err; |
14328 | 318 int block; |
319 strarg_t device; | |
29507
fc8416cffdcd
Use a buffer of about half a second, instead of sizing it to have
cladisch
parents:
29436
diff
changeset
|
320 snd_pcm_uframes_t chunk_size; |
12465 | 321 snd_pcm_uframes_t bufsize; |
17620
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
322 snd_pcm_uframes_t boundary; |
29586
2eff450157cd
The suboption parser now takes a const options list, so mark them all const.
reimar
parents:
29507
diff
changeset
|
323 const opt_t subopts[] = { |
14328 | 324 {"block", OPT_ARG_BOOL, &block, NULL}, |
30122
1772a5171ac7
Fix function declarations to avoid casting function pointers.
reimar
parents:
29826
diff
changeset
|
325 {"device", OPT_ARG_STR, &device, str_maxlen}, |
14328 | 326 {NULL} |
327 }; | |
328 | |
12747 | 329 char alsa_device[ALSA_DEVICE_SIZE + 1]; |
330 // make sure alsa_device is null-terminated even when using strncpy etc. | |
331 memset(alsa_device, 0, ALSA_DEVICE_SIZE + 1); | |
12465 | 332 |
14249 | 333 mp_msg(MSGT_AO,MSGL_V,"alsa-init: requested format: %d Hz, %d channels, %x\n", rate_hz, |
334 channels, format); | |
12465 | 335 alsa_handler = NULL; |
17690
9ca95aee8449
Show the actual ALSA version instead of the version mplayer was compiled
cladisch
parents:
17621
diff
changeset
|
336 #if SND_LIB_VERSION >= 0x010005 |
9ca95aee8449
Show the actual ALSA version instead of the version mplayer was compiled
cladisch
parents:
17621
diff
changeset
|
337 mp_msg(MSGT_AO,MSGL_V,"alsa-init: using ALSA %s\n", snd_asoundlib_version()); |
9ca95aee8449
Show the actual ALSA version instead of the version mplayer was compiled
cladisch
parents:
17621
diff
changeset
|
338 #else |
12465 | 339 mp_msg(MSGT_AO,MSGL_V,"alsa-init: compiled for ALSA-%s\n", SND_LIB_VERSION_STR); |
17690
9ca95aee8449
Show the actual ALSA version instead of the version mplayer was compiled
cladisch
parents:
17621
diff
changeset
|
340 #endif |
17691
b73103a82416
Output error messages from the ALSA library through mp_msg() instead of
cladisch
parents:
17690
diff
changeset
|
341 |
b73103a82416
Output error messages from the ALSA library through mp_msg() instead of
cladisch
parents:
17690
diff
changeset
|
342 snd_lib_error_set_handler(alsa_error_handler); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
343 |
12465 | 344 ao_data.samplerate = rate_hz; |
345 ao_data.format = format; | |
346 ao_data.channels = channels; | |
347 | |
348 switch (format) | |
349 { | |
14245 | 350 case AF_FORMAT_S8: |
12465 | 351 alsa_format = SND_PCM_FORMAT_S8; |
352 break; | |
14245 | 353 case AF_FORMAT_U8: |
12465 | 354 alsa_format = SND_PCM_FORMAT_U8; |
355 break; | |
14245 | 356 case AF_FORMAT_U16_LE: |
12465 | 357 alsa_format = SND_PCM_FORMAT_U16_LE; |
358 break; | |
14245 | 359 case AF_FORMAT_U16_BE: |
12465 | 360 alsa_format = SND_PCM_FORMAT_U16_BE; |
361 break; | |
30241
02b9c1a452e1
Add support for distinguishing between little- and big-endian SPDIF AC3
reimar
parents:
30237
diff
changeset
|
362 case AF_FORMAT_AC3_LE: |
14245 | 363 case AF_FORMAT_S16_LE: |
12465 | 364 alsa_format = SND_PCM_FORMAT_S16_LE; |
365 break; | |
30241
02b9c1a452e1
Add support for distinguishing between little- and big-endian SPDIF AC3
reimar
parents:
30237
diff
changeset
|
366 case AF_FORMAT_AC3_BE: |
14245 | 367 case AF_FORMAT_S16_BE: |
12465 | 368 alsa_format = SND_PCM_FORMAT_S16_BE; |
369 break; | |
17571
e476a1d38087
This adds support for more sample formats (U32, float BE, mu/A-law).
cladisch
parents:
17570
diff
changeset
|
370 case AF_FORMAT_U32_LE: |
e476a1d38087
This adds support for more sample formats (U32, float BE, mu/A-law).
cladisch
parents:
17570
diff
changeset
|
371 alsa_format = SND_PCM_FORMAT_U32_LE; |
e476a1d38087
This adds support for more sample formats (U32, float BE, mu/A-law).
cladisch
parents:
17570
diff
changeset
|
372 break; |
e476a1d38087
This adds support for more sample formats (U32, float BE, mu/A-law).
cladisch
parents:
17570
diff
changeset
|
373 case AF_FORMAT_U32_BE: |
e476a1d38087
This adds support for more sample formats (U32, float BE, mu/A-law).
cladisch
parents:
17570
diff
changeset
|
374 alsa_format = SND_PCM_FORMAT_U32_BE; |
e476a1d38087
This adds support for more sample formats (U32, float BE, mu/A-law).
cladisch
parents:
17570
diff
changeset
|
375 break; |
14245 | 376 case AF_FORMAT_S32_LE: |
12465 | 377 alsa_format = SND_PCM_FORMAT_S32_LE; |
378 break; | |
14245 | 379 case AF_FORMAT_S32_BE: |
12465 | 380 alsa_format = SND_PCM_FORMAT_S32_BE; |
381 break; | |
29386 | 382 case AF_FORMAT_U24_LE: |
29392
cd3ec59296a0
Use correct ALSA sample format for 24-bit samples packed in three bytes.
cladisch
parents:
29386
diff
changeset
|
383 alsa_format = SND_PCM_FORMAT_U24_3LE; |
29386 | 384 break; |
385 case AF_FORMAT_U24_BE: | |
29392
cd3ec59296a0
Use correct ALSA sample format for 24-bit samples packed in three bytes.
cladisch
parents:
29386
diff
changeset
|
386 alsa_format = SND_PCM_FORMAT_U24_3BE; |
29386 | 387 break; |
388 case AF_FORMAT_S24_LE: | |
29392
cd3ec59296a0
Use correct ALSA sample format for 24-bit samples packed in three bytes.
cladisch
parents:
29386
diff
changeset
|
389 alsa_format = SND_PCM_FORMAT_S24_3LE; |
29386 | 390 break; |
391 case AF_FORMAT_S24_BE: | |
29392
cd3ec59296a0
Use correct ALSA sample format for 24-bit samples packed in three bytes.
cladisch
parents:
29386
diff
changeset
|
392 alsa_format = SND_PCM_FORMAT_S24_3BE; |
29386 | 393 break; |
14245 | 394 case AF_FORMAT_FLOAT_LE: |
12570 | 395 alsa_format = SND_PCM_FORMAT_FLOAT_LE; |
396 break; | |
17571
e476a1d38087
This adds support for more sample formats (U32, float BE, mu/A-law).
cladisch
parents:
17570
diff
changeset
|
397 case AF_FORMAT_FLOAT_BE: |
e476a1d38087
This adds support for more sample formats (U32, float BE, mu/A-law).
cladisch
parents:
17570
diff
changeset
|
398 alsa_format = SND_PCM_FORMAT_FLOAT_BE; |
e476a1d38087
This adds support for more sample formats (U32, float BE, mu/A-law).
cladisch
parents:
17570
diff
changeset
|
399 break; |
e476a1d38087
This adds support for more sample formats (U32, float BE, mu/A-law).
cladisch
parents:
17570
diff
changeset
|
400 case AF_FORMAT_MU_LAW: |
e476a1d38087
This adds support for more sample formats (U32, float BE, mu/A-law).
cladisch
parents:
17570
diff
changeset
|
401 alsa_format = SND_PCM_FORMAT_MU_LAW; |
e476a1d38087
This adds support for more sample formats (U32, float BE, mu/A-law).
cladisch
parents:
17570
diff
changeset
|
402 break; |
e476a1d38087
This adds support for more sample formats (U32, float BE, mu/A-law).
cladisch
parents:
17570
diff
changeset
|
403 case AF_FORMAT_A_LAW: |
e476a1d38087
This adds support for more sample formats (U32, float BE, mu/A-law).
cladisch
parents:
17570
diff
changeset
|
404 alsa_format = SND_PCM_FORMAT_A_LAW; |
e476a1d38087
This adds support for more sample formats (U32, float BE, mu/A-law).
cladisch
parents:
17570
diff
changeset
|
405 break; |
12465 | 406 |
407 default: | |
14251 | 408 alsa_format = SND_PCM_FORMAT_MPEG; //? default should be -1 |
12465 | 409 break; |
410 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
411 |
12805
0b154063a3ca
fixes provided by reimar d«Órfinger. mixer, subdevice parsing, alsa#help,
joyping
parents:
12747
diff
changeset
|
412 //subdevice parsing |
14328 | 413 // set defaults |
414 block = 1; | |
12465 | 415 /* switch for spdif |
416 * sets opening sequence for SPDIF | |
417 * sets also the playback and other switches 'on the fly' | |
418 * while opening the abstract alias for the spdif subdevice | |
419 * 'iec958' | |
420 */ | |
30234 | 421 if (AF_FORMAT_IS_AC3(format)) { |
19889
d4bb39d65f87
When the hardware sample format is AC3, do not force using an hardcoded
cladisch
parents:
19887
diff
changeset
|
422 device.str = "iec958"; |
12747 | 423 mp_msg(MSGT_AO,MSGL_V,"alsa-spdif-init: playing AC3, %i channels\n", channels); |
12465 | 424 } |
13661
07dc40f25068
Only use S/PDIF output when no other alsa device is set, allows to use
reimar
parents:
13434
diff
changeset
|
425 else |
14328 | 426 /* in any case for multichannel playback we should select |
427 * appropriate device | |
428 */ | |
429 switch (channels) { | |
430 case 1: | |
431 case 2: | |
432 device.str = "default"; | |
433 mp_msg(MSGT_AO,MSGL_V,"alsa-init: setup for 1/2 channel(s)\n"); | |
434 break; | |
435 case 4: | |
436 if (alsa_format == SND_PCM_FORMAT_FLOAT_LE) | |
437 // hack - use the converter plugin | |
438 device.str = "plug:surround40"; | |
439 else | |
440 device.str = "surround40"; | |
441 mp_msg(MSGT_AO,MSGL_V,"alsa-init: device set to surround40\n"); | |
442 break; | |
443 case 6: | |
444 if (alsa_format == SND_PCM_FORMAT_FLOAT_LE) | |
445 device.str = "plug:surround51"; | |
446 else | |
447 device.str = "surround51"; | |
448 mp_msg(MSGT_AO,MSGL_V,"alsa-init: device set to surround51\n"); | |
449 break; | |
29826 | 450 case 8: |
451 if (alsa_format == SND_PCM_FORMAT_FLOAT_LE) | |
452 device.str = "plug:surround71"; | |
453 else | |
454 device.str = "surround71"; | |
455 mp_msg(MSGT_AO,MSGL_V,"alsa-init: device set to surround71\n"); | |
456 break; | |
14328 | 457 default: |
458 device.str = "default"; | |
20764 | 459 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_ChannelsNotSupported,channels); |
14328 | 460 } |
461 device.len = strlen(device.str); | |
462 if (subopt_parse(ao_subdevice, subopts) != 0) { | |
463 print_help(); | |
464 return 0; | |
465 } | |
466 parse_device(alsa_device, device.str, device.len); | |
12465 | 467 |
20185 | 468 mp_msg(MSGT_AO,MSGL_V,"alsa-init: using device %s\n", alsa_device); |
12465 | 469 |
470 if (!alsa_handler) { | |
30402 | 471 int open_mode = block ? 0 : SND_PCM_NONBLOCK; |
30234 | 472 int isac3 = AF_FORMAT_IS_AC3(format); |
12465 | 473 //modes = 0, SND_PCM_NONBLOCK, SND_PCM_ASYNC |
30234 | 474 if ((err = try_open_device(alsa_device, open_mode, isac3)) < 0) |
12465 | 475 { |
30401 | 476 if (err != -EBUSY && !block) { |
20764 | 477 mp_msg(MSGT_AO,MSGL_INFO,MSGTR_AO_ALSA_OpenInNonblockModeFailed); |
30234 | 478 if ((err = try_open_device(alsa_device, 0, isac3)) < 0) { |
20764 | 479 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_PlaybackOpenError, snd_strerror(err)); |
26757
0fdf04b07ecb
cosmetics: Remove pointless parentheses from return statements.
diego
parents:
24590
diff
changeset
|
480 return 0; |
12465 | 481 } |
482 } else { | |
20764 | 483 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_PlaybackOpenError, snd_strerror(err)); |
26757
0fdf04b07ecb
cosmetics: Remove pointless parentheses from return statements.
diego
parents:
24590
diff
changeset
|
484 return 0; |
12465 | 485 } |
486 } | |
487 | |
17619
9b619133f11a
Using non-blocking writes makes sense when the program wants to do other
cladisch
parents:
17618
diff
changeset
|
488 if ((err = snd_pcm_nonblock(alsa_handler, 0)) < 0) { |
20764 | 489 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_ErrorSetBlockMode, snd_strerror(err)); |
12465 | 490 } else { |
20743 | 491 mp_msg(MSGT_AO,MSGL_V,"alsa-init: pcm opened in blocking mode\n"); |
12465 | 492 } |
493 | |
494 snd_pcm_hw_params_alloca(&alsa_hwparams); | |
495 snd_pcm_sw_params_alloca(&alsa_swparams); | |
496 | |
497 // setting hw-parameters | |
498 if ((err = snd_pcm_hw_params_any(alsa_handler, alsa_hwparams)) < 0) | |
499 { | |
20764 | 500 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToGetInitialParameters, |
12465 | 501 snd_strerror(err)); |
26757
0fdf04b07ecb
cosmetics: Remove pointless parentheses from return statements.
diego
parents:
24590
diff
changeset
|
502 return 0; |
12465 | 503 } |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
504 |
17616
92431bc3d014
This patch removes mmap support because it doesn't have any benefit.
cladisch
parents:
17575
diff
changeset
|
505 err = snd_pcm_hw_params_set_access(alsa_handler, alsa_hwparams, |
92431bc3d014
This patch removes mmap support because it doesn't have any benefit.
cladisch
parents:
17575
diff
changeset
|
506 SND_PCM_ACCESS_RW_INTERLEAVED); |
12465 | 507 if (err < 0) { |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
508 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToSetAccessType, |
12465 | 509 snd_strerror(err)); |
26757
0fdf04b07ecb
cosmetics: Remove pointless parentheses from return statements.
diego
parents:
24590
diff
changeset
|
510 return 0; |
12465 | 511 } |
512 | |
513 /* workaround for nonsupported formats | |
514 sets default format to S16_LE if the given formats aren't supported */ | |
515 if ((err = snd_pcm_hw_params_test_format(alsa_handler, alsa_hwparams, | |
516 alsa_format)) < 0) | |
517 { | |
518 mp_msg(MSGT_AO,MSGL_INFO, | |
20764 | 519 MSGTR_AO_ALSA_FormatNotSupportedByHardware, af_fmt2str_short(format)); |
12465 | 520 alsa_format = SND_PCM_FORMAT_S16_LE; |
30241
02b9c1a452e1
Add support for distinguishing between little- and big-endian SPDIF AC3
reimar
parents:
30237
diff
changeset
|
521 if (AF_FORMAT_IS_AC3(ao_data.format)) |
02b9c1a452e1
Add support for distinguishing between little- and big-endian SPDIF AC3
reimar
parents:
30237
diff
changeset
|
522 ao_data.format = AF_FORMAT_AC3_LE; |
02b9c1a452e1
Add support for distinguishing between little- and big-endian SPDIF AC3
reimar
parents:
30237
diff
changeset
|
523 else |
14245 | 524 ao_data.format = AF_FORMAT_S16_LE; |
12465 | 525 } |
526 | |
527 if ((err = snd_pcm_hw_params_set_format(alsa_handler, alsa_hwparams, | |
528 alsa_format)) < 0) | |
529 { | |
20764 | 530 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToSetFormat, |
12465 | 531 snd_strerror(err)); |
26757
0fdf04b07ecb
cosmetics: Remove pointless parentheses from return statements.
diego
parents:
24590
diff
changeset
|
532 return 0; |
12465 | 533 } |
534 | |
16308
41278ab73e9b
set the nearest number of channels, return(0) upon errors
henry
parents:
14849
diff
changeset
|
535 if ((err = snd_pcm_hw_params_set_channels_near(alsa_handler, alsa_hwparams, |
41278ab73e9b
set the nearest number of channels, return(0) upon errors
henry
parents:
14849
diff
changeset
|
536 &ao_data.channels)) < 0) |
12465 | 537 { |
20764 | 538 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToSetChannels, |
12465 | 539 snd_strerror(err)); |
26757
0fdf04b07ecb
cosmetics: Remove pointless parentheses from return statements.
diego
parents:
24590
diff
changeset
|
540 return 0; |
12465 | 541 } |
542 | |
17849
ebebe97331af
To avoid a bug in ALSA's rate plugin that causes spurious overruns, try
cladisch
parents:
17848
diff
changeset
|
543 /* workaround for buggy rate plugin (should be fixed in ALSA 1.0.11) |
30410
67b70534caeb
Explain why we still disable the ALSA resampler even though it is probably
reimar
parents:
30402
diff
changeset
|
544 prefer our own resampler, since that allows users to choose the resampler, |
67b70534caeb
Explain why we still disable the ALSA resampler even though it is probably
reimar
parents:
30402
diff
changeset
|
545 even per file if desired */ |
17849
ebebe97331af
To avoid a bug in ALSA's rate plugin that causes spurious overruns, try
cladisch
parents:
17848
diff
changeset
|
546 #if SND_LIB_VERSION >= 0x010009 |
ebebe97331af
To avoid a bug in ALSA's rate plugin that causes spurious overruns, try
cladisch
parents:
17848
diff
changeset
|
547 if ((err = snd_pcm_hw_params_set_rate_resample(alsa_handler, alsa_hwparams, |
ebebe97331af
To avoid a bug in ALSA's rate plugin that causes spurious overruns, try
cladisch
parents:
17848
diff
changeset
|
548 0)) < 0) |
ebebe97331af
To avoid a bug in ALSA's rate plugin that causes spurious overruns, try
cladisch
parents:
17848
diff
changeset
|
549 { |
20764 | 550 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToDisableResampling, |
17849
ebebe97331af
To avoid a bug in ALSA's rate plugin that causes spurious overruns, try
cladisch
parents:
17848
diff
changeset
|
551 snd_strerror(err)); |
26757
0fdf04b07ecb
cosmetics: Remove pointless parentheses from return statements.
diego
parents:
24590
diff
changeset
|
552 return 0; |
17849
ebebe97331af
To avoid a bug in ALSA's rate plugin that causes spurious overruns, try
cladisch
parents:
17848
diff
changeset
|
553 } |
ebebe97331af
To avoid a bug in ALSA's rate plugin that causes spurious overruns, try
cladisch
parents:
17848
diff
changeset
|
554 #endif |
ebebe97331af
To avoid a bug in ALSA's rate plugin that causes spurious overruns, try
cladisch
parents:
17848
diff
changeset
|
555 |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
556 if ((err = snd_pcm_hw_params_set_rate_near(alsa_handler, alsa_hwparams, |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
557 &ao_data.samplerate, NULL)) < 0) |
12465 | 558 { |
20764 | 559 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToSetSamplerate2, |
12465 | 560 snd_strerror(err)); |
26757
0fdf04b07ecb
cosmetics: Remove pointless parentheses from return statements.
diego
parents:
24590
diff
changeset
|
561 return 0; |
12465 | 562 } |
563 | |
30237
9584cf67cea0
Use af_fmt2bits, it should give more sensible values than snd_pcm_format_physical_width,
reimar
parents:
30234
diff
changeset
|
564 bytes_per_sample = af_fmt2bits(ao_data.format) / 8; |
17570
401521ec0d61
This replaces the hardcoded numbers for the sample format widths with a
cladisch
parents:
17566
diff
changeset
|
565 bytes_per_sample *= ao_data.channels; |
401521ec0d61
This replaces the hardcoded numbers for the sample format widths with a
cladisch
parents:
17566
diff
changeset
|
566 ao_data.bps = ao_data.samplerate * bytes_per_sample; |
16309 | 567 |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
568 if ((err = snd_pcm_hw_params_set_buffer_time_near(alsa_handler, alsa_hwparams, |
17575
9972b744fd98
Small fixes: make all global variables static, remove some unused
cladisch
parents:
17574
diff
changeset
|
569 &alsa_buffer_time, NULL)) < 0) |
12465 | 570 { |
20764 | 571 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToSetBufferTimeNear, |
12465 | 572 snd_strerror(err)); |
26757
0fdf04b07ecb
cosmetics: Remove pointless parentheses from return statements.
diego
parents:
24590
diff
changeset
|
573 return 0; |
29507
fc8416cffdcd
Use a buffer of about half a second, instead of sizing it to have
cladisch
parents:
29436
diff
changeset
|
574 } |
12465 | 575 |
576 if ((err = snd_pcm_hw_params_set_periods_near(alsa_handler, alsa_hwparams, | |
17575
9972b744fd98
Small fixes: make all global variables static, remove some unused
cladisch
parents:
17574
diff
changeset
|
577 &alsa_fragcount, NULL)) < 0) { |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
578 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToSetPeriods, |
12465 | 579 snd_strerror(err)); |
19887
1259d6add8e6
When one of the PCM configuration function in init() fails, abort
cladisch
parents:
18009
diff
changeset
|
580 return 0; |
12465 | 581 } |
582 | |
583 /* finally install hardware parameters */ | |
584 if ((err = snd_pcm_hw_params(alsa_handler, alsa_hwparams)) < 0) | |
585 { | |
20764 | 586 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToSetHwParameters, |
12465 | 587 snd_strerror(err)); |
19887
1259d6add8e6
When one of the PCM configuration function in init() fails, abort
cladisch
parents:
18009
diff
changeset
|
588 return 0; |
12465 | 589 } |
590 // end setting hw-params | |
591 | |
592 | |
593 // gets buffersize for control | |
594 if ((err = snd_pcm_hw_params_get_buffer_size(alsa_hwparams, &bufsize)) < 0) | |
595 { | |
20764 | 596 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToGetBufferSize, snd_strerror(err)); |
19887
1259d6add8e6
When one of the PCM configuration function in init() fails, abort
cladisch
parents:
18009
diff
changeset
|
597 return 0; |
12465 | 598 } |
599 else { | |
600 ao_data.buffersize = bufsize * bytes_per_sample; | |
601 mp_msg(MSGT_AO,MSGL_V,"alsa-init: got buffersize=%i\n", ao_data.buffersize); | |
602 } | |
603 | |
17620
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
604 if ((err = snd_pcm_hw_params_get_period_size(alsa_hwparams, &chunk_size, NULL)) < 0) { |
20764 | 605 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToGetPeriodSize, snd_strerror(err)); |
19887
1259d6add8e6
When one of the PCM configuration function in init() fails, abort
cladisch
parents:
18009
diff
changeset
|
606 return 0; |
17620
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
607 } else { |
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
608 mp_msg(MSGT_AO,MSGL_V,"alsa-init: got period size %li\n", chunk_size); |
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
609 } |
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
610 ao_data.outburst = chunk_size * bytes_per_sample; |
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
611 |
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
612 /* setting software parameters */ |
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
613 if ((err = snd_pcm_sw_params_current(alsa_handler, alsa_swparams)) < 0) { |
20764 | 614 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToGetSwParameters, |
17620
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
615 snd_strerror(err)); |
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
616 return 0; |
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
617 } |
18009
fb7888812f13
Add workarounds for old prerelease versions of alsa-lib 0.9.0 that did
cladisch
parents:
17849
diff
changeset
|
618 #if SND_LIB_VERSION >= 0x000901 |
17620
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
619 if ((err = snd_pcm_sw_params_get_boundary(alsa_swparams, &boundary)) < 0) { |
20764 | 620 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToGetBoundary, |
17620
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
621 snd_strerror(err)); |
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
622 return 0; |
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
623 } |
18009
fb7888812f13
Add workarounds for old prerelease versions of alsa-lib 0.9.0 that did
cladisch
parents:
17849
diff
changeset
|
624 #else |
fb7888812f13
Add workarounds for old prerelease versions of alsa-lib 0.9.0 that did
cladisch
parents:
17849
diff
changeset
|
625 boundary = 0x7fffffff; |
fb7888812f13
Add workarounds for old prerelease versions of alsa-lib 0.9.0 that did
cladisch
parents:
17849
diff
changeset
|
626 #endif |
17620
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
627 /* start playing when one period has been written */ |
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
628 if ((err = snd_pcm_sw_params_set_start_threshold(alsa_handler, alsa_swparams, chunk_size)) < 0) { |
20764 | 629 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToSetStartThreshold, |
17620
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
630 snd_strerror(err)); |
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
631 return 0; |
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
632 } |
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
633 /* disable underrun reporting */ |
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
634 if ((err = snd_pcm_sw_params_set_stop_threshold(alsa_handler, alsa_swparams, boundary)) < 0) { |
20764 | 635 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToSetStopThreshold, |
17620
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
636 snd_strerror(err)); |
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
637 return 0; |
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
638 } |
18009
fb7888812f13
Add workarounds for old prerelease versions of alsa-lib 0.9.0 that did
cladisch
parents:
17849
diff
changeset
|
639 #if SND_LIB_VERSION >= 0x000901 |
17620
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
640 /* play silence when there is an underrun */ |
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
641 if ((err = snd_pcm_sw_params_set_silence_size(alsa_handler, alsa_swparams, boundary)) < 0) { |
20764 | 642 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToSetSilenceSize, |
17620
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
643 snd_strerror(err)); |
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
644 return 0; |
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
645 } |
18009
fb7888812f13
Add workarounds for old prerelease versions of alsa-lib 0.9.0 that did
cladisch
parents:
17849
diff
changeset
|
646 #endif |
17620
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
647 if ((err = snd_pcm_sw_params(alsa_handler, alsa_swparams)) < 0) { |
20764 | 648 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToGetSwParameters, |
17620
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
649 snd_strerror(err)); |
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
650 return 0; |
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
651 } |
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
652 /* end setting sw-params */ |
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
653 |
20185 | 654 mp_msg(MSGT_AO,MSGL_V,"alsa: %d Hz/%d channels/%d bpf/%d bytes buffer/%s\n", |
27682
25245b3e962f
Fix "format '%d' expects type 'int', but argument 6 has type 'size_t'" warning.
ranma
parents:
27680
diff
changeset
|
655 ao_data.samplerate, ao_data.channels, (int)bytes_per_sample, ao_data.buffersize, |
12465 | 656 snd_pcm_format_description(alsa_format)); |
657 | |
658 } // end switch alsa_handler (spdif) | |
659 alsa_can_pause = snd_pcm_hw_params_can_pause(alsa_hwparams); | |
26757
0fdf04b07ecb
cosmetics: Remove pointless parentheses from return statements.
diego
parents:
24590
diff
changeset
|
660 return 1; |
12465 | 661 } // end init |
662 | |
663 | |
664 /* close audio device */ | |
665 static void uninit(int immed) | |
666 { | |
667 | |
668 if (alsa_handler) { | |
669 int err; | |
670 | |
14849
d313f591d1a4
aos should respect the immed uninit flag (quit immediatly vs waiting till file
reimar
parents:
14612
diff
changeset
|
671 if (!immed) |
d313f591d1a4
aos should respect the immed uninit flag (quit immediatly vs waiting till file
reimar
parents:
14612
diff
changeset
|
672 snd_pcm_drain(alsa_handler); |
d313f591d1a4
aos should respect the immed uninit flag (quit immediatly vs waiting till file
reimar
parents:
14612
diff
changeset
|
673 |
12465 | 674 if ((err = snd_pcm_close(alsa_handler)) < 0) |
675 { | |
20764 | 676 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_PcmCloseError, snd_strerror(err)); |
12465 | 677 return; |
678 } | |
679 else { | |
680 alsa_handler = NULL; | |
20185 | 681 mp_msg(MSGT_AO,MSGL_V,"alsa-uninit: pcm closed\n"); |
12465 | 682 } |
683 } | |
684 else { | |
20764 | 685 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_NoHandlerDefined); |
12465 | 686 } |
687 } | |
688 | |
17566
f580a7755ac5
Patch by Stefan Huehner / stefan % huehner ! org \
rathann
parents:
17366
diff
changeset
|
689 static void audio_pause(void) |
12465 | 690 { |
691 int err; | |
692 | |
693 if (alsa_can_pause) { | |
694 if ((err = snd_pcm_pause(alsa_handler, 1)) < 0) | |
695 { | |
20764 | 696 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_PcmPauseError, snd_strerror(err)); |
12465 | 697 return; |
698 } | |
699 mp_msg(MSGT_AO,MSGL_V,"alsa-pause: pause supported by hardware\n"); | |
700 } else { | |
701 if ((err = snd_pcm_drop(alsa_handler)) < 0) | |
702 { | |
20764 | 703 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_PcmDropError, snd_strerror(err)); |
12465 | 704 return; |
705 } | |
706 } | |
707 } | |
708 | |
17566
f580a7755ac5
Patch by Stefan Huehner / stefan % huehner ! org \
rathann
parents:
17366
diff
changeset
|
709 static void audio_resume(void) |
12465 | 710 { |
711 int err; | |
712 | |
27680
a529f3763afa
Make alsa resume after suspend to disk (would say 'file descriptor is in bad state' before this change)
ranma
parents:
27281
diff
changeset
|
713 if (snd_pcm_state(alsa_handler) == SND_PCM_STATE_SUSPENDED) { |
a529f3763afa
Make alsa resume after suspend to disk (would say 'file descriptor is in bad state' before this change)
ranma
parents:
27281
diff
changeset
|
714 mp_msg(MSGT_AO,MSGL_INFO,MSGTR_AO_ALSA_PcmInSuspendModeTryingResume); |
a529f3763afa
Make alsa resume after suspend to disk (would say 'file descriptor is in bad state' before this change)
ranma
parents:
27281
diff
changeset
|
715 while ((err = snd_pcm_resume(alsa_handler)) == -EAGAIN) sleep(1); |
a529f3763afa
Make alsa resume after suspend to disk (would say 'file descriptor is in bad state' before this change)
ranma
parents:
27281
diff
changeset
|
716 } |
12465 | 717 if (alsa_can_pause) { |
718 if ((err = snd_pcm_pause(alsa_handler, 0)) < 0) | |
719 { | |
20764 | 720 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_PcmResumeError, snd_strerror(err)); |
12465 | 721 return; |
722 } | |
723 mp_msg(MSGT_AO,MSGL_V,"alsa-resume: resume supported by hardware\n"); | |
724 } else { | |
725 if ((err = snd_pcm_prepare(alsa_handler)) < 0) | |
726 { | |
20764 | 727 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_PcmPrepareError, snd_strerror(err)); |
12465 | 728 return; |
729 } | |
730 } | |
731 } | |
732 | |
733 /* stop playing and empty buffers (for seeking/pause) */ | |
17566
f580a7755ac5
Patch by Stefan Huehner / stefan % huehner ! org \
rathann
parents:
17366
diff
changeset
|
734 static void reset(void) |
12465 | 735 { |
736 int err; | |
737 | |
738 if ((err = snd_pcm_drop(alsa_handler)) < 0) | |
739 { | |
20764 | 740 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_PcmPrepareError, snd_strerror(err)); |
12465 | 741 return; |
742 } | |
743 if ((err = snd_pcm_prepare(alsa_handler)) < 0) | |
744 { | |
20764 | 745 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_PcmPrepareError, snd_strerror(err)); |
12465 | 746 return; |
747 } | |
748 return; | |
749 } | |
750 | |
751 /* | |
752 plays 'len' bytes of 'data' | |
753 returns: number of bytes played | |
754 modified last at 29.06.02 by jp | |
755 thanxs for marius <marius@rospot.com> for giving us the light ;) | |
756 */ | |
757 | |
17617
adfab82139c0
After removing play_mmap(), the play() function just unconditionally
cladisch
parents:
17616
diff
changeset
|
758 static int play(void* data, int len, int flags) |
12465 | 759 { |
29706
54f54530a4d3
Make the ao_alsa play function always process a multiple of ao_data.outburst
reimar
parents:
29586
diff
changeset
|
760 int num_frames; |
12465 | 761 snd_pcm_sframes_t res = 0; |
29706
54f54530a4d3
Make the ao_alsa play function always process a multiple of ao_data.outburst
reimar
parents:
29586
diff
changeset
|
762 if (!(flags & AOPLAY_FINAL_CHUNK)) |
54f54530a4d3
Make the ao_alsa play function always process a multiple of ao_data.outburst
reimar
parents:
29586
diff
changeset
|
763 len = len / ao_data.outburst * ao_data.outburst; |
54f54530a4d3
Make the ao_alsa play function always process a multiple of ao_data.outburst
reimar
parents:
29586
diff
changeset
|
764 num_frames = len / bytes_per_sample; |
12465 | 765 |
766 //mp_msg(MSGT_AO,MSGL_ERR,"alsa-play: frames=%i, len=%i\n",num_frames,len); | |
767 | |
768 if (!alsa_handler) { | |
20764 | 769 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_DeviceConfigurationError); |
12465 | 770 return 0; |
771 } | |
772 | |
17621
d9c518932302
Fix the error handling in the play() function: add a handler for EINTR,
cladisch
parents:
17620
diff
changeset
|
773 if (num_frames == 0) |
d9c518932302
Fix the error handling in the play() function: add a handler for EINTR,
cladisch
parents:
17620
diff
changeset
|
774 return 0; |
d9c518932302
Fix the error handling in the play() function: add a handler for EINTR,
cladisch
parents:
17620
diff
changeset
|
775 |
d9c518932302
Fix the error handling in the play() function: add a handler for EINTR,
cladisch
parents:
17620
diff
changeset
|
776 do { |
d9c518932302
Fix the error handling in the play() function: add a handler for EINTR,
cladisch
parents:
17620
diff
changeset
|
777 res = snd_pcm_writei(alsa_handler, data, num_frames); |
12465 | 778 |
17621
d9c518932302
Fix the error handling in the play() function: add a handler for EINTR,
cladisch
parents:
17620
diff
changeset
|
779 if (res == -EINTR) { |
d9c518932302
Fix the error handling in the play() function: add a handler for EINTR,
cladisch
parents:
17620
diff
changeset
|
780 /* nothing to do */ |
d9c518932302
Fix the error handling in the play() function: add a handler for EINTR,
cladisch
parents:
17620
diff
changeset
|
781 res = 0; |
d9c518932302
Fix the error handling in the play() function: add a handler for EINTR,
cladisch
parents:
17620
diff
changeset
|
782 } |
d9c518932302
Fix the error handling in the play() function: add a handler for EINTR,
cladisch
parents:
17620
diff
changeset
|
783 else if (res == -ESTRPIPE) { /* suspend */ |
20764 | 784 mp_msg(MSGT_AO,MSGL_INFO,MSGTR_AO_ALSA_PcmInSuspendModeTryingResume); |
12465 | 785 while ((res = snd_pcm_resume(alsa_handler)) == -EAGAIN) |
786 sleep(1); | |
787 } | |
17621
d9c518932302
Fix the error handling in the play() function: add a handler for EINTR,
cladisch
parents:
17620
diff
changeset
|
788 if (res < 0) { |
20764 | 789 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_WriteError, snd_strerror(res)); |
790 mp_msg(MSGT_AO,MSGL_INFO,MSGTR_AO_ALSA_TryingToResetSoundcard); | |
12465 | 791 if ((res = snd_pcm_prepare(alsa_handler)) < 0) { |
20764 | 792 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_PcmPrepareError, snd_strerror(res)); |
26757
0fdf04b07ecb
cosmetics: Remove pointless parentheses from return statements.
diego
parents:
24590
diff
changeset
|
793 return 0; |
12465 | 794 break; |
795 } | |
796 } | |
17621
d9c518932302
Fix the error handling in the play() function: add a handler for EINTR,
cladisch
parents:
17620
diff
changeset
|
797 } while (res == 0); |
12465 | 798 |
17621
d9c518932302
Fix the error handling in the play() function: add a handler for EINTR,
cladisch
parents:
17620
diff
changeset
|
799 return res < 0 ? res : res * bytes_per_sample; |
12465 | 800 } |
801 | |
802 /* how many byes are free in the buffer */ | |
17566
f580a7755ac5
Patch by Stefan Huehner / stefan % huehner ! org \
rathann
parents:
17366
diff
changeset
|
803 static int get_space(void) |
12465 | 804 { |
805 snd_pcm_status_t *status; | |
806 int ret; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
807 |
12747 | 808 snd_pcm_status_alloca(&status); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
809 |
12465 | 810 if ((ret = snd_pcm_status(alsa_handler, status)) < 0) |
811 { | |
20764 | 812 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_CannotGetPcmStatus, snd_strerror(ret)); |
26757
0fdf04b07ecb
cosmetics: Remove pointless parentheses from return statements.
diego
parents:
24590
diff
changeset
|
813 return 0; |
12465 | 814 } |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
815 |
17572
580dc69d69bf
Fix get_space(): we don't need to differentiate between the various PCM
cladisch
parents:
17571
diff
changeset
|
816 ret = snd_pcm_status_get_avail(status) * bytes_per_sample; |
24590
2c238fa777ff
ao_alsa: Fix get_space() return values larger than buffersize
uau
parents:
22166
diff
changeset
|
817 if (ret > ao_data.buffersize) // Buffer underrun? |
2c238fa777ff
ao_alsa: Fix get_space() return values larger than buffersize
uau
parents:
22166
diff
changeset
|
818 ret = ao_data.buffersize; |
26757
0fdf04b07ecb
cosmetics: Remove pointless parentheses from return statements.
diego
parents:
24590
diff
changeset
|
819 return ret; |
12465 | 820 } |
821 | |
822 /* delay in seconds between first and last sample in buffer */ | |
17566
f580a7755ac5
Patch by Stefan Huehner / stefan % huehner ! org \
rathann
parents:
17366
diff
changeset
|
823 static float get_delay(void) |
12465 | 824 { |
825 if (alsa_handler) { | |
17573
8921544f4114
Simplify get_delay(): we don't need to get the complete PCM status but
cladisch
parents:
17572
diff
changeset
|
826 snd_pcm_sframes_t delay; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
827 |
17573
8921544f4114
Simplify get_delay(): we don't need to get the complete PCM status but
cladisch
parents:
17572
diff
changeset
|
828 if (snd_pcm_delay(alsa_handler, &delay) < 0) |
8921544f4114
Simplify get_delay(): we don't need to get the complete PCM status but
cladisch
parents:
17572
diff
changeset
|
829 return 0; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
830 |
17573
8921544f4114
Simplify get_delay(): we don't need to get the complete PCM status but
cladisch
parents:
17572
diff
changeset
|
831 if (delay < 0) { |
8921544f4114
Simplify get_delay(): we don't need to get the complete PCM status but
cladisch
parents:
17572
diff
changeset
|
832 /* underrun - move the application pointer forward to catch up */ |
8921544f4114
Simplify get_delay(): we don't need to get the complete PCM status but
cladisch
parents:
17572
diff
changeset
|
833 #if SND_LIB_VERSION >= 0x000901 /* snd_pcm_forward() exists since 0.9.0rc8 */ |
8921544f4114
Simplify get_delay(): we don't need to get the complete PCM status but
cladisch
parents:
17572
diff
changeset
|
834 snd_pcm_forward(alsa_handler, -delay); |
8921544f4114
Simplify get_delay(): we don't need to get the complete PCM status but
cladisch
parents:
17572
diff
changeset
|
835 #endif |
8921544f4114
Simplify get_delay(): we don't need to get the complete PCM status but
cladisch
parents:
17572
diff
changeset
|
836 delay = 0; |
12465 | 837 } |
17573
8921544f4114
Simplify get_delay(): we don't need to get the complete PCM status but
cladisch
parents:
17572
diff
changeset
|
838 return (float)delay / (float)ao_data.samplerate; |
12465 | 839 } else { |
26757
0fdf04b07ecb
cosmetics: Remove pointless parentheses from return statements.
diego
parents:
24590
diff
changeset
|
840 return 0; |
12465 | 841 } |
842 } |