00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 #include <windows.h>
00059 #include <mmsystem.h>
00060 #include <stdio.h>
00061 #include <stdlib.h>
00062 #include <string.h>
00063
00064 #include "prim_type.h"
00065 #include "ad.h"
00066
00067
00068 #define DEFAULT_N_WI_BUF 32
00069 #define WI_BUFSIZE 2500
00070
00071
00072
00073 #ifdef _WIN32_WCE
00074 static void
00075 wavein_error(char *src, int32 ret)
00076 {
00077 TCHAR errbuf[512];
00078
00079 waveInGetErrorText(ret, errbuf, sizeof(errbuf));
00080 OutputDebugString(errbuf);
00081 }
00082
00083 #else
00084 static void
00085 wavein_error(char *src, int32 ret)
00086 {
00087 char errbuf[1024];
00088
00089 waveInGetErrorText(ret, errbuf, sizeof(errbuf));
00090 fprintf(stderr, "%s error %d: %s\n", src, ret, errbuf);
00091 }
00092 #endif
00093
00094
00095 static void
00096 wavein_free_buf(ad_wbuf_t * b)
00097 {
00098 GlobalUnlock(b->h_whdr);
00099 GlobalFree(b->h_whdr);
00100 GlobalUnlock(b->h_buf);
00101 GlobalFree(b->h_buf);
00102 }
00103
00104
00105 static int32
00106 wavein_alloc_buf(ad_wbuf_t * b, int32 samples_per_buf)
00107 {
00108 HGLOBAL h_buf;
00109 LPSTR p_buf;
00110 HGLOBAL h_whdr;
00111 LPWAVEHDR p_whdr;
00112
00113
00114 h_buf =
00115 GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE,
00116 samples_per_buf * sizeof(int16));
00117 if (!h_buf) {
00118 fprintf(stderr, "GlobalAlloc failed\n");
00119 return -1;
00120 }
00121 if ((p_buf = GlobalLock(h_buf)) == NULL) {
00122 GlobalFree(h_buf);
00123 fprintf(stderr, "GlobalLock failed\n");
00124 return -1;
00125 }
00126
00127
00128 h_whdr = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, sizeof(WAVEHDR));
00129 if (h_whdr == NULL) {
00130 GlobalUnlock(h_buf);
00131 GlobalFree(h_buf);
00132
00133 fprintf(stderr, "GlobalAlloc failed\n");
00134 return -1;
00135 }
00136 if ((p_whdr = GlobalLock(h_whdr)) == NULL) {
00137 GlobalUnlock(h_buf);
00138 GlobalFree(h_buf);
00139 GlobalFree(h_whdr);
00140
00141 fprintf(stderr, "GlobalLock failed\n");
00142 return -1;
00143 }
00144
00145 b->h_buf = h_buf;
00146 b->p_buf = p_buf;
00147 b->h_whdr = h_whdr;
00148 b->p_whdr = p_whdr;
00149
00150 p_whdr->lpData = p_buf;
00151 p_whdr->dwBufferLength = samples_per_buf * sizeof(int16);
00152 p_whdr->dwUser = 0L;
00153 p_whdr->dwFlags = 0L;
00154 p_whdr->dwLoops = 0L;
00155
00156 return 0;
00157 }
00158
00159
00160 static int32
00161 wavein_enqueue_buf(HWAVEIN h, LPWAVEHDR whdr)
00162 {
00163 int32 st;
00164
00165 if ((st = waveInPrepareHeader(h, whdr, sizeof(WAVEHDR))) != 0) {
00166 wavein_error("waveInPrepareHeader", st);
00167 return -1;
00168 }
00169 if ((st = waveInAddBuffer(h, whdr, sizeof(WAVEHDR))) != 0) {
00170 wavein_error("waveInAddBuffer", st);
00171 return -1;
00172 }
00173
00174 return 0;
00175 }
00176
00177
00178 static HWAVEIN
00179 wavein_open(int32 samples_per_sec, int32 bytes_per_sample)
00180 {
00181 WAVEFORMATEX wfmt;
00182 int32 st;
00183 HWAVEIN h;
00184
00185 if (bytes_per_sample != sizeof(int16)) {
00186 fprintf(stderr, "bytes/sample != %d\n", sizeof(int16));
00187 return NULL;
00188 }
00189
00190 wfmt.wFormatTag = WAVE_FORMAT_PCM;
00191 wfmt.nChannels = 1;
00192 wfmt.nSamplesPerSec = samples_per_sec;
00193 wfmt.nAvgBytesPerSec = samples_per_sec * bytes_per_sample;
00194 wfmt.nBlockAlign = bytes_per_sample;
00195 wfmt.wBitsPerSample = 8 * bytes_per_sample;
00196
00197
00198
00199 st = waveInOpen((LPHWAVEIN) & h, WAVE_MAPPER,
00200 (LPWAVEFORMATEX) & wfmt, (DWORD) 0L, 0L,
00201 (DWORD) CALLBACK_NULL);
00202 if (st != 0) {
00203 wavein_error("waveInOpen", st);
00204 return NULL;
00205 }
00206
00207 return h;
00208 }
00209
00210
00211 static int32
00212 wavein_close(ad_rec_t * r)
00213 {
00214 int32 i, st;
00215
00216
00217 for (i = 0; i < r->n_buf; i++) {
00218
00219
00220
00221 if (!(r->wi_buf[i].p_whdr->dwFlags & WHDR_PREPARED))
00222 continue;
00223 st = waveInUnprepareHeader(r->h_wavein,
00224 r->wi_buf[i].p_whdr, sizeof(WAVEHDR));
00225 if (st != 0) {
00226 wavein_error("waveInUnprepareHeader", st);
00227 return -1;
00228 }
00229 }
00230
00231
00232 for (i = 0; i < r->n_buf; i++)
00233 wavein_free_buf(&(r->wi_buf[i]));
00234 free(r->wi_buf);
00235
00236 if ((st = waveInClose(r->h_wavein)) != 0) {
00237 wavein_error("waveInClose", st);
00238 return -1;
00239 }
00240
00241 free(r);
00242
00243 return 0;
00244 }
00245
00246
00247 ad_rec_t *
00248 ad_open_sps_bufsize(int32 sps, int32 bufsize_msec)
00249 {
00250 ad_rec_t *r;
00251 int32 i, j;
00252 HWAVEIN h;
00253
00254 if ((h = wavein_open(sps, sizeof(int16))) == NULL)
00255 return NULL;
00256
00257 if ((r = (ad_rec_t *) malloc(sizeof(ad_rec_t))) == NULL) {
00258 fprintf(stderr, "malloc(%d) failed\n", sizeof(ad_rec_t));
00259 waveInClose(h);
00260 return NULL;
00261 }
00262
00263 r->n_buf = ((sps * bufsize_msec) / 1000) / WI_BUFSIZE;
00264 if (r->n_buf < DEFAULT_N_WI_BUF)
00265 r->n_buf = DEFAULT_N_WI_BUF;
00266 printf("Allocating %d buffers of %d samples each\n", r->n_buf,
00267 WI_BUFSIZE);
00268
00269 if ((r->wi_buf =
00270 (ad_wbuf_t *) calloc(r->n_buf, sizeof(ad_wbuf_t))) == NULL) {
00271 fprintf(stderr, "calloc(%d,%d) failed\n", r->n_buf,
00272 sizeof(ad_wbuf_t));
00273 free(r);
00274 waveInClose(h);
00275
00276 return NULL;
00277 }
00278 for (i = 0; i < r->n_buf; i++) {
00279 if (wavein_alloc_buf(&(r->wi_buf[i]), WI_BUFSIZE) < 0) {
00280 for (j = 0; j < i; j++)
00281 wavein_free_buf(&(r->wi_buf[j]));
00282 free(r->wi_buf);
00283 free(r);
00284 waveInClose(h);
00285
00286 return NULL;
00287 }
00288 }
00289
00290 r->h_wavein = h;
00291 r->opened = 1;
00292 r->recording = 0;
00293 r->curbuf = r->n_buf - 1;
00294 r->curlen = 0;
00295 r->lastbuf = r->curbuf;
00296 r->sps = sps;
00297 r->bps = sizeof(int16);
00298
00299 return r;
00300 }
00301
00302
00303 ad_rec_t *
00304 ad_open_dev(const char *dev, int32 sps)
00305 {
00306 return (ad_open_sps_bufsize
00307 (sps, WI_BUFSIZE * DEFAULT_N_WI_BUF * 1000 / sps));
00308 }
00309
00310
00311 ad_rec_t *
00312 ad_open_sps(int32 sps)
00313 {
00314 return (ad_open_sps_bufsize
00315 (sps, WI_BUFSIZE * DEFAULT_N_WI_BUF * 1000 / sps));
00316 }
00317
00318
00319 ad_rec_t *
00320 ad_open(void)
00321 {
00322 return (ad_open_sps(DEFAULT_SAMPLES_PER_SEC));
00323 }
00324
00325
00326 int32
00327 ad_close(ad_rec_t * r)
00328 {
00329 if (!r->opened)
00330 return AD_ERR_NOT_OPEN;
00331
00332 if (r->recording)
00333 if (ad_stop_rec(r) < 0)
00334 return AD_ERR_WAVE;
00335
00336 if (wavein_close(r) < 0)
00337 return AD_ERR_WAVE;
00338
00339 return 0;
00340 }
00341
00342
00343 int32
00344 ad_start_rec(ad_rec_t * r)
00345 {
00346 int32 i;
00347
00348 if ((!r->opened) || r->recording)
00349 return -1;
00350
00351 for (i = 0; i < r->n_buf; i++)
00352 if (wavein_enqueue_buf(r->h_wavein, r->wi_buf[i].p_whdr) < 0)
00353 return AD_ERR_WAVE;
00354 r->curbuf = r->n_buf - 1;
00355 r->curlen = 0;
00356
00357 if (waveInStart(r->h_wavein) != 0)
00358 return AD_ERR_WAVE;
00359
00360 r->recording = 1;
00361
00362 return 0;
00363 }
00364
00365
00366 int32
00367 ad_stop_rec(ad_rec_t * r)
00368 {
00369 int32 i, st;
00370
00371 if ((!r->opened) || (!r->recording))
00372 return -1;
00373
00374 if (waveInStop(r->h_wavein) != 0)
00375 return AD_ERR_WAVE;
00376
00377 if ((st = waveInReset(r->h_wavein)) != 0) {
00378 wavein_error("waveInReset", st);
00379 return AD_ERR_WAVE;
00380 }
00381
00382
00383 for (i = 0; i < r->n_buf; i++)
00384 while (!(r->wi_buf[i].p_whdr->dwFlags & WHDR_DONE));
00385
00386 if ((r->lastbuf = r->curbuf - 1) < 0)
00387 r->lastbuf = r->n_buf - 1;
00388
00389 r->recording = 0;
00390
00391 return 0;
00392 }
00393
00394
00395 int32
00396 ad_read(ad_rec_t * r, int16 * buf, int32 max)
00397 {
00398 int32 t, st, len;
00399 LPWAVEHDR whdr;
00400 int16 *sysbufp;
00401
00402 if (!r->opened)
00403 return AD_ERR_NOT_OPEN;
00404
00405
00406 if ((!r->recording) && (r->curbuf == r->lastbuf)
00407 && (r->curlen == 0))
00408 return AD_EOF;
00409
00410 len = 0;
00411 while (max > 0) {
00412
00413 if (r->curlen == 0) {
00414
00415 t = r->curbuf + 1;
00416 if (t >= r->n_buf)
00417 t = 0;
00418
00419 if (!(r->wi_buf[t].p_whdr->dwFlags & WHDR_DONE))
00420 return len;
00421
00422 r->curbuf = t;
00423 r->curlen = r->wi_buf[t].p_whdr->dwBytesRecorded >> 1;
00424 r->curoff = 0;
00425 }
00426
00427
00428 whdr = r->wi_buf[r->curbuf].p_whdr;
00429 t = (max < r->curlen) ? max : r->curlen;
00430
00431 if (t > 0) {
00432 sysbufp = (int16 *) (whdr->lpData);
00433 memcpy(buf, sysbufp + r->curoff, t * sizeof(int16));
00434
00435 buf += t;
00436 max -= t;
00437 r->curoff += t;
00438 r->curlen -= t;
00439 len += t;
00440 }
00441
00442
00443 if (r->curlen == 0) {
00444 if (r->recording) {
00445
00446 st = waveInUnprepareHeader(r->h_wavein,
00447 whdr, sizeof(WAVEHDR));
00448 if (st != 0) {
00449 wavein_error("waveInUnprepareHeader", st);
00450 return AD_ERR_WAVE;
00451 }
00452
00453 if (wavein_enqueue_buf(r->h_wavein, whdr) < 0)
00454 return AD_ERR_WAVE;
00455
00456 }
00457 else if (r->curbuf == r->lastbuf) {
00458 return len;
00459 }
00460 }
00461 }
00462
00463 return len;
00464 }