From: <sag...@us...> - 2011-10-15 23:42:26
|
Revision: 1105 http://modplug.svn.sourceforge.net/modplug/?rev=1105&view=rev Author: saga-games Date: 2011-10-15 23:42:19 +0000 (Sat, 15 Oct 2011) Log Message: ----------- [Fix] Pattern Editor: Fixed note interpolation (it was possible to interpolate between a note and f.e. note cut, but it was not possible to interpolate between a note and no note). [Mod] Plugin Window: Preset menu generation should now be a bit faster for plugins with lotsa presets (Synth1) [Imp] Sample Tuner: Added dialog where the pitch reference and target note can be specified. [Mod] OpenMPT: Version is now 1.20.00.43 Modified Paths: -------------- trunk/OpenMPT/mptrack/AbstractVstEditor.cpp trunk/OpenMPT/mptrack/Autotune.cpp trunk/OpenMPT/mptrack/Autotune.h trunk/OpenMPT/mptrack/Ctrl_smp.cpp trunk/OpenMPT/mptrack/View_pat.cpp trunk/OpenMPT/mptrack/mptrack.rc trunk/OpenMPT/mptrack/resource.h trunk/OpenMPT/mptrack/version.h Modified: trunk/OpenMPT/mptrack/AbstractVstEditor.cpp =================================================================== --- trunk/OpenMPT/mptrack/AbstractVstEditor.cpp 2011-10-15 13:36:57 UTC (rev 1104) +++ trunk/OpenMPT/mptrack/AbstractVstEditor.cpp 2011-10-15 23:42:19 UTC (rev 1105) @@ -411,36 +411,48 @@ m_pPresetMenu->CreatePopupMenu(); } + const int numSubMenus = (numProgs / PRESETS_PER_GROUP) + 1; + if(numSubMenus > 1) + { + // Create sub menus if necessary + m_pPresetMenuGroup.SetSize(numSubMenus); + for(int i = 0; i < numSubMenus; i++) + { + m_pPresetMenuGroup[i] = new CMenu(); + m_pPresetMenuGroup[i]->CreatePopupMenu(); + + CString label; + label.Format("Bank %d (%d-%d)", i, 1 + i * PRESETS_PER_GROUP, 1 + min((i + 1) * PRESETS_PER_GROUP - 1, numProgs)); + m_pPresetMenu->AppendMenu(MF_POPUP, (UINT) m_pPresetMenuGroup[i]->m_hMenu, label); + } + } + + int subMenuIndex = 0; + int entryInThisMenu = 0; + int entryInThisColumn = 0; + + // If there would only be 1 submenu, we add directly to factory menu + CMenu *targetMenu = (numProgs > PRESETS_PER_GROUP) ? m_pPresetMenuGroup[subMenuIndex] : m_pPresetMenu; + for (long p = 0; p < numProgs; p++) { CString programName = m_pVstPlugin->GetFormattedProgramName(p); - // Get menu item properties - const bool checkedItem = (p == curProg); - const bool splitMenu = (p % PRESETS_PER_COLUMN == 0 && p % PRESETS_PER_GROUP != 0); - const int subMenuIndex = p / PRESETS_PER_GROUP; - - if (numProgs > PRESETS_PER_GROUP) + if(++entryInThisMenu == PRESETS_PER_GROUP) { - // If necessary, add to appropriate submenu. - if (subMenuIndex >= m_pPresetMenuGroup.GetSize()) - { - //create new submenu if required. - m_pPresetMenuGroup.SetSize(m_pPresetMenuGroup.GetSize() + 1); - m_pPresetMenuGroup[subMenuIndex] = new CMenu(); - m_pPresetMenuGroup[subMenuIndex]->CreatePopupMenu(); - - CString label; - label.Format("Bank %d (%d-%d)", subMenuIndex, 1 + subMenuIndex * PRESETS_PER_GROUP, 1 + min((subMenuIndex + 1) * PRESETS_PER_GROUP - 1, numProgs)); - m_pPresetMenu->AppendMenu(MF_POPUP, (UINT) m_pPresetMenuGroup[subMenuIndex]->m_hMenu, label); - } - m_pPresetMenuGroup[subMenuIndex]->AppendMenu(MF_STRING | (checkedItem ? MF_CHECKED : 0) | (splitMenu ? MF_MENUBARBREAK : 0), ID_PRESET_SET + p, programName); - - } else + // Advance to next preset group (sub menu) + subMenuIndex++; + targetMenu = m_pPresetMenuGroup[subMenuIndex]; + entryInThisMenu = 0; + } + UINT splitMenuFlag = 0; + if(++entryInThisColumn == PRESETS_PER_COLUMN) { - // If there would only be 1 submenu, we add directly to factory menu - m_pPresetMenu->AppendMenu(MF_STRING | (checkedItem ? MF_CHECKED : MF_UNCHECKED) | (splitMenu ? MF_MENUBARBREAK : 0), ID_PRESET_SET + p, programName); + entryInThisColumn = 0; + splitMenuFlag = MF_MENUBARBREAK; } + + targetMenu->AppendMenu(MF_STRING | (p == curProg ? MF_CHECKED : MF_UNCHECKED) | splitMenuFlag, ID_PRESET_SET + p, programName); } //Add Factory menu to main menu Modified: trunk/OpenMPT/mptrack/Autotune.cpp =================================================================== --- trunk/OpenMPT/mptrack/Autotune.cpp 2011-10-15 13:36:57 UTC (rev 1104) +++ trunk/OpenMPT/mptrack/Autotune.cpp 2011-10-15 23:42:19 UTC (rev 1105) @@ -19,25 +19,25 @@ #define MIN_SAMPLE_LENGTH 2 -double Autotune::FrequencyToNote(double freq) const -//------------------------------------------------- +double Autotune::FrequencyToNote(double freq, double pitchReference) const +//------------------------------------------------------------------------ { - return ((12.0 * (log(freq / (440.0 / 2.0)) / log(2.0))) + 57.0); + return ((12.0 * (log(freq / (pitchReference / 2.0)) / log(2.0))) + 57.0); } -double Autotune::NoteToFrequency(double note) const -//------------------------------------------------- +double Autotune::NoteToFrequency(double note, double pitchReference) const +//------------------------------------------------------------------------ { - return 440.0 * pow(2.0, (note - 69.0) / 12.0); + return pitchReference * pow(2.0, (note - 69.0) / 12.0); } // Calculate the amount of samples for autocorrelation shifting for a given note -SmpLength Autotune::NoteToShift(uint32 sampleFreq, int note) const -//------------------------------------------------------------------- +SmpLength Autotune::NoteToShift(uint32 sampleFreq, int note, double pitchReference) const +//--------------------------------------------------------------------------------------- { - const double fundamentalFrequency = NoteToFrequency((double)note / BINS_PER_NOTE); + const double fundamentalFrequency = NoteToFrequency((double)note / BINS_PER_NOTE, pitchReference); return (SmpLength)max(Util::Round((double)sampleFreq / fundamentalFrequency), 1); } @@ -134,14 +134,14 @@ bool Autotune::CanApply() const - //----------------------------- +//----------------------------- { return (sample.pSample != nullptr && sample.nLength >= MIN_SAMPLE_LENGTH); } -bool Autotune::Apply() -//-------------------- +bool Autotune::Apply(double pitchReference, int targetNote) +//--------------------------------------------------------- { if(!CanApply()) { @@ -154,7 +154,7 @@ const uint32 sampleFreq = sample.GetSampleRate(modType); // At the lowest frequency, we get the highest autocorrelation shift amount. - const SmpLength maxShift = NoteToShift(sampleFreq, autocorrStartNote); + const SmpLength maxShift = NoteToShift(sampleFreq, autocorrStartNote, pitchReference); if(!PrepareSample(maxShift)) { return false; @@ -174,7 +174,7 @@ noteBin %= historyBins; } - const SmpLength autocorrShift = NoteToShift(sampleFreq, note); + const SmpLength autocorrShift = NoteToShift(sampleFreq, note, pitchReference); uint64 autocorrSum = 0; const int8 *normalData = sampleData; @@ -207,29 +207,34 @@ // ...and find global minimum int minimumBin = 0; - //bool decrease = false; for(int i = 0; i < historyBins; i++) { const int prev = (i > 0) ? (i - 1) : (historyBins - 1); - // Are we at a minimum? - //if(interpolatedHistogram[i] > interpolatedHistogram[prev] && decrease) + // Are we at the global minimum? + if(interpolatedHistogram[prev] < interpolatedHistogram[minimumBin]) { - // Are we at the global minimum? - if(interpolatedHistogram[prev] < interpolatedHistogram[minimumBin]) - { - minimumBin = prev; - } + minimumBin = prev; } - //decrease = (interpolatedHistogram[i] < interpolatedHistogram[prev]); + } + // Center target notes around C + if(targetNote >= 6) + { + targetNote -= 12; } - // Center around C - if(minimumBin >= 6 * BINS_PER_NOTE) minimumBin -= 12 * BINS_PER_NOTE; - const double newFundamentalFreq = NoteToFrequency(69.0 + (double)minimumBin / BINS_PER_NOTE); + // Center bins around target note + minimumBin -= targetNote * BINS_PER_NOTE; + if(minimumBin >= 6 * BINS_PER_NOTE) + { + minimumBin -= 12 * BINS_PER_NOTE; + } + minimumBin += targetNote * BINS_PER_NOTE; - sample.nC5Speed = (UINT)Util::Round(sample.nC5Speed * 440.0 / newFundamentalFreq); + const double newFundamentalFreq = NoteToFrequency(static_cast<double>(69 - targetNote) + static_cast<double>(minimumBin) / BINS_PER_NOTE, pitchReference); + sample.nC5Speed = (UINT)Util::Round(sample.nC5Speed * pitchReference / newFundamentalFreq); + if((modType & (MOD_TYPE_XM | MOD_TYPE_MOD)) != 0) { CSoundFile::FrequencyToTranspose(&sample); @@ -241,3 +246,60 @@ return true; } + + +///////////////////////////////////////////////////////////// +// CAutotuneDlg + +int CAutotuneDlg::pitchReference = 440; // Pitch reference in Hz +int CAutotuneDlg::targetNote = 0; // Target note (C = 0, C# = 1, etc...) + +extern const LPCSTR szNoteNames[12]; + +void CAutotuneDlg::DoDataExchange(CDataExchange* pDX) +//--------------------------------------------------- +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CAutotuneDlg) + DDX_Control(pDX, IDC_COMBO1, m_CbnNoteBox); + //}}AFX_DATA_MAP +} + + +BOOL CAutotuneDlg::OnInitDialog() +//------------------------------- +{ + CDialog::OnInitDialog(); + + m_CbnNoteBox.ResetContent(); + for(int note = 0; note < 12; note++) + { + const int item = m_CbnNoteBox.AddString(szNoteNames[note]); + m_CbnNoteBox.SetItemData(item, note); + if(note == targetNote) + { + m_CbnNoteBox.SetCurSel(item); + } + } + + SetDlgItemInt(IDC_EDIT1, pitchReference, FALSE); + + return TRUE; +} + + +void CAutotuneDlg::OnOK() +//----------------------- +{ + CDialog::OnOK(); + + targetNote = m_CbnNoteBox.GetItemData(m_CbnNoteBox.GetCurSel()); + pitchReference = GetDlgItemInt(IDC_EDIT1); +} + + +void CAutotuneDlg::OnCancel() +//--------------------------- +{ + CDialog::OnCancel(); +} Modified: trunk/OpenMPT/mptrack/Autotune.h =================================================================== --- trunk/OpenMPT/mptrack/Autotune.h 2011-10-15 13:36:57 UTC (rev 1104) +++ trunk/OpenMPT/mptrack/Autotune.h 2011-10-15 23:42:19 UTC (rev 1105) @@ -12,6 +12,7 @@ #define AUTOTUNE_H #include "../soundlib/Snd_defs.h" +#include "resource.h" //============ class Autotune @@ -29,7 +30,7 @@ public: Autotune(MODSAMPLE &smp, MODTYPE type, SmpLength selStart, SmpLength selEnd) : sample(smp), modType(type), selectionStart(selStart), selectionEnd(selEnd) { - sampleData = 0; + sampleData = nullptr; sampleLength = 0; }; @@ -39,12 +40,12 @@ } bool CanApply() const; - bool Apply(); + bool Apply(double pitchReference, int targetNote); protected: - double FrequencyToNote(double freq) const; - double NoteToFrequency(double note) const; - SmpLength NoteToShift(uint32 sampleFreq, int note) const; + double FrequencyToNote(double freq, double pitchReference) const; + double NoteToFrequency(double note, double pitchReference) const; + SmpLength NoteToShift(uint32 sampleFreq, int note, double pitchReference) const; template <class T> void CopySamples(const T* origSample, SmpLength sampleLoopStart, SmpLength sampleLoopEnd); @@ -53,4 +54,30 @@ }; + +//================================= +class CAutotuneDlg : public CDialog +//================================= +{ +protected: + static int pitchReference; // Pitch reference (440Hz by default) + static int targetNote; // Note which the sample should be tuned to (C by default) + + CComboBox m_CbnNoteBox; + +public: + CAutotuneDlg(CWnd *parent) : CDialog(IDD_AUTOTUNE, parent) + { }; + + int GetPitchReference() const { return pitchReference; } + int GetTargetNote() const { return targetNote; } + +protected: + virtual BOOL OnInitDialog(); + virtual void OnOK(); + virtual void OnCancel(); + virtual void DoDataExchange(CDataExchange* pDX); + +}; + #endif // AUTOTUNE_H Modified: trunk/OpenMPT/mptrack/Ctrl_smp.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2011-10-15 13:36:57 UTC (rev 1104) +++ trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2011-10-15 23:42:19 UTC (rev 1105) @@ -3200,11 +3200,15 @@ Autotune at(m_pSndFile->GetSample(m_nSample), m_pSndFile->GetType(), selection.nStart, selection.nEnd); if(at.CanApply()) { - BeginWaitCursor(); - m_pModDoc->GetSampleUndo()->PrepareUndo(m_nSample, sundo_none); - at.Apply(); - m_pModDoc->UpdateAllViews(NULL, (m_nSample << HINT_SHIFT_SMP) | HINT_SAMPLEINFO, NULL); - m_pModDoc->SetModified(); - EndWaitCursor(); + CAutotuneDlg dlg(this); + if(dlg.DoModal() == IDOK) + { + BeginWaitCursor(); + m_pModDoc->GetSampleUndo()->PrepareUndo(m_nSample, sundo_none); + at.Apply(static_cast<double>(dlg.GetPitchReference()), dlg.GetTargetNote()); + m_pModDoc->UpdateAllViews(NULL, (m_nSample << HINT_SHIFT_SMP) | HINT_SAMPLEINFO, NULL); + m_pModDoc->SetModified(); + EndWaitCursor(); + } } } Modified: trunk/OpenMPT/mptrack/View_pat.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_pat.cpp 2011-10-15 13:36:57 UTC (rev 1104) +++ trunk/OpenMPT/mptrack/View_pat.cpp 2011-10-15 23:42:19 UTC (rev 1105) @@ -2420,7 +2420,7 @@ bool changed = false; CArray<UINT,UINT> validChans; - if (type==EFFECT_COLUMN || type==PARAM_COLUMN) + if (type == EFFECT_COLUMN || type == PARAM_COLUMN) { CArray<UINT,UINT> moreValidChans; ListChansWhereColSelected(EFFECT_COLUMN, validChans); @@ -2464,6 +2464,14 @@ vdest = destCmd.note; vcmd = srcCmd.instr; verr = (distance * (NOTE_MAX - 1)) / NOTE_MAX; + if(srcCmd.note == NOTE_NONE) + { + vsrc = vdest; + vcmd = destCmd.note; + } else if(destCmd.note == NOTE_NONE) + { + vdest = vsrc; + } break; case VOL_COLUMN: vsrc = srcCmd.vol; @@ -2492,8 +2500,7 @@ PCinst = srcCmd.instr; if(PCinst == 0) PCinst = destCmd.instr; - } - else + } else { vsrc = srcCmd.param; vdest = destCmd.param; @@ -2524,7 +2531,7 @@ switch(type) { case NOTE_COLUMN: - if ((!pcmd->note) || (pcmd->instr == vcmd)) + if ((pcmd->note == NOTE_NONE) || (pcmd->instr == vcmd)) { int note = vsrc + ((vdest - vsrc) * i + verr) / distance; pcmd->note = (BYTE)note; @@ -2532,7 +2539,7 @@ } break; case VOL_COLUMN: - if ((!pcmd->volcmd) || (pcmd->volcmd == vcmd)) + if ((pcmd->volcmd == VOLCMD_NONE) || (pcmd->volcmd == vcmd)) { int vol = vsrc + ((vdest - vsrc) * i + verr) / distance; pcmd->vol = (BYTE)vol; @@ -2554,7 +2561,7 @@ } else { - if ((!pcmd->command) || (pcmd->command == vcmd)) + if ((pcmd->command == CMD_NONE) || (pcmd->command == vcmd)) { int val = vsrc + ((vdest - vsrc) * i + verr) / distance; pcmd->param = (BYTE)val; @@ -5581,17 +5588,24 @@ case NOTE_COLUMN: startRowCmd = startRowMC.note; endRowCmd = endRowMC.note; - result = (startRowCmd >= NOTE_MIN && endRowCmd >= NOTE_MIN); + result = (startRowCmd == endRowCmd && startRowCmd != NOTE_NONE) // Interpolate between two identical notes or Cut / Fade / etc... + || (startRowCmd != NOTE_NONE && endRowCmd == NOTE_NONE) // Fill in values from the first row + || (startRowCmd == NOTE_NONE && endRowCmd != NOTE_NONE) // Fill in values from the last row + || (NOTE_IS_VALID(startRowCmd) && NOTE_IS_VALID(endRowCmd) && !(startRowCmd == NOTE_NONE && endRowCmd == NOTE_NONE)); // Interpolate between two notes of which one may be empty break; case EFFECT_COLUMN: startRowCmd = startRowMC.command; endRowCmd = endRowMC.command; - result = (startRowCmd == endRowCmd && startRowCmd != CMD_NONE) || (startRowCmd != CMD_NONE && endRowCmd == CMD_NONE) || (startRowCmd == CMD_NONE && endRowCmd != CMD_NONE); + result = (startRowCmd == endRowCmd && startRowCmd != CMD_NONE) // Interpolate between two identical commands + || (startRowCmd != CMD_NONE && endRowCmd == CMD_NONE) // Fill in values from the first row + || (startRowCmd == CMD_NONE && endRowCmd != CMD_NONE); // Fill in values from the last row break; case VOL_COLUMN: startRowCmd = startRowMC.volcmd; endRowCmd = endRowMC.volcmd; - result = (startRowCmd == endRowCmd && startRowCmd != VOLCMD_NONE) || (startRowCmd != VOLCMD_NONE && endRowCmd == VOLCMD_NONE) || (startRowCmd == VOLCMD_NONE && endRowCmd != VOLCMD_NONE); + result = (startRowCmd == endRowCmd && startRowCmd != VOLCMD_NONE) // Interpolate between two identical commands + || (startRowCmd != VOLCMD_NONE && endRowCmd == VOLCMD_NONE) // Fill in values from the first row + || (startRowCmd == VOLCMD_NONE && endRowCmd != VOLCMD_NONE); // Fill in values from the last row break; default: result = false; Modified: trunk/OpenMPT/mptrack/mptrack.rc =================================================================== --- trunk/OpenMPT/mptrack/mptrack.rc 2011-10-15 13:36:57 UTC (rev 1104) +++ trunk/OpenMPT/mptrack/mptrack.rc 2011-10-15 23:42:19 UTC (rev 1105) @@ -219,7 +219,22 @@ PUSHBUTTON "Save &None",IDC_BUTTON2,300,108,66,14 END +IDD_AUTOTUNE DIALOGEX 0, 0, 166, 82 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Sample Tuner" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,54,60,50,14 + PUSHBUTTON "Cancel",IDCANCEL,108,60,50,14 + LTEXT "Tune sample to closest",IDC_STATIC,6,8,96,8 + COMBOBOX IDC_COMBO1,102,6,36,12,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP + LTEXT "Pitch reference (A)",IDC_STATIC,6,26,96,8 + EDITTEXT IDC_EDIT1,102,24,36,12,ES_AUTOHSCROLL | ES_NUMBER + LTEXT "Hz",IDC_STATIC,144,26,18,8 + CONTROL "",IDC_STATIC,"Static",SS_BLACKFRAME | SS_SUNKEN,6,48,150,1 +END + ///////////////////////////////////////////////////////////////////////////// // // DESIGNINFO @@ -315,6 +330,14 @@ TOPMARGIN, 7 BOTTOMMARGIN, 190 END + + IDD_AUTOTUNE, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 159 + TOPMARGIN, 7 + BOTTOMMARGIN, 75 + END END #endif // APSTUDIO_INVOKED @@ -2546,7 +2569,7 @@ STRINGTABLE BEGIN IDC_SAMPLE_XFADE "Crossfade Loop Points\nCrossfade between loop start and loop end to create seamless sample loops." - IDC_SAMPLE_AUTOTUNE "Autotune sample to C\nTune the sample to the closest C." + IDC_SAMPLE_AUTOTUNE "Sample Tuner\nTune the sample to a given note." END #endif // English (United States) resources Modified: trunk/OpenMPT/mptrack/resource.h =================================================================== --- trunk/OpenMPT/mptrack/resource.h 2011-10-15 13:36:57 UTC (rev 1104) +++ trunk/OpenMPT/mptrack/resource.h 2011-10-15 23:42:19 UTC (rev 1105) @@ -152,6 +152,7 @@ #define IDD_SAMPLE_XFADE 528 #define IDD_OPTIONS_UPDATE 529 #define IDD_CLOSEDOCUMENTS 530 +#define IDD_AUTOTUNE 531 #define IDC_BUTTON1 1001 #define IDC_BUTTON2 1002 #define IDC_BUTTON3 1003 @@ -1215,7 +1216,7 @@ #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_3D_CONTROLS 1 -#define _APS_NEXT_RESOURCE_VALUE 531 +#define _APS_NEXT_RESOURCE_VALUE 532 #define _APS_NEXT_COMMAND_VALUE 44474 #define _APS_NEXT_CONTROL_VALUE 2438 #define _APS_NEXT_SYMED_VALUE 901 Modified: trunk/OpenMPT/mptrack/version.h =================================================================== --- trunk/OpenMPT/mptrack/version.h 2011-10-15 13:36:57 UTC (rev 1104) +++ trunk/OpenMPT/mptrack/version.h 2011-10-15 23:42:19 UTC (rev 1105) @@ -15,7 +15,7 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 20 #define VER_MINOR 00 -#define VER_MINORMINOR 42 +#define VER_MINORMINOR 43 //Creates version number from version parts that appears in version string. //For example MAKE_VERSION_NUMERIC(1,17,02,28) gives version number of This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |