Fix:
[mplayer/glamo.git] / libmpdemux / audio_in.c
blob4a98b006186c2004d4ac7cae3ea94ed5b577ded5
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
5 #include "config.h"
7 #if defined(USE_TV) && (defined(HAVE_TV_V4L) || defined(HAVE_TV_V4L2))
9 #include "audio_in.h"
10 #include "mp_msg.h"
11 #include "help_mp.h"
12 #include <string.h>
13 #include <errno.h>
15 // sanitizes ai structure before calling other functions
16 int audio_in_init(audio_in_t *ai, int type)
18 ai->type = type;
19 ai->setup = 0;
21 ai->channels = -1;
22 ai->samplerate = -1;
23 ai->blocksize = -1;
24 ai->bytes_per_sample = -1;
25 ai->samplesize = -1;
27 switch (ai->type) {
28 #if defined(HAVE_ALSA9) || defined(HAVE_ALSA1X)
29 case AUDIO_IN_ALSA:
30 ai->alsa.handle = NULL;
31 ai->alsa.log = NULL;
32 ai->alsa.device = strdup("default");
33 return 0;
34 #endif
35 #ifdef USE_OSS_AUDIO
36 case AUDIO_IN_OSS:
37 ai->oss.audio_fd = -1;
38 ai->oss.device = strdup("/dev/dsp");
39 return 0;
40 #endif
41 default:
42 return -1;
46 int audio_in_setup(audio_in_t *ai)
49 switch (ai->type) {
50 #if defined(HAVE_ALSA9) || defined(HAVE_ALSA1X)
51 case AUDIO_IN_ALSA:
52 if (ai_alsa_init(ai) < 0) return -1;
53 ai->setup = 1;
54 return 0;
55 #endif
56 #ifdef USE_OSS_AUDIO
57 case AUDIO_IN_OSS:
58 if (ai_oss_init(ai) < 0) return -1;
59 ai->setup = 1;
60 return 0;
61 #endif
62 default:
63 return -1;
67 int audio_in_set_samplerate(audio_in_t *ai, int rate)
69 switch (ai->type) {
70 #if defined(HAVE_ALSA9) || defined(HAVE_ALSA1X)
71 case AUDIO_IN_ALSA:
72 ai->req_samplerate = rate;
73 if (!ai->setup) return 0;
74 if (ai_alsa_setup(ai) < 0) return -1;
75 return ai->samplerate;
76 #endif
77 #ifdef USE_OSS_AUDIO
78 case AUDIO_IN_OSS:
79 ai->req_samplerate = rate;
80 if (!ai->setup) return 0;
81 if (ai_oss_set_samplerate(ai) < 0) return -1;
82 return ai->samplerate;
83 #endif
84 default:
85 return -1;
89 int audio_in_set_channels(audio_in_t *ai, int channels)
91 switch (ai->type) {
92 #if defined(HAVE_ALSA9) || defined(HAVE_ALSA1X)
93 case AUDIO_IN_ALSA:
94 ai->req_channels = channels;
95 if (!ai->setup) return 0;
96 if (ai_alsa_setup(ai) < 0) return -1;
97 return ai->channels;
98 #endif
99 #ifdef USE_OSS_AUDIO
100 case AUDIO_IN_OSS:
101 ai->req_channels = channels;
102 if (!ai->setup) return 0;
103 if (ai_oss_set_channels(ai) < 0) return -1;
104 return ai->channels;
105 #endif
106 default:
107 return -1;
111 int audio_in_set_device(audio_in_t *ai, char *device)
113 #if defined(HAVE_ALSA9) || defined(HAVE_ALSA1X)
114 int i;
115 #endif
116 if (ai->setup) return -1;
117 switch (ai->type) {
118 #if defined(HAVE_ALSA9) || defined(HAVE_ALSA1X)
119 case AUDIO_IN_ALSA:
120 if (ai->alsa.device) free(ai->alsa.device);
121 ai->alsa.device = strdup(device);
122 /* mplayer cannot handle colons in arguments */
123 for (i = 0; i < (int)strlen(ai->alsa.device); i++) {
124 if (ai->alsa.device[i] == '.') ai->alsa.device[i] = ':';
126 return 0;
127 #endif
128 #ifdef USE_OSS_AUDIO
129 case AUDIO_IN_OSS:
130 if (ai->oss.device) free(ai->oss.device);
131 ai->oss.device = strdup(device);
132 return 0;
133 #endif
134 default:
135 return -1;
139 int audio_in_uninit(audio_in_t *ai)
141 if (ai->setup) {
142 switch (ai->type) {
143 #if defined(HAVE_ALSA9) || defined(HAVE_ALSA1X)
144 case AUDIO_IN_ALSA:
145 if (ai->alsa.log)
146 snd_output_close(ai->alsa.log);
147 if (ai->alsa.handle) {
148 snd_pcm_close(ai->alsa.handle);
150 ai->setup = 0;
151 return 0;
152 #endif
153 #ifdef USE_OSS_AUDIO
154 case AUDIO_IN_OSS:
155 close(ai->oss.audio_fd);
156 ai->setup = 0;
157 return 0;
158 #endif
161 return -1;
164 int audio_in_start_capture(audio_in_t *ai)
166 switch (ai->type) {
167 #if defined(HAVE_ALSA9) || defined(HAVE_ALSA1X)
168 case AUDIO_IN_ALSA:
169 return snd_pcm_start(ai->alsa.handle);
170 #endif
171 #ifdef USE_OSS_AUDIO
172 case AUDIO_IN_OSS:
173 return 0;
174 #endif
175 default:
176 return -1;
180 int audio_in_read_chunk(audio_in_t *ai, unsigned char *buffer)
182 int ret;
184 switch (ai->type) {
185 #if defined(HAVE_ALSA9) || defined(HAVE_ALSA1X)
186 case AUDIO_IN_ALSA:
187 ret = snd_pcm_readi(ai->alsa.handle, buffer, ai->alsa.chunk_size);
188 if (ret != ai->alsa.chunk_size) {
189 if (ret < 0) {
190 mp_msg(MSGT_TV, MSGL_ERR, MSGTR_MPDEMUX_AUDIOIN_ErrReadingAudio, snd_strerror(ret));
191 if (ret == -EPIPE) {
192 if (ai_alsa_xrun(ai) == 0) {
193 mp_msg(MSGT_TV, MSGL_ERR, MSGTR_MPDEMUX_AUDIOIN_XRUNSomeFramesMayBeLeftOut);
194 } else {
195 mp_msg(MSGT_TV, MSGL_ERR, MSGTR_MPDEMUX_AUDIOIN_ErrFatalCannotRecover);
198 } else {
199 mp_msg(MSGT_TV, MSGL_ERR, MSGTR_MPDEMUX_AUDIOIN_NotEnoughSamples);
201 return -1;
203 return ret;
204 #endif
205 #ifdef USE_OSS_AUDIO
206 case AUDIO_IN_OSS:
207 ret = read(ai->oss.audio_fd, buffer, ai->blocksize);
208 if (ret != ai->blocksize) {
209 if (ret < 0) {
210 mp_msg(MSGT_TV, MSGL_ERR, MSGTR_MPDEMUX_AUDIOIN_ErrReadingAudio, strerror(errno));
211 } else {
212 mp_msg(MSGT_TV, MSGL_ERR, MSGTR_MPDEMUX_AUDIOIN_NotEnoughSamples);
214 return -1;
216 return ret;
217 #endif
218 default:
219 return -1;
223 #endif