Files
AC_Pro/MicSetFormUnit.cpp
2026-06-13 00:05:19 +08:00

919 lines
22 KiB
C++

//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "MicSetFormUnit.h"
#include "Instruments.h"
#include "MessageFormUnit.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;
#define CLR_TEXT_HOT RGB( 201, 214, 229 )
#define CLR_TEXT_NOR RGB( 156, 170, 189 )
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "GeneralDialogPanel"
#pragma link "TextButton"
#pragma link "CKBox"
#pragma resource "*.dfm"
TMicSetForm *MicSetForm;
//---------------------------------------------------------------------------
__fastcall TMicSetForm::TMicSetForm(TComponent* Owner)
: TForm(Owner)
{
//加载图片
Font->Color = RGB(60,43,23);
m_iCurrPlaybackDevice = m_iCurrRecordDevice = -1;
m_iCurrOutput = m_iCurrInput = -1;
m_PopupMenu = NULL;
}
//---------------------------------------------------------------------------
void __fastcall TMicSetForm::FormCreate(TObject *Sender)
{
SetTransparent( this );
m_panGeneral->Font->Size = g_szFont9;
m_cbPlayDev->SetFontSize(g_szFont9);
m_cbOutput->SetFontSize(g_szFont9);
m_cbRecDev->SetFontSize(g_szFont9);
m_cbInput->SetFontSize(g_szFont9);
m_ckAuto->Font->Size = g_szFont9;
m_ckMoniter->Font->Size = g_szFont9;
m_rbCommon->Font->Size = g_szFont9;
m_rbASIO->Font->Size = g_szFont8;
m_rbWASAPI->Font->Size = g_szFont8;
m_ckMIDI->Font->Size = g_szFont8;
m_btnOk->FontSize = g_szFont9;
m_btnCanel->FontSize = g_szFont9;
//字体以及字体颜色修改
m_lblVolume->Font->Color = CLR_TEXT_NOR;
m_lblPlayback->Font->Color = CLR_TEXT_NOR;
m_lblOutput->Font->Color = CLR_TEXT_NOR;
m_lblRecord->Font->Color = CLR_TEXT_NOR;
m_lblInput->Font->Color = CLR_TEXT_NOR;
m_lblLatencyTime->Font->Color = CLR_TEXT_NOR;
m_lblHint->Font->Color = CLR_TEXT_NOR;
m_lblHintMsg->Font->Color = CLR_TEXT_NOR;
m_lblLatency->Font->Color = CLR_TEXT_NOR;
m_lblType->Font->Color = CLR_TEXT_NOR;
//-------------------------------选中状态判断
m_ckAuto->Checked = g_bRecordAutoAdjust;
m_ckMoniter->Checked = 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_rbASIO->Enabled = !m_aAsioPb.empty();
m_rbWASAPI->Enabled = !m_aWasapiPb.empty();
m_ckMIDI->Enabled = !m_aMidiRc.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;
m_ckMIDI->Checked = m_iCurrRecordDevice>=0 && (m_iCurrRecordDevice & IO_DEVICE_MIDI);
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;
}
//---------------------------------------------------------------------------
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( g_bRecordAutoAdjust!=m_ckAuto->Checked )
f_MM_SetRecordAutoAdjust( g_bRecordAutoAdjust );
if( g_bRecordMoniter!=m_ckMoniter->Checked )
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->ItemsCount;
if( iType==0 && !stricmp( rDevs[i]->name, "Default" ))
m_cbPlayDev->AddItem( "系统默认设备" )->Tag = rDevs[i]->iDevice;
else
m_cbPlayDev->AddItem( rDevs[i]->name )->Tag = rDevs[i]->iDevice;
}
}
m_cbPlayDev->DefItemIndex = iDevice;
m_cbPlayDev->Enabled = m_cbPlayDev->ItemsCount>0;
}
//---------------------------------------------------------------------------
void TMicSetForm::ReloadRecDev()
{
m_cbRecDev->Clear();
int iDevice = -1;
if( m_iCurrRecordDevice>=0 ){
int iType = m_iCurrRecordDevice & 0xF0000;
if( iType==IO_DEVICE_ASIO ){
for( int i=0; i<m_aAsioPb.size(); i++ ){
if( m_aAsioPb[i]->iDevice==m_iCurrRecordDevice ){
m_cbRecDev->AddItem( m_aAsioPb[i]->name )->Tag = m_aAsioPb[i]->iDevice;
break;
}
}
iDevice = 0;
}
else{
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_cbRecDev->ItemsCount;
if( iType==0 && !strcmp( rDevs[i]->name, "Default" ))
m_cbRecDev->AddItem( "系统默认设备" )->Tag = rDevs[i]->iDevice;
else
m_cbRecDev->AddItem( rDevs[i]->name )->Tag = rDevs[i]->iDevice;
}
}
}
m_cbRecDev->DefItemIndex = iDevice;
m_cbRecDev->Enabled = m_cbRecDev->ItemsCount>0;
if( !m_cbRecDev->Enabled )
m_cbRecDev->Caption = "";
}
//---------------------------------------------------------------------------
void TMicSetForm::ReloadOutput()
{
m_cbOutput->Clear();
int iType = m_iCurrPlaybackDevice & 0xF0000;
if( iType==IO_DEVICE_ASIO ){
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_cbOutput->AddItem( chanInfo[i].name );
}
if( iChannel>=0 )
m_cbOutput->DefItemIndex = iChannel/2;
m_lblASIO->Enabled = iChannel>=0;
m_iCurrOutput = iChannel;
}
else{
m_lblASIO->Visible = false;
m_cbOutput->AddItem( "默认输出" );
m_cbOutput->DefItemIndex = 0;
}
m_cbOutput->Enabled = m_cbOutput->ItemsCount>0;
if( !m_cbOutput->Enabled )
m_cbOutput->Caption = "";
}
//---------------------------------------------------------------------------
void TMicSetForm::ReloadInput()
{
m_cbInput->Clear();
bool bMidi = m_iCurrRecordDevice>=0 && (m_iCurrRecordDevice & IO_DEVICE_MIDI);
m_ckAuto->Visible = !bMidi;
m_ckMoniter->Visible = !bMidi;
if( bMidi ){
// m_lblLatency->Top = m_lblVolume->Top;
// m_lblLatencyTime->Top = m_lblVolume->Top;
// m_lblVolume->Caption = "缓冲时间:";
m_lblInput->Caption = "乐器音色:";
for( int i=0; i<112; i++ ){
m_cbInput->AddItem( GM_INSTRUMENT[i] );
}
m_cbInput->DefItemIndex = m_iCurrInput;
}
else{
// m_lblLatency->Top = m_lblInput->Top;
// m_lblLatencyTime->Top = m_lblInput->Top;
// m_lblVolume->Caption = "录音音量:";
m_lblInput->Caption = "录音输入:";
int iChannel = -1;
if( m_cbRecDev->DefItemIndex>=0 ){
IO_CHANNEL_INFO chanInfo[20];
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 );
if( iChannel<0 ){
iChannel = i;
}
}
if( iChannel<0 ){
iChannel = 0;
}
m_cbInput->DefItemIndex = iChannel;
}
else if( (m_iCurrPlaybackDevice & 0xF0000)!=IO_DEVICE_ASIO ){
m_cbInput->AddItem( "默认输入" );
m_cbInput->DefItemIndex = 0;
}
}
m_iCurrInput = iChannel;
}
m_cbInput->Enabled = m_cbInput->ItemsCount>0;
m_tbVolume->Enabled = m_cbInput->ItemsCount>0;
if( !m_cbInput->Enabled )
m_cbInput->Caption = "";
}
//---------------------------------------------------------------------------
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_btnCanel->Visible ){
ModalResult = mrCancel;
}
break;
}
}
//---------------------------------------------------------------------------
void __fastcall TMicSetForm::VolumeChange(TObject *Sender)
{
if( m_iCurrRecordDevice<0 )
return;
int nPos = m_tbVolume->Position;
m_tbVolume->Hint = IntToStr(nPos);
/* if( m_iCurrRecordDevice & IO_DEVICE_MIDI ){
f_MM_SetMidiInBuffer( nPos );
}
else{
*/ if( m_ckAuto->Visible && m_ckAuto->Checked ){
m_ckAuto->Checked = false;
f_MM_SetRecordAutoAdjust( m_ckAuto->Checked );
}
f_MM_SetStreamVolume( 1, nPos/100.0 );
// }
}
//---------------------------------------------------------------------------
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::BeginRecordTest(bool bStart)
{
if( bStart ){
HRESULT hr = f_MM_RecordTest( Handle );
if( hr==S_OK ){
if( m_ckAuto->Checked ){
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 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->ItemsCount>0)
msg += "输入";
if(errPlay>1 && m_cbOutput->ItemsCount>0)
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::OkClick(TObject *Sender)
{
g_iPlaybackDevice = m_iCurrPlaybackDevice;
g_iRecordDevice = m_iCurrRecordDevice;
g_iPlaybackOutput = m_iCurrOutput;
g_iRecordInput = m_iCurrInput;
if( m_iCurrPlaybackDevice>=0 ){
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;
}
}
}
if( m_iCurrRecordDevice>=0 ){
int 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_ckAuto->Checked;
g_bRecordMoniter = !(m_iCurrRecordDevice&IO_DEVICE_MIDI) && m_ckMoniter->Checked;
f_MM_SetRecordMoniter( g_bRecordMoniter );
}
//---------------------------------------------------------------------------
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 __fastcall TMicSetForm::AutoChange(TObject *Sender)
{
f_MM_SetRecordAutoAdjust( m_ckAuto->Checked );
}
//---------------------------------------------------------------------------
void __fastcall TMicSetForm::MoniterChange(TObject *Sender)
{
f_MM_SetRecordMoniter( m_ckMoniter->Checked );
}
//---------------------------------------------------------------------------
void __fastcall TMicSetForm::PlayDevChange(TComboBoxItem *Sender, int Index)
{
int iNewDev = m_cbPlayDev->GetItem(Index)->Tag;
if( iNewDev==m_iCurrPlaybackDevice )
return;
BeginRecordTest( false );
int iType = (m_iCurrPlaybackDevice & 0xF0000);
int iPlayDev = iNewDev, iOutput = -1,
iRecDev = m_iCurrRecordDevice,
iInput = m_iCurrInput;
if( !m_ckMIDI->Checked && 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();
if( !m_ckMIDI->Checked ){
ReloadRecDev();
ReloadInput();
}
}
if( hr==S_OK ){
if( m_iCurrRecordDevice>=0 )
BeginRecordTest();
}
else
ShowErrorMessage( hr );
m_tbVolume->Enabled = hr==S_OK;
Screen->Cursor = crDefault;
}
//---------------------------------------------------------------------------
void __fastcall TMicSetForm::RecDevChange(TComboBoxItem *Sender, int Index)
{
int iNewDev = m_cbRecDev->GetItem(Index)->Tag;
if( iNewDev==m_iCurrRecordDevice )
return;
BeginRecordTest( false );
int iPlayDev = m_iCurrPlaybackDevice,
iOutput = m_iCurrOutput,
iRecDev = iNewDev,
iInput = (iNewDev & IO_DEVICE_MIDI) ? 0 : -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;
ReloadInput();
if( hr==S_OK ){
if( m_iCurrRecordDevice>=0 )
BeginRecordTest();
}
else{
ShowErrorMessage( hr );
}
m_tbVolume->Enabled = hr==S_OK;
Screen->Cursor = crDefault;
}
//---------------------------------------------------------------------------
void __fastcall TMicSetForm::OutputChange(TComboBoxItem *Sender, int Index)
{
if( !m_rbASIO->Checked )
return;
int iIndex = Index * 2;
if( iIndex==m_iCurrOutput )
return;
BeginRecordTest( false );
int iPlayDev = m_iCurrPlaybackDevice,
iOutput = iIndex,
iRecDev = m_iCurrRecordDevice,
iInput = m_iCurrInput;
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( hr==S_OK ){
if( m_iCurrRecordDevice>=0 )
BeginRecordTest();
}
else{
ShowErrorMessage( hr );
}
m_tbVolume->Enabled = hr==S_OK;
Screen->Cursor = crDefault;
}
//---------------------------------------------------------------------------
void __fastcall TMicSetForm::InputChange(TComboBoxItem *Sender, int Index)
{
if( m_rbWASAPI->Checked && !m_ckMIDI->Checked )
return;
int iInput = m_cbInput->DefItemIndex;
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::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::MIDIInputClick(TObject *Sender)
{
bool bMidi = m_iCurrRecordDevice>0 && (m_iCurrRecordDevice & IO_DEVICE_MIDI);
if( bMidi==m_ckMIDI->Checked )
return;
BeginRecordTest( false );
int iPlayDev = m_iCurrPlaybackDevice,
iOutput = m_iCurrOutput,
iRecDev = -1,
iInput = -1;
if( m_ckMIDI->Checked ){
iRecDev = m_aMidiRc[0]->iDevice;
iInput = 0;
}
else{
int iPbType = m_iCurrPlaybackDevice & 0xF0000;
if( iPbType==IO_DEVICE_ASIO ){
iRecDev = iPlayDev;
}
else{
vector<IO_DEVICE_INFO*>& rDevsRc = iPbType==IO_DEVICE_WASAPI ? m_aWasapiRc
: m_aCommonRc;
if( rDevsRc.empty() ){
iRecDev = iPbType;
}
else{
for( int i=0; i<rDevsRc.size(); i++ ){
if( rDevsRc[i]->flags & DEVICE_DEFAULT ){
iRecDev = rDevsRc[i]->iDevice;
break;
}
}
}
}
}
Screen->Cursor = crHourGlass;
HRESULT hr = f_MM_SetIODevice( iPlayDev, iOutput, iRecDev, iInput );
m_iCurrPlaybackDevice = iPlayDev;
m_iCurrOutput = iOutput;
m_iCurrRecordDevice = iRecDev;
m_iCurrInput = iInput;
ReloadRecDev();
ReloadInput();
if( hr==S_OK ){
if( m_iCurrRecordDevice>=0 )
BeginRecordTest();
}
else{
ShowErrorMessage( hr );
}
Screen->Cursor = crDefault;
}
//---------------------------------------------------------------------------
void __fastcall TMicSetForm::DevTypeClick(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( m_ckMIDI->Checked ){
iRecDev = m_iCurrRecordDevice;
iInput = m_iCurrInput;
}
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;
}
//---------------------------------------------------------------------------
void __fastcall TMicSetForm::ASIOClick(TObject *Sender)
{
if( m_PopupMenu ){
delete m_PopupMenu;
m_PopupMenu = NULL;
}
m_PopupMenu = new TMenuPanel();
m_PopupMenu->Parent = this;
m_PopupMenu->CreateMenu( "显示面板", "", DoShowPanel );
m_PopupMenu->CreateMenu( "重启设备", "", DoRestart );
m_PopupMenu->Width = m_lblASIO->Width;
m_PopupMenu->Show( m_lblASIO->Left, m_lblASIO->Top+m_lblASIO->Height );
}
//---------------------------------------------------------------------------