//--------------------------------------------------------------------------- #include #pragma hdrstop #include "SetUpFormUnit.h" #include //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma link "GeneralDialogPanel" #pragma link "PNGButton" #pragma link "LineEdit" #pragma link "TextButton" #pragma resource "*.dfm" TSetUpForm *SetUpForm; //--------------------------------------------------------------------------- static const COLORREF colLable = RGB(156, 170, 189); #define SPEED_MIN 50 #define SPEED_MAX 200 //--------------------------------------------------------------------------- __fastcall TSetUpForm::TSetUpForm(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TSetUpForm::FormCreate(TObject *Sender) { m_pBKGPanel->Font->Size = g_szFont9; m_pEDspeed->SetTextFont(g_strTxtFontName, g_szFont9); m_pBtnCancel->FontSize = g_szFont9; m_pBtnOK->FontSize = g_szFont9; m_plbSpeed->Font->Color = colLable; m_pLBSpeedMin->Font->Color = colLable; m_pLBSpeedMax->Font->Color = colLable; m_plbBeat->Font->Color = colLable; m_pLBBeat44->Font->Color = colLable; m_pLBBeat43->Font->Color = colLable; m_pLBBeat42->Font->Color = colLable; m_pLBBeat86->Font->Color = colLable; ///////////////////////////// m_pPNGBTPlayTry->Visible = true; m_pPNGBTPlaying->Visible = false; m_pSpeedUD->Position = g_nMelodyTempo; m_pEDspeed->Text = IntToStr(g_nMelodyTempo); m_btnSpeed->Hint = L"设置速度\n连续点击鼠标或空格键"; m_iTS = g_iMelodyTimeSignature; m_nTempo = g_nMelodyTempo; m_pTBBeat->Max = 3; m_pTBBeat->Min = 0; m_pTBBeat->Position = g_iMelodyTimeSignature; m_pTBBeat->Enabled = g_Theme.Empty();// g_lstRawBars.empty(); m_pTBSpeed->Max = 200; m_pTBSpeed->Min = 50; m_pTBSpeed->Position = g_nMelodyTempo; HRESULT hResult = f_MM_CreateRealTimeMIDIStream( true ); if (hResult != S_OK) { DebugPrint("Create realtime midi stream error.\n"); } SetTransparent( this ); } //--------------------------------------------------------------------------- void __fastcall TSetUpForm::m_pEDspeedChange(TObject *Sender) { String str = m_pEDspeed->Text; int n = str.Length(); if (n == 0) return; bool flag = false; for (int i = 1; i <= n; i++) { if (str[i] < '0' || str[i] > '9') { m_pEDspeed->Clear(); flag = true; break; } } if (!flag) { int iSpeed = StrToInt(str); if ( iSpeed > SPEED_MAX ) m_pEDspeed->Text = iSpeed = SPEED_MAX; if( iSpeed>=SPEED_MIN && iSpeed<=SPEED_MAX ) { m_pSpeedUD->Position = iSpeed; m_pTBSpeed->Position = iSpeed; f_MM_SetTempo( iSpeed ); m_nTempo = iSpeed; } } } //--------------------------------------------------------------------------- void __fastcall TSetUpForm::PNGBTPlay(TObject *Sender) { TPNGButton *pPlay = (TPNGButton *)Sender; if(pPlay == m_pPNGBTPlayTry) { f_MM_Stop(); f_MM_Play( Handle, 0, TYPE_BEAT ); m_pPNGBTPlayTry->Hide(); m_pPNGBTPlaying->Show(); }else if(pPlay == m_pPNGBTPlaying){ f_MM_Stop(); m_pPNGBTPlayTry->Show(); m_pPNGBTPlaying->Hide(); } } //--------------------------------------------------------------------------- void __fastcall TSetUpForm::FormClose(TObject *Sender, TCloseAction &Action) { f_MM_Stop(); HRESULT hResult = f_MM_FreeRealTimeMIDIStream(); if (hResult != S_OK) { DebugPrint("Free realtime midi stream error.\n"); } } //--------------------------------------------------------------------------- void __fastcall TSetUpForm::m_btnSpeedMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { if( m_pPNGBTPlaying->Visible ){ f_MM_Stop(); m_pPNGBTPlayTry->Show(); m_pPNGBTPlaying->Hide(); } static int nDownNums = 0; static DWORD timeIni = 0; static DWORD timeSAverage = 0; DWORD timeCur = timeGetTime(); static DWORD timePre = timeCur; DWORD nCalTime; HRESULT hRet = f_MM_RealTimeMIDINoteOn( 42 ); //36 bool bTempo200 = (timeCur-timePre) < (60000/200)?(timeCur-timePre!=0?1:0):0; static int i=1; i++; //如果距离上次时间 //大于 一拍最慢速度所需时间 //重置 nDownNums和初始时间 if( timeCur-timePre > 60000/50 ) { nDownNums = 0; timeIni = 0; } nDownNums++; if( nDownNums<=3 ) { if( bTempo200 ) { nDownNums--; }else if(nDownNums != 1){ timeIni += timeCur - timePre; } } if( nDownNums>=3 && !bTempo200){ if(nDownNums==3){ nCalTime = timeSAverage = timeIni/2; }else{ //平滑处理 nCalTime = timeCur - timePre; nCalTime = (nCalTime + timeSAverage*3)/4; timeSAverage = nCalTime; } int nTempo = 0; if( nCalTime ) nTempo = 60000/nCalTime; if( nTempo>=50 && nTempo<=200 ){ m_pSpeedUD->Position = nTempo; m_pTBSpeed->Position = nTempo; m_pEDspeed->Text = IntToStr(nTempo); f_MM_SetTempo( nTempo ); m_nTempo = nTempo; } } timePre = timeCur; } //--------------------------------------------------------------------------- void __fastcall TSetUpForm::FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { switch( Key ){ case VK_SPACE: m_btnSpeedMouseDown( NULL, mbLeft, TShiftState(NULL), 0, 0 ); m_btnSpeed->SetDown(true); break; case VK_ESCAPE: ModalResult = mrCancel; break; case VK_RETURN: ModalResult = mrOk; break; default: break; } } //--------------------------------------------------------------------------- void __fastcall TSetUpForm::FormKeyUp(TObject *Sender, WORD &Key, TShiftState Shift) { switch( Key ){ case VK_SPACE: // m_btnSpeedMouseDown( NULL, mbLeft, TShiftState(NULL),0 ,0 ); m_btnSpeed->SetDown(false); break; default: break; } } //--------------------------------------------------------------------------- void __fastcall TSetUpForm::SkinTrackBarChange(TObject *Sender) { TSkinTrackBar *pTB = (TSkinTrackBar *)Sender; if( pTB == m_pTBSpeed) { int iSpeed = pTB->Position; m_pSpeedUD->Position = iSpeed; m_pEDspeed->Text = IntToStr(iSpeed); f_MM_SetTempo( iSpeed ); m_nTempo = iSpeed; }else { f_MM_Stop(); f_MM_SetTimeSignature( pTB->Position ); m_iTS = pTB->Position; if( m_pPNGBTPlaying->Visible ) f_MM_Play( Handle, 0, TYPE_BEAT ); } } //--------------------------------------------------------------------------- void __fastcall TSetUpForm::EventUDOnClicked(TObject *Sender, TUDBtnType Button) { if(Button == btNext) m_pSpeedUD->Position += 1; else m_pSpeedUD->Position -= 1; if(m_pSpeedUD->Position > SPEED_MAX) m_pSpeedUD->Position = SPEED_MAX; else if(m_pSpeedUD->Position < SPEED_MIN) m_pSpeedUD->Position = SPEED_MIN; m_pTBSpeed->Position = m_pSpeedUD->Position; m_pEDspeed->Text = IntToStr(m_pSpeedUD->Position); f_MM_SetTempo( m_pSpeedUD->Position ); m_nTempo = m_pSpeedUD->Position; } //---------------------------------------------------------------------------