/* * PSRatioCalc.cpp * --------------- * Purpose: Dialog for calculating sample pitch shift ratios in the sample editor. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Mptrack.h" #include "Mainfrm.h" #include "PSRatioCalc.h" OPENMPT_NAMESPACE_BEGIN // CPSRatioCalc dialog IMPLEMENT_DYNAMIC(CPSRatioCalc, CDialog) CPSRatioCalc::CPSRatioCalc(const CSoundFile &sndFile, SAMPLEINDEX sample, double ratio, CWnd* pParent /*=NULL*/) : CDialog(IDD_PITCHSHIFT, pParent) , m_dRatio(ratio) , sndFile(sndFile) , sampleIndex(sample) { // Calculate/verify samplerate at C5. const ModSample &smp = sndFile.GetSample(sampleIndex); uint32 sampleRate = smp.GetSampleRate(sndFile.GetType()); if(sampleRate <= 0) sampleRate = 8363; m_nSpeed = sndFile.m_PlayState.m_nMusicSpeed; m_nTempo = sndFile.m_PlayState.m_nMusicTempo; // Sample rate will not change. We can calculate original duration once and disgard sampleRate. m_lMsOrig = static_cast(1000.0 * ((double)smp.nLength / sampleRate)); CalcSamples(); CalcMs(); CalcRows(); } void CPSRatioCalc::DoDataExchange(CDataExchange* pDX) { CWnd* hasFocus = GetFocus(); CDialog::DoDataExchange(pDX); SmpLength origLength = sndFile.GetSample(sampleIndex).nLength; DDX_Text(pDX, IDC_SAMPLE_LENGTH_ORIGINAL, origLength); DDX_Text(pDX, IDC_SAMPLE_LENGTH_NEW, m_lSamplesNew); DDX_Text(pDX, IDC_MS_LENGTH_ORIGINAL2, m_lMsOrig); DDX_Text(pDX, IDC_MS_LENGTH_NEW, m_lMsNew); DDX_Text(pDX, IDC_SPEED, m_nSpeed); DDX_Text(pDX, IDC_ROW_LENGTH_ORIGINAL, m_dRowsOrig); //These 2 CEdits must only be updated if they don't have focus (to preserve trailing . and 0s etc..) if (pDX->m_bSaveAndValidate || hasFocus != GetDlgItem(IDC_ROW_LENGTH_NEW2)) DDX_Text(pDX, IDC_ROW_LENGTH_NEW2, m_dRowsNew); if (pDX->m_bSaveAndValidate || hasFocus != GetDlgItem(IDC_PSRATIO)) DDX_Text(pDX, IDC_PSRATIO, m_dRatio); } BEGIN_MESSAGE_MAP(CPSRatioCalc, CDialog) ON_EN_UPDATE(IDC_SAMPLE_LENGTH_NEW, &CPSRatioCalc::OnEnChangeSamples) ON_EN_UPDATE(IDC_MS_LENGTH_NEW, &CPSRatioCalc::OnEnChangeMs) ON_EN_UPDATE(IDC_SPEED, &CPSRatioCalc::OnEnChangeSpeed) ON_EN_UPDATE(IDC_TEMPO, &CPSRatioCalc::OnEnChangeSpeed) ON_EN_UPDATE(IDC_ROW_LENGTH_NEW2, &CPSRatioCalc::OnEnChangeRows) ON_EN_UPDATE(IDC_PSRATIO, &CPSRatioCalc::OnEnChangeratio) ON_BN_CLICKED(IDOK, &CPSRatioCalc::OnBnClickedOk) END_MESSAGE_MAP() BOOL CPSRatioCalc::OnInitDialog() { CDialog::OnInitDialog(); m_EditTempo.SubclassDlgItem(IDC_TEMPO, this); m_EditTempo.AllowNegative(false); m_EditTempo.SetTempoValue(m_nTempo); return TRUE; } // CPSRatioCalc message handlers void CPSRatioCalc::OnEnChangeSamples() { UpdateData(); if (m_lSamplesNew && sndFile.GetSample(sampleIndex).nLength) { m_dRatio = (double)m_lSamplesNew / (double)sndFile.GetSample(sampleIndex).nLength * 100; CalcMs(); CalcRows(); UpdateData(FALSE); } } void CPSRatioCalc::OnEnChangeMs() { UpdateData(); if (m_lMsOrig && m_lMsNew) { m_dRatio = (double)m_lMsNew / (double)m_lMsOrig * 100; CalcSamples(); CalcRows(); UpdateData(FALSE); } } void CPSRatioCalc::OnEnChangeRows() { UpdateData(); if (m_dRowsOrig && m_dRowsNew) { m_dRatio = m_dRowsNew / m_dRowsOrig * 100.0; CalcSamples(); CalcMs(); UpdateData(FALSE); } } void CPSRatioCalc::OnEnChangeSpeed() { UpdateData(); m_nTempo = m_EditTempo.GetTempoValue(); if (m_nTempo < TEMPO(1, 0)) m_nTempo = TEMPO(1, 0); if (m_nSpeed < 1) m_nSpeed = 1; CalcRows(); UpdateData(FALSE); } void CPSRatioCalc::OnEnChangeratio() { UpdateData(); if (m_dRatio) { CalcSamples(); CalcMs(); CalcRows(); UpdateData(FALSE); } } // CPSRatioCalc Internal Calculations: void CPSRatioCalc::CalcSamples() { m_lSamplesNew = static_cast(sndFile.GetSample(sampleIndex).nLength * (m_dRatio / 100.0)); return; } void CPSRatioCalc::CalcMs() { m_lMsNew = static_cast(m_lMsOrig * (m_dRatio / 100.0)); return; } void CPSRatioCalc::CalcRows() { double rowTime = sndFile.GetRowDuration(m_nTempo, m_nSpeed); m_dRowsOrig = (double)m_lMsOrig / rowTime; m_dRowsNew = m_dRowsOrig * (m_dRatio / 100); return; } void CPSRatioCalc::OnBnClickedOk() { if (m_dRatio<50.0 || m_dRatio>200.0) { Reporting::Error("Error: ratio must be between 50% and 200%."); return; } OnOK(); } OPENMPT_NAMESPACE_END