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