From: <sag...@us...> - 2011-03-07 00:51:50
|
Revision: 810 http://modplug.svn.sourceforge.net/modplug/?rev=810&view=rev Author: saga-games Date: 2011-03-07 00:51:43 +0000 (Mon, 07 Mar 2011) Log Message: ----------- [New] Sample Editor: There's a new tool to create seamless sample loops: The loop crossfader. Includes a new keyboard shortcut. [Mod] OpenMPT: Version is now 1.19.00.28 Modified Paths: -------------- trunk/OpenMPT/mptrack/CommandSet.cpp trunk/OpenMPT/mptrack/CommandSet.h trunk/OpenMPT/mptrack/Ctrl_smp.cpp trunk/OpenMPT/mptrack/Ctrl_smp.h trunk/OpenMPT/mptrack/Mainfrm.h trunk/OpenMPT/mptrack/SampleEditorDialogs.cpp trunk/OpenMPT/mptrack/SampleEditorDialogs.h trunk/OpenMPT/mptrack/View_smp.cpp trunk/OpenMPT/mptrack/mptrack.rc trunk/OpenMPT/mptrack/res/patterns.bmp trunk/OpenMPT/mptrack/resource.h trunk/OpenMPT/mptrack/version.h trunk/OpenMPT/soundlib/modsmp_ctrl.cpp trunk/OpenMPT/soundlib/modsmp_ctrl.h Modified: trunk/OpenMPT/mptrack/CommandSet.cpp =================================================================== --- trunk/OpenMPT/mptrack/CommandSet.cpp 2011-03-07 00:21:50 UTC (rev 809) +++ trunk/OpenMPT/mptrack/CommandSet.cpp 2011-03-07 00:51:43 UTC (rev 810) @@ -603,6 +603,7 @@ DefineKeyCommand(kcOrderlistPatInvalid, 1854, kcVisible, kcNoDummy, _T("Invalid (---) Index")); DefineKeyCommand(kcViewEditHistory, 1855, kcVisible, kcNoDummy, _T("View Edit History")); DefineKeyCommand(kcSampleQuickFade, 1856, kcVisible, kcNoDummy, _T("Quick fade")); + DefineKeyCommand(kcSampleXFade, 1857, kcVisible, kcNoDummy, _T("Crossfade sample loop")); // Add new key commands here. #ifdef _DEBUG @@ -1550,7 +1551,13 @@ CString err; if (errorCount < 10) { - err.Format("Line %d was not understood.", l); + if(spos == -1) + { + err.Format("Line %d was not understood.", l); + } else + { + err.Format("Line %d contained an unknown command.", l); + } errText += err + "\n"; Log(err); } else if (errorCount == 10) Modified: trunk/OpenMPT/mptrack/CommandSet.h =================================================================== --- trunk/OpenMPT/mptrack/CommandSet.h 2011-03-07 00:21:50 UTC (rev 809) +++ trunk/OpenMPT/mptrack/CommandSet.h 2011-03-07 00:51:43 UTC (rev 810) @@ -612,7 +612,8 @@ kcSampleSignUnsign, kcSampleRemoveDCOffset, kcSampleQuickFade, - kcEndSampleEditing=kcSampleQuickFade, + kcSampleXFade, + kcEndSampleEditing=kcSampleXFade, //kcSampStartNotes to kcInsNoteMapEndNoteStops must be contiguous. kcSampStartNotes, Modified: trunk/OpenMPT/mptrack/Ctrl_smp.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2011-03-07 00:21:50 UTC (rev 809) +++ trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2011-03-07 00:51:43 UTC (rev 810) @@ -71,6 +71,7 @@ ON_COMMAND(IDC_SAMPLE_INVERT, OnInvert) ON_COMMAND(IDC_SAMPLE_SIGN_UNSIGN, OnSignUnSign) ON_COMMAND(IDC_SAMPLE_DCOFFSET, OnRemoveDCOffset) + ON_COMMAND(IDC_SAMPLE_XFADE, OnXFade) ON_COMMAND(IDC_CHECK1, OnSetPanningChanged) ON_COMMAND(ID_PREVINSTRUMENT, OnPrevInstrument) ON_COMMAND(ID_NEXTINSTRUMENT, OnNextInstrument) @@ -213,13 +214,16 @@ m_ToolBar2.AddButton(IDC_SAMPLE_SILENCE, TIMAGE_SAMPLE_SILENCE); m_ToolBar2.AddButton(IDC_SAMPLE_INVERT, TIMAGE_SAMPLE_INVERT); m_ToolBar2.AddButton(IDC_SAMPLE_SIGN_UNSIGN, TIMAGE_SAMPLE_UNSIGN); + m_ToolBar2.AddButton(IDC_SAMPLE_XFADE, TIMAGE_SAMPLE_FIXLOOP); // Setup Controls m_SpinVolume.SetRange(0, 64); m_SpinGlobalVol.SetRange(0, 64); //rewbs.fix36944 - if (m_pSndFile->m_nType == MOD_TYPE_XM) { + if (m_pSndFile->m_nType == MOD_TYPE_XM) + { m_SpinPanning.SetRange(0, 255); - } else { + } else + { m_SpinPanning.SetRange(0, 64); } //end rewbs.fix36944 @@ -460,6 +464,9 @@ OnInvert(); break; + case IDC_SAMPLE_XFADE: + OnXFade(); + case IDC_SAMPLE_SIGN_UNSIGN: OnSignUnSign(); break; @@ -3102,3 +3109,49 @@ viewstate.dwEndSel = nEnd; SendViewMessage(VIEWMSG_LOADSTATE, (LPARAM)&viewstate); } + + +// Crossfade loop to create smooth loop transitions +#define DEFAULT_XFADE_LENGTH 16384 //4096 +#define LimitXFadeLength(x) min(min(x, pSmp->nLoopEnd - pSmp->nLoopStart), pSmp->nLoopEnd / 2) + +void CCtrlSamples::OnXFade() +//-------------------------- +{ + static UINT nFadeLength = DEFAULT_XFADE_LENGTH; + MODSAMPLE *pSmp = &m_pSndFile->Samples[m_nSample]; + + if(pSmp->pSample == nullptr) return; + if(pSmp->nLoopEnd <= pSmp->nLoopStart || pSmp->nLoopEnd > pSmp->nLength) return; + // Case 1: The loop start is preceeded by > XFADE_LENGTH samples. Nothing has to be adjusted. + // Case 2: The actual loop is shorter than XFADE_LENGTH samples. + // Case 3: There is not enough sample material before the loop start. Move the loop start. + nFadeLength = LimitXFadeLength(nFadeLength); + + CSampleXFadeDlg dlg(this, nFadeLength, LimitXFadeLength(GetDocument()->GetSoundFile()->Samples[m_nSample].nLength)); + if(dlg.DoModal() == IDOK) + { + nFadeLength = dlg.m_nSamples; + + if(nFadeLength < 4) return; + + m_pModDoc->GetSampleUndo()->PrepareUndo(m_nSample, sundo_update, pSmp->nLoopEnd - nFadeLength, pSmp->nLoopEnd); + // If we want to fade nFadeLength bytes, we need as much sample material before the loop point. nFadeLength has been adjusted above. + if(pSmp->nLoopStart < nFadeLength) + { + pSmp->nLoopStart = nFadeLength; + } + + if(ctrlSmp::XFadeSample(pSmp, nFadeLength, m_pSndFile)) + { + m_pModDoc->AdjustEndOfSample(m_nSample); + m_pModDoc->UpdateAllViews(NULL, (m_nSample << HINT_SHIFT_SMP) | HINT_SAMPLEDATA | HINT_SAMPLEINFO, NULL); + m_pModDoc->SetModified(); + } else + { + m_pModDoc->GetSampleUndo()->RemoveLastUndoStep(m_nSample); + } + + } +} + Modified: trunk/OpenMPT/mptrack/Ctrl_smp.h =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_smp.h 2011-03-07 00:21:50 UTC (rev 809) +++ trunk/OpenMPT/mptrack/Ctrl_smp.h 2011-03-07 00:51:43 UTC (rev 810) @@ -108,6 +108,7 @@ afx_msg void OnVibDepthChanged(); afx_msg void OnVibSweepChanged(); afx_msg void OnVibRateChanged(); + afx_msg void OnXFade(); afx_msg void OnVScroll(UINT, UINT, CScrollBar *); afx_msg LRESULT OnCustomKeyMsg(WPARAM, LPARAM); //rewbs.customKeys Modified: trunk/OpenMPT/mptrack/Mainfrm.h =================================================================== --- trunk/OpenMPT/mptrack/Mainfrm.h 2011-03-07 00:21:50 UTC (rev 809) +++ trunk/OpenMPT/mptrack/Mainfrm.h 2011-03-07 00:51:43 UTC (rev 810) @@ -285,6 +285,7 @@ TIMAGE_SAMPLE_UNSIGN, TIMAGE_SAMPLE_DCOFFSET, TIMAGE_PATTERN_OVERFLOWPASTE, + TIMAGE_SAMPLE_FIXLOOP, }; Modified: trunk/OpenMPT/mptrack/SampleEditorDialogs.cpp =================================================================== --- trunk/OpenMPT/mptrack/SampleEditorDialogs.cpp 2011-03-07 00:21:50 UTC (rev 809) +++ trunk/OpenMPT/mptrack/SampleEditorDialogs.cpp 2011-03-07 00:51:43 UTC (rev 810) @@ -170,3 +170,37 @@ CDialog::OnOK(); } + +///////////////////////////////////////////////////////////////////////// +// Sample cross-fade dialog + +void CSampleXFadeDlg::DoDataExchange(CDataExchange* pDX) +//------------------------------------------------------ +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CSampleGridDlg) + DDX_Control(pDX, IDC_EDIT1, m_EditSamples); + DDX_Control(pDX, IDC_SPIN1, m_SpinSamples); + //}}AFX_DATA_MAP +} + + +BOOL CSampleXFadeDlg::OnInitDialog() +//---------------------------------- +{ + CDialog::OnInitDialog(); + m_SpinSamples.SetRange32(0, m_nMaxSamples); + m_SpinSamples.SetPos(m_nSamples); + SetDlgItemInt(IDC_EDIT1, m_nSamples, FALSE); + GetDlgItem(IDC_EDIT1)->SetFocus(); + return TRUE; +} + + +void CSampleXFadeDlg::OnOK() +//-------------------------- +{ + m_nSamples = GetDlgItemInt(IDC_EDIT1, NULL, FALSE); + CDialog::OnOK(); +} + Modified: trunk/OpenMPT/mptrack/SampleEditorDialogs.h =================================================================== --- trunk/OpenMPT/mptrack/SampleEditorDialogs.h 2011-03-07 00:21:50 UTC (rev 809) +++ trunk/OpenMPT/mptrack/SampleEditorDialogs.h 2011-03-07 00:51:43 UTC (rev 810) @@ -96,4 +96,29 @@ virtual void OnOK(); }; + +///////////////////////////////////////////////////////////////////////// +// Sample cross-fade dialog + +//=================================== +class CSampleXFadeDlg: public CDialog +//=================================== +{ +public: + UINT m_nSamples, m_nMaxSamples; + +protected: + CEdit m_EditSamples; + CSpinButtonCtrl m_SpinSamples; + +public: + CSampleXFadeDlg(CWnd *parent, UINT nSamples, UINT nMaxSamples) : CDialog(IDD_SAMPLE_XFADE, parent) { m_nSamples = nSamples; m_nMaxSamples = nMaxSamples; }; + +protected: + virtual void DoDataExchange(CDataExchange* pDX); + virtual BOOL OnInitDialog(); + virtual void OnOK(); +}; + + #endif Modified: trunk/OpenMPT/mptrack/View_smp.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_smp.cpp 2011-03-07 00:21:50 UTC (rev 809) +++ trunk/OpenMPT/mptrack/View_smp.cpp 2011-03-07 00:51:43 UTC (rev 810) @@ -2646,6 +2646,7 @@ case kcSampleInvert: PostCtrlMessage(IDC_SAMPLE_INVERT); return wParam; case kcSampleSignUnsign: PostCtrlMessage(IDC_SAMPLE_SIGN_UNSIGN); return wParam; case kcSampleRemoveDCOffset: PostCtrlMessage(IDC_SAMPLE_DCOFFSET); return wParam; + case kcSampleXFade: PostCtrlMessage(IDC_SAMPLE_XFADE); return wParam; case kcSampleQuickFade: PostCtrlMessage(IDC_SAMPLE_QUICKFADE); return wParam; // Those don't seem to work. Modified: trunk/OpenMPT/mptrack/mptrack.rc =================================================================== --- trunk/OpenMPT/mptrack/mptrack.rc 2011-03-07 00:21:50 UTC (rev 809) +++ trunk/OpenMPT/mptrack/mptrack.rc 2011-03-07 00:51:43 UTC (rev 810) @@ -173,7 +173,20 @@ LTEXT "Grid Segments:",IDC_STATIC,6,8,60,8 END +IDD_SAMPLE_XFADE DIALOGEX 0, 0, 178, 82 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Sample Crossfader" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,66,60,50,14 + PUSHBUTTON "Cancel",IDCANCEL,120,60,50,14 + EDITTEXT IDC_EDIT1,108,6,54,12,ES_AUTOHSCROLL | ES_NUMBER + CONTROL "",IDC_SPIN1,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,144,6,11,14 + LTEXT "Higher numbers generate smoother loop transitions. However, the number is limited by the loop length and the amount of samples before the loop start.",IDC_STATIC,6,24,168,36 + LTEXT "Samples used for fading:",IDC_STATIC,6,8,96,8 +END + ///////////////////////////////////////////////////////////////////////////// // // DESIGNINFO @@ -245,6 +258,14 @@ TOPMARGIN, 7 BOTTOMMARGIN, 64 END + + IDD_SAMPLE_XFADE, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 171 + TOPMARGIN, 7 + BOTTOMMARGIN, 75 + END END #endif // APSTUDIO_INVOKED @@ -723,7 +744,7 @@ CTEXT "Resampling",IDC_STATIC,7,151,39,13,SS_CENTERIMAGE,WS_EX_STATICEDGE CONTROL "Highpass",IDC_CHECK4,"Button",BS_AUTOCHECKBOX | BS_FLAT | NOT WS_VISIBLE | WS_TABSTOP,181,19,45,10 CTEXT "Mode",IDC_STATIC,135,70,23,13,SS_CENTERIMAGE,WS_EX_STATICEDGE - RTEXT "--",IDC_TEXT1,204,62,27,8 + RTEXT "--",IDC_TEXT1,186,62,45,8 GROUPBOX "Pitch/Tempo Lock",IDC_STATIC,364,57,89,25 GROUPBOX "Sample Map",IDC_STATIC,461,27,62,141 CTEXT "Velocity handling",IDC_STATIC,367,102,83,10,SS_CENTERIMAGE,WS_EX_STATICEDGE @@ -1309,7 +1330,7 @@ END IDD_PLUGINEDITOR DIALOGEX 0, 0, 187, 95 -STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_TOOLWINDOW | WS_EX_CLIENTEDGE CAPTION "Editor" MENU IDR_PLUGINMENU @@ -2455,6 +2476,11 @@ ID_VIEW_SONGPROPERTIES "Edit global song properties or convert the module to another format" END +STRINGTABLE +BEGIN + IDC_SAMPLE_XFADE "Crossfade Loop Points\nCrossfade between loop start and loop end to create seamless sample loops." +END + #endif // Englisch (USA) resources ///////////////////////////////////////////////////////////////////////////// Modified: trunk/OpenMPT/mptrack/res/patterns.bmp =================================================================== (Binary files differ) Modified: trunk/OpenMPT/mptrack/resource.h =================================================================== --- trunk/OpenMPT/mptrack/resource.h 2011-03-07 00:21:50 UTC (rev 809) +++ trunk/OpenMPT/mptrack/resource.h 2011-03-07 00:51:43 UTC (rev 810) @@ -137,6 +137,7 @@ #define IDD_SAMPLE_GENERATOR_PRESETS 525 #define IDD_EDITHISTORY 526 #define IDD_SAMPLE_GRID_SIZE 527 +#define IDD_SAMPLE_XFADE 528 #define IDC_BUTTON1 1001 #define IDC_BUTTON2 1002 #define IDC_BUTTON3 1003 @@ -928,6 +929,7 @@ #define IDC_TOTAL_EDIT_TIME 2431 #define IDC_EDIT_HISTORY 2432 #define IDC_SAMPLE_QUICKFADE 2433 +#define IDC_SAMPLE_XFADE 2434 #define ID_FILE_NEWMOD 32771 #define ID_FILE_NEWXM 32772 #define ID_FILE_NEWS3M 32773 @@ -1195,9 +1197,9 @@ #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_3D_CONTROLS 1 -#define _APS_NEXT_RESOURCE_VALUE 528 +#define _APS_NEXT_RESOURCE_VALUE 529 #define _APS_NEXT_COMMAND_VALUE 60455 -#define _APS_NEXT_CONTROL_VALUE 2434 +#define _APS_NEXT_CONTROL_VALUE 2435 #define _APS_NEXT_SYMED_VALUE 901 #endif #endif Modified: trunk/OpenMPT/mptrack/version.h =================================================================== --- trunk/OpenMPT/mptrack/version.h 2011-03-07 00:21:50 UTC (rev 809) +++ trunk/OpenMPT/mptrack/version.h 2011-03-07 00:51:43 UTC (rev 810) @@ -15,7 +15,7 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 19 #define VER_MINOR 00 -#define VER_MINORMINOR 27 +#define VER_MINORMINOR 28 //Creates version number from version parts that appears in version string. //For example MAKE_VERSION_NUMERIC(1,17,02,28) gives version number of Modified: trunk/OpenMPT/soundlib/modsmp_ctrl.cpp =================================================================== --- trunk/OpenMPT/soundlib/modsmp_ctrl.cpp 2011-03-07 00:21:50 UTC (rev 809) +++ trunk/OpenMPT/soundlib/modsmp_ctrl.cpp 2011-03-07 00:51:43 UTC (rev 810) @@ -37,7 +37,7 @@ SmpLength InsertSilence(MODSAMPLE& smp, const SmpLength nSilenceLength, const SmpLength nStartFrom, CSoundFile* pSndFile) -//---------------------------------------------------------------------------------------------------------------------------- +//----------------------------------------------------------------------------------------------------------------------- { if(nSilenceLength == 0 || nSilenceLength >= MAX_SAMPLE_LENGTH || smp.nLength > MAX_SAMPLE_LENGTH - nSilenceLength) return smp.nLength; @@ -92,7 +92,7 @@ } SmpLength ResizeSample(MODSAMPLE& smp, const SmpLength nNewLength, CSoundFile* pSndFile) -//---------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------- { // Invalid sample size if(nNewLength > MAX_SAMPLE_LENGTH || nNewLength == smp.nLength) @@ -139,7 +139,7 @@ template <class T> void AdjustEndOfSampleImpl(MODSAMPLE& smp) -//-------------------------------------------- +//---------------------------------------- { MODSAMPLE* const pSmp = &smp; const UINT len = pSmp->nLength; @@ -168,7 +168,7 @@ bool AdjustEndOfSample(MODSAMPLE& smp, CSoundFile* pSndFile) -//-------------------------------------------------------------- +//---------------------------------------------------------- { MODSAMPLE* const pSmp = &smp; @@ -477,6 +477,43 @@ } +template <class T> +void XFadeSampleImpl(T* pStart, const SmpLength nOffset, SmpLength nFadeLength) +//----------------------------------------------------------------------------- +{ + for(SmpLength i = 0; i <= nFadeLength; i++) + { + double dPercentage = sqrt((double)i / (double)nFadeLength); // linear fades are boring + pStart[nOffset + i] = (T)(((double)pStart[nOffset + i]) * (1 - dPercentage) + ((double)pStart[i]) * dPercentage); + } +} + +// X-Fade sample data to create smooth loop transitions +bool XFadeSample(MODSAMPLE *pSmp, SmpLength iFadeLength, CSoundFile *pSndFile) +//---------------------------------------------------------------------------- +{ + if(pSmp->pSample == nullptr) return false; + if(pSmp->nLoopEnd <= pSmp->nLoopStart || pSmp->nLoopEnd > pSmp->nLength) return false; + if(pSmp->nLoopStart < iFadeLength) return false; + + SmpLength iStart = pSmp->nLoopStart - iFadeLength; + SmpLength iEnd = pSmp->nLoopEnd - iFadeLength; + iStart *= pSmp->GetNumChannels(); + iEnd *= pSmp->GetNumChannels(); + iFadeLength *= pSmp->GetNumChannels(); + + if(pSmp->GetElementarySampleSize() == 2) + XFadeSampleImpl(reinterpret_cast<int16*>(pSmp->pSample) + iStart, iEnd - iStart, iFadeLength); + else if(pSmp->GetElementarySampleSize() == 1) + XFadeSampleImpl(reinterpret_cast<int8*>(pSmp->pSample) + iStart, iEnd - iStart, iFadeLength); + else + return false; + + AdjustEndOfSample(*pSmp, pSndFile); + return true; +} + + } // namespace ctrlSmp Modified: trunk/OpenMPT/soundlib/modsmp_ctrl.h =================================================================== --- trunk/OpenMPT/soundlib/modsmp_ctrl.h 2011-03-07 00:21:50 UTC (rev 809) +++ trunk/OpenMPT/soundlib/modsmp_ctrl.h 2011-03-07 00:51:43 UTC (rev 810) @@ -62,6 +62,9 @@ // Invert sample data (flip by 180 degrees) bool InvertSample(MODSAMPLE *pSmp, SmpLength iStart, SmpLength iEnd, CSoundFile *pSndFile); +// Crossfade sample data to create smooth loops +bool XFadeSample(MODSAMPLE *pSmp, SmpLength iFadeLength, CSoundFile *pSndFile); + } // Namespace ctrlSmp namespace ctrlChn This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |