📄 compressor.cpp
字号:
{ wxPaintDC dc(this); int width, height; GetSize(&width, &height); if (!mBitmap || mWidth!=width || mHeight!=height) { if (mBitmap) delete mBitmap; mWidth = width; mHeight = height; mBitmap = new wxBitmap(mWidth, mHeight); } wxColour bkgnd = GetBackgroundColour(); wxBrush bkgndBrush(bkgnd, wxSOLID); wxMemoryDC memDC; memDC.SelectObject(*mBitmap); wxRect bkgndRect; bkgndRect.x = 0; bkgndRect.y = 0; bkgndRect.width = 40; bkgndRect.height = mHeight; memDC.SetBrush(bkgndBrush); memDC.SetPen(*wxTRANSPARENT_PEN); memDC.DrawRectangle(bkgndRect); bkgndRect.y = mHeight - 20; bkgndRect.width = mWidth; bkgndRect.height = 20; memDC.DrawRectangle(bkgndRect); wxRect border; border.x = 40; border.y = 0; border.width = mWidth; border.height = mHeight - 20; memDC.SetBrush(*wxWHITE_BRUSH); memDC.SetPen(*wxBLACK_PEN); memDC.DrawRectangle(border); mEnvRect.x = 44; mEnvRect.width = mWidth - 50; mEnvRect.y = 3; mEnvRect.height = mHeight - 26; double rangeDB = 60; int kneeX = (int)rint((rangeDB+threshold)*mEnvRect.width/rangeDB); int kneeY = (int)rint((rangeDB+threshold)*mEnvRect.height/rangeDB); int finalY = kneeY + (int)rint((-threshold/ratio)*mEnvRect.height/rangeDB); // Yellow line for threshold memDC.SetPen(wxPen(wxColour(220, 220, 0), 1, wxSOLID)); memDC.DrawLine(mEnvRect.x, mEnvRect.y + mEnvRect.height - kneeY, mEnvRect.x + mEnvRect.width, mEnvRect.y + mEnvRect.height - kneeY); // Was: Nice dark red line for the compression diagram// memDC.SetPen(wxPen(wxColour(180, 40, 40), 3, wxSOLID)); // Nice blue line for compressor, same color as used in the waveform envelope. memDC.SetPen( AColor::WideEnvelopePen) ; memDC.DrawLine(mEnvRect.x, mEnvRect.y + mEnvRect.height, mEnvRect.x + kneeX, mEnvRect.y + mEnvRect.height - kneeY); memDC.DrawLine(mEnvRect.x + kneeX, mEnvRect.y + mEnvRect.height - kneeY, mEnvRect.x + mEnvRect.width, mEnvRect.y + mEnvRect.height - finalY); // Paint border again memDC.SetBrush(*wxTRANSPARENT_BRUSH); memDC.SetPen(*wxBLACK_PEN); memDC.DrawRectangle(border); // Ruler Ruler vRuler; vRuler.SetBounds(0, 0, 40, mHeight-21); vRuler.SetOrientation(wxVERTICAL); vRuler.SetRange(0, -rangeDB); vRuler.SetFormat(Ruler::LinearDBFormat); vRuler.SetUnits(_("dB")); vRuler.Draw(memDC); Ruler hRuler; hRuler.SetBounds(41, mHeight-20, mWidth, mHeight); hRuler.SetOrientation(wxHORIZONTAL); hRuler.SetRange(-rangeDB, 0); hRuler.SetFormat(Ruler::LinearDBFormat); hRuler.SetUnits(_("dB")); hRuler.SetFlip(true); hRuler.Draw(memDC); dc.Blit(0, 0, mWidth, mHeight, &memDC, 0, 0, wxCOPY, FALSE);}//----------------------------------------------------------------------------// CompressorDialog//----------------------------------------------------------------------------enum { ThresholdID = 7100, RatioID, AttackID, PreviewID};BEGIN_EVENT_TABLE(CompressorDialog,wxDialog) EVT_BUTTON( wxID_OK, CompressorDialog::OnOk ) EVT_BUTTON( wxID_CANCEL, CompressorDialog::OnCancel ) EVT_BUTTON( PreviewID, CompressorDialog::OnPreview ) EVT_SIZE( CompressorDialog::OnSize ) EVT_SLIDER( ThresholdID, CompressorDialog::OnSlider ) EVT_SLIDER( RatioID, CompressorDialog::OnSlider ) EVT_SLIDER( AttackID, CompressorDialog::OnSlider )END_EVENT_TABLE()CompressorDialog::CompressorDialog(EffectCompressor *effect, wxWindow *parent, wxWindowID id, const wxString &title, const wxPoint &position, const wxSize& size, long style ) : wxDialog( parent, id, title, position, size, style ), mEffect(effect){ wxBoxSizer *mainSizer = new wxBoxSizer(wxVERTICAL); mainSizer->Add(new wxStaticText(this, -1, _("Dynamic Range Compressor by Dominic Mazzoni"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE), 0, wxALIGN_CENTRE|wxALL, 5); mPanel = new CompressorPanel(this, -1); mPanel->threshold = threshold; mPanel->ratio = ratio; mainSizer->Add(mPanel, 1, wxGROW|wxALIGN_CENTRE|wxALL, 5); wxFlexGridSizer *gridSizer = new wxFlexGridSizer(2, 0, 0); mThresholdText = new wxStaticText(this, -1, wxString(_("Threshold: ")) + wxT("XXX dB")); gridSizer->Add(mThresholdText, 0, wxALIGN_LEFT|wxALL, 5); mThresholdSlider = new wxSlider(this, ThresholdID, -8, -60, -1, wxDefaultPosition, wxSize(200, -1), wxSL_HORIZONTAL); gridSizer->Add(mThresholdSlider, 1, wxEXPAND|wxALL, 5); mRatioText = new wxStaticText(this, -1, wxString(_("Ratio: ")) + wxT("XXXX:1")); gridSizer->Add(mRatioText, 0, wxALIGN_LEFT|wxALL, 5); mRatioSlider = new wxSlider(this, RatioID, 4, 3, 20, wxDefaultPosition, wxSize(200, -1), wxSL_HORIZONTAL); gridSizer->Add(mRatioSlider, 1, wxEXPAND|wxALL, 5); mAttackText = new wxStaticText(this, -1, wxString(_("Attack Time: ")) + wxT("XXXX secs")); gridSizer->Add(mAttackText, 0, wxALIGN_LEFT|wxALL, 5); mAttackSlider = new wxSlider(this, AttackID, 2, 1, 10, wxDefaultPosition, wxSize(200, -1), wxSL_HORIZONTAL); gridSizer->Add(mAttackSlider, 1, wxEXPAND|wxALL, 5); mainSizer->Add(gridSizer, 0, wxALIGN_CENTRE|wxALIGN_CENTER_VERTICAL|wxALL, 5); wxBoxSizer *hSizer = new wxBoxSizer(wxHORIZONTAL); mGainCheckBox = new wxCheckBox(this, -1, _("Normalize to 0dB after compressing")); mGainCheckBox->SetValue(true); hSizer->Add(mGainCheckBox, 0, wxALIGN_LEFT|wxALL, 5); mainSizer->Add(hSizer, 0, wxALIGN_CENTRE|wxALIGN_CENTER_VERTICAL|wxALL, 5); hSizer = new wxBoxSizer(wxHORIZONTAL); wxButton *preview = new wxButton(this, PreviewID, mEffect->GetPreviewName()); hSizer->Add(preview, 0, wxALIGN_CENTRE|wxALL, 5); hSizer->Add(40, 10); wxButton *cancel = new wxButton(this, wxID_CANCEL, _("Cancel")); hSizer->Add(cancel, 0, wxALIGN_CENTRE|wxALL, 5); wxButton *ok = new wxButton(this, wxID_OK, _("OK")); ok->SetDefault(); ok->SetFocus(); hSizer->Add(ok, 0, wxALIGN_CENTRE|wxALL, 5); mainSizer->Add(hSizer, 0, wxALIGN_CENTRE|wxALIGN_CENTER_VERTICAL|wxALL, 5); SetAutoLayout(true); SetSizer(mainSizer); mainSizer->Fit(this); mainSizer->SetSizeHints(this); SetSizeHints(500, 300, 20000, 20000); SetSize(500, 400);}bool CompressorDialog::TransferDataToWindow(){ mPanel->threshold = threshold; mPanel->ratio = ratio; mThresholdSlider->SetValue((int)rint(threshold)); mRatioSlider->SetValue((int)rint(ratio*2)); mAttackSlider->SetValue((int)rint(attack*10)); mGainCheckBox->SetValue(useGain); TransferDataFromWindow(); return true;}bool CompressorDialog::TransferDataFromWindow(){ threshold = (double)mThresholdSlider->GetValue(); ratio = (double)(mRatioSlider->GetValue() / 2.0); attack = (double)(mAttackSlider->GetValue() / 10.0); useGain = mGainCheckBox->GetValue(); mPanel->threshold = threshold; mPanel->ratio = ratio; mThresholdText->SetLabel(wxString::Format(_("Threshold: %d dB"), (int)threshold)); if (mRatioSlider->GetValue()%2 == 0) mRatioText->SetLabel(wxString::Format(_("Ratio: %.0f:1"), ratio)); else mRatioText->SetLabel(wxString::Format(_("Ratio: %.1f:1"), ratio)); mAttackText->SetLabel(wxString::Format(_("Attack Time: %.1f secs"), attack)); mPanel->Refresh(false); return true;}void CompressorDialog::OnSize(wxSizeEvent &event){ event.Skip();}void CompressorDialog::OnOk(wxCommandEvent &event){ TransferDataFromWindow(); EndModal(true);}void CompressorDialog::OnPreview(wxCommandEvent &event){ TransferDataFromWindow(); // Save & restore parameters around Preview, because we didn't do OK. double oldAttackTime = mEffect->mAttackTime; double oldThresholdDB = mEffect->mThresholdDB; double oldRatio = mEffect->mRatio; bool oldUseGain = mEffect->mNormalize; mEffect->mAttackTime = attack; mEffect->mThresholdDB = threshold; mEffect->mRatio = ratio; mEffect->mNormalize = useGain; mEffect->Preview(); mEffect->mAttackTime = oldAttackTime; mEffect->mThresholdDB = oldThresholdDB; mEffect->mRatio = oldRatio; mEffect->mNormalize = oldUseGain;}void CompressorDialog::OnCancel(wxCommandEvent &event){ EndModal(false);}void CompressorDialog::OnSlider(wxCommandEvent &event){ TransferDataFromWindow();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -