diff options
Diffstat (limited to 'utils/voice_tweak/voice_tweakDlg.cpp')
| -rw-r--r-- | utils/voice_tweak/voice_tweakDlg.cpp | 408 |
1 files changed, 408 insertions, 0 deletions
diff --git a/utils/voice_tweak/voice_tweakDlg.cpp b/utils/voice_tweak/voice_tweakDlg.cpp new file mode 100644 index 0000000..502db48 --- /dev/null +++ b/utils/voice_tweak/voice_tweakDlg.cpp @@ -0,0 +1,408 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +// voice_tweakDlg.cpp : implementation file +// + +#include "stdafx.h" +#include "voice_tweak.h" +#include "voice_tweakDlg.h" +#include "voice_gain.h" +#include "dvoice.h" + + +void TermDPlayVoice( HINSTANCE &hInst, IDirectPlayVoiceTest* &pVoice ) +{ + if( pVoice ) + { + pVoice->Release(); + pVoice = NULL; + } + + if( hInst ) + { + FreeLibrary( hInst ); + hInst = NULL; + } +} + + +bool InitDPlayVoice( HINSTANCE &hInst, IDirectPlayVoiceTest* &pVoice ) +{ + typedef HRESULT (WINAPI *DirectPlayVoiceCreateFn)( + GUID* pcIID, + void** ppvInterface, + IUnknown* pUnknown + ); + + hInst = NULL; + pVoice = NULL; + + hInst = LoadLibrary( "dpvoice.dll" ); + if(hInst) + { + DirectPlayVoiceCreateFn fn = (DirectPlayVoiceCreateFn)GetProcAddress(hInst, "DirectPlayVoiceCreate"); + if(fn) + { + HRESULT hr = fn((GUID*)&IID_IDirectPlayVoiceTest, (void**)&pVoice, NULL); + if( SUCCEEDED( hr ) ) + return true; + } + } + + TermDPlayVoice( hInst, pVoice ); + return false; +} + + +bool IsDPlayVoiceAvailable() +{ + HINSTANCE hInst; + IDirectPlayVoiceTest *pVoice; + + bool bRet = InitDPlayVoice( hInst, pVoice ); + TermDPlayVoice( hInst, pVoice ); + + return bRet; +} + + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + + +#define VOLUMESLIDER_RANGE 1000 + + +CVoiceTweakApp* TweakApp() {return (CVoiceTweakApp*)AfxGetApp();} + + +extern "C" +{ + void Con_DPrintf (char *fmt, ...); + void Con_Printf (char *fmt, ...); +} + + +void PrintToTraceWindow(const char *fmt, va_list marker) +{ + char msg[2048]; + _vsnprintf(msg, sizeof(msg), fmt, marker); + OutputDebugString(msg); +} + +void Con_DPrintf (char *fmt, ...) +{ + va_list marker; + va_start(marker, fmt); + PrintToTraceWindow(fmt, marker); + va_end(marker); +} + +void Con_Printf (char *fmt, ...) +{ + va_list marker; + va_start(marker, fmt); + PrintToTraceWindow(fmt, marker); + va_end(marker); +} + + +///////////////////////////////////////////////////////////////////////////// +// CVoiceTweakDlg dialog + +CVoiceTweakDlg::CVoiceTweakDlg(CWnd* pParent /*=NULL*/) + : CDialog(CVoiceTweakDlg::IDD, pParent) +{ + //{{AFX_DATA_INIT(CVoiceTweakDlg) + //}}AFX_DATA_INIT + // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 + m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); +} + +CVoiceTweakDlg::~CVoiceTweakDlg() +{ + Term(); +} + +void CVoiceTweakDlg::Term() +{ + m_WinIdle.EndIdle(); +} + + +void CVoiceTweakDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CVoiceTweakDlg) + DDX_Control(pDX, IDC_HARDWAREGAIN, m_HardwareGain); + DDX_Control(pDX, IDC_VOICEVOLUME, m_VoiceVolume); + DDX_Control(pDX, IDC_VOLUMESLIDER, m_VolumeSlider); + DDX_Control(pDX, IDC_INSTRUCTIONTEXT, m_InstructionText); + //}}AFX_DATA_MAP +} + +BEGIN_MESSAGE_MAP(CVoiceTweakDlg, CDialog) + //{{AFX_MSG_MAP(CVoiceTweakDlg) + ON_WM_PAINT() + ON_WM_QUERYDRAGICON() + ON_MESSAGE(WM_TWEAKIDLE, OnIdle) + ON_WM_DESTROY() + ON_BN_CLICKED(IDC_HARDWAREGAIN, OnHardwareGain) + ON_BN_CLICKED(IDFURTHERHELP, OnFurtherhelp) + ON_BN_CLICKED(IDSYSTEMSETUP, OnSystemSetup) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + + +IMixerControls* GetAppMixerControls() +{ + return ((CVoiceTweakApp*)AfxGetApp())->m_pMixerControls; +} + + +void CVoiceTweakDlg::SetString(int childControl, int stringID) +{ + if(CWnd *pWnd = GetDlgItem(childControl)) + { + CString str; + str.LoadString(stringID); + pWnd->SetWindowText(str); + } +} + + +///////////////////////////////////////////////////////////////////////////// +// CVoiceTweakDlg message handlers + +BOOL CVoiceTweakDlg::OnInitDialog() +{ + CDialog::OnInitDialog(); + + // Set the icon for this dialog. The framework does this automatically + // when the application's main window is not a dialog + SetIcon(m_hIcon, TRUE); // Set big icon + SetIcon(m_hIcon, FALSE); // Set small icon + + CString str; + str.LoadString( MapLanguageStringID(IDS_HELPTEXT) ); + m_InstructionText.SetWindowText(str); + + + // Save off their old settings so we can restore if they hit cancel. + GetAppMixerControls()->GetValue_Float(IMixerControls::Control::MicVolume, m_OldVolume); + + float bBoostOn; + if(GetAppMixerControls()->GetValue_Float(IMixerControls::Control::MicBoost, bBoostOn)) + { + m_HardwareGain.SetCheck((int)bBoostOn); + } + else + { + m_HardwareGain.ShowWindow(SW_HIDE); + } + + // Initialize the volume control. + m_VolumeSlider.SetRange(0, 1000); + m_VolumeSlider.SetPos((int)(VOLUMESLIDER_RANGE - m_OldVolume * VOLUMESLIDER_RANGE)); + + m_VoiceVolume.SetRange32(0, (1 << (BYTES_PER_SAMPLE*8-1)) - 1); + + // Get idle messages... + m_WinIdle.StartIdle(GetSafeHwnd(), WM_TWEAKIDLE, 0,0, 10); + m_WinIdle.NextIdle(); + + // Set all the dialog item strings for localization. + SetString(IDOK, MapLanguageStringID(IDS_OKAY)); + SetString(IDCANCEL, MapLanguageStringID(IDS_CANCEL)); + SetString(IDC_VOICEINPUTFRAME, MapLanguageStringID(IDS_VOICEINPUT)); + SetString(IDC_VOLUMELABEL, MapLanguageStringID(IDS_VOLUME)); + SetString(IDC_HARDWAREGAIN, MapLanguageStringID(IDS_ENABLEGAIN)); + SetString(IDSYSTEMSETUP, MapLanguageStringID(IDS_SYSTEMSETUP)); + SetString(IDFURTHERHELP, MapLanguageStringID(IDS_HELP)); + + CString titleStr; + titleStr.LoadString( MapLanguageStringID(IDS_WINDOWTITLE) ); + SetWindowText(titleStr); + + if( !IsDPlayVoiceAvailable() ) + { + CWnd *pWnd = GetDlgItem( IDSYSTEMSETUP ); + if( pWnd ) + pWnd->EnableWindow( false ); + } + + return TRUE; // return TRUE unless you set the focus to a control +} + +// If you add a minimize button to your dialog, you will need the code below +// to draw the icon. For MFC applications using the document/view model, +// this is automatically done for you by the framework. + +void CVoiceTweakDlg::OnPaint() +{ + if (IsIconic()) + { + CPaintDC dc(this); // device context for painting + + SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); + + // Center icon in client rectangle + int cxIcon = GetSystemMetrics(SM_CXICON); + int cyIcon = GetSystemMetrics(SM_CYICON); + CRect rect; + GetClientRect(&rect); + int x = (rect.Width() - cxIcon + 1) / 2; + int y = (rect.Height() - cyIcon + 1) / 2; + + // Draw the icon + dc.DrawIcon(x, y, m_hIcon); + } + else + { + CDialog::OnPaint(); + } +} + +// The system calls this to obtain the cursor to display while the user drags +// the minimized window. +HCURSOR CVoiceTweakDlg::OnQueryDragIcon() +{ + return (HCURSOR) m_hIcon; +} + +BOOL CVoiceTweakDlg::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult) +{ + NMHDR *pHdr = (NMHDR*)lParam; + if(pHdr->hwndFrom == m_VolumeSlider.m_hWnd) + { + GetAppMixerControls()->SetValue_Float(IMixerControls::Control::MicVolume, (VOLUMESLIDER_RANGE - m_VolumeSlider.GetPos()) / (float)VOLUMESLIDER_RANGE); + } + + return CDialog::OnNotify(wParam, lParam, pResult); +} + + +LONG CVoiceTweakDlg::OnIdle(UINT a, LONG b) +{ + static DWORD startTime = GetTickCount(); + + if( TweakApp()->m_pVoiceRecord ) + { + short samples[22 * 1024]; + + // If the output has too many buffered samples, skip some data. + TweakApp()->m_pWaveOut->Idle(); + int nBufferedSamples = TweakApp()->m_pWaveOut->GetNumBufferedSamples(); + float nSeconds = nBufferedSamples / (float)VOICE_TWEAK_SAMPLE_RATE; + int nMinSamples = VOICE_TWEAK_SAMPLE_RATE / 5; + if( nBufferedSamples < nMinSamples ) + { + // We want at least a certain amount of buffered data. + int nSamplesToAdd = nMinSamples - nBufferedSamples; + memset( samples, 0, nSamplesToAdd*2 ); + TweakApp()->m_pWaveOut->PutSamples( samples, nSamplesToAdd ); + } + else + { + // Get the samples. + int nSamples = TweakApp()->m_pVoiceRecord->GetRecordedData(samples, sizeof(samples)/BYTES_PER_SAMPLE); + if( nSeconds < 0.5f ) + { + // Find the highest value. + int highValue = -100000; + for(int i=0; i < nSamples; i++) + highValue = max(abs(samples[i]), highValue); + + // Set our status bar accordingly. + highValue = (highValue >> 9) << 9; // Get rid of flicker. + m_VoiceVolume.SetPos(highValue); + + // Give the samples to the wave output... + if(TweakApp()->m_pWaveOut) + { + // Ignore the first second or so.. it's usually garbage. + DWORD curTime = GetTickCount(); + static DWORD silentTime = 500; + static DWORD fadeInTime = 1000; + if( curTime - startTime < silentTime ) + { + memset( samples, 0, nSamples*2 ); + } + else if( (curTime-silentTime) - startTime < fadeInTime ) + { + float flFade = ((curTime-silentTime) - startTime) / (float)fadeInTime; + flFade = flFade*flFade; + for( int i=0; i < nSamples; i++ ) + samples[i] = (short)( samples[i] * flFade ); + } + + TweakApp()->m_pWaveOut->PutSamples(samples, nSamples); + } + } + } + } + + // Tell the idle thread we're ready for another idle message. + m_WinIdle.NextIdle(); + return 0; +} + + +void CVoiceTweakDlg::OnDestroy() +{ + Term(); + + CDialog::OnDestroy(); +} + +void CVoiceTweakDlg::OnHardwareGain() +{ + if(m_HardwareGain.GetCheck()) + GetAppMixerControls()->SetValue_Float(IMixerControls::Control::MicBoost, true); + else + GetAppMixerControls()->SetValue_Float(IMixerControls::Control::MicBoost, false); +} + +void CVoiceTweakDlg::OnCancel() +{ + // Restore old settings. + GetAppMixerControls()->SetValue_Float(IMixerControls::Control::MicVolume, m_OldVolume); + + CDialog::OnCancel(); +} + +void CVoiceTweakDlg::OnFurtherhelp() +{ +} + + +void CVoiceTweakDlg::OnSystemSetup() +{ + TweakApp()->StopDevices(); + + bool bSucceeded = false; + HINSTANCE hInst; + IDirectPlayVoiceTest *pVoice; + if( InitDPlayVoice( hInst, pVoice ) ) + { + pVoice->CheckAudioSetup(NULL, NULL, m_hWnd, DVFLAGS_ALLOWBACK); + TermDPlayVoice( hInst, pVoice ); + } + else + { + CString str; + str.LoadString( MapLanguageStringID(IDS_NODPLAYVOICE) ); + MessageBox(str); + } + + if(!TweakApp()->StartDevices()) + AfxPostQuitMessage(0); +} |