diff options
author | Miller Puckette <millerpuckette@users.sourceforge.net> | 2004-09-06 20:20:36 +0000 |
---|---|---|
committer | Miller Puckette <millerpuckette@users.sourceforge.net> | 2004-09-06 20:20:36 +0000 |
commit | ed932acb5860bf8b9296169676499562a55d139e (patch) | |
tree | dc6a40dba908deb07c175cd40ee19c197318f72d /pd/src/s_audio_mmio.c | |
parent | dad636821f6e7d3ead02c157f308c0ceeba9af3d (diff) |
checking in version 0.38test5.
Oops, I realize I forgot some more nice files, will add them and re-commit.
svn path=/trunk/; revision=2010
Diffstat (limited to 'pd/src/s_audio_mmio.c')
-rw-r--r-- | pd/src/s_audio_mmio.c | 723 |
1 files changed, 363 insertions, 360 deletions
diff --git a/pd/src/s_audio_mmio.c b/pd/src/s_audio_mmio.c index 03fcaf69..30aa4d1c 100644 --- a/pd/src/s_audio_mmio.c +++ b/pd/src/s_audio_mmio.c @@ -30,7 +30,7 @@ int nt_realdacblksize; #define DEFREALDACBLKSIZE (4 * DEFDACBLKSIZE) /* larger underlying bufsize */ #define MAXBUFFER 100 /* number of buffers in use at maximum advance */ -#define DEFBUFFER 30 /* default is about 30x6 = 180 msec! */ +#define DEFBUFFER 30 /* default is about 30x6 = 180 msec! */ static int nt_naudiobuffer = DEFBUFFER; float sys_dacsr = DEFAULTSRATE; @@ -38,7 +38,7 @@ static int nt_whichapi = API_MMIO; static int nt_meters; /* true if we're metering */ static float nt_inmax; /* max input amplitude */ static float nt_outmax; /* max output amplitude */ -static int nt_nwavein, nt_nwaveout; /* number of WAVE devices in and out */ +static int nt_nwavein, nt_nwaveout; /* number of WAVE devices in and out */ typedef struct _sbuf { @@ -49,12 +49,12 @@ typedef struct _sbuf } t_sbuf; t_sbuf ntsnd_outvec[NAPORTS][MAXBUFFER]; /* circular buffer array */ -HWAVEOUT ntsnd_outdev[NAPORTS]; /* output device */ -static int ntsnd_outphase[NAPORTS]; /* index of next buffer to send */ +HWAVEOUT ntsnd_outdev[NAPORTS]; /* output device */ +static int ntsnd_outphase[NAPORTS]; /* index of next buffer to send */ -t_sbuf ntsnd_invec[NAPORTS][MAXBUFFER]; /* circular buffer array */ -HWAVEIN ntsnd_indev[NAPORTS]; /* input device */ -static int ntsnd_inphase[NAPORTS]; /* index of next buffer to read */ +t_sbuf ntsnd_invec[NAPORTS][MAXBUFFER]; /* circular buffer array */ +HWAVEIN ntsnd_indev[NAPORTS]; /* input device */ +static int ntsnd_inphase[NAPORTS]; /* index of next buffer to read */ static void nt_waveinerror(char *s, int err) { @@ -70,7 +70,7 @@ static void nt_waveouterror(char *s, int err) fprintf(stderr, s, t); } -static void wave_prep(t_sbuf *bp) +static void wave_prep(t_sbuf *bp, int setdone) { WAVEHDR *wh; short *sp; @@ -82,27 +82,27 @@ static void wave_prep(t_sbuf *bp) */ if (!(bp->hData = - GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, - (DWORD) (CHANNELS_PER_DEVICE * SAMPSIZE * nt_realdacblksize)))) - printf("alloc 1 failed\n"); + GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, + (DWORD) (CHANNELS_PER_DEVICE * SAMPSIZE * nt_realdacblksize)))) + printf("alloc 1 failed\n"); if (!(bp->lpData = - (HPSTR) GlobalLock(bp->hData))) - printf("lock 1 failed\n"); + (HPSTR) GlobalLock(bp->hData))) + printf("lock 1 failed\n"); /* Allocate and lock memory for the header. */ if (!(bp->hWaveHdr = - GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, (DWORD) sizeof(WAVEHDR)))) - printf("alloc 2 failed\n"); + GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, (DWORD) sizeof(WAVEHDR)))) + printf("alloc 2 failed\n"); if (!(wh = bp->lpWaveHdr = - (WAVEHDR *) GlobalLock(bp->hWaveHdr))) - printf("lock 2 failed\n"); + (WAVEHDR *) GlobalLock(bp->hWaveHdr))) + printf("lock 2 failed\n"); for (i = CHANNELS_PER_DEVICE * nt_realdacblksize, - sp = (short *)bp->lpData; i--; ) - *sp++ = 0; + sp = (short *)bp->lpData; i--; ) + *sp++ = 0; wh->lpData = bp->lpData; wh->dwBufferLength = (CHANNELS_PER_DEVICE * SAMPSIZE * nt_realdacblksize); @@ -110,6 +110,9 @@ static void wave_prep(t_sbuf *bp) wh->dwLoops = 0L; wh->lpNext = 0; wh->reserved = 0; + /* optionally (for writing) set DONE flag as if we had queued them */ + if (setdone) + wh->dwFlags = WHDR_DONE; } static UINT nt_whichdac = WAVE_MAPPER, nt_whichadc = WAVE_MAPPER; @@ -122,8 +125,8 @@ int mmio_do_open_audio(void) int nad, nda; static int naudioprepped = 0, nindevsprepped = 0, noutdevsprepped = 0; if (sys_verbose) - post("%d devices in, %d devices out", - nt_nwavein, nt_nwaveout); + post("%d devices in, %d devices out", + nt_nwavein, nt_nwaveout); form.wf.wFormatTag = WAVE_FORMAT_PCM; form.wf.nChannels = CHANNELS_PER_DEVICE; @@ -133,84 +136,84 @@ int mmio_do_open_audio(void) form.wBitsPerSample = 8 * SAMPSIZE; if (nt_nwavein <= 1 && nt_nwaveout <= 1) - nt_noresync(); + nt_noresync(); if (nindevsprepped < nt_nwavein) { - for (i = nindevsprepped; i < nt_nwavein; i++) - for (j = 0; j < nt_naudiobuffer; j++) - wave_prep(&ntsnd_invec[i][j]); - nindevsprepped = nt_nwavein; + for (i = nindevsprepped; i < nt_nwavein; i++) + for (j = 0; j < naudioprepped; j++) + wave_prep(&ntsnd_invec[i][j], 0); + nindevsprepped = nt_nwavein; } if (noutdevsprepped < nt_nwaveout) { - for (i = noutdevsprepped; i < nt_nwaveout; i++) - for (j = 0; j < nt_naudiobuffer; j++) - wave_prep(&ntsnd_outvec[i][j]); - noutdevsprepped = nt_nwaveout; + for (i = noutdevsprepped; i < nt_nwaveout; i++) + for (j = 0; j < naudioprepped; j++) + wave_prep(&ntsnd_outvec[i][j], 1); + noutdevsprepped = nt_nwaveout; } if (naudioprepped < nt_naudiobuffer) { - for (j = naudioprepped; j < nt_naudiobuffer; j++) - { - for (i = 0; i < nt_nwavein; i++) - wave_prep(&ntsnd_invec[i][j]); - for (i = 0; i < nt_nwaveout; i++) - wave_prep(&ntsnd_outvec[i][j]); - } - naudioprepped = nt_naudiobuffer; + for (j = naudioprepped; j < nt_naudiobuffer; j++) + { + for (i = 0; i < nt_nwavein; i++) + wave_prep(&ntsnd_invec[i][j], 0); + for (i = 0; i < nt_nwaveout; i++) + wave_prep(&ntsnd_outvec[i][j], 1); + } + naudioprepped = nt_naudiobuffer; } for (nad=0; nad < nt_nwavein; nad++) { - /* Open waveform device(s), sucessively numbered, for input */ - - mmresult = waveInOpen(&ntsnd_indev[nad], nt_whichadc+nad, - (WAVEFORMATEX *)(&form), 0L, 0L, CALLBACK_NULL); - - if (sys_verbose) - printf("opened adc device %d with return %d\n", - nt_whichadc+nad,mmresult); - - if (mmresult != MMSYSERR_NOERROR) - { - nt_waveinerror("waveInOpen: %s\n", mmresult); - nt_nwavein = nad; /* nt_nwavein = 0 wini */ - } - else - { - for (i = 0; i < nt_naudiobuffer; i++) - { - mmresult = waveInPrepareHeader(ntsnd_indev[nad], - ntsnd_invec[nad][i].lpWaveHdr, sizeof(WAVEHDR)); - if (mmresult != MMSYSERR_NOERROR) - nt_waveinerror("waveinprepareheader: %s\n", mmresult); - mmresult = waveInAddBuffer(ntsnd_indev[nad], - ntsnd_invec[nad][i].lpWaveHdr, sizeof(WAVEHDR)); - if (mmresult != MMSYSERR_NOERROR) - nt_waveinerror("waveInAddBuffer: %s\n", mmresult); - } - } + /* Open waveform device(s), sucessively numbered, for input */ + + mmresult = waveInOpen(&ntsnd_indev[nad], nt_whichadc+nad, + (WAVEFORMATEX *)(&form), 0L, 0L, CALLBACK_NULL); + + if (sys_verbose) + printf("opened adc device %d with return %d\n", + nt_whichadc+nad,mmresult); + + if (mmresult != MMSYSERR_NOERROR) + { + nt_waveinerror("waveInOpen: %s\n", mmresult); + nt_nwavein = nad; /* nt_nwavein = 0 wini */ + } + else + { + for (i = 0; i < nt_naudiobuffer; i++) + { + mmresult = waveInPrepareHeader(ntsnd_indev[nad], + ntsnd_invec[nad][i].lpWaveHdr, sizeof(WAVEHDR)); + if (mmresult != MMSYSERR_NOERROR) + nt_waveinerror("waveinprepareheader: %s\n", mmresult); + mmresult = waveInAddBuffer(ntsnd_indev[nad], + ntsnd_invec[nad][i].lpWaveHdr, sizeof(WAVEHDR)); + if (mmresult != MMSYSERR_NOERROR) + nt_waveinerror("waveInAddBuffer: %s\n", mmresult); + } + } } - /* quickly start them all together */ + /* quickly start them all together */ for (nad = 0; nad < nt_nwavein; nad++) - waveInStart(ntsnd_indev[nad]); + waveInStart(ntsnd_indev[nad]); for (nda = 0; nda < nt_nwaveout; nda++) - { - /* Open a waveform device for output in sucessiv device numbering*/ - mmresult = waveOutOpen(&ntsnd_outdev[nda], nt_whichdac + nda, - (WAVEFORMATEX *)(&form), 0L, 0L, CALLBACK_NULL); - - if (sys_verbose) - fprintf(stderr,"opened dac device %d, with return %d\n", - nt_whichdac +nda, mmresult); - - if (mmresult != MMSYSERR_NOERROR) - { - fprintf(stderr,"Wave out open device %d + %d\n",nt_whichdac,nda); + { + /* Open a waveform device for output in sucessiv device numbering*/ + mmresult = waveOutOpen(&ntsnd_outdev[nda], nt_whichdac + nda, + (WAVEFORMATEX *)(&form), 0L, 0L, CALLBACK_NULL); + + if (sys_verbose) + fprintf(stderr,"opened dac device %d, with return %d\n", + nt_whichdac +nda, mmresult); + + if (mmresult != MMSYSERR_NOERROR) + { + fprintf(stderr,"Wave out open device %d + %d\n",nt_whichdac,nda); nt_waveouterror("waveOutOpen device: %s\n", mmresult); nt_nwaveout = nda; - } + } } return (0); @@ -221,33 +224,33 @@ void mmio_close_audio( void) int errcode; int nda, nad; if (sys_verbose) - post("closing audio..."); + post("closing audio..."); for (nda=0; nda < nt_nwaveout; nda++) /*if (nt_nwaveout) wini */ { errcode = waveOutReset(ntsnd_outdev[nda]); if (errcode != MMSYSERR_NOERROR) - printf("error resetting output %d: %d\n", nda, errcode); + printf("error resetting output %d: %d\n", nda, errcode); errcode = waveOutClose(ntsnd_outdev[nda]); if (errcode != MMSYSERR_NOERROR) - printf("error closing output %d: %d\n",nda , errcode); + printf("error closing output %d: %d\n",nda , errcode); } nt_nwaveout = 0; for(nad=0; nad < nt_nwavein;nad++) /* if (nt_nwavein) wini */ { - errcode = waveInReset(ntsnd_indev[nad]); - if (errcode != MMSYSERR_NOERROR) - printf("error resetting input: %d\n", errcode); - errcode = waveInClose(ntsnd_indev[nad]); - if (errcode != MMSYSERR_NOERROR) - printf("error closing input: %d\n", errcode); + errcode = waveInReset(ntsnd_indev[nad]); + if (errcode != MMSYSERR_NOERROR) + printf("error resetting input: %d\n", errcode); + errcode = waveInClose(ntsnd_indev[nad]); + if (errcode != MMSYSERR_NOERROR) + printf("error closing input: %d\n", errcode); } nt_nwavein = 0; } -#define ADCJITTER 10 /* We tolerate X buffers of jitter by default */ +#define ADCJITTER 10 /* We tolerate X buffers of jitter by default */ #define DACJITTER 10 static int nt_adcjitterbufsallowed = ADCJITTER; @@ -277,25 +280,25 @@ static void nt_midisync(void) if (initsystime == -1) nt_resetmidisync(); jittersec = (nt_dacjitterbufsallowed > nt_adcjitterbufsallowed ? - nt_dacjitterbufsallowed : nt_adcjitterbufsallowed) - * nt_realdacblksize / sys_getsr(); + nt_dacjitterbufsallowed : nt_adcjitterbufsallowed) + * nt_realdacblksize / sys_getsr(); diff = sys_getrealtime() - 0.001 * clock_gettimesince(initsystime); if (diff > nt_hibuftime) nt_hibuftime = diff; if (diff < nt_hibuftime - jittersec) { - post("jitter excess %d %f", dac, diff); - nt_resetmidisync(); + post("jitter excess %d %f", dac, diff); + nt_resetmidisync(); } } static double nt_midigettimefor(LARGE_INTEGER timestamp) { /* this is broken now... used to work when "timestamp" was derived from - QueryPerformanceCounter() instead of the gates approved - timeGetSystemTime() call in the MIDI callback routine below. */ + QueryPerformanceCounter() instead of the gates approved + timeGetSystemTime() call in the MIDI callback routine below. */ return (nt_tixtotime(timestamp) - nt_hibuftime); } -#endif /* MIDI_TIMESTAMP */ +#endif /* MIDI_TIMESTAMP */ static int nt_fill = 0; @@ -303,87 +306,87 @@ static int nt_fill = 0; #define WRAPBACK(x) ((x) < 0 ? (x) + nt_naudiobuffer: (x)) #define MAXRESYNC 500 -#if 0 /* this is used for debugging */ +#if 0 /* this is used for debugging */ static void nt_printaudiostatus(void) { int nad, nda; for (nad = 0; nad < nt_nwavein; nad++) { - int phase = ntsnd_inphase[nad]; - int phase2 = phase, phase3 = WRAPFWD(phase2), count, ntrans = 0; - int firstphasedone = -1, firstphasebusy = -1; - for (count = 0; count < nt_naudiobuffer; count++) - { - int donethis = - (ntsnd_invec[nad][phase2].lpWaveHdr->dwFlags & WHDR_DONE); - int donenext = - (ntsnd_invec[nad][phase3].lpWaveHdr->dwFlags & WHDR_DONE); - if (donethis && !donenext) - { - if (firstphasebusy >= 0) goto multipleadc; - firstphasebusy = count; - } - if (!donethis && donenext) - { - if (firstphasedone >= 0) goto multipleadc; - firstphasedone = count; - } - phase2 = phase3; - phase3 = WRAPFWD(phase2 + 1); - } - post("nad %d phase %d busy %d done %d", nad, phase, firstphasebusy, - firstphasedone); - continue; + int phase = ntsnd_inphase[nad]; + int phase2 = phase, phase3 = WRAPFWD(phase2), count, ntrans = 0; + int firstphasedone = -1, firstphasebusy = -1; + for (count = 0; count < nt_naudiobuffer; count++) + { + int donethis = + (ntsnd_invec[nad][phase2].lpWaveHdr->dwFlags & WHDR_DONE); + int donenext = + (ntsnd_invec[nad][phase3].lpWaveHdr->dwFlags & WHDR_DONE); + if (donethis && !donenext) + { + if (firstphasebusy >= 0) goto multipleadc; + firstphasebusy = count; + } + if (!donethis && donenext) + { + if (firstphasedone >= 0) goto multipleadc; + firstphasedone = count; + } + phase2 = phase3; + phase3 = WRAPFWD(phase2 + 1); + } + post("nad %d phase %d busy %d done %d", nad, phase, firstphasebusy, + firstphasedone); + continue; multipleadc: - startpost("nad %d phase %d: oops:", nad, phase); - for (count = 0; count < nt_naudiobuffer; count++) - { - char buf[80]; - sprintf(buf, " %d", - (ntsnd_invec[nad][count].lpWaveHdr->dwFlags & WHDR_DONE)); - poststring(buf); - } - endpost(); + startpost("nad %d phase %d: oops:", nad, phase); + for (count = 0; count < nt_naudiobuffer; count++) + { + char buf[80]; + sprintf(buf, " %d", + (ntsnd_invec[nad][count].lpWaveHdr->dwFlags & WHDR_DONE)); + poststring(buf); + } + endpost(); } for (nda = 0; nda < nt_nwaveout; nda++) { - int phase = ntsnd_outphase[nad]; - int phase2 = phase, phase3 = WRAPFWD(phase2), count, ntrans = 0; - int firstphasedone = -1, firstphasebusy = -1; - for (count = 0; count < nt_naudiobuffer; count++) - { - int donethis = - (ntsnd_outvec[nda][phase2].lpWaveHdr->dwFlags & WHDR_DONE); - int donenext = - (ntsnd_outvec[nda][phase3].lpWaveHdr->dwFlags & WHDR_DONE); - if (donethis && !donenext) - { - if (firstphasebusy >= 0) goto multipledac; - firstphasebusy = count; - } - if (!donethis && donenext) - { - if (firstphasedone >= 0) goto multipledac; - firstphasedone = count; - } - phase2 = phase3; - phase3 = WRAPFWD(phase2 + 1); - } - if (firstphasebusy < 0) post("nda %d phase %d all %d", - nda, phase, (ntsnd_outvec[nad][0].lpWaveHdr->dwFlags & WHDR_DONE)); - else post("nda %d phase %d busy %d done %d", nda, phase, firstphasebusy, - firstphasedone); - continue; + int phase = ntsnd_outphase[nad]; + int phase2 = phase, phase3 = WRAPFWD(phase2), count, ntrans = 0; + int firstphasedone = -1, firstphasebusy = -1; + for (count = 0; count < nt_naudiobuffer; count++) + { + int donethis = + (ntsnd_outvec[nda][phase2].lpWaveHdr->dwFlags & WHDR_DONE); + int donenext = + (ntsnd_outvec[nda][phase3].lpWaveHdr->dwFlags & WHDR_DONE); + if (donethis && !donenext) + { + if (firstphasebusy >= 0) goto multipledac; + firstphasebusy = count; + } + if (!donethis && donenext) + { + if (firstphasedone >= 0) goto multipledac; + firstphasedone = count; + } + phase2 = phase3; + phase3 = WRAPFWD(phase2 + 1); + } + if (firstphasebusy < 0) post("nda %d phase %d all %d", + nda, phase, (ntsnd_outvec[nad][0].lpWaveHdr->dwFlags & WHDR_DONE)); + else post("nda %d phase %d busy %d done %d", nda, phase, firstphasebusy, + firstphasedone); + continue; multipledac: - startpost("nda %d phase %d: oops:", nda, phase); - for (count = 0; count < nt_naudiobuffer; count++) - { - char buf[80]; - sprintf(buf, " %d", - (ntsnd_outvec[nad][count].lpWaveHdr->dwFlags & WHDR_DONE)); - poststring(buf); - } - endpost(); + startpost("nda %d phase %d: oops:", nda, phase); + for (count = 0; count < nt_naudiobuffer; count++) + { + char buf[80]; + sprintf(buf, " %d", + (ntsnd_outvec[nad][count].lpWaveHdr->dwFlags & WHDR_DONE)); + poststring(buf); + } + endpost(); } } #endif /* 0 */ @@ -403,54 +406,54 @@ static void nt_resyncaudio(void) UINT mmresult; int nad, nda, count; if (nt_resync_cancelled) - return; - /* for each open input device, eat all buffers which are marked - ready. The next one will thus be "busy". */ + return; + /* for each open input device, eat all buffers which are marked + ready. The next one will thus be "busy". */ post("resyncing audio"); for (nad = 0; nad < nt_nwavein; nad++) { - int phase = ntsnd_inphase[nad]; - for (count = 0; count < MAXRESYNC; count++) - { - WAVEHDR *inwavehdr = ntsnd_invec[nad][phase].lpWaveHdr; - if (!(inwavehdr->dwFlags & WHDR_DONE)) break; - if (inwavehdr->dwFlags & WHDR_PREPARED) - waveInUnprepareHeader(ntsnd_indev[nad], - inwavehdr, sizeof(WAVEHDR)); - inwavehdr->dwFlags = 0L; - waveInPrepareHeader(ntsnd_indev[nad], inwavehdr, sizeof(WAVEHDR)); - mmresult = waveInAddBuffer(ntsnd_indev[nad], inwavehdr, - sizeof(WAVEHDR)); - if (mmresult != MMSYSERR_NOERROR) - nt_waveinerror("waveInAddBuffer: %s\n", mmresult); - ntsnd_inphase[nad] = phase = WRAPFWD(phase + 1); - } - if (count == MAXRESYNC) post("resync error 1"); + int phase = ntsnd_inphase[nad]; + for (count = 0; count < MAXRESYNC; count++) + { + WAVEHDR *inwavehdr = ntsnd_invec[nad][phase].lpWaveHdr; + if (!(inwavehdr->dwFlags & WHDR_DONE)) break; + if (inwavehdr->dwFlags & WHDR_PREPARED) + waveInUnprepareHeader(ntsnd_indev[nad], + inwavehdr, sizeof(WAVEHDR)); + inwavehdr->dwFlags = 0L; + waveInPrepareHeader(ntsnd_indev[nad], inwavehdr, sizeof(WAVEHDR)); + mmresult = waveInAddBuffer(ntsnd_indev[nad], inwavehdr, + sizeof(WAVEHDR)); + if (mmresult != MMSYSERR_NOERROR) + nt_waveinerror("waveInAddBuffer: %s\n", mmresult); + ntsnd_inphase[nad] = phase = WRAPFWD(phase + 1); + } + if (count == MAXRESYNC) post("resync error 1"); } - /* Each output buffer which is "ready" is filled with zeros and - queued. */ + /* Each output buffer which is "ready" is filled with zeros and + queued. */ for (nda = 0; nda < nt_nwaveout; nda++) { - int phase = ntsnd_outphase[nda]; - for (count = 0; count < MAXRESYNC; count++) - { - WAVEHDR *outwavehdr = ntsnd_outvec[nda][phase].lpWaveHdr; - if (!(outwavehdr->dwFlags & WHDR_DONE)) break; - if (outwavehdr->dwFlags & WHDR_PREPARED) - waveOutUnprepareHeader(ntsnd_outdev[nda], - outwavehdr, sizeof(WAVEHDR)); - outwavehdr->dwFlags = 0L; - memset((char *)(ntsnd_outvec[nda][phase].lpData), - 0, (CHANNELS_PER_DEVICE * SAMPSIZE * nt_realdacblksize)); - waveOutPrepareHeader(ntsnd_outdev[nda], outwavehdr, - sizeof(WAVEHDR)); - mmresult = waveOutWrite(ntsnd_outdev[nda], outwavehdr, - sizeof(WAVEHDR)); - if (mmresult != MMSYSERR_NOERROR) - nt_waveouterror("waveOutAddBuffer: %s\n", mmresult); - ntsnd_outphase[nda] = phase = WRAPFWD(phase + 1); - } - if (count == MAXRESYNC) post("resync error 2"); + int phase = ntsnd_outphase[nda]; + for (count = 0; count < MAXRESYNC; count++) + { + WAVEHDR *outwavehdr = ntsnd_outvec[nda][phase].lpWaveHdr; + if (!(outwavehdr->dwFlags & WHDR_DONE)) break; + if (outwavehdr->dwFlags & WHDR_PREPARED) + waveOutUnprepareHeader(ntsnd_outdev[nda], + outwavehdr, sizeof(WAVEHDR)); + outwavehdr->dwFlags = 0L; + memset((char *)(ntsnd_outvec[nda][phase].lpData), + 0, (CHANNELS_PER_DEVICE * SAMPSIZE * nt_realdacblksize)); + waveOutPrepareHeader(ntsnd_outdev[nda], outwavehdr, + sizeof(WAVEHDR)); + mmresult = waveOutWrite(ntsnd_outdev[nda], outwavehdr, + sizeof(WAVEHDR)); + if (mmresult != MMSYSERR_NOERROR) + nt_waveouterror("waveOutAddBuffer: %s\n", mmresult); + ntsnd_outphase[nda] = phase = WRAPFWD(phase + 1); + } + if (count == MAXRESYNC) post("resync error 2"); } #ifdef MIDI_TIMESTAMP @@ -474,11 +477,11 @@ void nt_logerror(int which) if (which == RESYNC) nt_resynccount++; if (sys_getrealtime() > nt_nextreporttime) { - post("%d audio I/O error%s", nt_errorcount, - (nt_errorcount > 1 ? "s" : "")); - if (nt_resynccount) post("DAC/ADC sync error"); - nt_errorcount = nt_resynccount = 0; - nt_nextreporttime = sys_getrealtime() - 5; + post("%d audio I/O error%s", nt_errorcount, + (nt_errorcount > 1 ? "s" : "")); + if (nt_resynccount) post("DAC/ADC sync error"); + nt_errorcount = nt_resynccount = 0; + nt_nextreporttime = sys_getrealtime() - 5; } #endif } @@ -523,126 +526,126 @@ int mmio_send_dacs(void) nt_outmax = maxsamp; } - /* the "fill pointer" nt_fill controls where in the next - I/O buffers we will write and/or read. If it's zero, we - first check whether the buffers are marked "done". */ + /* the "fill pointer" nt_fill controls where in the next + I/O buffers we will write and/or read. If it's zero, we + first check whether the buffers are marked "done". */ if (!nt_fill) { - for (nad = 0; nad < nt_nwavein; nad++) - { - int phase = ntsnd_inphase[nad]; - WAVEHDR *inwavehdr = ntsnd_invec[nad][phase].lpWaveHdr; - if (!(inwavehdr->dwFlags & WHDR_DONE)) goto idle; - } - for (nda = 0; nda < nt_nwaveout; nda++) - { - int phase = ntsnd_outphase[nda]; - WAVEHDR *outwavehdr = - ntsnd_outvec[nda][phase].lpWaveHdr; - if (!(outwavehdr->dwFlags & WHDR_DONE)) goto idle; - } - for (nad = 0; nad < nt_nwavein; nad++) - { - int phase = ntsnd_inphase[nad]; - WAVEHDR *inwavehdr = - ntsnd_invec[nad][phase].lpWaveHdr; - if (inwavehdr->dwFlags & WHDR_PREPARED) - waveInUnprepareHeader(ntsnd_indev[nad], - inwavehdr, sizeof(WAVEHDR)); - } - for (nda = 0; nda < nt_nwaveout; nda++) - { - int phase = ntsnd_outphase[nda]; - WAVEHDR *outwavehdr = ntsnd_outvec[nda][phase].lpWaveHdr; - if (outwavehdr->dwFlags & WHDR_PREPARED) - waveOutUnprepareHeader(ntsnd_outdev[nda], - outwavehdr, sizeof(WAVEHDR)); - } + for (nad = 0; nad < nt_nwavein; nad++) + { + int phase = ntsnd_inphase[nad]; + WAVEHDR *inwavehdr = ntsnd_invec[nad][phase].lpWaveHdr; + if (!(inwavehdr->dwFlags & WHDR_DONE)) goto idle; + } + for (nda = 0; nda < nt_nwaveout; nda++) + { + int phase = ntsnd_outphase[nda]; + WAVEHDR *outwavehdr = + ntsnd_outvec[nda][phase].lpWaveHdr; + if (!(outwavehdr->dwFlags & WHDR_DONE)) goto idle; + } + for (nad = 0; nad < nt_nwavein; nad++) + { + int phase = ntsnd_inphase[nad]; + WAVEHDR *inwavehdr = + ntsnd_invec[nad][phase].lpWaveHdr; + if (inwavehdr->dwFlags & WHDR_PREPARED) + waveInUnprepareHeader(ntsnd_indev[nad], + inwavehdr, sizeof(WAVEHDR)); + } + for (nda = 0; nda < nt_nwaveout; nda++) + { + int phase = ntsnd_outphase[nda]; + WAVEHDR *outwavehdr = ntsnd_outvec[nda][phase].lpWaveHdr; + if (outwavehdr->dwFlags & WHDR_PREPARED) + waveOutUnprepareHeader(ntsnd_outdev[nda], + outwavehdr, sizeof(WAVEHDR)); + } } - /* Convert audio output to fixed-point and put it in the output - buffer. */ + /* Convert audio output to fixed-point and put it in the output + buffer. */ for (nda = 0, fp1 = sys_soundout; nda < nt_nwaveout; nda++) { - int phase = ntsnd_outphase[nda]; - - for (i = 0, sp1 = (short *)(ntsnd_outvec[nda][phase].lpData) + - CHANNELS_PER_DEVICE * nt_fill; - i < 2; i++, fp1 += DEFDACBLKSIZE, sp1++) - { - for (j = 0, fp2 = fp1, sp2 = sp1; j < DEFDACBLKSIZE; - j++, fp2++, sp2 += CHANNELS_PER_DEVICE) - { - int x1 = 32767.f * *fp2; - if (x1 > 32767) x1 = 32767; - else if (x1 < -32767) x1 = -32767; - *sp2 = x1; - } - } + int phase = ntsnd_outphase[nda]; + + for (i = 0, sp1 = (short *)(ntsnd_outvec[nda][phase].lpData) + + CHANNELS_PER_DEVICE * nt_fill; + i < 2; i++, fp1 += DEFDACBLKSIZE, sp1++) + { + for (j = 0, fp2 = fp1, sp2 = sp1; j < DEFDACBLKSIZE; + j++, fp2++, sp2 += CHANNELS_PER_DEVICE) + { + int x1 = 32767.f * *fp2; + if (x1 > 32767) x1 = 32767; + else if (x1 < -32767) x1 = -32767; + *sp2 = x1; + } + } } memset(sys_soundout, 0, - (DEFDACBLKSIZE *sizeof(t_sample)*CHANNELS_PER_DEVICE)*nt_nwaveout); + (DEFDACBLKSIZE *sizeof(t_sample)*CHANNELS_PER_DEVICE)*nt_nwaveout); - /* vice versa for the input buffer */ + /* vice versa for the input buffer */ for (nad = 0, fp1 = sys_soundin; nad < nt_nwavein; nad++) { - int phase = ntsnd_inphase[nad]; - - for (i = 0, sp1 = (short *)(ntsnd_invec[nad][phase].lpData) + - CHANNELS_PER_DEVICE * nt_fill; - i < 2; i++, fp1 += DEFDACBLKSIZE, sp1++) - { - for (j = 0, fp2 = fp1, sp2 = sp1; j < DEFDACBLKSIZE; - j++, fp2++, sp2 += CHANNELS_PER_DEVICE) - { - *fp2 = ((float)(1./32767.)) * (float)(*sp2); - } - } + int phase = ntsnd_inphase[nad]; + + for (i = 0, sp1 = (short *)(ntsnd_invec[nad][phase].lpData) + + CHANNELS_PER_DEVICE * nt_fill; + i < 2; i++, fp1 += DEFDACBLKSIZE, sp1++) + { + for (j = 0, fp2 = fp1, sp2 = sp1; j < DEFDACBLKSIZE; + j++, fp2++, sp2 += CHANNELS_PER_DEVICE) + { + *fp2 = ((float)(1./32767.)) * (float)(*sp2); + } + } } nt_fill = nt_fill + DEFDACBLKSIZE; if (nt_fill == nt_realdacblksize) { - nt_fill = 0; - - for (nad = 0; nad < nt_nwavein; nad++) - { - int phase = ntsnd_inphase[nad]; - HWAVEIN device = ntsnd_indev[nad]; - WAVEHDR *inwavehdr = ntsnd_invec[nad][phase].lpWaveHdr; - waveInPrepareHeader(device, inwavehdr, sizeof(WAVEHDR)); - mmresult = waveInAddBuffer(device, inwavehdr, sizeof(WAVEHDR)); - if (mmresult != MMSYSERR_NOERROR) - nt_waveinerror("waveInAddBuffer: %s\n", mmresult); - ntsnd_inphase[nad] = WRAPFWD(phase + 1); - } - for (nda = 0; nda < nt_nwaveout; nda++) - { - int phase = ntsnd_outphase[nda]; - HWAVEOUT device = ntsnd_outdev[nda]; - WAVEHDR *outwavehdr = ntsnd_outvec[nda][phase].lpWaveHdr; - waveOutPrepareHeader(device, outwavehdr, sizeof(WAVEHDR)); - mmresult = waveOutWrite(device, outwavehdr, sizeof(WAVEHDR)); + nt_fill = 0; + + for (nad = 0; nad < nt_nwavein; nad++) + { + int phase = ntsnd_inphase[nad]; + HWAVEIN device = ntsnd_indev[nad]; + WAVEHDR *inwavehdr = ntsnd_invec[nad][phase].lpWaveHdr; + waveInPrepareHeader(device, inwavehdr, sizeof(WAVEHDR)); + mmresult = waveInAddBuffer(device, inwavehdr, sizeof(WAVEHDR)); if (mmresult != MMSYSERR_NOERROR) - nt_waveouterror("waveOutWrite: %s\n", mmresult); - ntsnd_outphase[nda] = WRAPFWD(phase + 1); - } - - /* check for DAC underflow or ADC overflow. */ - for (nad = 0; nad < nt_nwavein; nad++) - { - int phase = WRAPBACK(ntsnd_inphase[nad] - 2); - WAVEHDR *inwavehdr = ntsnd_invec[nad][phase].lpWaveHdr; - if (inwavehdr->dwFlags & WHDR_DONE) goto late; - } - for (nda = 0; nda < nt_nwaveout; nda++) - { - int phase = WRAPBACK(ntsnd_outphase[nda] - 2); - WAVEHDR *outwavehdr = ntsnd_outvec[nda][phase].lpWaveHdr; - if (outwavehdr->dwFlags & WHDR_DONE) goto late; - } + nt_waveinerror("waveInAddBuffer: %s\n", mmresult); + ntsnd_inphase[nad] = WRAPFWD(phase + 1); + } + for (nda = 0; nda < nt_nwaveout; nda++) + { + int phase = ntsnd_outphase[nda]; + HWAVEOUT device = ntsnd_outdev[nda]; + WAVEHDR *outwavehdr = ntsnd_outvec[nda][phase].lpWaveHdr; + waveOutPrepareHeader(device, outwavehdr, sizeof(WAVEHDR)); + mmresult = waveOutWrite(device, outwavehdr, sizeof(WAVEHDR)); + if (mmresult != MMSYSERR_NOERROR) + nt_waveouterror("waveOutWrite: %s\n", mmresult); + ntsnd_outphase[nda] = WRAPFWD(phase + 1); + } + + /* check for DAC underflow or ADC overflow. */ + for (nad = 0; nad < nt_nwavein; nad++) + { + int phase = WRAPBACK(ntsnd_inphase[nad] - 2); + WAVEHDR *inwavehdr = ntsnd_invec[nad][phase].lpWaveHdr; + if (inwavehdr->dwFlags & WHDR_DONE) goto late; + } + for (nda = 0; nda < nt_nwaveout; nda++) + { + int phase = WRAPBACK(ntsnd_outphase[nda] - 2); + WAVEHDR *outwavehdr = ntsnd_outvec[nda][phase].lpWaveHdr; + if (outwavehdr->dwFlags & WHDR_DONE) goto late; + } } return (1); @@ -659,29 +662,29 @@ idle: for (nad = 0; nad < nt_nwavein; nad++) { - int phase = ntsnd_inphase[nad]; - WAVEHDR *inwavehdr = - ntsnd_invec[nad] - [WRAPFWD(phase + nt_adcjitterbufsallowed)].lpWaveHdr; - if (inwavehdr->dwFlags & WHDR_DONE) - { - nt_resyncaudio(); - return (0); - } + int phase = ntsnd_inphase[nad]; + WAVEHDR *inwavehdr = + ntsnd_invec[nad] + [WRAPFWD(phase + nt_adcjitterbufsallowed)].lpWaveHdr; + if (inwavehdr->dwFlags & WHDR_DONE) + { + nt_resyncaudio(); + return (0); + } } - /* test dac sync the same way */ + /* test dac sync the same way */ for (nda = 0; nda < nt_nwaveout; nda++) { - int phase = ntsnd_outphase[nda]; - WAVEHDR *outwavehdr = - ntsnd_outvec[nda] - [WRAPFWD(phase + nt_dacjitterbufsallowed)].lpWaveHdr; - if (outwavehdr->dwFlags & WHDR_DONE) - { - nt_resyncaudio(); - return (0); - } + int phase = ntsnd_outphase[nda]; + WAVEHDR *outwavehdr = + ntsnd_outvec[nda] + [WRAPFWD(phase + nt_dacjitterbufsallowed)].lpWaveHdr; + if (outwavehdr->dwFlags & WHDR_DONE) + { + nt_resyncaudio(); + return (0); + } } #ifdef MIDI_TIMESTAMP nt_midisync(); @@ -701,24 +704,24 @@ void mmio_open_audio(int naudioindev, int *audioindev, nbuf = sys_advance_samples/nt_realdacblksize; if (nbuf >= MAXBUFFER) { - fprintf(stderr, "pd: audio buffering maxed out to %d\n", - (int)(MAXBUFFER * ((nt_realdacblksize * 1000.)/44100.))); - nbuf = MAXBUFFER; + fprintf(stderr, "pd: audio buffering maxed out to %d\n", + (int)(MAXBUFFER * ((nt_realdacblksize * 1000.)/44100.))); + nbuf = MAXBUFFER; } else if (nbuf < 4) nbuf = 4; fprintf(stderr, "%d audio buffers\n", nbuf); nt_naudiobuffer = nbuf; if (nt_adcjitterbufsallowed > nbuf - 2) - nt_adcjitterbufsallowed = nbuf - 2; + nt_adcjitterbufsallowed = nbuf - 2; if (nt_dacjitterbufsallowed > nbuf - 2) - nt_dacjitterbufsallowed = nbuf - 2; + nt_dacjitterbufsallowed = nbuf - 2; nt_nwavein = sys_inchannels / 2; nt_nwaveout = sys_outchannels / 2; nt_whichadc = (naudioindev < 1 ? - (nt_nwavein > 1 ? WAVE_MAPPER : -1) : audioindev[0]); + (nt_nwavein > 1 ? WAVE_MAPPER : -1) : audioindev[0]); nt_whichdac = (naudiooutdev < 1 ? - (nt_nwaveout > 1 ? WAVE_MAPPER : -1) : audiooutdev[0]); + (nt_nwaveout > 1 ? WAVE_MAPPER : -1) : audiooutdev[0]); if (naudiooutdev > 1 || naudioindev > 1) post("separate audio device choice not supported; using sequential devices."); mmio_do_open_audio(); @@ -739,53 +742,53 @@ void mmio_listdevs(void) ndevices = waveInGetNumDevs(); for (i = 0; i < ndevices; i++) { - WAVEINCAPS wicap; - wRtn = waveInGetDevCaps(i, (LPWAVEINCAPS) &wicap, + WAVEINCAPS wicap; + wRtn = waveInGetDevCaps(i, (LPWAVEINCAPS) &wicap, sizeof(wicap)); if (wRtn) nt_waveinerror("waveInGetDevCaps: %s\n", wRtn); - else fprintf(stderr, - "audio input device #%d: %s\n", i+1, wicap.szPname); + else fprintf(stderr, + "audio input device #%d: %s\n", i+1, wicap.szPname); } ndevices = waveOutGetNumDevs(); for (i = 0; i < ndevices; i++) { - WAVEOUTCAPS wocap; - wRtn = waveOutGetDevCaps(i, (LPWAVEOUTCAPS) &wocap, + WAVEOUTCAPS wocap; + wRtn = waveOutGetDevCaps(i, (LPWAVEOUTCAPS) &wocap, sizeof(wocap)); if (wRtn) nt_waveouterror("waveOutGetDevCaps: %s\n", wRtn); - else fprintf(stderr, - "audio output device #%d: %s\n", i+1, wocap.szPname); + else fprintf(stderr, + "audio output device #%d: %s\n", i+1, wocap.szPname); } } #endif void mmio_getdevs(char *indevlist, int *nindevs, char *outdevlist, int *noutdevs, int *canmulti, - int maxndev, int devdescsize) + int maxndev, int devdescsize) { int wRtn, ndev, i; *canmulti = 2; /* supports multiple devices */ ndev = waveInGetNumDevs(); if (ndev > maxndev) - ndev = maxndev; + ndev = maxndev; *nindevs = ndev; for (i = 0; i < ndev; i++) { - WAVEINCAPS wicap; - wRtn = waveInGetDevCaps(i, (LPWAVEINCAPS) &wicap, sizeof(wicap)); - sprintf(indevlist + i * devdescsize, (wRtn ? "???" : wicap.szPname)); + WAVEINCAPS wicap; + wRtn = waveInGetDevCaps(i, (LPWAVEINCAPS) &wicap, sizeof(wicap)); + sprintf(indevlist + i * devdescsize, (wRtn ? "???" : wicap.szPname)); } ndev = waveOutGetNumDevs(); if (ndev > maxndev) - ndev = maxndev; + ndev = maxndev; *noutdevs = ndev; for (i = 0; i < ndev; i++) { - WAVEOUTCAPS wocap; - wRtn = waveOutGetDevCaps(i, (LPWAVEOUTCAPS) &wocap, sizeof(wocap)); - sprintf(outdevlist + i * devdescsize, (wRtn ? "???" : wocap.szPname)); + WAVEOUTCAPS wocap; + wRtn = waveOutGetDevCaps(i, (LPWAVEOUTCAPS) &wocap, sizeof(wocap)); + sprintf(outdevlist + i * devdescsize, (wRtn ? "???" : wocap.szPname)); } } |