PSRatioCalc.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /*
  2. * PSRatioCalc.cpp
  3. * ---------------
  4. * Purpose: Dialog for calculating sample pitch shift ratios in the sample editor.
  5. * Notes : (currently none)
  6. * Authors: OpenMPT Devs
  7. * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
  8. */
  9. #include "stdafx.h"
  10. #include "Mptrack.h"
  11. #include "Mainfrm.h"
  12. #include "PSRatioCalc.h"
  13. OPENMPT_NAMESPACE_BEGIN
  14. // CPSRatioCalc dialog
  15. IMPLEMENT_DYNAMIC(CPSRatioCalc, CDialog)
  16. CPSRatioCalc::CPSRatioCalc(const CSoundFile &sndFile, SAMPLEINDEX sample, double ratio, CWnd* pParent /*=NULL*/)
  17. : CDialog(IDD_PITCHSHIFT, pParent)
  18. , m_dRatio(ratio)
  19. , sndFile(sndFile)
  20. , sampleIndex(sample)
  21. {
  22. // Calculate/verify samplerate at C5.
  23. const ModSample &smp = sndFile.GetSample(sampleIndex);
  24. uint32 sampleRate = smp.GetSampleRate(sndFile.GetType());
  25. if(sampleRate <= 0)
  26. sampleRate = 8363;
  27. m_nSpeed = sndFile.m_PlayState.m_nMusicSpeed;
  28. m_nTempo = sndFile.m_PlayState.m_nMusicTempo;
  29. // Sample rate will not change. We can calculate original duration once and disgard sampleRate.
  30. m_lMsOrig = static_cast<ULONGLONG>(1000.0 * ((double)smp.nLength / sampleRate));
  31. CalcSamples();
  32. CalcMs();
  33. CalcRows();
  34. }
  35. void CPSRatioCalc::DoDataExchange(CDataExchange* pDX)
  36. {
  37. CWnd* hasFocus = GetFocus();
  38. CDialog::DoDataExchange(pDX);
  39. SmpLength origLength = sndFile.GetSample(sampleIndex).nLength;
  40. DDX_Text(pDX, IDC_SAMPLE_LENGTH_ORIGINAL, origLength);
  41. DDX_Text(pDX, IDC_SAMPLE_LENGTH_NEW, m_lSamplesNew);
  42. DDX_Text(pDX, IDC_MS_LENGTH_ORIGINAL2, m_lMsOrig);
  43. DDX_Text(pDX, IDC_MS_LENGTH_NEW, m_lMsNew);
  44. DDX_Text(pDX, IDC_SPEED, m_nSpeed);
  45. DDX_Text(pDX, IDC_ROW_LENGTH_ORIGINAL, m_dRowsOrig);
  46. //These 2 CEdits must only be updated if they don't have focus (to preserve trailing . and 0s etc..)
  47. if (pDX->m_bSaveAndValidate || hasFocus != GetDlgItem(IDC_ROW_LENGTH_NEW2))
  48. DDX_Text(pDX, IDC_ROW_LENGTH_NEW2, m_dRowsNew);
  49. if (pDX->m_bSaveAndValidate || hasFocus != GetDlgItem(IDC_PSRATIO))
  50. DDX_Text(pDX, IDC_PSRATIO, m_dRatio);
  51. }
  52. BEGIN_MESSAGE_MAP(CPSRatioCalc, CDialog)
  53. ON_EN_UPDATE(IDC_SAMPLE_LENGTH_NEW, &CPSRatioCalc::OnEnChangeSamples)
  54. ON_EN_UPDATE(IDC_MS_LENGTH_NEW, &CPSRatioCalc::OnEnChangeMs)
  55. ON_EN_UPDATE(IDC_SPEED, &CPSRatioCalc::OnEnChangeSpeed)
  56. ON_EN_UPDATE(IDC_TEMPO, &CPSRatioCalc::OnEnChangeSpeed)
  57. ON_EN_UPDATE(IDC_ROW_LENGTH_NEW2, &CPSRatioCalc::OnEnChangeRows)
  58. ON_EN_UPDATE(IDC_PSRATIO, &CPSRatioCalc::OnEnChangeratio)
  59. ON_BN_CLICKED(IDOK, &CPSRatioCalc::OnBnClickedOk)
  60. END_MESSAGE_MAP()
  61. BOOL CPSRatioCalc::OnInitDialog()
  62. {
  63. CDialog::OnInitDialog();
  64. m_EditTempo.SubclassDlgItem(IDC_TEMPO, this);
  65. m_EditTempo.AllowNegative(false);
  66. m_EditTempo.SetTempoValue(m_nTempo);
  67. return TRUE;
  68. }
  69. // CPSRatioCalc message handlers
  70. void CPSRatioCalc::OnEnChangeSamples()
  71. {
  72. UpdateData();
  73. if (m_lSamplesNew && sndFile.GetSample(sampleIndex).nLength)
  74. {
  75. m_dRatio = (double)m_lSamplesNew / (double)sndFile.GetSample(sampleIndex).nLength * 100;
  76. CalcMs();
  77. CalcRows();
  78. UpdateData(FALSE);
  79. }
  80. }
  81. void CPSRatioCalc::OnEnChangeMs()
  82. {
  83. UpdateData();
  84. if (m_lMsOrig && m_lMsNew)
  85. {
  86. m_dRatio = (double)m_lMsNew / (double)m_lMsOrig * 100;
  87. CalcSamples();
  88. CalcRows();
  89. UpdateData(FALSE);
  90. }
  91. }
  92. void CPSRatioCalc::OnEnChangeRows()
  93. {
  94. UpdateData();
  95. if (m_dRowsOrig && m_dRowsNew)
  96. {
  97. m_dRatio = m_dRowsNew / m_dRowsOrig * 100.0;
  98. CalcSamples();
  99. CalcMs();
  100. UpdateData(FALSE);
  101. }
  102. }
  103. void CPSRatioCalc::OnEnChangeSpeed()
  104. {
  105. UpdateData();
  106. m_nTempo = m_EditTempo.GetTempoValue();
  107. if (m_nTempo < TEMPO(1, 0)) m_nTempo = TEMPO(1, 0);
  108. if (m_nSpeed < 1) m_nSpeed = 1;
  109. CalcRows();
  110. UpdateData(FALSE);
  111. }
  112. void CPSRatioCalc::OnEnChangeratio()
  113. {
  114. UpdateData();
  115. if (m_dRatio)
  116. {
  117. CalcSamples();
  118. CalcMs();
  119. CalcRows();
  120. UpdateData(FALSE);
  121. }
  122. }
  123. // CPSRatioCalc Internal Calculations:
  124. void CPSRatioCalc::CalcSamples()
  125. {
  126. m_lSamplesNew = static_cast<ULONGLONG>(sndFile.GetSample(sampleIndex).nLength * (m_dRatio / 100.0));
  127. return;
  128. }
  129. void CPSRatioCalc::CalcMs()
  130. {
  131. m_lMsNew = static_cast<ULONGLONG>(m_lMsOrig * (m_dRatio / 100.0));
  132. return;
  133. }
  134. void CPSRatioCalc::CalcRows()
  135. {
  136. double rowTime = sndFile.GetRowDuration(m_nTempo, m_nSpeed);
  137. m_dRowsOrig = (double)m_lMsOrig / rowTime;
  138. m_dRowsNew = m_dRowsOrig * (m_dRatio / 100);
  139. return;
  140. }
  141. void CPSRatioCalc::OnBnClickedOk()
  142. {
  143. if (m_dRatio<50.0 || m_dRatio>200.0)
  144. {
  145. Reporting::Error("Error: ratio must be between 50% and 200%.");
  146. return;
  147. }
  148. OnOK();
  149. }
  150. OPENMPT_NAMESPACE_END