Move setting of O_NONBLOCK before lirc_readconfig, this avoids a memleak
[mplayer/glamo.git] / stream / audio_in.c
blob45b1e9b79d3391b85eadbc7dd823f634df1beb74
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
5 #include "config.h"
7 #include "audio_in.h"
8 #include "mp_msg.h"
9 #include "help_mp.h"
10 #include <string.h>
11 #include <errno.h>
13 // sanitizes ai structure before calling other functions
14 int audio_in_init(audio_in_t *ai, int type)
16 ai->type = type;
17 ai->setup = 0;
19 ai->channels = -1;
20 ai->samplerate = -1;
21 ai->blocksize = -1;
22 ai->bytes_per_sample = -1;
23 ai->samplesize = -1;
25 switch (ai->type) {
26 #ifdef CONFIG_ALSA
27 case AUDIO_IN_ALSA:
28 ai->alsa.handle = NULL;
29 ai->alsa.log = NULL;
30 ai->alsa.device = strdup("default");
31 return 0;
32 #endif
33 #ifdef CONFIG_OSS_AUDIO
34 case AUDIO_IN_OSS:
35 ai->oss.audio_fd = -1;
36 ai->oss.device = strdup("/dev/dsp");
37 return 0;
38 #endif
39 default:
40 return -1;
44 int audio_in_setup(audio_in_t *ai)
47 switch (ai->type) {
48 #ifdef CONFIG_ALSA
49 case AUDIO_IN_ALSA:
50 if (ai_alsa_init(ai) < 0) return -1;
51 ai->setup = 1;
52 return 0;
53 #endif
54 #ifdef CONFIG_OSS_AUDIO
55 case AUDIO_IN_OSS:
56 if (ai_oss_init(ai) < 0) return -1;
57 ai->setup = 1;
58 return 0;
59 #endif
60 default:
61 return -1;
65 int audio_in_set_samplerate(audio_in_t *ai, int rate)
67 switch (ai->type) {
68 #ifdef CONFIG_ALSA
69 case AUDIO_IN_ALSA:
70 ai->req_samplerate = rate;
71 if (!ai->setup) return 0;
72 if (ai_alsa_setup(ai) < 0) return -1;
73 return ai->samplerate;
74 #endif
75 #ifdef CONFIG_OSS_AUDIO
76 case AUDIO_IN_OSS:
77 ai->req_samplerate = rate;
78 if (!ai->setup) return 0;
79 if (ai_oss_set_samplerate(ai) < 0) return -1;
80 return ai->samplerate;
81 #endif
82 default:
83 return -1;
87 int audio_in_set_channels(audio_in_t *ai, int channels)
89 switch (ai->type) {
90 #ifdef CONFIG_ALSA
91 case AUDIO_IN_ALSA:
92 ai->req_channels = channels;
93 if (!ai->setup) return 0;
94 if (ai_alsa_setup(ai) < 0) return -1;
95 return ai->channels;
96 #endif
97 #ifdef CONFIG_OSS_AUDIO
98 case AUDIO_IN_OSS:
99 ai->req_channels = channels;
100 if (!ai->setup) return 0;
101 if (ai_oss_set_channels(ai) < 0) return -1;
102 return ai->channels;
103 #endif
104 default:
105 return -1;
109 int audio_in_set_device(audio_in_t *ai, char *device)
111 #ifdef CONFIG_ALSA
112 int i;
113 #endif
114 if (ai->setup) return -1;
115 switch (ai->type) {
116 #ifdef CONFIG_ALSA
117 case AUDIO_IN_ALSA:
118 if (ai->alsa.device) free(ai->alsa.device);
119 ai->alsa.device = strdup(device);
120 /* mplayer cannot handle colons in arguments */
121 for (i = 0; i < (int)strlen(ai->alsa.device); i++) {
122 if (ai->alsa.device[i] == '.') ai->alsa.device[i] = ':';
124 return 0;
125 #endif
126 #ifdef CONFIG_OSS_AUDIO
127 case AUDIO_IN_OSS:
128 if (ai->oss.device) free(ai->oss.device);
129 ai->oss.device = strdup(device);
130 return 0;
131 #endif
132 default:
133 return -1;
137 int audio_in_uninit(audio_in_t *ai)
139 if (ai->setup) {
140 switch (ai->type) {
141 #ifdef CONFIG_ALSA
142 case AUDIO_IN_ALSA:
143 if (ai->alsa.log)
144 snd_output_close(ai->alsa.log);
145 if (ai->alsa.handle) {
146 snd_pcm_close(ai->alsa.handle);
148 ai->setup = 0;
149 return 0;
150 #endif
151 #ifdef CONFIG_OSS_AUDIO
152 case AUDIO_IN_OSS:
153 close(ai->oss.audio_fd);
154 ai->setup = 0;
155 return 0;
156 #endif
159 return -1;
162 int audio_in_start_capture(audio_in_t *ai)
164 switch (ai->type) {
165 #ifdef CONFIG_ALSA
166 case AUDIO_IN_ALSA:
167 return snd_pcm_start(ai->alsa.handle);
168 #endif
169 #ifdef CONFIG_OSS_AUDIO
170 case AUDIO_IN_OSS:
171 return 0;
172 #endif
173 default:
174 return -1;
178 int audio_in_read_chunk(audio_in_t *ai, unsigned char *buffer)
180 int ret;
182 switch (ai->type) {
183 #ifdef CONFIG_ALSA
184 case AUDIO_IN_ALSA:
185 ret = snd_pcm_readi(ai->alsa.handle, buffer, ai->alsa.chunk_size);
186 if (ret != ai->alsa.chunk_size) {
187 if (ret < 0) {
188 mp_msg(MSGT_TV, MSGL_ERR, MSGTR_MPDEMUX_AUDIOIN_ErrReadingAudio, snd_strerror(ret));
189 if (ret == -EPIPE) {
190 if (ai_alsa_xrun(ai) == 0) {
191 mp_msg(MSGT_TV, MSGL_ERR, MSGTR_MPDEMUX_AUDIOIN_XRUNSomeFramesMayBeLeftOut);
192 } else {
193 mp_msg(MSGT_TV, MSGL_ERR, MSGTR_MPDEMUX_AUDIOIN_ErrFatalCannotRecover);
196 } else {
197 mp_msg(MSGT_TV, MSGL_ERR, MSGTR_MPDEMUX_AUDIOIN_NotEnoughSamples);
199 return -1;
201 return ret;
202 #endif
203 #ifdef CONFIG_OSS_AUDIO
204 case AUDIO_IN_OSS:
205 ret = read(ai->oss.audio_fd, buffer, ai->blocksize);
206 if (ret != ai->blocksize) {
207 if (ret < 0) {
208 mp_msg(MSGT_TV, MSGL_ERR, MSGTR_MPDEMUX_AUDIOIN_ErrReadingAudio, strerror(errno));
209 } else {
210 mp_msg(MSGT_TV, MSGL_ERR, MSGTR_MPDEMUX_AUDIOIN_NotEnoughSamples);
212 return -1;
214 return ret;
215 #endif
216 default:
217 return -1;