engine/fteqtv/sc_dsound.c

192 lines
4.4 KiB
C

#include "qtv.h"
#ifdef COMMENTARY
#include <dsound.h>
static HANDLE hInstDS;
static HRESULT (WINAPI *pDirectSoundCaptureCreate)(GUID FAR *lpGUID, LPDIRECTSOUNDCAPTURE FAR *lplpDS, IUnknown FAR *pUnkOuter);
typedef struct {
soundcapt_t funcs;
LPDIRECTSOUNDCAPTURE DSCapture;
LPDIRECTSOUNDCAPTUREBUFFER DSCaptureBuffer;
long lastreadpos;
WAVEFORMATEX wfxFormat;
long bufferbytes;
} dscapture_t;
void DSOUND_CloseCapture(soundcapt_t *ghnd)
{
dscapture_t *hnd = (dscapture_t*)ghnd;
if (hnd->DSCaptureBuffer)
{
IDirectSoundCaptureBuffer_Stop(hnd->DSCaptureBuffer);
IDirectSoundCaptureBuffer_Release(hnd->DSCaptureBuffer);
hnd->DSCaptureBuffer=NULL;
}
if (hnd->DSCapture)
{
IDirectSoundCapture_Release(hnd->DSCapture);
hnd->DSCapture=NULL;
}
free(hnd);
}
int DSOUND_UpdateCapture(soundcapt_t *ghnd, int samplechunks, char *buffer)
{
dscapture_t *hnd = (dscapture_t*)ghnd;
HRESULT hr;
LPBYTE lpbuf1 = NULL;
LPBYTE lpbuf2 = NULL;
DWORD dwsize1 = 0;
DWORD dwsize2 = 0;
DWORD capturePos;
DWORD readPos;
long filled;
int inputbytes;
inputbytes = hnd->wfxFormat.wBitsPerSample/8;
// Query to see how much data is in buffer.
hr = IDirectSoundCaptureBuffer_GetCurrentPosition(hnd->DSCaptureBuffer, &capturePos, &readPos );
if( hr != DS_OK )
{
return 0;
}
filled = readPos - hnd->lastreadpos;
if( filled < 0 )
filled += hnd->bufferbytes; // unwrap offset
if (filled > samplechunks) //figure out how much we need to empty it by, and if that's enough to be worthwhile.
filled = samplechunks;
else if (filled < samplechunks)
return 0;
if ((filled/inputbytes) & 1) //force even numbers of samples
filled -= inputbytes;
// Lock free space in the DS
hr = IDirectSoundCaptureBuffer_Lock ( hnd->DSCaptureBuffer, hnd->lastreadpos, filled, (void **) &lpbuf1, &dwsize1,
(void **) &lpbuf2, &dwsize2, 0);
if (hr == DS_OK)
{
// Copy from DS to the buffer
memcpy( buffer, lpbuf1, dwsize1);
if(lpbuf2 != NULL)
{
memcpy( buffer+dwsize1, lpbuf2, dwsize2);
}
// Update our buffer offset and unlock sound buffer
hnd->lastreadpos = (hnd->lastreadpos + dwsize1 + dwsize2) % (hnd->bufferbytes);
IDirectSoundCaptureBuffer_Unlock ( hnd->DSCaptureBuffer, lpbuf1, dwsize1, lpbuf2, dwsize2);
}
else
{
return 0;
}
return filled/inputbytes;
}
soundcapt_t *SND_InitCapture (int speed, int bits)
{
dscapture_t *hnd;
DSCBUFFERDESC bufdesc;
if (!hInstDS)
{
hInstDS = LoadLibrary("dsound.dll");
if (hInstDS == NULL)
{
printf ("Couldn't load dsound.dll\n");
return NULL;
}
}
if (!pDirectSoundCaptureCreate)
{
pDirectSoundCaptureCreate = (void *)GetProcAddress(hInstDS,"DirectSoundCaptureCreate");
if (!pDirectSoundCaptureCreate)
{
printf ("Couldn't get DS proc addr (DirectSoundCaptureCreate)\n");
return NULL;
}
}
hnd = malloc(sizeof(dscapture_t));
memset(hnd, 0, sizeof(*hnd));
hnd->wfxFormat.wFormatTag = WAVE_FORMAT_PCM;
hnd->wfxFormat.nChannels = 1;
hnd->wfxFormat.nSamplesPerSec = speed;
hnd->wfxFormat.wBitsPerSample = bits;
hnd->wfxFormat.nBlockAlign = hnd->wfxFormat.nChannels * (hnd->wfxFormat.wBitsPerSample / 8);
hnd->wfxFormat.nAvgBytesPerSec = hnd->wfxFormat.nSamplesPerSec * hnd->wfxFormat.nBlockAlign;
hnd->wfxFormat.cbSize = 0;
bufdesc.dwSize = sizeof(bufdesc);
bufdesc.dwBufferBytes = hnd->bufferbytes = speed*bits/8; //1 sec
bufdesc.dwFlags = 0;
bufdesc.dwReserved = 0;
bufdesc.lpwfxFormat = &hnd->wfxFormat;
pDirectSoundCaptureCreate(NULL, &hnd->DSCapture, NULL);
if (FAILED(IDirectSoundCapture_CreateCaptureBuffer(hnd->DSCapture, &bufdesc, &hnd->DSCaptureBuffer, NULL)))
{
printf ("Couldn't create a capture buffer\n");
IDirectSoundCapture_Release(hnd->DSCapture);
free(hnd);
return NULL;
}
IDirectSoundCaptureBuffer_Start(hnd->DSCaptureBuffer, DSBPLAY_LOOPING);
hnd->lastreadpos = 0;
hnd->funcs.update = DSOUND_UpdateCapture;
hnd->funcs.close = DSOUND_CloseCapture;
return &hnd->funcs;
}
/*
void soundtestcallback (char *buffer, int samples, int bitspersample)
{
FILE *f;
f = fopen("c:/test.raw", "at");
fseek(f, 0, SEEK_END);
fwrite(buffer, samples, bitspersample/8, f);
fclose(f);
}
void soundtest(void)
{
soundcapt_t *capt;
capt = SNDDMA_InitCapture(11025, 8);
while(1)
capt->update(capt, 1400, soundtestcallback);
capt->close(capt);
}
*/
#endif