Mercurial > mplayer.hg
annotate libao2/ao_alsa.c @ 36963:e539d330c7be
Remove unnecessary bounds checks in Win32 GUI.
The checks that the rendered potmeter button
doesn't exceed the bounds is not necessary as
the item value is already limited within the
range of 0 to 100.
Patch by Hans-Dieter Kosch, hdkosch kabelbw de.
author | ib |
---|---|
date | Mon, 24 Mar 2014 12:52:01 +0000 |
parents | 36820f219892 |
children | 86893b300a45 |
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 |
35443
f045a1d92c06
Make AF_FORMAT_IS_IEC61937 include AF_FORMAT_IS_AC3.
reimar
parents:
35200
diff
changeset
|
114 if(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; | |
35474
e53785e5205b
Do not use strrchr when strchr works just as well.
reimar
parents:
35443
diff
changeset
|
238 while ((tmp = strchr(dest, '.'))) |
12805
0b154063a3ca
fixes provided by reimar d«Órfinger. mixer, subdevice parsing, alsa#help,
joyping
parents:
12747
diff
changeset
|
239 tmp[0] = ','; |
35474
e53785e5205b
Do not use strrchr when strchr works just as well.
reimar
parents:
35443
diff
changeset
|
240 while ((tmp = strchr(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) { |
36493 | 261 /* to set the non-audio bit, use AES0=6 |
262 * 6 == IEC958_AES0_NONAUDIO | IEC958_AES0_PRO_EMPHASIS_NONE */ | |
22166
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
263 len = strlen(device); |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
264 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
|
265 if (!ac3_device) |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
266 return -ENOMEM; |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
267 strcpy(ac3_device, device); |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
268 args = strchr(ac3_device, ':'); |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
269 if (!args) { |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
270 /* 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
|
271 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
|
272 } else { |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
273 do |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
274 ++args; |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
275 while (isspace(*args)); |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
276 if (*args == '\0') { |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
277 /* ":" but no parameters */ |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
278 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
|
279 } else if (*args != '{') { |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
280 /* 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
|
281 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
|
282 } else { |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
283 /* 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
|
284 do |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
285 --len; |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
286 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
|
287 if (ac3_device[len] == '}') |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
288 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
|
289 } |
d4bb39d65f87
When the hardware sample format is AC3, do not force using an hardcoded
cladisch
parents:
19887
diff
changeset
|
290 } |
22166
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
291 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
|
292 open_mode); |
68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
cladisch
parents:
20764
diff
changeset
|
293 free(ac3_device); |
33347
f60b1fd07712
Simplify code and avoid an incorrect "may be used initialized"
reimar
parents:
31834
diff
changeset
|
294 if (err >= 0) |
f60b1fd07712
Simplify code and avoid an incorrect "may be used initialized"
reimar
parents:
31834
diff
changeset
|
295 return err; |
19889
d4bb39d65f87
When the hardware sample format is AC3, do not force using an hardcoded
cladisch
parents:
19887
diff
changeset
|
296 } |
33347
f60b1fd07712
Simplify code and avoid an incorrect "may be used initialized"
reimar
parents:
31834
diff
changeset
|
297 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
|
298 } |
d4bb39d65f87
When the hardware sample format is AC3, do not force using an hardcoded
cladisch
parents:
19887
diff
changeset
|
299 |
12465 | 300 /* |
301 open & setup audio device | |
302 return: 1=success 0=fail | |
303 */ | |
304 static int init(int rate_hz, int channels, int format, int flags) | |
305 { | |
30398 | 306 unsigned int alsa_buffer_time = 500000; /* 0.5 s */ |
307 unsigned int alsa_fragcount = 16; | |
12465 | 308 int err; |
14328 | 309 int block; |
310 strarg_t device; | |
29507
fc8416cffdcd
Use a buffer of about half a second, instead of sizing it to have
cladisch
parents:
29436
diff
changeset
|
311 snd_pcm_uframes_t chunk_size; |
12465 | 312 snd_pcm_uframes_t bufsize; |
17620
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
313 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
|
314 const opt_t subopts[] = { |
14328 | 315 {"block", OPT_ARG_BOOL, &block, NULL}, |
30122
1772a5171ac7
Fix function declarations to avoid casting function pointers.
reimar
parents:
29826
diff
changeset
|
316 {"device", OPT_ARG_STR, &device, str_maxlen}, |
14328 | 317 {NULL} |
318 }; | |
319 | |
12747 | 320 char alsa_device[ALSA_DEVICE_SIZE + 1]; |
321 // make sure alsa_device is null-terminated even when using strncpy etc. | |
322 memset(alsa_device, 0, ALSA_DEVICE_SIZE + 1); | |
12465 | 323 |
14249 | 324 mp_msg(MSGT_AO,MSGL_V,"alsa-init: requested format: %d Hz, %d channels, %x\n", rate_hz, |
325 channels, format); | |
12465 | 326 alsa_handler = NULL; |
17690
9ca95aee8449
Show the actual ALSA version instead of the version mplayer was compiled
cladisch
parents:
17621
diff
changeset
|
327 #if SND_LIB_VERSION >= 0x010005 |
9ca95aee8449
Show the actual ALSA version instead of the version mplayer was compiled
cladisch
parents:
17621
diff
changeset
|
328 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
|
329 #else |
12465 | 330 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
|
331 #endif |
17691
b73103a82416
Output error messages from the ALSA library through mp_msg() instead of
cladisch
parents:
17690
diff
changeset
|
332 |
b73103a82416
Output error messages from the ALSA library through mp_msg() instead of
cladisch
parents:
17690
diff
changeset
|
333 snd_lib_error_set_handler(alsa_error_handler); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
334 |
12465 | 335 ao_data.samplerate = rate_hz; |
336 ao_data.format = format; | |
337 ao_data.channels = channels; | |
338 | |
339 switch (format) | |
340 { | |
14245 | 341 case AF_FORMAT_S8: |
12465 | 342 alsa_format = SND_PCM_FORMAT_S8; |
343 break; | |
14245 | 344 case AF_FORMAT_U8: |
12465 | 345 alsa_format = SND_PCM_FORMAT_U8; |
346 break; | |
14245 | 347 case AF_FORMAT_U16_LE: |
12465 | 348 alsa_format = SND_PCM_FORMAT_U16_LE; |
349 break; | |
14245 | 350 case AF_FORMAT_U16_BE: |
12465 | 351 alsa_format = SND_PCM_FORMAT_U16_BE; |
352 break; | |
30241
02b9c1a452e1
Add support for distinguishing between little- and big-endian SPDIF AC3
reimar
parents:
30237
diff
changeset
|
353 case AF_FORMAT_AC3_LE: |
14245 | 354 case AF_FORMAT_S16_LE: |
34103 | 355 case AF_FORMAT_IEC61937_LE: |
12465 | 356 alsa_format = SND_PCM_FORMAT_S16_LE; |
357 break; | |
30241
02b9c1a452e1
Add support for distinguishing between little- and big-endian SPDIF AC3
reimar
parents:
30237
diff
changeset
|
358 case AF_FORMAT_AC3_BE: |
14245 | 359 case AF_FORMAT_S16_BE: |
34103 | 360 case AF_FORMAT_IEC61937_BE: |
12465 | 361 alsa_format = SND_PCM_FORMAT_S16_BE; |
362 break; | |
17571
e476a1d38087
This adds support for more sample formats (U32, float BE, mu/A-law).
cladisch
parents:
17570
diff
changeset
|
363 case AF_FORMAT_U32_LE: |
e476a1d38087
This adds support for more sample formats (U32, float BE, mu/A-law).
cladisch
parents:
17570
diff
changeset
|
364 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
|
365 break; |
e476a1d38087
This adds support for more sample formats (U32, float BE, mu/A-law).
cladisch
parents:
17570
diff
changeset
|
366 case AF_FORMAT_U32_BE: |
e476a1d38087
This adds support for more sample formats (U32, float BE, mu/A-law).
cladisch
parents:
17570
diff
changeset
|
367 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
|
368 break; |
14245 | 369 case AF_FORMAT_S32_LE: |
12465 | 370 alsa_format = SND_PCM_FORMAT_S32_LE; |
371 break; | |
14245 | 372 case AF_FORMAT_S32_BE: |
12465 | 373 alsa_format = SND_PCM_FORMAT_S32_BE; |
374 break; | |
29386 | 375 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
|
376 alsa_format = SND_PCM_FORMAT_U24_3LE; |
29386 | 377 break; |
378 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
|
379 alsa_format = SND_PCM_FORMAT_U24_3BE; |
29386 | 380 break; |
381 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
|
382 alsa_format = SND_PCM_FORMAT_S24_3LE; |
29386 | 383 break; |
384 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
|
385 alsa_format = SND_PCM_FORMAT_S24_3BE; |
29386 | 386 break; |
14245 | 387 case AF_FORMAT_FLOAT_LE: |
12570 | 388 alsa_format = SND_PCM_FORMAT_FLOAT_LE; |
389 break; | |
17571
e476a1d38087
This adds support for more sample formats (U32, float BE, mu/A-law).
cladisch
parents:
17570
diff
changeset
|
390 case AF_FORMAT_FLOAT_BE: |
e476a1d38087
This adds support for more sample formats (U32, float BE, mu/A-law).
cladisch
parents:
17570
diff
changeset
|
391 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
|
392 break; |
e476a1d38087
This adds support for more sample formats (U32, float BE, mu/A-law).
cladisch
parents:
17570
diff
changeset
|
393 case AF_FORMAT_MU_LAW: |
e476a1d38087
This adds support for more sample formats (U32, float BE, mu/A-law).
cladisch
parents:
17570
diff
changeset
|
394 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
|
395 break; |
e476a1d38087
This adds support for more sample formats (U32, float BE, mu/A-law).
cladisch
parents:
17570
diff
changeset
|
396 case AF_FORMAT_A_LAW: |
e476a1d38087
This adds support for more sample formats (U32, float BE, mu/A-law).
cladisch
parents:
17570
diff
changeset
|
397 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
|
398 break; |
12465 | 399 |
400 default: | |
14251 | 401 alsa_format = SND_PCM_FORMAT_MPEG; //? default should be -1 |
12465 | 402 break; |
403 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
404 |
12805
0b154063a3ca
fixes provided by reimar d«Órfinger. mixer, subdevice parsing, alsa#help,
joyping
parents:
12747
diff
changeset
|
405 //subdevice parsing |
14328 | 406 // set defaults |
407 block = 1; | |
12465 | 408 /* switch for spdif |
409 * sets opening sequence for SPDIF | |
410 * sets also the playback and other switches 'on the fly' | |
411 * while opening the abstract alias for the spdif subdevice | |
412 * 'iec958' | |
413 */ | |
35443
f045a1d92c06
Make AF_FORMAT_IS_IEC61937 include AF_FORMAT_IS_AC3.
reimar
parents:
35200
diff
changeset
|
414 if (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
|
415 device.str = "iec958"; |
34103 | 416 mp_msg(MSGT_AO,MSGL_V,"alsa-spdif-init: playing AC3/iec61937/iec958, %i channels\n", channels); |
12465 | 417 } |
13661
07dc40f25068
Only use S/PDIF output when no other alsa device is set, allows to use
reimar
parents:
13434
diff
changeset
|
418 else |
14328 | 419 /* in any case for multichannel playback we should select |
420 * appropriate device | |
421 */ | |
422 switch (channels) { | |
423 case 1: | |
424 case 2: | |
425 device.str = "default"; | |
426 mp_msg(MSGT_AO,MSGL_V,"alsa-init: setup for 1/2 channel(s)\n"); | |
427 break; | |
428 case 4: | |
429 if (alsa_format == SND_PCM_FORMAT_FLOAT_LE) | |
430 // hack - use the converter plugin | |
431 device.str = "plug:surround40"; | |
432 else | |
433 device.str = "surround40"; | |
434 mp_msg(MSGT_AO,MSGL_V,"alsa-init: device set to surround40\n"); | |
435 break; | |
436 case 6: | |
437 if (alsa_format == SND_PCM_FORMAT_FLOAT_LE) | |
438 device.str = "plug:surround51"; | |
439 else | |
440 device.str = "surround51"; | |
441 mp_msg(MSGT_AO,MSGL_V,"alsa-init: device set to surround51\n"); | |
442 break; | |
29826 | 443 case 8: |
444 if (alsa_format == SND_PCM_FORMAT_FLOAT_LE) | |
445 device.str = "plug:surround71"; | |
446 else | |
447 device.str = "surround71"; | |
448 mp_msg(MSGT_AO,MSGL_V,"alsa-init: device set to surround71\n"); | |
449 break; | |
14328 | 450 default: |
451 device.str = "default"; | |
20764 | 452 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_ChannelsNotSupported,channels); |
14328 | 453 } |
454 device.len = strlen(device.str); | |
455 if (subopt_parse(ao_subdevice, subopts) != 0) { | |
456 print_help(); | |
457 return 0; | |
458 } | |
459 parse_device(alsa_device, device.str, device.len); | |
12465 | 460 |
20185 | 461 mp_msg(MSGT_AO,MSGL_V,"alsa-init: using device %s\n", alsa_device); |
12465 | 462 |
463 if (!alsa_handler) { | |
30402 | 464 int open_mode = block ? 0 : SND_PCM_NONBLOCK; |
35443
f045a1d92c06
Make AF_FORMAT_IS_IEC61937 include AF_FORMAT_IS_AC3.
reimar
parents:
35200
diff
changeset
|
465 int isac3 = AF_FORMAT_IS_IEC61937(format); |
12465 | 466 //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
|
467 mp_msg(MSGT_AO,MSGL_V,"alsa-init: opening device in %sblocking mode\n", block ? "" : "non-"); |
30234 | 468 if ((err = try_open_device(alsa_device, open_mode, isac3)) < 0) |
12465 | 469 { |
30401 | 470 if (err != -EBUSY && !block) { |
20764 | 471 mp_msg(MSGT_AO,MSGL_INFO,MSGTR_AO_ALSA_OpenInNonblockModeFailed); |
30234 | 472 if ((err = try_open_device(alsa_device, 0, isac3)) < 0) { |
20764 | 473 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
|
474 return 0; |
12465 | 475 } |
476 } else { | |
20764 | 477 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
|
478 return 0; |
12465 | 479 } |
480 } | |
481 | |
17619
9b619133f11a
Using non-blocking writes makes sense when the program wants to do other
cladisch
parents:
17618
diff
changeset
|
482 if ((err = snd_pcm_nonblock(alsa_handler, 0)) < 0) { |
20764 | 483 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_ErrorSetBlockMode, snd_strerror(err)); |
12465 | 484 } else { |
34763
6834d78ac904
Clarify the used opening modes by improving the verbose status messages.
ib
parents:
34754
diff
changeset
|
485 mp_msg(MSGT_AO,MSGL_V,"alsa-init: device reopened in blocking mode\n"); |
12465 | 486 } |
487 | |
488 snd_pcm_hw_params_alloca(&alsa_hwparams); | |
489 snd_pcm_sw_params_alloca(&alsa_swparams); | |
490 | |
491 // setting hw-parameters | |
492 if ((err = snd_pcm_hw_params_any(alsa_handler, alsa_hwparams)) < 0) | |
493 { | |
20764 | 494 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToGetInitialParameters, |
12465 | 495 snd_strerror(err)); |
26757
0fdf04b07ecb
cosmetics: Remove pointless parentheses from return statements.
diego
parents:
24590
diff
changeset
|
496 return 0; |
12465 | 497 } |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
498 |
17616
92431bc3d014
This patch removes mmap support because it doesn't have any benefit.
cladisch
parents:
17575
diff
changeset
|
499 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
|
500 SND_PCM_ACCESS_RW_INTERLEAVED); |
12465 | 501 if (err < 0) { |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
502 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToSetAccessType, |
12465 | 503 snd_strerror(err)); |
26757
0fdf04b07ecb
cosmetics: Remove pointless parentheses from return statements.
diego
parents:
24590
diff
changeset
|
504 return 0; |
12465 | 505 } |
506 | |
507 /* workaround for nonsupported formats | |
508 sets default format to S16_LE if the given formats aren't supported */ | |
509 if ((err = snd_pcm_hw_params_test_format(alsa_handler, alsa_hwparams, | |
510 alsa_format)) < 0) | |
511 { | |
512 mp_msg(MSGT_AO,MSGL_INFO, | |
20764 | 513 MSGTR_AO_ALSA_FormatNotSupportedByHardware, af_fmt2str_short(format)); |
12465 | 514 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
|
515 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
|
516 ao_data.format = AF_FORMAT_AC3_LE; |
34103 | 517 else if (AF_FORMAT_IS_IEC61937(ao_data.format)) |
518 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
|
519 else |
14245 | 520 ao_data.format = AF_FORMAT_S16_LE; |
12465 | 521 } |
522 | |
523 if ((err = snd_pcm_hw_params_set_format(alsa_handler, alsa_hwparams, | |
524 alsa_format)) < 0) | |
525 { | |
20764 | 526 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToSetFormat, |
12465 | 527 snd_strerror(err)); |
26757
0fdf04b07ecb
cosmetics: Remove pointless parentheses from return statements.
diego
parents:
24590
diff
changeset
|
528 return 0; |
12465 | 529 } |
530 | |
16308
41278ab73e9b
set the nearest number of channels, return(0) upon errors
henry
parents:
14849
diff
changeset
|
531 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
|
532 &ao_data.channels)) < 0) |
12465 | 533 { |
20764 | 534 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToSetChannels, |
12465 | 535 snd_strerror(err)); |
26757
0fdf04b07ecb
cosmetics: Remove pointless parentheses from return statements.
diego
parents:
24590
diff
changeset
|
536 return 0; |
12465 | 537 } |
538 | |
17849
ebebe97331af
To avoid a bug in ALSA's rate plugin that causes spurious overruns, try
cladisch
parents:
17848
diff
changeset
|
539 /* 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
|
540 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
|
541 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
|
542 #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
|
543 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
|
544 0)) < 0) |
ebebe97331af
To avoid a bug in ALSA's rate plugin that causes spurious overruns, try
cladisch
parents:
17848
diff
changeset
|
545 { |
20764 | 546 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
|
547 snd_strerror(err)); |
26757
0fdf04b07ecb
cosmetics: Remove pointless parentheses from return statements.
diego
parents:
24590
diff
changeset
|
548 return 0; |
17849
ebebe97331af
To avoid a bug in ALSA's rate plugin that causes spurious overruns, try
cladisch
parents:
17848
diff
changeset
|
549 } |
ebebe97331af
To avoid a bug in ALSA's rate plugin that causes spurious overruns, try
cladisch
parents:
17848
diff
changeset
|
550 #endif |
ebebe97331af
To avoid a bug in ALSA's rate plugin that causes spurious overruns, try
cladisch
parents:
17848
diff
changeset
|
551 |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
552 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
|
553 &ao_data.samplerate, NULL)) < 0) |
12465 | 554 { |
20764 | 555 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToSetSamplerate2, |
12465 | 556 snd_strerror(err)); |
26757
0fdf04b07ecb
cosmetics: Remove pointless parentheses from return statements.
diego
parents:
24590
diff
changeset
|
557 return 0; |
12465 | 558 } |
559 | |
30237
9584cf67cea0
Use af_fmt2bits, it should give more sensible values than snd_pcm_format_physical_width,
reimar
parents:
30234
diff
changeset
|
560 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
|
561 bytes_per_sample *= ao_data.channels; |
401521ec0d61
This replaces the hardcoded numbers for the sample format widths with a
cladisch
parents:
17566
diff
changeset
|
562 ao_data.bps = ao_data.samplerate * bytes_per_sample; |
16309 | 563 |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
564 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
|
565 &alsa_buffer_time, NULL)) < 0) |
12465 | 566 { |
20764 | 567 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToSetBufferTimeNear, |
12465 | 568 snd_strerror(err)); |
26757
0fdf04b07ecb
cosmetics: Remove pointless parentheses from return statements.
diego
parents:
24590
diff
changeset
|
569 return 0; |
29507
fc8416cffdcd
Use a buffer of about half a second, instead of sizing it to have
cladisch
parents:
29436
diff
changeset
|
570 } |
12465 | 571 |
572 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
|
573 &alsa_fragcount, NULL)) < 0) { |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
574 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToSetPeriods, |
12465 | 575 snd_strerror(err)); |
19887
1259d6add8e6
When one of the PCM configuration function in init() fails, abort
cladisch
parents:
18009
diff
changeset
|
576 return 0; |
12465 | 577 } |
578 | |
579 /* finally install hardware parameters */ | |
580 if ((err = snd_pcm_hw_params(alsa_handler, alsa_hwparams)) < 0) | |
581 { | |
20764 | 582 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToSetHwParameters, |
12465 | 583 snd_strerror(err)); |
19887
1259d6add8e6
When one of the PCM configuration function in init() fails, abort
cladisch
parents:
18009
diff
changeset
|
584 return 0; |
12465 | 585 } |
586 // end setting hw-params | |
587 | |
588 | |
589 // gets buffersize for control | |
590 if ((err = snd_pcm_hw_params_get_buffer_size(alsa_hwparams, &bufsize)) < 0) | |
591 { | |
20764 | 592 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
|
593 return 0; |
12465 | 594 } |
595 else { | |
596 ao_data.buffersize = bufsize * bytes_per_sample; | |
597 mp_msg(MSGT_AO,MSGL_V,"alsa-init: got buffersize=%i\n", ao_data.buffersize); | |
598 } | |
599 | |
17620
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
600 if ((err = snd_pcm_hw_params_get_period_size(alsa_hwparams, &chunk_size, NULL)) < 0) { |
20764 | 601 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
|
602 return 0; |
17620
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
603 } else { |
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
604 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
|
605 } |
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
606 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
|
607 |
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
608 /* setting software parameters */ |
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
609 if ((err = snd_pcm_sw_params_current(alsa_handler, alsa_swparams)) < 0) { |
20764 | 610 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
|
611 snd_strerror(err)); |
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
612 return 0; |
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
613 } |
18009
fb7888812f13
Add workarounds for old prerelease versions of alsa-lib 0.9.0 that did
cladisch
parents:
17849
diff
changeset
|
614 #if SND_LIB_VERSION >= 0x000901 |
17620
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
615 if ((err = snd_pcm_sw_params_get_boundary(alsa_swparams, &boundary)) < 0) { |
20764 | 616 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
|
617 snd_strerror(err)); |
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
618 return 0; |
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
619 } |
18009
fb7888812f13
Add workarounds for old prerelease versions of alsa-lib 0.9.0 that did
cladisch
parents:
17849
diff
changeset
|
620 #else |
fb7888812f13
Add workarounds for old prerelease versions of alsa-lib 0.9.0 that did
cladisch
parents:
17849
diff
changeset
|
621 boundary = 0x7fffffff; |
fb7888812f13
Add workarounds for old prerelease versions of alsa-lib 0.9.0 that did
cladisch
parents:
17849
diff
changeset
|
622 #endif |
17620
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
623 /* 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
|
624 if ((err = snd_pcm_sw_params_set_start_threshold(alsa_handler, alsa_swparams, chunk_size)) < 0) { |
20764 | 625 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
|
626 snd_strerror(err)); |
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
627 return 0; |
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
628 } |
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
629 /* disable underrun reporting */ |
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
630 if ((err = snd_pcm_sw_params_set_stop_threshold(alsa_handler, alsa_swparams, boundary)) < 0) { |
20764 | 631 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
|
632 snd_strerror(err)); |
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
633 return 0; |
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
634 } |
18009
fb7888812f13
Add workarounds for old prerelease versions of alsa-lib 0.9.0 that did
cladisch
parents:
17849
diff
changeset
|
635 #if SND_LIB_VERSION >= 0x000901 |
17620
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
636 /* play silence when there is an underrun */ |
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
637 if ((err = snd_pcm_sw_params_set_silence_size(alsa_handler, alsa_swparams, boundary)) < 0) { |
20764 | 638 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
|
639 snd_strerror(err)); |
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
640 return 0; |
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
641 } |
18009
fb7888812f13
Add workarounds for old prerelease versions of alsa-lib 0.9.0 that did
cladisch
parents:
17849
diff
changeset
|
642 #endif |
17620
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
643 if ((err = snd_pcm_sw_params(alsa_handler, alsa_swparams)) < 0) { |
20764 | 644 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
|
645 snd_strerror(err)); |
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
646 return 0; |
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
647 } |
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
648 /* end setting sw-params */ |
dd4db8c43d92
This changes the software parameters to be more compatible with the
cladisch
parents:
17619
diff
changeset
|
649 |
20185 | 650 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
|
651 ao_data.samplerate, ao_data.channels, (int)bytes_per_sample, ao_data.buffersize, |
12465 | 652 snd_pcm_format_description(alsa_format)); |
653 | |
654 } // end switch alsa_handler (spdif) | |
655 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
|
656 return 1; |
12465 | 657 } // end init |
658 | |
659 | |
660 /* close audio device */ | |
661 static void uninit(int immed) | |
662 { | |
663 | |
664 if (alsa_handler) { | |
665 int err; | |
666 | |
14849
d313f591d1a4
aos should respect the immed uninit flag (quit immediatly vs waiting till file
reimar
parents:
14612
diff
changeset
|
667 if (!immed) |
d313f591d1a4
aos should respect the immed uninit flag (quit immediatly vs waiting till file
reimar
parents:
14612
diff
changeset
|
668 snd_pcm_drain(alsa_handler); |
d313f591d1a4
aos should respect the immed uninit flag (quit immediatly vs waiting till file
reimar
parents:
14612
diff
changeset
|
669 |
12465 | 670 if ((err = snd_pcm_close(alsa_handler)) < 0) |
671 { | |
20764 | 672 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_PcmCloseError, snd_strerror(err)); |
12465 | 673 return; |
674 } | |
675 else { | |
676 alsa_handler = NULL; | |
20185 | 677 mp_msg(MSGT_AO,MSGL_V,"alsa-uninit: pcm closed\n"); |
12465 | 678 } |
679 } | |
680 else { | |
20764 | 681 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_NoHandlerDefined); |
12465 | 682 } |
683 } | |
684 | |
17566
f580a7755ac5
Patch by Stefan Huehner / stefan % huehner ! org \
rathann
parents:
17366
diff
changeset
|
685 static void audio_pause(void) |
12465 | 686 { |
687 int err; | |
688 | |
689 if (alsa_can_pause) { | |
690 if ((err = snd_pcm_pause(alsa_handler, 1)) < 0) | |
691 { | |
20764 | 692 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_PcmPauseError, snd_strerror(err)); |
12465 | 693 return; |
694 } | |
695 mp_msg(MSGT_AO,MSGL_V,"alsa-pause: pause supported by hardware\n"); | |
696 } else { | |
34754 | 697 prepause_space = get_space(); |
12465 | 698 if ((err = snd_pcm_drop(alsa_handler)) < 0) |
699 { | |
20764 | 700 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_PcmDropError, snd_strerror(err)); |
12465 | 701 return; |
702 } | |
703 } | |
704 } | |
705 | |
17566
f580a7755ac5
Patch by Stefan Huehner / stefan % huehner ! org \
rathann
parents:
17366
diff
changeset
|
706 static void audio_resume(void) |
12465 | 707 { |
708 int err; | |
709 | |
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
|
710 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
|
711 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
|
712 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
|
713 } |
12465 | 714 if (alsa_can_pause) { |
715 if ((err = snd_pcm_pause(alsa_handler, 0)) < 0) | |
716 { | |
20764 | 717 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_PcmResumeError, snd_strerror(err)); |
12465 | 718 return; |
719 } | |
720 mp_msg(MSGT_AO,MSGL_V,"alsa-resume: resume supported by hardware\n"); | |
721 } else { | |
722 if ((err = snd_pcm_prepare(alsa_handler)) < 0) | |
723 { | |
20764 | 724 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_PcmPrepareError, snd_strerror(err)); |
12465 | 725 return; |
726 } | |
34754 | 727 mp_ao_resume_refill(&audio_out_alsa, prepause_space); |
12465 | 728 } |
729 } | |
730 | |
731 /* stop playing and empty buffers (for seeking/pause) */ | |
17566
f580a7755ac5
Patch by Stefan Huehner / stefan % huehner ! org \
rathann
parents:
17366
diff
changeset
|
732 static void reset(void) |
12465 | 733 { |
734 int err; | |
735 | |
736 if ((err = snd_pcm_drop(alsa_handler)) < 0) | |
737 { | |
20764 | 738 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_PcmPrepareError, snd_strerror(err)); |
12465 | 739 return; |
740 } | |
741 if ((err = snd_pcm_prepare(alsa_handler)) < 0) | |
742 { | |
20764 | 743 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_PcmPrepareError, snd_strerror(err)); |
12465 | 744 return; |
745 } | |
746 return; | |
747 } | |
748 | |
749 /* | |
750 plays 'len' bytes of 'data' | |
751 returns: number of bytes played | |
752 modified last at 29.06.02 by jp | |
753 thanxs for marius <marius@rospot.com> for giving us the light ;) | |
754 */ | |
755 | |
17617
adfab82139c0
After removing play_mmap(), the play() function just unconditionally
cladisch
parents:
17616
diff
changeset
|
756 static int play(void* data, int len, int flags) |
12465 | 757 { |
29706
54f54530a4d3
Make the ao_alsa play function always process a multiple of ao_data.outburst
reimar
parents:
29586
diff
changeset
|
758 int num_frames; |
12465 | 759 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
|
760 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
|
761 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
|
762 num_frames = len / bytes_per_sample; |
12465 | 763 |
764 //mp_msg(MSGT_AO,MSGL_ERR,"alsa-play: frames=%i, len=%i\n",num_frames,len); | |
765 | |
766 if (!alsa_handler) { | |
20764 | 767 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_DeviceConfigurationError); |
12465 | 768 return 0; |
769 } | |
770 | |
17621
d9c518932302
Fix the error handling in the play() function: add a handler for EINTR,
cladisch
parents:
17620
diff
changeset
|
771 if (num_frames == 0) |
d9c518932302
Fix the error handling in the play() function: add a handler for EINTR,
cladisch
parents:
17620
diff
changeset
|
772 return 0; |
d9c518932302
Fix the error handling in the play() function: add a handler for EINTR,
cladisch
parents:
17620
diff
changeset
|
773 |
d9c518932302
Fix the error handling in the play() function: add a handler for EINTR,
cladisch
parents:
17620
diff
changeset
|
774 do { |
d9c518932302
Fix the error handling in the play() function: add a handler for EINTR,
cladisch
parents:
17620
diff
changeset
|
775 res = snd_pcm_writei(alsa_handler, data, num_frames); |
12465 | 776 |
17621
d9c518932302
Fix the error handling in the play() function: add a handler for EINTR,
cladisch
parents:
17620
diff
changeset
|
777 if (res == -EINTR) { |
d9c518932302
Fix the error handling in the play() function: add a handler for EINTR,
cladisch
parents:
17620
diff
changeset
|
778 /* nothing to do */ |
d9c518932302
Fix the error handling in the play() function: add a handler for EINTR,
cladisch
parents:
17620
diff
changeset
|
779 res = 0; |
d9c518932302
Fix the error handling in the play() function: add a handler for EINTR,
cladisch
parents:
17620
diff
changeset
|
780 } |
d9c518932302
Fix the error handling in the play() function: add a handler for EINTR,
cladisch
parents:
17620
diff
changeset
|
781 else if (res == -ESTRPIPE) { /* suspend */ |
20764 | 782 mp_msg(MSGT_AO,MSGL_INFO,MSGTR_AO_ALSA_PcmInSuspendModeTryingResume); |
12465 | 783 while ((res = snd_pcm_resume(alsa_handler)) == -EAGAIN) |
784 sleep(1); | |
785 } | |
17621
d9c518932302
Fix the error handling in the play() function: add a handler for EINTR,
cladisch
parents:
17620
diff
changeset
|
786 if (res < 0) { |
20764 | 787 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_WriteError, snd_strerror(res)); |
788 mp_msg(MSGT_AO,MSGL_INFO,MSGTR_AO_ALSA_TryingToResetSoundcard); | |
12465 | 789 if ((res = snd_pcm_prepare(alsa_handler)) < 0) { |
20764 | 790 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_PcmPrepareError, snd_strerror(res)); |
12465 | 791 break; |
792 } | |
35200 | 793 res = 0; |
12465 | 794 } |
17621
d9c518932302
Fix the error handling in the play() function: add a handler for EINTR,
cladisch
parents:
17620
diff
changeset
|
795 } while (res == 0); |
12465 | 796 |
35200 | 797 return res < 0 ? 0 : res * bytes_per_sample; |
12465 | 798 } |
799 | |
800 /* how many byes are free in the buffer */ | |
17566
f580a7755ac5
Patch by Stefan Huehner / stefan % huehner ! org \
rathann
parents:
17366
diff
changeset
|
801 static int get_space(void) |
12465 | 802 { |
803 snd_pcm_status_t *status; | |
804 int ret; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
805 |
12747 | 806 snd_pcm_status_alloca(&status); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
807 |
12465 | 808 if ((ret = snd_pcm_status(alsa_handler, status)) < 0) |
809 { | |
20764 | 810 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
|
811 return 0; |
12465 | 812 } |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
813 |
17572
580dc69d69bf
Fix get_space(): we don't need to differentiate between the various PCM
cladisch
parents:
17571
diff
changeset
|
814 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
|
815 if (ret > ao_data.buffersize) // Buffer underrun? |
2c238fa777ff
ao_alsa: Fix get_space() return values larger than buffersize
uau
parents:
22166
diff
changeset
|
816 ret = ao_data.buffersize; |
26757
0fdf04b07ecb
cosmetics: Remove pointless parentheses from return statements.
diego
parents:
24590
diff
changeset
|
817 return ret; |
12465 | 818 } |
819 | |
820 /* delay in seconds between first and last sample in buffer */ | |
17566
f580a7755ac5
Patch by Stefan Huehner / stefan % huehner ! org \
rathann
parents:
17366
diff
changeset
|
821 static float get_delay(void) |
12465 | 822 { |
823 if (alsa_handler) { | |
17573
8921544f4114
Simplify get_delay(): we don't need to get the complete PCM status but
cladisch
parents:
17572
diff
changeset
|
824 snd_pcm_sframes_t delay; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
825 |
17573
8921544f4114
Simplify get_delay(): we don't need to get the complete PCM status but
cladisch
parents:
17572
diff
changeset
|
826 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
|
827 return 0; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
828 |
17573
8921544f4114
Simplify get_delay(): we don't need to get the complete PCM status but
cladisch
parents:
17572
diff
changeset
|
829 if (delay < 0) { |
8921544f4114
Simplify get_delay(): we don't need to get the complete PCM status but
cladisch
parents:
17572
diff
changeset
|
830 /* 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
|
831 #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
|
832 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
|
833 #endif |
8921544f4114
Simplify get_delay(): we don't need to get the complete PCM status but
cladisch
parents:
17572
diff
changeset
|
834 delay = 0; |
12465 | 835 } |
17573
8921544f4114
Simplify get_delay(): we don't need to get the complete PCM status but
cladisch
parents:
17572
diff
changeset
|
836 return (float)delay / (float)ao_data.samplerate; |
12465 | 837 } else { |
26757
0fdf04b07ecb
cosmetics: Remove pointless parentheses from return statements.
diego
parents:
24590
diff
changeset
|
838 return 0; |
12465 | 839 } |
840 } |