Mercurial > mplayer.hg
annotate libao2/ao_oss.c @ 27771:15df1f217e6d
Convert typeof keyword into __typeof__
typeof is a gcc extension and the former is not accepted in C99 without
GNU extensions enabled (e.g. via -fasm).
This fixes compilation on PPC.
author | conrad |
---|---|
date | Sun, 19 Oct 2008 18:56:35 +0000 |
parents | 4da9ce4d8327 |
children | e45b08f2f5d3 |
rev | line source |
---|---|
954 | 1 #include <stdio.h> |
2 #include <stdlib.h> | |
3 | |
4 #include <sys/ioctl.h> | |
5 #include <unistd.h> | |
6 #include <sys/time.h> | |
7 #include <sys/types.h> | |
8 #include <sys/stat.h> | |
9 #include <fcntl.h> | |
5204
6bbf3271a694
non-blocking open - patch by Fredrik Kuivinen <freku045@student.liu.se>
arpi
parents:
4803
diff
changeset
|
10 #include <errno.h> |
6bbf3271a694
non-blocking open - patch by Fredrik Kuivinen <freku045@student.liu.se>
arpi
parents:
4803
diff
changeset
|
11 #include <string.h> |
954 | 12 |
14123 | 13 #include "config.h" |
14 #include "mp_msg.h" | |
15 #include "mixer.h" | |
16 #include "help_mp.h" | |
954 | 17 |
14245 | 18 #ifdef HAVE_SYS_SOUNDCARD_H |
19 #include <sys/soundcard.h> | |
20 #else | |
21 #ifdef HAVE_SOUNDCARD_H | |
22 #include <soundcard.h> | |
23 #endif | |
24 #endif | |
25 | |
17020 | 26 #include "libaf/af_format.h" |
1532 | 27 |
954 | 28 #include "audio_out.h" |
29 #include "audio_out_internal.h" | |
30 | |
31 static ao_info_t info = | |
32 { | |
33 "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
|
34 "oss", |
954 | 35 "A'rpi", |
36 "" | |
37 }; | |
38 | |
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
|
39 /* 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
|
40 |
954 | 41 LIBAO_EXTERN(oss) |
42 | |
14245 | 43 static int format2oss(int format) |
44 { | |
45 switch(format) | |
46 { | |
47 case AF_FORMAT_U8: return AFMT_U8; | |
48 case AF_FORMAT_S8: return AFMT_S8; | |
49 case AF_FORMAT_U16_LE: return AFMT_U16_LE; | |
50 case AF_FORMAT_U16_BE: return AFMT_U16_BE; | |
51 case AF_FORMAT_S16_LE: return AFMT_S16_LE; | |
52 case AF_FORMAT_S16_BE: return AFMT_S16_BE; | |
14397
d862ff282815
Check for every 24 and 32 bit AFMT_ separately if it is defined.
reimar
parents:
14273
diff
changeset
|
53 #ifdef AFMT_U24_LE |
14245 | 54 case AF_FORMAT_U24_LE: return AFMT_U24_LE; |
14397
d862ff282815
Check for every 24 and 32 bit AFMT_ separately if it is defined.
reimar
parents:
14273
diff
changeset
|
55 #endif |
d862ff282815
Check for every 24 and 32 bit AFMT_ separately if it is defined.
reimar
parents:
14273
diff
changeset
|
56 #ifdef AFMT_U24_BE |
14245 | 57 case AF_FORMAT_U24_BE: return AFMT_U24_BE; |
14397
d862ff282815
Check for every 24 and 32 bit AFMT_ separately if it is defined.
reimar
parents:
14273
diff
changeset
|
58 #endif |
d862ff282815
Check for every 24 and 32 bit AFMT_ separately if it is defined.
reimar
parents:
14273
diff
changeset
|
59 #ifdef AFMT_S24_LE |
14245 | 60 case AF_FORMAT_S24_LE: return AFMT_S24_LE; |
14397
d862ff282815
Check for every 24 and 32 bit AFMT_ separately if it is defined.
reimar
parents:
14273
diff
changeset
|
61 #endif |
d862ff282815
Check for every 24 and 32 bit AFMT_ separately if it is defined.
reimar
parents:
14273
diff
changeset
|
62 #ifdef AFMT_S24_BE |
14245 | 63 case AF_FORMAT_S24_BE: return AFMT_S24_BE; |
64 #endif | |
14397
d862ff282815
Check for every 24 and 32 bit AFMT_ separately if it is defined.
reimar
parents:
14273
diff
changeset
|
65 #ifdef AFMT_U32_LE |
14245 | 66 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
|
67 #endif |
d862ff282815
Check for every 24 and 32 bit AFMT_ separately if it is defined.
reimar
parents:
14273
diff
changeset
|
68 #ifdef AFMT_U32_BE |
14245 | 69 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
|
70 #endif |
d862ff282815
Check for every 24 and 32 bit AFMT_ separately if it is defined.
reimar
parents:
14273
diff
changeset
|
71 #ifdef AFMT_S32_LE |
14245 | 72 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
|
73 #endif |
d862ff282815
Check for every 24 and 32 bit AFMT_ separately if it is defined.
reimar
parents:
14273
diff
changeset
|
74 #ifdef AFMT_S32_BE |
14245 | 75 case AF_FORMAT_S32_BE: return AFMT_S32_BE; |
76 #endif | |
77 #ifdef AFMT_FLOAT | |
78 case AF_FORMAT_FLOAT_NE: return AFMT_FLOAT; | |
79 #endif | |
80 // SPECIALS | |
81 case AF_FORMAT_MU_LAW: return AFMT_MU_LAW; | |
82 case AF_FORMAT_A_LAW: return AFMT_A_LAW; | |
83 case AF_FORMAT_IMA_ADPCM: return AFMT_IMA_ADPCM; | |
84 #ifdef AFMT_MPEG | |
85 case AF_FORMAT_MPEG2: return AFMT_MPEG; | |
86 #endif | |
87 #ifdef AFMT_AC3 | |
88 case AF_FORMAT_AC3: return AFMT_AC3; | |
89 #endif | |
90 } | |
14609
082177fb93b1
print "Unknown/not supported internal format" message only with -v as it
reimar
parents:
14404
diff
changeset
|
91 mp_msg(MSGT_AO, MSGL_V, "OSS: Unknown/not supported internal format: %s\n", af_fmt2str_short(format)); |
14245 | 92 return -1; |
93 } | |
94 | |
95 static int oss2format(int format) | |
96 { | |
97 switch(format) | |
98 { | |
99 case AFMT_U8: return AF_FORMAT_U8; | |
100 case AFMT_S8: return AF_FORMAT_S8; | |
101 case AFMT_U16_LE: return AF_FORMAT_U16_LE; | |
102 case AFMT_U16_BE: return AF_FORMAT_U16_BE; | |
103 case AFMT_S16_LE: return AF_FORMAT_S16_LE; | |
104 case AFMT_S16_BE: return AF_FORMAT_S16_BE; | |
14397
d862ff282815
Check for every 24 and 32 bit AFMT_ separately if it is defined.
reimar
parents:
14273
diff
changeset
|
105 #ifdef AFMT_U24_LE |
14245 | 106 case AFMT_U24_LE: return AF_FORMAT_U24_LE; |
14397
d862ff282815
Check for every 24 and 32 bit AFMT_ separately if it is defined.
reimar
parents:
14273
diff
changeset
|
107 #endif |
d862ff282815
Check for every 24 and 32 bit AFMT_ separately if it is defined.
reimar
parents:
14273
diff
changeset
|
108 #ifdef AFMT_U24_BE |
14245 | 109 case AFMT_U24_BE: return AF_FORMAT_U24_BE; |
14397
d862ff282815
Check for every 24 and 32 bit AFMT_ separately if it is defined.
reimar
parents:
14273
diff
changeset
|
110 #endif |
d862ff282815
Check for every 24 and 32 bit AFMT_ separately if it is defined.
reimar
parents:
14273
diff
changeset
|
111 #ifdef AFMT_S24_LE |
14245 | 112 case AFMT_S24_LE: return AF_FORMAT_S24_LE; |
14397
d862ff282815
Check for every 24 and 32 bit AFMT_ separately if it is defined.
reimar
parents:
14273
diff
changeset
|
113 #endif |
d862ff282815
Check for every 24 and 32 bit AFMT_ separately if it is defined.
reimar
parents:
14273
diff
changeset
|
114 #ifdef AFMT_S24_BE |
14245 | 115 case AFMT_S24_BE: return AF_FORMAT_S24_BE; |
116 #endif | |
14397
d862ff282815
Check for every 24 and 32 bit AFMT_ separately if it is defined.
reimar
parents:
14273
diff
changeset
|
117 #ifdef AFMT_U32_LE |
14245 | 118 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
|
119 #endif |
d862ff282815
Check for every 24 and 32 bit AFMT_ separately if it is defined.
reimar
parents:
14273
diff
changeset
|
120 #ifdef AFMT_U32_BE |
14245 | 121 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
|
122 #endif |
d862ff282815
Check for every 24 and 32 bit AFMT_ separately if it is defined.
reimar
parents:
14273
diff
changeset
|
123 #ifdef AFMT_S32_LE |
14245 | 124 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
|
125 #endif |
d862ff282815
Check for every 24 and 32 bit AFMT_ separately if it is defined.
reimar
parents:
14273
diff
changeset
|
126 #ifdef AFMT_S32_BE |
14245 | 127 case AFMT_S32_BE: return AF_FORMAT_S32_BE; |
128 #endif | |
129 #ifdef AFMT_FLOAT | |
130 case AFMT_FLOAT: return AF_FORMAT_FLOAT_NE; | |
131 #endif | |
132 // SPECIALS | |
133 case AFMT_MU_LAW: return AF_FORMAT_MU_LAW; | |
134 case AFMT_A_LAW: return AF_FORMAT_A_LAW; | |
135 case AFMT_IMA_ADPCM: return AF_FORMAT_IMA_ADPCM; | |
136 #ifdef AFMT_MPEG | |
137 case AFMT_MPEG: return AF_FORMAT_MPEG2; | |
138 #endif | |
139 #ifdef AFMT_AC3 | |
140 case AFMT_AC3: return AF_FORMAT_AC3; | |
141 #endif | |
142 } | |
17994
6927fabaef92
Part1 of several printf2mp_msg changes in patch from Otvos Attila oattila AT chello DOT hu
reynaldo
parents:
17566
diff
changeset
|
143 mp_msg(MSGT_GLOBAL,MSGL_ERR,MSGTR_AO_OSS_UnknownUnsupportedFormat, format); |
14245 | 144 return -1; |
145 } | |
146 | |
4803 | 147 static char *dsp=PATH_DEV_DSP; |
1020
72cacd3b8f30
Solaris 8 support - patch by Marcus Comstedt <marcus@idonex.se>
arpi_esp
parents:
956
diff
changeset
|
148 static audio_buf_info zz; |
954 | 149 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
|
150 static int prepause_space; |
954 | 151 |
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
|
152 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
|
153 static int oss_mixer_channel = SOUND_MIXER_PCM; |
1191 | 154 |
954 | 155 // to set/get/query special features/parameters |
9633
12b1790038b0
64bit libao2 fix by Jens Axboe <mplayer-dev@kernel.dk>
alex
parents:
9141
diff
changeset
|
156 static int control(int cmd,void *arg){ |
954 | 157 switch(cmd){ |
158 case AOCONTROL_SET_DEVICE: | |
159 dsp=(char*)arg; | |
160 return CONTROL_OK; | |
6795 | 161 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
|
162 *(char**)arg=dsp; |
6795 | 163 return CONTROL_OK; |
15898 | 164 #ifdef SNDCTL_DSP_GETFMTS |
954 | 165 case AOCONTROL_QUERY_FORMAT: |
15898 | 166 { |
167 int format; | |
168 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
|
169 if ((unsigned int)format & (unsigned long)arg) |
15898 | 170 return CONTROL_TRUE; |
171 return CONTROL_FALSE; | |
172 } | |
173 #endif | |
1191 | 174 case AOCONTROL_GET_VOLUME: |
175 case AOCONTROL_SET_VOLUME: | |
176 { | |
177 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
|
178 int fd, v, devs; |
1528
a444bd456fcc
ac3/spdif patch by German Gomez Garcia <german@piraos.com>
arpi
parents:
1456
diff
changeset
|
179 |
14245 | 180 if(ao_data.format == AF_FORMAT_AC3) |
1528
a444bd456fcc
ac3/spdif patch by German Gomez Garcia <german@piraos.com>
arpi
parents:
1456
diff
changeset
|
181 return CONTROL_TRUE; |
1191 | 182 |
4788
d678ce495a75
Moved HW dependent mixer stuff to libao and removed master switch
anders
parents:
4184
diff
changeset
|
183 if ((fd = open(oss_mixer_device, O_RDONLY)) > 0) |
1191 | 184 { |
185 ioctl(fd, SOUND_MIXER_READ_DEVMASK, &devs); | |
11837 | 186 if (devs & (1 << oss_mixer_channel)) |
4788
d678ce495a75
Moved HW dependent mixer stuff to libao and removed master switch
anders
parents:
4184
diff
changeset
|
187 { |
1191 | 188 if (cmd == AOCONTROL_GET_VOLUME) |
4788
d678ce495a75
Moved HW dependent mixer stuff to libao and removed master switch
anders
parents:
4184
diff
changeset
|
189 { |
11837 | 190 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
|
191 vol->right = (v & 0xFF00) >> 8; |
d678ce495a75
Moved HW dependent mixer stuff to libao and removed master switch
anders
parents:
4184
diff
changeset
|
192 vol->left = v & 0x00FF; |
d678ce495a75
Moved HW dependent mixer stuff to libao and removed master switch
anders
parents:
4184
diff
changeset
|
193 } |
1191 | 194 else |
4788
d678ce495a75
Moved HW dependent mixer stuff to libao and removed master switch
anders
parents:
4184
diff
changeset
|
195 { |
d678ce495a75
Moved HW dependent mixer stuff to libao and removed master switch
anders
parents:
4184
diff
changeset
|
196 v = ((int)vol->right << 8) | (int)vol->left; |
11837 | 197 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
|
198 } |
d678ce495a75
Moved HW dependent mixer stuff to libao and removed master switch
anders
parents:
4184
diff
changeset
|
199 } |
1191 | 200 else |
201 { | |
202 close(fd); | |
203 return CONTROL_ERROR; | |
204 } | |
205 close(fd); | |
206 return CONTROL_OK; | |
207 } | |
208 } | |
209 return CONTROL_ERROR; | |
954 | 210 } |
211 return CONTROL_UNKNOWN; | |
212 } | |
213 | |
214 // open & setup audio device | |
215 // return: 1=success 0=fail | |
216 static int init(int rate,int channels,int format,int flags){ | |
11837 | 217 char *mixer_channels [SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_NAMES; |
14245 | 218 int oss_format; |
16959
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
219 char *mdev = mixer_device, *mchan = mixer_channel; |
954 | 220 |
14264 | 221 mp_msg(MSGT_AO,MSGL_V,"ao2: %d Hz %d chans %s\n",rate,channels, |
222 af_fmt2str_short(format)); | |
954 | 223 |
16959
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
224 if (ao_subdevice) { |
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
225 char *m,*c; |
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
226 m = strchr(ao_subdevice,':'); |
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
227 if(m) { |
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
228 c = strchr(m+1,':'); |
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
229 if(c) { |
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
230 mchan = c+1; |
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
231 c[0] = '\0'; |
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
232 } |
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
233 mdev = m+1; |
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
234 m[0] = '\0'; |
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
235 } |
1191 | 236 dsp = ao_subdevice; |
16959
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
237 } |
1191 | 238 |
16959
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
239 if(mdev) |
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
240 oss_mixer_device=mdev; |
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
241 else |
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
242 oss_mixer_device=PATH_DEV_MIXER; |
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
243 |
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
244 if(mchan){ |
11837 | 245 int fd, devs, i; |
246 | |
247 if ((fd = open(oss_mixer_device, O_RDONLY)) == -1){ | |
13383
c1955840883d
mp_msg transition of unmaintained audio output drivers.
ivo
parents:
12383
diff
changeset
|
248 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_OSS_CantOpenMixer, |
11837 | 249 oss_mixer_device, strerror(errno)); |
250 }else{ | |
251 ioctl(fd, SOUND_MIXER_READ_DEVMASK, &devs); | |
252 close(fd); | |
253 | |
254 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
|
255 if(!strcasecmp(mixer_channels[i], mchan)){ |
11837 | 256 if(!(devs & (1 << i))){ |
16959
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
257 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_OSS_ChanNotFound,mchan); |
11837 | 258 i = SOUND_MIXER_NRDEVICES+1; |
259 break; | |
260 } | |
261 oss_mixer_channel = i; | |
262 break; | |
263 } | |
264 } | |
265 if(i==SOUND_MIXER_NRDEVICES){ | |
16959
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
266 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_OSS_ChanNotFound,mchan); |
11837 | 267 } |
268 } | |
16959
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
269 } else |
832a93fc5deb
Allow setting the mixer per instance so one can fallback between
albeu
parents:
15898
diff
changeset
|
270 oss_mixer_channel = SOUND_MIXER_PCM; |
11837 | 271 |
6296 | 272 mp_msg(MSGT_AO,MSGL_V,"audio_setup: using '%s' dsp device\n", dsp); |
11837 | 273 mp_msg(MSGT_AO,MSGL_V,"audio_setup: using '%s' mixer device\n", oss_mixer_device); |
274 mp_msg(MSGT_AO,MSGL_V,"audio_setup: using '%s' mixer device\n", mixer_channels[oss_mixer_channel]); | |
1191 | 275 |
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
|
276 #ifdef __linux__ |
5204
6bbf3271a694
non-blocking open - patch by Fredrik Kuivinen <freku045@student.liu.se>
arpi
parents:
4803
diff
changeset
|
277 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
|
278 #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
|
279 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
|
280 #endif |
954 | 281 if(audio_fd<0){ |
13383
c1955840883d
mp_msg transition of unmaintained audio output drivers.
ivo
parents:
12383
diff
changeset
|
282 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_OSS_CantOpenDev, dsp, strerror(errno)); |
954 | 283 return 0; |
284 } | |
285 | |
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
|
286 #ifdef __linux__ |
5204
6bbf3271a694
non-blocking open - patch by Fredrik Kuivinen <freku045@student.liu.se>
arpi
parents:
4803
diff
changeset
|
287 /* Remove the non-blocking flag */ |
6bbf3271a694
non-blocking open - patch by Fredrik Kuivinen <freku045@student.liu.se>
arpi
parents:
4803
diff
changeset
|
288 if(fcntl(audio_fd, F_SETFL, 0) < 0) { |
13383
c1955840883d
mp_msg transition of unmaintained audio output drivers.
ivo
parents:
12383
diff
changeset
|
289 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
|
290 return 0; |
6bbf3271a694
non-blocking open - patch by Fredrik Kuivinen <freku045@student.liu.se>
arpi
parents:
4803
diff
changeset
|
291 } |
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
|
292 #endif |
8303 | 293 |
294 #if defined(FD_CLOEXEC) && defined(F_SETFD) | |
295 fcntl(audio_fd, F_SETFD, FD_CLOEXEC); | |
296 #endif | |
5204
6bbf3271a694
non-blocking open - patch by Fredrik Kuivinen <freku045@student.liu.se>
arpi
parents:
4803
diff
changeset
|
297 |
14245 | 298 if(format == AF_FORMAT_AC3) { |
4184
f648f699eda6
hwac3 fix for cmedia 8738 by Hans-Peter Raschke <Hans-Peter.Raschke@wintermann-datenservice.de>
arpi
parents:
3455
diff
changeset
|
299 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
|
300 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
|
301 } |
5790 | 302 |
303 ac3_retry: | |
3095 | 304 ao_data.format=format; |
14245 | 305 oss_format=format2oss(format); |
14260
7f3c14830dcd
100l set default format for AF_FORMATs not supported by sound card
rtognimp
parents:
14245
diff
changeset
|
306 if (oss_format == -1) { |
5790 | 307 #ifdef WORDS_BIGENDIAN |
14245 | 308 oss_format=AFMT_S16_BE; |
5790 | 309 #else |
14245 | 310 oss_format=AFMT_S16_LE; |
5790 | 311 #endif |
14404
e4a52af25ee4
Use AF_FORMAT_S16_NE instead of #ifdef WORDS_BIGENDIAN ...
reimar
parents:
14397
diff
changeset
|
312 format=AF_FORMAT_S16_NE; |
14260
7f3c14830dcd
100l set default format for AF_FORMATs not supported by sound card
rtognimp
parents:
14245
diff
changeset
|
313 } |
7f3c14830dcd
100l set default format for AF_FORMATs not supported by sound card
rtognimp
parents:
14245
diff
changeset
|
314 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
|
315 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
|
316 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
|
317 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
|
318 format=AF_FORMAT_S16_NE; |
5790 | 319 goto ac3_retry; |
1528
a444bd456fcc
ac3/spdif patch by German Gomez Garcia <german@piraos.com>
arpi
parents:
1456
diff
changeset
|
320 } |
7668 | 321 #if 0 |
14245 | 322 if(oss_format!=format2oss(format)) |
17058 | 323 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 | 324 #endif |
14245 | 325 |
326 ao_data.format = oss2format(oss_format); | |
327 if (ao_data.format == -1) return 0; | |
14264 | 328 |
329 mp_msg(MSGT_AO,MSGL_V,"audio_setup: sample format: %s (requested: %s)\n", | |
330 af_fmt2str_short(ao_data.format), af_fmt2str_short(format)); | |
954 | 331 |
8848 | 332 ao_data.channels = channels; |
14245 | 333 if(format != AF_FORMAT_AC3) { |
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
|
334 // 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
|
335 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
|
336 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
|
337 ao_data.channels != channels ) { |
13383
c1955840883d
mp_msg transition of unmaintained audio output drivers.
ivo
parents:
12383
diff
changeset
|
338 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
|
339 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
|
340 } |
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
|
341 } |
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
|
342 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
|
343 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
|
344 if (ioctl (audio_fd, SNDCTL_DSP_STEREO, &c) == -1) { |
13383
c1955840883d
mp_msg transition of unmaintained audio output drivers.
ivo
parents:
12383
diff
changeset
|
345 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
|
346 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
|
347 } |
9141
20793317e5ff
nice 10l bug, found by Balatoni Denes <pnis@coder.hu>
arpi
parents:
8848
diff
changeset
|
348 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
|
349 } |
6296 | 350 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
|
351 // 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
|
352 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
|
353 ioctl (audio_fd, SNDCTL_DSP_SPEED, &ao_data.samplerate); |
6296 | 354 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
|
355 } |
954 | 356 |
357 if(ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &zz)==-1){ | |
358 int r=0; | |
13383
c1955840883d
mp_msg transition of unmaintained audio output drivers.
ivo
parents:
12383
diff
changeset
|
359 mp_msg(MSGT_AO,MSGL_WARN,MSGTR_AO_OSS_CantUseGetospace); |
954 | 360 if(ioctl(audio_fd, SNDCTL_DSP_GETBLKSIZE, &r)==-1){ |
6296 | 361 mp_msg(MSGT_AO,MSGL_V,"audio_setup: %d bytes/frag (config.h)\n",ao_data.outburst); |
954 | 362 } else { |
3095 | 363 ao_data.outburst=r; |
6296 | 364 mp_msg(MSGT_AO,MSGL_V,"audio_setup: %d bytes/frag (GETBLKSIZE)\n",ao_data.outburst); |
954 | 365 } |
366 } else { | |
6296 | 367 mp_msg(MSGT_AO,MSGL_V,"audio_setup: frags: %3d/%d (%d bytes/frag) free: %6d\n", |
954 | 368 zz.fragments, zz.fragstotal, zz.fragsize, zz.bytes); |
3095 | 369 if(ao_data.buffersize==-1) ao_data.buffersize=zz.bytes; |
370 ao_data.outburst=zz.fragsize; | |
954 | 371 } |
372 | |
3095 | 373 if(ao_data.buffersize==-1){ |
954 | 374 // Measuring buffer size: |
375 void* data; | |
3095 | 376 ao_data.buffersize=0; |
954 | 377 #ifdef HAVE_AUDIO_SELECT |
3095 | 378 data=malloc(ao_data.outburst); memset(data,0,ao_data.outburst); |
379 while(ao_data.buffersize<0x40000){ | |
954 | 380 fd_set rfds; |
381 struct timeval tv; | |
382 FD_ZERO(&rfds); FD_SET(audio_fd,&rfds); | |
383 tv.tv_sec=0; tv.tv_usec = 0; | |
384 if(!select(audio_fd+1, NULL, &rfds, NULL, &tv)) break; | |
3095 | 385 write(audio_fd,data,ao_data.outburst); |
386 ao_data.buffersize+=ao_data.outburst; | |
954 | 387 } |
388 free(data); | |
3095 | 389 if(ao_data.buffersize==0){ |
13383
c1955840883d
mp_msg transition of unmaintained audio output drivers.
ivo
parents:
12383
diff
changeset
|
390 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_OSS_CantUseSelect); |
954 | 391 return 0; |
392 } | |
393 #endif | |
394 } | |
395 | |
8603
30bef3c97b8b
ao_oss was not using the channel & format returned by the soundcard
arpi
parents:
8304
diff
changeset
|
396 ao_data.bps=ao_data.channels; |
14245 | 397 if(ao_data.format != AF_FORMAT_U8 && ao_data.format != AF_FORMAT_S8) |
8603
30bef3c97b8b
ao_oss was not using the channel & format returned by the soundcard
arpi
parents:
8304
diff
changeset
|
398 ao_data.bps*=2; |
30bef3c97b8b
ao_oss was not using the channel & format returned by the soundcard
arpi
parents:
8304
diff
changeset
|
399 |
6075
0b3b6d03779c
fix for L<->R swap with 6ch playback - based on patch by Eric Lammerts <eric@lammerts.org>
arpi
parents:
5907
diff
changeset
|
400 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
|
401 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
|
402 |
954 | 403 return 1; |
404 } | |
405 | |
406 // close audio device | |
12145 | 407 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
|
408 if(audio_fd == -1) return; |
12145 | 409 #ifdef SNDCTL_DSP_SYNC |
410 // to get the buffer played | |
411 if (!immed) | |
412 ioctl(audio_fd, SNDCTL_DSP_SYNC, NULL); | |
413 #endif | |
1020
72cacd3b8f30
Solaris 8 support - patch by Marcus Comstedt <marcus@idonex.se>
arpi_esp
parents:
956
diff
changeset
|
414 #ifdef SNDCTL_DSP_RESET |
12145 | 415 if (immed) |
416 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
|
417 #endif |
954 | 418 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
|
419 audio_fd = -1; |
954 | 420 } |
421 | |
422 // stop playing and empty buffers (for seeking/pause) | |
17566
f580a7755ac5
Patch by Stefan Huehner / stefan % huehner ! org \
rathann
parents:
17058
diff
changeset
|
423 static void reset(void){ |
14245 | 424 int oss_format; |
12145 | 425 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
|
426 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
|
427 if(audio_fd < 0){ |
13383
c1955840883d
mp_msg transition of unmaintained audio output drivers.
ivo
parents:
12383
diff
changeset
|
428 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_OSS_CantReopen, strerror(errno)); |
954 | 429 return; |
430 } | |
431 | |
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
|
432 #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
|
433 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
|
434 #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
|
435 |
14245 | 436 oss_format = format2oss(ao_data.format); |
437 ioctl (audio_fd, SNDCTL_DSP_SETFMT, &oss_format); | |
438 if(ao_data.format != AF_FORMAT_AC3) { | |
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
|
439 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
|
440 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
|
441 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
|
442 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
|
443 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
|
444 } |
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
|
445 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
|
446 } |
954 | 447 } |
448 | |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
1020
diff
changeset
|
449 // stop playing, keep buffers (for pause) |
17566
f580a7755ac5
Patch by Stefan Huehner / stefan % huehner ! org \
rathann
parents:
17058
diff
changeset
|
450 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
|
451 { |
23809
6c348181fb20
Somewhat hackish fix for A-V desync with ao_oss and frame stepping:
reimar
parents:
21547
diff
changeset
|
452 prepause_space = get_space(); |
12145 | 453 uninit(1); |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
1020
diff
changeset
|
454 } |
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
1020
diff
changeset
|
455 |
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
1020
diff
changeset
|
456 // resume playing, after audio_pause() |
17566
f580a7755ac5
Patch by Stefan Huehner / stefan % huehner ! org \
rathann
parents:
17058
diff
changeset
|
457 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
|
458 { |
23809
6c348181fb20
Somewhat hackish fix for A-V desync with ao_oss and frame stepping:
reimar
parents:
21547
diff
changeset
|
459 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
|
460 reset(); |
23809
6c348181fb20
Somewhat hackish fix for A-V desync with ao_oss and frame stepping:
reimar
parents:
21547
diff
changeset
|
461 fillcnt = get_space() - prepause_space; |
6c348181fb20
Somewhat hackish fix for A-V desync with ao_oss and frame stepping:
reimar
parents:
21547
diff
changeset
|
462 if (fillcnt > 0) { |
6c348181fb20
Somewhat hackish fix for A-V desync with ao_oss and frame stepping:
reimar
parents:
21547
diff
changeset
|
463 void *silence = calloc(fillcnt, 1); |
6c348181fb20
Somewhat hackish fix for A-V desync with ao_oss and frame stepping:
reimar
parents:
21547
diff
changeset
|
464 play(silence, fillcnt, 0); |
6c348181fb20
Somewhat hackish fix for A-V desync with ao_oss and frame stepping:
reimar
parents:
21547
diff
changeset
|
465 free(silence); |
6c348181fb20
Somewhat hackish fix for A-V desync with ao_oss and frame stepping:
reimar
parents:
21547
diff
changeset
|
466 } |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
1020
diff
changeset
|
467 } |
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
1020
diff
changeset
|
468 |
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
1020
diff
changeset
|
469 |
954 | 470 // return: how many bytes can be played without blocking |
17566
f580a7755ac5
Patch by Stefan Huehner / stefan % huehner ! org \
rathann
parents:
17058
diff
changeset
|
471 static int get_space(void){ |
3095 | 472 int playsize=ao_data.outburst; |
954 | 473 |
1020
72cacd3b8f30
Solaris 8 support - patch by Marcus Comstedt <marcus@idonex.se>
arpi_esp
parents:
956
diff
changeset
|
474 #ifdef SNDCTL_DSP_GETOSPACE |
954 | 475 if(ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &zz)!=-1){ |
476 // calculate exact buffer space: | |
3455
921a78c7b4aa
limit get_space return <= MAX_OUTBURST, whilst always an exact number of fragments
steve
parents:
3319
diff
changeset
|
477 playsize = zz.fragments*zz.fragsize; |
921a78c7b4aa
limit get_space return <= MAX_OUTBURST, whilst always an exact number of fragments
steve
parents:
3319
diff
changeset
|
478 if (playsize > MAX_OUTBURST) |
921a78c7b4aa
limit get_space return <= MAX_OUTBURST, whilst always an exact number of fragments
steve
parents:
3319
diff
changeset
|
479 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
|
480 return playsize; |
954 | 481 } |
1020
72cacd3b8f30
Solaris 8 support - patch by Marcus Comstedt <marcus@idonex.se>
arpi_esp
parents:
956
diff
changeset
|
482 #endif |
954 | 483 |
484 // check buffer | |
485 #ifdef HAVE_AUDIO_SELECT | |
486 { fd_set rfds; | |
487 struct timeval tv; | |
488 FD_ZERO(&rfds); | |
489 FD_SET(audio_fd, &rfds); | |
490 tv.tv_sec = 0; | |
491 tv.tv_usec = 0; | |
492 if(!select(audio_fd+1, NULL, &rfds, NULL, &tv)) return 0; // not block! | |
493 } | |
494 #endif | |
495 | |
3095 | 496 return ao_data.outburst; |
954 | 497 } |
498 | |
499 // plays 'len' bytes of 'data' | |
500 // it should round it down to outburst*n | |
501 // return: number of bytes played | |
502 static int play(void* data,int len,int flags){ | |
18842 | 503 if(len==0) |
504 return len; | |
505 if(len>ao_data.outburst || !(flags & AOPLAY_FINAL_CHUNK)) { | |
506 len/=ao_data.outburst; | |
507 len*=ao_data.outburst; | |
508 } | |
509 len=write(audio_fd,data,len); | |
954 | 510 return len; |
511 } | |
512 | |
513 static int audio_delay_method=2; | |
514 | |
3095 | 515 // 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
|
516 static float get_delay(void){ |
3095 | 517 /* Calculate how many bytes/second is sent out */ |
954 | 518 if(audio_delay_method==2){ |
5872 | 519 #ifdef SNDCTL_DSP_GETODELAY |
954 | 520 int r=0; |
521 if(ioctl(audio_fd, SNDCTL_DSP_GETODELAY, &r)!=-1) | |
3095 | 522 return ((float)r)/(float)ao_data.bps; |
5872 | 523 #endif |
954 | 524 audio_delay_method=1; // fallback if not supported |
525 } | |
526 if(audio_delay_method==1){ | |
527 // SNDCTL_DSP_GETOSPACE | |
528 if(ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &zz)!=-1) | |
3095 | 529 return ((float)(ao_data.buffersize-zz.bytes))/(float)ao_data.bps; |
954 | 530 audio_delay_method=0; // fallback if not supported |
531 } | |
3095 | 532 return ((float)ao_data.buffersize)/(float)ao_data.bps; |
954 | 533 } |