sync with en/mplayer.1 rev. 30936
[mplayer/glamo.git] / stream / audio_in.c
blob48e325706a9138cff3f428e7f07fb102ff0709e8
1 /*
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.
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <unistd.h>
23 #include "config.h"
25 #include "audio_in.h"
26 #include "mp_msg.h"
27 #include "help_mp.h"
28 #include <string.h>
29 #include <errno.h>
31 // sanitizes ai structure before calling other functions
32 int audio_in_init(audio_in_t *ai, int type)
34 ai->type = type;
35 ai->setup = 0;
37 ai->channels = -1;
38 ai->samplerate = -1;
39 ai->blocksize = -1;
40 ai->bytes_per_sample = -1;
41 ai->samplesize = -1;
43 switch (ai->type) {
44 #ifdef CONFIG_ALSA
45 case AUDIO_IN_ALSA:
46 ai->alsa.handle = NULL;
47 ai->alsa.log = NULL;
48 ai->alsa.device = strdup("default");
49 return 0;
50 #endif
51 #ifdef CONFIG_OSS_AUDIO
52 case AUDIO_IN_OSS:
53 ai->oss.audio_fd = -1;
54 ai->oss.device = strdup("/dev/dsp");
55 return 0;
56 #endif
57 default:
58 return -1;
62 int audio_in_setup(audio_in_t *ai)
65 switch (ai->type) {
66 #ifdef CONFIG_ALSA
67 case AUDIO_IN_ALSA:
68 if (ai_alsa_init(ai) < 0) return -1;
69 ai->setup = 1;
70 return 0;
71 #endif
72 #ifdef CONFIG_OSS_AUDIO
73 case AUDIO_IN_OSS:
74 if (ai_oss_init(ai) < 0) return -1;
75 ai->setup = 1;
76 return 0;
77 #endif
78 default:
79 return -1;
83 int audio_in_set_samplerate(audio_in_t *ai, int rate)
85 switch (ai->type) {
86 #ifdef CONFIG_ALSA
87 case AUDIO_IN_ALSA:
88 ai->req_samplerate = rate;
89 if (!ai->setup) return 0;
90 if (ai_alsa_setup(ai) < 0) return -1;
91 return ai->samplerate;
92 #endif
93 #ifdef CONFIG_OSS_AUDIO
94 case AUDIO_IN_OSS:
95 ai->req_samplerate = rate;
96 if (!ai->setup) return 0;
97 if (ai_oss_set_samplerate(ai) < 0) return -1;
98 return ai->samplerate;
99 #endif
100 default:
101 return -1;
105 int audio_in_set_channels(audio_in_t *ai, int channels)
107 switch (ai->type) {
108 #ifdef CONFIG_ALSA
109 case AUDIO_IN_ALSA:
110 ai->req_channels = channels;
111 if (!ai->setup) return 0;
112 if (ai_alsa_setup(ai) < 0) return -1;
113 return ai->channels;
114 #endif
115 #ifdef CONFIG_OSS_AUDIO
116 case AUDIO_IN_OSS:
117 ai->req_channels = channels;
118 if (!ai->setup) return 0;
119 if (ai_oss_set_channels(ai) < 0) return -1;
120 return ai->channels;
121 #endif
122 default:
123 return -1;
127 int audio_in_set_device(audio_in_t *ai, char *device)
129 #ifdef CONFIG_ALSA
130 int i;
131 #endif
132 if (ai->setup) return -1;
133 switch (ai->type) {
134 #ifdef CONFIG_ALSA
135 case AUDIO_IN_ALSA:
136 if (ai->alsa.device) free(ai->alsa.device);
137 ai->alsa.device = strdup(device);
138 /* mplayer cannot handle colons in arguments */
139 for (i = 0; i < (int)strlen(ai->alsa.device); i++) {
140 if (ai->alsa.device[i] == '.') ai->alsa.device[i] = ':';
142 return 0;
143 #endif
144 #ifdef CONFIG_OSS_AUDIO
145 case AUDIO_IN_OSS:
146 if (ai->oss.device) free(ai->oss.device);
147 ai->oss.device = strdup(device);
148 return 0;
149 #endif
150 default:
151 return -1;
155 int audio_in_uninit(audio_in_t *ai)
157 if (ai->setup) {
158 switch (ai->type) {
159 #ifdef CONFIG_ALSA
160 case AUDIO_IN_ALSA:
161 if (ai->alsa.log)
162 snd_output_close(ai->alsa.log);
163 if (ai->alsa.handle) {
164 snd_pcm_close(ai->alsa.handle);
166 ai->setup = 0;
167 return 0;
168 #endif
169 #ifdef CONFIG_OSS_AUDIO
170 case AUDIO_IN_OSS:
171 close(ai->oss.audio_fd);
172 ai->setup = 0;
173 return 0;
174 #endif
177 return -1;
180 int audio_in_start_capture(audio_in_t *ai)
182 switch (ai->type) {
183 #ifdef CONFIG_ALSA
184 case AUDIO_IN_ALSA:
185 return snd_pcm_start(ai->alsa.handle);
186 #endif
187 #ifdef CONFIG_OSS_AUDIO
188 case AUDIO_IN_OSS:
189 return 0;
190 #endif
191 default:
192 return -1;
196 int audio_in_read_chunk(audio_in_t *ai, unsigned char *buffer)
198 int ret;
200 switch (ai->type) {
201 #ifdef CONFIG_ALSA
202 case AUDIO_IN_ALSA:
203 ret = snd_pcm_readi(ai->alsa.handle, buffer, ai->alsa.chunk_size);
204 if (ret != ai->alsa.chunk_size) {
205 if (ret < 0) {
206 mp_msg(MSGT_TV, MSGL_ERR, MSGTR_MPDEMUX_AUDIOIN_ErrReadingAudio, snd_strerror(ret));
207 if (ret == -EPIPE) {
208 if (ai_alsa_xrun(ai) == 0) {
209 mp_msg(MSGT_TV, MSGL_ERR, MSGTR_MPDEMUX_AUDIOIN_XRUNSomeFramesMayBeLeftOut);
210 } else {
211 mp_msg(MSGT_TV, MSGL_ERR, MSGTR_MPDEMUX_AUDIOIN_ErrFatalCannotRecover);
214 } else {
215 mp_msg(MSGT_TV, MSGL_ERR, MSGTR_MPDEMUX_AUDIOIN_NotEnoughSamples);
217 return -1;
219 return ret;
220 #endif
221 #ifdef CONFIG_OSS_AUDIO
222 case AUDIO_IN_OSS:
223 ret = read(ai->oss.audio_fd, buffer, ai->blocksize);
224 if (ret != ai->blocksize) {
225 if (ret < 0) {
226 mp_msg(MSGT_TV, MSGL_ERR, MSGTR_MPDEMUX_AUDIOIN_ErrReadingAudio, strerror(errno));
227 } else {
228 mp_msg(MSGT_TV, MSGL_ERR, MSGTR_MPDEMUX_AUDIOIN_NotEnoughSamples);
230 return -1;
232 return ret;
233 #endif
234 default:
235 return -1;