From: <sag...@us...> - 2012-11-21 00:08:45
|
Revision: 1436 http://modplug.svn.sourceforge.net/modplug/?rev=1436&view=rev Author: saga-games Date: 2012-11-21 00:08:35 +0000 (Wed, 21 Nov 2012) Log Message: ----------- [New] Sample Editor: Added new Stereo to Mono sample conversion modes: Only left / right channel, Split into two samples. Modified Paths: -------------- trunk/OpenMPT/mptrack/MPTHacks.cpp trunk/OpenMPT/mptrack/View_smp.cpp trunk/OpenMPT/mptrack/View_smp.h trunk/OpenMPT/mptrack/resource.h trunk/OpenMPT/soundlib/modsmp_ctrl.cpp trunk/OpenMPT/soundlib/modsmp_ctrl.h Modified: trunk/OpenMPT/mptrack/MPTHacks.cpp =================================================================== --- trunk/OpenMPT/mptrack/MPTHacks.cpp 2012-11-20 20:18:02 UTC (rev 1435) +++ trunk/OpenMPT/mptrack/MPTHacks.cpp 2012-11-21 00:08:35 UTC (rev 1436) @@ -350,7 +350,7 @@ foundHere = foundHacks = true; if(autofix) { - ctrlSmp::ConvertToMono(smp, &m_SndFile); + ctrlSmp::ConvertToMono(smp, &m_SndFile, ctrlSmp::mixChannels); } else { break; Modified: trunk/OpenMPT/mptrack/View_smp.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_smp.cpp 2012-11-20 20:18:02 UTC (rev 1435) +++ trunk/OpenMPT/mptrack/View_smp.cpp 2012-11-21 00:08:35 UTC (rev 1436) @@ -89,7 +89,10 @@ ON_COMMAND(ID_SAMPLE_SETLOOP, OnSetLoop) ON_COMMAND(ID_SAMPLE_SETSUSTAINLOOP, OnSetSustainLoop) ON_COMMAND(ID_SAMPLE_8BITCONVERT, On8BitConvert) - ON_COMMAND(ID_SAMPLE_MONOCONVERT, OnMonoConvert) + ON_COMMAND(ID_SAMPLE_MONOCONVERT, OnMonoConvertMix) + ON_COMMAND(ID_SAMPLE_MONOCONVERT_LEFT, OnMonoConvertLeft) + ON_COMMAND(ID_SAMPLE_MONOCONVERT_RIGHT, OnMonoConvertRight) + ON_COMMAND(ID_SAMPLE_MONOCONVERT_SPLIT, OnMonoConvertSplit) ON_COMMAND(ID_SAMPLE_TRIM, OnSampleTrim) ON_COMMAND(ID_PREVINSTRUMENT, OnPrevInstrument) ON_COMMAND(ID_NEXTINSTRUMENT, OnNextInstrument) @@ -1527,13 +1530,21 @@ if(m_dwBeginSel >= m_dwEndSel) { - if (sample.uFlags & CHN_16BIT) ::AppendMenu(hMenu, MF_STRING, ID_SAMPLE_8BITCONVERT, "Convert to 8-bit"); - if (sample.uFlags & CHN_STEREO) ::AppendMenu(hMenu, MF_STRING, ID_SAMPLE_MONOCONVERT, "Convert to mono"); + if(sample.GetElementarySampleSize() > 1) ::AppendMenu(hMenu, MF_STRING, ID_SAMPLE_8BITCONVERT, "Convert to &8-bit"); + if(sample.GetNumChannels() > 1) + { + HMENU hMonoMenu = ::CreatePopupMenu(); + ::AppendMenu(hMonoMenu, MF_STRING, ID_SAMPLE_MONOCONVERT, "&Mix Channels"); + ::AppendMenu(hMonoMenu, MF_STRING, ID_SAMPLE_MONOCONVERT_LEFT, "&Left Channel"); + ::AppendMenu(hMonoMenu, MF_STRING, ID_SAMPLE_MONOCONVERT_RIGHT, "&Right Channel"); + ::AppendMenu(hMonoMenu, MF_STRING, ID_SAMPLE_MONOCONVERT_SPLIT, "&Split Sample"); + ::AppendMenu(hMenu, MF_POPUP, reinterpret_cast<UINT_PTR>(hMonoMenu), "Convert to &Mono"); + } } // "Trim" menu item is responding differently if there's no selection, // but a loop present: "trim around loop point"! (jojo in topic 2258) - std::string sTrimMenuText = "Trim"; + std::string sTrimMenuText = "T&rim"; bool bIsGrayed = ( (m_dwEndSel<=m_dwBeginSel) || (m_dwEndSel - m_dwBeginSel < MIN_TRIM_LENGTH) || (m_dwEndSel - m_dwBeginSel == sample.nLength) ); @@ -1554,13 +1565,13 @@ ::AppendMenu(hMenu, MF_STRING|(bIsGrayed) ? MF_GRAYED : 0, ID_SAMPLE_TRIM, sTrimMenuText.c_str()); if((m_dwBeginSel == 0 && m_dwEndSel != 0) || (m_dwBeginSel < sample.nLength && m_dwEndSel == sample.nLength)) { - ::AppendMenu(hMenu, MF_STRING, ID_SAMPLE_QUICKFADE, "Quick fade\t" + ih->GetKeyTextFromCommand(kcSampleQuickFade)); + ::AppendMenu(hMenu, MF_STRING, ID_SAMPLE_QUICKFADE, "Quick &fade\t" + ih->GetKeyTextFromCommand(kcSampleQuickFade)); } - ::AppendMenu(hMenu, MF_STRING, ID_EDIT_CUT, "Cut\t" + ih->GetKeyTextFromCommand(kcEditCut)); - ::AppendMenu(hMenu, MF_STRING, ID_EDIT_COPY, "Copy\t" + ih->GetKeyTextFromCommand(kcEditCopy)); + ::AppendMenu(hMenu, MF_STRING, ID_EDIT_CUT, "Cu&t\t" + ih->GetKeyTextFromCommand(kcEditCut)); + ::AppendMenu(hMenu, MF_STRING, ID_EDIT_COPY, "&Copy\t" + ih->GetKeyTextFromCommand(kcEditCopy)); } - ::AppendMenu(hMenu, MF_STRING, ID_EDIT_PASTE, "Paste\t" + ih->GetKeyTextFromCommand(kcEditPaste)); - ::AppendMenu(hMenu, MF_STRING | (pModDoc->GetSampleUndo().CanUndo(m_nSample) ? 0 : MF_GRAYED), ID_EDIT_UNDO, "Undo\t" + ih->GetKeyTextFromCommand(kcEditUndo)); + ::AppendMenu(hMenu, MF_STRING, ID_EDIT_PASTE, "&Paste\t" + ih->GetKeyTextFromCommand(kcEditPaste)); + ::AppendMenu(hMenu, MF_STRING | (pModDoc->GetSampleUndo().CanUndo(m_nSample) ? 0 : MF_GRAYED), ID_EDIT_UNDO, "&Undo\t" + ih->GetKeyTextFromCommand(kcEditUndo)); ClientToScreen(&pt); ::TrackPopupMenu(hMenu, TPM_LEFTALIGN|TPM_RIGHTBUTTON, pt.x, pt.y, 0, m_hWnd, NULL); ::DestroyMenu(hMenu); @@ -2063,8 +2074,8 @@ } -void CViewSample::OnMonoConvert() -//------------------------------- +void CViewSample::OnMonoConvert(ctrlSmp::StereoToMonoMode convert) +//---------------------------------------------------------------- { CModDoc *pModDoc = GetDocument(); BeginWaitCursor(); @@ -2072,11 +2083,58 @@ { CSoundFile *pSndFile = pModDoc->GetSoundFile(); ModSample &sample = pSndFile->GetSample(m_nSample); - if(sample.GetNumChannels() > 1&& sample.pSample != nullptr && sample.nLength != 0) + if(sample.GetNumChannels() > 1 && sample.pSample != nullptr && sample.nLength != 0) { + SAMPLEINDEX rightSmp = SAMPLEINDEX_INVALID; + if(convert == ctrlSmp::splitSample) + { + // Split sample into two slots + rightSmp = pModDoc->InsertSample(true); + if(rightSmp != SAMPLEINDEX_INVALID) + { + pSndFile->ReadSampleFromSong(rightSmp, pSndFile, m_nSample); + } else + { + return; + } + } + pModDoc->GetSampleUndo().PrepareUndo(m_nSample, sundo_replace); - if(ctrlSmp::ConvertToMono(sample, pSndFile)) + + if(ctrlSmp::ConvertToMono(sample, pSndFile, convert)) { + if(convert == ctrlSmp::splitSample) + { + // Split mode: We need to convert the right channel as well! + ModSample &right = pSndFile->GetSample(rightSmp); + ctrlSmp::ConvertToMono(right, pSndFile, ctrlSmp::onlyRight); + + // Try to create a new instrument as well which maps to the right sample. + INSTRUMENTINDEX ins = pModDoc->FindSampleParent(m_nSample); + if(ins != INSTRUMENTINDEX_INVALID) + { + INSTRUMENTINDEX rightIns = pModDoc->InsertInstrument(0, ins); + if(rightIns != INSTRUMENTINDEX_INVALID) + { + for(size_t i = 0; i < CountOf(pSndFile->Instruments[rightIns]->Keyboard); i++) + { + if(pSndFile->Instruments[rightIns]->Keyboard[i] == m_nSample) + { + pSndFile->Instruments[rightIns]->Keyboard[i] = rightSmp; + } + } + } + } + + // Finally, adjust sample panning + if(pSndFile->GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT | MOD_TYPE_XM)) + { + sample.uFlags.set(CHN_PANNING); + sample.nPan = 0; + right.uFlags.set(CHN_PANNING); + right.nPan = 256; + } + } pModDoc->SetModified(); pModDoc->UpdateAllViews(NULL, (m_nSample << HINT_SHIFT_SMP) | HINT_SAMPLEDATA | HINT_SAMPLEINFO, NULL); } else Modified: trunk/OpenMPT/mptrack/View_smp.h =================================================================== --- trunk/OpenMPT/mptrack/View_smp.h 2012-11-20 20:18:02 UTC (rev 1435) +++ trunk/OpenMPT/mptrack/View_smp.h 2012-11-21 00:08:35 UTC (rev 1436) @@ -17,6 +17,8 @@ #define SMP_LEFTBAR_BUTTONS 8 +#include "modsmp_ctrl.h" + //====================================== class CViewSample: public CModScrollView //====================================== @@ -85,6 +87,8 @@ void AdjustLoopPoints(UINT &loopStart, UINT &loopEnd, UINT length) const; + void OnMonoConvert(ctrlSmp::StereoToMonoMode convert); + public: //{{AFX_VIRTUAL(CViewSample) virtual void OnDraw(CDC *); @@ -130,7 +134,10 @@ afx_msg void OnSetLoop(); afx_msg void OnSetSustainLoop(); afx_msg void On8BitConvert(); - afx_msg void OnMonoConvert(); + afx_msg void OnMonoConvertMix() { OnMonoConvert(ctrlSmp::mixChannels); } + afx_msg void OnMonoConvertLeft() { OnMonoConvert(ctrlSmp::onlyLeft); } + afx_msg void OnMonoConvertRight() { OnMonoConvert(ctrlSmp::onlyRight); } + afx_msg void OnMonoConvertSplit() { OnMonoConvert(ctrlSmp::splitSample); } afx_msg void OnSampleTrim(); afx_msg void OnPrevInstrument(); afx_msg void OnNextInstrument(); Modified: trunk/OpenMPT/mptrack/resource.h =================================================================== --- trunk/OpenMPT/mptrack/resource.h 2012-11-20 20:18:02 UTC (rev 1435) +++ trunk/OpenMPT/mptrack/resource.h 2012-11-21 00:08:35 UTC (rev 1436) @@ -1210,6 +1210,9 @@ #define ID_ORDERLIST_LOCKPLAYBACK 44603 #define ID_ORDERLIST_UNLOCKPLAYBACK 44604 #define ID_TRANSPOSE_CUSTOM 44605 +#define ID_SAMPLE_MONOCONVERT_LEFT 44606 +#define ID_SAMPLE_MONOCONVERT_RIGHT 44607 +#define ID_SAMPLE_MONOCONVERT_SPLIT 44608 // Next default values for new objects // @@ -1217,7 +1220,7 @@ #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_3D_CONTROLS 1 #define _APS_NEXT_RESOURCE_VALUE 536 -#define _APS_NEXT_COMMAND_VALUE 44606 +#define _APS_NEXT_COMMAND_VALUE 44609 #define _APS_NEXT_CONTROL_VALUE 2441 #define _APS_NEXT_SYMED_VALUE 901 #endif Modified: trunk/OpenMPT/soundlib/modsmp_ctrl.cpp =================================================================== --- trunk/OpenMPT/soundlib/modsmp_ctrl.cpp 2012-11-20 20:18:02 UTC (rev 1435) +++ trunk/OpenMPT/soundlib/modsmp_ctrl.cpp 2012-11-21 00:08:35 UTC (rev 1436) @@ -588,8 +588,8 @@ template <class T> -void ConvertStereoToMonoImpl(T* pDest, const SmpLength length) -//------------------------------------------------------------ +void ConvertStereoToMonoMixImpl(T* pDest, const SmpLength length) +//--------------------------------------------------------------- { const T* pEnd = pDest + length; for(T* pSource = pDest; pDest != pEnd; pDest++, pSource += 2) @@ -599,19 +599,46 @@ } +template <class T> +void ConvertStereoToMonoOneChannelImpl(T* pDest, const SmpLength length) +//---------------------------------------------------------------------- +{ + const T* pEnd = pDest + length; + for(T* pSource = pDest; pDest != pEnd; pDest++, pSource += 2) + { + *pDest = *pSource; + } +} + + // Convert a multichannel sample to mono (currently only implemented for stereo) -bool ConvertToMono(ModSample &smp, CSoundFile *pSndFile) -//------------------------------------------------------ +bool ConvertToMono(ModSample &smp, CSoundFile *pSndFile, StereoToMonoMode conversionMode) +//--------------------------------------------------------------------------------------- { if(smp.pSample == nullptr || smp.nLength == 0 || smp.GetNumChannels() != 2) return false; // Note: Sample is overwritten in-place! Unused data is not deallocated! - if(smp.GetElementarySampleSize() == 2) - ConvertStereoToMonoImpl(reinterpret_cast<int16*>(smp.pSample), smp.nLength); - else if(smp.GetElementarySampleSize() == 1) - ConvertStereoToMonoImpl(reinterpret_cast<int8*>(smp.pSample), smp.nLength); - else - return false; + if(conversionMode == mixChannels) + { + if(smp.GetElementarySampleSize() == 2) + ConvertStereoToMonoMixImpl(reinterpret_cast<int16 *>(smp.pSample), smp.nLength); + else if(smp.GetElementarySampleSize() == 1) + ConvertStereoToMonoMixImpl(reinterpret_cast<int8 *>(smp.pSample), smp.nLength); + else + return false; + } else + { + if(conversionMode == splitSample) + { + conversionMode = onlyLeft; + } + if(smp.GetElementarySampleSize() == 2) + ConvertStereoToMonoOneChannelImpl(reinterpret_cast<int16 *>(smp.pSample) + (conversionMode == onlyLeft ? 0 : 1), smp.nLength); + else if(smp.GetElementarySampleSize() == 1) + ConvertStereoToMonoOneChannelImpl(reinterpret_cast<int8 *>(smp.pSample) + (conversionMode == onlyLeft ? 0 : 1), smp.nLength); + else + return false; + } CriticalSection cs; smp.uFlags &= ~(CHN_STEREO); Modified: trunk/OpenMPT/soundlib/modsmp_ctrl.h =================================================================== --- trunk/OpenMPT/soundlib/modsmp_ctrl.h 2012-11-20 20:18:02 UTC (rev 1435) +++ trunk/OpenMPT/soundlib/modsmp_ctrl.h 2012-11-21 00:08:35 UTC (rev 1436) @@ -74,8 +74,16 @@ // Crossfade sample data to create smooth loops bool XFadeSample(ModSample &smp, SmpLength iFadeLength, CSoundFile *pSndFile); +enum StereoToMonoMode +{ + mixChannels, + onlyLeft, + onlyRight, + splitSample, +}; + // Convert a sample with any number of channels to mono -bool ConvertToMono(ModSample &smp, CSoundFile *pSndFile); +bool ConvertToMono(ModSample &smp, CSoundFile *pSndFile, StereoToMonoMode conversionMode); } // Namespace ctrlSmp This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |