libsent/src/adin/adin_mic_freebsd.c

説明を見る。
00001 
00044 /*
00045  * Copyright (c) 1991-2006 Kawahara Lab., Kyoto University
00046  * Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology
00047  * Copyright (c) 2005-2006 Julius project team, Nagoya Institute of Technology
00048  * All rights reserved
00049  */
00050 
00051 /* Thanks to Kentaro Nagatomo for information */
00052 /* All functions are the same as OSS version, except the header filename */
00053 
00054 #include <sent/stddefs.h>
00055 #include <sent/adin.h>
00056 
00057 #include <sys/ioctl.h>
00058 #include <sys/types.h>
00059 #include <sys/stat.h>
00060 #include <fcntl.h>
00061 #include <poll.h>
00062 
00063 /* sound header */
00064 #include <machine/soundcard.h>
00065 
00067 #define DEFAULT_DEVICE "/dev/dsp"
00068 
00069 static int audio_fd;            
00070 static boolean need_swap;       
00071 struct pollfd fds[1];           
00072 
00073 #define FREQALLOWRANGE 200      
00074 #define POLLINTERVAL 200        
00075 
00076 
00084 boolean
00085 adin_mic_standby(int sfreq, void *arg)
00086 {
00087   int fmt, fmt_can, fmt1, fmt2, rfmt; /* sampling format */
00088   int samplerate;               /* actual sampling rate */
00089   int stereo;           /* mono */
00090   char *defaultdev = DEFAULT_DEVICE; /* default device */
00091   char *devname;
00092 
00093   /* set device name */
00094   if ((devname = getenv("AUDIODEV")) == NULL) {
00095     devname = defaultdev;
00096   }
00097   
00098   /* open device */
00099   if ((audio_fd = open(devname, O_RDONLY)) == -1) {
00100     perror("adin_mic_standby: open");
00101     return(FALSE);
00102   }
00103 
00104   /* check whether soundcard can record 16bit data */
00105   /* and set fmt */
00106   if (ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &fmt_can) == -1) {
00107     perror("adin_mic_standby: sndctl_dsp_getfmts");
00108     return(FALSE);
00109   }
00110 #ifdef WORDS_BIGENDIAN
00111   fmt1 = AFMT_S16_BE;
00112   fmt2 = AFMT_S16_LE;
00113 #else
00114   fmt1 = AFMT_S16_LE;               /* 16bit signed (little endian) */
00115   fmt2 = AFMT_S16_BE;               /* (big endian) */
00116 #endif /* WORDS_BIGENDIAN */
00117   /* fmt2 needs byte swap */
00118   if (fmt_can & fmt1) {
00119     fmt = fmt1;
00120     need_swap = FALSE;
00121   } else if (fmt_can & fmt2) {
00122     fmt = fmt2;
00123     need_swap = TRUE;
00124   } else {
00125     fprintf(stderr, "adin_mic_standby: 16bit recording not supported\n");
00126     return FALSE;
00127   }
00128 #ifdef DEBUG
00129   if (need_swap) {
00130     j_printf("samples need swap\n");
00131   } else {
00132     j_printf("samples need not swap\n");
00133   }
00134 #endif
00135   
00136   if (close(audio_fd) != 0) return FALSE;
00137 
00138   /* re-open for recording */
00139   /* open device */
00140   if ((audio_fd = open(devname, O_RDONLY)) == -1) {
00141     perror("adin_mic_standby: open");
00142     return(FALSE);
00143   }
00144   /* set format, samplerate, channels */
00145   rfmt = fmt;
00146   if (ioctl(audio_fd, SNDCTL_DSP_SETFMT, &rfmt) == -1) {
00147     perror("adin_mic_standby: sndctl_dsp_setfmt");
00148     return(FALSE);
00149   }
00150   if (rfmt != fmt) {
00151     fprintf(stderr, "adin_mic_standby: 16bit recording not supported\n");
00152     return FALSE;
00153   }
00154 
00155   stereo = 0;                   /* mono */
00156   if (ioctl(audio_fd, SNDCTL_DSP_STEREO, &stereo) == -1) {
00157     perror("adin_mic_standby: sndctl_dsp_stereo (mono)");
00158     return(FALSE);
00159   }
00160   if (stereo != 0) {
00161     fprintf(stderr,"adin_mic_standby: monoral recording not supported\n");
00162     return FALSE;
00163   }
00164 
00165   samplerate = sfreq;
00166   if (ioctl(audio_fd, SNDCTL_DSP_SPEED, &samplerate) == -1) {
00167     fprintf(stderr, "adin_mic_standby: sndctl_dsp_speed (%dHz)\n", sfreq);
00168     return(FALSE);
00169   }
00170   if (samplerate < sfreq - FREQALLOWRANGE || samplerate > sfreq + FREQALLOWRANGE) {
00171     fprintf(stderr,"adin_mic_standby: couldn't set sampling rate to near %dHz. (%d)\n", sfreq, samplerate);
00172     return FALSE;
00173   }
00174   if (samplerate != sfreq) {
00175     fprintf(stderr,"adin_mic_standby: set sampling rate to %dHz\n", samplerate);
00176   }
00177 
00178   /* set polling status */
00179   fds[0].fd = audio_fd;
00180   fds[0].events = POLLIN;
00181   
00182   return TRUE;
00183 }
00184  
00190 boolean
00191 adin_mic_start()
00192 {
00193   char buf[2];
00194 
00195   /* Read 1 sample (and ignore it) to tell the audio device start recording.
00196      (If you knows better way, teach me...) */
00197   read(audio_fd, buf, 2);
00198   return(TRUE);
00199 }
00200 
00206 boolean
00207 adin_mic_stop()
00208 {
00209   /*
00210    * Not reset device on each end of speech, just let the buffer overrun...
00211    * Resetting and restarting of recording device sometimes causes
00212    * hawling noises at the next recording.
00213    * I don't now why, so take the easy way... :-(
00214    */
00215   return TRUE;
00216 }
00217 
00230 int
00231 adin_mic_read(SP16 *buf, int sampnum)
00232 {
00233   int size,cnt;
00234   audio_buf_info info;
00235 
00236   /* wait till at least one sample can be read */
00237   poll(fds, 1, POLLINTERVAL);
00238   /* get actual sample num in the device buffer */
00239   if (ioctl(audio_fd, SNDCTL_DSP_GETISPACE, &info) == -1) {
00240     perror("adin_mic_read: sndctl_dsp_getispace");
00241     return(-2);
00242   }
00243   
00244   /* get them as much as possible */
00245   size = sampnum * sizeof(SP16);
00246   if (size > info.bytes) size = info.bytes;
00247   cnt = read(audio_fd, buf, size);
00248   if ( cnt < 0 ) {
00249     perror("adin_mic_read: read error\n");
00250     return ( -2 );
00251   }
00252   cnt /= sizeof(short);
00253   if (need_swap) swap_sample_bytes(buf, cnt);
00254   return(cnt);
00255 }

Juliusに対してTue Dec 26 16:19:28 2006に生成されました。  doxygen 1.5.0