libsent/src/adin/adin_mic_freebsd.c

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

Generated on Tue Dec 18 15:59:54 2007 for Julius by  doxygen 1.5.4