2 * This file is part of MPlayer.
4 * MPlayer is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * MPlayer is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 #include <string.h> /* strerror */
27 #include <sys/ioctl.h>
29 #ifdef HAVE_SYS_SOUNDCARD_H
30 #include <sys/soundcard.h>
32 #ifdef HAVE_SOUNDCARD_H
33 #include <soundcard.h>
35 #include <linux/soundcard.h>
42 int ai_oss_set_samplerate(audio_in_t
*ai
)
44 int tmp
= ai
->req_samplerate
;
45 if (ioctl(ai
->oss
.audio_fd
, SNDCTL_DSP_SPEED
, &tmp
) == -1) return -1;
50 int ai_oss_set_channels(audio_in_t
*ai
)
55 if (ai
->req_channels
> 2)
57 ioctl_param
= ai
->req_channels
;
58 mp_msg(MSGT_TV
, MSGL_V
, "ioctl dsp channels: %d\n",
59 err
= ioctl(ai
->oss
.audio_fd
, SNDCTL_DSP_CHANNELS
, &ioctl_param
));
61 mp_tmsg(MSGT_TV
, MSGL_ERR
, "Unable to set channel count: %d\n",
65 ai
->channels
= ioctl_param
;
69 ioctl_param
= (ai
->req_channels
== 2);
70 mp_msg(MSGT_TV
, MSGL_V
, "ioctl dsp stereo: %d (req: %d)\n",
71 err
= ioctl(ai
->oss
.audio_fd
, SNDCTL_DSP_STEREO
, &ioctl_param
),
74 mp_tmsg(MSGT_TV
, MSGL_ERR
, "Unable to set stereo: %d\n",
75 ai
->req_channels
== 2);
78 ai
->channels
= ioctl_param
? 2 : 1;
83 int ai_oss_init(audio_in_t
*ai
)
88 ai
->oss
.audio_fd
= open(ai
->oss
.device
, O_RDONLY
);
89 if (ai
->oss
.audio_fd
< 0)
91 mp_tmsg(MSGT_TV
, MSGL_ERR
, "Unable to open '%s': %s\n",
92 ai
->oss
.device
, strerror(errno
));
97 mp_msg(MSGT_TV
, MSGL_V
, "ioctl dsp getfmt: %d\n",
98 ioctl(ai
->oss
.audio_fd
, SNDCTL_DSP_GETFMTS
, &ioctl_param
));
100 mp_msg(MSGT_TV
, MSGL_V
, "Supported formats: %x\n", ioctl_param
);
101 if (!(ioctl_param
& AFMT_S16_LE
))
102 mp_tmsg(MSGT_TV
, MSGL_ERR
, "unsupported format\n");
104 ioctl_param
= AFMT_S16_LE
;
105 mp_msg(MSGT_TV
, MSGL_V
, "ioctl dsp setfmt: %d\n",
106 err
= ioctl(ai
->oss
.audio_fd
, SNDCTL_DSP_SETFMT
, &ioctl_param
));
108 mp_tmsg(MSGT_TV
, MSGL_ERR
, "Unable to set audio format.");
112 if (ai_oss_set_channels(ai
) < 0) return -1;
114 ioctl_param
= ai
->req_samplerate
;
115 mp_msg(MSGT_TV
, MSGL_V
, "ioctl dsp speed: %d\n",
116 err
= ioctl(ai
->oss
.audio_fd
, SNDCTL_DSP_SPEED
, &ioctl_param
));
118 mp_tmsg(MSGT_TV
, MSGL_ERR
, "Unable to set samplerate: %d\n",
122 ai
->samplerate
= ioctl_param
;
124 mp_msg(MSGT_TV
, MSGL_V
, "ioctl dsp trigger: %d\n",
125 ioctl(ai
->oss
.audio_fd
, SNDCTL_DSP_GETTRIGGER
, &ioctl_param
));
126 mp_msg(MSGT_TV
, MSGL_V
, "trigger: %x\n", ioctl_param
);
127 ioctl_param
= PCM_ENABLE_INPUT
;
128 mp_msg(MSGT_TV
, MSGL_V
, "ioctl dsp trigger: %d\n",
129 err
= ioctl(ai
->oss
.audio_fd
, SNDCTL_DSP_SETTRIGGER
, &ioctl_param
));
131 mp_tmsg(MSGT_TV
, MSGL_ERR
, "Unable to set trigger: %d\n",
136 mp_msg(MSGT_TV
, MSGL_V
, "ioctl dsp getblocksize: %d\n",
137 err
= ioctl(ai
->oss
.audio_fd
, SNDCTL_DSP_GETBLKSIZE
, &ai
->blocksize
));
139 mp_tmsg(MSGT_TV
, MSGL_ERR
, "Unable to get block size!\n");
141 mp_msg(MSGT_TV
, MSGL_V
, "blocksize: %d\n", ai
->blocksize
);
143 // correct the blocksize to a reasonable value
144 if (ai
->blocksize
<= 0) {
145 ai
->blocksize
= 4096*ai
->channels
*2;
146 mp_tmsg(MSGT_TV
, MSGL_ERR
, "Audio block size is zero, setting to %d!\n", ai
->blocksize
);
147 } else if (ai
->blocksize
< 4096*ai
->channels
*2) {
148 ai
->blocksize
*= 4096*ai
->channels
*2/ai
->blocksize
;
149 mp_tmsg(MSGT_TV
, MSGL_ERR
, "Audio block size too low, setting to %d!\n", ai
->blocksize
);
153 ai
->bytes_per_sample
= 2;