Mercurial > mplayer.hg
annotate libao2/ao_oss.c @ 13249:a6642a4330fa
ensure that avi files have a valid header as soon as possible.
without this, the header says 0x0 video size, which works with mplayer
when the video size is stored in the codec data, but it does NOT work
with other players or with codecs that don't store size (e.g. snow).
actually i don't like having seeks in the muxer module, but i don't
know any other way to implement this fix without major changes to
mencoder. if you have a better fix, please reverse this and commit
yours.
author | rfelker |
---|---|
date | Sun, 05 Sep 2004 16:51:15 +0000 |
parents | 94ba609e53f7 |
children | c1955840883d |
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> |
1532 | 12 //#include <sys/soundcard.h> |
954 | 13 |
14 #include "../config.h" | |
6296 | 15 #include "../mp_msg.h" |
4788
d678ce495a75
Moved HW dependent mixer stuff to libao and removed master switch
anders
parents:
4184
diff
changeset
|
16 #include "../mixer.h" |
954 | 17 |
1532 | 18 #include "afmt.h" |
19 | |
954 | 20 #include "audio_out.h" |
21 #include "audio_out_internal.h" | |
22 | |
23 static ao_info_t info = | |
24 { | |
25 "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
|
26 "oss", |
954 | 27 "A'rpi", |
28 "" | |
29 }; | |
30 | |
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
|
31 /* 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
|
32 |
954 | 33 LIBAO_EXTERN(oss) |
34 | |
4803 | 35 static char *dsp=PATH_DEV_DSP; |
1020
72cacd3b8f30
Solaris 8 support - patch by Marcus Comstedt <marcus@idonex.se>
arpi_esp
parents:
956
diff
changeset
|
36 static audio_buf_info zz; |
954 | 37 static int audio_fd=-1; |
38 | |
4803 | 39 char *oss_mixer_device = PATH_DEV_MIXER; |
11837 | 40 int oss_mixer_channel = SOUND_MIXER_PCM; |
1191 | 41 |
954 | 42 // to set/get/query special features/parameters |
9633
12b1790038b0
64bit libao2 fix by Jens Axboe <mplayer-dev@kernel.dk>
alex
parents:
9141
diff
changeset
|
43 static int control(int cmd,void *arg){ |
954 | 44 switch(cmd){ |
45 case AOCONTROL_SET_DEVICE: | |
46 dsp=(char*)arg; | |
47 return CONTROL_OK; | |
6795 | 48 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
|
49 *(char**)arg=dsp; |
6795 | 50 return CONTROL_OK; |
954 | 51 case AOCONTROL_QUERY_FORMAT: |
52 return CONTROL_TRUE; | |
1191 | 53 case AOCONTROL_GET_VOLUME: |
54 case AOCONTROL_SET_VOLUME: | |
55 { | |
56 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
|
57 int fd, v, devs; |
1528
a444bd456fcc
ac3/spdif patch by German Gomez Garcia <german@piraos.com>
arpi
parents:
1456
diff
changeset
|
58 |
3095 | 59 if(ao_data.format == AFMT_AC3) |
1528
a444bd456fcc
ac3/spdif patch by German Gomez Garcia <german@piraos.com>
arpi
parents:
1456
diff
changeset
|
60 return CONTROL_TRUE; |
1191 | 61 |
4788
d678ce495a75
Moved HW dependent mixer stuff to libao and removed master switch
anders
parents:
4184
diff
changeset
|
62 if ((fd = open(oss_mixer_device, O_RDONLY)) > 0) |
1191 | 63 { |
64 ioctl(fd, SOUND_MIXER_READ_DEVMASK, &devs); | |
11837 | 65 if (devs & (1 << oss_mixer_channel)) |
4788
d678ce495a75
Moved HW dependent mixer stuff to libao and removed master switch
anders
parents:
4184
diff
changeset
|
66 { |
1191 | 67 if (cmd == AOCONTROL_GET_VOLUME) |
4788
d678ce495a75
Moved HW dependent mixer stuff to libao and removed master switch
anders
parents:
4184
diff
changeset
|
68 { |
11837 | 69 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
|
70 vol->right = (v & 0xFF00) >> 8; |
d678ce495a75
Moved HW dependent mixer stuff to libao and removed master switch
anders
parents:
4184
diff
changeset
|
71 vol->left = v & 0x00FF; |
d678ce495a75
Moved HW dependent mixer stuff to libao and removed master switch
anders
parents:
4184
diff
changeset
|
72 } |
1191 | 73 else |
4788
d678ce495a75
Moved HW dependent mixer stuff to libao and removed master switch
anders
parents:
4184
diff
changeset
|
74 { |
d678ce495a75
Moved HW dependent mixer stuff to libao and removed master switch
anders
parents:
4184
diff
changeset
|
75 v = ((int)vol->right << 8) | (int)vol->left; |
11837 | 76 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
|
77 } |
d678ce495a75
Moved HW dependent mixer stuff to libao and removed master switch
anders
parents:
4184
diff
changeset
|
78 } |
1191 | 79 else |
80 { | |
81 close(fd); | |
82 return CONTROL_ERROR; | |
83 } | |
84 close(fd); | |
85 return CONTROL_OK; | |
86 } | |
87 } | |
88 return CONTROL_ERROR; | |
954 | 89 } |
90 return CONTROL_UNKNOWN; | |
91 } | |
92 | |
93 // open & setup audio device | |
94 // return: 1=success 0=fail | |
95 static int init(int rate,int channels,int format,int flags){ | |
11837 | 96 char *mixer_channels [SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_NAMES; |
954 | 97 |
6296 | 98 mp_msg(MSGT_AO,MSGL_V,"ao2: %d Hz %d chans %s\n",rate,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
|
99 audio_out_format_name(format)); |
954 | 100 |
1191 | 101 if (ao_subdevice) |
102 dsp = ao_subdevice; | |
103 | |
4788
d678ce495a75
Moved HW dependent mixer stuff to libao and removed master switch
anders
parents:
4184
diff
changeset
|
104 if(mixer_device) |
d678ce495a75
Moved HW dependent mixer stuff to libao and removed master switch
anders
parents:
4184
diff
changeset
|
105 oss_mixer_device=mixer_device; |
d678ce495a75
Moved HW dependent mixer stuff to libao and removed master switch
anders
parents:
4184
diff
changeset
|
106 |
11837 | 107 if(mixer_channel){ |
108 int fd, devs, i; | |
109 | |
110 if ((fd = open(oss_mixer_device, O_RDONLY)) == -1){ | |
111 mp_msg(MSGT_AO,MSGL_ERR,"audio_setup: Can't open mixer device %s: %s\n", | |
112 oss_mixer_device, strerror(errno)); | |
113 }else{ | |
114 ioctl(fd, SOUND_MIXER_READ_DEVMASK, &devs); | |
115 close(fd); | |
116 | |
117 for (i=0; i<SOUND_MIXER_NRDEVICES; i++){ | |
118 if(!strcasecmp(mixer_channels[i], mixer_channel)){ | |
119 if(!(devs & (1 << i))){ | |
120 mp_msg(MSGT_AO,MSGL_ERR,"audio_setup: Audio card mixer does not have channel '%s' using default\n", | |
121 mixer_channel); | |
122 i = SOUND_MIXER_NRDEVICES+1; | |
123 break; | |
124 } | |
125 oss_mixer_channel = i; | |
126 break; | |
127 } | |
128 } | |
129 if(i==SOUND_MIXER_NRDEVICES){ | |
130 mp_msg(MSGT_AO,MSGL_ERR,"audio_setup: Can't find mixer channel '%s' using default\n", | |
131 mixer_channel); | |
132 } | |
133 } | |
134 } | |
135 | |
6296 | 136 mp_msg(MSGT_AO,MSGL_V,"audio_setup: using '%s' dsp device\n", dsp); |
11837 | 137 mp_msg(MSGT_AO,MSGL_V,"audio_setup: using '%s' mixer device\n", oss_mixer_device); |
138 mp_msg(MSGT_AO,MSGL_V,"audio_setup: using '%s' mixer device\n", mixer_channels[oss_mixer_channel]); | |
1191 | 139 |
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
|
140 #ifdef __linux__ |
5204
6bbf3271a694
non-blocking open - patch by Fredrik Kuivinen <freku045@student.liu.se>
arpi
parents:
4803
diff
changeset
|
141 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
|
142 #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
|
143 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
|
144 #endif |
954 | 145 if(audio_fd<0){ |
6296 | 146 mp_msg(MSGT_AO,MSGL_ERR,"audio_setup: Can't open audio device %s: %s\n", dsp, strerror(errno)); |
954 | 147 return 0; |
148 } | |
149 | |
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
|
150 #ifdef __linux__ |
5204
6bbf3271a694
non-blocking open - patch by Fredrik Kuivinen <freku045@student.liu.se>
arpi
parents:
4803
diff
changeset
|
151 /* Remove the non-blocking flag */ |
6bbf3271a694
non-blocking open - patch by Fredrik Kuivinen <freku045@student.liu.se>
arpi
parents:
4803
diff
changeset
|
152 if(fcntl(audio_fd, F_SETFL, 0) < 0) { |
8304 | 153 mp_msg(MSGT_AO,MSGL_ERR,"audio_setup: Can't make filedescriptor blocking: %s\n", strerror(errno)); |
5204
6bbf3271a694
non-blocking open - patch by Fredrik Kuivinen <freku045@student.liu.se>
arpi
parents:
4803
diff
changeset
|
154 return 0; |
6bbf3271a694
non-blocking open - patch by Fredrik Kuivinen <freku045@student.liu.se>
arpi
parents:
4803
diff
changeset
|
155 } |
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
|
156 #endif |
8303 | 157 |
158 #if defined(FD_CLOEXEC) && defined(F_SETFD) | |
159 fcntl(audio_fd, F_SETFD, FD_CLOEXEC); | |
160 #endif | |
5204
6bbf3271a694
non-blocking open - patch by Fredrik Kuivinen <freku045@student.liu.se>
arpi
parents:
4803
diff
changeset
|
161 |
4184
f648f699eda6
hwac3 fix for cmedia 8738 by Hans-Peter Raschke <Hans-Peter.Raschke@wintermann-datenservice.de>
arpi
parents:
3455
diff
changeset
|
162 if(format == AFMT_AC3) { |
f648f699eda6
hwac3 fix for cmedia 8738 by Hans-Peter Raschke <Hans-Peter.Raschke@wintermann-datenservice.de>
arpi
parents:
3455
diff
changeset
|
163 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
|
164 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
|
165 } |
5790 | 166 |
167 ac3_retry: | |
3095 | 168 ao_data.format=format; |
5790 | 169 if( ioctl(audio_fd, SNDCTL_DSP_SETFMT, &ao_data.format)<0 || |
170 ao_data.format != format) if(format == AFMT_AC3){ | |
6296 | 171 mp_msg(MSGT_AO,MSGL_WARN,"Can't set audio device %s to AC3 output, trying S16...\n", dsp); |
5790 | 172 #ifdef WORDS_BIGENDIAN |
173 format=AFMT_S16_BE; | |
174 #else | |
175 format=AFMT_S16_LE; | |
176 #endif | |
177 goto ac3_retry; | |
1528
a444bd456fcc
ac3/spdif patch by German Gomez Garcia <german@piraos.com>
arpi
parents:
1456
diff
changeset
|
178 } |
6296 | 179 mp_msg(MSGT_AO,MSGL_V,"audio_setup: sample format: %s (requested: %s)\n", |
3095 | 180 audio_out_format_name(ao_data.format), audio_out_format_name(format)); |
7668 | 181 #if 0 |
6899 | 182 if(ao_data.format!=format) |
183 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 '-aop list=format'\n",audio_out_format_name(format)); | |
7668 | 184 #endif |
954 | 185 |
8848 | 186 ao_data.channels = channels; |
1528
a444bd456fcc
ac3/spdif patch by German Gomez Garcia <german@piraos.com>
arpi
parents:
1456
diff
changeset
|
187 if(format != AFMT_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
|
188 // 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
|
189 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
|
190 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
|
191 ao_data.channels != channels ) { |
6296 | 192 mp_msg(MSGT_AO,MSGL_ERR,"audio_setup: Failed to set audio device to %d channels\n", 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
|
193 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
|
194 } |
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
|
195 } |
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
|
196 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
|
197 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
|
198 if (ioctl (audio_fd, SNDCTL_DSP_STEREO, &c) == -1) { |
6296 | 199 mp_msg(MSGT_AO,MSGL_ERR,"audio_setup: Failed to set audio device to %d channels\n", 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
|
200 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
|
201 } |
9141
20793317e5ff
nice 10l bug, found by Balatoni Denes <pnis@coder.hu>
arpi
parents:
8848
diff
changeset
|
202 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
|
203 } |
6296 | 204 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
|
205 // 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
|
206 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
|
207 ioctl (audio_fd, SNDCTL_DSP_SPEED, &ao_data.samplerate); |
6296 | 208 mp_msg(MSGT_AO,MSGL_V,"audio_setup: using %d Hz samplerate (requested: %d)\n",ao_data.samplerate,rate); |
7668 | 209 #if 0 |
6296 | 210 if(ao_data.samplerate!=rate) |
6588
12826366a806
more informal warning and also fixed a 10l bug. Patch by tibcu
alex
parents:
6296
diff
changeset
|
211 mp_msg(MSGT_AO,MSGL_WARN,"WARNING! Your soundcard does NOT support %d Hz samplerate! A-V sync problems or wrong speed are possible! Try with '-aop list=resample:fout=%d'\n",rate,ao_data.samplerate); |
7668 | 212 #endif |
1528
a444bd456fcc
ac3/spdif patch by German Gomez Garcia <german@piraos.com>
arpi
parents:
1456
diff
changeset
|
213 } |
954 | 214 |
215 if(ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &zz)==-1){ | |
216 int r=0; | |
6296 | 217 mp_msg(MSGT_AO,MSGL_WARN,"audio_setup: driver doesn't support SNDCTL_DSP_GETOSPACE :-(\n"); |
954 | 218 if(ioctl(audio_fd, SNDCTL_DSP_GETBLKSIZE, &r)==-1){ |
6296 | 219 mp_msg(MSGT_AO,MSGL_V,"audio_setup: %d bytes/frag (config.h)\n",ao_data.outburst); |
954 | 220 } else { |
3095 | 221 ao_data.outburst=r; |
6296 | 222 mp_msg(MSGT_AO,MSGL_V,"audio_setup: %d bytes/frag (GETBLKSIZE)\n",ao_data.outburst); |
954 | 223 } |
224 } else { | |
6296 | 225 mp_msg(MSGT_AO,MSGL_V,"audio_setup: frags: %3d/%d (%d bytes/frag) free: %6d\n", |
954 | 226 zz.fragments, zz.fragstotal, zz.fragsize, zz.bytes); |
3095 | 227 if(ao_data.buffersize==-1) ao_data.buffersize=zz.bytes; |
228 ao_data.outburst=zz.fragsize; | |
954 | 229 } |
230 | |
3095 | 231 if(ao_data.buffersize==-1){ |
954 | 232 // Measuring buffer size: |
233 void* data; | |
3095 | 234 ao_data.buffersize=0; |
954 | 235 #ifdef HAVE_AUDIO_SELECT |
3095 | 236 data=malloc(ao_data.outburst); memset(data,0,ao_data.outburst); |
237 while(ao_data.buffersize<0x40000){ | |
954 | 238 fd_set rfds; |
239 struct timeval tv; | |
240 FD_ZERO(&rfds); FD_SET(audio_fd,&rfds); | |
241 tv.tv_sec=0; tv.tv_usec = 0; | |
242 if(!select(audio_fd+1, NULL, &rfds, NULL, &tv)) break; | |
3095 | 243 write(audio_fd,data,ao_data.outburst); |
244 ao_data.buffersize+=ao_data.outburst; | |
954 | 245 } |
246 free(data); | |
3095 | 247 if(ao_data.buffersize==0){ |
6296 | 248 mp_msg(MSGT_AO,MSGL_ERR,"\n *** Your audio driver DOES NOT support select() ***\n" |
249 "Recompile mplayer with #undef HAVE_AUDIO_SELECT in config.h !\n\n"); | |
954 | 250 return 0; |
251 } | |
252 #endif | |
253 } | |
254 | |
8603
30bef3c97b8b
ao_oss was not using the channel & format returned by the soundcard
arpi
parents:
8304
diff
changeset
|
255 ao_data.bps=ao_data.channels; |
30bef3c97b8b
ao_oss was not using the channel & format returned by the soundcard
arpi
parents:
8304
diff
changeset
|
256 if(ao_data.format != AFMT_U8 && ao_data.format != AFMT_S8) |
30bef3c97b8b
ao_oss was not using the channel & format returned by the soundcard
arpi
parents:
8304
diff
changeset
|
257 ao_data.bps*=2; |
30bef3c97b8b
ao_oss was not using the channel & format returned by the soundcard
arpi
parents:
8304
diff
changeset
|
258 |
6075
0b3b6d03779c
fix for L<->R swap with 6ch playback - based on patch by Eric Lammerts <eric@lammerts.org>
arpi
parents:
5907
diff
changeset
|
259 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
|
260 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
|
261 |
954 | 262 return 1; |
263 } | |
264 | |
265 // close audio device | |
12145 | 266 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
|
267 if(audio_fd == -1) return; |
12145 | 268 #ifdef SNDCTL_DSP_SYNC |
269 // to get the buffer played | |
270 if (!immed) | |
271 ioctl(audio_fd, SNDCTL_DSP_SYNC, NULL); | |
272 #endif | |
1020
72cacd3b8f30
Solaris 8 support - patch by Marcus Comstedt <marcus@idonex.se>
arpi_esp
parents:
956
diff
changeset
|
273 #ifdef SNDCTL_DSP_RESET |
12145 | 274 if (immed) |
275 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
|
276 #endif |
954 | 277 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
|
278 audio_fd = -1; |
954 | 279 } |
280 | |
281 // stop playing and empty buffers (for seeking/pause) | |
282 static void reset(){ | |
12145 | 283 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
|
284 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
|
285 if(audio_fd < 0){ |
6296 | 286 mp_msg(MSGT_AO,MSGL_ERR,"\nFatal error: *** CANNOT RE-OPEN / RESET AUDIO DEVICE *** %s\n", strerror(errno)); |
954 | 287 return; |
288 } | |
289 | |
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
|
290 #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
|
291 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
|
292 #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
|
293 |
3095 | 294 ioctl (audio_fd, SNDCTL_DSP_SETFMT, &ao_data.format); |
295 if(ao_data.format != AFMT_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
|
296 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
|
297 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
|
298 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
|
299 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
|
300 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
|
301 } |
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
|
302 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
|
303 } |
954 | 304 } |
305 | |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
1020
diff
changeset
|
306 // stop playing, keep buffers (for pause) |
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
1020
diff
changeset
|
307 static void audio_pause() |
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
1020
diff
changeset
|
308 { |
12145 | 309 uninit(1); |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
1020
diff
changeset
|
310 } |
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
1020
diff
changeset
|
311 |
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
1020
diff
changeset
|
312 // resume playing, after audio_pause() |
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
1020
diff
changeset
|
313 static void audio_resume() |
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
1020
diff
changeset
|
314 { |
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
|
315 reset(); |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
1020
diff
changeset
|
316 } |
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
1020
diff
changeset
|
317 |
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
1020
diff
changeset
|
318 |
954 | 319 // return: how many bytes can be played without blocking |
320 static int get_space(){ | |
3095 | 321 int playsize=ao_data.outburst; |
954 | 322 |
1020
72cacd3b8f30
Solaris 8 support - patch by Marcus Comstedt <marcus@idonex.se>
arpi_esp
parents:
956
diff
changeset
|
323 #ifdef SNDCTL_DSP_GETOSPACE |
954 | 324 if(ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &zz)!=-1){ |
325 // calculate exact buffer space: | |
3455
921a78c7b4aa
limit get_space return <= MAX_OUTBURST, whilst always an exact number of fragments
steve
parents:
3319
diff
changeset
|
326 playsize = zz.fragments*zz.fragsize; |
921a78c7b4aa
limit get_space return <= MAX_OUTBURST, whilst always an exact number of fragments
steve
parents:
3319
diff
changeset
|
327 if (playsize > MAX_OUTBURST) |
921a78c7b4aa
limit get_space return <= MAX_OUTBURST, whilst always an exact number of fragments
steve
parents:
3319
diff
changeset
|
328 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
|
329 return playsize; |
954 | 330 } |
1020
72cacd3b8f30
Solaris 8 support - patch by Marcus Comstedt <marcus@idonex.se>
arpi_esp
parents:
956
diff
changeset
|
331 #endif |
954 | 332 |
333 // check buffer | |
334 #ifdef HAVE_AUDIO_SELECT | |
335 { fd_set rfds; | |
336 struct timeval tv; | |
337 FD_ZERO(&rfds); | |
338 FD_SET(audio_fd, &rfds); | |
339 tv.tv_sec = 0; | |
340 tv.tv_usec = 0; | |
341 if(!select(audio_fd+1, NULL, &rfds, NULL, &tv)) return 0; // not block! | |
342 } | |
343 #endif | |
344 | |
3095 | 345 return ao_data.outburst; |
954 | 346 } |
347 | |
348 // plays 'len' bytes of 'data' | |
349 // it should round it down to outburst*n | |
350 // return: number of bytes played | |
351 static int play(void* data,int len,int flags){ | |
3095 | 352 len/=ao_data.outburst; |
353 len=write(audio_fd,data,len*ao_data.outburst); | |
954 | 354 return len; |
355 } | |
356 | |
357 static int audio_delay_method=2; | |
358 | |
3095 | 359 // return: delay in seconds between first and last sample in buffer |
360 static float get_delay(){ | |
361 /* Calculate how many bytes/second is sent out */ | |
954 | 362 if(audio_delay_method==2){ |
5872 | 363 #ifdef SNDCTL_DSP_GETODELAY |
954 | 364 int r=0; |
365 if(ioctl(audio_fd, SNDCTL_DSP_GETODELAY, &r)!=-1) | |
3095 | 366 return ((float)r)/(float)ao_data.bps; |
5872 | 367 #endif |
954 | 368 audio_delay_method=1; // fallback if not supported |
369 } | |
370 if(audio_delay_method==1){ | |
371 // SNDCTL_DSP_GETOSPACE | |
372 if(ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &zz)!=-1) | |
3095 | 373 return ((float)(ao_data.buffersize-zz.bytes))/(float)ao_data.bps; |
954 | 374 audio_delay_method=0; // fallback if not supported |
375 } | |
3095 | 376 return ((float)ao_data.buffersize)/(float)ao_data.bps; |
954 | 377 } |