www.pudn.com > SoundFx.rar > soundfx.cpp, change:2004-07-10,size:46812b


#define STRICT 
#include <windows.h> 
#include "basetsd.h" 
#include <mmsystem.h> 
#include <mmreg.h> 
#include <dxerr9.h> 
#include <dsound.h> 
#include <cguid.h> 
#include <commctrl.h> 
#include <commdlg.h> 
#include <stdio.h> 
#include "DSUtil.h" 
#include "resource.h" 
#define SAFE_DELETE(p)       { if(p) { delete (p);     (p)=NULL; } } 
#define SAFE_DELETE_ARRAY(p) { if(p) { delete[] (p);   (p)=NULL; } } 
#define SAFE_RELEASE(p)      { if(p) { (p)->Release(); (p)=NULL; } } 
INT_PTR CALLBACK MainDlgProc( HWND hDlg, UINT msg,  WPARAM wParam, LPARAM lParam ); 
VOID    OnInitDialog( HWND hDlg ); 
VOID    OnTimer( HWND hDlg ); 
VOID    OnOpenSoundFile( HWND hDlg ); 
HRESULT OnPlaySound( HWND hDlg ); 
VOID    OnEffectChanged( HWND hDlg ); 
HRESULT ValidateWaveFile( HWND hDlg, TCHAR* strFileName ); 
HRESULT CreateAndFillBuffer( HWND hDlg, DWORD dwCreationFlags ); 
VOID    SetBufferOptions( LONG lFrequency, LONG lPakn, LONG lVolume ); 
VOID    EnablePlayUI( HWND hDlg, BOOL bEnable ); 
VOID    LoadParameterUI ( HWND hDlg, DWORD dwFXType ); 
VOID    ResetParameterUI ( HWND hDlg ); 
enum ESFXType 
{ 
    eSFX_chorus = 0, 
    eSFX_compressor, 
    eSFX_distortion, 
    eSFX_echo, 
    eSFX_flanger, 
    eSFX_gargle, 
    eSFX_parameq, 
    eSFX_reverb, 
     
    eNUM_SFX 
}; 
class CSoundFXManager 
{ 
public: 
    CSoundFXManager( ); 
    ~CSoundFXManager( ); 
public:  
    HRESULT Initialize ( LPDIRECTSOUNDBUFFER lpDSB, BOOL bLoadDefaultParamValues ); 
    HRESULT UnInitialize ( ); 
    HRESULT SetFXEnable( DWORD esfxType ); 
    HRESULT ActivateFX( ); 
    HRESULT DisableAllFX( ); 
    HRESULT LoadCurrentFXParameters( ); 
public:  
    LPDIRECTSOUNDFXCHORUS8      m_lpChorus; 
    LPDIRECTSOUNDFXCOMPRESSOR8  m_lpCompressor; 
    LPDIRECTSOUNDFXDISTORTION8  m_lpDistortion; 
    LPDIRECTSOUNDFXECHO8        m_lpEcho; 
    LPDIRECTSOUNDFXFLANGER8     m_lpFlanger; 
    LPDIRECTSOUNDFXGARGLE8      m_lpGargle; 
    LPDIRECTSOUNDFXPARAMEQ8     m_lpParamEq; 
    LPDIRECTSOUNDFXWAVESREVERB8 m_lpReverb; 
    DSFXChorus                  m_paramsChorus; 
    DSFXCompressor              m_paramsCompressor; 
    DSFXDistortion              m_paramsDistortion; 
    DSFXEcho                    m_paramsEcho; 
    DSFXFlanger                 m_paramsFlanger; 
    DSFXGargle                  m_paramsGargle; 
    DSFXParamEq                 m_paramsParamEq; 
    DSFXWavesReverb             m_paramsReverb; 
    LPDIRECTSOUNDBUFFER8        m_lpDSB8; 
protected: 
    DSEFFECTDESC                m_rgFxDesc[eNUM_SFX]; 
    const GUID *                m_rgRefGuids[eNUM_SFX]; 
    LPVOID *                    m_rgPtrs[eNUM_SFX]; 
    BOOL                        m_rgLoaded[eNUM_SFX]; 
    DWORD                       m_dwNumFX; 
    HRESULT EnableGenericFX( GUID guidSFXClass, REFGUID rguidInterface, LPVOID * ppObj ); 
    HRESULT LoadDefaultParamValues( ); 
}; 
#define             DEFAULT_SLIDER_MIN          1 
#define             DEFAULT_SLIDER_MAX          0x7FFFFF 
#define             DEFAULT_SLIDER_INC          DEFAULT_SLIDER_MAX >> 11 
CSoundManager *     g_lpSoundManager = NULL; 
CSound *            g_lpSound = NULL; 
CSoundFXManager *   g_lpFXManager = NULL; 
HINSTANCE           g_hInst = NULL; 
TCHAR               g_tszFilename[MAX_PATH]; 
DWORD               g_dwCurrentFXType           = eSFX_chorus; 
const TCHAR *       g_tszFXNames[] = { "Chorus", "Compressor", "Distortion", "Echo", 
                                       "Flanger", "Gargle", "Param Eq", "Reverb" }; 
INT APIENTRY WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR pCmdLine, INT nCmdShow ) 
{ 
    g_hInst = hInst; 
    CoInitialize( NULL ); 
     
    InitCommonControls(); 
     
    DialogBox( hInst, MAKEINTRESOURCE(IDD_MAIN), NULL, MainDlgProc ); 
    CoUninitialize(); 
    return TRUE; 
} 
INT_PTR CALLBACK MainDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam ) 
{ 
    HRESULT hr; 
    switch( msg ) 
    { 
        case WM_COMMAND: 
            switch( LOWORD(wParam) ) 
            { 
                case IDOK: 
                case IDCANCEL: 
                    EndDialog( hDlg, IDOK ); 
                    break; 
                case IDC_BUTTON_OPEN: 
                    OnOpenSoundFile( hDlg ); 
                    break; 
                case IDC_BUTTON_PLAY: 
                    if( FAILED( hr = OnPlaySound( hDlg ) ) ) 
                    { 
                        DXTRACE_ERR_MSGBOX( TEXT("OnPlaySound"), hr ); 
                        MessageBox( hDlg, "Error playing DirectSound buffer." 
                                    "Sample will now exit.", "DirectSound Sample", 
                                    MB_OK | MB_ICONERROR ); 
                        EndDialog( hDlg, IDABORT ); 
                    } 
                    break; 
                case IDC_BUTTON_STOP: 
                    if( g_lpSound ) 
                    { 
                        g_lpSound->Stop(); 
                        g_lpSound->Reset(); 
                    } 
                    g_lpFXManager->DisableAllFX( ); 
                    EnablePlayUI( hDlg, TRUE ); 
                    SetDlgItemText( hDlg, IDC_TEXT_STATUS, TEXT("Sound stopped.") ); 
                    break; 
                case IDC_RADIO_TRIANGLE: 
                case IDC_RADIO_SQUARE: 
                case IDC_RADIO_SINE: 
                case IDC_RADIO_NEG_180: 
                case IDC_RADIO_NEG_90: 
                case IDC_RADIO_ZERO: 
                case IDC_RADIO_90: 
                case IDC_RADIO_180: 
                    OnEffectChanged( hDlg ); 
                    break; 
                default: 
                    if( LOWORD( wParam ) >= IDC_RADIO_CHORUS && 
                        LOWORD( wParam ) <= IDC_RADIO_REVERB ) 
                    { 
                        g_dwCurrentFXType = LOWORD( wParam ) - IDC_RADIO_CHORUS; 
                        LoadParameterUI( hDlg, g_dwCurrentFXType ); 
                    } 
                    else 
                        return FALSE;  
            } 
            break; 
        case WM_TIMER: 
            OnTimer( hDlg ); 
            break; 
        case WM_INITDIALOG: 
            OnInitDialog( hDlg ); 
            break; 
        case WM_NOTIFY: 
        { 
             
             
             
                OnEffectChanged( hDlg ); 
             
            break; 
        } 
        case WM_DESTROY: 
             
            KillTimer( hDlg, 1 ); 
            SAFE_DELETE( g_lpFXManager ); 
            SAFE_DELETE( g_lpSound ); 
            SAFE_DELETE( g_lpSoundManager ); 
            break; 
        default: 
            return FALSE;  
    } 
    return TRUE;  
} 
VOID OnInitDialog( HWND hDlg ) 
{ 
    HRESULT hr; 
     
    HICON hIcon = LoadIcon( g_hInst, MAKEINTRESOURCE( IDI_ICON ) ); 
    PostMessage( hDlg, WM_SETICON, ICON_BIG, ( LPARAM ) hIcon ); 
    PostMessage( hDlg, WM_SETICON, ICON_SMALL, ( LPARAM ) hIcon ); 
     
     
     
    g_lpSoundManager = new CSoundManager(); 
    g_lpFXManager = new CSoundFXManager(); 
    if( NULL == g_lpSoundManager || 
        NULL == g_lpFXManager ) 
    { 
        DXTRACE_ERR_MSGBOX( TEXT("Initialize"), E_OUTOFMEMORY ); 
        EndDialog( hDlg, IDABORT ); 
        return; 
    } 
    if( FAILED( hr = g_lpSoundManager->Initialize( hDlg, DSSCL_PRIORITY ) ) ) 
    { 
        DXTRACE_ERR_MSGBOX( TEXT("Initialize"), hr ); 
        MessageBox( hDlg, "Error initializing DirectSound.  Sample will now exit.", 
                            "DirectSound Sample", MB_OK | MB_ICONERROR ); 
        EndDialog( hDlg, IDABORT ); 
        return; 
    } 
    if( FAILED( hr = g_lpSoundManager->SetPrimaryBufferFormat( 2, 22050, 16 ) ) ) 
    { 
        DXTRACE_ERR_MSGBOX( TEXT("SetPrimaryBufferFormat"), hr ); 
        MessageBox( hDlg, "Error initializing DirectSound.  Sample will now exit.", 
                          "DirectSound Sample", MB_OK | MB_ICONERROR ); 
        EndDialog( hDlg, IDABORT ); 
        return; 
    } 
     
    SetTimer( hDlg, 0, 250, NULL ); 
     
    TCHAR strFile[MAX_PATH]; 
    if( GetWindowsDirectory( strFile, MAX_PATH ) == 0 ) 
        return; 
    lstrcat( strFile, "\\media\\ding.wav" ); 
     
    if( FAILED( hr = ValidateWaveFile( hDlg, strFile ) ) ) 
    { 
         
        SetDlgItemText( hDlg, IDC_TEXT_FILENAME, TEXT("") ); 
        SetDlgItemText( hDlg, IDC_TEXT_STATUS, TEXT("No file loaded.") ); 
        EnableWindow( GetDlgItem( hDlg, IDC_BUTTON_PLAY ), FALSE ); 
        EnableWindow( GetDlgItem( hDlg, IDC_BUTTON_STOP ), FALSE ); 
        return; 
    } 
    if( SUCCEEDED( hr = g_lpSoundManager->Create( &g_lpSound, g_tszFilename, 
                                                  DSBCAPS_CTRLFX, GUID_NULL ) ) ) 
    { 
        g_lpFXManager->Initialize( g_lpSound->GetBuffer( 0 ), TRUE ); 
         
        g_lpFXManager->UnInitialize( ); 
        SAFE_DELETE( g_lpSound ); 
    } 
     
    CheckDlgButton( hDlg, IDC_CHECK_LOOP, BST_CHECKED ); 
    CheckRadioButton( hDlg, IDC_RADIO_CHORUS, IDC_RADIO_REVERB, IDC_RADIO_CHORUS ); 
    LoadParameterUI( hDlg, g_dwCurrentFXType ); 
    EnablePlayUI( hDlg, TRUE ); 
} 
HRESULT OnPlaySound( HWND hDlg ) 
{ 
    HRESULT hr; 
    DWORD   dwCreationFlags; 
    DWORD   dwLooped; 
    DWORD   i; 
    BOOL bLooped        = ( IsDlgButtonChecked( hDlg, IDC_CHECK_LOOP ) == BST_CHECKED ); 
     
    dwCreationFlags = DSBCAPS_CTRLFX; 
     
    g_lpFXManager->DisableAllFX( ); 
    SAFE_DELETE( g_lpSound ); 
     
     
     
    if( FAILED( hr = g_lpSoundManager->Create( &g_lpSound, g_tszFilename, 
                                               dwCreationFlags, GUID_NULL ) ) ) 
    { 
         
        DXTRACE_ERR( TEXT("Create"), hr ); 
        if( hr == DSERR_BUFFERTOOSMALL ) 
        { 
             
             
             
            SetDlgItemText( hDlg, IDC_TEXT_STATUS, TEXT("Wave file is too short (less than 150ms) for effect processing.") ); 
        } 
        else 
        { 
            SetDlgItemText( hDlg, IDC_TEXT_STATUS, TEXT("Could not create sound buffer.") ); 
        } 
        return S_FALSE; 
    } 
    g_lpFXManager->Initialize( g_lpSound->GetBuffer( 0 ), FALSE ); 
    for( i = IDC_CHECK_CHORUS; i <= IDC_CHECK_REVERB; i++ ) 
    { 
        if( IsDlgButtonChecked( hDlg, i ) == BST_CHECKED ) 
            g_lpFXManager->SetFXEnable( i - IDC_CHECK_CHORUS ); 
    } 
    if( FAILED( hr = g_lpFXManager->ActivateFX( ) ) ) 
        goto LFail; 
    if( FAILED( hr = g_lpFXManager->LoadCurrentFXParameters( ) ) ) 
        goto LFail; 
     
    dwLooped = bLooped ? DSBPLAY_LOOPING : 0L; 
    if( FAILED( hr = g_lpSound->Play( 0, dwLooped ) ) ) 
        return DXTRACE_ERR( TEXT("Play"), hr ); 
     
    EnablePlayUI( hDlg, FALSE ); 
    SetDlgItemText( hDlg, IDC_TEXT_STATUS, TEXT("Sound playing.") ); 
    return S_OK; 
LFail: 
     
    SetDlgItemText( hDlg, IDC_TEXT_STATUS, TEXT("Effects creation failed.  Some effects may not support 8-bit wave files.") ); 
    return S_OK; 
} 
VOID OnOpenSoundFile( HWND hDlg ) 
{ 
    static TCHAR strFileName[MAX_PATH] = TEXT(""); 
    static TCHAR strPath[MAX_PATH] = TEXT(""); 
     
    OPENFILENAME ofn = { sizeof(OPENFILENAME), hDlg, NULL, 
                         TEXT("Wave Files\0*.wav\0All Files\0*.*\0\0"), NULL, 
                         0, 1, strFileName, MAX_PATH, NULL, 0, strPath, 
                         TEXT("Open Sound File"), 
                         OFN_FILEMUSTEXIST|OFN_HIDEREADONLY, 0, 0, 
                         TEXT(".wav"), 0, NULL, NULL }; 
     
    if( '\0' == strPath[0] ) 
    { 
        if( GetWindowsDirectory( strPath, MAX_PATH ) != 0 ) 
        { 
            if( strcmp( &strPath[strlen(strPath)], TEXT("\\") ) ) 
                strcat( strPath, TEXT("\\") ); 
            strcat( strPath, TEXT("MEDIA") ); 
        } 
    } 
     
    
    
    SetDlgItemText( hDlg, IDC_TEXT_STATUS, TEXT("Loading file...") ); 
     
    g_lpFXManager->DisableAllFX( ); 
     
    if( TRUE != GetOpenFileName( &ofn ) ) 
    { 
         
        SetDlgItemText( hDlg, IDC_TEXT_FILENAME, TEXT("") ); 
        SetDlgItemText( hDlg, IDC_TEXT_STATUS, TEXT("No file loaded.") ); 
       
       
        return; 
    } 
    SetDlgItemText( hDlg, IDC_TEXT_FILENAME, TEXT("") ); 
     
    if( FAILED( ValidateWaveFile( hDlg, strFileName ) ) ) 
    { 
         
        SetDlgItemText( hDlg, IDC_TEXT_FILENAME, TEXT("") ); 
        
        
        return; 
    } 
    EnablePlayUI( hDlg, TRUE ); 
     
    strcpy( strPath, strFileName ); 
    char* strLastSlash = strrchr( strPath, '\\' ); 
    if( strLastSlash ) 
        strLastSlash[0] = '\0'; 
} 
VOID OnTimer( HWND hDlg ) 
{ 
    if( IsWindowEnabled( GetDlgItem( hDlg, IDC_BUTTON_STOP ) ) ) 
    { 
         
        if( g_lpSound && !g_lpSound->IsSoundPlaying() ) 
        { 
             
            EnablePlayUI( hDlg, TRUE ); 
            SetDlgItemText( hDlg, IDC_TEXT_STATUS, TEXT("Sound stopped.") ); 
        } 
    } 
} 
VOID EnablePlayUI( HWND hDlg, BOOL bEnable ) 
{ 
    if( bEnable ) 
    { 
        EnableWindow( GetDlgItem( hDlg, IDC_CHECK_LOOP      ), TRUE ); 
        EnableWindow( GetDlgItem( hDlg, IDC_BUTTON_PLAY     ), TRUE ); 
        EnableWindow( GetDlgItem( hDlg, IDC_BUTTON_STOP     ), FALSE ); 
        SetFocus(     GetDlgItem( hDlg, IDC_BUTTON_PLAY )   ); 
    } 
    else 
    { 
        EnableWindow( GetDlgItem( hDlg, IDC_CHECK_LOOP      ), FALSE ); 
        EnableWindow( GetDlgItem( hDlg, IDC_BUTTON_PLAY     ), FALSE ); 
        EnableWindow( GetDlgItem( hDlg, IDC_BUTTON_STOP     ), TRUE ); 
        SetFocus(     GetDlgItem( hDlg, IDC_BUTTON_STOP )   ); 
    } 
    for( DWORD i = IDC_CHECK_CHORUS; i <= IDC_CHECK_REVERB; i++ ) 
        EnableWindow( GetDlgItem( hDlg, i ), bEnable ); 
} 
VOID ResetParameterUI( HWND hwndDlg ) 
{ 
    HWND hwndItem; 
    DWORD i; 
    for ( i = IDC_PARAM_NAME1; i <= IDC_PARAM_MAX6; i++ ) 
    { 
        hwndItem = GetDlgItem( hwndDlg, i ); 
        SendMessage( hwndItem, WM_SETTEXT, 0, ( LPARAM ) TEXT( "- - -" ) ); 
        EnableWindow( hwndItem, FALSE ); 
    } 
    for ( i = IDC_SLIDER1; i <= IDC_SLIDER6; i += 5 ) 
    { 
        PostMessage( GetDlgItem( hwndDlg, i ), TBM_SETRANGEMIN, FALSE, DEFAULT_SLIDER_MIN ); 
        PostMessage( GetDlgItem( hwndDlg, i ), TBM_SETRANGEMAX, FALSE, DEFAULT_SLIDER_MAX ); 
        PostMessage( GetDlgItem( hwndDlg, i ), TBM_SETLINESIZE, FALSE, DEFAULT_SLIDER_INC ); 
        PostMessage( GetDlgItem( hwndDlg, i ), TBM_SETPOS, TRUE, 0 ); 
    } 
    EnableWindow( GetDlgItem( hwndDlg, IDC_RADIO_TRIANGLE ), FALSE ); 
    EnableWindow( GetDlgItem( hwndDlg, IDC_RADIO_SQUARE ), FALSE ); 
    EnableWindow( GetDlgItem( hwndDlg, IDC_RADIO_SINE ), FALSE ); 
    EnableWindow( GetDlgItem( hwndDlg, IDC_FRAME_WAVEFORM ), FALSE ); 
    EnableWindow( GetDlgItem( hwndDlg, IDC_RADIO_NEG_180 ), FALSE ); 
    EnableWindow( GetDlgItem( hwndDlg, IDC_RADIO_NEG_90 ), FALSE ); 
    EnableWindow( GetDlgItem( hwndDlg, IDC_RADIO_ZERO ), FALSE ); 
    EnableWindow( GetDlgItem( hwndDlg, IDC_RADIO_90 ), FALSE ); 
    EnableWindow( GetDlgItem( hwndDlg, IDC_RADIO_180 ), FALSE ); 
    EnableWindow( GetDlgItem( hwndDlg, IDC_FRAME_PHASE ), FALSE ); 
} 
VOID EnableSingleParameter( HWND hwndDlg, DWORD resID ) 
{ 
    for ( DWORD i = resID; i < resID + 5; i++ ) 
        EnableWindow( GetDlgItem( hwndDlg, i ), TRUE ); 
} 
VOID PosSlider( HWND hwndDlg, DWORD dwSlider, FLOAT val, FLOAT min, FLOAT max, 
                FLOAT fSliderInc ) 
{ 
    HWND hwndSlider = GetDlgItem( hwndDlg, dwSlider ); 
    LONG lSliderInc = (LONG) ( (fSliderInc / (max - min)) * DEFAULT_SLIDER_MAX ); 
    PostMessage( hwndSlider, TBM_SETLINESIZE, FALSE, lSliderInc ); 
    FLOAT res = ( val - min ) / ( max - min ); 
    if( res < 0.0f ) 
        res = 0.0f; 
    else if( res > 1.0f ) 
        res = 1.0f; 
    LONG pos = (LONG) ( res * DEFAULT_SLIDER_MAX ); 
    PostMessage( hwndSlider, TBM_SETPOS, TRUE, pos ); 
} 
VOID LoadSingleParameter( HWND hwndDlg, DWORD id, const TCHAR * tszName, FLOAT val, 
                          FLOAT min, FLOAT max, FLOAT fSliderInc = 0.1f, 
                          DWORD dwPrecision = 1 ) 
{ 
    TCHAR tszstr[MAX_PATH]; 
     
    EnableSingleParameter( hwndDlg, id ); 
    SendMessage( GetDlgItem( hwndDlg, id ), WM_SETTEXT, 0, ( LPARAM ) tszName ); 
    switch( dwPrecision ) 
    { 
        case 0: 
            sprintf( tszstr, "%.0f", val ); 
            SendMessage( GetDlgItem( hwndDlg, id + 1 ), WM_SETTEXT, 0, ( LPARAM ) tszstr ); 
            sprintf( tszstr, "%.0f", min ); 
            SendMessage( GetDlgItem( hwndDlg, id + 3 ), WM_SETTEXT, 0, ( LPARAM ) tszstr ); 
            sprintf( tszstr, "%.0f", max ); 
            SendMessage( GetDlgItem( hwndDlg, id + 4 ), WM_SETTEXT, 0, ( LPARAM ) tszstr ); 
            break; 
        case 1: 
            sprintf( tszstr, "%.1f", val ); 
            SendMessage( GetDlgItem( hwndDlg, id + 1 ), WM_SETTEXT, 0, ( LPARAM ) tszstr ); 
            sprintf( tszstr, "%.1f", min ); 
            SendMessage( GetDlgItem( hwndDlg, id + 3 ), WM_SETTEXT, 0, ( LPARAM ) tszstr ); 
            sprintf( tszstr, "%.1f", max ); 
            SendMessage( GetDlgItem( hwndDlg, id + 4 ), WM_SETTEXT, 0, ( LPARAM ) tszstr ); 
            break; 
        default: 
        case 2: 
            sprintf( tszstr, "%.2f", val ); 
            SendMessage( GetDlgItem( hwndDlg, id + 1 ), WM_SETTEXT, 0, ( LPARAM ) tszstr ); 
            sprintf( tszstr, "%.2f", min ); 
            SendMessage( GetDlgItem( hwndDlg, id + 3 ), WM_SETTEXT, 0, ( LPARAM ) tszstr ); 
            sprintf( tszstr, "%.2f", max ); 
            SendMessage( GetDlgItem( hwndDlg, id + 4 ), WM_SETTEXT, 0, ( LPARAM ) tszstr ); 
            break; 
    } 
    PosSlider( hwndDlg, id + 2, val, min, max, fSliderInc ); 
} 
VOID SaveSingleParameter( HWND hwndDlg, DWORD id, FLOAT * val, FLOAT min, FLOAT max, DWORD dwPrecision = 1 ) 
{ 
    TCHAR tszstr[MAX_PATH]; 
    DWORD pos = ( DWORD ) SendMessage( GetDlgItem( hwndDlg, id + 2), TBM_GETPOS, 0, 0 ); 
    FLOAT percent = ( FLOAT ) ( pos - DEFAULT_SLIDER_MIN ) / ( FLOAT ) ( DEFAULT_SLIDER_MAX - DEFAULT_SLIDER_MIN ); 
    *val = percent * ( max - min ) + min; 
    switch( dwPrecision ) 
    { 
        case 0: 
            sprintf( tszstr, "%.0f", *val ); 
            break; 
        case 1: 
            sprintf( tszstr, "%.1f", *val ); 
            break; 
        case 2: 
        default: 
            sprintf( tszstr, "%.2f", *val ); 
            break; 
    } 
    SendMessage( GetDlgItem( hwndDlg, id + 1 ), WM_SETTEXT, 0, ( LPARAM ) tszstr ); 
} 
VOID LoadWaveformRadio( HWND hwndDlg, LONG waveform, LONG triangle, LONG square, LONG sine ) 
{ 
    if( waveform == triangle ) 
        CheckRadioButton( hwndDlg, IDC_RADIO_TRIANGLE, IDC_RADIO_SINE, IDC_RADIO_TRIANGLE ); 
    else if( waveform == square ) 
        CheckRadioButton( hwndDlg, IDC_RADIO_TRIANGLE, IDC_RADIO_SINE, IDC_RADIO_SQUARE ); 
    else if( waveform == sine ) 
        CheckRadioButton( hwndDlg, IDC_RADIO_TRIANGLE, IDC_RADIO_SINE, IDC_RADIO_SINE ); 
    if( triangle >= 0 ) 
        EnableWindow( GetDlgItem( hwndDlg, IDC_RADIO_TRIANGLE ), TRUE ); 
    if( square >= 0 ) 
        EnableWindow( GetDlgItem( hwndDlg, IDC_RADIO_SQUARE ), TRUE ); 
    if( sine >= 0 ) 
        EnableWindow( GetDlgItem( hwndDlg, IDC_RADIO_SINE ), TRUE ); 
    EnableWindow( GetDlgItem( hwndDlg, IDC_FRAME_WAVEFORM ), ( triangle + square + sine != -3 ) ); 
} 
VOID LoadPhaseRadio( HWND hwndDlg, LONG phase, LONG neg180, LONG neg90, LONG zero, LONG pos90, LONG pos180 ) 
{ 
    for( int i = IDC_RADIO_NEG_180; i <= IDC_RADIO_180; i++ ) 
        EnableWindow( GetDlgItem( hwndDlg, i ), TRUE ); 
    EnableWindow( GetDlgItem( hwndDlg, IDC_FRAME_PHASE), TRUE ); 
    if( phase == neg180 ) 
        CheckRadioButton( hwndDlg, IDC_RADIO_NEG_180, IDC_RADIO_90, IDC_RADIO_NEG_180 ); 
    else if( phase == neg90 ) 
        CheckRadioButton( hwndDlg, IDC_RADIO_NEG_180, IDC_RADIO_90, IDC_RADIO_NEG_90 ); 
    else if( phase == zero ) 
        CheckRadioButton( hwndDlg, IDC_RADIO_NEG_180, IDC_RADIO_90, IDC_RADIO_ZERO ); 
    else if( phase == pos90 ) 
        CheckRadioButton( hwndDlg, IDC_RADIO_NEG_180, IDC_RADIO_90, IDC_RADIO_90 ); 
    else if( phase == pos180 ) 
        CheckRadioButton( hwndDlg, IDC_RADIO_NEG_180, IDC_RADIO_90, IDC_RADIO_180 ); 
} 
VOID LoadParameterUI( HWND hwndDlg, DWORD dwFXType ) 
{ 
    TCHAR tszstr[MAX_PATH]; 
     
    ResetParameterUI( hwndDlg ); 
    sprintf( tszstr, "修改[%s]音效的参数", g_tszFXNames[dwFXType] ); 
    SetDlgItemText( hwndDlg, IDC_FRAME, tszstr ); 
    switch( dwFXType) 
    { 
        case eSFX_chorus: 
        { 
            LoadSingleParameter( hwndDlg, IDC_PARAM_NAME1, TEXT( "Wet/Dry Mix (%)" ), g_lpFXManager->m_paramsChorus.fWetDryMix, DSFXCHORUS_WETDRYMIX_MIN, DSFXCHORUS_WETDRYMIX_MAX ); 
            LoadSingleParameter( hwndDlg, IDC_PARAM_NAME2, TEXT( "Depth (%)" ), g_lpFXManager->m_paramsChorus.fDepth, DSFXCHORUS_DEPTH_MIN, DSFXCHORUS_DEPTH_MAX ); 
            LoadSingleParameter( hwndDlg, IDC_PARAM_NAME3, TEXT( "Feedback (%)" ), g_lpFXManager->m_paramsChorus.fFeedback, DSFXCHORUS_FEEDBACK_MIN, DSFXCHORUS_FEEDBACK_MAX ); 
            LoadSingleParameter( hwndDlg, IDC_PARAM_NAME4, TEXT( "Frequency (Hz)" ), g_lpFXManager->m_paramsChorus.fFrequency, DSFXCHORUS_FREQUENCY_MIN, DSFXCHORUS_FREQUENCY_MAX ); 
            LoadSingleParameter( hwndDlg, IDC_PARAM_NAME5, TEXT( "Delay (ms)" ), g_lpFXManager->m_paramsChorus.fDelay, DSFXCHORUS_DELAY_MIN, DSFXCHORUS_DELAY_MAX ); 
            LoadWaveformRadio( hwndDlg, g_lpFXManager->m_paramsChorus.lWaveform, DSFXCHORUS_WAVE_TRIANGLE, -1, DSFXCHORUS_WAVE_SIN ); 
            LoadPhaseRadio( hwndDlg, g_lpFXManager->m_paramsChorus.lPhase, DSFXCHORUS_PHASE_NEG_180, DSFXCHORUS_PHASE_NEG_90, DSFXCHORUS_PHASE_ZERO, DSFXCHORUS_PHASE_90, DSFXCHORUS_PHASE_180 ); 
            break; 
        } 
        case eSFX_compressor: 
        { 
            LoadSingleParameter( hwndDlg, IDC_PARAM_NAME1, TEXT( "Gain (dB)" ), g_lpFXManager->m_paramsCompressor.fGain, DSFXCOMPRESSOR_GAIN_MIN, DSFXCOMPRESSOR_GAIN_MAX ); 
            LoadSingleParameter( hwndDlg, IDC_PARAM_NAME2, TEXT( "Attack (ms)" ), g_lpFXManager->m_paramsCompressor.fAttack, DSFXCOMPRESSOR_ATTACK_MIN, DSFXCOMPRESSOR_ATTACK_MAX ); 
            LoadSingleParameter( hwndDlg, IDC_PARAM_NAME3, TEXT( "Release (ms)" ), g_lpFXManager->m_paramsCompressor.fRelease, DSFXCOMPRESSOR_RELEASE_MIN, DSFXCOMPRESSOR_RELEASE_MAX ); 
            LoadSingleParameter( hwndDlg, IDC_PARAM_NAME4, TEXT( "Threshold (dB)" ), g_lpFXManager->m_paramsCompressor.fThreshold, DSFXCOMPRESSOR_THRESHOLD_MIN, DSFXCOMPRESSOR_THRESHOLD_MAX ); 
            LoadSingleParameter( hwndDlg, IDC_PARAM_NAME5, TEXT( "Ratio (x:1)" ), g_lpFXManager->m_paramsCompressor.fRatio, DSFXCOMPRESSOR_RATIO_MIN, DSFXCOMPRESSOR_RATIO_MAX ); 
            LoadSingleParameter( hwndDlg, IDC_PARAM_NAME6, TEXT( "Predelay (ms)" ), g_lpFXManager->m_paramsCompressor.fPredelay, DSFXCOMPRESSOR_PREDELAY_MIN, DSFXCOMPRESSOR_PREDELAY_MAX, 0.05f, 2 ); 
            break; 
        } 
        case eSFX_distortion: 
        { 
            LoadSingleParameter( hwndDlg, IDC_PARAM_NAME1, TEXT( "Gain (dB)" ), g_lpFXManager->m_paramsDistortion.fGain, DSFXDISTORTION_GAIN_MIN, DSFXDISTORTION_GAIN_MAX ); 
            LoadSingleParameter( hwndDlg, IDC_PARAM_NAME2, TEXT( "Edge (%)" ), g_lpFXManager->m_paramsDistortion.fEdge, DSFXDISTORTION_EDGE_MIN, DSFXDISTORTION_EDGE_MAX ); 
            LoadSingleParameter( hwndDlg, IDC_PARAM_NAME3, TEXT( "PostEQ Center Freq (Hz)" ), g_lpFXManager->m_paramsDistortion.fPostEQCenterFrequency, DSFXDISTORTION_POSTEQCENTERFREQUENCY_MIN, DSFXDISTORTION_POSTEQCENTERFREQUENCY_MAX, 1.0f, 0 ); 
            LoadSingleParameter( hwndDlg, IDC_PARAM_NAME4, TEXT( "PostEQ Bandwidth (Hz)" ), g_lpFXManager->m_paramsDistortion.fPostEQBandwidth, DSFXDISTORTION_POSTEQBANDWIDTH_MIN, DSFXDISTORTION_POSTEQBANDWIDTH_MAX, 1.0f, 0 ); 
            LoadSingleParameter( hwndDlg, IDC_PARAM_NAME5, TEXT( "PreLowpass Cutoff (Hz)" ), g_lpFXManager->m_paramsDistortion.fPreLowpassCutoff, DSFXDISTORTION_PRELOWPASSCUTOFF_MIN, DSFXDISTORTION_PRELOWPASSCUTOFF_MAX, 1.0f, 0 ); 
            break; 
        } 
        case eSFX_echo: 
        { 
            LoadSingleParameter( hwndDlg, IDC_PARAM_NAME1, TEXT( "Wet/Dry Mix (%)" ), g_lpFXManager->m_paramsEcho.fWetDryMix, DSFXECHO_WETDRYMIX_MIN, DSFXECHO_WETDRYMIX_MAX ); 
            LoadSingleParameter( hwndDlg, IDC_PARAM_NAME2, TEXT( "Feedback (%)" ), g_lpFXManager->m_paramsEcho.fFeedback, DSFXECHO_FEEDBACK_MIN, DSFXECHO_FEEDBACK_MAX ); 
            LoadSingleParameter( hwndDlg, IDC_PARAM_NAME3, TEXT( "Left Delay (ms)" ), g_lpFXManager->m_paramsEcho.fLeftDelay, DSFXECHO_LEFTDELAY_MIN, DSFXECHO_LEFTDELAY_MAX ); 
            LoadSingleParameter( hwndDlg, IDC_PARAM_NAME4, TEXT( "Right Delay (ms)" ), g_lpFXManager->m_paramsEcho.fRightDelay, DSFXECHO_RIGHTDELAY_MIN, DSFXECHO_RIGHTDELAY_MAX ); 
            LoadSingleParameter( hwndDlg, IDC_PARAM_NAME5, TEXT( "Pan Delay (bool)" ), (float) g_lpFXManager->m_paramsEcho.lPanDelay, DSFXECHO_PANDELAY_MIN, DSFXECHO_PANDELAY_MAX ); 
            break; 
        } 
        case eSFX_flanger: 
        { 
            LoadSingleParameter( hwndDlg, IDC_PARAM_NAME1, TEXT( "Wet/Dry Mix (%)" ), g_lpFXManager->m_paramsFlanger.fWetDryMix, DSFXFLANGER_WETDRYMIX_MIN, DSFXFLANGER_WETDRYMIX_MAX ); 
            LoadSingleParameter( hwndDlg, IDC_PARAM_NAME2, TEXT( "Depth (%)" ), g_lpFXManager->m_paramsFlanger.fDepth, DSFXFLANGER_DEPTH_MIN, DSFXFLANGER_DEPTH_MAX ); 
            LoadSingleParameter( hwndDlg, IDC_PARAM_NAME3, TEXT( "Feedback (%)" ), g_lpFXManager->m_paramsFlanger.fFeedback, DSFXFLANGER_FEEDBACK_MIN, DSFXFLANGER_FEEDBACK_MAX ); 
            LoadSingleParameter( hwndDlg, IDC_PARAM_NAME4, TEXT( "Frequency (Hz)" ), g_lpFXManager->m_paramsFlanger.fFrequency, DSFXFLANGER_FREQUENCY_MIN, DSFXFLANGER_FREQUENCY_MAX, 0.01f, 2 ); 
            LoadSingleParameter( hwndDlg, IDC_PARAM_NAME5, TEXT( "Delay (ms)" ), g_lpFXManager->m_paramsFlanger.fDelay, DSFXFLANGER_DELAY_MIN, DSFXFLANGER_DELAY_MAX, 0.01f, 2 ); 
            LoadWaveformRadio( hwndDlg, g_lpFXManager->m_paramsFlanger.lWaveform, DSFXFLANGER_WAVE_TRIANGLE, -1, DSFXFLANGER_WAVE_SIN ); 
            LoadPhaseRadio( hwndDlg, g_lpFXManager->m_paramsFlanger.lPhase, DSFXFLANGER_PHASE_NEG_180, DSFXFLANGER_PHASE_NEG_90, DSFXFLANGER_PHASE_ZERO, DSFXFLANGER_PHASE_90, DSFXFLANGER_PHASE_180 ); 
            break; 
        } 
        case eSFX_gargle: 
        { 
            LoadSingleParameter( hwndDlg, IDC_PARAM_NAME1, TEXT( "Rate (Hz)" ), ( FLOAT ) g_lpFXManager->m_paramsGargle.dwRateHz, ( FLOAT ) DSFXGARGLE_RATEHZ_MIN, ( FLOAT ) DSFXGARGLE_RATEHZ_MAX ); 
            LoadWaveformRadio( hwndDlg, g_lpFXManager->m_paramsGargle.dwWaveShape, DSFXGARGLE_WAVE_TRIANGLE, DSFXGARGLE_WAVE_SQUARE, -1 ); 
            break; 
        } 
        case eSFX_parameq: 
        { 
            LoadSingleParameter( hwndDlg, IDC_PARAM_NAME1, TEXT( "Center Freq (Hz)" ), g_lpFXManager->m_paramsParamEq.fCenter, DSFXPARAMEQ_CENTER_MIN, DSFXPARAMEQ_CENTER_MAX ); 
            LoadSingleParameter( hwndDlg, IDC_PARAM_NAME2, TEXT( "Bandwidth (Hz)" ), g_lpFXManager->m_paramsParamEq.fBandwidth, DSFXPARAMEQ_BANDWIDTH_MIN, DSFXPARAMEQ_BANDWIDTH_MAX ); 
            LoadSingleParameter( hwndDlg, IDC_PARAM_NAME3, TEXT( "Gain (dB)" ), g_lpFXManager->m_paramsParamEq.fGain, DSFXPARAMEQ_GAIN_MIN, DSFXPARAMEQ_GAIN_MAX ); 
            break; 
        } 
        case eSFX_reverb: 
        { 
            LoadSingleParameter( hwndDlg, IDC_PARAM_NAME1, TEXT( "In Gain (dB)" ), g_lpFXManager->m_paramsReverb.fInGain, DSFX_WAVESREVERB_INGAIN_MIN, DSFX_WAVESREVERB_INGAIN_MAX ); 
            LoadSingleParameter( hwndDlg, IDC_PARAM_NAME2, TEXT( "Reverb Mix (dB)" ), g_lpFXManager->m_paramsReverb.fReverbMix, DSFX_WAVESREVERB_REVERBMIX_MIN, DSFX_WAVESREVERB_REVERBMIX_MAX ); 
            LoadSingleParameter( hwndDlg, IDC_PARAM_NAME3, TEXT( "Reverb Time (ms)" ), g_lpFXManager->m_paramsReverb.fReverbTime, DSFX_WAVESREVERB_REVERBTIME_MIN, DSFX_WAVESREVERB_REVERBTIME_MAX ); 
            LoadSingleParameter( hwndDlg, IDC_PARAM_NAME4, TEXT( "HighFreq RT Ratio (x:1)" ), g_lpFXManager->m_paramsReverb.fHighFreqRTRatio, DSFX_WAVESREVERB_HIGHFREQRTRATIO_MIN, DSFX_WAVESREVERB_HIGHFREQRTRATIO_MAX, 0.01f, 2 ); 
            break; 
        } 
    } 
} 
VOID OnEffectChanged( HWND hwndDlg ) 
{ 
    switch( g_dwCurrentFXType ) 
    { 
        case eSFX_chorus: 
        { 
            SaveSingleParameter( hwndDlg, IDC_PARAM_NAME1, &g_lpFXManager->m_paramsChorus.fWetDryMix, DSFXCHORUS_WETDRYMIX_MIN, DSFXCHORUS_WETDRYMIX_MAX ); 
            SaveSingleParameter( hwndDlg, IDC_PARAM_NAME2, &g_lpFXManager->m_paramsChorus.fDepth, DSFXCHORUS_DEPTH_MIN, DSFXCHORUS_DEPTH_MAX ); 
            SaveSingleParameter( hwndDlg, IDC_PARAM_NAME3, &g_lpFXManager->m_paramsChorus.fFeedback, DSFXCHORUS_FEEDBACK_MIN, DSFXCHORUS_FEEDBACK_MAX ); 
            SaveSingleParameter( hwndDlg, IDC_PARAM_NAME4, &g_lpFXManager->m_paramsChorus.fFrequency, DSFXCHORUS_FREQUENCY_MIN, DSFXCHORUS_FREQUENCY_MAX ); 
            SaveSingleParameter( hwndDlg, IDC_PARAM_NAME5, &g_lpFXManager->m_paramsChorus.fDelay, DSFXCHORUS_DELAY_MIN, DSFXCHORUS_DELAY_MAX ); 
            if( IsDlgButtonChecked( hwndDlg, IDC_RADIO_TRIANGLE ) == BST_CHECKED ) 
                g_lpFXManager->m_paramsChorus.lWaveform = DSFXCHORUS_WAVE_TRIANGLE; 
            else 
                g_lpFXManager->m_paramsChorus.lWaveform = DSFXCHORUS_WAVE_SIN; 
            if( IsDlgButtonChecked( hwndDlg, IDC_RADIO_NEG_180 ) == BST_CHECKED ) 
                g_lpFXManager->m_paramsChorus.lPhase = DSFXCHORUS_PHASE_NEG_180; 
            else if( IsDlgButtonChecked( hwndDlg, IDC_RADIO_NEG_90 ) == BST_CHECKED ) 
                g_lpFXManager->m_paramsChorus.lPhase = DSFXCHORUS_PHASE_NEG_90; 
            else if( IsDlgButtonChecked( hwndDlg, IDC_RADIO_ZERO ) == BST_CHECKED ) 
                g_lpFXManager->m_paramsChorus.lPhase = DSFXCHORUS_PHASE_ZERO; 
            else if( IsDlgButtonChecked( hwndDlg, IDC_RADIO_90 ) == BST_CHECKED ) 
                g_lpFXManager->m_paramsChorus.lPhase = DSFXCHORUS_PHASE_90; 
            else 
                g_lpFXManager->m_paramsChorus.lPhase = DSFXCHORUS_PHASE_180; 
            if( g_lpFXManager->m_lpChorus ) 
                g_lpFXManager->m_lpChorus->SetAllParameters( &g_lpFXManager->m_paramsChorus ); 
            break; 
        } 
        case eSFX_compressor: 
        { 
            SaveSingleParameter( hwndDlg, IDC_PARAM_NAME1, &g_lpFXManager->m_paramsCompressor.fGain, DSFXCOMPRESSOR_GAIN_MIN, DSFXCOMPRESSOR_GAIN_MAX ); 
            SaveSingleParameter( hwndDlg, IDC_PARAM_NAME2, &g_lpFXManager->m_paramsCompressor.fAttack, DSFXCOMPRESSOR_ATTACK_MIN, DSFXCOMPRESSOR_ATTACK_MAX ); 
            SaveSingleParameter( hwndDlg, IDC_PARAM_NAME3, &g_lpFXManager->m_paramsCompressor.fRelease, DSFXCOMPRESSOR_RELEASE_MIN, DSFXCOMPRESSOR_RELEASE_MAX ); 
            SaveSingleParameter( hwndDlg, IDC_PARAM_NAME4, &g_lpFXManager->m_paramsCompressor.fThreshold, DSFXCOMPRESSOR_THRESHOLD_MIN, DSFXCOMPRESSOR_THRESHOLD_MAX ); 
            SaveSingleParameter( hwndDlg, IDC_PARAM_NAME5, &g_lpFXManager->m_paramsCompressor.fRatio, DSFXCOMPRESSOR_RATIO_MIN, DSFXCOMPRESSOR_RATIO_MAX ); 
            SaveSingleParameter( hwndDlg, IDC_PARAM_NAME6, &g_lpFXManager->m_paramsCompressor.fPredelay, DSFXCOMPRESSOR_PREDELAY_MIN, DSFXCOMPRESSOR_PREDELAY_MAX, 2 ); 
            if( g_lpFXManager->m_lpCompressor ) 
                g_lpFXManager->m_lpCompressor->SetAllParameters( &g_lpFXManager->m_paramsCompressor ); 
            break; 
        } 
        case eSFX_distortion: 
        { 
            SaveSingleParameter( hwndDlg, IDC_PARAM_NAME1, &g_lpFXManager->m_paramsDistortion.fGain, DSFXDISTORTION_GAIN_MIN, DSFXDISTORTION_GAIN_MAX ); 
            SaveSingleParameter( hwndDlg, IDC_PARAM_NAME2, &g_lpFXManager->m_paramsDistortion.fEdge, DSFXDISTORTION_EDGE_MIN, DSFXDISTORTION_EDGE_MAX ); 
            SaveSingleParameter( hwndDlg, IDC_PARAM_NAME3, &g_lpFXManager->m_paramsDistortion.fPostEQCenterFrequency, DSFXDISTORTION_POSTEQCENTERFREQUENCY_MIN, DSFXDISTORTION_POSTEQCENTERFREQUENCY_MAX, 0 ); 
            SaveSingleParameter( hwndDlg, IDC_PARAM_NAME4, &g_lpFXManager->m_paramsDistortion.fPostEQBandwidth, DSFXDISTORTION_POSTEQBANDWIDTH_MIN, DSFXDISTORTION_POSTEQBANDWIDTH_MAX, 0 ); 
            SaveSingleParameter( hwndDlg, IDC_PARAM_NAME5, &g_lpFXManager->m_paramsDistortion.fPreLowpassCutoff, DSFXDISTORTION_PRELOWPASSCUTOFF_MIN, DSFXDISTORTION_PRELOWPASSCUTOFF_MAX, 0 ); 
            if( g_lpFXManager->m_lpDistortion ) 
                g_lpFXManager->m_lpDistortion->SetAllParameters( &g_lpFXManager->m_paramsDistortion ); 
            break; 
        } 
        case eSFX_echo: 
        { 
            SaveSingleParameter( hwndDlg, IDC_PARAM_NAME1, &g_lpFXManager->m_paramsEcho.fWetDryMix, DSFXECHO_WETDRYMIX_MIN, DSFXECHO_WETDRYMIX_MAX ); 
            SaveSingleParameter( hwndDlg, IDC_PARAM_NAME2, &g_lpFXManager->m_paramsEcho.fFeedback, DSFXECHO_FEEDBACK_MIN, DSFXECHO_FEEDBACK_MAX ); 
            SaveSingleParameter( hwndDlg, IDC_PARAM_NAME3, &g_lpFXManager->m_paramsEcho.fLeftDelay, DSFXECHO_LEFTDELAY_MIN, DSFXECHO_LEFTDELAY_MAX ); 
            SaveSingleParameter( hwndDlg, IDC_PARAM_NAME4, &g_lpFXManager->m_paramsEcho.fRightDelay, DSFXECHO_RIGHTDELAY_MIN, DSFXECHO_RIGHTDELAY_MAX ); 
            float fTemp; 
            SaveSingleParameter( hwndDlg, IDC_PARAM_NAME5, &fTemp, DSFXECHO_PANDELAY_MIN, DSFXECHO_PANDELAY_MAX ); 
            g_lpFXManager->m_paramsEcho.lPanDelay = (LONG) fTemp; 
            if( g_lpFXManager->m_lpEcho ) 
                g_lpFXManager->m_lpEcho->SetAllParameters( &g_lpFXManager->m_paramsEcho ); 
            break; 
        } 
        case eSFX_flanger: 
        { 
            SaveSingleParameter( hwndDlg, IDC_PARAM_NAME1, &g_lpFXManager->m_paramsFlanger.fWetDryMix, DSFXFLANGER_WETDRYMIX_MIN, DSFXFLANGER_WETDRYMIX_MAX ); 
            SaveSingleParameter( hwndDlg, IDC_PARAM_NAME2, &g_lpFXManager->m_paramsFlanger.fDepth, DSFXFLANGER_DEPTH_MIN, DSFXFLANGER_DEPTH_MAX ); 
            SaveSingleParameter( hwndDlg, IDC_PARAM_NAME3, &g_lpFXManager->m_paramsFlanger.fFeedback, DSFXFLANGER_FEEDBACK_MIN, DSFXFLANGER_FEEDBACK_MAX ); 
            SaveSingleParameter( hwndDlg, IDC_PARAM_NAME4, &g_lpFXManager->m_paramsFlanger.fFrequency, DSFXFLANGER_FREQUENCY_MIN, DSFXFLANGER_FREQUENCY_MAX, 2 ); 
            SaveSingleParameter( hwndDlg, IDC_PARAM_NAME5, &g_lpFXManager->m_paramsFlanger.fDelay, DSFXFLANGER_DELAY_MIN, DSFXFLANGER_DELAY_MAX, 2 ); 
            if( IsDlgButtonChecked( hwndDlg, IDC_RADIO_TRIANGLE ) == BST_CHECKED ) 
                g_lpFXManager->m_paramsFlanger.lWaveform = DSFXFLANGER_WAVE_TRIANGLE; 
            else 
                g_lpFXManager->m_paramsFlanger.lWaveform = DSFXFLANGER_WAVE_SIN; 
            if( IsDlgButtonChecked( hwndDlg, IDC_RADIO_NEG_180 ) == BST_CHECKED ) 
                g_lpFXManager->m_paramsFlanger.lPhase = DSFXFLANGER_PHASE_NEG_180; 
            else if( IsDlgButtonChecked( hwndDlg, IDC_RADIO_NEG_90 ) == BST_CHECKED ) 
                g_lpFXManager->m_paramsFlanger.lPhase = DSFXFLANGER_PHASE_NEG_90; 
            else if( IsDlgButtonChecked( hwndDlg, IDC_RADIO_ZERO ) == BST_CHECKED ) 
                g_lpFXManager->m_paramsFlanger.lPhase = DSFXFLANGER_PHASE_ZERO; 
            else if( IsDlgButtonChecked( hwndDlg, IDC_RADIO_90 ) == BST_CHECKED ) 
                g_lpFXManager->m_paramsFlanger.lPhase = DSFXFLANGER_PHASE_90; 
            else 
                g_lpFXManager->m_paramsFlanger.lPhase = DSFXFLANGER_PHASE_180; 
            if( g_lpFXManager->m_lpFlanger ) 
                g_lpFXManager->m_lpFlanger->SetAllParameters( &g_lpFXManager->m_paramsFlanger ); 
            break; 
        } 
        case eSFX_gargle: 
        { 
            FLOAT fRateHz; 
            SaveSingleParameter( hwndDlg, IDC_PARAM_NAME1, &fRateHz, DSFXGARGLE_RATEHZ_MIN, DSFXGARGLE_RATEHZ_MAX ); 
            g_lpFXManager->m_paramsGargle.dwRateHz = (DWORD) fRateHz; 
            if( IsDlgButtonChecked( hwndDlg, IDC_RADIO_TRIANGLE ) == BST_CHECKED ) 
                g_lpFXManager->m_paramsGargle.dwWaveShape = DSFXGARGLE_WAVE_TRIANGLE; 
            else 
                g_lpFXManager->m_paramsGargle.dwWaveShape = DSFXGARGLE_WAVE_SQUARE; 
            if( g_lpFXManager->m_lpGargle ) 
                g_lpFXManager->m_lpGargle->SetAllParameters( &g_lpFXManager->m_paramsGargle ); 
            break; 
        } 
        case eSFX_parameq: 
        { 
            SaveSingleParameter( hwndDlg, IDC_PARAM_NAME1, &g_lpFXManager->m_paramsParamEq.fCenter, DSFXPARAMEQ_CENTER_MIN, DSFXPARAMEQ_CENTER_MAX ); 
            SaveSingleParameter( hwndDlg, IDC_PARAM_NAME2, &g_lpFXManager->m_paramsParamEq.fBandwidth, DSFXPARAMEQ_BANDWIDTH_MIN, DSFXPARAMEQ_BANDWIDTH_MAX ); 
            SaveSingleParameter( hwndDlg, IDC_PARAM_NAME3, &g_lpFXManager->m_paramsParamEq.fGain, DSFXPARAMEQ_GAIN_MIN, DSFXPARAMEQ_GAIN_MAX ); 
            if( g_lpFXManager->m_lpParamEq ) 
                g_lpFXManager->m_lpParamEq->SetAllParameters( &g_lpFXManager->m_paramsParamEq ); 
            break; 
        } 
        case eSFX_reverb: 
        { 
            SaveSingleParameter( hwndDlg, IDC_PARAM_NAME1, &g_lpFXManager->m_paramsReverb.fInGain, DSFX_WAVESREVERB_INGAIN_MIN, DSFX_WAVESREVERB_INGAIN_MAX ); 
            SaveSingleParameter( hwndDlg, IDC_PARAM_NAME2, &g_lpFXManager->m_paramsReverb.fReverbMix, DSFX_WAVESREVERB_REVERBMIX_MIN, DSFX_WAVESREVERB_REVERBMIX_MAX ); 
            SaveSingleParameter( hwndDlg, IDC_PARAM_NAME3, &g_lpFXManager->m_paramsReverb.fReverbTime, DSFX_WAVESREVERB_REVERBTIME_MIN, DSFX_WAVESREVERB_REVERBTIME_MAX ); 
            SaveSingleParameter( hwndDlg, IDC_PARAM_NAME4, &g_lpFXManager->m_paramsReverb.fHighFreqRTRatio, DSFX_WAVESREVERB_HIGHFREQRTRATIO_MIN, DSFX_WAVESREVERB_HIGHFREQRTRATIO_MAX, 2 ); 
            if( g_lpFXManager->m_lpReverb ) 
                g_lpFXManager->m_lpReverb->SetAllParameters( &g_lpFXManager->m_paramsReverb ); 
            break; 
        } 
    } 
} 
HRESULT ValidateWaveFile( HWND hDlg, TCHAR* strFileName ) 
{ 
    HRESULT hr; 
    CWaveFile waveFile; 
    if( -1 == GetFileAttributes(strFileName) ) 
        return E_FAIL; 
     
    HANDLE hFile = CreateFile( strFileName, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ); 
    if( hFile != NULL ) 
    { 
         
         
         
        DWORD dwFileSizeHigh = 0; 
        DWORD dwFileSize = GetFileSize( hFile, &dwFileSizeHigh ); 
        CloseHandle( hFile ); 
        if( dwFileSizeHigh != 0 || dwFileSize > 1000000 ) 
        { 
            SetDlgItemText( hDlg, IDC_TEXT_STATUS, TEXT("File too large.  You should stream large files.") ); 
            return E_FAIL; 
        } 
    } 
     
    if( FAILED( hr = waveFile.Open( strFileName, NULL, WAVEFILE_READ ) ) ) 
    { 
        waveFile.Close(); 
        SetDlgItemText( hDlg, IDC_TEXT_STATUS, TEXT("Bad wave file.") ); 
        return DXTRACE_ERR_MSGBOX( TEXT("Open"), hr ); 
    } 
    else  
    { 
        WAVEFORMATEX* pwfx = waveFile.GetFormat(); 
        if( pwfx->wFormatTag != WAVE_FORMAT_PCM && pwfx->wFormatTag != WAVE_FORMAT_IEEE_FLOAT ) 
        { 
             
            SetDlgItemText( hDlg, IDC_TEXT_STATUS, TEXT("Wave file must be PCM or IEEE FLOAT for effects control.") ); 
            SetDlgItemText( hDlg, IDC_TEXT_FILENAME, TEXT("") ); 
            return E_FAIL; 
        } 
         
        waveFile.Close(); 
         
        SetDlgItemText( hDlg, IDC_TEXT_FILENAME, strFileName ); 
        SetDlgItemText( hDlg, IDC_TEXT_STATUS, TEXT("File loaded.") ); 
        strcpy( g_tszFilename, strFileName ); 
        return S_OK; 
    } 
} 
CSoundFXManager::CSoundFXManager( ) 
{ 
    m_lpChorus = NULL; 
    m_lpCompressor = NULL; 
    m_lpDistortion = NULL; 
    m_lpEcho = NULL; 
    m_lpFlanger = NULL; 
    m_lpGargle = NULL; 
    m_lpParamEq = NULL; 
    m_lpReverb = NULL; 
    ZeroMemory( &m_paramsChorus, sizeof( DSFXChorus ) ); 
    ZeroMemory( &m_paramsCompressor, sizeof( DSFXCompressor ) ); 
    ZeroMemory( &m_paramsDistortion, sizeof( DSFXDistortion ) ); 
    ZeroMemory( &m_paramsFlanger, sizeof( DSFXFlanger ) ); 
    ZeroMemory( &m_paramsEcho, sizeof( DSFXEcho ) ); 
    ZeroMemory( &m_paramsGargle, sizeof( DSFXGargle ) ); 
    ZeroMemory( &m_paramsParamEq, sizeof( DSFXParamEq ) ); 
    ZeroMemory( &m_paramsReverb, sizeof( DSFXWavesReverb ) ); 
    m_dwNumFX = 0; 
    ZeroMemory( m_rgFxDesc, sizeof( DSEFFECTDESC ) * eNUM_SFX ); 
    ZeroMemory( m_rgRefGuids, sizeof( GUID * ) * eNUM_SFX ); 
    ZeroMemory( m_rgPtrs, sizeof(LPVOID*) * eNUM_SFX ); 
    ZeroMemory( m_rgLoaded, sizeof( BOOL ) * eNUM_SFX ); 
    m_lpDSB8 = NULL; 
} 
CSoundFXManager::~CSoundFXManager( ) 
{ 
     
    DisableAllFX( ); 
     
    SAFE_RELEASE( m_lpDSB8 ); 
} 
HRESULT CSoundFXManager::Initialize( LPDIRECTSOUNDBUFFER lpDSB, BOOL bLoadDefaultParamValues ) 
{ 
    HRESULT hr; 
    if( m_lpDSB8 ) 
    { 
         
        DisableAllFX( ); 
        SAFE_RELEASE( m_lpDSB8 ); 
    } 
    if( NULL == lpDSB ) 
        return S_OK; 
     
    if( FAILED( hr = lpDSB->QueryInterface( IID_IDirectSoundBuffer8, (LPVOID*) &m_lpDSB8 ) ) ) 
        return hr; 
    if( bLoadDefaultParamValues ) 
        LoadDefaultParamValues( ); 
    return S_OK; 
} 
HRESULT CSoundFXManager::UnInitialize( ) 
{ 
    Initialize( NULL, FALSE ); 
    return S_OK; 
} 
HRESULT CSoundFXManager::LoadDefaultParamValues( ) 
{ 
    DWORD i; 
    if( NULL == m_lpDSB8 ) 
        return E_FAIL; 
    for( i = eSFX_chorus; i < eNUM_SFX; i++ ) 
        SetFXEnable( i ); 
    ActivateFX( ); 
    if( m_lpChorus ) 
        m_lpChorus->GetAllParameters( &m_paramsChorus ); 
    if( m_lpCompressor ) 
        m_lpCompressor->GetAllParameters( &m_paramsCompressor ); 
    if( m_lpDistortion ) 
        m_lpDistortion->GetAllParameters( &m_paramsDistortion ); 
    if( m_lpEcho ) 
        m_lpEcho->GetAllParameters( &m_paramsEcho ); 
    if( m_lpFlanger ) 
        m_lpFlanger->GetAllParameters( &m_paramsFlanger ); 
    if( m_lpGargle ) 
        m_lpGargle->GetAllParameters( &m_paramsGargle ); 
    if( m_lpParamEq ) 
        m_lpParamEq->GetAllParameters( &m_paramsParamEq ); 
    if( m_lpReverb ) 
        m_lpReverb->GetAllParameters( &m_paramsReverb ); 
    DisableAllFX( ); 
    return S_OK; 
} 
HRESULT CSoundFXManager::LoadCurrentFXParameters( ) 
{ 
    if( m_lpChorus ) 
        m_lpChorus->SetAllParameters( &m_paramsChorus ); 
    if( m_lpCompressor ) 
        m_lpCompressor->SetAllParameters( &m_paramsCompressor ); 
    if( m_lpDistortion ) 
        m_lpDistortion->SetAllParameters( &m_paramsDistortion ); 
    if( m_lpEcho ) 
        m_lpEcho->SetAllParameters( &m_paramsEcho ); 
    if( m_lpFlanger ) 
        m_lpFlanger->SetAllParameters( &m_paramsFlanger ); 
    if( m_lpGargle ) 
        m_lpGargle->SetAllParameters( &m_paramsGargle ); 
    if( m_lpParamEq ) 
        m_lpParamEq->SetAllParameters( &m_paramsParamEq ); 
    if( m_lpReverb ) 
        m_lpReverb->SetAllParameters( &m_paramsReverb ); 
    return S_OK; 
} 
HRESULT CSoundFXManager:: 
SetFXEnable( DWORD esfxType ) 
{ 
    HRESULT hr; 
    if( esfxType >= eNUM_SFX ) 
        return E_FAIL; 
    if( m_rgLoaded[esfxType] ) 
        return S_FALSE; 
    else 
        m_rgLoaded[esfxType] = TRUE; 
    switch ( esfxType ) 
    { 
    case eSFX_chorus: 
        hr = EnableGenericFX( GUID_DSFX_STANDARD_CHORUS,     IID_IDirectSoundFXChorus8, 
                              (LPVOID*) &m_lpChorus ); 
        break; 
    case eSFX_compressor: 
        hr = EnableGenericFX( GUID_DSFX_STANDARD_COMPRESSOR, IID_IDirectSoundFXCompressor8, 
                              (LPVOID*) &m_lpCompressor ); 
        break; 
    case eSFX_distortion: 
        hr = EnableGenericFX( GUID_DSFX_STANDARD_DISTORTION, IID_IDirectSoundFXDistortion8, 
                              (LPVOID*) &m_lpDistortion ); 
        break; 
    case eSFX_echo: 
        hr = EnableGenericFX( GUID_DSFX_STANDARD_ECHO,       IID_IDirectSoundFXEcho8, 
                              (LPVOID*) &m_lpEcho ); 
        break; 
    case eSFX_flanger: 
        hr = EnableGenericFX( GUID_DSFX_STANDARD_FLANGER,    IID_IDirectSoundFXFlanger8, 
                              (LPVOID*) &m_lpFlanger ); 
        break; 
    case eSFX_gargle: 
        hr = EnableGenericFX( GUID_DSFX_STANDARD_GARGLE,     IID_IDirectSoundFXGargle8, 
                              (LPVOID*) &m_lpGargle ); 
        break; 
    case eSFX_parameq: 
        hr = EnableGenericFX( GUID_DSFX_STANDARD_PARAMEQ,    IID_IDirectSoundFXParamEq8, 
                              (LPVOID*) &m_lpParamEq ); 
        break; 
    case eSFX_reverb: 
        hr = EnableGenericFX( GUID_DSFX_WAVES_REVERB,        IID_IDirectSoundFXWavesReverb8, 
                              (LPVOID*) &m_lpReverb ); 
        break; 
    default: 
        hr = E_FAIL; 
        break; 
    } 
    return hr; 
} 
HRESULT CSoundFXManager::DisableAllFX( ) 
{ 
     
    SAFE_RELEASE( m_lpChorus ); 
    SAFE_RELEASE( m_lpCompressor ); 
    SAFE_RELEASE( m_lpDistortion ); 
    SAFE_RELEASE( m_lpEcho ); 
    SAFE_RELEASE( m_lpFlanger ); 
    SAFE_RELEASE( m_lpGargle ); 
    SAFE_RELEASE( m_lpParamEq ); 
    SAFE_RELEASE( m_lpReverb ); 
    m_dwNumFX = 0; 
    ZeroMemory( m_rgFxDesc, sizeof( DSEFFECTDESC ) * eNUM_SFX ); 
    ZeroMemory( m_rgRefGuids, sizeof( GUID * ) * eNUM_SFX ); 
    ZeroMemory( m_rgPtrs, sizeof(LPVOID*) * eNUM_SFX ); 
    ZeroMemory( m_rgLoaded, sizeof( BOOL ) * eNUM_SFX ); 
    if( NULL == m_lpDSB8 ) 
        return E_FAIL; 
     
    if( m_lpDSB8 ) 
        m_lpDSB8->Stop(); 
     
    m_lpDSB8->SetFX( 0, NULL, NULL ); 
    return S_OK; 
} 
HRESULT CSoundFXManager::ActivateFX( ) 
{ 
    DWORD dwResults[eNUM_SFX]; 
    HRESULT hr; 
    DWORD i; 
    if( NULL == m_lpDSB8 ) 
        return E_FAIL; 
    if( m_dwNumFX == 0 ) 
        return S_FALSE; 
    if( FAILED( hr = m_lpDSB8->SetFX( m_dwNumFX, m_rgFxDesc, dwResults ) ) ) 
        return hr; 
     
    for( i = 0; i < m_dwNumFX; i++ ) 
        if( FAILED( hr = m_lpDSB8->GetObjectInPath( m_rgFxDesc[i].guidDSFXClass, 0, *m_rgRefGuids[i], m_rgPtrs[i] ) ) ) 
            return DXTRACE_ERR_MSGBOX( TEXT("GetObjectInPath"), hr ); 
    return S_OK; 
} 
HRESULT CSoundFXManager::EnableGenericFX( GUID guidSFXClass, REFGUID rguidInterface, LPVOID * ppObj ) 
{ 
     
    if( *ppObj ) 
        return S_FALSE; 
    if( m_dwNumFX >= eNUM_SFX ) 
        return E_FAIL; 
     
    ZeroMemory( &m_rgFxDesc[m_dwNumFX], sizeof(DSEFFECTDESC) ); 
    m_rgFxDesc[m_dwNumFX].dwSize         = sizeof(DSEFFECTDESC); 
    m_rgFxDesc[m_dwNumFX].dwFlags        = 0; 
    CopyMemory( &m_rgFxDesc[m_dwNumFX].guidDSFXClass, &guidSFXClass, sizeof(GUID) ); 
    m_rgRefGuids[m_dwNumFX] = &rguidInterface; 
    m_rgPtrs[m_dwNumFX] = ppObj; 
    m_dwNumFX++; 
    return S_OK; 
}