00001
00056
00057
00058
00059
00060
00061
00062
00063 #include <sent/stddefs.h>
00064 #include <sent/adin.h>
00065
00066 #include <sys/ioctl.h>
00067 #include <sys/types.h>
00068 #include <sys/stat.h>
00069 #include <sys/time.h>
00070 #include <fcntl.h>
00071
00072
00073 #include <sys/soundcard.h>
00074
00076 #define DEFAULT_DEVICE "/dev/dsp"
00077
00078 #define FREQALLOWRANGE 200
00079 #define MAXPOLLINTERVAL 300
00080
00086 #define FRAGMENT_POWER 10
00087
00088 static int audio_fd;
00089 static boolean need_swap;
00090 static int frag_size;
00091 static boolean stereo_rec;
00092
00101 boolean
00102 adin_mic_standby(int sfreq, void *dummy)
00103 {
00104 int fmt, fmt_can, fmt1, fmt2, rfmt;
00105 int samplerate;
00106 char *defaultdev = DEFAULT_DEVICE;
00107 char *devname;
00108
00109
00110 if ((devname = getenv("AUDIODEV")) == NULL) {
00111 devname = defaultdev;
00112 }
00113
00114
00115 if ((audio_fd = open(devname, O_RDONLY|O_NONBLOCK)) == -1) {
00116 j_printerr("adin_mic_standby: device=%s\n", devname);
00117 perror("adin_mic_standby: open device");
00118 return(FALSE);
00119 }
00120
00121
00122
00123 if (ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &fmt_can) == -1) {
00124 perror("adin_mic_standby: sndctl_dsp_getfmts");
00125 return(FALSE);
00126 }
00127 #ifdef WORDS_BIGENDIAN
00128 fmt1 = AFMT_S16_BE;
00129 fmt2 = AFMT_S16_LE;
00130 #else
00131 fmt1 = AFMT_S16_LE;
00132 fmt2 = AFMT_S16_BE;
00133 #endif
00134
00135 if (fmt_can & fmt1) {
00136 fmt = fmt1;
00137 need_swap = FALSE;
00138 } else if (fmt_can & fmt2) {
00139 fmt = fmt2;
00140 need_swap = TRUE;
00141 } else {
00142 fprintf(stderr, "adin_mic_standby: 16bit recording not supported\n");
00143 return FALSE;
00144 }
00145 #ifdef DEBUG
00146 if (need_swap) {
00147 j_printf("samples need swap\n");
00148 } else {
00149 j_printf("samples need not swap\n");
00150 }
00151 #endif
00152
00153 if (close(audio_fd) != 0) return FALSE;
00154
00155
00156
00157 if ((audio_fd = open(devname, O_RDONLY)) == -1) {
00158 j_printerr("adin_mic_standby: device=%s\n", devname);
00159 perror("adin_mic_standby: open device");
00160 return(FALSE);
00161 }
00162
00163
00164
00165
00166 {
00167 int arg;
00168 arg = 0x7fff0000 | FRAGMENT_POWER;
00169 if (ioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &arg)) {
00170 fprintf(stderr, "adin_mic_standby: set fragment size to 2^%d=%d bytes (%d msec)\n", FRAGMENT_POWER, 2 << (FRAGMENT_POWER-1), (2 << (FRAGMENT_POWER-1)) * 1000 / (sfreq * sizeof(SP16)));
00171 }
00172 }
00173
00174
00175 rfmt = fmt;
00176 if (ioctl(audio_fd, SNDCTL_DSP_SETFMT, &rfmt) == -1) {
00177 perror("adin_mic_standby: sndctl_dsp_setfmt");
00178 return(FALSE);
00179 }
00180 if (rfmt != fmt) {
00181 fprintf(stderr, "adin_mic_standby: 16bit recording not supported\n");
00182 return FALSE;
00183 }
00184
00185 {
00186
00187 int channels;
00188 int stereo;
00189 boolean ok_p = FALSE;
00190
00191 stereo = 0;
00192 if (ioctl(audio_fd, SNDCTL_DSP_STEREO, &stereo) == -1) {
00193
00194 perror("adin_mic_standby: sndctl_dsp_stereo (mono)");
00195 } else {
00196 if (stereo != 0) {
00197
00198 fprintf(stderr, "adin_mic_standby: failed to set monaural recording by SNDCTL_DSP_STEREO\n");
00199 } else {
00200
00201 stereo_rec = FALSE;
00202 ok_p = TRUE;
00203 }
00204 }
00205 if (! ok_p) {
00206
00207 channels = 1;
00208 if (ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &channels) == -1) {
00209
00210 perror("adin_mic_standby: sndctl_dsp_channels (channels = 1)");
00211 } else {
00212 if (channels != 1) {
00213
00214 fprintf(stderr, "adin_mic_standby: failed to set monaural recording by SNDCTL_DSP_CHANNELS\n");
00215 } else {
00216
00217 fprintf(stderr, "adin_mic_standby: SNDCTL_DSP_CHANNELS used for monaural record setting\n");
00218 stereo_rec = FALSE;
00219 ok_p = TRUE;
00220 }
00221 }
00222 }
00223 if (! ok_p) {
00224
00225 fprintf(stderr, "adin_mic_standby: monaural recording failed, use stereo left channel\n");
00226 stereo = 1;
00227 if (ioctl(audio_fd, SNDCTL_DSP_STEREO, &stereo) == -1) {
00228
00229 perror("adin_mic_standby: sndctl_dsp_stereo (stereo)");
00230 } else {
00231 if (stereo != 1) {
00232
00233 fprintf(stderr, "adin_mic_standby: failed to set stereo recording by SNDCTL_DSP_STEREO\n");
00234 } else {
00235
00236 stereo_rec = TRUE;
00237 ok_p = TRUE;
00238 }
00239 }
00240 }
00241 if (! ok_p) {
00242
00243 channels = 2;
00244 if (ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &channels) == -1) {
00245
00246 perror("adin_mic_standby: sndctl_dsp_channels (channels = 2)");
00247 } else {
00248 if (channels != 2) {
00249
00250 fprintf(stderr, "adin_mic_standby: failed to set stereo recording by SNDCTL_DSP_CHANNELS\n");
00251 } else {
00252
00253 fprintf(stderr, "adin_mic_standby: SNDCTL_DSP_CHANNELS used for stereo record setting\n");
00254 stereo_rec = TRUE;
00255 ok_p = TRUE;
00256 }
00257 }
00258 }
00259 if (! ok_p) {
00260 fprintf(stderr,"adin_mic_standby: give up setting record channels\n");
00261 return FALSE;
00262 }
00263 }
00264
00265 samplerate = sfreq;
00266 if (ioctl(audio_fd, SNDCTL_DSP_SPEED, &samplerate) == -1) {
00267 fprintf(stderr, "adin_mic_standby: sndctl_dsp_speed (%dHz)\n", sfreq);
00268 return(FALSE);
00269 }
00270 if (samplerate < sfreq - FREQALLOWRANGE || samplerate > sfreq + FREQALLOWRANGE) {
00271 fprintf(stderr,"adin_mic_standby: couldn't set sampling rate to near %dHz. (%d)\n", sfreq, samplerate);
00272 return FALSE;
00273 }
00274 if (samplerate != sfreq) {
00275 fprintf(stderr,"adin_mic_standby: set sampling rate to %dHz\n", samplerate);
00276 }
00277
00278
00279 if (ioctl(audio_fd, SNDCTL_DSP_GETBLKSIZE, &frag_size) == -1) {
00280 fprintf(stderr, "adin_mic_standby: failed to get fragment size\n");
00281 return(FALSE);
00282 }
00283 j_printf("fragment size = %d bytes (%d msec)", frag_size, frag_size * 1000/ (sfreq * sizeof(SP16)));
00284 if (frag_size != 2 << (FRAGMENT_POWER-1)) {
00285 j_printf(" (tried = %d bytes)", 2 << (FRAGMENT_POWER-1));
00286 }
00287 j_printf("\n");
00288
00289 return TRUE;
00290 }
00291
00297 boolean
00298 adin_mic_start()
00299 {
00300 char buf[4];
00301
00302
00303 if (stereo_rec) {
00304 read(audio_fd, buf, 4);
00305 } else {
00306 read(audio_fd, buf, 2);
00307 }
00308
00309 return(TRUE);
00310 }
00311
00317 boolean
00318 adin_mic_stop()
00319 {
00320
00321
00322
00323
00324
00325
00326 return TRUE;
00327 }
00328
00346 int
00347 adin_mic_read(SP16 *buf, int sampnum)
00348 {
00349 int size,cnt,i;
00350 audio_buf_info info;
00351 fd_set rfds;
00352 struct timeval tv;
00353 int status;
00354
00355
00356
00357
00358
00359 FD_ZERO(&rfds);
00360 FD_SET(audio_fd, &rfds);
00361 tv.tv_sec = 0;
00362 tv.tv_usec = MAXPOLLINTERVAL * 1000;
00363 status = select(audio_fd+1, &rfds, NULL, NULL, &tv);
00364 if (status < 0) {
00365
00366 j_printerr("adin_mic_read: device polling failed\n");
00367 return(-2);
00368 }
00369 if (FD_ISSET(audio_fd, &rfds)) {
00370
00371 if (ioctl(audio_fd, SNDCTL_DSP_GETISPACE, &info) == -1) {
00372 perror("adin_mic_read: sndctl_dsp_getispace");
00373 return(-2);
00374 }
00375
00376 size = sampnum * sizeof(SP16);
00377 if (size > info.bytes) size = info.bytes;
00378 if (size < frag_size) size = frag_size;
00379 size &= ~ 1;
00380 cnt = read(audio_fd, buf, size);
00381 if ( cnt < 0 ) {
00382 perror("adin_mic_read: read error\n");
00383 return ( -2 );
00384 }
00385 cnt /= sizeof(short);
00386
00387 if (stereo_rec) {
00388
00389 for(i=1;i<cnt;i+=2) buf[(i-1)/2]=buf[i];
00390 cnt/=2;
00391 }
00392
00393 if (need_swap) swap_sample_bytes(buf, cnt);
00394 } else {
00395 j_printerr("adin_mic_read: no data fragment after %d msec?\n", MAXPOLLINTERVAL);
00396 cnt = 0;
00397 }
00398
00399 return(cnt);
00400 }