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