Julius 4.2
|
00001 00045 /* 00046 * Copyright (c) 1991-2011 Kawahara Lab., Kyoto University 00047 * Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology 00048 * Copyright (c) 2005-2011 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 #if defined(HAVE_SYS_SOUNDCARD_H) 00066 #include <sys/soundcard.h> 00067 #elif defined(HAVE_MACHINE_SOUNDCARD_H) 00068 #include <machine/soundcard.h> 00069 #endif 00070 00072 #define DEFAULT_DEVICE "/dev/dsp" 00073 00074 static int srate; 00075 static int audio_fd; 00076 static boolean need_swap; 00077 struct pollfd fds[1]; 00078 00079 #define FREQALLOWRANGE 200 ///< Acceptable width of sampling frequency 00080 #define POLLINTERVAL 200 ///< Polling interval in miliseconds 00081 00082 static char *defaultdev = DEFAULT_DEVICE; 00083 static char devname[MAXPATHLEN]; 00084 00093 boolean 00094 adin_mic_standby(int sfreq, void *arg) 00095 { 00096 /* store required sampling rate for checking after opening device */ 00097 srate = sfreq; 00098 return TRUE; 00099 } 00100 00108 static boolean 00109 adin_mic_open(char *devstr) 00110 { 00111 int fmt, fmt_can, fmt1, fmt2, rfmt; /* sampling format */ 00112 int samplerate; /* actual sampling rate */ 00113 int stereo; /* mono */ 00114 char *p; 00115 00116 /* open device */ 00117 if ((audio_fd = open(devstr, O_RDONLY)) == -1) { 00118 jlog("Error: adin_freebsd: failed to open %s\n", devstr); 00119 return(FALSE); 00120 } 00121 00122 /* check whether soundcard can record 16bit data */ 00123 /* and set fmt */ 00124 if (ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &fmt_can) == -1) { 00125 jlog("Error: adin_freebsd: failed to get formats from audio device\n"); 00126 return(FALSE); 00127 } 00128 #ifdef WORDS_BIGENDIAN 00129 fmt1 = AFMT_S16_BE; 00130 fmt2 = AFMT_S16_LE; 00131 #else 00132 fmt1 = AFMT_S16_LE; /* 16bit signed (little endian) */ 00133 fmt2 = AFMT_S16_BE; /* (big endian) */ 00134 #endif /* WORDS_BIGENDIAN */ 00135 /* fmt2 needs byte swap */ 00136 if (fmt_can & fmt1) { 00137 fmt = fmt1; 00138 need_swap = FALSE; 00139 } else if (fmt_can & fmt2) { 00140 fmt = fmt2; 00141 need_swap = TRUE; 00142 } else { 00143 jlog("Error: adin_freebsd: 16bit recording not supported on this device\n"); 00144 return FALSE; 00145 } 00146 #ifdef DEBUG 00147 if (need_swap) { 00148 jlog("Stat: adin_freebsd: samples need swap\n"); 00149 } else { 00150 jlog("Stat: adin_freebsd: samples need not swap\n"); 00151 } 00152 #endif 00153 00154 if (close(audio_fd) != 0) return FALSE; 00155 00156 /* re-open for recording */ 00157 /* open device */ 00158 if ((audio_fd = open(devstr, O_RDONLY)) == -1) { 00159 jlog("Error: adin_freebsd: failed to open %s", devstr); 00160 return(FALSE); 00161 } 00162 /* set format, samplerate, channels */ 00163 rfmt = fmt; 00164 if (ioctl(audio_fd, SNDCTL_DSP_SETFMT, &rfmt) == -1) { 00165 jlog("Error: adin_freebsd: failed to get available formats from device\n"); 00166 return(FALSE); 00167 } 00168 if (rfmt != fmt) { 00169 jlog("Error: adin_freebsd: 16bit recording is not supported on this device\n"); 00170 return FALSE; 00171 } 00172 00173 stereo = 0; /* mono */ 00174 if (ioctl(audio_fd, SNDCTL_DSP_STEREO, &stereo) == -1) { 00175 jlog("Error: adin_freebsd: failed to set monoral recording\n"); 00176 return(FALSE); 00177 } 00178 if (stereo != 0) { 00179 jlog("Error: adin_freebsd: monoral recording not supported on this device\n"); 00180 return FALSE; 00181 } 00182 00183 samplerate = srate; 00184 if (ioctl(audio_fd, SNDCTL_DSP_SPEED, &samplerate) == -1) { 00185 jlog("Erorr: adin_freebsd: failed to set sample rate to %dHz\n", srate); 00186 return(FALSE); 00187 } 00188 if (samplerate < srate - FREQALLOWRANGE || samplerate > srate + FREQALLOWRANGE) { 00189 jlog("Error: adin_freebsd: failed to set sampling rate to near %dHz. (%d)\n", srate, samplerate); 00190 return FALSE; 00191 } 00192 if (samplerate != srate) { 00193 jlog("Warning: adin_freebsd: specified sampling rate was %dHz but set to %dHz, \n", srate, samplerate); 00194 } 00195 00196 /* set polling status */ 00197 fds[0].fd = audio_fd; 00198 fds[0].events = POLLIN; 00199 00200 return TRUE; 00201 } 00202 00203 00211 boolean 00212 adin_mic_begin(char *pathname) 00213 { 00214 /* set device name */ 00215 if (pathname != NULL) { 00216 strncpy(devname, pathname, MAXPATHLEN); 00217 jlog("Stat: adin_freebsd: device name = %s (from argument)\n", devname); 00218 } else if ((p = getenv("AUDIODEV")) != NULL) { 00219 strncpy(devname, p, MAXPATHLEN); 00220 jlog("Stat: adin_freebsd: device name = %s (from AUDIODEV)\n", devname); 00221 } else { 00222 strncpy(devname, defaultdev, MAXPATHLEN); 00223 jlog("Stat: adin_freebsd: device name = %s (application default)\n", devname); 00224 } 00225 00226 /* open the device */ 00227 return(adin_mic_open(devname)); 00228 } 00229 00235 boolean 00236 adin_mic_end() 00237 { 00238 if (close(audio_fd) != 0) return FALSE; 00239 return TRUE; 00240 } 00241 00254 int 00255 adin_mic_read(SP16 *buf, int sampnum) 00256 { 00257 int size,cnt; 00258 audio_buf_info info; 00259 00260 /* wait till at least one sample can be read */ 00261 poll(fds, 1, POLLINTERVAL); 00262 /* get actual sample num in the device buffer */ 00263 if (ioctl(audio_fd, SNDCTL_DSP_GETISPACE, &info) == -1) { 00264 jlog("Error: adin_freebsd: adin_mic_read: sndctl_dsp_getispace"); 00265 return(-2); 00266 } 00267 00268 /* get them as much as possible */ 00269 size = sampnum * sizeof(SP16); 00270 if (size > info.bytes) size = info.bytes; 00271 cnt = read(audio_fd, buf, size); 00272 if ( cnt < 0 ) { 00273 jlog("Error: adin_freebsd: adin_mic_read: read error\n"); 00274 return ( -2 ); 00275 } 00276 cnt /= sizeof(short); 00277 if (need_swap) swap_sample_bytes(buf, cnt); 00278 return(cnt); 00279 } 00280 00288 char * 00289 adin_mic_input_name() 00290 { 00291 return(devname); 00292 }