2010-04-24 21:37:39 +00:00
|
|
|
/* ZeroSPU2
|
|
|
|
* Copyright (C) 2006-2007 zerofrog
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
2010-07-04 22:49:00 +00:00
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
2010-04-24 21:37:39 +00:00
|
|
|
*/
|
2010-04-25 00:31:27 +00:00
|
|
|
|
2010-04-24 21:37:39 +00:00
|
|
|
#include "dsound51.h"
|
|
|
|
HWND hWMain = NULL;
|
|
|
|
|
|
|
|
LPDIRECTSOUND lpDS;
|
|
|
|
LPDIRECTSOUNDBUFFER lpDSBPRIMARY = NULL;
|
|
|
|
LPDIRECTSOUNDBUFFER lpDSBSECONDARY1 = NULL;
|
|
|
|
LPDIRECTSOUNDBUFFER lpDSBSECONDARY2 = NULL;
|
|
|
|
DSBUFFERDESC dsbd;
|
|
|
|
DSBUFFERDESC dsbdesc;
|
|
|
|
DSCAPS dscaps;
|
|
|
|
DSBCAPS dsbcaps;
|
|
|
|
|
|
|
|
unsigned long LastWrite = 0xffffffff;
|
|
|
|
unsigned long LastWriteS = 0xffffffff;
|
|
|
|
unsigned long LastPlay = 0;
|
|
|
|
|
|
|
|
int DSSetupSound()
|
|
|
|
{
|
|
|
|
HRESULT dsval;
|
|
|
|
WAVEFORMATEX pcmwf;
|
|
|
|
|
|
|
|
dsval = DirectSoundCreate(NULL,&lpDS,NULL);
|
2010-04-25 00:31:27 +00:00
|
|
|
if(dsval != DS_OK)
|
2010-04-24 21:37:39 +00:00
|
|
|
{
|
|
|
|
MessageBox(hWMain,"DirectSoundCreate!","Error",MB_OK);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2010-04-25 00:31:27 +00:00
|
|
|
if(DS_OK != IDirectSound_SetCooperativeLevel(lpDS,hWMain, DSSCL_PRIORITY))
|
2010-04-24 21:37:39 +00:00
|
|
|
{
|
2010-04-25 00:31:27 +00:00
|
|
|
if(DS_OK != IDirectSound_SetCooperativeLevel(lpDS,hWMain, DSSCL_NORMAL))
|
2010-04-24 21:37:39 +00:00
|
|
|
{
|
|
|
|
MessageBox(hWMain,"SetCooperativeLevel!","Error",MB_OK);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
memset(&dsbd,0,sizeof(DSBUFFERDESC));
|
|
|
|
dsbd.dwSize = sizeof(DSBUFFERDESC); // NT4 hack! sizeof(dsbd);
|
2010-04-25 00:31:27 +00:00
|
|
|
dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER;
|
|
|
|
dsbd.dwBufferBytes = 0;
|
2010-04-24 21:37:39 +00:00
|
|
|
dsbd.lpwfxFormat = NULL;
|
|
|
|
|
|
|
|
dsval = IDirectSound_CreateSoundBuffer(lpDS,&dsbd,&lpDSBPRIMARY,NULL);
|
2010-04-25 00:31:27 +00:00
|
|
|
if(dsval != DS_OK)
|
2010-04-24 21:37:39 +00:00
|
|
|
{
|
|
|
|
MessageBox(hWMain, "CreateSoundBuffer (Primary)", "Error",MB_OK);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
memset(&pcmwf, 0, sizeof(WAVEFORMATEX));
|
|
|
|
pcmwf.wFormatTag = WAVE_FORMAT_PCM;
|
|
|
|
|
2010-04-25 00:31:27 +00:00
|
|
|
pcmwf.nChannels = 2;
|
2010-04-24 21:37:39 +00:00
|
|
|
pcmwf.nBlockAlign = 4;
|
|
|
|
|
|
|
|
pcmwf.nSamplesPerSec = SAMPLE_RATE;
|
|
|
|
|
|
|
|
pcmwf.nAvgBytesPerSec = pcmwf.nSamplesPerSec * pcmwf.nBlockAlign;
|
|
|
|
pcmwf.wBitsPerSample = 16;
|
|
|
|
|
|
|
|
dsval = IDirectSoundBuffer_SetFormat(lpDSBPRIMARY,&pcmwf);
|
2010-04-25 00:31:27 +00:00
|
|
|
if(dsval != DS_OK)
|
2010-04-24 21:37:39 +00:00
|
|
|
{
|
|
|
|
MessageBox(hWMain, "SetFormat!", "Error",MB_OK);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
dscaps.dwSize = sizeof(DSCAPS);
|
|
|
|
dsbcaps.dwSize = sizeof(DSBCAPS);
|
|
|
|
IDirectSound_GetCaps(lpDS,&dscaps);
|
|
|
|
IDirectSoundBuffer_GetCaps(lpDSBPRIMARY,&dsbcaps);
|
|
|
|
|
2010-04-25 00:31:27 +00:00
|
|
|
memset(&dsbdesc, 0, sizeof(DSBUFFERDESC));
|
2010-04-24 21:37:39 +00:00
|
|
|
// NT4 hack! sizeof(DSBUFFERDESC);
|
2010-04-25 00:31:27 +00:00
|
|
|
dsbdesc.dwSize = sizeof(DSBUFFERDESC);
|
2010-04-24 21:37:39 +00:00
|
|
|
dsbdesc.dwFlags = DSBCAPS_LOCHARDWARE | DSBCAPS_STICKYFOCUS | DSBCAPS_GETCURRENTPOSITION2;
|
|
|
|
dsbdesc.dwBufferBytes = SOUNDSIZE;
|
|
|
|
dsbdesc.lpwfxFormat = (LPWAVEFORMATEX)&pcmwf;
|
|
|
|
|
|
|
|
dsval = IDirectSound_CreateSoundBuffer(lpDS,&dsbdesc,&lpDSBSECONDARY1,NULL);
|
2010-04-25 00:31:27 +00:00
|
|
|
if(dsval != DS_OK)
|
2010-04-24 21:37:39 +00:00
|
|
|
{
|
|
|
|
dsbdesc.dwFlags = DSBCAPS_LOCSOFTWARE | DSBCAPS_STICKYFOCUS | DSBCAPS_GETCURRENTPOSITION2;
|
|
|
|
dsval = IDirectSound_CreateSoundBuffer(lpDS,&dsbdesc,&lpDSBSECONDARY1,NULL);
|
2010-04-25 00:31:27 +00:00
|
|
|
if(dsval != DS_OK)
|
2010-04-24 21:37:39 +00:00
|
|
|
{
|
|
|
|
MessageBox(hWMain,"CreateSoundBuffer (Secondary1)", "Error",MB_OK);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
dsval = IDirectSoundBuffer_Play(lpDSBPRIMARY,0,0,DSBPLAY_LOOPING);
|
|
|
|
if(dsval != DS_OK)
|
|
|
|
{
|
|
|
|
MessageBox(hWMain,"Play (Primary)","Error",MB_OK);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
dsval = IDirectSoundBuffer_Play(lpDSBSECONDARY1,0,0,DSBPLAY_LOOPING);
|
2010-04-25 00:31:27 +00:00
|
|
|
if(dsval != DS_OK)
|
2010-04-24 21:37:39 +00:00
|
|
|
{
|
|
|
|
MessageBox(hWMain,"Play (Secondary1)","Error",MB_OK);
|
|
|
|
return -1;
|
|
|
|
}
|
2010-04-25 00:31:27 +00:00
|
|
|
|
2010-04-24 21:37:39 +00:00
|
|
|
// init some play vars
|
|
|
|
LastWrite = 0x00000000;
|
2010-04-25 00:31:27 +00:00
|
|
|
LastPlay = 0;
|
|
|
|
|
2010-04-24 21:37:39 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void DSRemoveSound()
|
2010-04-25 00:31:27 +00:00
|
|
|
{
|
2010-04-24 21:37:39 +00:00
|
|
|
int iRes;
|
|
|
|
|
2010-04-25 00:31:27 +00:00
|
|
|
if (lpDSBSECONDARY1 != NULL)
|
2010-04-24 21:37:39 +00:00
|
|
|
{
|
|
|
|
IDirectSoundBuffer_Stop(lpDSBSECONDARY1);
|
|
|
|
iRes = IDirectSoundBuffer_Release(lpDSBSECONDARY1);
|
2010-04-25 00:31:27 +00:00
|
|
|
|
2010-04-24 21:37:39 +00:00
|
|
|
// FF says such a loop is bad... Demo says it's good... Pete doesn't care
|
|
|
|
while(iRes!=0) iRes = IDirectSoundBuffer_Release(lpDSBSECONDARY1);
|
2010-04-25 00:31:27 +00:00
|
|
|
|
2010-04-24 21:37:39 +00:00
|
|
|
lpDSBSECONDARY1 = NULL;
|
|
|
|
}
|
|
|
|
|
2010-04-25 00:31:27 +00:00
|
|
|
if (lpDSBPRIMARY != NULL)
|
2010-04-24 21:37:39 +00:00
|
|
|
{
|
|
|
|
IDirectSoundBuffer_Stop(lpDSBPRIMARY);
|
|
|
|
iRes = IDirectSoundBuffer_Release(lpDSBPRIMARY);
|
2010-04-25 00:31:27 +00:00
|
|
|
|
2010-04-24 21:37:39 +00:00
|
|
|
// FF says such a loop is bad... Demo says it's good... Pete doesn't care
|
|
|
|
while(iRes!=0) iRes = IDirectSoundBuffer_Release(lpDSBPRIMARY);
|
2010-04-25 00:31:27 +00:00
|
|
|
|
2010-04-24 21:37:39 +00:00
|
|
|
lpDSBPRIMARY = NULL;
|
|
|
|
}
|
|
|
|
|
2010-04-25 00:31:27 +00:00
|
|
|
if (lpDS!=NULL)
|
2010-04-24 21:37:39 +00:00
|
|
|
{
|
|
|
|
iRes = IDirectSound_Release(lpDS);
|
2010-04-25 00:31:27 +00:00
|
|
|
|
2010-04-24 21:37:39 +00:00
|
|
|
// FF says such a loop is bad... Demo says it's good... Pete doesn't care
|
|
|
|
while(iRes!=0) iRes = IDirectSound_Release(lpDS);
|
2010-04-25 00:31:27 +00:00
|
|
|
|
2010-04-24 21:37:39 +00:00
|
|
|
lpDS = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
int DSSoundGetBytesBuffered()
|
|
|
|
{
|
|
|
|
unsigned long cplay,cwrite;
|
|
|
|
|
|
|
|
if (LastWrite == 0xffffffff) return 0;
|
|
|
|
|
|
|
|
IDirectSoundBuffer_GetCurrentPosition(lpDSBSECONDARY1,&cplay,&cwrite);
|
|
|
|
|
|
|
|
if(cplay > SOUNDSIZE) return SOUNDSIZE;
|
|
|
|
if(cplay < LastWrite) return LastWrite - cplay;
|
2010-04-25 00:31:27 +00:00
|
|
|
|
2010-04-24 21:37:39 +00:00
|
|
|
return (SOUNDSIZE - cplay) + LastWrite;
|
|
|
|
}
|
|
|
|
|
|
|
|
void DSSoundFeedVoiceData(unsigned char* pSound,long lBytes)
|
|
|
|
{
|
|
|
|
LPVOID lpvPtr1, lpvPtr2;
|
2010-04-25 00:31:27 +00:00
|
|
|
unsigned long dwBytes1,dwBytes2;
|
2010-04-24 21:37:39 +00:00
|
|
|
unsigned long *lpSS, *lpSD;
|
|
|
|
unsigned long dw,cplay,cwrite;
|
|
|
|
HRESULT hr;
|
|
|
|
unsigned long status;
|
|
|
|
|
|
|
|
IDirectSoundBuffer_GetStatus(lpDSBSECONDARY1,&status);
|
2010-04-25 00:31:27 +00:00
|
|
|
if (status & DSBSTATUS_BUFFERLOST)
|
2010-04-24 21:37:39 +00:00
|
|
|
{
|
|
|
|
if (IDirectSoundBuffer_Restore(lpDSBSECONDARY1) != DS_OK) return;
|
|
|
|
IDirectSoundBuffer_Play(lpDSBSECONDARY1,0,0,DSBPLAY_LOOPING);
|
|
|
|
}
|
|
|
|
|
|
|
|
IDirectSoundBuffer_GetCurrentPosition(lpDSBSECONDARY1,&cplay,&cwrite);
|
|
|
|
|
|
|
|
if(LastWrite == 0xffffffff) LastWrite=cwrite;
|
|
|
|
|
|
|
|
hr = IDirectSoundBuffer_Lock(lpDSBSECONDARY1,LastWrite,lBytes,
|
|
|
|
&lpvPtr1, &dwBytes1, &lpvPtr2, &dwBytes2, 0);
|
|
|
|
|
2010-04-25 00:31:27 +00:00
|
|
|
if (hr != DS_OK)
|
2010-04-24 21:37:39 +00:00
|
|
|
{
|
|
|
|
LastWrite=0xffffffff;
|
|
|
|
return;
|
|
|
|
}
|
2010-04-25 00:31:27 +00:00
|
|
|
|
2010-04-24 21:37:39 +00:00
|
|
|
lpSS = (unsigned long *)pSound;
|
|
|
|
lpSD = (unsigned long *)lpvPtr1;
|
|
|
|
dw = dwBytes1 >> 2;
|
|
|
|
|
2010-04-25 00:31:27 +00:00
|
|
|
while(dw)
|
2010-04-24 21:37:39 +00:00
|
|
|
{
|
|
|
|
*lpSD++=*lpSS++;
|
|
|
|
dw--;
|
|
|
|
}
|
|
|
|
|
2010-04-25 00:31:27 +00:00
|
|
|
if (lpvPtr2)
|
2010-04-24 21:37:39 +00:00
|
|
|
{
|
|
|
|
lpSD = (unsigned long *)lpvPtr2;
|
|
|
|
dw = dwBytes2 >> 2;
|
2010-04-25 00:31:27 +00:00
|
|
|
|
|
|
|
while(dw)
|
2010-04-24 21:37:39 +00:00
|
|
|
{
|
|
|
|
*lpSD++ = *lpSS++;
|
|
|
|
dw--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
IDirectSoundBuffer_Unlock(lpDSBSECONDARY1,lpvPtr1,dwBytes1,lpvPtr2,dwBytes2);
|
|
|
|
LastWrite += lBytes;
|
|
|
|
if(LastWrite >= SOUNDSIZE) LastWrite -= SOUNDSIZE;
|
|
|
|
LastPlay = cplay;
|
2010-04-25 00:31:27 +00:00
|
|
|
}
|