summaryrefslogtreecommitdiff
path: root/utils/voice_tweak/voice_tweakDlg.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/voice_tweak/voice_tweakDlg.cpp')
-rw-r--r--utils/voice_tweak/voice_tweakDlg.cpp408
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);
+}