790 lines
19 KiB
C++
790 lines
19 KiB
C++
//---------------------------------------------------------------------------
|
|
#include <vcl.h>
|
|
#pragma hdrstop
|
|
|
|
#include "GlobalUnit.h"
|
|
#include "MessageFormUnit.h"
|
|
#include "MicSetFormUnit.h"
|
|
|
|
#define IO_DEVICE_WASAPI 0x10000
|
|
#define IO_DEVICE_ASIO 0x20000
|
|
#define IO_DEVICE_MIDI 0x40000
|
|
#define DEVICE_DEFAULT 0x02
|
|
#define REC_INPUT_OFF 0x10000
|
|
|
|
// source info structure
|
|
typedef struct {
|
|
char name[256];
|
|
DWORD flags;
|
|
} IO_CHANNEL_INFO;
|
|
|
|
//---------------------------------------------------------------------------
|
|
#pragma package(smart_init)
|
|
#pragma link "PNGButton"
|
|
#pragma resource "*.dfm"
|
|
|
|
USEFORM("MessageFormUnit.cpp", MessageForm);
|
|
|
|
TMicSetForm *MicSetForm;
|
|
|
|
//---------------------------------------------------------------------------
|
|
__fastcall TMicSetForm::TMicSetForm(TComponent* Owner)
|
|
: TForm(Owner)
|
|
{
|
|
m_pImgCheck = new TBitmap();
|
|
m_pImgCheck->LoadFromResourceName(int(HInstance), L"AutoLoginCheck");
|
|
|
|
Font->Color = RGB(60,43,23);
|
|
|
|
m_iCurrPlaybackDevice = m_iCurrRecordDevice = -1;
|
|
m_iCurrOutput = m_iCurrInput = -1;
|
|
|
|
m_PopupMenu = NULL;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
__fastcall TMicSetForm::~TMicSetForm()
|
|
{
|
|
if( m_pImgCheck ){
|
|
delete m_pImgCheck;
|
|
m_pImgCheck = NULL;
|
|
}
|
|
|
|
if( m_PopupMenu ){
|
|
delete m_PopupMenu;
|
|
m_PopupMenu = NULL;
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TMicSetForm::FormCreate(TObject *Sender)
|
|
{
|
|
m_tbVolume->ControlStyle>>csOpaque;
|
|
|
|
Font->Color = RGB(60,43,23);
|
|
|
|
//绘制圆角窗体
|
|
HRGN hRgn = CreateRoundRectRgn( 0, 0, Width+1, Height+1, 16, 16 );
|
|
SetWindowRgn( Handle, hRgn, false );
|
|
DeleteObject( hRgn );
|
|
|
|
m_bAutoAdjust = g_bRecordAutoAdjust;
|
|
m_bMoniter = g_bRecordMoniter;
|
|
|
|
m_iCurrPlaybackDevice = g_iPlaybackDevice;
|
|
m_iCurrOutput = g_iPlaybackOutput;
|
|
m_iCurrRecordDevice = g_iRecordDevice;
|
|
m_iCurrInput = g_iRecordInput;
|
|
|
|
IO_DEVICE_INFO aPbDevs[20], //播放设备
|
|
aRcDevs[20]; //录音设备
|
|
|
|
int nPbDev = f_MM_GetPlaybackDeviceInfo( 20, aPbDevs );
|
|
int nRcDev = f_MM_GetRecordDeviceInfo( 20, aRcDevs );
|
|
|
|
for( int i=0; i<nPbDev; i++ ){
|
|
IO_DEVICE_INFO * pDev = new IO_DEVICE_INFO(aPbDevs[i]);
|
|
|
|
if( pDev->iDevice & IO_DEVICE_WASAPI )
|
|
m_aWasapiPb.push_back( pDev );
|
|
else if( pDev->iDevice & IO_DEVICE_ASIO )
|
|
m_aAsioPb.push_back( pDev );
|
|
else
|
|
m_aCommonPb.push_back( pDev );
|
|
}
|
|
|
|
for( int i=0; i<nRcDev; i++ ){
|
|
IO_DEVICE_INFO * pDev = new IO_DEVICE_INFO(aRcDevs[i]);
|
|
|
|
if( pDev->iDevice & IO_DEVICE_WASAPI )
|
|
m_aWasapiRc.push_back( pDev );
|
|
else if( pDev->iDevice & IO_DEVICE_MIDI )
|
|
m_aMidiRc.push_back( pDev );
|
|
else
|
|
m_aCommonRc.push_back( pDev );
|
|
}
|
|
|
|
m_rbCommon->Enabled = !m_aCommonPb.empty();// && !m_aCommonRc.empty();
|
|
m_rbASIO->Enabled = !m_aAsioPb.empty();
|
|
m_rbWASAPI->Enabled = !m_aWasapiPb.empty();// && !m_aWasapiPb.empty();
|
|
|
|
int iType = m_iCurrPlaybackDevice>=0 ? (m_iCurrPlaybackDevice & 0xF0000) : -1;
|
|
|
|
|
|
if( m_iCurrPlaybackDevice<0 && !m_aCommonPb.empty()
|
|
|| m_iCurrRecordDevice<0 && ( iType==0 && !m_aCommonRc.empty()
|
|
|| iType==IO_DEVICE_WASAPI && !m_aWasapiRc.empty() ) )
|
|
f_MM_SetIODevice( m_iCurrPlaybackDevice, m_iCurrOutput,
|
|
m_iCurrRecordDevice, m_iCurrInput );
|
|
if( iType<0 )
|
|
iType = m_iCurrPlaybackDevice>=0 ? (m_iCurrPlaybackDevice & 0xF0000) : -1;
|
|
|
|
m_rbCommon->Checked = iType==0;
|
|
m_rbASIO->Checked = iType==IO_DEVICE_ASIO;
|
|
m_rbWASAPI->Checked = iType==IO_DEVICE_WASAPI;
|
|
|
|
ReloadPlayDev();
|
|
ReloadOutput();
|
|
|
|
ReloadRecDev();
|
|
ReloadInput();
|
|
|
|
m_pTimerLatency = new TTimer(this);
|
|
m_pTimerLatency->Enabled = false;
|
|
m_pTimerLatency->Interval = 250;
|
|
m_pTimerLatency->OnTimer = LatencyTimerProc;
|
|
|
|
m_tbVolume->Position = g_fRecordVolume * 100;
|
|
m_tbVolume->Hint = IntToStr(m_tbVolume->Position);
|
|
|
|
if( m_iCurrPlaybackDevice>=0 && m_iCurrRecordDevice>=0 )
|
|
BeginRecordTest();
|
|
else
|
|
m_tbVolume->Enabled = false;
|
|
|
|
SetTransparent( this );
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TMicSetForm::FormClose(TObject *Sender, TCloseAction &Action)
|
|
{
|
|
BeginRecordTest( false );
|
|
|
|
if( m_pTimerLatency ){
|
|
delete m_pTimerLatency;
|
|
m_pTimerLatency = NULL;
|
|
}
|
|
if( m_PopupMenu ){
|
|
delete m_PopupMenu;
|
|
m_PopupMenu = NULL;
|
|
}
|
|
|
|
while( !m_aCommonPb.empty() ){
|
|
delete m_aCommonPb.back();
|
|
m_aCommonPb.pop_back();
|
|
}
|
|
while( !m_aCommonRc.empty() ){
|
|
delete m_aCommonRc.back();
|
|
m_aCommonRc.pop_back();
|
|
}
|
|
while( !m_aWasapiPb.empty() ){
|
|
delete m_aWasapiPb.back();
|
|
m_aWasapiPb.pop_back();
|
|
}
|
|
while( !m_aWasapiRc.empty() ){
|
|
delete m_aWasapiRc.back();
|
|
m_aWasapiRc.pop_back();
|
|
}
|
|
while( !m_aAsioPb.empty() ){
|
|
delete m_aAsioPb.back();
|
|
m_aAsioPb.pop_back();
|
|
}
|
|
while( !m_aMidiRc.empty() ){
|
|
delete m_aMidiRc.back();
|
|
m_aMidiRc.pop_back();
|
|
}
|
|
|
|
if( ModalResult!=mrOk ){
|
|
if( !(g_iPlaybackDevice==m_iCurrPlaybackDevice
|
|
&& g_iRecordDevice==m_iCurrRecordDevice
|
|
&& g_iPlaybackOutput==m_iCurrOutput
|
|
&& g_iRecordInput==m_iCurrInput) ){
|
|
f_MM_SetIODevice( g_iPlaybackDevice, g_iPlaybackOutput,
|
|
g_iRecordDevice, g_iRecordInput );
|
|
}
|
|
if( m_bAutoAdjust!=g_bRecordAutoAdjust )
|
|
f_MM_SetRecordAutoAdjust( g_bRecordAutoAdjust );
|
|
if( m_bMoniter!=g_bRecordMoniter )
|
|
f_MM_SetRecordMoniter( g_bRecordMoniter );
|
|
f_MM_SetStreamVolume( 1, g_fRecordVolume );
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void TMicSetForm::ReloadPlayDev()
|
|
{
|
|
m_cbPlayDev->Clear();
|
|
|
|
int iDevice = -1;
|
|
|
|
if( m_iCurrPlaybackDevice>0 ){
|
|
int iType = m_iCurrPlaybackDevice & 0xF0000;
|
|
vector<IO_DEVICE_INFO*>& rDevs = iType==IO_DEVICE_WASAPI ? m_aWasapiPb
|
|
: iType==IO_DEVICE_ASIO ? m_aAsioPb
|
|
: m_aCommonPb;
|
|
for( int i=0; i<rDevs.size(); i++ ){
|
|
if( rDevs[i]->iDevice==m_iCurrPlaybackDevice )
|
|
iDevice = m_cbPlayDev->Items->Count;
|
|
|
|
if( iType==0 && !strcmp( rDevs[i]->name, "Default" ))
|
|
m_cbPlayDev->AddItem( "系统默认设备", (TObject*)rDevs[i]->iDevice );
|
|
else
|
|
m_cbPlayDev->AddItem( rDevs[i]->name, (TObject*)rDevs[i]->iDevice );
|
|
}
|
|
}
|
|
|
|
m_cbPlayDev->ItemIndex = iDevice;
|
|
m_cbPlayDev->Enabled = m_cbPlayDev->Items->Count > 0;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void TMicSetForm::ReloadRecDev()
|
|
{
|
|
if( !m_rbASIO->Checked ){
|
|
m_cbRecDevOrOutput->Clear();
|
|
|
|
int iDevice = -1;
|
|
if( m_iCurrRecordDevice>=0 ){
|
|
int iType = m_iCurrRecordDevice & 0xF0000;
|
|
|
|
m_lblRecDevOrOutput->Caption = "录音设备";
|
|
m_cbRecDevOrOutput->Width = m_cbPlayDev->Width;
|
|
m_lblASIO->Visible = false;
|
|
|
|
vector<IO_DEVICE_INFO*>& rDevs = iType==IO_DEVICE_WASAPI ? m_aWasapiRc
|
|
: iType==IO_DEVICE_MIDI ? m_aMidiRc
|
|
: m_aCommonRc;
|
|
for( int i=0; i<rDevs.size(); i++ ){
|
|
if( rDevs[i]->iDevice==m_iCurrRecordDevice )
|
|
iDevice = m_cbRecDevOrOutput->Items->Count;
|
|
|
|
if( iType==0 && !strcmp( rDevs[i]->name, "Default" ))
|
|
m_cbRecDevOrOutput->AddItem( "系统默认设备", (TObject*)rDevs[i]->iDevice );
|
|
else
|
|
m_cbRecDevOrOutput->AddItem( rDevs[i]->name, (TObject*)rDevs[i]->iDevice );
|
|
}
|
|
}
|
|
|
|
m_cbRecDevOrOutput->ItemIndex = iDevice;
|
|
m_cbRecDevOrOutput->Enabled = m_cbRecDevOrOutput->Items->Count > 0;
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void TMicSetForm::ReloadOutput()
|
|
{
|
|
if( m_rbASIO->Checked ){
|
|
int iDevice = -1;
|
|
|
|
m_cbRecDevOrOutput->Clear();
|
|
|
|
m_lblRecDevOrOutput->Caption = "播放输出";
|
|
m_cbRecDevOrOutput->Width = m_cbInput->Width;
|
|
m_lblASIO->Visible = true;
|
|
|
|
IO_CHANNEL_INFO chanInfo[20];
|
|
int nSize = f_MM_GetPlaybackOutputInfo( 20, chanInfo );
|
|
int iChannel = -1;
|
|
|
|
if( m_iCurrOutput>=0 && m_iCurrOutput<nSize)
|
|
iChannel = m_iCurrOutput;
|
|
else if( nSize>0 )
|
|
iChannel = 0;
|
|
|
|
for( int i=0; i<nSize; i+=2 ){
|
|
m_cbRecDevOrOutput->AddItem( chanInfo[i].name, (TObject*)i );
|
|
}
|
|
|
|
if( iChannel>=0 )
|
|
m_cbRecDevOrOutput->ItemIndex = iChannel/2;
|
|
|
|
|
|
m_iCurrOutput = iChannel;
|
|
m_lblASIO->Enabled = iChannel>=0;
|
|
m_cbRecDevOrOutput->Enabled = m_cbRecDevOrOutput->Items->Count > 0;
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void TMicSetForm::ReloadInput()
|
|
{
|
|
m_cbInput->Clear();
|
|
|
|
if( !m_cbRecDevOrOutput->Enabled ){
|
|
m_cbInput->Enabled = false;
|
|
return;
|
|
}
|
|
|
|
IO_CHANNEL_INFO chanInfo[20];
|
|
int iChannel = -1;
|
|
int nSize = f_MM_GetRecordInputInfo( 20, chanInfo );
|
|
|
|
if( m_iCurrInput>=0 && m_iCurrInput<nSize){
|
|
iChannel = m_iCurrInput;
|
|
}
|
|
|
|
if( nSize>0 ){
|
|
for( int i=0; i<nSize; i++ ){
|
|
m_cbInput->AddItem( chanInfo[i].name, (TObject*)i );
|
|
if( iChannel<0 ){
|
|
iChannel = i;
|
|
}
|
|
}
|
|
|
|
if( iChannel<0 ){
|
|
iChannel = 0;
|
|
}
|
|
|
|
m_cbInput->ItemIndex = iChannel;
|
|
}
|
|
else if( (m_iCurrPlaybackDevice & 0xF0000)!=IO_DEVICE_ASIO ){
|
|
m_cbInput->AddItem( "默认输入", (TObject*)0 );
|
|
m_cbInput->ItemIndex = 0;
|
|
}
|
|
|
|
m_cbInput->Enabled = m_cbInput->Items->Count > 0;
|
|
|
|
m_iCurrInput = iChannel;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TMicSetForm::WMNCHitTest(TWMNCHitTest &Msg)
|
|
{
|
|
TForm::Dispatch(&Msg);
|
|
|
|
if( Msg.Result==HTCLIENT && Msg.YPos<Top+24
|
|
&& Msg.XPos>Left+35 && Msg.XPos<Left+275 )
|
|
Msg.Result = HTCAPTION;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TMicSetForm::FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift)
|
|
{
|
|
switch( Key ){
|
|
case VK_RETURN:
|
|
case ' ':
|
|
if( m_btnOk->Visible ){
|
|
OkClick( NULL );
|
|
ModalResult = mrOk;
|
|
}
|
|
break;
|
|
|
|
case VK_ESCAPE:
|
|
if( m_btnCancel->Visible )
|
|
ModalResult = mrCancel;
|
|
break;
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TMicSetForm::CheckPaint(TObject *Sender)
|
|
{
|
|
TPaintBox* pPB = (TPaintBox*)Sender;
|
|
|
|
//绘制Check状态
|
|
int x = 0;
|
|
if( pPB==m_pbAutoCheck && !m_bAutoAdjust
|
|
|| pPB==m_pbMoniter && !m_bMoniter ){
|
|
x = -m_pImgCheck->Width/2;
|
|
}
|
|
|
|
pPB->Canvas->Draw(x, 0, m_pImgCheck);
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TMicSetForm::CheckClick(TObject *Sender)
|
|
{
|
|
TPaintBox* pPB = (TPaintBox*)Sender;
|
|
|
|
//切换Check状态
|
|
if( pPB==m_pbAutoCheck ){
|
|
m_bAutoAdjust = !m_bAutoAdjust;
|
|
f_MM_SetRecordAutoAdjust( m_bAutoAdjust );
|
|
}
|
|
else{
|
|
m_bMoniter = !m_bMoniter;
|
|
f_MM_SetRecordMoniter( m_bMoniter );
|
|
}
|
|
|
|
pPB->Invalidate();
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TMicSetForm::OkClick(TObject *Sender)
|
|
{
|
|
g_iPlaybackDevice = m_iCurrPlaybackDevice;
|
|
g_iRecordDevice = m_iCurrRecordDevice;
|
|
g_iPlaybackOutput = m_iCurrOutput;
|
|
g_iRecordInput = m_iCurrInput;
|
|
|
|
int iType = m_iCurrPlaybackDevice & 0xF0000;
|
|
vector<IO_DEVICE_INFO*>& rDevsPb = iType==IO_DEVICE_WASAPI ? m_aWasapiPb
|
|
: iType==IO_DEVICE_ASIO ? m_aAsioPb
|
|
: m_aCommonPb;
|
|
for( int i=0; i<rDevsPb.size(); i++ ){
|
|
if( rDevsPb[i]->iDevice==m_iCurrPlaybackDevice ){
|
|
strcpy( g_strPlaybackDevice, rDevsPb[i]->name );
|
|
break;
|
|
}
|
|
}
|
|
|
|
iType = m_iCurrRecordDevice & 0xF0000;
|
|
if( iType==IO_DEVICE_ASIO ){
|
|
strcpy( g_strRecordDevice, g_strPlaybackDevice );
|
|
}
|
|
else{
|
|
vector<IO_DEVICE_INFO*>& rDevsRc = iType==IO_DEVICE_WASAPI ? m_aWasapiRc
|
|
: iType==IO_DEVICE_MIDI ? m_aMidiRc
|
|
: m_aCommonRc;
|
|
|
|
for( int i=0; i<rDevsRc.size(); i++ ){
|
|
if( rDevsRc[i]->iDevice==m_iCurrRecordDevice ){
|
|
strcpy( g_strRecordDevice, rDevsRc[i]->name );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//保存所有状态
|
|
g_fRecordVolume = m_tbVolume->Position / 100.0;
|
|
// g_fRecordVolume = f_MM_GetStreamVolume( 1 ) / 100.0;
|
|
g_bRecordAutoAdjust = m_bAutoAdjust;
|
|
g_bRecordMoniter = m_bMoniter;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TMicSetForm::PlayDevChange(TObject *Sender)
|
|
{
|
|
int iNewDev = (int)(m_cbPlayDev->Items->Objects[m_cbPlayDev->ItemIndex]);
|
|
if( iNewDev==m_iCurrPlaybackDevice )
|
|
return;
|
|
|
|
BeginRecordTest( false );
|
|
|
|
int iType = (m_iCurrPlaybackDevice & 0xF0000);
|
|
int iPlayDev = iNewDev, iOutput = -1,
|
|
iRecDev = m_iCurrRecordDevice,
|
|
iInput = m_iCurrInput;
|
|
|
|
if( iType==IO_DEVICE_ASIO ){
|
|
iRecDev = iNewDev;
|
|
iInput = -1;
|
|
}
|
|
|
|
Screen->Cursor = crHourGlass;
|
|
|
|
HRESULT hr = f_MM_SetIODevice( iPlayDev, iOutput, iRecDev, iInput );
|
|
|
|
m_iCurrPlaybackDevice = iPlayDev;
|
|
m_iCurrOutput = iOutput;
|
|
m_iCurrRecordDevice = iRecDev;
|
|
m_iCurrInput = iInput;
|
|
|
|
if( iType==IO_DEVICE_ASIO ){
|
|
ReloadOutput();
|
|
ReloadInput();
|
|
}
|
|
|
|
if( hr==S_OK ){
|
|
if( m_iCurrRecordDevice>=0 )
|
|
BeginRecordTest();
|
|
}
|
|
else
|
|
ShowErrorMessage( hr );
|
|
|
|
m_tbVolume->Enabled = hr==S_OK && m_iCurrRecordDevice>=0;
|
|
Screen->Cursor = crDefault;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TMicSetForm::RecDevOrOutputChange(TObject *Sender)
|
|
{
|
|
int iIndex = (int)(m_cbRecDevOrOutput->Items->Objects[m_cbRecDevOrOutput->ItemIndex]);
|
|
|
|
int iPlayDev = m_iCurrPlaybackDevice,
|
|
iOutput = m_iCurrOutput,
|
|
iRecDev = m_iCurrRecordDevice,
|
|
iInput = m_iCurrInput;
|
|
|
|
if( m_rbASIO->Checked ){
|
|
if( iIndex==m_iCurrOutput )
|
|
return;
|
|
else
|
|
iOutput = iIndex;
|
|
}
|
|
else{
|
|
if( iIndex==m_iCurrRecordDevice )
|
|
return;
|
|
else
|
|
iRecDev = iIndex;
|
|
}
|
|
|
|
BeginRecordTest( false );
|
|
|
|
Screen->Cursor = crHourGlass;
|
|
|
|
HRESULT hr = f_MM_SetIODevice( iPlayDev, iOutput, iRecDev, iInput );
|
|
|
|
m_iCurrPlaybackDevice = iPlayDev;
|
|
m_iCurrOutput = iOutput;
|
|
m_iCurrRecordDevice = iRecDev;
|
|
m_iCurrInput = iInput;
|
|
|
|
if( !m_rbASIO->Checked )
|
|
ReloadInput();
|
|
|
|
if( hr==S_OK ){
|
|
if( m_iCurrRecordDevice>=0 )
|
|
BeginRecordTest();
|
|
}
|
|
else
|
|
ShowErrorMessage( hr );
|
|
|
|
m_tbVolume->Enabled = hr==S_OK && m_iCurrRecordDevice>=0;
|
|
Screen->Cursor = crDefault;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TMicSetForm::InputChange(TObject *Sender)
|
|
{
|
|
int iInput = m_cbInput->ItemIndex;
|
|
if( iInput==m_iCurrInput )
|
|
return;
|
|
|
|
BeginRecordTest( false );
|
|
|
|
int iPlayDev = m_iCurrPlaybackDevice,
|
|
iOutput = m_iCurrOutput,
|
|
iRecDev = m_iCurrRecordDevice;
|
|
|
|
Screen->Cursor = crHourGlass;
|
|
|
|
HRESULT hr = f_MM_SetIODevice( iPlayDev, iOutput, iRecDev, iInput );
|
|
|
|
m_iCurrInput = iInput;
|
|
|
|
if( hr==S_OK )
|
|
BeginRecordTest();
|
|
else
|
|
ShowErrorMessage( hr );
|
|
|
|
m_tbVolume->Enabled = hr==S_OK;
|
|
Screen->Cursor = crDefault;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TMicSetForm::VolumeChange(TObject *Sender)
|
|
{
|
|
int nVol = m_tbVolume->Position;
|
|
m_tbVolume->Hint = IntToStr(nVol);
|
|
|
|
f_MM_SetStreamVolume( 1, nVol/100.0 );
|
|
|
|
if( m_bAutoAdjust ){
|
|
m_bAutoAdjust = false;
|
|
m_pbAutoCheck->Invalidate();
|
|
|
|
f_MM_SetRecordAutoAdjust( m_bAutoAdjust );
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TMicSetForm::UMRecordVolJust(TMessage &Message)
|
|
{
|
|
m_tbVolume->OnChange = NULL;
|
|
m_tbVolume->Position = (int)Message.WParam;
|
|
m_tbVolume->Hint = IntToStr((int)Message.WParam);
|
|
m_tbVolume->OnChange = VolumeChange;
|
|
}
|
|
// ---------------------------------------------------------------------------
|
|
|
|
void TMicSetForm::BeginRecordTest(bool bStart)
|
|
{
|
|
if( bStart ){
|
|
HRESULT hr = f_MM_RecordTest( Handle );
|
|
if( hr==S_OK ){
|
|
if( m_bAutoAdjust ){
|
|
m_tbVolume->OnChange = NULL;
|
|
m_tbVolume->Position = 100;
|
|
m_tbVolume->Hint = IntToStr(100);
|
|
|
|
f_MM_SetStreamVolume( 1, 1 );
|
|
}
|
|
|
|
m_tbVolume->Enabled = true;
|
|
m_tbVolume->OnChange = VolumeChange;
|
|
m_pTimerLatency->Enabled = true;
|
|
m_lblLatencyTime->Caption = "0.0 ms";
|
|
}
|
|
else{
|
|
m_pTimerLatency->Enabled = false;
|
|
m_tbVolume->Enabled = false;
|
|
m_lblLatencyTime->Caption = "---- ms";
|
|
|
|
ShowErrorMessage( hr );
|
|
}
|
|
}
|
|
else{
|
|
m_pTimerLatency->Enabled = false;
|
|
f_MM_Stop();
|
|
m_tbVolume->Enabled = false;
|
|
m_lblLatencyTime->Caption = "---- ms";
|
|
}
|
|
}
|
|
// ---------------------------------------------------------------------------
|
|
|
|
void __fastcall TMicSetForm::LatencyTimerProc(TObject* Sender)
|
|
{
|
|
float fLatency = f_MM_GetLatency( true );
|
|
char str[16];
|
|
sprintf( str, "%.1f ms", fLatency );
|
|
m_lblLatencyTime->Caption = str;
|
|
}
|
|
// ---------------------------------------------------------------------------
|
|
|
|
void TMicSetForm::ShowErrorMessage( int errcode )
|
|
{
|
|
String msg;
|
|
|
|
int errRec = LOWORD( errcode ),
|
|
errPlay = HIWORD( errcode ),
|
|
err = errRec>0 ? errRec : errPlay;
|
|
|
|
if( err==1 ){
|
|
msg += L"内存空间不足。";
|
|
}
|
|
else{
|
|
if(errRec>1 && m_cbInput->Enabled)
|
|
msg += "输入";
|
|
if(errPlay>1 && m_cbRecDevOrOutput->Enabled)
|
|
msg += "输出";
|
|
}
|
|
|
|
if( msg.Length()==0 )
|
|
return;
|
|
|
|
if( err==46 ){
|
|
msg += L"设备被其它程序独占。";
|
|
}
|
|
else if( err==37 ){
|
|
msg += L"设备无法打开。";
|
|
}
|
|
else if( err==3 || err==23 ){
|
|
msg += L"设备无效。";
|
|
}
|
|
else{
|
|
msg += L"设备启动失败。";
|
|
}
|
|
|
|
MessageForm->ShowMessage( msg, MB_ICONERROR|MB_OK );
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TMicSetForm::ASIOMouseDown(TObject *Sender, TMouseButton Button,
|
|
TShiftState Shift, int X, int Y)
|
|
{
|
|
if( Button==mbLeft ){
|
|
if( m_PopupMenu ){
|
|
delete m_PopupMenu;
|
|
m_PopupMenu = NULL;
|
|
}
|
|
|
|
m_PopupMenu = new TPopMenu(NULL);
|
|
|
|
m_PopupMenu->CreateCustomMenuItem( "显示面板", DoShowPanel );
|
|
m_PopupMenu->CreateCustomMenuItem( "重启设备", DoRestart );
|
|
|
|
TPoint point( m_lblASIO->Left, m_lblASIO->Top+m_lblASIO->Height );
|
|
point = ClientToScreen(point);
|
|
m_PopupMenu->Popup( point.X, point.Y );
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TMicSetForm::DoShowPanel(TObject* Sender)
|
|
{
|
|
if( m_iCurrPlaybackDevice & IO_DEVICE_ASIO )
|
|
f_MM_ShowAsioPanel();
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TMicSetForm::DoRestart(TObject* Sender)
|
|
{
|
|
if( m_iCurrPlaybackDevice & IO_DEVICE_ASIO ){
|
|
if( f_MM_RestartAsioDevice()==S_OK ){
|
|
ReloadOutput();
|
|
ReloadInput();
|
|
}
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TMicSetForm::DeviceTypeClick(TObject *Sender)
|
|
{
|
|
int iTypeOld = m_iCurrPlaybackDevice & 0xF0000;
|
|
int iType = m_rbASIO->Checked ? IO_DEVICE_ASIO
|
|
: m_rbWASAPI->Checked ? IO_DEVICE_WASAPI
|
|
: 0;
|
|
|
|
if( iType==iTypeOld )
|
|
return;
|
|
|
|
BeginRecordTest( false );
|
|
|
|
int iPlayDev = -1, iOutput = -1,
|
|
iRecDev = -1, iInput = -1;
|
|
|
|
if( iType==IO_DEVICE_ASIO ){
|
|
iPlayDev = m_aAsioPb[0]->iDevice;
|
|
|
|
if( iRecDev<0 )
|
|
iRecDev = iPlayDev;
|
|
}
|
|
else{
|
|
vector<IO_DEVICE_INFO*>& rDevsPb = iType==IO_DEVICE_WASAPI ? m_aWasapiPb
|
|
: iType==IO_DEVICE_ASIO ? m_aAsioPb
|
|
: m_aCommonPb;
|
|
for( int i=0; i<rDevsPb.size(); i++ ){
|
|
if( rDevsPb[i]->flags & DEVICE_DEFAULT ){
|
|
iPlayDev = rDevsPb[i]->iDevice;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if( iRecDev<0 ){
|
|
vector<IO_DEVICE_INFO*>& rDevsRc = iType==IO_DEVICE_WASAPI ? m_aWasapiRc
|
|
: m_aCommonRc;
|
|
|
|
for( int i=0; i<rDevsRc.size(); i++ ){
|
|
if( rDevsRc[i]->flags & DEVICE_DEFAULT ){
|
|
iRecDev = rDevsRc[i]->iDevice;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Screen->Cursor = crHourGlass;
|
|
|
|
m_iCurrPlaybackDevice = iPlayDev;
|
|
m_iCurrOutput = iOutput;
|
|
|
|
HRESULT hr = f_MM_SetIODevice( iPlayDev, iOutput, iRecDev, iInput );
|
|
|
|
if( iPlayDev>=0 ){
|
|
m_iCurrPlaybackDevice = iPlayDev;
|
|
m_iCurrOutput = iOutput;
|
|
}
|
|
|
|
m_iCurrRecordDevice = iRecDev;
|
|
m_iCurrInput = iInput;
|
|
|
|
ReloadPlayDev();
|
|
ReloadOutput();
|
|
|
|
ReloadRecDev();
|
|
ReloadInput();
|
|
|
|
if( hr==S_OK ){
|
|
if( m_cbInput->Enabled )
|
|
BeginRecordTest();
|
|
}
|
|
else
|
|
ShowErrorMessage( hr );
|
|
|
|
Screen->Cursor = crDefault;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|