Mercurial > mplayer.hg
annotate libao2/ao_oss.c @ 31074:84a83cc32f99
10l: correctly use video_stream instead of audio_stream in the video section
( copy&paste error :( )
author | aurel |
---|---|
date | Mon, 03 May 2010 22:40:00 +0000 |
parents | 02b9c1a452e1 |
children | 9d4720deada1 |
rev | line source |
---|---|
28343 | 1 /* |
2 * OSS audio output driver | |
3 * | |
4 * This file is part of MPlayer. | |
5 * | |
6 * MPlayer is free software; you can redistribute it and/or modify | |
7 * it under the terms of the GNU General Public License as published by | |
8 * the Free Software Foundation; either version 2 of the License, or | |
9 * (at your option) any later version. | |
10 * | |
11 * MPlayer is distributed in the hope that it will be useful, | |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 * GNU General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU General Public License along | |
17 * with MPlayer; if not, write to the Free Software Foundation, Inc., | |
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
19 */ | |
20 | |
954 | 21 #include <stdio.h> |
22 #include <stdlib.h> | |
23 | |
24 #include <sys/ioctl.h> | |
25 #include <unistd.h> | |
26 #include <sys/time.h> | |
27 #include <sys/types.h> | |
28 #include <sys/stat.h> | |
29 #include <fcntl.h> | |
5204
6bbf3271a694
non-blocking open - patch by Fredrik Kuivinen <freku045@student.liu.se>
arpi
parents:
4803
diff
changeset
|
30 #include <errno.h> |
6bbf3271a694
non-blocking open - patch by Fredrik Kuivinen <freku045@student.liu.se>
arpi
parents:
4803
diff
changeset
|
31 #include <string.h> |
954 | 32 |
14123 | 33 #include "config.h" |
34 #include "mp_msg.h" | |
35 #include "mixer.h" | |
36 #include "help_mp.h" | |
954 | 37 |
14245 | 38 #ifdef HAVE_SYS_SOUNDCARD_H |
39 #include <sys/soundcard.h> | |
40 #else | |
41 #ifdef HAVE_SOUNDCARD_H | |
42 #include <soundcard.h> | |
43 #endif | |
44 #endif | |
45 | |
17020 | 46 #include "libaf/af_format.h" |
1532 | 47 |
954 | 48 #include "audio_out.h" |
49 #include "audio_out_internal.h" | |
50 | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
51 static const ao_info_t info = |
954 | 52 { |
53 "OSS/ioctl audio output", | |
956
a6cecd9a1bad
'-ao' switch (including '-ao help'), fixing Arpi's bug (short name 'null' for both of oss and null driver ;)
lgb
parents:
954
diff
changeset
|
54 "oss", |
954 | 55 "A'rpi", |
56 "" | |
57 }; | |
58 | |
3181
c8edb0691f09
Extended oss output driver and libac3 to support 4 and 6 channel output mixes. added -channels command line option
steve
parents:
3137
diff
changeset
|
59 /* Support for >2 output channels added 2001-11-25 - Steve Davies <steve@daviesfam.org> */ |
c8edb0691f09
Extended oss output driver and libac3 to support 4 and 6 channel output mixes. added -channels command line option
steve
parents:
3137
diff
changeset
|
60 |
954 | 61 LIBAO_EXTERN(oss) |
62 | |
14245 | 63 static int format2oss(int format) |
64 { | |
65 switch(format) | |
66 { | |
67 case AF_FORMAT_U8: return AFMT_U8; | |
68 case AF_FORMAT_S8: return AFMT_S8; | |
69 case AF_FORMAT_U16_LE: return AFMT_U16_LE; | |
70 case AF_FORMAT_U16_BE: return AFMT_U16_BE; | |
71 case AF_FORMAT_S16_LE: return AFMT_S16_LE; | |
72 case AF_FORMAT_S16_BE: return AFMT_S16_BE; | |
29396
2de35e358503
Use the correct OSS format, where possible, for mplayer's packed 24-bit
cladisch
parents:
29263
diff
changeset
|
73 #ifdef AFMT_S24_PACKED |
2de35e358503
Use the correct OSS format, where possible, for mplayer's packed 24-bit
cladisch
parents:
29263
diff
changeset
|
74 case AF_FORMAT_S24_LE: return AFMT_S24_PACKED; |
14245 | 75 #endif |
14397
d862ff282815
Check for every 24 and 32 bit AFMT_ separately if it is defined.
reimar
parents:
14273
diff
changeset
|
76 #ifdef AFMT_U32_LE |
14245 | 77 case AF_FORMAT_U32_LE: return AFMT_U32_LE; |
14397
d862ff282815
Check for every 24 and 32 bit AFMT_ separately if it is defined.
reimar
parents:
14273
diff
changeset
|
78 #endif |
d862ff282815
Check for every 24 and 32 bit AFMT_ separately if it is defined.
reimar
parents:
14273
diff
changeset
|
79 #ifdef AFMT_U32_BE |
14245 | 80 case AF_FORMAT_U32_BE: return AFMT_U32_BE; |
14397
d862ff282815
Check for every 24 and 32 bit AFMT_ separately if it is defined.
reimar
parents:
14273
diff
changeset
|
81 #endif |
d862ff282815
Check for every 24 and 32 bit AFMT_ separately if it is defined.
reimar
parents:
14273
diff
changeset
|
82 #ifdef AFMT_S32_LE |
14245 | 83 case AF_FORMAT_S32_LE: return AFMT_S32_LE; |
14397
d862ff282815
Check for every 24 and 32 bit AFMT_ separately if it is defined.
reimar
parents:
14273
diff
changeset
|
84 #endif |
d862ff282815
Check for every 24 and 32 bit AFMT_ separately if it is defined.
reimar
parents:
14273
diff
changeset
|
85 #ifdef AFMT_S32_BE |
14245 | 86 case AF_FORMAT_S32_BE: return AFMT_S32_BE; |
87 #endif | |
88 #ifdef AFMT_FLOAT | |
89 case AF_FORMAT_FLOAT_NE: return AFMT_FLOAT; | |
90 #endif | |
91 // SPECIALS | |
92 case AF_FORMAT_MU_LAW: return AFMT_MU_LAW; | |
93 case AF_FORMAT_A_LAW: return AFMT_A_LAW; | |
94 case AF_FORMAT_IMA_ADPCM: return AFMT_IMA_ADPCM; | |
95 #ifdef AFMT_MPEG | |
96 case AF_FORMAT_MPEG2: return AFMT_MPEG; | |
97 #endif | |
98 #ifdef AFMT_AC3 | |
30241
02b9c1a452e1
Add support for distinguishing between little- and big-endian SPDIF AC3
reimar
parents:
30239
diff
changeset
|
99 case AF_FORMAT_AC3_NE: return AFMT_AC3; |
14245 | 100 #endif |
101 } | |
14609
082177fb93b1
print "Unknown/not supported internal format" message only with -v as it
reimar
parents:
14404
diff
changeset
|
102 mp_msg(MSGT_AO, MSGL_V, "OSS: Unknown/not supported internal format: %s\n", af_fmt2str_short(format)); |
14245 | 103 return -1; |
104 } | |
105 | |
106 static int oss2format(int format) | |
107 { | |
108 switch(format) | |
109 { | |
110 case AFMT_U8: return AF_FORMAT_U8; | |
111 case AFMT_S8: return AF_FORMAT_S8; | |
112 case AFMT_U16_LE: return AF_FORMAT_U16_LE; | |
113 case AFMT_U16_BE: return AF_FORMAT_U16_BE; | |
114 case AFMT_S16_LE: return AF_FORMAT_S16_LE; | |
115 case AFMT_S16_BE: return AF_FORMAT_S16_BE; | |
29396
2de35e358503
Use the correct OSS format, where possible, for mplayer's packed 24-bit
cladisch
parents:
29263
diff
changeset
|
116 #ifdef AFMT_S24_PACKED |
2de35e358503
Use the correct OSS format, where possible, for mplayer's packed 24-bit
cladisch
parents:
29263
diff
changeset
|
117 case AFMT_S24_PACKED: return AF_FORMAT_S24_LE; |
14245 | 118 #endif |
14397
d862ff282815
Check for every 24 and 32 bit AFMT_ separately if it is defined.
reimar
parents:
14273
diff
changeset
|
119 #ifdef AFMT_U32_LE |
14245 | 120 case AFMT_U32_LE: return AF_FORMAT_U32_LE; |
14397
d862ff282815
Check for every 24 and 32 bit AFMT_ separately if it is defined.
reimar
parents:
14273
diff
changeset
|
121 #endif |
d862ff282815
Check for every 24 and 32 bit AFMT_ separately if it is defined.
reimar
parents:
14273
diff
changeset
|
122 #ifdef AFMT_U32_BE |
14245 | 123 case AFMT_U32_BE: return AF_FORMAT_U32_BE; |
14397
d862ff282815
Check for every 24 and 32 bit AFMT_ separately if it is defined.
reimar
parents:
14273
diff
changeset
|
124 #endif |
d862ff282815
Check for every 24 and 32 bit AFMT_ separately if it is defined.
reimar
parents:
14273
diff
changeset
|
125 #ifdef AFMT_S32_LE |
14245 | 126 case AFMT_S32_LE: return AF_FORMAT_S32_LE; |
14397
d862ff282815
Check for every 24 and 32 bit AFMT_ separately if it is defined.
reimar
parents:
14273
diff
changeset
|
127 #endif |
d862ff282815
Check for every 24 and 32 bit AFMT_ separately if it is defined.
reimar
parents:
14273
diff
changeset
|
128 #ifdef AFMT_S32_BE |
14245 | 129 case AFMT_S32_BE: return AF_FORMAT_S32_BE; |
130 #endif | |
131 #ifdef AFMT_FLOAT | |
132 case AFMT_FLOAT: return AF_FORMAT_FLOAT_NE; | |
133 #endif | |
134 // SPECIALS | |
135 case AFMT_MU_LAW: return AF_FORMAT_MU_LAW; | |
136 case AFMT_A_LAW: return AF_FORMAT_A_LAW; | |
137 case AFMT_IMA_ADPCM: return AF_FORMAT_IMA_ADPCM; | |
138 #ifdef AFMT_MPEG | |
139 case AFMT_MPEG: return AF_FORMAT_MPEG2; | |
140 #endif | |
141 #ifdef AFMT_AC3 | |
30241
02b9c1a452e1
Add support for distinguishing between little- and big-endian SPDIF AC3
reimar
parents:
30239
diff
changeset
|
142 case AFMT_AC3: return AF_FORMAT_AC3_NE; |
14245 | 143 #endif |
144 } | |
17994
6927fabaef92
Part1 of several printf2mp_msg changes in patch from Otvos Attila oattila AT chello DOT hu
reynaldo
parents:
17566
diff
changeset
|
145 mp_msg(MSGT_GLOBAL,MSGL_ERR,MSGTR_AO_OSS_UnknownUnsupportedFormat, format); |
14245 | 146 return -1; |
147 } | |
148 | |
4803 | 149 static char *dsp=PATH_DEV_DSP; |
1020
72cacd3b8f30
Solaris 8 support - patch by Marcus Comstedt <marcus@idonex.se>
arpi_esp
parents:
956
diff
changeset
|
150 static audio_buf_info zz; |
954 | 151 static int audio_fd=-1; |
23809
6c348181fb20
Somewhat hackish fix for A-V desync with ao_oss and frame stepping:
reimar
parents:
21547
diff
changeset
|
152 static int prepause_space; |
954 | 153 |
18966
0662e5119de2
two variables are made static, one of them additionaly modified to const char*. Patch by Stefan Huehner, stefan AT huehner-org
reynaldo
parents:
18842
diff
changeset
|
154 static const char *oss_mixer_device = PATH_DEV_MIXER; |
0662e5119de2
two variables are made static, one of them additionaly modified to const char*. Patch by Stefan Huehner, stefan AT huehner-org
reynaldo
parents:
18842
diff
changeset
|
155 static int oss_mixer_channel = SOUND_MIXER_PCM; |
1191 | 156 |
954 | 157 // to set/get/query special features/parameters |
9633
12b1790038b0
64bit libao2 fix by Jens Axboe <mplayer-dev@kernel.dk>
alex
parents:
9141
diff
changeset
|
158 static int control(int cmd,void *arg){ |
954 | 159 switch(cmd){ |
160 case AOCONTROL_SET_DEVICE: | |
161 dsp=(char*)arg; | |
162 return CONTROL_OK; | |
6795 | 163 case AOCONTROL_GET_DEVICE: |
12383
94ba609e53f7
ok this one is beyond stupid. the code didn't even do what was intended
rfelker
parents:
12145
diff
changeset
|
164 *(char**)arg=dsp; |
6795 | 165 return CONTROL_OK; |
15898 | 166 #ifdef SNDCTL_DSP_GETFMTS |
954 | 167 case AOCONTROL_QUERY_FORMAT: |
15898 | 168 { |
169 int format; | |
170 if (!ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &format)) | |
27450
4da9ce4d8327
Fix 'cast from pointer to integer of different size' on 64bit architectures. Casting to long should work for 32bit and 64bit and not make a difference to the boolean operation (since 'format' is always 32bit (int) the upper 32bit of 'arg' won't matter, but the compiler should be happy now. Casting both to unsigned makes sure the compiler isn't messing things up by sign-extending 'format' to 64bit before masking)
ranma
parents:
23809
diff
changeset
|
171 if ((unsigned int)format & (unsigned long)arg) |
15898 | 172 return CONTROL_TRUE; |
173 return CONTROL_FALSE; | |
174 } | |
175 #endif | |
1191 | 176 case AOCONTROL_GET_VOLUME: |
177 case AOCONTROL_SET_VOLUME: | |
178 { | |
179 ao_control_vol_t *vol = (ao_control_vol_t *)arg; | |
7472
c4434bdf6e51
tons of warning fixes, also some 10l bugfixes, including Dominik's PVA bug
arpi
parents:
7118
diff
changeset
|
180 int fd, v, devs; |
1528
a444bd456fcc
ac3/spdif patch by German Gomez Garcia <german@piraos.com>
arpi
parents:
1456
diff
changeset
|
181 |
30239 | 182 if(AF_FORMAT_IS_AC3(ao_data.format)) |
1528
a444bd456fcc
ac3/spdif patch by German Gomez Garcia <german@piraos.com>
arpi
parents:
1456
diff
changeset
|
183 return CONTROL_TRUE; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
184 |
4788
d678ce495a75
Moved HW dependent mixer stuff to libao and removed master switch
anders
parents:
4184
diff
changeset
|
185 if ((fd = open(oss_mixer_device, O_RDONLY)) > 0) |
1191 | 186 { |
187 ioctl(fd, SOUND_MIXER_READ_DEVMASK, &devs); | |
11837 | 188 if (devs & (1 << oss_mixer_channel)) |
4788
d678ce495a75
Moved HW dependent mixer stuff to libao and removed master switch
anders
parents:
4184
diff
changeset
|
189 { |
1191 | 190 if (cmd == AOCONTROL_GET_VOLUME) |
4788
d678ce495a75
Moved HW dependent mixer stuff to libao and removed master switch
anders
parents:
4184
diff
changeset
|
191 { |
11837 | 192 ioctl(fd, MIXER_READ(oss_mixer_channel), &v); |
4788
d678ce495a75
Moved HW dependent mixer stuff to libao and removed master switch
anders
parents:
4184
diff
changeset
|
193 vol->right = (v & 0xFF00) >> 8; |
d678ce495a75
Moved HW dependent mixer stuff to libao and removed master switch
anders
parents:
4184
diff
changeset
|
194 vol->left = v & 0x00FF; |
d678ce495a75
Moved HW dependent mixer stuff to libao and removed master switch
anders
parents:
4184
diff
changeset
|
195 } |
1191 | 196 else |
4788
d678ce495a75
Moved HW dependent mixer stuff to libao and removed master switch
anders
parents:
4184
diff
changeset
|
197 { |
d678ce495a75
Moved HW dependent mixer stuff to libao and removed master switch
anders
parents:
4184
diff
changeset
|
198 v = ((int)vol->right << 8) | (int)vol->left; |
11837 | 199 ioctl(fd, MIXER_WRITE(oss_mixer_channel), &v); |
4788
d678ce495a75
Moved HW dependent mixer stuff to libao and removed master switch
anders
parents:
4184
diff
changeset
|
200 } |
d678ce495a75
Moved HW dependent mixer stuff to libao and removed master switch
anders
parents:
4184
diff
changeset
|
201 } |
1191 | 202 else |
203 { | |
204 close(fd); | |
205 return CONTROL_ERROR; | |
206 } | |
207 close(fd); | |
208 return CONTROL_OK; | |
209 } | |
210 } | |
211 return CONTROL_ERROR; | |
954 | 212 } |
213 return CONTROL_UNKNOWN; | |
214 } | |
215 | |
216 // open & setup audio device | |
217 // return: 1=success 0=fail | |
218 static int init(int rate,int channels,int format,int flags){ | |
11837 | 219 char *mixer_channels [SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_NAMES; |
14245 | 220 int oss_format; |
16959
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
221 char *mdev = mixer_device, *mchan = mixer_channel; |
954 | 222 |
14264 | 223 mp_msg(MSGT_AO,MSGL_V,"ao2: %d Hz %d chans %s\n",rate,channels, |
224 af_fmt2str_short(format)); | |
954 | 225 |
16959
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
226 if (ao_subdevice) { |
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
227 char *m,*c; |
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
228 m = strchr(ao_subdevice,':'); |
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
229 if(m) { |
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
230 c = strchr(m+1,':'); |
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
231 if(c) { |
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
232 mchan = c+1; |
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
233 c[0] = '\0'; |
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
234 } |
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
235 mdev = m+1; |
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
236 m[0] = '\0'; |
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
237 } |
1191 | 238 dsp = ao_subdevice; |
16959
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
239 } |
1191 | 240 |
16959
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
241 if(mdev) |
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
242 oss_mixer_device=mdev; |
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
243 else |
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
244 oss_mixer_device=PATH_DEV_MIXER; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
245 |
16959
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
246 if(mchan){ |
11837 | 247 int fd, devs, i; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
248 |
11837 | 249 if ((fd = open(oss_mixer_device, O_RDONLY)) == -1){ |
13383
c1955840883d
mp_msg transition of unmaintained audio output drivers.
ivo
parents:
12383
diff
changeset
|
250 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_OSS_CantOpenMixer, |
11837 | 251 oss_mixer_device, strerror(errno)); |
252 }else{ | |
253 ioctl(fd, SOUND_MIXER_READ_DEVMASK, &devs); | |
254 close(fd); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
255 |
11837 | 256 for (i=0; i<SOUND_MIXER_NRDEVICES; i++){ |
16959
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
257 if(!strcasecmp(mixer_channels[i], mchan)){ |
11837 | 258 if(!(devs & (1 << i))){ |
16959
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
259 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_OSS_ChanNotFound,mchan); |
11837 | 260 i = SOUND_MIXER_NRDEVICES+1; |
261 break; | |
262 } | |
263 oss_mixer_channel = i; | |
264 break; | |
265 } | |
266 } | |
267 if(i==SOUND_MIXER_NRDEVICES){ | |
16959
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
268 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_OSS_ChanNotFound,mchan); |
11837 | 269 } |
270 } | |
16959
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
271 } else |
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
272 oss_mixer_channel = SOUND_MIXER_PCM; |
11837 | 273 |
6296 | 274 mp_msg(MSGT_AO,MSGL_V,"audio_setup: using '%s' dsp device\n", dsp); |
11837 | 275 mp_msg(MSGT_AO,MSGL_V,"audio_setup: using '%s' mixer device\n", oss_mixer_device); |
276 mp_msg(MSGT_AO,MSGL_V,"audio_setup: using '%s' mixer device\n", mixer_channels[oss_mixer_channel]); | |
1191 | 277 |
5907
d8c34a35ccb9
nonblock open is not legal for OSS (see OSS api docs), and causes problems on freebsd (and maybe other OSs)
arpi
parents:
5872
diff
changeset
|
278 #ifdef __linux__ |
5204
6bbf3271a694
non-blocking open - patch by Fredrik Kuivinen <freku045@student.liu.se>
arpi
parents:
4803
diff
changeset
|
279 audio_fd=open(dsp, O_WRONLY | O_NONBLOCK); |
5907
d8c34a35ccb9
nonblock open is not legal for OSS (see OSS api docs), and causes problems on freebsd (and maybe other OSs)
arpi
parents:
5872
diff
changeset
|
280 #else |
d8c34a35ccb9
nonblock open is not legal for OSS (see OSS api docs), and causes problems on freebsd (and maybe other OSs)
arpi
parents:
5872
diff
changeset
|
281 audio_fd=open(dsp, O_WRONLY); |
d8c34a35ccb9
nonblock open is not legal for OSS (see OSS api docs), and causes problems on freebsd (and maybe other OSs)
arpi
parents:
5872
diff
changeset
|
282 #endif |
954 | 283 if(audio_fd<0){ |
13383
c1955840883d
mp_msg transition of unmaintained audio output drivers.
ivo
parents:
12383
diff
changeset
|
284 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_OSS_CantOpenDev, dsp, strerror(errno)); |
954 | 285 return 0; |
286 } | |
287 | |
5907
d8c34a35ccb9
nonblock open is not legal for OSS (see OSS api docs), and causes problems on freebsd (and maybe other OSs)
arpi
parents:
5872
diff
changeset
|
288 #ifdef __linux__ |
5204
6bbf3271a694
non-blocking open - patch by Fredrik Kuivinen <freku045@student.liu.se>
arpi
parents:
4803
diff
changeset
|
289 /* Remove the non-blocking flag */ |
6bbf3271a694
non-blocking open - patch by Fredrik Kuivinen <freku045@student.liu.se>
arpi
parents:
4803
diff
changeset
|
290 if(fcntl(audio_fd, F_SETFL, 0) < 0) { |
13383
c1955840883d
mp_msg transition of unmaintained audio output drivers.
ivo
parents:
12383
diff
changeset
|
291 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_OSS_CantMakeFd, strerror(errno)); |
5204
6bbf3271a694
non-blocking open - patch by Fredrik Kuivinen <freku045@student.liu.se>
arpi
parents:
4803
diff
changeset
|
292 return 0; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
293 } |
5907
d8c34a35ccb9
nonblock open is not legal for OSS (see OSS api docs), and causes problems on freebsd (and maybe other OSs)
arpi
parents:
5872
diff
changeset
|
294 #endif |
8303 | 295 |
296 #if defined(FD_CLOEXEC) && defined(F_SETFD) | |
297 fcntl(audio_fd, F_SETFD, FD_CLOEXEC); | |
298 #endif | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
299 |
30239 | 300 if(AF_FORMAT_IS_AC3(format)) { |
4184
f648f699eda6
hwac3 fix for cmedia 8738 by Hans-Peter Raschke <Hans-Peter.Raschke@wintermann-datenservice.de>
arpi
parents:
3455
diff
changeset
|
301 ao_data.samplerate=rate; |
f648f699eda6
hwac3 fix for cmedia 8738 by Hans-Peter Raschke <Hans-Peter.Raschke@wintermann-datenservice.de>
arpi
parents:
3455
diff
changeset
|
302 ioctl (audio_fd, SNDCTL_DSP_SPEED, &ao_data.samplerate); |
f648f699eda6
hwac3 fix for cmedia 8738 by Hans-Peter Raschke <Hans-Peter.Raschke@wintermann-datenservice.de>
arpi
parents:
3455
diff
changeset
|
303 } |
5790 | 304 |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
305 ac3_retry: |
30241
02b9c1a452e1
Add support for distinguishing between little- and big-endian SPDIF AC3
reimar
parents:
30239
diff
changeset
|
306 if (AF_FORMAT_IS_AC3(format)) |
02b9c1a452e1
Add support for distinguishing between little- and big-endian SPDIF AC3
reimar
parents:
30239
diff
changeset
|
307 format = AF_FORMAT_AC3_NE; |
3095 | 308 ao_data.format=format; |
14245 | 309 oss_format=format2oss(format); |
14260
7f3c14830dcd
100l set default format for AF_FORMATs not supported by sound card
rtognimp
parents:
14245
diff
changeset
|
310 if (oss_format == -1) { |
29401
f01023c524c3
Replace WORDS_BIGENDIAN by HAVE_BIGENDIAN in all internal code.
diego
parents:
29396
diff
changeset
|
311 #if HAVE_BIGENDIAN |
14245 | 312 oss_format=AFMT_S16_BE; |
5790 | 313 #else |
14245 | 314 oss_format=AFMT_S16_LE; |
5790 | 315 #endif |
14404
e4a52af25ee4
Use AF_FORMAT_S16_NE instead of #ifdef WORDS_BIGENDIAN ...
reimar
parents:
14397
diff
changeset
|
316 format=AF_FORMAT_S16_NE; |
14260
7f3c14830dcd
100l set default format for AF_FORMATs not supported by sound card
rtognimp
parents:
14245
diff
changeset
|
317 } |
7f3c14830dcd
100l set default format for AF_FORMATs not supported by sound card
rtognimp
parents:
14245
diff
changeset
|
318 if( ioctl(audio_fd, SNDCTL_DSP_SETFMT, &oss_format)<0 || |
14834
2d919650990a
Have OSS audio out fall back to s16ne instead of u8 if it can't open the
ivo
parents:
14609
diff
changeset
|
319 oss_format != format2oss(format)) { |
2d919650990a
Have OSS audio out fall back to s16ne instead of u8 if it can't open the
ivo
parents:
14609
diff
changeset
|
320 mp_msg(MSGT_AO,MSGL_WARN, MSGTR_AO_OSS_CantSet, dsp, |
2d919650990a
Have OSS audio out fall back to s16ne instead of u8 if it can't open the
ivo
parents:
14609
diff
changeset
|
321 af_fmt2str_short(format), af_fmt2str_short(AF_FORMAT_S16_NE) ); |
14404
e4a52af25ee4
Use AF_FORMAT_S16_NE instead of #ifdef WORDS_BIGENDIAN ...
reimar
parents:
14397
diff
changeset
|
322 format=AF_FORMAT_S16_NE; |
5790 | 323 goto ac3_retry; |
1528
a444bd456fcc
ac3/spdif patch by German Gomez Garcia <german@piraos.com>
arpi
parents:
1456
diff
changeset
|
324 } |
7668 | 325 #if 0 |
14245 | 326 if(oss_format!=format2oss(format)) |
17058 | 327 mp_msg(MSGT_AO,MSGL_WARN,"WARNING! Your soundcard does NOT support %s sample format! Broken audio or bad playback speed are possible! Try with '-af format'\n",audio_out_format_name(format)); |
7668 | 328 #endif |
14245 | 329 |
330 ao_data.format = oss2format(oss_format); | |
331 if (ao_data.format == -1) return 0; | |
14264 | 332 |
333 mp_msg(MSGT_AO,MSGL_V,"audio_setup: sample format: %s (requested: %s)\n", | |
334 af_fmt2str_short(ao_data.format), af_fmt2str_short(format)); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
335 |
8848 | 336 ao_data.channels = channels; |
30239 | 337 if(!AF_FORMAT_IS_AC3(format)) { |
3181
c8edb0691f09
Extended oss output driver and libac3 to support 4 and 6 channel output mixes. added -channels command line option
steve
parents:
3137
diff
changeset
|
338 // We only use SNDCTL_DSP_CHANNELS for >2 channels, in case some drivers don't have it |
c8edb0691f09
Extended oss output driver and libac3 to support 4 and 6 channel output mixes. added -channels command line option
steve
parents:
3137
diff
changeset
|
339 if (ao_data.channels > 2) { |
3319
66134af21278
fixed to check that SNDCTL_DSP_CHANNELS actually grants the requested number of channels
steve
parents:
3181
diff
changeset
|
340 if ( ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &ao_data.channels) == -1 || |
66134af21278
fixed to check that SNDCTL_DSP_CHANNELS actually grants the requested number of channels
steve
parents:
3181
diff
changeset
|
341 ao_data.channels != channels ) { |
13383
c1955840883d
mp_msg transition of unmaintained audio output drivers.
ivo
parents:
12383
diff
changeset
|
342 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_OSS_CantSetChans, channels); |
3181
c8edb0691f09
Extended oss output driver and libac3 to support 4 and 6 channel output mixes. added -channels command line option
steve
parents:
3137
diff
changeset
|
343 return 0; |
c8edb0691f09
Extended oss output driver and libac3 to support 4 and 6 channel output mixes. added -channels command line option
steve
parents:
3137
diff
changeset
|
344 } |
c8edb0691f09
Extended oss output driver and libac3 to support 4 and 6 channel output mixes. added -channels command line option
steve
parents:
3137
diff
changeset
|
345 } |
c8edb0691f09
Extended oss output driver and libac3 to support 4 and 6 channel output mixes. added -channels command line option
steve
parents:
3137
diff
changeset
|
346 else { |
c8edb0691f09
Extended oss output driver and libac3 to support 4 and 6 channel output mixes. added -channels command line option
steve
parents:
3137
diff
changeset
|
347 int c = ao_data.channels-1; |
c8edb0691f09
Extended oss output driver and libac3 to support 4 and 6 channel output mixes. added -channels command line option
steve
parents:
3137
diff
changeset
|
348 if (ioctl (audio_fd, SNDCTL_DSP_STEREO, &c) == -1) { |
13383
c1955840883d
mp_msg transition of unmaintained audio output drivers.
ivo
parents:
12383
diff
changeset
|
349 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_OSS_CantSetChans, ao_data.channels); |
3181
c8edb0691f09
Extended oss output driver and libac3 to support 4 and 6 channel output mixes. added -channels command line option
steve
parents:
3137
diff
changeset
|
350 return 0; |
c8edb0691f09
Extended oss output driver and libac3 to support 4 and 6 channel output mixes. added -channels command line option
steve
parents:
3137
diff
changeset
|
351 } |
9141
20793317e5ff
nice 10l bug, found by Balatoni Denes <pnis@coder.hu>
arpi
parents:
8848
diff
changeset
|
352 ao_data.channels=c+1; |
3181
c8edb0691f09
Extended oss output driver and libac3 to support 4 and 6 channel output mixes. added -channels command line option
steve
parents:
3137
diff
changeset
|
353 } |
6296 | 354 mp_msg(MSGT_AO,MSGL_V,"audio_setup: using %d channels (requested: %d)\n", ao_data.channels, channels); |
3181
c8edb0691f09
Extended oss output driver and libac3 to support 4 and 6 channel output mixes. added -channels command line option
steve
parents:
3137
diff
changeset
|
355 // set rate |
c8edb0691f09
Extended oss output driver and libac3 to support 4 and 6 channel output mixes. added -channels command line option
steve
parents:
3137
diff
changeset
|
356 ao_data.samplerate=rate; |
c8edb0691f09
Extended oss output driver and libac3 to support 4 and 6 channel output mixes. added -channels command line option
steve
parents:
3137
diff
changeset
|
357 ioctl (audio_fd, SNDCTL_DSP_SPEED, &ao_data.samplerate); |
6296 | 358 mp_msg(MSGT_AO,MSGL_V,"audio_setup: using %d Hz samplerate (requested: %d)\n",ao_data.samplerate,rate); |
1528
a444bd456fcc
ac3/spdif patch by German Gomez Garcia <german@piraos.com>
arpi
parents:
1456
diff
changeset
|
359 } |
954 | 360 |
361 if(ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &zz)==-1){ | |
362 int r=0; | |
13383
c1955840883d
mp_msg transition of unmaintained audio output drivers.
ivo
parents:
12383
diff
changeset
|
363 mp_msg(MSGT_AO,MSGL_WARN,MSGTR_AO_OSS_CantUseGetospace); |
954 | 364 if(ioctl(audio_fd, SNDCTL_DSP_GETBLKSIZE, &r)==-1){ |
6296 | 365 mp_msg(MSGT_AO,MSGL_V,"audio_setup: %d bytes/frag (config.h)\n",ao_data.outburst); |
954 | 366 } else { |
3095 | 367 ao_data.outburst=r; |
6296 | 368 mp_msg(MSGT_AO,MSGL_V,"audio_setup: %d bytes/frag (GETBLKSIZE)\n",ao_data.outburst); |
954 | 369 } |
370 } else { | |
6296 | 371 mp_msg(MSGT_AO,MSGL_V,"audio_setup: frags: %3d/%d (%d bytes/frag) free: %6d\n", |
954 | 372 zz.fragments, zz.fragstotal, zz.fragsize, zz.bytes); |
3095 | 373 if(ao_data.buffersize==-1) ao_data.buffersize=zz.bytes; |
374 ao_data.outburst=zz.fragsize; | |
954 | 375 } |
376 | |
3095 | 377 if(ao_data.buffersize==-1){ |
954 | 378 // Measuring buffer size: |
379 void* data; | |
3095 | 380 ao_data.buffersize=0; |
954 | 381 #ifdef HAVE_AUDIO_SELECT |
3095 | 382 data=malloc(ao_data.outburst); memset(data,0,ao_data.outburst); |
383 while(ao_data.buffersize<0x40000){ | |
954 | 384 fd_set rfds; |
385 struct timeval tv; | |
386 FD_ZERO(&rfds); FD_SET(audio_fd,&rfds); | |
387 tv.tv_sec=0; tv.tv_usec = 0; | |
388 if(!select(audio_fd+1, NULL, &rfds, NULL, &tv)) break; | |
3095 | 389 write(audio_fd,data,ao_data.outburst); |
390 ao_data.buffersize+=ao_data.outburst; | |
954 | 391 } |
392 free(data); | |
3095 | 393 if(ao_data.buffersize==0){ |
13383
c1955840883d
mp_msg transition of unmaintained audio output drivers.
ivo
parents:
12383
diff
changeset
|
394 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_OSS_CantUseSelect); |
954 | 395 return 0; |
396 } | |
397 #endif | |
398 } | |
399 | |
8603
30bef3c97b8b
ao_oss was not using the channel & format returned by the soundcard
arpi
parents:
8304
diff
changeset
|
400 ao_data.bps=ao_data.channels; |
29708
38a054e832c7
fix calculation of ao_data.bps for sample formats with more than 16 bits
cladisch
parents:
29401
diff
changeset
|
401 switch (ao_data.format & AF_FORMAT_BITS_MASK) { |
38a054e832c7
fix calculation of ao_data.bps for sample formats with more than 16 bits
cladisch
parents:
29401
diff
changeset
|
402 case AF_FORMAT_8BIT: |
38a054e832c7
fix calculation of ao_data.bps for sample formats with more than 16 bits
cladisch
parents:
29401
diff
changeset
|
403 break; |
38a054e832c7
fix calculation of ao_data.bps for sample formats with more than 16 bits
cladisch
parents:
29401
diff
changeset
|
404 case AF_FORMAT_16BIT: |
8603
30bef3c97b8b
ao_oss was not using the channel & format returned by the soundcard
arpi
parents:
8304
diff
changeset
|
405 ao_data.bps*=2; |
29708
38a054e832c7
fix calculation of ao_data.bps for sample formats with more than 16 bits
cladisch
parents:
29401
diff
changeset
|
406 break; |
38a054e832c7
fix calculation of ao_data.bps for sample formats with more than 16 bits
cladisch
parents:
29401
diff
changeset
|
407 case AF_FORMAT_24BIT: |
38a054e832c7
fix calculation of ao_data.bps for sample formats with more than 16 bits
cladisch
parents:
29401
diff
changeset
|
408 ao_data.bps*=3; |
38a054e832c7
fix calculation of ao_data.bps for sample formats with more than 16 bits
cladisch
parents:
29401
diff
changeset
|
409 break; |
38a054e832c7
fix calculation of ao_data.bps for sample formats with more than 16 bits
cladisch
parents:
29401
diff
changeset
|
410 case AF_FORMAT_32BIT: |
38a054e832c7
fix calculation of ao_data.bps for sample formats with more than 16 bits
cladisch
parents:
29401
diff
changeset
|
411 ao_data.bps*=4; |
38a054e832c7
fix calculation of ao_data.bps for sample formats with more than 16 bits
cladisch
parents:
29401
diff
changeset
|
412 break; |
38a054e832c7
fix calculation of ao_data.bps for sample formats with more than 16 bits
cladisch
parents:
29401
diff
changeset
|
413 } |
8603
30bef3c97b8b
ao_oss was not using the channel & format returned by the soundcard
arpi
parents:
8304
diff
changeset
|
414 |
6075
0b3b6d03779c
fix for L<->R swap with 6ch playback - based on patch by Eric Lammerts <eric@lammerts.org>
arpi
parents:
5907
diff
changeset
|
415 ao_data.outburst-=ao_data.outburst % ao_data.bps; // round down |
8603
30bef3c97b8b
ao_oss was not using the channel & format returned by the soundcard
arpi
parents:
8304
diff
changeset
|
416 ao_data.bps*=ao_data.samplerate; |
6075
0b3b6d03779c
fix for L<->R swap with 6ch playback - based on patch by Eric Lammerts <eric@lammerts.org>
arpi
parents:
5907
diff
changeset
|
417 |
954 | 418 return 1; |
419 } | |
420 | |
421 // close audio device | |
12145 | 422 static void uninit(int immed){ |
7118
4332922afec4
release /dev/dsp on pause patch by Eric Lammerts <eric@lammerts.org> (and D Richard Felker III <dalias@aerifal.cx>)
alex
parents:
6899
diff
changeset
|
423 if(audio_fd == -1) return; |
12145 | 424 #ifdef SNDCTL_DSP_SYNC |
425 // to get the buffer played | |
426 if (!immed) | |
427 ioctl(audio_fd, SNDCTL_DSP_SYNC, NULL); | |
428 #endif | |
1020
72cacd3b8f30
Solaris 8 support - patch by Marcus Comstedt <marcus@idonex.se>
arpi_esp
parents:
956
diff
changeset
|
429 #ifdef SNDCTL_DSP_RESET |
12145 | 430 if (immed) |
431 ioctl(audio_fd, SNDCTL_DSP_RESET, NULL); | |
1020
72cacd3b8f30
Solaris 8 support - patch by Marcus Comstedt <marcus@idonex.se>
arpi_esp
parents:
956
diff
changeset
|
432 #endif |
954 | 433 close(audio_fd); |
7118
4332922afec4
release /dev/dsp on pause patch by Eric Lammerts <eric@lammerts.org> (and D Richard Felker III <dalias@aerifal.cx>)
alex
parents:
6899
diff
changeset
|
434 audio_fd = -1; |
954 | 435 } |
436 | |
437 // stop playing and empty buffers (for seeking/pause) | |
17566
f580a7755ac5
Patch by Stefan Huehner / stefan % huehner ! org \
rathann
parents:
17058
diff
changeset
|
438 static void reset(void){ |
14245 | 439 int oss_format; |
12145 | 440 uninit(1); |
5907
d8c34a35ccb9
nonblock open is not legal for OSS (see OSS api docs), and causes problems on freebsd (and maybe other OSs)
arpi
parents:
5872
diff
changeset
|
441 audio_fd=open(dsp, O_WRONLY); |
d8c34a35ccb9
nonblock open is not legal for OSS (see OSS api docs), and causes problems on freebsd (and maybe other OSs)
arpi
parents:
5872
diff
changeset
|
442 if(audio_fd < 0){ |
13383
c1955840883d
mp_msg transition of unmaintained audio output drivers.
ivo
parents:
12383
diff
changeset
|
443 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_OSS_CantReopen, strerror(errno)); |
954 | 444 return; |
445 } | |
446 | |
10600
3cf428b56cde
Set close-on-exec after newer open (in reset func). Patch by Andriy Gapon <agapon@cv-nj.com>
alex
parents:
9633
diff
changeset
|
447 #if defined(FD_CLOEXEC) && defined(F_SETFD) |
3cf428b56cde
Set close-on-exec after newer open (in reset func). Patch by Andriy Gapon <agapon@cv-nj.com>
alex
parents:
9633
diff
changeset
|
448 fcntl(audio_fd, F_SETFD, FD_CLOEXEC); |
3cf428b56cde
Set close-on-exec after newer open (in reset func). Patch by Andriy Gapon <agapon@cv-nj.com>
alex
parents:
9633
diff
changeset
|
449 #endif |
3cf428b56cde
Set close-on-exec after newer open (in reset func). Patch by Andriy Gapon <agapon@cv-nj.com>
alex
parents:
9633
diff
changeset
|
450 |
14245 | 451 oss_format = format2oss(ao_data.format); |
30239 | 452 if(AF_FORMAT_IS_AC3(ao_data.format)) |
28605
65e49c604b25
Set samplerate in reset also for AC3, and set it before the format in that
reimar
parents:
28579
diff
changeset
|
453 ioctl (audio_fd, SNDCTL_DSP_SPEED, &ao_data.samplerate); |
14245 | 454 ioctl (audio_fd, SNDCTL_DSP_SETFMT, &oss_format); |
30239 | 455 if(!AF_FORMAT_IS_AC3(ao_data.format)) { |
3181
c8edb0691f09
Extended oss output driver and libac3 to support 4 and 6 channel output mixes. added -channels command line option
steve
parents:
3137
diff
changeset
|
456 if (ao_data.channels > 2) |
c8edb0691f09
Extended oss output driver and libac3 to support 4 and 6 channel output mixes. added -channels command line option
steve
parents:
3137
diff
changeset
|
457 ioctl (audio_fd, SNDCTL_DSP_CHANNELS, &ao_data.channels); |
c8edb0691f09
Extended oss output driver and libac3 to support 4 and 6 channel output mixes. added -channels command line option
steve
parents:
3137
diff
changeset
|
458 else { |
c8edb0691f09
Extended oss output driver and libac3 to support 4 and 6 channel output mixes. added -channels command line option
steve
parents:
3137
diff
changeset
|
459 int c = ao_data.channels-1; |
c8edb0691f09
Extended oss output driver and libac3 to support 4 and 6 channel output mixes. added -channels command line option
steve
parents:
3137
diff
changeset
|
460 ioctl (audio_fd, SNDCTL_DSP_STEREO, &c); |
c8edb0691f09
Extended oss output driver and libac3 to support 4 and 6 channel output mixes. added -channels command line option
steve
parents:
3137
diff
changeset
|
461 } |
c8edb0691f09
Extended oss output driver and libac3 to support 4 and 6 channel output mixes. added -channels command line option
steve
parents:
3137
diff
changeset
|
462 ioctl (audio_fd, SNDCTL_DSP_SPEED, &ao_data.samplerate); |
1528
a444bd456fcc
ac3/spdif patch by German Gomez Garcia <german@piraos.com>
arpi
parents:
1456
diff
changeset
|
463 } |
954 | 464 } |
465 | |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
1020
diff
changeset
|
466 // stop playing, keep buffers (for pause) |
17566
f580a7755ac5
Patch by Stefan Huehner / stefan % huehner ! org \
rathann
parents:
17058
diff
changeset
|
467 static void audio_pause(void) |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
1020
diff
changeset
|
468 { |
23809
6c348181fb20
Somewhat hackish fix for A-V desync with ao_oss and frame stepping:
reimar
parents:
21547
diff
changeset
|
469 prepause_space = get_space(); |
12145 | 470 uninit(1); |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
1020
diff
changeset
|
471 } |
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
1020
diff
changeset
|
472 |
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
1020
diff
changeset
|
473 // resume playing, after audio_pause() |
17566
f580a7755ac5
Patch by Stefan Huehner / stefan % huehner ! org \
rathann
parents:
17058
diff
changeset
|
474 static void audio_resume(void) |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
1020
diff
changeset
|
475 { |
23809
6c348181fb20
Somewhat hackish fix for A-V desync with ao_oss and frame stepping:
reimar
parents:
21547
diff
changeset
|
476 int fillcnt; |
7118
4332922afec4
release /dev/dsp on pause patch by Eric Lammerts <eric@lammerts.org> (and D Richard Felker III <dalias@aerifal.cx>)
alex
parents:
6899
diff
changeset
|
477 reset(); |
23809
6c348181fb20
Somewhat hackish fix for A-V desync with ao_oss and frame stepping:
reimar
parents:
21547
diff
changeset
|
478 fillcnt = get_space() - prepause_space; |
28579
0405513156d1
100l, do 0-filling on resume (to avoid desync after pause) in ao_oss only when
reimar
parents:
28343
diff
changeset
|
479 if (fillcnt > 0 && !(ao_data.format & AF_FORMAT_SPECIAL_MASK)) { |
23809
6c348181fb20
Somewhat hackish fix for A-V desync with ao_oss and frame stepping:
reimar
parents:
21547
diff
changeset
|
480 void *silence = calloc(fillcnt, 1); |
6c348181fb20
Somewhat hackish fix for A-V desync with ao_oss and frame stepping:
reimar
parents:
21547
diff
changeset
|
481 play(silence, fillcnt, 0); |
6c348181fb20
Somewhat hackish fix for A-V desync with ao_oss and frame stepping:
reimar
parents:
21547
diff
changeset
|
482 free(silence); |
6c348181fb20
Somewhat hackish fix for A-V desync with ao_oss and frame stepping:
reimar
parents:
21547
diff
changeset
|
483 } |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
1020
diff
changeset
|
484 } |
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
1020
diff
changeset
|
485 |
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
1020
diff
changeset
|
486 |
954 | 487 // return: how many bytes can be played without blocking |
17566
f580a7755ac5
Patch by Stefan Huehner / stefan % huehner ! org \
rathann
parents:
17058
diff
changeset
|
488 static int get_space(void){ |
3095 | 489 int playsize=ao_data.outburst; |
954 | 490 |
1020
72cacd3b8f30
Solaris 8 support - patch by Marcus Comstedt <marcus@idonex.se>
arpi_esp
parents:
956
diff
changeset
|
491 #ifdef SNDCTL_DSP_GETOSPACE |
954 | 492 if(ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &zz)!=-1){ |
493 // calculate exact buffer space: | |
3455
921a78c7b4aa
limit get_space return <= MAX_OUTBURST, whilst always an exact number of fragments
steve
parents:
3319
diff
changeset
|
494 playsize = zz.fragments*zz.fragsize; |
921a78c7b4aa
limit get_space return <= MAX_OUTBURST, whilst always an exact number of fragments
steve
parents:
3319
diff
changeset
|
495 if (playsize > MAX_OUTBURST) |
921a78c7b4aa
limit get_space return <= MAX_OUTBURST, whilst always an exact number of fragments
steve
parents:
3319
diff
changeset
|
496 playsize = (MAX_OUTBURST / zz.fragsize) * zz.fragsize; |
921a78c7b4aa
limit get_space return <= MAX_OUTBURST, whilst always an exact number of fragments
steve
parents:
3319
diff
changeset
|
497 return playsize; |
954 | 498 } |
1020
72cacd3b8f30
Solaris 8 support - patch by Marcus Comstedt <marcus@idonex.se>
arpi_esp
parents:
956
diff
changeset
|
499 #endif |
954 | 500 |
501 // check buffer | |
502 #ifdef HAVE_AUDIO_SELECT | |
503 { fd_set rfds; | |
504 struct timeval tv; | |
505 FD_ZERO(&rfds); | |
506 FD_SET(audio_fd, &rfds); | |
507 tv.tv_sec = 0; | |
508 tv.tv_usec = 0; | |
509 if(!select(audio_fd+1, NULL, &rfds, NULL, &tv)) return 0; // not block! | |
510 } | |
511 #endif | |
512 | |
3095 | 513 return ao_data.outburst; |
954 | 514 } |
515 | |
516 // plays 'len' bytes of 'data' | |
517 // it should round it down to outburst*n | |
518 // return: number of bytes played | |
519 static int play(void* data,int len,int flags){ | |
18842 | 520 if(len==0) |
521 return len; | |
522 if(len>ao_data.outburst || !(flags & AOPLAY_FINAL_CHUNK)) { | |
523 len/=ao_data.outburst; | |
524 len*=ao_data.outburst; | |
525 } | |
526 len=write(audio_fd,data,len); | |
954 | 527 return len; |
528 } | |
529 | |
530 static int audio_delay_method=2; | |
531 | |
3095 | 532 // return: delay in seconds between first and last sample in buffer |
17566
f580a7755ac5
Patch by Stefan Huehner / stefan % huehner ! org \
rathann
parents:
17058
diff
changeset
|
533 static float get_delay(void){ |
3095 | 534 /* Calculate how many bytes/second is sent out */ |
954 | 535 if(audio_delay_method==2){ |
5872 | 536 #ifdef SNDCTL_DSP_GETODELAY |
954 | 537 int r=0; |
538 if(ioctl(audio_fd, SNDCTL_DSP_GETODELAY, &r)!=-1) | |
3095 | 539 return ((float)r)/(float)ao_data.bps; |
5872 | 540 #endif |
954 | 541 audio_delay_method=1; // fallback if not supported |
542 } | |
543 if(audio_delay_method==1){ | |
544 // SNDCTL_DSP_GETOSPACE | |
545 if(ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &zz)!=-1) | |
3095 | 546 return ((float)(ao_data.buffersize-zz.bytes))/(float)ao_data.bps; |
954 | 547 audio_delay_method=0; // fallback if not supported |
548 } | |
3095 | 549 return ((float)ao_data.buffersize)/(float)ao_data.bps; |
954 | 550 } |