00001 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
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 
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; 
00093   int samplerate;               
00094   int stereo;           
00095   char *defaultdev = DEFAULT_DEVICE; 
00096   char *devname;
00097 
00098   
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   
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   
00113   
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;               
00123   fmt2 = AFMT_S16_BE;               
00124 #endif 
00125   
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   
00147   
00148   if ((audio_fd = open(devname, O_RDONLY)) == -1) {
00149     jlog("Error: adin_freebsd: failed to open %s", devname);
00150     return(FALSE);
00151   }
00152   
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;                   
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   
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 
00214 
00215 
00216 
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   
00240   poll(fds, 1, POLLINTERVAL);
00241   
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   
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 }