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 }