2006-07-18 02:53:36 +00:00
/* FCE Ultra - NES/Famicom Emulator
*
* Copyright notice for this file :
* Copyright ( C ) 2002 Xodnizel
*
* 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
* Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
*/
LPDIRECTSOUND ppDS = 0 ; /* DirectSound object. */
LPDIRECTSOUNDBUFFER ppbuf = 0 ; /* Primary buffer object. */
LPDIRECTSOUNDBUFFER ppbufsec = 0 ; /* Secondary buffer object. */
LPDIRECTSOUNDBUFFER ppbufw ; /* Buffer to actually write to. */
long DSBufferSize ; /* The size of the buffer that we can write to, in bytes. */
long BufHowMuch ; /* How many bytes we should try to buffer. */
DWORD ToWritePos ; /* Position which the next write to the buffer
should write to .
*/
DSBUFFERDESC DSBufferDesc ;
WAVEFORMATEX wfa ;
WAVEFORMATEX wf ;
2006-07-28 07:42:14 +00:00
//bittag=1 -> 8bit output
2006-07-18 02:53:36 +00:00
int bittage ;
static int mute = 0 ; /* TODO: add to config? add to GUI. */
void TrashSound ( void )
{
FCEUI_Sound ( 0 ) ;
if ( ppbufsec )
{
IDirectSoundBuffer_Stop ( ppbufsec ) ;
IDirectSoundBuffer_Release ( ppbufsec ) ;
ppbufsec = 0 ;
}
if ( ppbuf )
{
IDirectSoundBuffer_Stop ( ppbuf ) ;
IDirectSoundBuffer_Release ( ppbuf ) ;
ppbuf = 0 ;
}
if ( ppDS )
{
IDirectSound_Release ( ppDS ) ;
ppDS = 0 ;
}
}
void CheckDStatus ( void )
{
DWORD status ;
status = 0 ;
IDirectSoundBuffer_GetStatus ( ppbufw , & status ) ;
if ( status & DSBSTATUS_BUFFERLOST )
{
IDirectSoundBuffer_Restore ( ppbufw ) ;
}
if ( ! ( status & DSBSTATUS_PLAYING ) )
{
ToWritePos = 0 ;
IDirectSoundBuffer_SetFormat ( ppbufw , & wf ) ;
IDirectSoundBuffer_Play ( ppbufw , 0 , 0 , DSBPLAY_LOOPING ) ;
}
}
2006-07-18 06:35:48 +00:00
static uint32 RawCanWrite ( void )
2006-07-18 02:53:36 +00:00
{
DWORD CurWritePos , CurPlayPos = 0 ;
CheckDStatus ( ) ;
CurWritePos = 0 ;
if ( IDirectSoundBuffer_GetCurrentPosition ( ppbufw , & CurPlayPos , & CurWritePos ) = = DS_OK )
{
// FCEU_DispMessage("%8d",(CurWritePos-CurPlayPos));
}
CurWritePos = ( CurPlayPos + BufHowMuch ) % DSBufferSize ;
/* If the current write pos is >= half the buffer size less than the to write pos,
assume DirectSound has wrapped around .
*/
2006-07-18 06:35:48 +00:00
if ( ( ( int32 ) ToWritePos - ( int32 ) CurWritePos ) > = ( DSBufferSize / 2 ) )
2006-07-18 02:53:36 +00:00
{
CurWritePos + = DSBufferSize ;
//FCEU_printf("Fixit: %d,%d,%d\n",ToWritePos,CurWritePos,CurWritePos-DSBufferSize);
}
if ( ToWritePos < CurWritePos )
{
2006-07-18 06:35:48 +00:00
int32 howmuch = ( int32 ) CurWritePos - ( int32 ) ToWritePos ;
2006-07-18 02:53:36 +00:00
if ( howmuch > BufHowMuch ) /* Oopsie. Severe buffer overflow... */
{
//FCEU_printf("Ack");
ToWritePos = CurWritePos % DSBufferSize ;
}
return ( CurWritePos - ToWritePos ) ;
}
else
return ( 0 ) ;
}
int32 GetWriteSound ( void )
{
if ( ! soundo )
return 0 ;
return ( RawCanWrite ( ) > > bittage ) ;
}
int32 GetMaxSound ( void )
{
return ( BufHowMuch > > bittage ) ;
}
2006-07-18 06:35:48 +00:00
static int RawWrite ( void * data , uint32 len )
2006-07-18 02:53:36 +00:00
{
2006-07-18 06:35:48 +00:00
//uint32 cw; //mbg merge 7/17/06 removed
2006-07-18 02:53:36 +00:00
//printf("Pre: %d\n",SexyALI_DSound_RawCanWrite(device));
//fflush(stdout);
if ( ! soundo )
return 0 ;
CheckDStatus ( ) ;
/* In this block, we write as much data as we can, then we write
the rest of it in > = 1 ms chunks .
*/
while ( len )
{
VOID * LockPtr [ 2 ] = { 0 , 0 } ;
DWORD LockLen [ 2 ] = { 0 , 0 } ;
2006-07-19 05:57:00 +00:00
//mbg merge 7/17/06 changed to uint
//mbg merge 7/18/06 was causing a crash when fastforwarding unless this was initialized to len
uint32 curlen = len ;
2006-07-18 02:53:36 +00:00
// THIS LIMITS THE EMULATION SPEED
if ( ( ! NoWaiting ) | | ( soundoptions & SO_OLDUP ) )
while ( ! ( curlen = RawCanWrite ( ) ) )
{
Sleep ( 1 ) ;
}
if ( curlen > len ) curlen = len ;
if ( DS_OK = = IDirectSoundBuffer_Lock ( ppbufw , ToWritePos , curlen , & LockPtr [ 0 ] , & LockLen [ 0 ] , & LockPtr [ 1 ] , & LockLen [ 1 ] , 0 ) )
{
}
if ( LockPtr [ 1 ] ! = 0 & & LockPtr [ 1 ] ! = LockPtr [ 0 ] )
{
if ( mute )
{
if ( bittage )
{
memset ( LockPtr [ 0 ] , 0 , LockLen [ 0 ] ) ;
memset ( LockPtr [ 1 ] , 0 , len - LockLen [ 0 ] ) ;
}
else
{
memset ( LockPtr [ 0 ] , 0x80 , LockLen [ 0 ] ) ;
memset ( LockPtr [ 1 ] , 0x80 , len - LockLen [ 0 ] ) ;
}
}
else
{
/* not mute */
memcpy ( LockPtr [ 0 ] , data , LockLen [ 0 ] ) ;
2006-07-18 06:35:48 +00:00
memcpy ( LockPtr [ 1 ] , ( char * ) data + LockLen [ 0 ] , len - LockLen [ 0 ] ) ; //mbg merge 7/17/06 added cast
2006-07-18 02:53:36 +00:00
}
}
else if ( LockPtr [ 0 ] )
{
if ( mute )
{
if ( bittage )
memset ( LockPtr [ 0 ] , 0 , curlen ) ;
else
memset ( LockPtr [ 0 ] , 0x80 , curlen ) ;
}
else
{
/* not mute */
memcpy ( LockPtr [ 0 ] , data , curlen ) ;
}
}
IDirectSoundBuffer_Unlock ( ppbufw , LockPtr [ 0 ] , LockLen [ 0 ] , LockPtr [ 1 ] , LockLen [ 1 ] ) ;
ToWritePos = ( ToWritePos + curlen ) % DSBufferSize ;
len - = curlen ;
2006-07-18 06:35:48 +00:00
data = ( uint8 * ) data + curlen ; //mbg merge 7/17/06 reworked to be type proper
2006-07-18 02:53:36 +00:00
if ( len & & ! NoWaiting & & ( fps_scale < = 256 | | ( soundoptions & SO_OLDUP ) ) )
Sleep ( 1 ) ; // do some extra sleeping if we think there's time and we're not scaling up the FPS or in turbo mode
} // end while(len) loop
return ( 1 ) ;
}
int silencer = 0 ;
int FCEUD_WriteSoundData ( int32 * Buffer , int scale , int Count )
{
# define WSD_BUFSIZE (2 * 96000 / 50)
int P ;
int iCount = 0 ;
static int16 MBuffer [ WSD_BUFSIZE * 2 ] ;
if ( ! ( soundoptions & SO_OLDUP ) )
{
if ( FCEUI_EmulationPaused ( ) )
memset ( MBuffer , 0 , WSD_BUFSIZE ) ; // slow and/or unnecessary
if ( FCEUI_EmulationPaused ( ) ) scale > > = 1 ;
// limit frequency change to between 50% and 200%
if ( scale > 512 ) scale = 512 ;
if ( scale < 128 ) scale = 128 ;
}
// for(;Count>0;Count-=WSD_BUFSIZE)
{
int amt = ( soundoptions & SO_OLDUP ) ? Count : ( Count > WSD_BUFSIZE ? WSD_BUFSIZE : Count ) ;
if ( ! bittage )
{
if ( silencer )
for ( P = 0 ; P < amt ; P + + )
* ( ( ( uint8 * ) MBuffer ) + P ) = ( ( int8 ) ( Buffer [ 0 ] > > 8 ) ) ^ 128 ;
else if ( scale = = 256 ) // exactly 100% speed
for ( P = 0 ; P < amt ; P + + )
* ( ( ( uint8 * ) MBuffer ) + P ) = ( ( int8 ) ( Buffer [ P ] > > 8 ) ) ^ 128 ;
else // change sound frequency
for ( P = 0 ; P < amt ; P + + )
* ( ( ( uint8 * ) MBuffer ) + P ) = ( ( int8 ) ( Buffer [ P * scale / 256 ] > > 8 ) ) ^ 128 ;
RawWrite ( MBuffer , amt ) ;
}
else // force 8-bit sound is off:
{
if ( silencer )
for ( P = 0 ; P < amt ; P + + )
MBuffer [ P ] = Buffer [ 0 ] ;
else if ( scale = = 256 ) // exactly 100% speed
for ( P = 0 ; P < amt ; P + + )
MBuffer [ P ] = Buffer [ P ] ;
else // change sound frequency
for ( P = 0 ; P < amt ; P + + )
MBuffer [ P ] = Buffer [ P * scale / 256 ] ;
RawWrite ( MBuffer , amt * 2 ) ;
}
iCount + = amt ;
}
// FCEUI_AviSoundUpdate((void*)MBuffer, Count);
return iCount ;
}
2006-07-20 06:10:45 +00:00
/*
//mbg merge 7/19/06 an experiment in understanding the sound update code
int FCEUD_WriteSoundData ( int32 * Buffer , int scale , int Count )
{
# define WSD_BUFSIZE (2 * 96000 / 50)
int P ;
int iCount = 0 ;
static int16 MBuffer [ WSD_BUFSIZE * 2 ] ;
//if(!(soundoptions&SO_OLDUP))
//{
//shouldnt the sound be stopped?
//if(FCEUI_EmulationPaused())
// memset(MBuffer, 0, WSD_BUFSIZE); // slow and/or unnecessary
//why?
//if(FCEUI_EmulationPaused()) scale >>= 1;
// limit frequency change to between 50% and 200%
//if(scale > 512) scale = 512;
//if(scale < 128) scale = 128;
//}
int silence = FCEUI_EmulationPaused ( ) | silencer ;
for ( ; Count > 0 ; Count - = WSD_BUFSIZE )
{
//int amt = (soundoptions&SO_OLDUP) ? Count : (Count > WSD_BUFSIZE ? WSD_BUFSIZE : Count);
int amt = ( Count > WSD_BUFSIZE ? WSD_BUFSIZE : Count ) ;
if ( ! bittage )
{
if ( silence )
for ( P = 0 ; P < amt ; P + + )
* ( ( ( uint8 * ) MBuffer ) + P ) = ( ( int8 ) ( Buffer [ 0 ] > > 8 ) ) ^ 128 ;
else if ( scale = = 256 ) // exactly 100% speed
for ( P = 0 ; P < amt ; P + + )
* ( ( ( uint8 * ) MBuffer ) + P ) = ( ( int8 ) ( Buffer [ P ] > > 8 ) ) ^ 128 ;
else // change sound frequency
for ( P = 0 ; P < amt ; P + + )
* ( ( ( uint8 * ) MBuffer ) + P ) = ( ( int8 ) ( Buffer [ P * scale / 256 ] > > 8 ) ) ^ 128 ;
RawWrite ( MBuffer , amt ) ;
}
else // force 8-bit sound is off:
{
if ( silence )
for ( P = 0 ; P < amt ; P + + )
MBuffer [ P ] = Buffer [ 0 ] ;
else if ( scale = = 256 ) // exactly 100% speed
for ( P = 0 ; P < amt ; P + + )
MBuffer [ P ] = Buffer [ P ] ;
else // change sound frequency
for ( int chan = 0 ; chan < 2 ; chan + + ) {
int16 * dest = MBuffer + chan ;
int32 * src = Buffer + chan ;
int work = amt > > 1 ;
for ( P = 0 ; P < work ; P + + ) {
//interpolate
int loc = P * scale ;
int mix = src [ ( loc > > 8 ) < < 1 ] ;
mix + = ( ( src [ ( ( loc > > 8 ) + 1 ) < < 1 ] - mix ) * ( loc & 255 ) ) > > 8 ;
dest [ P < < 1 ] = mix ;
}
}
RawWrite ( MBuffer , amt * 2 ) ;
}
iCount + = amt ;
}
// FCEUI_AviSoundUpdate((void*)MBuffer, Count);
return iCount ;
}
*/
2006-07-18 02:53:36 +00:00
int InitSound ( )
{
DSCAPS dscaps ;
DSBCAPS dsbcaps ;
memset ( & wf , 0x00 , sizeof ( wf ) ) ;
wf . wFormatTag = WAVE_FORMAT_PCM ;
wf . nChannels = 1 ;
wf . nSamplesPerSec = soundrate ;
ddrval = DirectSoundCreate ( 0 , & ppDS , 0 ) ;
if ( ddrval ! = DS_OK )
{
FCEUD_PrintError ( " DirectSound: Error creating DirectSound object. " ) ;
return 0 ;
}
if ( soundoptions & SO_SECONDARY )
{
trysecondary :
ddrval = IDirectSound_SetCooperativeLevel ( ppDS , hAppWnd , DSSCL_PRIORITY ) ;
if ( ddrval ! = DS_OK )
{
FCEUD_PrintError ( " DirectSound: Error setting cooperative level to DDSCL_PRIORITY. " ) ;
TrashSound ( ) ;
return 0 ;
}
}
else
{
ddrval = IDirectSound_SetCooperativeLevel ( ppDS , hAppWnd , DSSCL_WRITEPRIMARY ) ;
if ( ddrval ! = DS_OK )
{
FCEUD_PrintError ( " DirectSound: Error setting cooperative level to DDSCL_WRITEPRIMARY. Forcing use of secondary sound buffer and trying again... " ) ;
soundoptions | = SO_SECONDARY ;
goto trysecondary ;
}
}
memset ( & dscaps , 0x00 , sizeof ( dscaps ) ) ;
dscaps . dwSize = sizeof ( dscaps ) ;
ddrval = IDirectSound_GetCaps ( ppDS , & dscaps ) ;
if ( ddrval ! = DS_OK )
{
FCEUD_PrintError ( " DirectSound: Error getting capabilities. " ) ;
return 0 ;
}
if ( dscaps . dwFlags & DSCAPS_EMULDRIVER )
FCEUD_PrintError ( " DirectSound: Sound device is being emulated through waveform-audio functions. Sound quality will most likely be awful. Try to update your sound device's sound drivers. " ) ;
IDirectSound_Compact ( ppDS ) ;
memset ( & DSBufferDesc , 0x00 , sizeof ( DSBUFFERDESC ) ) ;
DSBufferDesc . dwSize = sizeof ( DSBufferDesc ) ;
if ( soundoptions & SO_SECONDARY )
DSBufferDesc . dwFlags = DSBCAPS_PRIMARYBUFFER ;
else
DSBufferDesc . dwFlags = DSBCAPS_PRIMARYBUFFER | DSBCAPS_GETCURRENTPOSITION2 ;
ddrval = IDirectSound_CreateSoundBuffer ( ppDS , & DSBufferDesc , & ppbuf , 0 ) ;
if ( ddrval ! = DS_OK )
{
FCEUD_PrintError ( " DirectSound: Error creating primary buffer. " ) ;
TrashSound ( ) ;
return 0 ;
}
memset ( & wfa , 0x00 , sizeof ( wfa ) ) ;
if ( soundoptions & SO_FORCE8BIT )
bittage = 0 ;
else
{
bittage = 1 ;
if ( ( ! ( dscaps . dwFlags & DSCAPS_PRIMARY16BIT ) & & ! ( soundoptions & SO_SECONDARY ) ) | |
( ! ( dscaps . dwFlags & DSCAPS_SECONDARY16BIT ) & & ( soundoptions & SO_SECONDARY ) ) )
{
FCEUD_PrintError ( " DirectSound: 16-bit sound is not supported. Forcing 8-bit sound. " ) ;
bittage = 0 ;
soundoptions | = SO_FORCE8BIT ;
}
}
wf . wBitsPerSample = 8 < < bittage ;
wf . nBlockAlign = bittage + 1 ;
wf . nAvgBytesPerSec = wf . nSamplesPerSec * wf . nBlockAlign ;
ddrval = IDirectSoundBuffer_SetFormat ( ppbuf , & wf ) ;
if ( ddrval ! = DS_OK )
{
FCEUD_PrintError ( " DirectSound: Error setting primary buffer format. " ) ;
TrashSound ( ) ;
return 0 ;
}
IDirectSoundBuffer_GetFormat ( ppbuf , & wfa , sizeof ( wfa ) , 0 ) ;
if ( soundoptions & SO_SECONDARY )
{
memset ( & DSBufferDesc , 0x00 , sizeof ( DSBUFFERDESC ) ) ;
DSBufferDesc . dwSize = sizeof ( DSBufferDesc ) ;
DSBufferDesc . dwFlags = DSBCAPS_GETCURRENTPOSITION2 ;
if ( soundoptions & SO_GFOCUS )
DSBufferDesc . dwFlags | = DSBCAPS_GLOBALFOCUS ;
DSBufferDesc . dwBufferBytes = 65536 ;
DSBufferDesc . lpwfxFormat = & wfa ;
ddrval = IDirectSound_CreateSoundBuffer ( ppDS , & DSBufferDesc , & ppbufsec , 0 ) ;
if ( ddrval ! = DS_OK )
{
FCEUD_PrintError ( " DirectSound: Error creating secondary buffer. " ) ;
TrashSound ( ) ;
return 0 ;
}
}
//sprintf(TempArray,"%d\n",wfa.nSamplesPerSec);
//FCEUD_PrintError(TempArray);
if ( soundoptions & SO_SECONDARY )
{
DSBufferSize = 65536 ;
IDirectSoundBuffer_SetCurrentPosition ( ppbufsec , 0 ) ;
ppbufw = ppbufsec ;
}
else
{
memset ( & dsbcaps , 0 , sizeof ( dsbcaps ) ) ;
dsbcaps . dwSize = sizeof ( dsbcaps ) ;
ddrval = IDirectSoundBuffer_GetCaps ( ppbuf , & dsbcaps ) ;
if ( ddrval ! = DS_OK )
{
FCEUD_PrintError ( " DirectSound: Error getting buffer capabilities. " ) ;
TrashSound ( ) ;
return 0 ;
}
DSBufferSize = dsbcaps . dwBufferBytes ;
if ( DSBufferSize < 8192 )
{
FCEUD_PrintError ( " DirectSound: Primary buffer size is too small! " ) ;
TrashSound ( ) ;
return 0 ;
}
ppbufw = ppbuf ;
}
BufHowMuch = ( soundbuftime * soundrate / 1000 ) < < bittage ;
FCEUI_Sound ( soundrate ) ;
return 1 ;
}
static HWND uug = 0 ;
static void UpdateSD ( HWND hwndDlg )
{
int t ;
CheckDlgButton ( hwndDlg , 126 , soundo ? BST_CHECKED : BST_UNCHECKED ) ;
CheckDlgButton ( hwndDlg , 122 , ( soundoptions & SO_FORCE8BIT ) ? BST_CHECKED : BST_UNCHECKED ) ;
CheckDlgButton ( hwndDlg , 123 , ( soundoptions & SO_SECONDARY ) ? BST_CHECKED : BST_UNCHECKED ) ;
CheckDlgButton ( hwndDlg , 124 , ( soundoptions & SO_GFOCUS ) ? BST_CHECKED : BST_UNCHECKED ) ;
CheckDlgButton ( hwndDlg , 130 , ( soundoptions & SO_MUTEFA ) ? BST_CHECKED : BST_UNCHECKED ) ;
CheckDlgButton ( hwndDlg , 131 , ( soundoptions & SO_OLDUP ) ? BST_CHECKED : BST_UNCHECKED ) ;
SendDlgItemMessage ( hwndDlg , 129 , CB_SETCURSEL , soundquality , ( LPARAM ) ( LPSTR ) 0 ) ;
t = 0 ;
if ( soundrate = = 22050 ) t = 1 ;
else if ( soundrate = = 44100 ) t = 2 ;
else if ( soundrate = = 48000 ) t = 3 ;
else if ( soundrate = = 96000 ) t = 4 ;
SendDlgItemMessage ( hwndDlg , 200 , CB_SETCURSEL , t , ( LPARAM ) ( LPSTR ) 0 ) ;
}
BOOL CALLBACK SoundConCallB ( HWND hwndDlg , UINT uMsg , WPARAM wParam , LPARAM lParam )
{
switch ( uMsg ) {
case WM_NCRBUTTONDOWN :
case WM_NCMBUTTONDOWN :
case WM_NCLBUTTONDOWN : StopSound ( ) ; break ;
case WM_INITDIALOG :
/* Volume Trackbar */
SendDlgItemMessage ( hwndDlg , 500 , TBM_SETRANGE , 1 , MAKELONG ( 0 , 150 ) ) ;
SendDlgItemMessage ( hwndDlg , 500 , TBM_SETTICFREQ , 25 , 0 ) ;
SendDlgItemMessage ( hwndDlg , 500 , TBM_SETPOS , 1 , 150 - soundvolume ) ;
/* buffer size time trackbar */
SendDlgItemMessage ( hwndDlg , 128 , TBM_SETRANGE , 1 , MAKELONG ( 15 , 200 ) ) ;
SendDlgItemMessage ( hwndDlg , 128 , TBM_SETTICFREQ , 1 , 0 ) ;
SendDlgItemMessage ( hwndDlg , 128 , TBM_SETPOS , 1 , soundbuftime ) ;
{
char tbuf [ 8 ] ;
sprintf ( tbuf , " %d " , soundbuftime ) ;
SetDlgItemText ( hwndDlg , 666 , ( LPTSTR ) tbuf ) ;
}
SendDlgItemMessage ( hwndDlg , 129 , CB_ADDSTRING , 0 , ( LPARAM ) ( LPSTR ) " Low " ) ;
SendDlgItemMessage ( hwndDlg , 129 , CB_ADDSTRING , 0 , ( LPARAM ) ( LPSTR ) " High " ) ;
SendDlgItemMessage ( hwndDlg , 129 , CB_ADDSTRING , 0 , ( LPARAM ) ( LPSTR ) " Highest " ) ;
SendDlgItemMessage ( hwndDlg , 200 , CB_ADDSTRING , 0 , ( LPARAM ) ( LPSTR ) " 11025 " ) ;
SendDlgItemMessage ( hwndDlg , 200 , CB_ADDSTRING , 0 , ( LPARAM ) ( LPSTR ) " 22050 " ) ;
SendDlgItemMessage ( hwndDlg , 200 , CB_ADDSTRING , 0 , ( LPARAM ) ( LPSTR ) " 44100 " ) ;
SendDlgItemMessage ( hwndDlg , 200 , CB_ADDSTRING , 0 , ( LPARAM ) ( LPSTR ) " 48000 " ) ;
SendDlgItemMessage ( hwndDlg , 200 , CB_ADDSTRING , 0 , ( LPARAM ) ( LPSTR ) " 96000 " ) ;
UpdateSD ( hwndDlg ) ;
break ;
case WM_VSCROLL :
soundvolume = 150 - SendDlgItemMessage ( hwndDlg , 500 , TBM_GETPOS , 0 , 0 ) ;
FCEUI_SetSoundVolume ( soundvolume ) ;
break ;
case WM_HSCROLL :
{
char tbuf [ 8 ] ;
soundbuftime = SendDlgItemMessage ( hwndDlg , 128 , TBM_GETPOS , 0 , 0 ) ;
sprintf ( tbuf , " %d " , soundbuftime ) ;
SetDlgItemText ( hwndDlg , 666 , ( LPTSTR ) tbuf ) ;
BufHowMuch = ( soundbuftime * soundrate / 1000 ) < < bittage ;
//soundbufsize=(soundbuftime*soundrate/1000);
}
break ;
case WM_CLOSE :
case WM_QUIT : goto gornk ;
case WM_COMMAND :
switch ( HIWORD ( wParam ) )
{
case CBN_SELENDOK :
switch ( LOWORD ( wParam ) )
{
case 200 :
{
int tmp ;
tmp = SendDlgItemMessage ( hwndDlg , 200 , CB_GETCURSEL , 0 , ( LPARAM ) ( LPSTR ) 0 ) ;
if ( tmp = = 0 ) tmp = 11025 ;
else if ( tmp = = 1 ) tmp = 22050 ;
else if ( tmp = = 2 ) tmp = 44100 ;
else if ( tmp = = 3 ) tmp = 48000 ;
else tmp = 96000 ;
if ( tmp ! = soundrate )
{
soundrate = tmp ;
if ( soundrate < 44100 )
{
soundquality = 0 ;
FCEUI_SetSoundQuality ( 0 ) ;
UpdateSD ( hwndDlg ) ;
}
if ( soundo )
{
TrashSound ( ) ;
soundo = InitSound ( ) ;
UpdateSD ( hwndDlg ) ;
}
}
}
break ;
case 129 :
soundquality = SendDlgItemMessage ( hwndDlg , 129 , CB_GETCURSEL , 0 , ( LPARAM ) ( LPSTR ) 0 ) ;
if ( soundrate < 44100 ) soundquality = 0 ;
FCEUI_SetSoundQuality ( soundquality ) ;
UpdateSD ( hwndDlg ) ;
break ;
}
break ;
case BN_CLICKED :
switch ( LOWORD ( wParam ) )
{
case 122 : soundoptions ^ = SO_FORCE8BIT ;
if ( soundo )
{
TrashSound ( ) ;
soundo = InitSound ( ) ;
UpdateSD ( hwndDlg ) ;
}
break ;
case 123 : soundoptions ^ = SO_SECONDARY ;
if ( soundo )
{
TrashSound ( ) ;
soundo = InitSound ( ) ;
UpdateSD ( hwndDlg ) ;
}
break ;
case 124 : soundoptions ^ = SO_GFOCUS ;
if ( soundo )
{
TrashSound ( ) ;
soundo = InitSound ( ) ;
UpdateSD ( hwndDlg ) ;
}
break ;
case 130 : soundoptions ^ = SO_MUTEFA ;
break ;
case 131 : soundoptions ^ = SO_OLDUP ;
if ( soundo )
{
TrashSound ( ) ;
soundo = InitSound ( ) ;
UpdateSD ( hwndDlg ) ;
}
break ;
case 126 : soundo = ! soundo ;
if ( ! soundo ) TrashSound ( ) ;
else soundo = InitSound ( ) ;
UpdateSD ( hwndDlg ) ;
break ;
}
}
if ( ! ( wParam > > 16 ) )
switch ( wParam & 0xFFFF )
{
case 1 :
gornk :
DestroyWindow ( hwndDlg ) ;
uug = 0 ;
break ;
}
}
return 0 ;
}
void ConfigSound ( void )
{
if ( ! uug )
uug = CreateDialog ( fceu_hInstance , " SOUNDCONFIG " , 0 , SoundConCallB ) ;
else
SetFocus ( uug ) ;
}
void StopSound ( void )
{
if ( soundo )
{
VOID * LockPtr = 0 ;
DWORD LockLen = 0 ;
if ( DS_OK = = IDirectSoundBuffer_Lock ( ppbufw , 0 , DSBufferSize , & LockPtr , & LockLen , 0 , 0 , 0 ) )
{
//FCEUD_PrintError("K");
if ( bittage )
memset ( LockPtr , 0 , LockLen ) ;
else
memset ( LockPtr , 0x80 , LockLen ) ;
IDirectSoundBuffer_Unlock ( ppbufw , LockPtr , LockLen , 0 , 0 ) ;
}
//IDirectSoundBuffer_Stop(ppbufw);
}
}
void FCEUD_SoundToggle ( void )
{
if ( mute )
{
mute = 0 ;
FCEU_DispMessage ( " Sound mute off. " ) ;
}
else
{
mute = 1 ;
StopSound ( ) ;
FCEU_DispMessage ( " Sound mute on. " ) ;
}
}
void FCEUD_SoundVolumeAdjust ( int n )
{
switch ( n )
{
case - 1 : soundvolume - = 10 ; if ( soundvolume < 0 ) soundvolume = 0 ; break ;
case 0 : soundvolume = 100 ; break ;
case 1 : soundvolume + = 10 ; if ( soundvolume > 150 ) soundvolume = 150 ; break ;
}
mute = 0 ;
FCEUI_SetSoundVolume ( soundvolume ) ;
FCEU_DispMessage ( " Sound volume %d. " , soundvolume ) ;
}
2006-07-23 23:30:39 +00:00
# include "wave.cpp"