int32 ad_stop_play (ad_play_t *p) { int32 i, st; LPWAVEHDR whdr; if ((! p->opened) || (! p->playing)) return -1; #if 0 whdr->dwUser = (plen <= 0) ? 1 : 0; #endif /* Wait for all buffers to be emptied and unprepare them */ for (i = 0; i < N_WO_BUF; i++) { whdr = p->wo_buf[i].p_whdr; while (p->busy[i] && (! (whdr->dwFlags & WHDR_DONE))) Sleep(100); st = waveOutUnprepareHeader(p->h_waveout, whdr, sizeof(WAVEHDR)); if (st != 0) { waveout_error("waveOutUnprepareHeader", st); return -1; } p->busy[i] = 0; } return 0; }
static HWAVEOUT waveout_open (int32 samples_per_sec, int32 bytes_per_sample) { WAVEFORMATEX wfmt; int32 st; HWAVEOUT h; if (bytes_per_sample != sizeof(int16)) { fprintf(stderr, "bytes/sample != %d\n", sizeof(int16)); return NULL; } wfmt.wFormatTag = WAVE_FORMAT_PCM; wfmt.nChannels = 1; wfmt.nSamplesPerSec = samples_per_sec; wfmt.nAvgBytesPerSec = samples_per_sec * bytes_per_sample; wfmt.nBlockAlign = bytes_per_sample; wfmt.wBitsPerSample = 8 * bytes_per_sample; wfmt.cbSize = 0; /* There should be a check here for a device of the desired type; later... */ st = waveOutOpen ((LPHWAVEOUT) &h, WAVE_MAPPER, (LPWAVEFORMATEX) &wfmt, (DWORD) 0L, 0L, (DWORD) CALLBACK_NULL); if (st != 0) { waveout_error("waveOutOpen", st); return NULL; } return h; }
static int32 waveout_enqueue_buf (HWAVEOUT h, LPWAVEHDR whdr) { int32 st; if ((st = waveOutPrepareHeader (h, whdr, sizeof(WAVEHDR))) != 0) { waveout_error("waveOutPrepareHeader", st); return -1; } if ((st = waveOutWrite (h, whdr, sizeof(WAVEHDR))) != 0) { waveout_error("waveOutWrite", st); return -1; } return 0; }
static int waveout_write(const char *buffer, int count) { int written = 0; int len, rc; count = FRAME_SIZE_ALIGN(count); clean_buffers(); while (count > 0) { WAVEHDR *hdr = &buffers[buffer_idx]; if (hdr->dwFlags != 0) { /* no free buffers */ break; } len = FRAME_SIZE_ALIGN( min(count, buffer_size) ); hdr->dwBufferLength = len; memcpy(hdr->lpData, buffer + written, len); if ((rc = waveOutPrepareHeader(wave_out, hdr, sizeof(WAVEHDR))) != MMSYSERR_NOERROR) { waveout_error("waveOutPrepareHeader", rc); break; } if ((rc = waveOutWrite(wave_out, hdr, sizeof(WAVEHDR))) != MMSYSERR_NOERROR) { waveOutUnprepareHeader(wave_out, hdr, sizeof(WAVEHDR)); hdr->dwFlags = 0; waveout_error("waveOutWrite", rc); break; } written += len; count -= len; buffer_idx = (buffer_idx + 1) % buffer_count; buffers_free--; } return written; }
static int32 waveout_close (ad_play_t *p) { int32 st; waveout_mem_cleanup (p, N_WO_BUF); if ((st = waveOutClose (p->h_waveout)) != 0) { waveout_error("waveOutClose", st); return -1; } free (p); return 0; }
static int waveout_close(void) { int rc; waveOutReset(wave_out); clean_buffers(); if ((rc = waveOutClose(wave_out)) != MMSYSERR_NOERROR) { waveout_error("waveOutClose", rc); return -1; } wave_out = NULL; return 0; }
int32 ad_write(ad_play_t * p, int16 * buf, int32 size) { int32 i, k, len, st; LPWAVEHDR whdr; if ((!p->opened) || (!p->playing)) return -1; len = 0; for (i = 0; (i < N_WO_BUF) && (size > 0); i++) { whdr = p->wo_buf[p->nxtbuf].p_whdr; if (p->busy[p->nxtbuf]) { if (!(whdr->dwFlags & WHDR_DONE)) return len; st = waveOutUnprepareHeader(p->h_waveout, whdr, sizeof(WAVEHDR)); if (st != 0) { waveout_error("waveOutUnprepareHeader", st); return -1; } p->busy[p->nxtbuf] = 0; } k = (size > WO_BUFSIZE) ? WO_BUFSIZE : size; whdr->dwBufferLength = k * sizeof(int16); memcpy(whdr->lpData, (LPSTR) buf, k * sizeof(int16)); if (waveout_enqueue_buf(p->h_waveout, whdr) < 0) return -1; buf += k; size -= k; len += k; p->busy[(p->nxtbuf)++] = 1; if (p->nxtbuf >= N_WO_BUF) p->nxtbuf = 0; } return len; }