0e3193a3ef
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@3246 fc73d0e0-1445-4013-8a0c-d673dee63da5
251 lines
5.9 KiB
C
251 lines
5.9 KiB
C
#include "qtv.h"
|
|
#ifdef COMMENTARY
|
|
#include <dsound.h>
|
|
|
|
static HANDLE hInstDS;
|
|
static HRESULT (WINAPI *pDirectSoundCreate)(LPGUID, LPDIRECTSOUND *, LPUNKNOWN);
|
|
|
|
typedef struct {
|
|
soundplay_t funcs;
|
|
|
|
LPDIRECTSOUND ds;
|
|
LPDIRECTSOUNDBUFFER dsbuf;
|
|
|
|
int buffersize;
|
|
|
|
int writepos;
|
|
int readpos;
|
|
|
|
int sampbytes;
|
|
|
|
} dsplay_t;
|
|
|
|
int DSOUND_UpdatePlayback(soundplay_t *sp, int samplechunks, char *buffer)
|
|
{
|
|
int ret;
|
|
dsplay_t *dsp = (dsplay_t*)sp;
|
|
char *sbuf;
|
|
int sbufsize;
|
|
int writable;
|
|
int remaining = samplechunks;
|
|
|
|
if (!samplechunks)
|
|
return 0;
|
|
|
|
IDirectSoundBuffer_GetCurrentPosition(dsp->dsbuf, &dsp->readpos, NULL);
|
|
dsp->readpos /= dsp->sampbytes;
|
|
|
|
while (ret = IDirectSoundBuffer_Lock(dsp->dsbuf, 0, dsp->buffersize*dsp->sampbytes, (void**)&sbuf, &sbufsize, NULL, NULL, 0))
|
|
{
|
|
if (!FAILED(ret))
|
|
break;
|
|
if (ret == DSERR_BUFFERLOST)
|
|
printf("Buffer lost\n");
|
|
else
|
|
break;
|
|
|
|
// if (FAILED(IDirectSoundBuffer_Resore(dsp->dsbuf)))
|
|
// return 0;
|
|
}
|
|
//memset(sbuf, 0, sbufsize);
|
|
writable = remaining;
|
|
if (writable > sbufsize/dsp->sampbytes - dsp->writepos)
|
|
writable = sbufsize/dsp->sampbytes - dsp->writepos;
|
|
memcpy(sbuf+dsp->writepos*dsp->sampbytes, buffer, writable*dsp->sampbytes);
|
|
remaining -= writable;
|
|
buffer += writable*dsp->sampbytes;
|
|
dsp->writepos += writable;
|
|
dsp->writepos %= dsp->buffersize;
|
|
if (samplechunks > 0)
|
|
{
|
|
writable = remaining;
|
|
if (writable > dsp->readpos)
|
|
writable = dsp->readpos;
|
|
memcpy(sbuf, buffer, writable*dsp->sampbytes);
|
|
remaining -= writable;
|
|
dsp->writepos += writable;
|
|
dsp->writepos %= dsp->buffersize;
|
|
}
|
|
IDirectSoundBuffer_Unlock(dsp->dsbuf, sbuf, sbufsize, NULL, 0);
|
|
|
|
printf("%i %i\n", 100*dsp->readpos / dsp->buffersize, 100*dsp->writepos / dsp->buffersize);
|
|
|
|
return samplechunks - remaining;
|
|
}
|
|
|
|
void DSOUND_Shutdown(soundplay_t *dsp)
|
|
{
|
|
}
|
|
|
|
soundplay_t *SND_InitPlayback(int speed, int bits)
|
|
{
|
|
int ret;
|
|
DSBCAPS caps;
|
|
DSBUFFERDESC bufdesc;
|
|
LPDIRECTSOUND ds;
|
|
dsplay_t *hnd;
|
|
WAVEFORMATEX format;
|
|
|
|
if (!hInstDS)
|
|
{
|
|
hInstDS = LoadLibrary("dsound.dll");
|
|
|
|
if (hInstDS == NULL)
|
|
{
|
|
printf ("Couldn't load dsound.dll\n");
|
|
return NULL;
|
|
}
|
|
|
|
pDirectSoundCreate = (void *)GetProcAddress(hInstDS,"DirectSoundCreate");
|
|
|
|
if (!pDirectSoundCreate)
|
|
{
|
|
printf ("Couldn't get DS proc addr\n");
|
|
return NULL;
|
|
}
|
|
|
|
// pDirectSoundEnumerate = (void *)GetProcAddress(hInstDS,"DirectSoundEnumerateA");
|
|
}
|
|
|
|
ds = NULL;
|
|
pDirectSoundCreate(NULL, &ds, NULL);
|
|
|
|
if (!ds)
|
|
return NULL;
|
|
hnd = malloc(sizeof(*hnd));
|
|
memset(hnd, 0, sizeof(*hnd));
|
|
|
|
hnd->funcs.update = DSOUND_UpdatePlayback;
|
|
hnd->funcs.close = DSOUND_Shutdown;
|
|
|
|
hnd->ds = ds;
|
|
hnd->sampbytes = bits/8;
|
|
|
|
if (FAILED(IDirectSound_SetCooperativeLevel (hnd->ds, GetDesktopWindow(), DSSCL_EXCLUSIVE)))
|
|
printf("SetCooperativeLevel failed\n");
|
|
|
|
memset(&bufdesc, 0, sizeof(bufdesc));
|
|
bufdesc.dwSize = sizeof(bufdesc);
|
|
// bufdesc.dwFlags |= DSBCAPS_GLOBALFOCUS; //so we hear it if quake is loaded
|
|
bufdesc.dwFlags |= DSBCAPS_PRIMARYBUFFER; //so we can set speed
|
|
bufdesc.dwFlags |= DSBCAPS_CTRLVOLUME;
|
|
bufdesc.lpwfxFormat = NULL;
|
|
bufdesc.dwBufferBytes = 0;
|
|
|
|
format.wFormatTag = WAVE_FORMAT_PCM;
|
|
format.cbSize = 0;
|
|
|
|
format.nChannels = 1;
|
|
format.wBitsPerSample = bits;
|
|
format.nSamplesPerSec = speed;
|
|
format.nBlockAlign = format.nChannels * format.wBitsPerSample / 8;
|
|
format.nAvgBytesPerSec = format.nSamplesPerSec * format.nBlockAlign;
|
|
|
|
ret = IDirectSound_CreateSoundBuffer(hnd->ds, &bufdesc, &hnd->dsbuf, NULL);
|
|
|
|
if (!hnd->dsbuf)
|
|
{
|
|
printf("Couldn't create primary buffer\n");
|
|
DSOUND_Shutdown(&hnd->funcs);
|
|
return NULL;
|
|
}
|
|
|
|
if (FAILED(IDirectSoundBuffer_SetFormat(hnd->dsbuf, &format)))
|
|
printf("SetFormat failed\n");
|
|
|
|
//and now make a secondary buffer
|
|
bufdesc.dwFlags = 0;
|
|
bufdesc.dwFlags |= DSBCAPS_CTRLFREQUENCY;
|
|
bufdesc.dwFlags |= DSBCAPS_LOCSOFTWARE;
|
|
bufdesc.dwFlags |= DSBCAPS_GLOBALFOCUS;
|
|
bufdesc.dwBufferBytes = speed * format.nChannels * hnd->sampbytes;
|
|
bufdesc.lpwfxFormat = &format;
|
|
|
|
ret = IDirectSound_CreateSoundBuffer(hnd->ds, &bufdesc, &hnd->dsbuf, NULL);
|
|
if (!hnd->dsbuf)
|
|
{
|
|
printf("Couldn't create secondary buffer\n");
|
|
DSOUND_Shutdown(&hnd->funcs);
|
|
return NULL;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
memset(&caps, 0, sizeof(caps));
|
|
caps.dwSize = sizeof(caps);
|
|
IDirectSoundBuffer_GetCaps(hnd->dsbuf, &caps);
|
|
hnd->buffersize = caps.dwBufferBytes / hnd->sampbytes;
|
|
|
|
//clear out the buffer
|
|
{
|
|
char *buffer;
|
|
int buffersize=0;
|
|
IDirectSoundBuffer_Play(hnd->dsbuf, 0, 0, DSBPLAY_LOOPING);
|
|
ret = IDirectSoundBuffer_Lock(hnd->dsbuf, 0, hnd->buffersize*hnd->sampbytes, (void**)&buffer, &buffersize, NULL, NULL, 0);
|
|
memset(buffer, 0, buffersize);
|
|
IDirectSoundBuffer_Unlock(hnd->dsbuf, buffer, buffersize, NULL, 0);
|
|
IDirectSoundBuffer_Stop(hnd->dsbuf);
|
|
}
|
|
//DSERR_INVALIDPARAM
|
|
IDirectSoundBuffer_Play(hnd->dsbuf, 0, 0, DSBPLAY_LOOPING);
|
|
|
|
|
|
IDirectSoundBuffer_GetCurrentPosition(hnd->dsbuf, &hnd->readpos, &hnd->writepos);
|
|
|
|
hnd->writepos = hnd->readpos + speed / 2; //position our write position a quater of a second infront of the read position
|
|
|
|
printf("%i %i\n", 100*hnd->readpos / hnd->buffersize, 100*hnd->writepos / hnd->buffersize);
|
|
|
|
return &hnd->funcs;
|
|
}
|
|
|
|
|
|
/*
|
|
|
|
|
|
void soundtest(void)
|
|
{
|
|
int speed = 22100*2;
|
|
int bits = 16;
|
|
|
|
int i;
|
|
|
|
int sampsavailable;
|
|
short buffer[1024];
|
|
soundcapt_t *capt;
|
|
soundplay_t *play;
|
|
|
|
capt = SND_InitCapture (speed, bits);
|
|
if (!capt)
|
|
{
|
|
printf("Failed to init capturer\n");
|
|
exit(0);
|
|
}
|
|
|
|
play = SND_InitPlayback (speed, bits);
|
|
if (!play)
|
|
{
|
|
printf("Failed to init playback\n");
|
|
exit(0);
|
|
}
|
|
|
|
|
|
|
|
|
|
for(;;)
|
|
{
|
|
for (i = 0; i < sizeof(buffer)/sizeof(buffer[0]); i++)
|
|
buffer[i] = rand();
|
|
sampsavailable = capt->update(capt, sizeof(buffer)/(bits/8), (char*)buffer);
|
|
play->update(play, sampsavailable, (char*)buffer);
|
|
|
|
Sleep(1);
|
|
}
|
|
}
|
|
*/
|
|
#endif
|