From: <sag...@us...> - 2011-11-12 17:27:05
|
Revision: 1134 http://modplug.svn.sourceforge.net/modplug/?rev=1134&view=rev Author: saga-games Date: 2011-11-12 17:26:58 +0000 (Sat, 12 Nov 2011) Log Message: ----------- [Fix] IT Compatibility: No pan swing, panbrello, panning envelopes, etc. is applied on surround channels anymore. [Ref] MODTYPE is now an enum. [Ref] Moved FindOrder to class ModSequence. Modified Paths: -------------- trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/Mptrack.cpp trunk/OpenMPT/mptrack/Mptrack.h trunk/OpenMPT/mptrack/PatternGotoDialog.cpp trunk/OpenMPT/mptrack/View_pat.cpp trunk/OpenMPT/mptrack/dlg_misc.cpp trunk/OpenMPT/mptrack/version.h trunk/OpenMPT/soundlib/ModSequence.cpp trunk/OpenMPT/soundlib/ModSequence.h trunk/OpenMPT/soundlib/Snd_defs.h trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/Sndfile.h trunk/OpenMPT/soundlib/Sndmix.cpp Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2011-11-06 15:05:09 UTC (rev 1133) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2011-11-12 17:26:58 UTC (rev 1134) @@ -367,7 +367,7 @@ EndWaitCursor(); } // Convert to MOD/S3M/XM/IT - switch(m_SndFile.m_nType) + switch(m_SndFile.GetType()) { case MOD_TYPE_MOD: case MOD_TYPE_S3M: @@ -914,13 +914,8 @@ MODCHANNEL *pChn = &m_SndFile.Chn[nChn]; - //stop channel, just in case. - if (pChn->nLength) - { - pChn->nPos = pChn->nPosLo = pChn->nLength = 0; - } - // reset channel properties; in theory the chan is completely unused anyway. + pChn->nPos = pChn->nPosLo = pChn->nLength = 0; pChn->dwFlags &= CHN_SAMPLEFLAGS; pChn->dwFlags &= ~(CHN_MUTE); pChn->nGlobalVol = 64; @@ -964,7 +959,7 @@ // Handle sample looping. // Changed line to fix http://forum.openmpt.org/index.php?topic=1700.0 - //if ((loopstart + 16 < loopend) && (loopstart >= 0) && (loopend <= (LONG)pChn->nLength)) { + //if ((loopstart + 16 < loopend) && (loopstart >= 0) && (loopend <= (LONG)pChn->nLength)) if ((loopstart + 16 < loopend) && (loopstart >= 0) && (pChn->pModSample != nullptr)) { pChn->nPos = loopstart; @@ -993,23 +988,9 @@ pChn->nLength = pChn->nLoopEnd = pChn->pModSample->nLength; } - /* - if (bpause) { - if ((loopstart + 16 < loopend) && (loopstart >= 0) && (loopend <= (LONG)pChn->nLength)) { - pChn->nPos = loopstart; - pChn->nPosLo = 0; - pChn->nLoopStart = loopstart; - pChn->nLoopEnd = loopend; - pChn->nLength = loopend; - } - m_SndFile.m_nBufferCount = 0; - m_SndFile.m_dwSongFlags |= SONG_PAUSED; - if ((!(CMainFrame::GetSettings().m_dwPatternSetup & PATTERN_NOEXTRALOUD)) && (nsmp)) pChn->dwFlags |= CHN_EXTRALOUD; - } else pChn->dwFlags &= ~CHN_EXTRALOUD; - */ //rewbs.vstiLive - if (nins <= m_SndFile.m_nInstruments) + if (nins <= m_SndFile.GetNumInstruments()) { const MODINSTRUMENT *pIns = m_SndFile.Instruments[nins]; if (pIns && pIns->HasValidMIDIChannel()) // instro sends to a midi chan @@ -1024,9 +1005,8 @@ if ((nPlugin) && (nPlugin <= MAX_MIXPLUGINS)) { - IMixPlugin *pPlugin = m_SndFile.m_MixPlugins[nPlugin-1].pMixPlugin; + IMixPlugin *pPlugin = m_SndFile.m_MixPlugins[nPlugin - 1].pMixPlugin; if (pPlugin) pPlugin->MidiCommand(pIns->nMidiChannel, pIns->nMidiProgram, pIns->wMidiBank, pIns->NoteMap[note - 1], pChn->nVolume, MAX_BASECHANNELS); - //if (pPlugin) pPlugin->MidiCommand(pIns->nMidiChannel, pIns->nMidiProgram, pIns->wMidiBank, note, pChn->GetVSTVolume(), MAX_BASECHANNELS); } } } @@ -3206,9 +3186,9 @@ //end rewbs.fix3185 //ensure order correlates with pattern. - if (pSndFile->Order[ord]!=pat) + if (pSndFile->Order[ord] != pat) { - ORDERINDEX tentativeOrder = pSndFile->FindOrder(pat); + ORDERINDEX tentativeOrder = pSndFile->Order.FindOrder(pat); if (tentativeOrder != ORDERINDEX_INVALID) //ensure a valid order exists. { ord = tentativeOrder; Modified: trunk/OpenMPT/mptrack/Mptrack.cpp =================================================================== --- trunk/OpenMPT/mptrack/Mptrack.cpp 2011-11-06 15:05:09 UTC (rev 1133) +++ trunk/OpenMPT/mptrack/Mptrack.cpp 2011-11-12 17:26:58 UTC (rev 1134) @@ -542,7 +542,7 @@ ///////////////////////////////////////////////////////////////////////////// // CTrackApp -UINT CTrackApp::m_nDefaultDocType = MOD_TYPE_IT; +MODTYPE CTrackApp::m_nDefaultDocType = MOD_TYPE_IT; MEMORYSTATUS CTrackApp::gMemStatus; // -> CODE#0023 Modified: trunk/OpenMPT/mptrack/Mptrack.h =================================================================== --- trunk/OpenMPT/mptrack/Mptrack.h 2011-11-06 15:05:09 UTC (rev 1133) +++ trunk/OpenMPT/mptrack/Mptrack.h 2011-11-12 17:26:58 UTC (rev 1134) @@ -105,7 +105,7 @@ friend class CMainFrame; // static data protected: - static UINT m_nDefaultDocType; + static MODTYPE m_nDefaultDocType; static LPMIDILIBSTRUCT glpMidiLibrary; static BOOL m_nProject; @@ -152,8 +152,8 @@ // -! NEW_FEATURE#0023 static LPCTSTR GetAppDirPath() {return m_szExePath;} // Returns '\'-ended executable directory path. - static UINT GetDefaultDocType() { return m_nDefaultDocType; } - static VOID SetDefaultDocType(UINT n) { m_nDefaultDocType = n; } + static MODTYPE GetDefaultDocType() { return m_nDefaultDocType; } + static void SetDefaultDocType(MODTYPE n) { m_nDefaultDocType = n; } static LPMIDILIBSTRUCT GetMidiLibrary() { return glpMidiLibrary; } static BOOL ImportMidiConfig(LPCSTR lpszFileName, BOOL bNoWarning=FALSE); static BOOL ExportMidiConfig(LPCSTR lpszFileName); Modified: trunk/OpenMPT/mptrack/PatternGotoDialog.cpp =================================================================== --- trunk/OpenMPT/mptrack/PatternGotoDialog.cpp 2011-11-06 15:05:09 UTC (rev 1133) +++ trunk/OpenMPT/mptrack/PatternGotoDialog.cpp 2011-11-12 17:26:58 UTC (rev 1134) @@ -103,7 +103,7 @@ } UpdateData(); - m_nOrder = m_pSndFile->FindOrder(static_cast<PATTERNINDEX>(m_nPattern), m_nActiveOrder); + m_nOrder = m_pSndFile->Order.FindOrder(static_cast<PATTERNINDEX>(m_nPattern), m_nActiveOrder); if (m_nOrder >= m_pSndFile->Order.size()) { m_nOrder=0; Modified: trunk/OpenMPT/mptrack/View_pat.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_pat.cpp 2011-11-06 15:05:09 UTC (rev 1133) +++ trunk/OpenMPT/mptrack/View_pat.cpp 2011-11-12 17:26:58 UTC (rev 1134) @@ -3788,7 +3788,7 @@ SetCurrentColumn(CreateCursor(0, (GetChanFromCursor(m_dwCursor) - 1) % pSndFile->GetNumChannels(), GetColTypeFromCursor(m_dwCursor))); else SetCurrentColumn(CreateCursor(0, (pSndFile->GetNumChannels() - 1), GetColTypeFromCursor(m_dwCursor))); - UINT n = CreateCursor(m_nRow) | m_dwCursor; + DWORD n = CreateCursor(m_nRow) | m_dwCursor; SetCurSel(n, n); return wParam;} case kcHomeHorizontalSelect: @@ -3815,20 +3815,22 @@ if (m_nRow < pModDoc->GetPatternSize(m_nPattern) - 1) SetCurrentRow(pModDoc->GetPatternSize(m_nPattern) - 1); return wParam; - case kcNextPattern: { UINT n = m_nPattern + 1; + case kcNextPattern: { PATTERNINDEX n = m_nPattern + 1; while ((n < pSndFile->Patterns.Size()) && (!pSndFile->Patterns[n])) n++; SetCurrentPattern((n < pSndFile->Patterns.Size()) ? n : 0); ORDERINDEX currentOrder = SendCtrlMessage(CTRLMSG_GETCURRENTORDER); - ORDERINDEX newOrder = pSndFile->FindOrder(m_nPattern, currentOrder, true); + ORDERINDEX newOrder = pSndFile->Order.FindOrder(m_nPattern, currentOrder, true); SendCtrlMessage(CTRLMSG_SETCURRENTORDER, newOrder); - return wParam; } - case kcPrevPattern: { UINT n = (m_nPattern) ? m_nPattern - 1 : pSndFile->Patterns.Size()-1; + return wParam; + } + case kcPrevPattern: { PATTERNINDEX n = (m_nPattern) ? m_nPattern - 1 : pSndFile->Patterns.Size() - 1; while ((n > 0) && (!pSndFile->Patterns[n])) n--; SetCurrentPattern(n); ORDERINDEX currentOrder = SendCtrlMessage(CTRLMSG_GETCURRENTORDER); - ORDERINDEX newOrder = pSndFile->FindOrder(m_nPattern, currentOrder, false); + ORDERINDEX newOrder = pSndFile->Order.FindOrder(m_nPattern, currentOrder, false); SendCtrlMessage(CTRLMSG_SETCURRENTORDER, newOrder); - return wParam; } + return wParam; + } case kcSelectWithCopySelect: case kcSelectWithNav: case kcSelect: if (!(m_dwStatus & (PATSTATUS_DRAGNDROPEDIT|PATSTATUS_SELECTROW))) m_dwStartSel = CreateCursor(m_nRow) | m_dwCursor; Modified: trunk/OpenMPT/mptrack/dlg_misc.cpp =================================================================== --- trunk/OpenMPT/mptrack/dlg_misc.cpp 2011-11-06 15:05:09 UTC (rev 1133) +++ trunk/OpenMPT/mptrack/dlg_misc.cpp 2011-11-12 17:26:58 UTC (rev 1134) @@ -170,7 +170,7 @@ void CModTypeDlg::UpdateChannelCBox() //----------------------------------- { - const MODTYPE type = m_TypeBox.GetItemData(m_TypeBox.GetCurSel()); + const MODTYPE type = static_cast<MODTYPE>(m_TypeBox.GetItemData(m_TypeBox.GetCurSel())); CHANNELINDEX currChanSel = m_ChannelsBox.GetItemData(m_ChannelsBox.GetCurSel()); const CHANNELINDEX minChans = CSoundFile::GetModSpecifications(type).channelsMin; const CHANNELINDEX maxChans = CSoundFile::GetModSpecifications(type).channelsMax; @@ -200,7 +200,7 @@ void CModTypeDlg::UpdateDialog() //------------------------------ { - const MODTYPE type = m_TypeBox.GetItemData(m_TypeBox.GetCurSel()); + const MODTYPE type = static_cast<MODTYPE>(m_TypeBox.GetItemData(m_TypeBox.GetCurSel())); UpdateChannelCBox(); @@ -365,7 +365,7 @@ } int sel = m_ChannelsBox.GetItemData(m_ChannelsBox.GetCurSel()); - int type = m_TypeBox.GetItemData(m_TypeBox.GetCurSel()); + MODTYPE type = static_cast<MODTYPE>(m_TypeBox.GetItemData(m_TypeBox.GetCurSel())); CHANNELINDEX maxChans = CSoundFile::GetModSpecifications(type).channelsMax; @@ -395,7 +395,7 @@ int sel = m_TypeBox.GetCurSel(); if (sel >= 0) { - m_nType = m_TypeBox.GetItemData(sel); + m_nType = static_cast<MODTYPE>(m_TypeBox.GetItemData(sel)); // -> CODE#0023 // -> DESC="IT project files (.itp)" if(m_pSndFile->m_dwSongFlags & SONG_ITPROJECT && sel != 4) Modified: trunk/OpenMPT/mptrack/version.h =================================================================== --- trunk/OpenMPT/mptrack/version.h 2011-11-06 15:05:09 UTC (rev 1133) +++ trunk/OpenMPT/mptrack/version.h 2011-11-12 17:26:58 UTC (rev 1134) @@ -15,7 +15,7 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 20 #define VER_MINOR 00 -#define VER_MINORMINOR 52 +#define VER_MINORMINOR 53 //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/ModSequence.cpp =================================================================== --- trunk/OpenMPT/soundlib/ModSequence.cpp 2011-11-06 15:05:09 UTC (rev 1133) +++ trunk/OpenMPT/soundlib/ModSequence.cpp 2011-11-12 17:26:58 UTC (rev 1134) @@ -264,7 +264,33 @@ } +ORDERINDEX ModSequence::FindOrder(PATTERNINDEX nPat, ORDERINDEX startFromOrder, bool searchForward) const +//------------------------------------------------------------------------------------------------------- +{ + const ORDERINDEX maxOrder = GetLength(); + ORDERINDEX foundAtOrder = ORDERINDEX_INVALID; + ORDERINDEX candidateOrder = 0; + for (ORDERINDEX p = 0; p < maxOrder; p++) + { + if (searchForward) + { + candidateOrder = (startFromOrder + p) % maxOrder; // wrap around MAX_ORDERS + } else + { + candidateOrder = (startFromOrder - p + maxOrder) % maxOrder; // wrap around 0 and MAX_ORDERS + } + if ((*this)[candidateOrder] == nPat) + { + foundAtOrder = candidateOrder; + break; + } + } + + return foundAtOrder; +} + + ///////////////////////////////////// // ModSequenceSet ///////////////////////////////////// Modified: trunk/OpenMPT/soundlib/ModSequence.h =================================================================== --- trunk/OpenMPT/soundlib/ModSequence.h 2011-11-06 15:05:09 UTC (rev 1133) +++ trunk/OpenMPT/soundlib/ModSequence.h 2011-11-12 17:26:58 UTC (rev 1134) @@ -67,17 +67,20 @@ // Returns length of sequence stopping counting on first '---' (or at the end of sequence). ORDERINDEX GetLengthFirstEmpty() const; - PATTERNINDEX GetInvalidPatIndex() const {return m_nInvalidIndex;} //To correspond 0xFF + PATTERNINDEX GetInvalidPatIndex() const {return m_nInvalidIndex;} // To correspond 0xFF static PATTERNINDEX GetInvalidPatIndex(const MODTYPE type); - PATTERNINDEX GetIgnoreIndex() const {return m_nIgnoreIndex;} //To correspond 0xFE + PATTERNINDEX GetIgnoreIndex() const {return m_nIgnoreIndex;} // To correspond 0xFE static PATTERNINDEX GetIgnoreIndex(const MODTYPE type); - // Returns the previous/next order ignoring skip indeces(+++). + // Returns the previous/next order ignoring skip indices(+++). // If no previous/next order exists, return first/last order, and zero // when orderlist is empty. ORDERINDEX GetPreviousOrderIgnoringSkips(const ORDERINDEX start) const; ORDERINDEX GetNextOrderIgnoringSkips(const ORDERINDEX start) const; + + // Find an order item that contains a given pattern number. + ORDERINDEX FindOrder(PATTERNINDEX nPat, ORDERINDEX startFromOrder = 0, bool searchForward = true) const; ModSequence& operator=(const ModSequence& seq); @@ -86,10 +89,10 @@ size_t WriteToByteArray(BYTE* dest, const UINT numOfBytes, const UINT destSize) const; bool ReadAsByte(const BYTE* pFrom, const int howMany, const int memLength); - // Deprecated function used for MPTm's created in 1.17.02.46 - 1.17.02.48. + // Deprecated function used for MPTm files created with OpenMPT 1.17.02.46 - 1.17.02.48. DWORD Deserialize(const BYTE* const src, const DWORD memLength); - //Returns true if the IT orderlist datafield is not sufficient to store orderlist information. + // Returns true if the IT orderlist datafield is not sufficient to store orderlist information. bool NeedsExtraDatafield() const; protected: Modified: trunk/OpenMPT/soundlib/Snd_defs.h =================================================================== --- trunk/OpenMPT/soundlib/Snd_defs.h 2011-11-06 15:05:09 UTC (rev 1133) +++ trunk/OpenMPT/soundlib/Snd_defs.h 2011-11-12 17:26:58 UTC (rev 1134) @@ -39,7 +39,6 @@ typedef uint8 SEQUENCEINDEX; const SEQUENCEINDEX SEQUENCEINDEX_MAX = uint8_max; const SEQUENCEINDEX SEQUENCEINDEX_INVALID = SEQUENCEINDEX_MAX; -typedef uint32 MODTYPE; typedef uintptr_t SmpLength; @@ -56,6 +55,7 @@ const PATTERNINDEX MAX_PATTERNS = 240; const SAMPLEINDEX MAX_SAMPLES = 4000; const INSTRUMENTINDEX MAX_INSTRUMENTS = 256; //200 +const PLUGINDEX MAX_MIXPLUGINS = 100; //50 const SEQUENCEINDEX MAX_SEQUENCES = 50; @@ -75,38 +75,51 @@ #define MAX_EQ_BANDS 6 -#define MAX_MIXPLUGINS 100 //50 #define MAX_PLUGPRESETS 1000 //rewbs.plugPresets -#define MOD_TYPE_NONE 0x00 -#define MOD_TYPE_MOD 0x01 -#define MOD_TYPE_S3M 0x02 -#define MOD_TYPE_XM 0x04 -#define MOD_TYPE_MED 0x08 -#define MOD_TYPE_MTM 0x10 -#define MOD_TYPE_IT 0x20 -#define MOD_TYPE_669 0x40 -#define MOD_TYPE_ULT 0x80 -#define MOD_TYPE_STM 0x100 -#define MOD_TYPE_FAR 0x200 -#define MOD_TYPE_WAV 0x400 -#define MOD_TYPE_AMF 0x800 -#define MOD_TYPE_AMS 0x1000 -#define MOD_TYPE_DSM 0x2000 -#define MOD_TYPE_MDL 0x4000 -#define MOD_TYPE_OKT 0x8000 -#define MOD_TYPE_MID 0x10000 -#define MOD_TYPE_DMF 0x20000 -#define MOD_TYPE_PTM 0x40000 -#define MOD_TYPE_DBM 0x80000 -#define MOD_TYPE_MT2 0x100000 -#define MOD_TYPE_AMF0 0x200000 -#define MOD_TYPE_PSM 0x400000 -#define MOD_TYPE_J2B 0x800000 -#define MOD_TYPE_MPT 0x1000000 -#define MOD_TYPE_IMF 0x2000000 -#define MOD_TYPE_UMX 0x80000000 // Fake type +enum MODTYPE +{ + MOD_TYPE_NONE = 0x00, + MOD_TYPE_MOD = 0x01, + MOD_TYPE_S3M = 0x02, + MOD_TYPE_XM = 0x04, + MOD_TYPE_MED = 0x08, + MOD_TYPE_MTM = 0x10, + MOD_TYPE_IT = 0x20, + MOD_TYPE_669 = 0x40, + MOD_TYPE_ULT = 0x80, + MOD_TYPE_STM = 0x100, + MOD_TYPE_FAR = 0x200, + MOD_TYPE_WAV = 0x400, + MOD_TYPE_AMF = 0x800, + MOD_TYPE_AMS = 0x1000, + MOD_TYPE_DSM = 0x2000, + MOD_TYPE_MDL = 0x4000, + MOD_TYPE_OKT = 0x8000, + MOD_TYPE_MID = 0x10000, + MOD_TYPE_DMF = 0x20000, + MOD_TYPE_PTM = 0x40000, + MOD_TYPE_DBM = 0x80000, + MOD_TYPE_MT2 = 0x100000, + MOD_TYPE_AMF0 = 0x200000, + MOD_TYPE_PSM = 0x400000, + MOD_TYPE_J2B = 0x800000, + MOD_TYPE_MPT = 0x1000000, + MOD_TYPE_IMF = 0x2000000, + MOD_TYPE_UMX = 0x80000000, // Fake type +}; +// Allow for type safe combinations of MODTYPEs. +inline MODTYPE operator | (MODTYPE a, MODTYPE b) +{ + return static_cast<MODTYPE>(+a | +b); +}; + +inline MODTYPE operator & (MODTYPE a, MODTYPE b) +{ + return static_cast<MODTYPE>(+a & +b); +}; + // For compatibility mode #define TRK_IMPULSETRACKER (MOD_TYPE_IT | MOD_TYPE_MPT) #define TRK_FASTTRACKER2 (MOD_TYPE_XM) Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2011-11-06 15:05:09 UTC (rev 1133) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2011-11-12 17:26:58 UTC (rev 1134) @@ -668,7 +668,7 @@ m_dwCreatedWithVersion = MptVersion::num; } - // Adjust song names + // Adjust song / sample names for (UINT iSmp=0; iSmp<MAX_SAMPLES; iSmp++) { LPSTR p = m_szNames[iSmp]; @@ -698,9 +698,9 @@ Chn[ich].nRetrigParam = Chn[ich].nRetrigCount = 1; } } - // Checking instruments + // Checking samples MODSAMPLE *pSmp = Samples; - for (UINT iIns=0; iIns<MAX_INSTRUMENTS; iIns++, pSmp++) + for (SAMPLEINDEX nSmp = 0; nSmp < MAX_SAMPLES; nSmp++, pSmp++) { if (pSmp->pSample) { @@ -773,8 +773,8 @@ string sNotFound; std::list<PLUGINDEX> notFoundIDs; - // Load plugins only when m_pModDoc != 0. (can be == 0 for example when examining module samples in treeview. - if (gpMixPluginCreateProc && GetpModDoc()) + // Load plugins only when m_pModDoc is valid. (can be invalid for example when examining module samples in treeview. + if (gpMixPluginCreateProc && GetpModDoc() != nullptr) { for (PLUGINDEX iPlug = 0; iPlug < MAX_MIXPLUGINS; iPlug++) { @@ -1187,7 +1187,7 @@ void CSoundFile::SuspendPlugins() //------------------------------- { - for (UINT iPlug=0; iPlug<MAX_MIXPLUGINS; iPlug++) + for (PLUGINDEX iPlug=0; iPlug<MAX_MIXPLUGINS; iPlug++) { if (!m_MixPlugins[iPlug].pMixPlugin) continue; //most common branch @@ -1206,7 +1206,7 @@ void CSoundFile::ResumePlugins() //------------------------------ { - for (UINT iPlug=0; iPlug<MAX_MIXPLUGINS; iPlug++) + for (PLUGINDEX iPlug=0; iPlug<MAX_MIXPLUGINS; iPlug++) { if (!m_MixPlugins[iPlug].pMixPlugin) continue; //most common branch @@ -1309,71 +1309,26 @@ //m_nSeqOverride = 0; } -ORDERINDEX CSoundFile::FindOrder(PATTERNINDEX nPat, ORDERINDEX startFromOrder, bool direction) -//-------------------------------------------------------------------------------------------- -{ - const ORDERINDEX maxOrder = Order.GetLength(); - ORDERINDEX foundAtOrder = ORDERINDEX_INVALID; - ORDERINDEX candidateOrder = 0; - for (ORDERINDEX p = 0; p < maxOrder; p++) - { - if (direction) - { - candidateOrder = (startFromOrder + p) % maxOrder; //wrap around MAX_ORDERS - } else - { - candidateOrder = (startFromOrder - p + maxOrder) % maxOrder; //wrap around 0 and MAX_ORDERS - } - if (Order[candidateOrder] == nPat) - { - foundAtOrder = candidateOrder; - break; - } - } - - return foundAtOrder; -} //end rewbs.playSongFromCursor MODTYPE CSoundFile::GetBestSaveFormat() const //------------------------------------------- { - if ((!m_nSamples) || (!m_nChannels)) return MOD_TYPE_NONE; - if (!m_nType) return MOD_TYPE_NONE; - if (m_nType & (MOD_TYPE_MOD/*|MOD_TYPE_OKT*/)) + if ((!m_nSamples) || (!m_nChannels) || GetType() == MOD_TYPE_NONE) return MOD_TYPE_NONE; + if (GetType() & (MOD_TYPE_MOD/*|MOD_TYPE_OKT*/)) return MOD_TYPE_MOD; - if (m_nType & (MOD_TYPE_S3M|MOD_TYPE_STM|MOD_TYPE_ULT|MOD_TYPE_FAR|MOD_TYPE_PTM|MOD_TYPE_MTM)) + if (GetType() & (MOD_TYPE_S3M|MOD_TYPE_STM|MOD_TYPE_ULT|MOD_TYPE_FAR|MOD_TYPE_PTM|MOD_TYPE_MTM)) return MOD_TYPE_S3M; - if (m_nType & (MOD_TYPE_XM|MOD_TYPE_MED/*|MOD_TYPE_MT2*/)) + if (GetType() & (MOD_TYPE_XM|MOD_TYPE_MED/*|MOD_TYPE_MT2*/)) return MOD_TYPE_XM; - if(m_nType & MOD_TYPE_MPT) + if(GetType() & MOD_TYPE_MPT) return MOD_TYPE_MPT; return MOD_TYPE_IT; } -MODTYPE CSoundFile::GetSaveFormats() const -//---------------------------------------- -{ - UINT n = 0; - if ((!m_nSamples) || (!m_nChannels) || (m_nType == MOD_TYPE_NONE)) return 0; - switch(m_nType) - { - case MOD_TYPE_MOD: n = MOD_TYPE_MOD; - case MOD_TYPE_S3M: n = MOD_TYPE_S3M; - } - n |= MOD_TYPE_XM | MOD_TYPE_IT | MOD_TYPE_MPT; - if (!m_nInstruments) - { - if (m_nSamples < 32) n |= MOD_TYPE_MOD; - n |= MOD_TYPE_S3M; - } - return n; -} - - LPCTSTR CSoundFile::GetSampleName(UINT nSample) const //--------------------------------------------------- { Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2011-11-06 15:05:09 UTC (rev 1133) +++ trunk/OpenMPT/soundlib/Sndfile.h 2011-11-12 17:26:58 UTC (rev 1134) @@ -249,10 +249,11 @@ { // First 32-bytes: Most used mixing information: don't change it // These fields are accessed directly by the MMX mixing code (look out for CHNOFS_PCURRENTSAMPLE), so the order is crucial + // In the meantime, MMX mixing has been removed because it interfered with the new resonant filter code, and the byte offsets are also no longer hardcoded... LPSTR pCurrentSample; DWORD nPos; - DWORD nPosLo; // actually 16-bit - LONG nInc; // 16.16 + DWORD nPosLo; // actually 16-bit (fractional part) + LONG nInc; // 16.16 fixed point LONG nRightVol; LONG nLeftVol; LONG nRightRamp; @@ -796,7 +797,6 @@ static const CModSpecifications& GetModSpecifications(const MODTYPE type); double GetCurrentBPM() const; - ORDERINDEX FindOrder(PATTERNINDEX nPat, ORDERINDEX startFromOrder = 0, bool direction = true); //rewbs.playSongFromCursor void DontLoopPattern(PATTERNINDEX nPat, ROWINDEX nRow = 0); //rewbs.playSongFromCursor void SetCurrentPos(UINT nPos); void SetCurrentOrder(ORDERINDEX nOrder); @@ -886,7 +886,6 @@ // MOD Convert function MODTYPE GetBestSaveFormat() const; - MODTYPE GetSaveFormats() const; void ConvertModCommand(MODCOMMAND *) const; void S3MConvert(MODCOMMAND *m, bool bIT) const; void S3MSaveConvert(UINT *pcmd, UINT *pprm, bool bIT, bool bCompatibilityExport = false) const; Modified: trunk/OpenMPT/soundlib/Sndmix.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndmix.cpp 2011-11-06 15:05:09 UTC (rev 1133) +++ trunk/OpenMPT/soundlib/Sndmix.cpp 2011-11-12 17:26:58 UTC (rev 1134) @@ -1825,7 +1825,7 @@ { rampLength = (1 << (VOLUMERAMPPRECISION-1)); } - if(rampLength < (LONG)globalRampLength) + if(rampLength < globalRampLength) { rampLength = globalRampLength; } @@ -2094,6 +2094,13 @@ } + // IT Compatibility: Ensure that there is no pan swing, panbrello, panning envelopes, etc. applied on surround channels. + // Test case: surround-pan.it + if((pChn->dwFlags & CHN_SURROUND) && !(m_dwSongFlags & SONG_SURROUNDPAN) && IsCompatibleMode(TRK_IMPULSETRACKER)) + { + pChn->nRealPan = 128; + } + // Now that all relevant envelopes etc. have been processed, we can parse the MIDI macro data. ProcessMacroOnChannel(nChn); @@ -2109,7 +2116,7 @@ // Final Period if (period <= m_nMinPeriod) { - if (m_nType & MOD_TYPE_S3M) pChn->nLength = 0; + if (GetType() & MOD_TYPE_S3M) pChn->nLength = 0; period = m_nMinPeriod; } //rewbs: temporarily commenting out block to allow notes below A-0. @@ -2126,12 +2133,12 @@ }*/ UINT freq = 0; - if(m_nType != MOD_TYPE_MPT || !pIns || pIns->pTuning == nullptr) + if(GetType() != MOD_TYPE_MPT || pIns == nullptr || pIns->pTuning == nullptr) { freq = GetFreqFromPeriod(period, pChn->nC5Speed, nPeriodFrac); - } - else //In this case: m_nType == MOD_TYPE_MPT and using custom tunings. + } else { + // In this case: GetType() == MOD_TYPE_MPT and using custom tunings. if(pChn->m_CalculateFreq || (pChn->m_ReCalculateFreqOnFirstTick && m_nTickCount == 0)) { pChn->m_Freq = Util::Round<UINT>(pChn->nC5Speed * vibratoFactor * pIns->pTuning->GetRatio(pChn->nNote - NOTE_MIDDLEC + arpeggioSteps, pChn->nFineTune+pChn->m_PortamentoFineSteps)); @@ -2145,11 +2152,12 @@ } // Applying Pitch/Tempo lock. - if(m_nType & (MOD_TYPE_IT | MOD_TYPE_MPT) && pIns && pIns->wPitchToTempoLock) + if(GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT) && pIns && pIns->wPitchToTempoLock) + { freq = _muldivr(freq, m_nMusicTempo, pIns->wPitchToTempoLock); + } - - if ((m_nType & (MOD_TYPE_IT | MOD_TYPE_MPT)) && (freq < 256)) + if ((GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)) && (freq < 256)) { pChn->nFadeOutVol = 0; pChn->dwFlags |= CHN_NOTEFADE; @@ -2161,7 +2169,7 @@ if ((ninc >= 0xFFB0) && (ninc <= 0x10090)) ninc = 0x10000; if (m_nFreqFactor != 128) ninc = (ninc * m_nFreqFactor) >> 7; if (ninc > 0xFF0000) ninc = 0xFF0000; - pChn->nInc = (ninc+1) & ~3; + pChn->nInc = (ninc + 1) & ~3; } else { // Avoid nasty noises... @@ -2179,7 +2187,6 @@ IncrementPitchFilterEnvelopePosition(pChn); } - #ifdef MODPLUG_PLAYER // Limit CPU -> > 80% -> don't ramp if ((gnCPUUsage >= 80) && (!pChn->nRealVolume)) @@ -2187,18 +2194,22 @@ pChn->nLeftVol = pChn->nRightVol = 0; } #endif // MODPLUG_PLAYER + // Volume ramping pChn->dwFlags &= ~CHN_VOLUMERAMP; if ((pChn->nRealVolume) || (pChn->nLeftVol) || (pChn->nRightVol)) pChn->dwFlags |= CHN_VOLUMERAMP; + #ifdef MODPLUG_PLAYER // Decrease VU-Meter if (pChn->nVUMeter > VUMETER_DECAY) pChn->nVUMeter -= VUMETER_DECAY; else pChn->nVUMeter = 0; #endif // MODPLUG_PLAYER + #ifdef ENABLE_STEREOVU if (pChn->nLeftVU > VUMETER_DECAY) pChn->nLeftVU -= VUMETER_DECAY; else pChn->nLeftVU = 0; if (pChn->nRightVU > VUMETER_DECAY) pChn->nRightVU -= VUMETER_DECAY; else pChn->nRightVU = 0; #endif + // Check for too big nInc if (((pChn->nInc >> 16) + 1) >= (LONG)(pChn->nLoopEnd - pChn->nLoopStart)) pChn->dwFlags &= ~CHN_LOOP; pChn->nNewRightVol = pChn->nNewLeftVol = 0; @@ -2213,6 +2224,7 @@ vutmp >>= 1; if (pChn->nVUMeter < vutmp) pChn->nVUMeter = vutmp; #endif // MODPLUG_PLAYER + #ifdef ENABLE_STEREOVU UINT vul = (pChn->nRealVolume * pChn->nRealPan) >> 14; if (vul > 127) vul = 127; @@ -2225,11 +2237,13 @@ vur >>= 1; if (pChn->nRightVU < vur) pChn->nRightVU = (BYTE)vur; #endif + #ifdef MODPLUG_TRACKER - UINT kChnMasterVol = (pChn->dwFlags & CHN_EXTRALOUD) ? 0x100 : nMasterVol; + const UINT kChnMasterVol = (pChn->dwFlags & CHN_EXTRALOUD) ? 0x100 : nMasterVol; #else #define kChnMasterVol nMasterVol #endif // MODPLUG_TRACKER + // Adjusting volumes if (gnChannels >= 2) { @@ -2237,7 +2251,7 @@ pan *= (int)m_nStereoSeparation; pan /= 128; pan += 128; - pan = CLAMP(pan, 0, 256); + Limit(pan, 0, 256); #ifndef FASTSOUNDLIB if (gdwSoundSetup & SNDMIX_REVERSESTEREO) pan = 256 - pan; #endif @@ -2248,7 +2262,7 @@ realvol = (pChn->nRealVolume * kChnMasterVol) >> 7; } else { - //Extra attenuation required here if we're bypassing pre-amp. + // Extra attenuation required here if we're bypassing pre-amp. realvol = (pChn->nRealVolume * kChnMasterVol) >> 8; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2011-11-18 22:30:55
|
Revision: 1137 http://modplug.svn.sourceforge.net/modplug/?rev=1137&view=rev Author: saga-games Date: 2011-11-18 22:30:48 +0000 (Fri, 18 Nov 2011) Log Message: ----------- [Fix] Loading instruments from other modules is no longer limited to 32 samples [Imp] Added more consistency checks / conversions when loading samples / instruments from files. Modified Paths: -------------- trunk/OpenMPT/mptrack/ModConvert.cpp trunk/OpenMPT/soundlib/Sampleio.cpp trunk/OpenMPT/soundlib/Sndfile.h Modified: trunk/OpenMPT/mptrack/ModConvert.cpp =================================================================== --- trunk/OpenMPT/mptrack/ModConvert.cpp 2011-11-18 22:21:47 UTC (rev 1136) +++ trunk/OpenMPT/mptrack/ModConvert.cpp 2011-11-18 22:30:48 UTC (rev 1137) @@ -97,18 +97,17 @@ if(nNewType == nOldType) return true; - const bool oldTypeIsMOD = (nOldType == MOD_TYPE_MOD), oldTypeIsXM = (nOldType == MOD_TYPE_XM), - oldTypeIsS3M = (nOldType == MOD_TYPE_S3M), oldTypeIsIT = (nOldType == MOD_TYPE_IT), - oldTypeIsMPT = (nOldType == MOD_TYPE_MPT), oldTypeIsMOD_XM = (oldTypeIsMOD || oldTypeIsXM), - oldTypeIsS3M_IT_MPT = (oldTypeIsS3M || oldTypeIsIT || oldTypeIsMPT), - oldTypeIsIT_MPT = (oldTypeIsIT || oldTypeIsMPT); + const bool oldTypeIsXM = (nOldType == MOD_TYPE_XM), + oldTypeIsS3M = (nOldType == MOD_TYPE_S3M), oldTypeIsIT = (nOldType == MOD_TYPE_IT), + oldTypeIsMPT = (nOldType == MOD_TYPE_MPT), + oldTypeIsS3M_IT_MPT = (oldTypeIsS3M || oldTypeIsIT || oldTypeIsMPT), + oldTypeIsIT_MPT = (oldTypeIsIT || oldTypeIsMPT); const bool newTypeIsMOD = (nNewType == MOD_TYPE_MOD), newTypeIsXM = (nNewType == MOD_TYPE_XM), - newTypeIsS3M = (nNewType == MOD_TYPE_S3M), newTypeIsIT = (nNewType == MOD_TYPE_IT), - newTypeIsMPT = (nNewType == MOD_TYPE_MPT), newTypeIsMOD_XM = (newTypeIsMOD || newTypeIsXM), - newTypeIsS3M_IT_MPT = (newTypeIsS3M || newTypeIsIT || newTypeIsMPT), - newTypeIsXM_IT_MPT = (newTypeIsXM || newTypeIsIT || newTypeIsMPT), - newTypeIsIT_MPT = (newTypeIsIT || newTypeIsMPT); + newTypeIsS3M = (nNewType == MOD_TYPE_S3M), newTypeIsIT = (nNewType == MOD_TYPE_IT), + newTypeIsMPT = (nNewType == MOD_TYPE_MPT), newTypeIsMOD_XM = (newTypeIsMOD || newTypeIsXM), + newTypeIsXM_IT_MPT = (newTypeIsXM || newTypeIsIT || newTypeIsMPT), + newTypeIsIT_MPT = (newTypeIsIT || newTypeIsMPT); const CModSpecifications& specs = m_SndFile.GetModSpecifications(nNewType); @@ -271,14 +270,12 @@ // Bidi loops if((sample.uFlags & CHN_PINGPONGLOOP) != 0) { - sample.uFlags &= ~CHN_PINGPONGLOOP; CHANGEMODTYPE_WARNING(wSampleBidiLoops); } // Autovibrato if(sample.nVibDepth || sample.nVibRate || sample.nVibSweep) { - sample.nVibDepth = sample.nVibRate = sample.nVibSweep = sample.nVibType = 0; CHANGEMODTYPE_WARNING(wSampleAutoVibrato); } } @@ -289,71 +286,17 @@ // Sustain loops - convert to normal loops if((sample.uFlags & CHN_SUSTAINLOOP) != 0) { - // We probably overwrite a normal loop here, but since sustain loops are evaluated before normal loops, this is just correct. - sample.nLoopStart = sample.nSustainStart; - sample.nLoopEnd = sample.nSustainEnd; - sample.uFlags |= CHN_LOOP; - if(sample.uFlags & CHN_PINGPONGSUSTAIN) - { - sample.uFlags |= CHN_PINGPONGLOOP; - } else - { - sample.uFlags &= ~CHN_PINGPONGLOOP; - } CHANGEMODTYPE_WARNING(wSampleSustainLoops); } - sample.nSustainStart = sample.nSustainEnd = 0; - sample.uFlags &= ~(CHN_SUSTAINLOOP|CHN_PINGPONGSUSTAIN); } - // Transpose to Frequency (MOD/XM to S3M/IT/MPT) - if(oldTypeIsMOD_XM && newTypeIsS3M_IT_MPT) + // TODO: Pattern notes could be transposed based on the previous relative tone? + if(newTypeIsMOD && sample.RelativeTone != 0) { - sample.nC5Speed = CSoundFile::TransposeToFrequency(sample.RelativeTone, sample.nFineTune); - sample.RelativeTone = 0; - sample.nFineTune = 0; + CHANGEMODTYPE_WARNING(wMODSampleFrequency); } - // Frequency to Transpose (S3M/IT/MPT to MOD/XM) - if(oldTypeIsS3M_IT_MPT && newTypeIsMOD_XM) - { - CSoundFile::FrequencyToTranspose(&sample); - // No relative note for MOD files - // TODO: Pattern notes could be transposed based on the previous relative tone? - if(newTypeIsMOD && sample.RelativeTone != 0) - { - sample.RelativeTone = 0; - CHANGEMODTYPE_WARNING(wMODSampleFrequency); - } - } - - // All XM samples have default panning, and XM's autovibrato settings are rather limited. - if(newTypeIsXM) - { - if(!(sample.uFlags & CHN_PANNING)) - { - sample.uFlags |= CHN_PANNING; - sample.nPan = 128; - } - - LimitMax(sample.nVibDepth, BYTE(15)); - LimitMax(sample.nVibRate, BYTE(63)); - } - - // S3M / MOD samples don't have panning. - if(newTypeIsMOD || newTypeIsS3M) - { - sample.uFlags &= ~CHN_PANNING; - } - - if((oldTypeIsXM && newTypeIsIT_MPT) || (oldTypeIsIT_MPT && newTypeIsXM)) - { - // Autovibrato sweep setting is inverse in XM (0 = "no sweep") and IT (0 = "no vibrato") - if(sample.nVibRate != 0 && sample.nVibDepth != 0) - { - sample.nVibSweep = 255 - sample.nVibSweep; - } - } + m_SndFile.ConvertSample(nSmp, nOldType, nNewType); } for(INSTRUMENTINDEX nIns = 1; nIns <= m_SndFile.GetNumInstruments(); nIns++) @@ -367,9 +310,9 @@ // Convert IT/MPT to XM (fix instruments) if(oldTypeIsIT_MPT && newTypeIsXM) { - for (UINT k = 0; k < NOTE_MAX; k++) + for (size_t i = 0; i < CountOf(pIns->NoteMap); i++) { - if ((pIns->NoteMap[k]) && (pIns->NoteMap[k] != (BYTE)(k+1))) + if ((pIns->NoteMap[i]) && (pIns->NoteMap[i] != (BYTE)(i + 1))) { CHANGEMODTYPE_WARNING(wBrokenNoteMap); break; @@ -379,52 +322,29 @@ if(pIns->VolEnv.nSustainStart != pIns->VolEnv.nSustainEnd) { CHANGEMODTYPE_WARNING(wInstrumentSustainLoops); - pIns->VolEnv.nSustainEnd = pIns->VolEnv.nSustainStart; } if(pIns->PanEnv.nSustainStart != pIns->PanEnv.nSustainEnd) { CHANGEMODTYPE_WARNING(wInstrumentSustainLoops); - pIns->PanEnv.nSustainEnd = pIns->PanEnv.nSustainStart; } - pIns->VolEnv.dwFlags &= ~ENV_CARRY; - pIns->PanEnv.dwFlags &= ~ENV_CARRY; - pIns->PitchEnv.dwFlags &= ~(ENV_CARRY|ENV_ENABLED|ENV_FILTER); - pIns->dwFlags &= ~INS_SETPANNING; - pIns->SetCutoff(pIns->GetCutoff(), false); - pIns->SetResonance(pIns->GetResonance(), false); - pIns->nFilterMode = FLTMODE_UNCHANGED; - - pIns->nCutSwing = pIns->nPanSwing = pIns->nResSwing = pIns->nVolSwing = 0; - - pIns->nPPC = NOTE_MIDDLEC - 1; - pIns->nPPS = 0; - - pIns->nGlobalVol = 64; - pIns->nPan = 128; } - // Convert XM to IT/MPTM - fix fadeout length - if(oldTypeIsXM && newTypeIsIT_MPT) - { - LimitMax(pIns->nFadeOut, 8192u); - } - // Convert MPT to anything - remove instrument tunings, Pitch/Tempo Lock if(oldTypeIsMPT) { if(pIns->pTuning != nullptr) { - pIns->SetTuning(nullptr); CHANGEMODTYPE_WARNING(wInstrumentTuning); } if(pIns->wPitchToTempoLock != 0) { - pIns->wPitchToTempoLock = 0; CHANGEMODTYPE_WARNING(wPitchToTempoLock); } } + + m_SndFile.ConvertInstrument(nIns, nOldType, nNewType); } if(newTypeIsMOD) @@ -566,7 +486,7 @@ CHANGEMODTYPE_CHECK(wInstrumentSustainLoops, "Sustain loops were converted to sustain points.\n"); CHANGEMODTYPE_CHECK(wInstrumentTuning, "Instrument tunings will be lost.\n"); CHANGEMODTYPE_CHECK(wPitchToTempoLock, "Pitch / Tempo Lock instrument property is not supported by the new format.\n"); - CHANGEMODTYPE_CHECK(wBrokenNoteMap, "Note Mapping will be lost when saving as XM.\n"); + CHANGEMODTYPE_CHECK(wBrokenNoteMap, "Instrument Note Mapping is not supported by the new format.\n"); CHANGEMODTYPE_CHECK(wReleaseNode, "Instrument envelope release nodes are not supported by the new format.\n"); // General warnings Modified: trunk/OpenMPT/soundlib/Sampleio.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sampleio.cpp 2011-11-18 22:21:47 UTC (rev 1136) +++ trunk/OpenMPT/soundlib/Sampleio.cpp 2011-11-18 22:30:48 UTC (rev 1137) @@ -61,7 +61,7 @@ || (psig[76/4] == LittleEndian(0x53524353)) // S3I signature || ((psig[0] == LittleEndian(0x4D524F46)) && (psig[2] == LittleEndian(0x46464941))) // AIFF signature || ((psig[0] == LittleEndian(0x4D524F46)) && (psig[2] == LittleEndian(0x58565338))) // 8SVX signature - || (psig[0] == LittleEndian(LittleEndian(IT_IMPS))) // ITS signature + || (psig[0] == LittleEndian(IT_IMPS)) // ITS signature ) { // Loading Instrument @@ -91,8 +91,6 @@ DestroyInstrument(nInstr, deleteAssociatedSamples); Instruments[nInstr] = pIns; - // Default values - pIns->nFadeOut = 1024; if (nSample) ReadSampleFromFile(nSample, lpMemFile, dwFileLength); return true; } @@ -188,12 +186,15 @@ // I/O From another song // -bool CSoundFile::ReadInstrumentFromSong(INSTRUMENTINDEX nInstr, CSoundFile *pSrcSong, UINT nSrcInstr) -//--------------------------------------------------------------------------------------------------- +bool CSoundFile::ReadInstrumentFromSong(INSTRUMENTINDEX targetInstr, const CSoundFile *pSrcSong, INSTRUMENTINDEX sourceInstr) +//--------------------------------------------------------------------------------------------------------------------------- { - if ((!pSrcSong) || (!nSrcInstr) || (nSrcInstr > pSrcSong->m_nInstruments) - || (nInstr >= MAX_INSTRUMENTS) || (!pSrcSong->Instruments[nSrcInstr])) return false; - if (m_nInstruments < nInstr) m_nInstruments = nInstr; + if ((!pSrcSong) || (!sourceInstr) || (sourceInstr > pSrcSong->GetNumInstruments()) + || (targetInstr >= MAX_INSTRUMENTS) || (!pSrcSong->Instruments[sourceInstr])) + { + return false; + } + if (m_nInstruments < targetInstr) m_nInstruments = targetInstr; MODINSTRUMENT *pIns; @@ -205,95 +206,88 @@ return false; } - DestroyInstrument(nInstr, deleteAssociatedSamples); + DestroyInstrument(targetInstr, deleteAssociatedSamples); - Instruments[nInstr] = pIns; + Instruments[targetInstr] = pIns; + *pIns = *pSrcSong->Instruments[sourceInstr]; - // TODO we want to copy ALL samples, not just 32! Use vectors here. - WORD samplemap[32]; - WORD samplesrc[32]; - UINT nSamples = 0; - UINT nsmp = 1; - *pIns = *pSrcSong->Instruments[nSrcInstr]; - for (UINT i=0; i<128; i++) + vector<SAMPLEINDEX> sourceSample; // Sample index in source song + vector<SAMPLEINDEX> targetSample; // Sample index in target song + SAMPLEINDEX targetIndex = 1; // Next index for inserting sample + + for(size_t i = 0; i < CountOf(pIns->Keyboard); i++) { - UINT n = pIns->Keyboard[i]; - if ((n) && (n <= pSrcSong->m_nSamples) && (i < NOTE_MAX)) + const SAMPLEINDEX sourceIndex = pIns->Keyboard[i]; + if(sourceIndex > 0 && sourceIndex <= pSrcSong->GetNumSamples()) { - UINT j = 0; - for (j=0; j<nSamples; j++) + const vector<SAMPLEINDEX>::const_iterator entry = std::find(sourceSample.begin(), sourceSample.end(), sourceIndex); + if(entry == sourceSample.end()) { - if (samplesrc[j] == n) break; - } - if (j >= nSamples) - { - while ((nsmp < MAX_SAMPLES) && ((Samples[nsmp].pSample) || (m_szNames[nsmp][0]))) nsmp++; - if ((nSamples < 32) && (nsmp < MAX_SAMPLES)) + // Didn't consider this sample yet, so add it to our map. + while((targetIndex < MAX_SAMPLES) && ((Samples[targetIndex].pSample) || (m_szNames[targetIndex][0]))) targetIndex++; + if(targetIndex <= GetModSpecifications().samplesMax) { - samplesrc[nSamples] = (WORD)n; - samplemap[nSamples] = (WORD)nsmp; - nSamples++; - pIns->Keyboard[i] = (SAMPLEINDEX)nsmp; - if (m_nSamples < nsmp) m_nSamples = nsmp; - nsmp++; + sourceSample.push_back(sourceIndex); + targetSample.push_back(targetIndex); + pIns->Keyboard[i] = targetIndex++; } else { pIns->Keyboard[i] = 0; } } else { - pIns->Keyboard[i] = samplemap[j]; + // Sample reference has already been created, so only need to update the sample map. + pIns->Keyboard[i] = *(entry - sourceSample.begin() + targetSample.begin()); } } else { + // Invalid or no source sample pIns->Keyboard[i] = 0; } } - // Load Samples - for (UINT k=0; k<nSamples; k++) + + ConvertInstrument(targetInstr, pSrcSong->GetType()); + + // Copy all referenced samples over + for(size_t i = 0; i < targetSample.size(); i++) { - ReadSampleFromSong(samplemap[k], pSrcSong, samplesrc[k]); + ReadSampleFromSong(targetSample[i], pSrcSong, sourceSample[i]); } return true; } -bool CSoundFile::ReadSampleFromSong(SAMPLEINDEX nSample, CSoundFile *pSrcSong, UINT nSrcSample) -//--------------------------------------------------------------------------------------------- +bool CSoundFile::ReadSampleFromSong(SAMPLEINDEX targetSample, const CSoundFile *pSrcSong, SAMPLEINDEX sourceSample) +//----------------------------------------------------------------------------------------------------------------- { - if ((!pSrcSong) || (!nSrcSample) || (nSrcSample > pSrcSong->m_nSamples) || (nSample >= MAX_SAMPLES)) return false; - MODSAMPLE *psmp = &pSrcSong->Samples[nSrcSample]; - UINT nSize = psmp->nLength; - if (psmp->uFlags & CHN_16BIT) nSize *= 2; - if (psmp->uFlags & CHN_STEREO) nSize *= 2; - if (m_nSamples < nSample) m_nSamples = nSample; - if (Samples[nSample].pSample) + if ((!pSrcSong) || (!sourceSample) || (sourceSample > pSrcSong->m_nSamples) || (targetSample >= GetModSpecifications().samplesMax)) { - Samples[nSample].nLength = 0; - FreeSample(Samples[nSample].pSample); + return false; } - Samples[nSample] = *psmp; - if (psmp->pSample) + + const MODSAMPLE *pSourceSample = &pSrcSong->Samples[sourceSample]; + + if (m_nSamples < targetSample) m_nSamples = targetSample; + if (Samples[targetSample].pSample) { - Samples[nSample].pSample = AllocateSample(nSize+8); - if (Samples[nSample].pSample) + Samples[targetSample].nLength = 0; + FreeSample(Samples[targetSample].pSample); + } + Samples[targetSample] = *pSourceSample; + if (pSourceSample->pSample) + { + UINT nSize = pSourceSample->GetSampleSizeInBytes(); + Samples[targetSample].pSample = AllocateSample(nSize + 8); + if (Samples[targetSample].pSample) { - memcpy(Samples[nSample].pSample, psmp->pSample, nSize); - AdjustSampleLoop(&Samples[nSample]); + memcpy(Samples[targetSample].pSample, pSourceSample->pSample, nSize); + AdjustSampleLoop(&Samples[targetSample]); } } - if ((!(m_nType & (MOD_TYPE_MOD|MOD_TYPE_XM))) && (pSrcSong->m_nType & (MOD_TYPE_MOD|MOD_TYPE_XM))) - { - MODSAMPLE *pSmp = &Samples[nSample]; - pSmp->nC5Speed = TransposeToFrequency(pSmp->RelativeTone, pSmp->nFineTune); - pSmp->RelativeTone = 0; - pSmp->nFineTune = 0; - } else - if ((m_nType & (MOD_TYPE_MOD|MOD_TYPE_XM)) && (!(pSrcSong->m_nType & (MOD_TYPE_MOD|MOD_TYPE_XM)))) - { - FrequencyToTranspose(&Samples[nSample]); - } + + ConvertSample(targetSample, pSrcSong->GetType()); + return true; } @@ -443,7 +437,7 @@ if (m_nType & MOD_TYPE_XM) FrequencyToTranspose(pSmp); pSmp->nVibType = pSmp->nVibSweep = pSmp->nVibDepth = pSmp->nVibRate = 0; pSmp->filename[0] = 0; - memset(m_szNames[nSample], 0, 32); + MemsetZero(m_szNames[nSample]); if (pSmp->nLength > MAX_SAMPLE_LENGTH) pSmp->nLength = MAX_SAMPLE_LENGTH; // IMA ADPCM 4:1 if (pfmtpk) @@ -1029,7 +1023,9 @@ pSmp->nC5Speed = pss->nC5Speed; pSmp->RelativeTone = 0; pSmp->nFineTune = 0; - if (m_nType & MOD_TYPE_XM) FrequencyToTranspose(pSmp); + + ConvertSample(nSample, MOD_TYPE_S3M); + if (pss->flags & 0x01) pSmp->uFlags |= CHN_LOOP; flags = (pss->flags & 0x04) ? RS_PCM16U : RS_PCM8U; if (pss->flags & 0x02) flags |= RSF_STEREO; @@ -1254,6 +1250,8 @@ memcpy(m_szNames[samplemap[ismp]], psh->name, 22); memcpy(pSmp->filename, psh->name, 22); pSmp->filename[21] = 0; + + ConvertSample(samplemap[ismp], MOD_TYPE_XM); } // Reading sample data for (UINT dsmp=0; dsmp<nsamples; dsmp++) @@ -1264,6 +1262,8 @@ dwMemPos += samplesize[dsmp]; } + ConvertInstrument(nInstr, MOD_TYPE_XM); + // -> CODE#0027 // -> DESC="per-instrument volume ramping setup (refered as attack)" @@ -1340,6 +1340,11 @@ xih.vibsweep = min(Samples[n].nVibSweep, 255); xih.vibdepth = min(Samples[n].nVibDepth, 15); xih.vibrate = min(Samples[n].nVibRate, 63); + if((xih.vibdepth | xih.vibrate) != 0 && !(GetType() & MOD_TYPE_XM)) + { + // Sweep is upside down in XM + xih.vibsweep = 255 - xih.vibsweep; + } } if (nsamples < 32) smptable[nsamples++] = n; k = nsamples - 1; @@ -1476,12 +1481,6 @@ pSmp->nFineTune = psh->finetune; pSmp->nC5Speed = 8363; pSmp->RelativeTone = (int)psh->relnote; - if (m_nType != MOD_TYPE_XM) - { - pSmp->nC5Speed = TransposeToFrequency(pSmp->RelativeTone, pSmp->nFineTune); - pSmp->RelativeTone = 0; - pSmp->nFineTune = 0; - } pSmp->nPan = psh->pan; pSmp->uFlags |= CHN_PANNING; pSmp->nVibType = pih->vibtype; @@ -1491,6 +1490,7 @@ memcpy(pSmp->filename, psh->name, 22); pSmp->filename[21] = 0; } + ConvertSample(nSample, MOD_TYPE_XM); if (dwMemPos >= dwFileLength) return true; ReadSample(pSmp, sampleflags, (LPSTR)(lpMemFile+dwMemPos), dwFileLength-dwMemPos); return true; @@ -1657,7 +1657,6 @@ if (pis->C5Speed < 256) pSmp->nC5Speed = 256; pSmp->RelativeTone = 0; pSmp->nFineTune = 0; - if (GetType() == MOD_TYPE_XM) FrequencyToTranspose(pSmp); pSmp->nVolume = pis->vol << 2; if (pSmp->nVolume > 256) pSmp->nVolume = 256; pSmp->nGlobalVol = pis->gvl; @@ -1696,10 +1695,14 @@ // IT 2.14 8-bit packed sample ? if (pis->flags & 8) flags = RS_IT2148; } + + ConvertSample(nSample, MOD_TYPE_IT); + // -> CODE#0027 // -> DESC="per-instrument volume ramping setup (refered as attack)" // ReadSample(pSmp, flags, (LPSTR)(lpMemFile+dwMemPos), dwFileLength + dwOffset - dwMemPos); // return TRUE; + return ReadSample(pSmp, flags, (LPSTR)(lpMemFile+dwMemPos), dwFileLength + dwOffset - dwMemPos); // -! NEW_FEATURE#0027 } @@ -1788,6 +1791,8 @@ // Leave if no extra instrument settings are available (end of file reached) if(dwMemPos >= dwFileLength) return true; + ConvertInstrument(nInstr, MOD_TYPE_IT); + ReadExtendedInstrumentProperties(pIns, lpMemFile + dwMemPos, dwFileLength - dwMemPos); // -! NEW_FEATURE#0027 @@ -1931,6 +1936,11 @@ itss.dfp = psmp->nPan >> 2; itss.vit = autovibxm2it[psmp->nVibType & 7]; itss.vir = min(psmp->nVibSweep, 255); + if((itss.vid | itss.vis) && (GetType() & MOD_TYPE_XM)) + { + // Sweep is upside down in XM + itss.vir = 255 - itss.vir; + } itss.vid = min(psmp->nVibDepth, 32); itss.vis = min(psmp->nVibRate, 64); if (psmp->uFlags & CHN_PANNING) itss.dfp |= 0x80; @@ -2188,3 +2198,158 @@ return (pSmp->pSample != nullptr); } + +// Translate sample properties between two given formats. +void CSoundFile::ConvertSample(SAMPLEINDEX sample, MODTYPE fromType, MODTYPE toType) +//---------------------------------------------------------------------------------- +{ + if(toType == MOD_TYPE_NONE) + { + toType = GetType(); + } + + if(sample < 1 || sample > GetNumSamples()) + { + return; + } + + MODSAMPLE &smp = GetSample(sample); + // Convert between frequency and transpose values if necessary. + if ((!(toType & (MOD_TYPE_MOD | MOD_TYPE_XM))) && (fromType & (MOD_TYPE_MOD | MOD_TYPE_XM))) + { + smp.nC5Speed = TransposeToFrequency(smp.RelativeTone, smp.nFineTune); + smp.RelativeTone = 0; + smp.nFineTune = 0; + } else if((toType & (MOD_TYPE_MOD | MOD_TYPE_XM)) && (!(fromType & (MOD_TYPE_MOD | MOD_TYPE_XM)))) + { + FrequencyToTranspose(&smp); + if(toType & MOD_TYPE_MOD) + { + smp.RelativeTone = 0; + } + } + + // No ping-pong loop, panning and auto-vibrato for MOD / S3M samples + if(toType & (MOD_TYPE_MOD | MOD_TYPE_S3M)) + { + smp.uFlags &= ~(CHN_PINGPONGLOOP | CHN_PANNING); + + smp.nVibDepth = 0; + smp.nVibRate = 0; + smp.nVibSweep = 0; + smp.nVibType = VIB_SINE; + } + + // No sustain loops for MOD/S3M/XM + if(toType & (MOD_TYPE_MOD | MOD_TYPE_XM | MOD_TYPE_S3M)) + { + // Sustain loops - convert to normal loops + if((smp.uFlags & CHN_SUSTAINLOOP) != 0) + { + // We probably overwrite a normal loop here, but since sustain loops are evaluated before normal loops, this is just correct. + smp.nLoopStart = smp.nSustainStart; + smp.nLoopEnd = smp.nSustainEnd; + smp.uFlags |= CHN_LOOP; + if(smp.uFlags & CHN_PINGPONGSUSTAIN) + { + smp.uFlags |= CHN_PINGPONGLOOP; + } else + { + smp.uFlags &= ~CHN_PINGPONGLOOP; + } + } + smp.nSustainStart = smp.nSustainEnd = 0; + smp.uFlags &= ~(CHN_SUSTAINLOOP|CHN_PINGPONGSUSTAIN); + } + + // All XM samples have default panning, and XM's autovibrato settings are rather limited. + if(toType & MOD_TYPE_XM) + { + if(!(smp.uFlags & CHN_PANNING)) + { + smp.uFlags |= CHN_PANNING; + smp.nPan = 128; + } + + LimitMax(smp.nVibDepth, BYTE(15)); + LimitMax(smp.nVibRate, BYTE(63)); + } + + + // Autovibrato sweep setting is inverse in XM (0 = "no sweep") and IT (0 = "no vibrato") + if(((fromType & MOD_TYPE_XM) && (toType & (MOD_TYPE_IT | MOD_TYPE_MPT))) || ((toType & MOD_TYPE_XM) && (fromType & (MOD_TYPE_IT | MOD_TYPE_MPT)))) + { + if(smp.nVibRate != 0 && smp.nVibDepth != 0) + { + smp.nVibSweep = 255 - smp.nVibSweep; + } + } +} + + +// Translate instrument properties between two given formats. +void CSoundFile::ConvertInstrument(INSTRUMENTINDEX instr, MODTYPE fromType, MODTYPE toType) +//----------------------------------------------------------------------------------------- +{ + UNREFERENCED_PARAMETER(fromType); + + if(toType == MOD_TYPE_NONE) + { + toType = GetType(); + } + + if(instr < 1 || instr > GetNumInstruments() || Instruments[instr] == nullptr) + { + return; + } + + MODINSTRUMENT *pIns = Instruments[instr]; + + if(toType & MOD_TYPE_XM) + { + for(size_t i = 0; i < CountOf(pIns->NoteMap); i++) + { + pIns->NoteMap[i] = static_cast<BYTE>(i + 1); + } + + // Convert sustain loops to sustain "points" + pIns->VolEnv.nSustainEnd = pIns->VolEnv.nSustainStart; + pIns->PanEnv.nSustainEnd = pIns->PanEnv.nSustainStart; + + pIns->VolEnv.dwFlags &= ~ENV_CARRY; + pIns->PanEnv.dwFlags &= ~ENV_CARRY; + pIns->PitchEnv.dwFlags &= ~(ENV_CARRY|ENV_ENABLED|ENV_FILTER); + + pIns->dwFlags &= ~INS_SETPANNING; + pIns->SetCutoff(pIns->GetCutoff(), false); + pIns->SetResonance(pIns->GetResonance(), false); + pIns->nFilterMode = FLTMODE_UNCHANGED; + + pIns->nCutSwing = pIns->nPanSwing = pIns->nResSwing = pIns->nVolSwing = 0; + + pIns->nPPC = NOTE_MIDDLEC - 1; + pIns->nPPS = 0; + + pIns->nNNA = NNA_NOTECUT; + pIns->nDCT = DCT_NONE; + pIns->nDNA = DNA_NOTECUT; + + pIns->nGlobalVol = 64; + pIns->nPan = 128; + + LimitMax(pIns->nFadeOut, 32767u); + } + + // Limit fadeout length for IT / MPT + if(toType & (MOD_TYPE_IT | MOD_TYPE_MPT)) + { + LimitMax(pIns->nFadeOut, 8192u); + } + + // MPT-specific features - remove instrument tunings, Pitch/Tempo Lock for other formats + if(!(toType & MOD_TYPE_MPT)) + { + pIns->SetTuning(nullptr); + pIns->wPitchToTempoLock = 0; + } +} Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2011-11-18 22:21:47 UTC (rev 1136) +++ trunk/OpenMPT/soundlib/Sndfile.h 2011-11-18 22:30:48 UTC (rev 1137) @@ -896,6 +896,11 @@ static void S3MSxx2MODExx(MODCOMMAND *m); // Convert Sxx to Exx void SetupMODPanning(bool bForceSetup = false); // Setup LRRL panning, max channel volume + // Translate sample properties between two given formats. + void ConvertSample(SAMPLEINDEX sample, MODTYPE fromType, MODTYPE toType = MOD_TYPE_NONE); + // Translate instrument properties between two given formats. + void ConvertInstrument(INSTRUMENTINDEX instr, MODTYPE fromType, MODTYPE toType = MOD_TYPE_NONE); + public: // Real-time sound functions void SuspendPlugins(); //rewbs.VSTCompliance @@ -1090,8 +1095,8 @@ bool SaveXIInstrument(INSTRUMENTINDEX nInstr, LPCSTR lpszFileName); bool SaveITIInstrument(INSTRUMENTINDEX nInstr, LPCSTR lpszFileName); // I/O from another sound file - bool ReadInstrumentFromSong(INSTRUMENTINDEX nInstr, CSoundFile *pSrcSong, UINT nSrcInstrument); - bool ReadSampleFromSong(SAMPLEINDEX nSample, CSoundFile *pSrcSong, UINT nSrcSample); + bool ReadInstrumentFromSong(INSTRUMENTINDEX targetInstr, const CSoundFile *pSrcSong, INSTRUMENTINDEX sourceInstr); + bool ReadSampleFromSong(SAMPLEINDEX targetSample, const CSoundFile *pSrcSong, SAMPLEINDEX sourceSample); // Period/Note functions UINT GetNoteFromPeriod(UINT period) const; UINT GetPeriodFromNote(UINT note, int nFineTune, UINT nC5Speed) const; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2011-11-18 22:52:27
|
Revision: 1138 http://modplug.svn.sourceforge.net/modplug/?rev=1138&view=rev Author: saga-games Date: 2011-11-18 22:52:19 +0000 (Fri, 18 Nov 2011) Log Message: ----------- [Ref] Moved some of the MIDI Macro code around yet again. Should also work in VS2008 again. [Mod] OpenMPT: Version is now 1.20.00.54 Modified Paths: -------------- trunk/OpenMPT/mptrack/Ctrl_pat.cpp trunk/OpenMPT/mptrack/mptrack.vcproj trunk/OpenMPT/mptrack/mptrack_08.vcproj trunk/OpenMPT/mptrack/mptrack_10.vcxproj trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters trunk/OpenMPT/mptrack/test/test.cpp trunk/OpenMPT/mptrack/version.h trunk/OpenMPT/soundlib/Sndfile.cpp Added Paths: ----------- trunk/OpenMPT/mptrack/MIDIMacroDialog.cpp trunk/OpenMPT/mptrack/MIDIMacroDialog.h trunk/OpenMPT/soundlib/MIDIMacros.cpp trunk/OpenMPT/soundlib/MIDIMacros.h Removed Paths: ------------- trunk/OpenMPT/mptrack/MIDIMacros.cpp trunk/OpenMPT/mptrack/MIDIMacros.h Modified: trunk/OpenMPT/mptrack/Ctrl_pat.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_pat.cpp 2011-11-18 22:30:48 UTC (rev 1137) +++ trunk/OpenMPT/mptrack/Ctrl_pat.cpp 2011-11-18 22:52:19 UTC (rev 1138) @@ -9,7 +9,7 @@ #include "view_pat.h" #include "ChannelManagerDlg.h" #include "../common/StringFixer.h" -#include "MIDIMacros.h" +#include "MIDIMacroDialog.h" ////////////////////////////////////////////////////////////// Added: trunk/OpenMPT/mptrack/MIDIMacroDialog.cpp =================================================================== --- trunk/OpenMPT/mptrack/MIDIMacroDialog.cpp (rev 0) +++ trunk/OpenMPT/mptrack/MIDIMacroDialog.cpp 2011-11-18 22:52:19 UTC (rev 1138) @@ -0,0 +1,531 @@ +/* + * MIDIMacroDialog.cpp + * ------------------- + * Purpose: MIDI Macro Configuration Dialog implementation + * Notes : (currently none) + * Authors: OpenMPT Devs + */ + +#include "stdafx.h" +#include "../common/Reporting.h" +#include "../common/StringFixer.h" +#include "Mainfrm.h" +#include "mptrack.h" +#include "Vstplug.h" +#include "resource.h" +#include "MIDIMacros.h" +#include "MIDIMacroDialog.h" + + +BEGIN_MESSAGE_MAP(CMidiMacroSetup, CDialog) + ON_COMMAND(IDC_CHECK1, OnEmbedMidiCfg) + ON_COMMAND(IDC_BUTTON1, OnSetAsDefault) + ON_COMMAND(IDC_BUTTON2, OnResetCfg) + ON_COMMAND(IDC_BUTTON3, OnMacroHelp) + ON_CBN_SELCHANGE(IDC_COMBO1, OnSFxChanged) + ON_CBN_SELCHANGE(IDC_COMBO2, OnSFxPresetChanged) + ON_CBN_SELCHANGE(IDC_COMBO3, OnZxxPresetChanged) + ON_CBN_SELCHANGE(IDC_COMBO4, UpdateDialog) + ON_CBN_SELCHANGE(IDC_MACROPLUG, OnPlugChanged) + ON_CBN_SELCHANGE(IDC_MACROPARAM,OnPlugParamChanged) + ON_CBN_SELCHANGE(IDC_MACROCC, OnCCChanged) + ON_EN_CHANGE(IDC_EDIT1, OnSFxEditChanged) + ON_EN_CHANGE(IDC_EDIT2, OnZxxEditChanged) + ON_COMMAND_RANGE(ID_PLUGSELECT, ID_PLUGSELECT + NUM_MACROS - 1, OnViewAllParams) //rewbs.patPlugName + ON_COMMAND_RANGE(ID_PLUGSELECT + NUM_MACROS, ID_PLUGSELECT + NUM_MACROS + NUM_MACROS - 1, OnSetSFx) //rewbs.patPlugName +END_MESSAGE_MAP() + + +void CMidiMacroSetup::DoDataExchange(CDataExchange* pDX) +//------------------------------------------------------ +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CModTypeDlg) + DDX_Control(pDX, IDC_COMBO1, m_CbnSFx); + DDX_Control(pDX, IDC_COMBO2, m_CbnSFxPreset); + DDX_Control(pDX, IDC_COMBO3, m_CbnZxxPreset); + DDX_Control(pDX, IDC_COMBO4, m_CbnZxx); + DDX_Control(pDX, IDC_EDIT1, m_EditSFx); + DDX_Control(pDX, IDC_EDIT2, m_EditZxx); + DDX_Control(pDX, IDC_MACROPLUG, m_CbnMacroPlug); + DDX_Control(pDX, IDC_MACROPARAM, m_CbnMacroParam); + DDX_Control(pDX, IDC_MACROCC, m_CbnMacroCC); + //}}AFX_DATA_MAP +} + + +BOOL CMidiMacroSetup::OnInitDialog() +//---------------------------------- +{ + CHAR s[128]; + CDialog::OnInitDialog(); + CheckDlgButton(IDC_CHECK1, m_bEmbed ? BST_CHECKED : BST_UNCHECKED); + m_EditSFx.SetLimitText(MACRO_LENGTH - 1); + m_EditZxx.SetLimitText(MACRO_LENGTH - 1); + + for (UINT isfx=0; isfx<16; isfx++) + { + wsprintf(s, "%d (SF%X)", isfx, isfx); + m_CbnSFx.AddString(s); + } + m_CbnSFx.SetCurSel(0); + for(int i = 0; i < sfx_max; i++) + { + m_CbnSFxPreset.SetItemData(m_CbnSFxPreset.AddString(macroTools.GetMacroName(static_cast<enmParameteredMacroType>(i))), i); + } + OnSFxChanged(); + + for (int cc = MIDICC_start; cc <= MIDICC_end; cc++) + { + wsprintf(s, "CC %02d %s", cc, MidiCCNames[cc]); + m_CbnMacroCC.SetItemData(m_CbnMacroCC.AddString(s), cc); + } + + for (int zxx = 0; zxx < 128; zxx++) + { + wsprintf(s, "Z%02X", zxx | 0x80); + m_CbnZxx.AddString(s); + } + m_CbnZxx.SetCurSel(0); + m_CbnZxxPreset.AddString("Custom"); + m_CbnZxxPreset.AddString("Z80-Z8F controls resonance"); + m_CbnZxxPreset.AddString("Z80-ZFF controls resonance"); + m_CbnZxxPreset.AddString("Z80-ZFF controls cutoff"); + m_CbnZxxPreset.AddString("Z80-ZFF controls filter mode"); + m_CbnZxxPreset.AddString("Z80-Z9F controls resonance+mode"); + m_CbnZxxPreset.SetCurSel(macroTools.GetZxxType(m_MidiCfg.szMidiZXXExt)); + UpdateDialog(); + + int offsetx=108, offsety=30, separatorx=4, separatory=2, + height=18, widthMacro=30, widthVal=90, widthType=135, widthBtn=70; + + for (UINT m = 0; m < NUM_MACROS; m++) + { + m_EditMacro[m].Create("", /*BS_FLAT |*/ WS_CHILD | WS_VISIBLE | WS_TABSTOP /*| WS_BORDER*/, + CRect(offsetx, offsety + m * (separatory + height), offsetx + widthMacro, offsety + m * (separatory + height) + height), this, ID_PLUGSELECT + NUM_MACROS + m); + m_EditMacro[m].SetFont(GetFont()); + + m_EditMacroType[m].Create(ES_READONLY | WS_CHILD| WS_VISIBLE | WS_TABSTOP | WS_BORDER, + CRect(offsetx + separatorx + widthMacro, offsety + m* (separatory + height), offsetx + widthMacro + widthType, offsety + m * (separatory + height) + height), this, ID_PLUGSELECT + NUM_MACROS + m); + m_EditMacroType[m].SetFont(GetFont()); + + m_EditMacroValue[m].Create(ES_CENTER | ES_READONLY | WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER, + CRect(offsetx + separatorx + widthType + widthMacro, offsety + m * (separatory + height), offsetx + widthMacro + widthType + widthVal, offsety + m * (separatory + height) + height), this, ID_PLUGSELECT + NUM_MACROS + m); + m_EditMacroValue[m].SetFont(GetFont()); + + m_BtnMacroShowAll[m].Create("Show All...", WS_CHILD | WS_TABSTOP | WS_VISIBLE, + CRect(offsetx + separatorx + widthType + widthMacro + widthVal, offsety + m *(separatory + height), offsetx + widthMacro + widthType + widthVal + widthBtn, offsety + m * (separatory + height) + height), this, ID_PLUGSELECT + m); + m_BtnMacroShowAll[m].SetFont(GetFont()); + } + UpdateMacroList(); + + for (UINT plug=0; plug<MAX_MIXPLUGINS; plug++) + { + PSNDMIXPLUGIN p = &(m_SndFile.m_MixPlugins[plug]); + StringFixer::SetNullTerminator(p->Info.szLibraryName); + if (p->Info.szLibraryName[0]) + { + wsprintf(s, "FX%d: %s", plug+1, p->Info.szName); + m_CbnMacroPlug.SetItemData(m_CbnMacroPlug.AddString(s), plug); + } + } + m_CbnMacroPlug.SetCurSel(0); + OnPlugChanged(); + return FALSE; +} + + +// macro == -1 for updating all macros at once +void CMidiMacroSetup::UpdateMacroList(int macro) +//---------------------------------------------- +{ + if (!m_EditMacro[0]) + { + // GUI not yet initialized + return; + } + + int start, end; + + if (macro >= 0 && macro < 16) + { + start = end = macro; + } else + { + start = 0; + end = NUM_MACROS - 1; + } + + CString s; + const int selectedMacro = m_CbnSFx.GetCurSel(); + + for (int m = start; m <= end; m++) + { + // SFx + s.Format("SF%X", m); + m_EditMacro[m].SetWindowText(s); + + // Macro value: + CString macroText = m_MidiCfg.szMidiSFXExt[m]; + m_EditMacroValue[m].SetWindowText(macroText); + m_EditMacroValue[m].SetBackColor(m == selectedMacro ? RGB(200, 200, 225) : RGB(245, 245, 245)); + + // Macro Type: + const enmParameteredMacroType macroType = macroTools.GetMacroType(macroText); + switch (macroType) + { + case sfx_cc: + s.Format("MIDI CC %d", macroTools.MacroToMidiCC(macroText)); + break; + + case sfx_plug: + s.Format("Control Plugin Param %d", macroTools.MacroToPlugParam(macroText)); + break; + + default: + s = macroTools.GetMacroName(macroType); + break; + } + m_EditMacroType[m].SetWindowText(s); + m_EditMacroType[m].SetBackColor(m == selectedMacro ? RGB(200,200,225) : RGB(245,245,245) ); + + // Param details button: + m_BtnMacroShowAll[m].ShowWindow((macroType == sfx_plug) ? SW_SHOW : SW_HIDE); + } +} + + +void CMidiMacroSetup::UpdateDialog() +//---------------------------------- +{ + CHAR s[MACRO_LENGTH]; + UINT sfx, sfx_preset, zxx; + + sfx = m_CbnSFx.GetCurSel(); + sfx_preset = m_CbnSFxPreset.GetItemData(m_CbnSFxPreset.GetCurSel()); + if (sfx < 16) + { + ToggleBoxes(sfx_preset, sfx); + memcpy(s, m_MidiCfg.szMidiSFXExt[sfx], MACRO_LENGTH); + StringFixer::SetNullTerminator(s); + m_EditSFx.SetWindowText(s); + } + + zxx = m_CbnZxx.GetCurSel(); + if (zxx < 0x80) + { + memcpy(s, m_MidiCfg.szMidiZXXExt[zxx], MACRO_LENGTH); + StringFixer::SetNullTerminator(s); + m_EditZxx.SetWindowText(s); + } + UpdateMacroList(); +} + + +void CMidiMacroSetup::OnSetAsDefault() +//------------------------------------ +{ + theApp.SetDefaultMidiMacro(&m_MidiCfg); +} + + +void CMidiMacroSetup::OnResetCfg() +//-------------------------------- +{ + theApp.GetDefaultMidiMacro(&m_MidiCfg); + m_CbnZxxPreset.SetCurSel(0); + OnSFxChanged(); +} + + +void CMidiMacroSetup::OnMacroHelp() +//--------------------------------- +{ + Reporting::Information(_T("Valid characters in macros:\n\n" + "0-9, A-F - Raw hex data (4-Bit value)\n" + "c - MIDI channel (4-Bit value)\n" + "n - Note value\n\n" + "v - Note velocity\n" + "u - Computed note volume (including envelopes)\n\n" + "x - Note panning\n" + "y - Computed panning (including envelopes)\n\n" + "a - High byte of bank select\n" + "b - Low byte of bank select\n" + "p - Program select\n\n" + "z - Zxx parameter (00-7F)\n\n" + "Macros can be up to 31 characters long and contain multiple MIDI messages. SysEx messages are automatically terminated if not specified by the user."), + _T("OpenMPT MIDI Macro quick reference")); +} + + +void CMidiMacroSetup::OnEmbedMidiCfg() +//------------------------------------ +{ + m_bEmbed = IsDlgButtonChecked(IDC_CHECK1) != BST_UNCHECKED; +} + + +void CMidiMacroSetup::OnSFxChanged() +//---------------------------------- +{ + UINT sfx = m_CbnSFx.GetCurSel(); + if (sfx < 16) + { + CString macroText; + memcpy(macroText.GetBuffer(MACRO_LENGTH), m_MidiCfg.szMidiSFXExt[sfx], MACRO_LENGTH); + int preset = macroTools.GetMacroType(macroText); + m_CbnSFxPreset.SetCurSel(preset); + } + UpdateDialog(); +} + + +void CMidiMacroSetup::OnSFxPresetChanged() +//---------------------------------------- +{ + UINT sfx = m_CbnSFx.GetCurSel(); + enmParameteredMacroType sfx_preset = static_cast<enmParameteredMacroType>(m_CbnSFxPreset.GetItemData(m_CbnSFxPreset.GetCurSel())); + + if (sfx < 16) + { + if(sfx_preset != sfx_custom) + { + strcpy(m_MidiCfg.szMidiSFXExt[sfx], macroTools.CreateParameteredMacroFromType(sfx_preset)); + } + UpdateDialog(); + } +} + + +void CMidiMacroSetup::OnZxxPresetChanged() +//---------------------------------------- +{ + enmFixedMacroType zxx_preset = static_cast<enmFixedMacroType>(m_CbnZxxPreset.GetCurSel()); + + if (zxx_preset != zxx_custom) + { + macroTools.CreateZxxFromType(m_MidiCfg.szMidiZXXExt, zxx_preset); + UpdateDialog(); + } +} + + +void CMidiMacroSetup::OnSFxEditChanged() +//-------------------------------------- +{ + UINT sfx = m_CbnSFx.GetCurSel(); + if (sfx < 16) + { + if(ValidateMacroString(m_EditSFx, m_MidiCfg.szMidiSFXExt[sfx], true)) + { + CHAR s[MACRO_LENGTH]; + MemsetZero(s); + m_EditSFx.GetWindowText(s, MACRO_LENGTH); + StringFixer::SetNullTerminator(s); + memcpy(m_MidiCfg.szMidiSFXExt[sfx], s, MACRO_LENGTH); + + int sfx_preset = macroTools.GetMacroType(m_MidiCfg.szMidiSFXExt[sfx]); + m_CbnSFxPreset.SetCurSel(sfx_preset); + ToggleBoxes(sfx_preset, sfx); + UpdateMacroList(sfx); + } + } +} + + +void CMidiMacroSetup::OnZxxEditChanged() +//-------------------------------------- +{ + UINT zxx = m_CbnZxx.GetCurSel(); + if (zxx < 128) + { + if(ValidateMacroString(m_EditZxx, m_MidiCfg.szMidiZXXExt[zxx], false)) + { + CHAR s[MACRO_LENGTH]; + MemsetZero(s); + m_EditZxx.GetWindowText(s, MACRO_LENGTH); + StringFixer::SetNullTerminator(s); + memcpy(m_MidiCfg.szMidiZXXExt[zxx], s, MACRO_LENGTH); + } + } +} + +void CMidiMacroSetup::OnSetSFx(UINT id) +//------------------------------------- +{ + m_CbnSFx.SetCurSel(id - (ID_PLUGSELECT + NUM_MACROS)); + OnSFxChanged(); +} + +void CMidiMacroSetup::OnViewAllParams(UINT id) +//-------------------------------------------- +{ + CString message, plugName, line; + int sfx = id - ID_PLUGSELECT; + int param = macroTools.MacroToPlugParam(m_MidiCfg.szMidiSFXExt[sfx]); + CVstPlugin *pVstPlugin; + message.Format("These are the parameters that can be controlled by macro SF%X:\n\n", sfx); + + for(PLUGINDEX plug = 0; plug < MAX_MIXPLUGINS; plug++) + { + plugName = m_SndFile.m_MixPlugins[plug].Info.szName; + if(m_SndFile.m_MixPlugins[plug].Info.dwPluginId1 != 0) + { + pVstPlugin = (CVstPlugin*) m_SndFile.m_MixPlugins[plug].pMixPlugin; + if(pVstPlugin && param <= pVstPlugin->GetNumParameters()) + { + line.Format("FX%d: %s\t %s\n", plug + 1, plugName, pVstPlugin->GetFormattedParamName(param)); + message += line; + } + } + } + + Reporting::Notification(message, "Macro -> Params"); +} + +void CMidiMacroSetup::OnPlugChanged() +//----------------------------------- +{ + int plug = m_CbnMacroPlug.GetItemData(m_CbnMacroPlug.GetCurSel()); + + if (plug < 0 || plug > MAX_MIXPLUGINS) + return; + + PSNDMIXPLUGIN pPlugin = &m_SndFile.m_MixPlugins[plug]; + CVstPlugin *pVstPlugin = (pPlugin->pMixPlugin) ? (CVstPlugin *)pPlugin->pMixPlugin : NULL; + + if (pVstPlugin) + { + m_CbnMacroParam.SetRedraw(FALSE); + m_CbnMacroParam.Clear(); + m_CbnMacroParam.ResetContent(); + AddPluginParameternamesToCombobox(m_CbnMacroParam, *pVstPlugin); + m_CbnMacroParam.SetRedraw(TRUE); + + int param = macroTools.MacroToPlugParam(m_MidiCfg.szMidiSFXExt[m_CbnSFx.GetCurSel()]); + m_CbnMacroParam.SetCurSel(param); + } + //OnPlugParamChanged(); +} + +void CMidiMacroSetup::OnPlugParamChanged() +//---------------------------------------- +{ + CString macroText; + UINT param = m_CbnMacroParam.GetItemData(m_CbnMacroParam.GetCurSel()); + + if(param < 128) + { + macroText.Format("F0F0%02Xz",param + 128); + m_EditSFx.SetWindowText(macroText); + } else if(param < 384) + { + macroText.Format("F0F1%02Xz",param - 128); + m_EditSFx.SetWindowText(macroText); + } else + { + Reporting::Notification("Only parameters 0 to 383 can be controlled using MIDI Macros. Use Parameter Control Events to automate higher parameters."); + } +} + +void CMidiMacroSetup::OnCCChanged() +//--------------------------------- +{ + CString macroText; + UINT cc = m_CbnMacroCC.GetItemData(m_CbnMacroCC.GetCurSel()); + macroText.Format("Bc%02Xz", cc & 0xFF); + m_EditSFx.SetWindowText(macroText); +} + +void CMidiMacroSetup::ToggleBoxes(UINT sfx_preset, UINT sfx) +//---------------------------------------------------------- +{ + + if (sfx_preset == sfx_plug) + { + m_CbnMacroCC.ShowWindow(FALSE); + m_CbnMacroPlug.ShowWindow(TRUE); + m_CbnMacroParam.ShowWindow(TRUE); + m_CbnMacroPlug.EnableWindow(TRUE); + m_CbnMacroParam.EnableWindow(TRUE); + SetDlgItemText(IDC_GENMACROLABEL, "Plug/Param"); + m_CbnMacroParam.SetCurSel(macroTools.MacroToPlugParam(m_MidiCfg.szMidiSFXExt[sfx])); + } else + { + m_CbnMacroPlug.EnableWindow(FALSE); + m_CbnMacroParam.EnableWindow(FALSE); + } + + if (sfx_preset == sfx_cc) + { + m_CbnMacroCC.EnableWindow(TRUE); + m_CbnMacroCC.ShowWindow(TRUE); + m_CbnMacroPlug.ShowWindow(FALSE); + m_CbnMacroParam.ShowWindow(FALSE); + SetDlgItemText(IDC_GENMACROLABEL, "MIDI CC"); + m_CbnMacroCC.SetCurSel(macroTools.MacroToMidiCC(m_MidiCfg.szMidiSFXExt[sfx])); + } else + { + m_CbnMacroCC.EnableWindow(FALSE); + } + + //m_EditSFx.EnableWindow((sfx_preset == sfx_unused) ? FALSE : TRUE); + +} + + +bool CMidiMacroSetup::ValidateMacroString(CEdit &wnd, char *lastMacro, bool isParametric) +//--------------------------------------------------------------------------------------- +{ + CString macroStr; + wnd.GetWindowText(macroStr); + + bool allowed = true, caseChange = false; + for(int i = 0; i < macroStr.GetLength(); i++) + { + char c = macroStr.GetAt(i); + if(c == 'k' || c == 'K') // Previously, 'K' was used for MIDI channel + { + caseChange = true; + macroStr.SetAt(i, 'c'); + } else if(c >= 'd' && c <= 'f') // abc have special meanings, but def can be fixed + { + caseChange = true; + macroStr.SetAt(i, c - 'a' + 'A'); + } else if(c == 'N' || c == 'V' || c == 'U' || c == 'X' || c == 'Y' || c == 'Z' || c == 'P') + { + caseChange = true; + macroStr.SetAt(i, c - 'A' + 'a'); + } else if(!( + (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'c') || + (c == 'v' || c == 'u' || c == 'x' || c == 'y' || c == 'p' || c == 'n' || c == ' ') || + (c == 'z' && isParametric))) + { + allowed = false; + break; + } + } + + if(!allowed) + { + // Replace text and keep cursor position if we just typed in an invalid character + int start, end; + wnd.GetSel(start, end); + wnd.SetWindowText(lastMacro); + wnd.SetSel(start - 1, end - 1, true); + MessageBeep(MB_OK); + return false; + } + else + { + if(caseChange) + { + // Replace text and keep cursor position if there was a case conversion + int start, end; + wnd.GetSel(start, end); + wnd.SetWindowText(macroStr); + wnd.SetSel(start, end, true); + } + return true; + } +} Added: trunk/OpenMPT/mptrack/MIDIMacroDialog.h =================================================================== --- trunk/OpenMPT/mptrack/MIDIMacroDialog.h (rev 0) +++ trunk/OpenMPT/mptrack/MIDIMacroDialog.h 2011-11-18 22:52:19 UTC (rev 1138) @@ -0,0 +1,65 @@ +/* + * MIDIMacroDialog.h + * ----------------- + * Purpose: Header file for MIDI macro configuration dialog implementation + * Notes : (currently none) + * Authors: OpenMPT Devs + */ + +#pragma once +#ifndef MIDIMACRODIALOG_H +#define MIDIMACRODIALOG_H +//class CColourEdit; +#include "ColourEdit.h" +#include "../soundlib/MIDIMacros.h" + + +//=================================== +class CMidiMacroSetup: public CDialog +//=================================== +{ +public: + CMidiMacroSetup(CSoundFile &sndFile, CWnd *parent = NULL) : CDialog(IDD_MIDIMACRO, parent), m_SndFile(sndFile), macroTools(sndFile), m_MidiCfg(sndFile.m_MidiCfg) + { + m_bEmbed = (m_SndFile.m_dwSongFlags & SONG_EMBEDMIDICFG) != 0; + } + + bool m_bEmbed; + MODMIDICFG m_MidiCfg; + + +protected: + CComboBox m_CbnSFx, m_CbnSFxPreset, m_CbnZxx, m_CbnZxxPreset, m_CbnMacroPlug, m_CbnMacroParam, m_CbnMacroCC; + CEdit m_EditSFx, m_EditZxx; + CColourEdit m_EditMacroValue[NUM_MACROS], m_EditMacroType[NUM_MACROS]; //rewbs.macroGUI + CButton m_EditMacro[NUM_MACROS], m_BtnMacroShowAll[NUM_MACROS]; + + CSoundFile &m_SndFile; + MIDIMacroTools macroTools; + + bool ValidateMacroString(CEdit &wnd, char *lastMacro, bool isParametric); + + void UpdateMacroList(int macro=-1); + void ToggleBoxes(UINT preset, UINT sfx); + virtual BOOL OnInitDialog(); + virtual void DoDataExchange(CDataExchange* pDX); + afx_msg void UpdateDialog(); + afx_msg void OnSetAsDefault(); + afx_msg void OnResetCfg(); + afx_msg void OnMacroHelp(); + afx_msg void OnEmbedMidiCfg(); + afx_msg void OnSFxChanged(); + afx_msg void OnSFxPresetChanged(); + afx_msg void OnZxxPresetChanged(); + afx_msg void OnSFxEditChanged(); + afx_msg void OnZxxEditChanged(); + afx_msg void OnPlugChanged(); + afx_msg void OnPlugParamChanged(); + afx_msg void OnCCChanged(); + + afx_msg void OnViewAllParams(UINT id); + afx_msg void OnSetSFx(UINT id); + DECLARE_MESSAGE_MAP() +}; + +#endif // MIDIMACRODIALOG_H Deleted: trunk/OpenMPT/mptrack/MIDIMacros.cpp =================================================================== --- trunk/OpenMPT/mptrack/MIDIMacros.cpp 2011-11-18 22:30:48 UTC (rev 1137) +++ trunk/OpenMPT/mptrack/MIDIMacros.cpp 2011-11-18 22:52:19 UTC (rev 1138) @@ -1,785 +0,0 @@ -/* - * MIDIMacros.cpp - * -------------- - * Purpose: Helper functions / classes for MIDI Macro functionality, including the MIDI Macro editor. - * Notes : (currently none) - * Authors: OpenMPT Devs - */ - -#include "stdafx.h" -#include "../common/Reporting.h" -#include "../common/StringFixer.h" -#include "Mainfrm.h" -#include "mptrack.h" -#include "Vstplug.h" -#include "resource.h" -#include "MIDIMacros.h" - - - -enmParameteredMacroType MIDIMacroTools::GetMacroType(CString value) -//----------------------------------------------------------------- -{ - value.Remove(' '); - if (value.Compare("") == 0) return sfx_unused; - if (value.Compare("F0F000z") == 0) return sfx_cutoff; - if (value.Compare("F0F001z") == 0) return sfx_reso; - if (value.Compare("F0F002z") == 0) return sfx_mode; - if (value.Compare("F0F003z") == 0) return sfx_drywet; - if (value.Compare("Bc00z") >= 0 && value.Compare("BcFFz") <= 0 && value.GetLength() == 5) - return sfx_cc; - if (value.Compare("F0F080z") >= 0 && value.Compare("F0F1FFz") <= 0 && value.GetLength() == 7) - return sfx_plug; - return sfx_custom; // custom / unknown -} - - -// Returns macro description including plugin parameter / MIDI CC information -CString MIDIMacroTools::GetMacroName(CString value, PLUGINDEX plugin) const -//------------------------------------------------------------------------- -{ - const enmParameteredMacroType macroType = GetMacroType(value); - - switch(macroType) - { - case sfx_plug: - { - const int param = MacroToPlugParam(value); - CString paramName; - - if(plugin < MAX_MIXPLUGINS) - { - CVstPlugin *pPlug = reinterpret_cast<CVstPlugin *>(m_SndFile.m_MixPlugins[plugin].pMixPlugin); - if(pPlug) - { - paramName = pPlug->GetParamName(param); - } - if (paramName.IsEmpty()) - { - return _T("N/A"); - } - - CString formattedName; - formattedName.Format(_T("Param %d (%s)"), param, paramName); - return CString(formattedName); - } else - { - return _T("N/A - No Plugin"); - } - } - - case sfx_cc: - { - CString formattedCC; - formattedCC.Format(_T("MIDI CC %d"), MacroToMidiCC(value)); - return formattedCC; - } - - default: - return GetMacroName(macroType); - } -} - - -// Returns generic macro description. -CString MIDIMacroTools::GetMacroName(enmParameteredMacroType macro) -//----------------------------------------------------------------- -{ - switch(macro) - { - case sfx_unused: - return _T("Unused"); - case sfx_cutoff: - return _T("Set Filter Cutoff"); - case sfx_reso: - return _T("Set Filter Resonance"); - case sfx_mode: - return _T("Set Filter Mode"); - case sfx_drywet: - return _T("Set Plugin Dry/Wet Ratio"); - case sfx_plug: - return _T("Control Plugin Parameter..."); - case sfx_cc: - return _T("MIDI CC..."); - case sfx_custom: - default: - return _T("Custom"); - } -} - - -int MIDIMacroTools::MacroToPlugParam(CString macro) -//------------------------------------------------- -{ - macro.Remove(' '); - int code=0; - char* param = (char *) (LPCTSTR) macro; - param += 4; - if ((param[0] >= '0') && (param[0] <= '9')) code = (param[0] - '0') << 4; else - if ((param[0] >= 'A') && (param[0] <= 'F')) code = (param[0] - 'A' + 0x0A) << 4; - if ((param[1] >= '0') && (param[1] <= '9')) code += (param[1] - '0'); else - if ((param[1] >= 'A') && (param[1] <= 'F')) code += (param[1] - 'A' + 0x0A); - - if (macro.GetLength() >= 4 && macro.GetAt(3) == '0') - return (code - 128); - else - return (code + 128); -} - - -int MIDIMacroTools::MacroToMidiCC(CString macro) -//---------------------------------------------- -{ - macro.Remove(' '); - int code=0; - char* param = (char *) (LPCTSTR) macro; - param += 2; - if ((param[0] >= '0') && (param[0] <= '9')) code = (param[0] - '0') << 4; else - if ((param[0] >= 'A') && (param[0] <= 'F')) code = (param[0] - 'A' + 0x0A) << 4; - if ((param[1] >= '0') && (param[1] <= '9')) code += (param[1] - '0'); else - if ((param[1] >= 'A') && (param[1] <= 'F')) code += (param[1] - 'A' + 0x0A); - - return code; -} - - -int MIDIMacroTools::FindMacroForParam(long param) const -//----------------------------------------------------- -{ - for (size_t macro = 0; macro < NUM_MACROS; macro++) - { - CString macroString = m_SndFile.m_MidiCfg.szMidiSFXExt[macro]; - if (GetMacroType(macroString) == sfx_plug && MacroToPlugParam(macroString) == param) - { - return macro; - } - } - - return -1; -} - - -// Retrieve Zxx (Z80-ZFF) type from current macro configuration -enmFixedMacroType MIDIMacroTools::GetZxxType(const char (&szMidiZXXExt)[128][MACRO_LENGTH]) -//----------------------------------------------------------------------------------------- -{ - // Compare with all possible preset patterns - for(size_t i = 1; i < zxx_max; i++) - { - // Prepare pattern to compare - char szPatterns[128][MACRO_LENGTH]; - CreateZxxFromType(szPatterns, static_cast<enmFixedMacroType>(i)); - - bool bFound = true; - for(size_t j = 0; j < 128; j++) - { - if(strncmp(szPatterns[j], szMidiZXXExt[j], MACRO_LENGTH)) - { - bFound = false; - break; - } - } - if(bFound) return static_cast<enmFixedMacroType>(i); - } - return zxx_custom; // Custom setup -} - - -// Create Zxx (Z80 - ZFF) from one out of five presets -void MIDIMacroTools::CreateZxxFromType(char (&szMidiZXXExt)[128][MACRO_LENGTH], enmFixedMacroType iZxxType) -//--------------------------------------------------------------------------------------------------------- -{ - for(size_t i = 0; i < 128; i++) - { - switch(iZxxType) - { - case zxx_reso4Bit: - // Type 1 - Z80 - Z8F controls resonance - if (i < 16) wsprintf(szMidiZXXExt[i], "F0F001%02X", i * 8); - else strcpy(szMidiZXXExt[i], ""); - break; - - case zxx_reso7Bit: - // Type 2 - Z80 - ZFF controls resonance - wsprintf(szMidiZXXExt[i], "F0F001%02X", i); - break; - - case zxx_cutoff: - // Type 3 - Z80 - ZFF controls cutoff - wsprintf(szMidiZXXExt[i], "F0F000%02X", i); - break; - - case zxx_mode: - // Type 4 - Z80 - ZFF controls filter mode - wsprintf(szMidiZXXExt[i], "F0F002%02X", i); - break; - - case zxx_resomode: - // Type 5 - Z80 - Z9F controls resonance + filter mode - if (i < 16) wsprintf(szMidiZXXExt[i], "F0F001%02X", i * 8); - else if (i < 32) wsprintf(szMidiZXXExt[i], "F0F002%02X", (i - 16) * 8); - else strcpy(szMidiZXXExt[i], ""); - break; - } - } -} - - -// Check if the MIDI Macro configuration used is the default one, -// i.e. the configuration that is assumed when loading a file that has no macros embedded. -bool MIDIMacroTools::IsMacroDefaultSetupUsed() const -//-------------------------------------------------- -{ - // TODO - Global macros - - // SF0: Z00-Z7F controls cutoff - if(GetMacroType(m_SndFile.m_MidiCfg.szMidiSFXExt[0]) != sfx_cutoff) - { - return false; - } - // Z80-Z8F controls resonance - if(GetZxxType(m_SndFile.m_MidiCfg.szMidiZXXExt) != zxx_reso4Bit) - { - return false; - } - // All other parametered macros are unused - for(size_t i = 1; i < NUM_MACROS; i++) - { - if(GetMacroType(m_SndFile.m_MidiCfg.szMidiSFXExt[i]) != sfx_unused) - { - return false; - } - } - return true; -} - - -#ifdef MODPLUG_TRACKER - -//////////////////////////////////////////////////////////////////////// -// MIDI Macro Configuration Dialog - -BEGIN_MESSAGE_MAP(CMidiMacroSetup, CDialog) - ON_COMMAND(IDC_CHECK1, OnEmbedMidiCfg) - ON_COMMAND(IDC_BUTTON1, OnSetAsDefault) - ON_COMMAND(IDC_BUTTON2, OnResetCfg) - ON_COMMAND(IDC_BUTTON3, OnMacroHelp) - ON_CBN_SELCHANGE(IDC_COMBO1, OnSFxChanged) - ON_CBN_SELCHANGE(IDC_COMBO2, OnSFxPresetChanged) - ON_CBN_SELCHANGE(IDC_COMBO3, OnZxxPresetChanged) - ON_CBN_SELCHANGE(IDC_COMBO4, UpdateDialog) - ON_CBN_SELCHANGE(IDC_MACROPLUG, OnPlugChanged) - ON_CBN_SELCHANGE(IDC_MACROPARAM,OnPlugParamChanged) - ON_CBN_SELCHANGE(IDC_MACROCC, OnCCChanged) - ON_EN_CHANGE(IDC_EDIT1, OnSFxEditChanged) - ON_EN_CHANGE(IDC_EDIT2, OnZxxEditChanged) - ON_COMMAND_RANGE(ID_PLUGSELECT, ID_PLUGSELECT + NUM_MACROS - 1, OnViewAllParams) //rewbs.patPlugName - ON_COMMAND_RANGE(ID_PLUGSELECT + NUM_MACROS, ID_PLUGSELECT + NUM_MACROS + NUM_MACROS - 1, OnSetSFx) //rewbs.patPlugName -END_MESSAGE_MAP() - - -void CMidiMacroSetup::DoDataExchange(CDataExchange* pDX) -//------------------------------------------------------ -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CModTypeDlg) - DDX_Control(pDX, IDC_COMBO1, m_CbnSFx); - DDX_Control(pDX, IDC_COMBO2, m_CbnSFxPreset); - DDX_Control(pDX, IDC_COMBO3, m_CbnZxxPreset); - DDX_Control(pDX, IDC_COMBO4, m_CbnZxx); - DDX_Control(pDX, IDC_EDIT1, m_EditSFx); - DDX_Control(pDX, IDC_EDIT2, m_EditZxx); - DDX_Control(pDX, IDC_MACROPLUG, m_CbnMacroPlug); - DDX_Control(pDX, IDC_MACROPARAM, m_CbnMacroParam); - DDX_Control(pDX, IDC_MACROCC, m_CbnMacroCC); - //}}AFX_DATA_MAP -} - - -BOOL CMidiMacroSetup::OnInitDialog() -//---------------------------------- -{ - CHAR s[128]; - CDialog::OnInitDialog(); - CheckDlgButton(IDC_CHECK1, m_bEmbed ? BST_CHECKED : BST_UNCHECKED); - m_EditSFx.SetLimitText(MACRO_LENGTH - 1); - m_EditZxx.SetLimitText(MACRO_LENGTH - 1); - - for (UINT isfx=0; isfx<16; isfx++) - { - wsprintf(s, "%d (SF%X)", isfx, isfx); - m_CbnSFx.AddString(s); - } - m_CbnSFx.SetCurSel(0); - for(int i = 0; i < sfx_max; i++) - { - m_CbnSFxPreset.SetItemData(m_CbnSFxPreset.AddString(macroTools.GetMacroName(static_cast<enmParameteredMacroType>(i))), i); - } - OnSFxChanged(); - - for (int cc = MIDICC_start; cc <= MIDICC_end; cc++) - { - wsprintf(s, "CC %02d %s", cc, MidiCCNames[cc]); - m_CbnMacroCC.SetItemData(m_CbnMacroCC.AddString(s), cc); - } - - for (int zxx = 0; zxx < 128; zxx++) - { - wsprintf(s, "Z%02X", zxx | 0x80); - m_CbnZxx.AddString(s); - } - m_CbnZxx.SetCurSel(0); - m_CbnZxxPreset.AddString("Custom"); - m_CbnZxxPreset.AddString("Z80-Z8F controls resonance"); - m_CbnZxxPreset.AddString("Z80-ZFF controls resonance"); - m_CbnZxxPreset.AddString("Z80-ZFF controls cutoff"); - m_CbnZxxPreset.AddString("Z80-ZFF controls filter mode"); - m_CbnZxxPreset.AddString("Z80-Z9F controls resonance+mode"); - m_CbnZxxPreset.SetCurSel(macroTools.GetZxxType(m_MidiCfg.szMidiZXXExt)); - UpdateDialog(); - - int offsetx=108, offsety=30, separatorx=4, separatory=2, - height=18, widthMacro=30, widthVal=90, widthType=135, widthBtn=70; - - for (UINT m = 0; m < NUM_MACROS; m++) - { - m_EditMacro[m].Create("", /*BS_FLAT |*/ WS_CHILD | WS_VISIBLE | WS_TABSTOP /*| WS_BORDER*/, - CRect(offsetx, offsety + m * (separatory + height), offsetx + widthMacro, offsety + m * (separatory + height) + height), this, ID_PLUGSELECT + NUM_MACROS + m); - m_EditMacro[m].SetFont(GetFont()); - - m_EditMacroType[m].Create(ES_READONLY | WS_CHILD| WS_VISIBLE | WS_TABSTOP | WS_BORDER, - CRect(offsetx + separatorx + widthMacro, offsety + m* (separatory + height), offsetx + widthMacro + widthType, offsety + m * (separatory + height) + height), this, ID_PLUGSELECT + NUM_MACROS + m); - m_EditMacroType[m].SetFont(GetFont()); - - m_EditMacroValue[m].Create(ES_CENTER | ES_READONLY | WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER, - CRect(offsetx + separatorx + widthType + widthMacro, offsety + m * (separatory + height), offsetx + widthMacro + widthType + widthVal, offsety + m * (separatory + height) + height), this, ID_PLUGSELECT + NUM_MACROS + m); - m_EditMacroValue[m].SetFont(GetFont()); - - m_BtnMacroShowAll[m].Create("Show All...", WS_CHILD | WS_TABSTOP | WS_VISIBLE, - CRect(offsetx + separatorx + widthType + widthMacro + widthVal, offsety + m *(separatory + height), offsetx + widthMacro + widthType + widthVal + widthBtn, offsety + m * (separatory + height) + height), this, ID_PLUGSELECT + m); - m_BtnMacroShowAll[m].SetFont(GetFont()); - } - UpdateMacroList(); - - for (UINT plug=0; plug<MAX_MIXPLUGINS; plug++) - { - PSNDMIXPLUGIN p = &(m_SndFile.m_MixPlugins[plug]); - StringFixer::SetNullTerminator(p->Info.szLibraryName); - if (p->Info.szLibraryName[0]) - { - wsprintf(s, "FX%d: %s", plug+1, p->Info.szName); - m_CbnMacroPlug.SetItemData(m_CbnMacroPlug.AddString(s), plug); - } - } - m_CbnMacroPlug.SetCurSel(0); - OnPlugChanged(); - return FALSE; -} - - -// macro == -1 for updating all macros at once -void CMidiMacroSetup::UpdateMacroList(int macro) -//---------------------------------------------- -{ - if (!m_EditMacro[0]) - { - // GUI not yet initialized - return; - } - - int start, end; - - if (macro >= 0 && macro < 16) - { - start = end = macro; - } else - { - start = 0; - end = NUM_MACROS - 1; - } - - CString s; - const int selectedMacro = m_CbnSFx.GetCurSel(); - - for (int m = start; m <= end; m++) - { - // SFx - s.Format("SF%X", m); - m_EditMacro[m].SetWindowText(s); - - // Macro value: - CString macroText = m_MidiCfg.szMidiSFXExt[m]; - m_EditMacroValue[m].SetWindowText(macroText); - m_EditMacroValue[m].SetBackColor(m == selectedMacro ? RGB(200, 200, 225) : RGB(245, 245, 245)); - - // Macro Type: - const enmParameteredMacroType macroType = macroTools.GetMacroType(macroText); - switch (macroType) - { - case sfx_cc: - s.Format("MIDI CC %d", macroTools.MacroToMidiCC(macroText)); - break; - - case sfx_plug: - s.Format("Control Plugin Param %d", macroTools.MacroToPlugParam(macroText)); - break; - - default: - s = macroTools.GetMacroName(macroType); - break; - } - m_EditMacroType[m].SetWindowText(s); - m_EditMacroType[m].SetBackColor(m == selectedMacro ? RGB(200,200,225) : RGB(245,245,245) ); - - // Param details button: - m_BtnMacroShowAll[m].ShowWindow((macroType == sfx_plug) ? SW_SHOW : SW_HIDE); - } -} - - -void CMidiMacroSetup::UpdateDialog() -//---------------------------------- -{ - CHAR s[MACRO_LENGTH]; - UINT sfx, sfx_preset, zxx; - - sfx = m_CbnSFx.GetCurSel(); - sfx_preset = m_CbnSFxPreset.GetItemData(m_CbnSFxPreset.GetCurSel()); - if (sfx < 16) - { - ToggleBoxes(sfx_preset, sfx); - memcpy(s, m_MidiCfg.szMidiSFXExt[sfx], MACRO_LENGTH); - StringFixer::SetNullTerminator(s); - m_EditSFx.SetWindowText(s); - } - - zxx = m_CbnZxx.GetCurSel(); - if (zxx < 0x80) - { - memcpy(s, m_MidiCfg.szMidiZXXExt[zxx], MACRO_LENGTH); - StringFixer::SetNullTerminator(s); - m_EditZxx.SetWindowText(s); - } - UpdateMacroList(); -} - - -void CMidiMacroSetup::OnSetAsDefault() -//------------------------------------ -{ - theApp.SetDefaultMidiMacro(&m_MidiCfg); -} - - -void CMidiMacroSetup::OnResetCfg() -//-------------------------------- -{ - theApp.GetDefaultMidiMacro(&m_MidiCfg); - m_CbnZxxPreset.SetCurSel(0); - OnSFxChanged(); -} - - -void CMidiMacroSetup::OnMacroHelp() -//--------------------------------- -{ - Reporting::Information(_T("Valid characters in macros:\n\n" - "0-9, A-F - Raw hex data (4-Bit value)\n" - "c - MIDI channel (4-Bit value)\n" - "n - Note value\n\n" - "v - Note velocity\n" - "u - Computed note volume (including envelopes)\n\n" - "x - Note panning\n" - "y - Computed panning (including envelopes)\n\n" - "a - High byte of bank select\n" - "b - Low byte of bank select\n" - "p - Program select\n\n" - "z - Zxx parameter (00-7F)\n\n" - "Macros can be up to 31 characters long and contain multiple MIDI messages. SysEx messages are automatically terminated if not specified by the user."), - _T("OpenMPT MIDI Macro quick reference")); -} - - -void CMidiMacroSetup::OnEmbedMidiCfg() -//------------------------------------ -{ - m_bEmbed = IsDlgButtonChecked(IDC_CHECK1) != BST_UNCHECKED; -} - - -void CMidiMacroSetup::OnSFxChanged() -//---------------------------------- -{ - UINT sfx = m_CbnSFx.GetCurSel(); - if (sfx < 16) - { - CString macroText; - memcpy(macroText.GetBuffer(MACRO_LENGTH), m_MidiCfg.szMidiSFXExt[sfx], MACRO_LENGTH); - int preset = macroTools.GetMacroType(macroText); - m_CbnSFxPreset.SetCurSel(preset); - } - UpdateDialog(); -} - - -void CMidiMacroSetup::OnSFxPresetChanged() -//---------------------------------------- -{ - UINT sfx = m_CbnSFx.GetCurSel(); - UINT sfx_preset = m_CbnSFxPreset.GetItemData(m_CbnSFxPreset.GetCurSel()); - - if (sfx < 16) - { - char *pmacro = m_MidiCfg.szMidiSFXExt[sfx]; - switch(sfx_preset) - { - case sfx_unused: strcpy(pmacro, ""); break; // unused - case sfx_cutoff: strcpy(pmacro, "F0F000z"); break; // cutoff - case sfx_reso: strcpy(pmacro, "F0F001z"); break; // reso - case sfx_mode: strcpy(pmacro, "F0F002z"); break; // mode - case sfx_drywet: strcpy(pmacro, "F0F003z"); break; - case sfx_cc: strcpy(pmacro, "Bc00z"); break; // MIDI cc - TODO: get value from other menus - case sfx_plug: strcpy(pmacro, "F0F080z"); break; // plug param - TODO: get value from other menus - case sfx_custom: /*strcpy(pmacro, "z");*/ break; // custom - leave as is. - } - UpdateDialog(); - } -} - - -void CMidiMacroSetup::OnZxxPresetChanged() -//---------------------------------------- -{ - enmFixedMacroType zxx_preset = static_cast<enmFixedMacroType>(m_CbnZxxPreset.GetCurSel()); - - if (zxx_preset != zxx_custom) - { - macroTools.CreateZxxFromType(m_MidiCfg.szMidiZXXExt, zxx_preset); - UpdateDialog(); - } -} - - -void CMidiMacroSetup::OnSFxEditChanged() -//-------------------------------------- -{ - CHAR s[MACRO_LENGTH]; - UINT sfx = m_CbnSFx.GetCurSel(); - if (sfx < 16) - { - if(ValidateMacroString(m_EditSFx, m_MidiCfg.szMidiSFXExt[sfx], true)) - { - MemsetZero(s); - m_EditSFx.GetWindowText(s, MACRO_LENGTH); - StringFixer::SetNullTerminator(s); - memcpy(m_MidiCfg.szMidiSFXExt[sfx], s, MACRO_LENGTH); - - int sfx_preset = macroTools.GetMacroType(m_MidiCfg.szMidiSFXExt[sfx]); - //int param = macroTools.MacroToPlugParam(m_MidiCfg.szMidiSFXExt[sfx]); - - m_CbnSFxPreset.SetCurSel(sfx_preset); - ToggleBoxes(sfx_preset, sfx); - UpdateMacroList(sfx); - } - } -} - - -void CMidiMacroSetup::OnZxxEditChanged() -//-------------------------------------- -{ - CHAR s[MACRO_LENGTH]; - UINT zxx = m_CbnZxx.GetCurSel(); - if (zxx < 128) - { - if(ValidateMacroString(m_EditZxx, m_MidiCfg.szMidiZXXExt[zxx], false)) - { - MemsetZero(s); - m_EditZxx.GetWindowText(s, MACRO_LENGTH); - StringFixer::SetNullTerminator(s); - memcpy(m_MidiCfg.szMidiZXXExt[zxx], s, MACRO_LENGTH); - } - } -} - -void CMidiMacroSetup::OnSetSFx(UINT id) -//------------------------------------- -{ - m_CbnSFx.SetCurSel(id-(ID_PLUGSELECT + NUM_MACROS)); - OnSFxChanged(); -} - -void CMidiMacroSetup::OnViewAllParams(UINT id) -//-------------------------------------------- -{ - CString message, plugName, line; - int sfx = id-ID_PLUGSELECT; - int param = macroTools.MacroToPlugParam(m_MidiCfg.szMidiSFXExt[sfx]); - CVstPlugin *pVstPlugin; - message.Format("These are the parameters that can be controlled by macro SF%X:\n\n",sfx); - - for (UINT plug=0; plug<MAX_MIXPLUGINS; plug++) - { - plugName = m_SndFile.m_MixPlugins[plug].Info.szName; - if (plugName != "") - { - pVstPlugin=(CVstPlugin*) m_SndFile.m_MixPlugins[plug].pMixPlugin; - if (pVstPlugin && param <= pVstPlugin->GetNumParameters()) - { - line.Format("FX%d: %s\t %s\n", plug + 1, plugName, pVstPlugin->GetFormattedParamName(param)); - message += line; - } - } - } - - Reporting::Notification(message, "Macro -> Params"); -} - -void CMidiMacroSetup::OnPlugChanged() -//----------------------------------- -{ - int plug = m_CbnMacroPlug.GetItemData(m_CbnMacroPlug.GetCurSel()); - - if (plug < 0 || plug > MAX_MIXPLUGINS) - return; - - PSNDMIXPLUGIN pPlugin = &m_SndFile.m_MixPlugins[plug]; - CVstPlugin *pVstPlugin = (pPlugin->pMixPlugin) ? (CVstPlugin *)pPlugin->pMixPlugin : NULL; - - if (pVstPlugin) - { - m_CbnMacroParam.SetRedraw(FALSE); - m_CbnMacroParam.Clear(); - m_CbnMacroParam.ResetContent(); - AddPluginParameternamesToCombobox(m_CbnMacroParam, *pVstPlugin); - m_CbnMacroParam.SetRedraw(TRUE); - - int param = macroTools.MacroToPlugParam(m_MidiCfg.szMidiSFXExt[m_CbnSFx.GetCurSel()]); - m_CbnMacroParam.SetCurSel(param); - } - //OnPlugParamChanged(); -} - -void CMidiMacroSetup::OnPlugParamChanged() -//---------------------------------------- -{ - CString macroText; - UINT param = m_CbnMacroParam.GetItemData(m_CbnMacroParam.GetCurSel()); - - if (param < 128) - { - macroText.Format("F0F0%02Xz",param + 128); - m_EditSFx.SetWindowText(macroText); - } else if (param < 384) - { - macroText.Format("F0F1%02Xz",param - 128); - m_EditSFx.SetWindowText(macroText); - } else - { - Reporting::Notification("MPT can only assign macros to parameters 0 to 383. Use Parameter Control Notes to automate higher parameters."); - } -} - -void CMidiMacroSetup::OnCCChanged() -//--------------------------------- -{ - CString macroText; - UINT cc = m_CbnMacroCC.GetItemData(m_CbnMacroCC.GetCurSel()); - macroText.Format("Bc%02Xz", cc & 0xFF); - m_EditSFx.SetWindowText(macroText); -} - -void CMidiMacroSetup::ToggleBoxes(UINT sfx_preset, UINT sfx) -//---------------------------------------------------------- -{ - - if (sfx_preset == sfx_plug) - { - m_CbnMacroCC.ShowWindow(FALSE); - m_CbnMacroPlug.ShowWindow(TRUE); - m_CbnMacroParam.ShowWindow(TRUE); - m_CbnMacroPlug.EnableWindow(TRUE); - m_CbnMacroParam.EnableWindow(TRUE); - SetDlgItemText(IDC_GENMACROLABEL, "Plug/Param"); - m_CbnMacroParam.SetCurSel(macroTools.MacroToPlugParam(m_MidiCfg.szMidiSFXExt[sfx])); - } else - { - m_CbnMacroPlug.EnableWindow(FALSE); - m_CbnMacroParam.EnableWindow(FALSE); - } - - if (sfx_preset == sfx_cc) - { - m_CbnMacroCC.EnableWindow(TRUE); - m_CbnMacroCC.ShowWindow(TRUE); - m_CbnMacroPlug.ShowWindow(FALSE); - m_CbnMacroParam.ShowWindow(FALSE); - SetDlgItemText(IDC_GENMACROLABEL, "MIDI CC"); - m_CbnMacroCC.SetCurSel(macroTools.MacroToMidiCC(m_MidiCfg.szMidiSFXExt[sfx])); - } else - { - m_CbnMacroCC.EnableWindow(FALSE); - } - - //m_EditSFx.EnableWindow((sfx_preset == sfx_unused) ? FALSE : TRUE); - -} - - -bool CMidiMacroSetup::ValidateMacroString(CEdit &wnd, char *lastMacro, bool isParametric) -//--------------------------------------------------------------------------------------- -{ - CString macroStr; - wnd.GetWindowText(macroStr); - - bool allowed = true, caseChange = false; - for(int i = 0; i < macroStr.GetLength(); i++) - { - char c = macroStr.GetAt(i); - if(c == 'k' || c == 'K') // Previously, 'K' was used for MIDI channel - { - caseChange = true; - macroStr.SetAt(i, 'c'); - } else if (c >= 'd' && c <= 'f') // abc have special meanings, but def can be fixed - { - caseChange = true; - macroStr.SetAt(i, c - 'a' + 'A'); - } else if(c == 'N' || c == 'V' || c == 'U' || c == 'X' || c == 'Y' || c == 'Z' || c == 'P') - { - caseChange = true; - macroStr.SetAt(i, c - 'A' + 'a'); - } else if(!( - (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'c') || - (c == 'v' || c == 'u' || c == 'x' || c == 'y' || c == 'p' || c == 'n' || c == ' ') || - (c == 'z' && isParametric))) - { - allowed = false; - break; - } - } - - if(!allowed) - { - // Replace text and keep cursor position if we just typed in an invalid character - int start, end; - wnd.GetSel(start, end); - wnd.SetWindowText(lastMacro); - wnd.SetSel(start - 1, end - 1, true); - MessageBeep(MB_OK); - return false; - } - else - { - if(caseChange) - { - // Replace text and keep cursor position if there was a case conversion - int start, end; - wnd.GetSel(start, end); - wnd.SetWindowText(macroStr); - wnd.SetSel(start, end, true); - } - return true; - } -} - -#endif // MODPLUG_TRACKER Deleted: trunk/OpenMPT/mptrack/MIDIMacros.h =================================================================== --- trunk/OpenMPT/mptrack/MIDIMacros.h 2011-11-18 22:30:48 UTC (rev 1137) +++ trunk/OpenMPT/mptrack/MIDIMacros.h 2011-11-18 22:52:19 UTC (rev 1138) @@ -1,133 +0,0 @@ -/* - * MIDIMacros.h - * ------------ - * Purpose: Header file for MIDI macro helper functions / classes - * Notes : (currently none) - * Authors: OpenMPT Devs - */ - -#pragma once -#ifndef MIDIMACROS_H -#define MIDIMACROS_H - -// parametered macro presets: -enum enmParameteredMacroType -{ - sfx_unused = 0, - sfx_cutoff, // Type 1 - Z00 - Z7F controls resonant filter cutoff - sfx_reso, // Type 2 - Z00 - Z7F controls resonant filter resonance - sfx_mode, // Type 3 - Z00 - Z7F controls resonant filter mode (lowpass / highpass) - sfx_drywet, // Type 4 - Z00 - Z7F controls plugin Dry / Wet ratio - sfx_plug, // Type 5 - Z00 - Z7F controls a plugin parameter - sfx_cc, // Type 6 - Z00 - Z7F controls MIDI CC - sfx_custom, - - sfx_max -}; - - -// fixed macro presets: -enum enmFixedMacroType -{ - zxx_custom = 0, - zxx_reso4Bit, // Type 1 - Z80 - Z8F controls resonant filter resonance - zxx_reso7Bit, // Type 2 - Z80 - ZFF controls resonant filter resonance - zxx_cutoff, // Type 3 - Z80 - ZFF controls resonant filter cutoff - zxx_mode, // Type 4 - Z80 - ZFF controls resonant filter mode (lowpass / highpass) - zxx_resomode, // Type 5 - Z80 - Z9F controls resonance + filter mode - - zxx_max -}; - - -class MIDIMacroTools -{ -protected: - CSoundFile &m_SndFile; - -public: - // Get macro type from a macro string - static enmParameteredMacroType GetMacroType(CString value); - static enmFixedMacroType GetZxxType(const char (&szMidiZXXExt)[128][MACRO_LENGTH]); - - // Translate macro type or macro string to macro name - static CString GetMacroName(enmParameteredMacroType macro); - CString GetMacroName(CString value, PLUGINDEX plugin) const; - - // Extract information from a macro string. - static int MacroToPlugParam(CString value); - static int MacroToMidiCC(CString value); - - // Check if any macro can automate a given plugin parameter - int FindMacroForParam(long param) const; - - // Create a new Zxx macro - static void CreateZxxFromType(char (&szMidiZXXExt)[128][MACRO_LENGTH], enmFixedMacroType iZxxType); - - // Check if a given set of macros is the default IT macro set. - bool IsMacroDefaultSetupUsed() const; - - MIDIMacroTools(CSoundFile &sndFile) : m_SndFile(sndFile) { }; -}; - - -#ifdef MODPLUG_TRACKER - -//////////////////////////////////////////////////////////////////////// -// MIDI Macro Configuration Dialog - -//class CColourEdit; -#include "ColourEdit.h" - - -//=================================== -class CMidiMacroSetup: public CDialog -//=================================== -{ -public: - CMidiMacroSetup(CSoundFile &sndFile, CWnd *parent = NULL) : CDialog(IDD_MIDIMACRO, parent), m_SndFile(sndFile), macroTools(sndFile), m_MidiCfg(sndFile.m_MidiCfg) - { - m_bEmbed = (m_SndFile.m_dwSongFlags & SONG_EMBEDMIDICFG) != 0; - } - - bool m_bEmbed; - MODMIDICFG m_MidiCfg; - - -protected: - CComboBox m_CbnSFx, m_CbnSFxPreset, m_CbnZxx, m_CbnZxxPreset, m_CbnMacroPlug, m_CbnMacroParam, m_CbnMacroCC; - CEdit m_EditSFx, m_EditZxx; - CColourEdit m_EditMacroValue[NUM_MACROS], m_EditMacroType[NUM_MACROS]; //rewbs.macroGUI - CButton m_EditMacro[NUM_MACROS], m_BtnMacroShowAll[NUM_MACROS]; - - CSoundFile &m_SndFile; - MIDIMacroTools macroTools; - - bool ValidateMacroString(CEdit &wnd, char *lastMacro, bool isParametric); - - void UpdateMacroList(int macro=-1); - void ToggleBoxes(UINT preset, UINT sfx); - virtual BOOL OnInitDialog(); - virtual void DoDataExchange(CDataExchange* pDX); - afx_msg void UpdateDialog(); - afx_msg void OnSetAsDefault(); - afx_msg void OnResetCfg(); - afx_msg void OnMacroHelp(); - afx_msg void OnEmbedMidiCfg(); - afx_msg void OnSFxChanged(); - afx_msg void OnSFxPresetChanged(); - afx_msg void OnZxxPresetChanged(); - afx_msg void OnSFxEditChanged(); - afx_msg void OnZxxEditChanged(); - afx_msg void OnPlugChanged(); - afx_msg void OnPlugParamChanged(); - afx_msg void OnCCChanged(); - - afx_msg void OnViewAllParams(UINT id); - afx_msg void OnSetSFx(UINT id); - DECLARE_MESSAGE_MAP() -}; - -#endif // MODPLUG_TRACKER - -#endif // MIDIMACROS_H Modified: trunk/OpenMPT/mptrack/mptrack.vcproj =================================================================== --- trunk/OpenMPT/mptrack/mptrack.vcproj 2011-11-18 22:30:48 UTC (rev 1137) +++ trunk/OpenMPT/mptrack/mptrack.vcproj 2011-11-18 22:52:19 UTC (rev 1138) @@ -280,9 +280,12 @@ RelativePath="..\soundlib\Message.cpp"> </File> <File - RelativePath=".\MIDIMacros.cpp"> + RelativePath=".\MIDIMacroDialog.cpp"> </File> <File + RelativePath=".\soundlib\MIDIMacros.cpp"> + </File> + <File RelativePath=".\MIDIMappingDialog.cpp"> </File> <File @@ -768,9 +771,12 @@ RelativePath="..\soundlib\midi.h"> </File> <File - RelativePath=".\MIDIMacros.h"> + RelativePath=".\MIDIMacroDialog.h"> </File> <File + RelativePath=".\soundlib\MIDIMacros.h"> + </File> + <File RelativePath=".\MIDIMappingDialog.h"> </File> <File Modified: trunk/OpenMPT/mptrack/mptrack_08.vcproj =================================================================== --- trunk/OpenMPT/mptrack/mptrack_08.vcproj 2011-11-18 22:30:48 UTC (rev 1137) +++ trunk/OpenMPT/mptrack/mptrack_08.vcproj 2011-11-18 22:52:19 UTC (rev 1138) @@ -377,6 +377,10 @@ > </File> <File + RelativePath=".\MIDIMacroDialog.cpp" + > + </File> + <File RelativePath="..\soundlib\MIDIMacros.cpp" > </File> @@ -1019,10 +1023,14 @@ > </File> <File - RelativePath=".\MIDIMacros.h" + RelativePath=".\MIDIMacroDialog.h" > </File> <File + RelativePath=".\soundlib\MIDIMacros.h" + > + </File> + <File RelativePath=".\MIDIMappingDialog.h" > </File> Modified: trunk/OpenMPT/mptrack/mptrack_10.vcxproj =================================================================== --- trunk/OpenMPT/mptrack/mptrack_10.vcxproj 2011-11-18 22:30:48 UTC (rev 1137) +++ trunk/OpenMPT/mptrack/mptrack_10.vcxproj 2011-11-18 22:52:19 UTC (rev 1138) @@ -169,6 +169,7 @@ <ItemGroup> <ClCompile Include="..\common\misc_util.cpp" /> <ClCompile Include="..\common\Reporting.cpp" /> + <ClCompile Include="..\soundlib\MIDIMacros.cpp" /> <ClCompile Include="AbstractVstEditor.cpp" /> <ClCompile Include="ACMConvert.cpp" /> <ClCompile Include="ArrayUtils.cpp" /> @@ -204,7 +205,7 @@ <ClCompile Include="mainbar.cpp" /> <ClCompile Include="MainFrm.cpp" /> <ClCompile Include="..\soundlib\Message.cpp" /> - <ClCompile Include="MIDIMacros.cpp" /> + <ClCompile Include="MIDIMacroDialog.cpp" /> <ClCompile Include="MIDIMappingDialog.cpp" /> <ClCompile Include="..\soundlib\mmcmp.cpp" /> <ClCompile Include="..\soundlib\Mmx_mix.cpp" /> @@ -326,10 +327,11 @@ <ClInclude Include="..\common\Reporting.h" /> <ClInclude Include="..\common\StringFixer.h" /> <ClInclude Include="..\common\typedefs.h" /> + <ClInclude Include="..\soundlib\MIDIMacros.h" /> <ClInclude Include="ACMConvert.h" /> <ClInclude Include="Autotune.h" /> <ClInclude Include="ExceptionHandler.h" /> - <ClInclude Include="MIDIMacros.h" /> + <ClInclude Include="MIDIMacroDialog.h" /> <ClInclude Include="PatternRandomizer.h" /> <ClInclude Include="PatternRandomizerGUI.h" /> <ClInclude Include="PatternRandomizerGUIEffect.h" /> Modified: trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters =================================================================== --- trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters 2011-11-18 22:30:48 UTC (rev 1137) +++ trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters 2011-11-18 22:52:19 UTC (rev 1138) @@ -433,7 +433,10 @@ <ClCompile Include="Autotune.cpp"> <Filter>Source Files</Filter> </ClCompile> - <ClCompile Include="MIDIMacros.cpp"> + <ClCompile Include="MIDIMacroDialog.cpp"> + <Filter>Source Files\Dialogs</Filter> + </ClCompile> + <ClCompile Include="..\soundlib\MIDIMacros.cpp"> <Filter>Source Files</Filter> </ClCompile> </ItemGroup> @@ -762,7 +765,10 @@ <ClInclude Include="Autotune.h"> <Filter>Header Files</Filter> </ClInclude> - <ClInclude Include="MIDIMacros.h"> + <ClInclude Include="MIDIMacroDialog.h"> + <Filter>Header Files\Dialogs</Filter> + </ClInclude> + <ClInclude Include="..\soundlib\MIDIMacros.h"> <Filter>Header Files</Filter> </ClInclude> </ItemGroup> Modified: trunk/OpenMPT/mptrack/test/test.cpp =================================================================== --- trunk/OpenMPT/mptrack/test/test.cpp 2011-11-18 22:30:48 UTC (rev 1137) +++ trunk/OpenMPT/mptrack/test/test.cpp 2011-11-18 22:52:19 UTC (rev 1138) @@ -9,7 +9,7 @@ #include "../moddoc.h" #include "../MainFrm.h" #include "../version.h" -#include "../MIDIMacros.h" +#include "../../soundlib/MIDIMacros.h" #include "../../common/misc_util.h" #include "../serialization_utils.h" #include <limits> Modified: trunk/OpenMPT/mptrack/version.h =================================================================== --- trunk/OpenMPT/mptrack/version.h 2011-11-18 22:30:48 UTC (rev 1137) +++ trunk/OpenMPT/mptrack/version.h 2011-11-18 22:52:19 UTC (rev 1138) @@ -15,7 +15,7 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 20 #define VER_MINOR 00 -#define VER_MINORMINOR 53 +#define VER_MINORMINOR 54 //Creates version number from version parts that appears in version string. //For example MAKE_VERSION_NUMERIC(1,17,02,28) gives version number of Added: trunk/OpenMPT/soundlib/MIDIMacros.cpp =================================================================== --- trunk/OpenMPT/soundlib/MIDIMacros.cpp (rev 0) +++ trunk/OpenMPT/soundlib/MIDIMacros.cpp 2011-11-18 22:52:19 UTC (rev 1138) @@ -0,0 +1,291 @@ +/* + * MIDIMacros.cpp + * -------------- + * Purpose: Helper functions / classes for MIDI Macro functionality. + * Notes : (currently none) + * Authors: OpenMPT Devs + */ + +#include "stdafx.h" +#include "midi.h" +#include "Sndfile.h" +#include "MIDIMacros.h" +#ifndef NO_VST +#include "../mptrack/Vstplug.h" +#endif // NO_VST + + +enmParameteredMacroType MIDIMacroTools::GetMacroType(CString value) +//----------------------------------------------------------------- +{ + value.Remove(' '); + for(size_t i = 0; i < sfx_max; i++) + { + enmParameteredMacroType sfx = static_cast<enmParameteredMacroType>(i); + if(sfx != sfx_custom) + { + if(value.Compare(CreateParameteredMacroFromType(sfx)) == 0) return sfx; + } + } + // Special macros with additional "parameter": + if (value.Compare(CreateParameteredMacroFromType(sfx_cc, MIDICC_start)) >= 0 && value.Compare(CreateParameteredMacroFromType(sfx_cc, MIDICC_end)) <= 0 && value.GetLength() == 5) + return sfx_cc; + if (value.Compare(CreateParameteredMacroFromType(sfx_plug, 0)) >= 0 && value.Compare(CreateParameteredMacroFromType(sfx_plug, 0x17F)) <= 0 && value.GetLength() == 7) + return sfx_plug; + return sfx_custom; // custom / unknown +} + + +// Returns macro description including plugin parameter / MIDI CC information +CString MIDIMacroTools::GetMacroName(CString value, PLUGINDEX plugin) const +//------------------------------------------------------------------------- +{ + const enmParameteredMacroType macroType = GetMacroType(value); + + switch(macroType) + { + case sfx_plug: + { + const int param = MacroToPlugParam(value); + CString paramName; + +#ifndef NO_VST + if(plugin < MAX_MIXPLUGINS) + { + CVstPlugin *pPlug = reinterpret_cast<CVstPlugin *>(m_SndFile.m_MixPlugins[plugin].pMixPlugin); + if(pPlug) + { + paramName = pPlug->GetParamName(param); + } + if (paramName.IsEmpty()) + { + return _T("N/A"); + } + + CString formattedName; + formattedName.Format(_T("Param %d (%s)"), param, paramName); + return CString(formattedName); + } else +#endif // NO_VST + { + return _T("N/A - No Plugin"); + } + } + + case sfx_cc: + { + CString formattedCC; + formattedCC.Format(_T("MIDI CC %d"), MacroToMidiCC(value)); + return formattedCC; + } + + default: + return GetMacroName(macroType); + } +} + + +// Returns generic macro description. +CString MIDIMacroTools::GetMacroName(enmParameteredMacroType macro) +//----------------------------------------------------------------- +{ + switch(macro) + { + case sfx_unused: + return _T("Unused"); + case sfx_cutoff: + return _T("Set Filter Cutoff"); + case sfx_reso: + return _T("Set Filter Resonance"); + case sfx_mode: + return _T("Set Filter Mode"); + case sfx_drywet: + return _T("Set Plugin Dry/Wet Ratio"); + case sfx_plug: + return _T("Control Plugin Parameter..."); + case sfx_cc: + return _T("MIDI CC..."); + case sfx_custom: + default: + return _T("Custom"); + } +} + + +int MIDIMacroTools::MacroToPlugParam(CString macro) +//------------------------------------------------- +{ + macro.Remove(' '); + int code=0; + char* param = (char *) (LPCTSTR) macro; + param += 4; + if ((param[0] >= '0') && (param[0] <= '9')) code = (param[0] - '0') << 4; else + if ((param[0] >= 'A') && (param[0] <= 'F')) code = (param[0] - 'A' + 0x0A) << 4; + if ((param[1] >= '0') && (param[1] <= '9')) code += (param[1] - '0'); else + if ((param[1] >= 'A') && (param[1] <= 'F')) code += (param[1] - 'A' + 0x0A); + + if (macro.GetLength() >= 4 && macro.GetAt(3) == '0') + return (code - 128); + else + return (code + 128); +} + + +int MIDIMacroTools::MacroToMidiCC(CString macro) +//---------------------------------------------- +{ + macro.Remove(' '); + int code=0; + char* param = (char *) (LPCTSTR) macro; + param += 2; + if ((param[0] >= '0') && (param[0] <= '9')) code = (param[0] - '0') << 4; else + if ((param[0] >= 'A') && (param[0] <= 'F')) code = (param[0] - 'A' + 0x0A) << 4; + if ((param[1] >= '0') && (param[1] <= '9')) code += (param[1] - '0'); else + if ((param[1] >= 'A') && (param[1] <= 'F')) code += (param[1] - 'A' + 0x0A); + + return code; +} + + +int MIDIMacroTools::FindMacroForParam(long param) const +//----------------------------------------------------- +{ + for (size_t macro = 0; macro < NUM_MACROS; macro++) + { + CString macroString = m_SndFile.m_MidiCfg.szMidiSFXExt[macro]; + if (GetMacroType(macroString) == sfx_plug && MacroToPlugParam(macroString) == param) + { + return macro; + } + } + + return -1; +} + + +// Retrieve Zxx (Z80-ZFF) type from current macro configuration +enmFixedMacroType MIDIMacroTools::GetZxxType(const char (&szMidiZXXExt)[128][MACRO_LENGTH]) +//----------------------------------------------------------------------------------------- +{ + // Compare with all possible preset patterns + for(size_t i = 1; i < zxx_max; i++) + { + // Prepare pattern to compare + char szPatterns[128][MACRO_LENGTH]; + CreateZxxFromType(szPatterns, static_cast<enmFixedMacroType>(i)); + + bool bFound = true; + for(size_t j = 0; j < 128; j++) + { + if(strncmp(szPatterns[j], szMidiZXXExt[j], MACRO_LENGTH)) + { + bFound = false; + break; + } + } + if(bFound) return static_cast<enmFixedMacroType>(i); + } + return zxx_custom; // Custom setup +} + + +// Create Zxx (Z80 - ZFF) from one out of five presets +void MIDIMacroTools::CreateZxxFromType(char (&szMidiZXXExt)[128][MACRO_LENGTH], enmFixedMacroType iZxxType) +//--------------------------------------------------------------------------------------------------------- +{ + for(size_t i = 0; i < 128; i++) + { + switch(iZxxType) + { + case zxx_reso4Bit: + // Type 1 - Z80 - Z8F controls resonance + if (i < 16) wsprintf(szMidiZXXExt[i], "F0F001%02X", i * 8); + else strcpy(szMidiZXXExt[i], ""); + break; + + case zxx_reso7Bit: + // Type 2 - Z80 - ZFF controls resonance + wsprintf(szMidiZXXExt[i], "F0F001%02X", i); + break; + + case zxx_cutoff: + // Type 3 - Z80 - ZFF controls cutoff + wsprintf(szMidiZXXExt[i], "F0F000%02X", i); + break; + + case zxx_mode: + // Type 4 - Z80 - ZFF controls filter mode + wsprintf(szMidiZXXExt[i], "F0F002%02X", i); + break; + + case zxx_resomode: + // Type 5 - Z80 - Z9F controls resonance + filter mode + if (i < 16) wsprintf(szMidiZXXExt[i], "F0F001%02X", i * 8); + else if (i < 32) wsprintf(szMidiZXXExt[i], "F0F002%02X", (i - 16) * 8); + else strcpy(szMidiZXXExt[i], ""); + break; + } + } +} + + +CString MIDIMacroTools::CreateParameteredMacroFromType(enmParameteredMacroType type, int subType) +//----------------------------------------------------------------------------------------------- +{ + CString result; + + switch(type) + { + case sfx_unused: + result = ""; + break; + case sfx_cutoff: + result = "F0F000z"; + break; + case sfx_reso: + result = "F0F001z"; + break; + case sfx_mode: + result = "F0F002z"; + break; + case sfx_drywet: + result = "F0F003z"; + break; + case sfx_cc: + result.Format("Bc%02Xz", subType); + break; + case sfx_plug: + result.Format("F0F%03Xz", subType + 0x80); + break; + } + return result; +} + + +// Check if the MIDI Macro confi... [truncated message content] |
From: <sag...@us...> - 2011-11-21 20:59:08
|
Revision: 1140 http://modplug.svn.sourceforge.net/modplug/?rev=1140&view=rev Author: saga-games Date: 2011-11-21 20:58:57 +0000 (Mon, 21 Nov 2011) Log Message: ----------- [Fix] IT Compatibility: If a sample is shorter than the retrig time (i.e. it stops before the retrig counter hits zero), it is not retriggered. [Fix] Note Properties: Plugin indices for PC Notes were off by one. Modified Paths: -------------- trunk/OpenMPT/mptrack/PatternEditorDialogs.cpp trunk/OpenMPT/soundlib/Snd_fx.cpp Modified: trunk/OpenMPT/mptrack/PatternEditorDialogs.cpp =================================================================== --- trunk/OpenMPT/mptrack/PatternEditorDialogs.cpp 2011-11-19 23:57:16 UTC (rev 1139) +++ trunk/OpenMPT/mptrack/PatternEditorDialogs.cpp 2011-11-21 20:58:57 UTC (rev 1140) @@ -1080,8 +1080,11 @@ if(m_bIsParamControl) { // plugin param control note - AddPluginParameternamesToCombobox(*combo, pSndFile->m_MixPlugins[m_nPlugin]); - combo->SetCurSel(m_nPluginParam); + if(m_nPlugin > 0 && m_nPlugin <= MAX_MIXPLUGINS) + { + AddPluginParameternamesToCombobox(*combo, pSndFile->m_MixPlugins[m_nPlugin - 1]); + combo->SetCurSel(m_nPluginParam); + } } else { // process as effect Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp =================================================================== --- trunk/OpenMPT/soundlib/Snd_fx.cpp 2011-11-19 23:57:16 UTC (rev 1139) +++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2011-11-21 20:58:57 UTC (rev 1140) @@ -3677,7 +3677,7 @@ } else { // old routines - if (m_nType & (MOD_TYPE_S3M|MOD_TYPE_IT|MOD_TYPE_MPT)) + if (GetType() & (MOD_TYPE_S3M|MOD_TYPE_IT|MOD_TYPE_MPT)) { if (!nRetrigSpeed) nRetrigSpeed = 1; if ((nRetrigCount) && (!(nRetrigCount % nRetrigSpeed))) bDoRetrig = true; @@ -3692,7 +3692,7 @@ if (!realspeed) realspeed = 1; if ((!(param & 0x100)) && (m_nMusicSpeed) && (!(m_nTickCount % realspeed))) bDoRetrig = true; nRetrigCount++; - } else if (m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2)) nRetrigCount = 0; + } else if (GetType() & (MOD_TYPE_XM|MOD_TYPE_MT2)) nRetrigCount = 0; if (nRetrigCount >= realspeed) { if ((m_nTickCount) || ((param & 0x100) && (!pChn->rowCommand.note))) bDoRetrig = true; @@ -3700,6 +3700,13 @@ } } + // IT compatibility: If a sample is shorter than the retrig time (i.e. it stops before the retrig counter hits zero), it is not retriggered. + // Test case: retrig-short.it + if(pChn->nLength == 0 && IsCompatibleMode(TRK_IMPULSETRACKER)) + { + return; + } + if (bDoRetrig) { UINT dv = (param >> 4) & 0x0F; @@ -3716,7 +3723,7 @@ vol += ((int)retrigTable2[dv]) << 2; } - vol = CLAMP(vol, 0, 256); + Limit(vol, 0, 256); pChn->nVolume = vol; pChn->dwFlags |= CHN_FASTVOLRAMP; @@ -3725,7 +3732,7 @@ LONG nOldPeriod = pChn->nPeriod; if ((nNote) && (nNote <= NOTE_MAX) && (pChn->nLength)) CheckNNA(nChn, 0, nNote, TRUE); bool bResetEnv = false; - if (m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2)) + if (GetType() & (MOD_TYPE_XM|MOD_TYPE_MT2)) { if ((pChn->rowCommand.instr) && (param < 0x100)) { @@ -3740,8 +3747,8 @@ { ProcessMidiOut(nChn, pChn); //Send retrig to Midi } - if ((m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT)) && (!pChn->rowCommand.note) && (nOldPeriod)) pChn->nPeriod = nOldPeriod; - if (!(m_nType & (MOD_TYPE_S3M|MOD_TYPE_IT|MOD_TYPE_MPT))) nRetrigCount = 0; + if ((GetType() & (MOD_TYPE_IT|MOD_TYPE_MPT)) && (!pChn->rowCommand.note) && (nOldPeriod)) pChn->nPeriod = nOldPeriod; + if (!(GetType() & (MOD_TYPE_S3M|MOD_TYPE_IT|MOD_TYPE_MPT))) nRetrigCount = 0; // IT compatibility: see previous IT compatibility comment =) if(IsCompatibleMode(TRK_IMPULSETRACKER)) pChn->nPos = pChn->nPosLo = 0; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2011-11-22 19:46:51
|
Revision: 1141 http://modplug.svn.sourceforge.net/modplug/?rev=1141&view=rev Author: saga-games Date: 2011-11-22 19:46:44 +0000 (Tue, 22 Nov 2011) Log Message: ----------- [Fix] Sample copying / saving: Extra sample settings (autovibrato and such) are now saved / copied correctly in all cases. Previously, they were f.e. lost when copying a sample that has loops and were ignored outright in WAV files. [Mod] OpenMPT: Version is now 1.20.00.55 Modified Paths: -------------- trunk/OpenMPT/mptrack/View_smp.cpp trunk/OpenMPT/mptrack/version.h trunk/OpenMPT/soundlib/Sampleio.cpp Modified: trunk/OpenMPT/mptrack/View_smp.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_smp.cpp 2011-11-21 20:58:57 UTC (rev 1140) +++ trunk/OpenMPT/mptrack/View_smp.cpp 2011-11-22 19:46:44 UTC (rev 1141) @@ -1399,7 +1399,7 @@ m_dwStatus |= SMPSTATUS_MOUSEDRAG; SetFocus(); SetCapture(); - bool oldsel = (m_dwBeginSel != m_dwEndSel) ? true : false; + bool oldsel = (m_dwBeginSel != m_dwEndSel); // shift + click = update selection if(!m_bDrawingEnabled && CMainFrame::GetInputHandler()->ShiftPressed()) @@ -1870,10 +1870,10 @@ EmptyClipboard(); LPBYTE p = (LPBYTE)GlobalLock(hCpy); WAVEFILEHEADER *phdr = (WAVEFILEHEADER *)p; - WAVEFORMATHEADER *pfmt = (WAVEFORMATHEADER *)(p+sizeof(WAVEFILEHEADER)); - WAVEDATAHEADER *pdata = (WAVEDATAHEADER *)(p+sizeof(WAVEFILEHEADER)+sizeof(WAVEFORMATHEADER)); + WAVEFORMATHEADER *pfmt = (WAVEFORMATHEADER *)(p + sizeof(WAVEFILEHEADER)); + WAVEDATAHEADER *pdata = (WAVEDATAHEADER *)(p + sizeof(WAVEFILEHEADER) + sizeof(WAVEFORMATHEADER)); phdr->id_RIFF = IFFID_RIFF; - phdr->filesize = sizeof(WAVEFILEHEADER)+sizeof(WAVEFORMATHEADER)+sizeof(WAVEDATAHEADER)-8; + phdr->filesize = sizeof(WAVEFILEHEADER) + sizeof(WAVEFORMATHEADER) + sizeof(WAVEDATAHEADER) - 8; phdr->id_WAVE = IFFID_WAVE; pfmt->id_fmt = IFFID_fmt; pfmt->hdrlen = 16; @@ -1929,26 +1929,34 @@ WAVEEXTRAHEADER *pxh = (WAVEEXTRAHEADER *)(psamples+dwSmpLen+psh->smpl_len+8); pxh->xtra_id = IFFID_xtra; pxh->xtra_len = sizeof(WAVEEXTRAHEADER)-8; + pxh->dwFlags = sample.uFlags; pxh->wPan = sample.nPan; pxh->wVolume = sample.nVolume; pxh->wGlobalVol = sample.nGlobalVol; + pxh->nVibType = sample.nVibType; pxh->nVibSweep = sample.nVibSweep; pxh->nVibDepth = sample.nVibDepth; pxh->nVibRate = sample.nVibRate; + if(pSndFile->GetType() & MOD_TYPE_XM && (pxh->nVibDepth | pxh->nVibRate)) + { + // XM vibrato is upside down + pxh->nVibSweep = 255 - pxh->nVibSweep; + } + if ((pSndFile->m_szNames[m_nSample][0]) || (sample.filename[0])) { LPSTR pszText = (LPSTR)(pxh+1); - memcpy(pszText, pSndFile->m_szNames[m_nSample], 32); - pxh->xtra_len += 32; + memcpy(pszText, pSndFile->m_szNames[m_nSample], MAX_SAMPLENAME); + pxh->xtra_len += MAX_SAMPLENAME; if (sample.filename[0]) { - memcpy(pszText + 32, sample.filename, MAX_SAMPLEFILENAME); + memcpy(pszText + MAX_SAMPLENAME, sample.filename, MAX_SAMPLEFILENAME); pxh->xtra_len += MAX_SAMPLEFILENAME; } } - phdr->filesize += sizeof(WAVESMPLHEADER) + pxh->xtra_len + 8; + phdr->filesize += (psh->smpl_len + 8) + (pxh->xtra_len + 8); } GlobalUnlock(hCpy); SetClipboardData (CF_WAVE, (HANDLE) hCpy); Modified: trunk/OpenMPT/mptrack/version.h =================================================================== --- trunk/OpenMPT/mptrack/version.h 2011-11-21 20:58:57 UTC (rev 1140) +++ trunk/OpenMPT/mptrack/version.h 2011-11-22 19:46:44 UTC (rev 1141) @@ -15,7 +15,7 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 20 #define VER_MINOR 00 -#define VER_MINORMINOR 54 +#define VER_MINORMINOR 55 //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/Sampleio.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sampleio.cpp 2011-11-21 20:58:57 UTC (rev 1140) +++ trunk/OpenMPT/soundlib/Sampleio.cpp 2011-11-22 19:46:44 UTC (rev 1141) @@ -431,10 +431,8 @@ pSmp->nVolume = 256; pSmp->nGlobalVol = 64; pSmp->uFlags = (pfmt->bitspersample > 8) ? CHN_16BIT : 0; - if (m_nType & MOD_TYPE_XM) pSmp->uFlags |= CHN_PANNING; pSmp->RelativeTone = 0; pSmp->nFineTune = 0; - if (m_nType & MOD_TYPE_XM) FrequencyToTranspose(pSmp); pSmp->nVibType = pSmp->nVibSweep = pSmp->nVibDepth = pSmp->nVibRate = 0; pSmp->filename[0] = 0; MemsetZero(m_szNames[nSample]); @@ -530,16 +528,19 @@ LPSTR pszTextEx = (LPSTR)(pxh+1); if (xtrabytes >= MAX_SAMPLENAME) { - memcpy(m_szNames[nSample], pszTextEx, MAX_SAMPLENAME - 1); + memcpy(m_szNames[nSample], pszTextEx, MAX_SAMPLENAME); + StringFixer::SetNullTerminator(m_szNames[nSample]); pszTextEx += MAX_SAMPLENAME; xtrabytes -= MAX_SAMPLENAME; if (xtrabytes >= MAX_SAMPLEFILENAME) { memcpy(pSmp->filename, pszTextEx, MAX_SAMPLEFILENAME); + StringFixer::SetNullTerminator(pSmp->filename); xtrabytes -= MAX_SAMPLEFILENAME; } } } + ConvertSample(nSample, MOD_TYPE_IT); return true; } @@ -561,11 +562,11 @@ FILE *f; if ((f = fopen(lpszFileName, "wb")) == NULL) return false; - memset(&extra, 0, sizeof(extra)); - memset(&smpl, 0, sizeof(smpl)); + MemsetZero(extra); + MemsetZero(smpl); header.id_RIFF = IFFID_RIFF; - header.filesize = sizeof(header)+sizeof(format)+sizeof(data)+sizeof(extra)-8; - header.filesize += 12+8+16+8+32; // LIST(INAM, ISFT) + header.filesize = sizeof(header) + sizeof(format) + sizeof(data) + sizeof(smpl) + sizeof(extra) - 8; + header.filesize += sizeof(list) + 8 + 16 + 8 + 32; // LIST(INAM, ISFT) header.id_WAVE = IFFID_WAVE; format.id_fmt = IFFID_fmt; format.hdrlen = 16; @@ -636,15 +637,23 @@ // "xtra" field extra.xtra_id = IFFID_xtra; extra.xtra_len = sizeof(extra) - 8; + extra.dwFlags = pSmp->uFlags; extra.wPan = pSmp->nPan; extra.wVolume = pSmp->nVolume; extra.wGlobalVol = pSmp->nGlobalVol; extra.wReserved = 0; + extra.nVibType = pSmp->nVibType; extra.nVibSweep = pSmp->nVibSweep; extra.nVibDepth = pSmp->nVibDepth; extra.nVibRate = pSmp->nVibRate; + if(GetType() & MOD_TYPE_XM && (extra.nVibDepth | extra.nVibRate)) + { + // XM vibrato is upside down + extra.nVibSweep = 255 - extra.nVibSweep; + } + fwrite(&extra, 1, sizeof(extra), f); fclose(f); return true; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2011-12-03 15:55:03
|
Revision: 1142 http://modplug.svn.sourceforge.net/modplug/?rev=1142&view=rev Author: saga-games Date: 2011-12-03 15:54:55 +0000 (Sat, 03 Dec 2011) Log Message: ----------- [Mod] Song flags are not updated "live" anymore in song properties (http://bugs.openmpt.org/view.php?id=212). [Mod] Sample undo history is not lost anymore when converting between two mod formats. [Fix] Fixed some off-by-one sample / instrument limits [Fix] PSM16 Loader: More sample frequency fixes... Should be about right now (cross-comparing with Silverball and Epic Pinball seems to verify this) [Mod] OpenMPT: Version is now 1.20.00.56 Modified Paths: -------------- trunk/OpenMPT/mptrack/ModConvert.cpp trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/mptrack/UpdateCheck.cpp trunk/OpenMPT/mptrack/dlg_misc.cpp trunk/OpenMPT/mptrack/dlg_misc.h trunk/OpenMPT/mptrack/version.h trunk/OpenMPT/mptrack/view_com.cpp trunk/OpenMPT/soundlib/Load_psm.cpp trunk/OpenMPT/soundlib/mod_specifications.h Modified: trunk/OpenMPT/mptrack/ModConvert.cpp =================================================================== --- trunk/OpenMPT/mptrack/ModConvert.cpp 2011-11-22 19:46:44 UTC (rev 1141) +++ trunk/OpenMPT/mptrack/ModConvert.cpp 2011-12-03 15:54:55 UTC (rev 1142) @@ -106,7 +106,6 @@ const bool newTypeIsMOD = (nNewType == MOD_TYPE_MOD), newTypeIsXM = (nNewType == MOD_TYPE_XM), newTypeIsS3M = (nNewType == MOD_TYPE_S3M), newTypeIsIT = (nNewType == MOD_TYPE_IT), newTypeIsMPT = (nNewType == MOD_TYPE_MPT), newTypeIsMOD_XM = (newTypeIsMOD || newTypeIsXM), - newTypeIsXM_IT_MPT = (newTypeIsXM || newTypeIsIT || newTypeIsMPT), newTypeIsIT_MPT = (newTypeIsIT || newTypeIsMPT); const CModSpecifications& specs = m_SndFile.GetModSpecifications(nNewType); @@ -257,6 +256,7 @@ for(SAMPLEINDEX nSmp = 1; nSmp <= m_SndFile.GetNumSamples(); nSmp++) { MODSAMPLE &sample = m_SndFile.GetSample(nSmp); + GetSampleUndo().PrepareUndo(nSmp, sundo_none); // Too many samples? Only 31 samples allowed in MOD format... if(newTypeIsMOD && nSmp > 31 && sample.nLength > 0) @@ -412,16 +412,14 @@ CriticalSection cs; m_SndFile.ChangeModTypeTo(nNewType); - if(!newTypeIsXM_IT_MPT && (m_SndFile.m_dwSongFlags & SONG_LINEARSLIDES)) + + // Song flags + if(!(CSoundFile::GetModSpecifications(nNewType).songFlags & SONG_LINEARSLIDES) && (m_SndFile.m_dwSongFlags & SONG_LINEARSLIDES)) { CHANGEMODTYPE_WARNING(wLinearSlides); - m_SndFile.m_dwSongFlags &= ~SONG_LINEARSLIDES; } - if(!newTypeIsIT_MPT) m_SndFile.m_dwSongFlags &= ~(SONG_ITOLDEFFECTS|SONG_ITCOMPATGXX); - if(!newTypeIsS3M) m_SndFile.m_dwSongFlags &= ~SONG_FASTVOLSLIDES; - if(!newTypeIsMOD) m_SndFile.m_dwSongFlags &= ~SONG_PT1XMODE; - if(newTypeIsS3M || newTypeIsMOD) m_SndFile.m_dwSongFlags &= ~SONG_EXFILTERRANGE; if(oldTypeIsXM && newTypeIsIT_MPT) m_SndFile.m_dwSongFlags |= SONG_ITCOMPATGXX; + m_SndFile.m_dwSongFlags &= SONG_PLAY_FLAGS | CSoundFile::GetModSpecifications(nNewType).songFlags; // Adjust mix levels if(newTypeIsMOD || newTypeIsS3M) @@ -435,11 +433,11 @@ } // Automatically enable compatible mode when converting from MOD and S3M, since it's automatically enabled in those formats. - if((nOldType & (MOD_TYPE_MOD|MOD_TYPE_S3M)) && (nNewType & (MOD_TYPE_XM|MOD_TYPE_IT))) + if((nOldType & (MOD_TYPE_MOD | MOD_TYPE_S3M)) && (nNewType & (MOD_TYPE_XM | MOD_TYPE_IT))) { m_SndFile.SetModFlag(MSF_COMPATIBLE_PLAY, true); } - if((nNewType & (MOD_TYPE_XM|MOD_TYPE_IT)) && !m_SndFile.GetModFlag(MSF_COMPATIBLE_PLAY)) + if((nNewType & (MOD_TYPE_XM | MOD_TYPE_IT)) && !m_SndFile.GetModFlag(MSF_COMPATIBLE_PLAY)) { CHANGEMODTYPE_WARNING(wCompatibilityMode); } @@ -448,10 +446,10 @@ ChangeFileExtension(nNewType); // Check mod specifications - m_SndFile.m_nDefaultTempo = CLAMP(m_SndFile.m_nDefaultTempo, specs.tempoMin, specs.tempoMax); - m_SndFile.m_nDefaultSpeed = CLAMP(m_SndFile.m_nDefaultSpeed, specs.speedMin, specs.speedMax); + Limit(m_SndFile.m_nDefaultTempo, specs.tempoMin, specs.tempoMax); + Limit(m_SndFile.m_nDefaultSpeed, specs.speedMin, specs.speedMax); - for(INSTRUMENTINDEX i = 1; i <= m_SndFile.m_nInstruments; i++) if(m_SndFile.Instruments[i] != nullptr) + for(INSTRUMENTINDEX i = 1; i <= m_SndFile.GetNumInstruments(); i++) if(m_SndFile.Instruments[i] != nullptr) { UpdateEnvelopes(&(m_SndFile.Instruments[i]->VolEnv), &m_SndFile, warnings); UpdateEnvelopes(&(m_SndFile.Instruments[i]->PanEnv), &m_SndFile, warnings); @@ -498,7 +496,6 @@ SetModified(); GetPatternUndo().ClearUndo(); - GetSampleUndo().ClearUndo(); UpdateAllViews(NULL, HINT_MODTYPE | HINT_MODGENERAL); EndWaitCursor(); Modified: trunk/OpenMPT/mptrack/Modedit.cpp =================================================================== --- trunk/OpenMPT/mptrack/Modedit.cpp 2011-11-22 19:46:44 UTC (rev 1141) +++ trunk/OpenMPT/mptrack/Modedit.cpp 2011-12-03 15:54:55 UTC (rev 1142) @@ -360,7 +360,7 @@ return false; } - const INSTRUMENTINDEX nInstrumentMax = m_SndFile.GetModSpecifications().instrumentsMax - 1; + const INSTRUMENTINDEX nInstrumentMax = m_SndFile.GetModSpecifications().instrumentsMax; const SAMPLEINDEX nInstruments = min(m_SndFile.GetNumSamples(), nInstrumentMax); for(SAMPLEINDEX smp = 1; smp <= nInstruments; smp++) @@ -460,7 +460,7 @@ m_SndFile.Order.Append(); } - for (UINT j=0; j<m_SndFile.Order.size(); j++) + for (ORDERINDEX j = 0; j < m_SndFile.Order.size(); j++) { if (m_SndFile.Order[j] == i) break; if (m_SndFile.Order[j] == m_SndFile.Order.GetInvalidPatIndex() && nOrd == ORDERINDEX_INVALID) @@ -468,11 +468,11 @@ m_SndFile.Order[j] = i; break; } - if ((nOrd >= 0) && (j == (UINT)nOrd)) + if (j == nOrd) { - for (UINT k=m_SndFile.Order.size()-1; k>j; k--) + for (ORDERINDEX k = m_SndFile.Order.size() - 1; k > j; k--) { - m_SndFile.Order[k] = m_SndFile.Order[k-1]; + m_SndFile.Order[k] = m_SndFile.Order[k - 1]; } m_SndFile.Order[j] = i; break; @@ -511,14 +511,14 @@ // Insert a new instrument assigned to sample nSample or duplicate instrument nDuplicate. -// If nSample is invalid, an approriate sample slot is selected. 0 means "no sample". +// If nSample is invalid, an appropriate sample slot is selected. 0 means "no sample". INSTRUMENTINDEX CModDoc::InsertInstrument(SAMPLEINDEX nSample, INSTRUMENTINDEX nDuplicate) //---------------------------------------------------------------------------------------- { if (m_SndFile.GetModSpecifications().instrumentsMax == 0) return INSTRUMENTINDEX_INVALID; MODINSTRUMENT *pDup = nullptr; - const INSTRUMENTINDEX nInstrumentMax = m_SndFile.GetModSpecifications().instrumentsMax - 1; + const INSTRUMENTINDEX nInstrumentMax = m_SndFile.GetModSpecifications().instrumentsMax; if ((nDuplicate > 0) && (nDuplicate <= m_SndFile.m_nInstruments)) { pDup = m_SndFile.Instruments[nDuplicate]; @@ -566,7 +566,7 @@ newsmp = nSample; } else if (!pDup) { - for(SAMPLEINDEX k = 1; k <= m_SndFile.m_nSamples; k++) + for(SAMPLEINDEX k = 1; k <= m_SndFile.GetNumSamples(); k++) { if (!m_SndFile.IsSampleUsed(k)) { @@ -623,11 +623,11 @@ sample.nC5Speed = 8363; sample.RelativeTone = 0; sample.nFineTune = 0; - sample.nVibType = 0; + sample.nVibType = VIB_SINE; sample.nVibSweep = 0; sample.nVibDepth = 0; sample.nVibRate = 0; - sample.uFlags &= ~(CHN_PANNING|CHN_SUSTAINLOOP); + sample.uFlags &= ~(CHN_PANNING|CHN_SUSTAINLOOP|CHN_LOOP); if(m_SndFile.GetType() == MOD_TYPE_XM) { sample.uFlags |= CHN_PANNING; @@ -813,7 +813,7 @@ { LPCSTR pszFormatName; EmptyClipboard(); - switch(m_SndFile.m_nType) + switch(m_SndFile.GetType()) { case MOD_TYPE_S3M: pszFormatName = "S3M"; break; case MOD_TYPE_XM: pszFormatName = "XM"; break; @@ -994,7 +994,7 @@ } const CModSpecifications &sourceSpecs = CSoundFile::GetModSpecifications(origFormat); - const bool bS3MCommands = (origFormat & (MOD_TYPE_IT|MOD_TYPE_MPT|MOD_TYPE_S3M)) != 0 ? true : false; + const bool bS3MCommands = (origFormat & (MOD_TYPE_IT|MOD_TYPE_MPT|MOD_TYPE_S3M)) != 0; pos = startPos; while ((nrow < m_SndFile.Patterns[nPattern].GetNumRows())) Modified: trunk/OpenMPT/mptrack/UpdateCheck.cpp =================================================================== --- trunk/OpenMPT/mptrack/UpdateCheck.cpp 2011-11-22 19:46:44 UTC (rev 1141) +++ trunk/OpenMPT/mptrack/UpdateCheck.cpp 2011-12-03 15:54:55 UTC (rev 1142) @@ -81,11 +81,12 @@ // Never ran update checks before, so we notify the user of automatic update checks. if(CUpdateCheck::showUpdateHint) { + CUpdateCheck::showUpdateHint = false; CString msg; msg.Format("OpenMPT would like to check for updates now, proceed?\n\nNote: In the future, OpenMPT will check for updates every %d days. If you do not want this, you can disable update checks in the setup.", CUpdateCheck::updateCheckPeriod); if(Reporting::Confirm(msg, "OpenMPT Internet Update") == cnfNo) { - CUpdateCheck::showUpdateHint = false; + CUpdateCheck::lastUpdateCheck = now; caller->Terminate(); return 0; } @@ -165,7 +166,7 @@ { if(!caller->isAutoUpdate) { - Reporting::Information("You already have the latest version of OpenMPT.", "OpenMPT Internet Update"); + Reporting::Information("You already have the latest version of OpenMPT installed.", "OpenMPT Internet Update"); } } else { @@ -293,7 +294,7 @@ case 31: radioID = IDC_RADIO4; break; } CheckRadioButton(IDC_RADIO1, IDC_RADIO4, radioID); - CheckDlgButton(IDC_CHECK1, CUpdateCheck::GetSendGUID() ? MF_CHECKED : MF_UNCHECKED); + CheckDlgButton(IDC_CHECK1, CUpdateCheck::GetSendGUID() ? BST_CHECKED : BST_UNCHECKED); SetDlgItemText(IDC_EDIT1, CUpdateCheck::GetUpdateURL()); const time_t t = CUpdateCheck::GetLastUpdateCheck(); Modified: trunk/OpenMPT/mptrack/dlg_misc.cpp =================================================================== --- trunk/OpenMPT/mptrack/dlg_misc.cpp 2011-11-22 19:46:44 UTC (rev 1141) +++ trunk/OpenMPT/mptrack/dlg_misc.cpp 2011-12-03 15:54:55 UTC (rev 1142) @@ -20,17 +20,7 @@ BEGIN_MESSAGE_MAP(CModTypeDlg, CDialog) //{{AFX_MSG_MAP(CModTypeDlg) - ON_COMMAND(IDC_CHECK1, OnCheck1) - ON_COMMAND(IDC_CHECK2, OnCheck2) - ON_COMMAND(IDC_CHECK3, OnCheck3) - ON_COMMAND(IDC_CHECK4, OnCheck4) - ON_COMMAND(IDC_CHECK5, OnCheck5) -// -> CODE#0023 -// -> DESC="IT project files (.itp)" - ON_COMMAND(IDC_CHECK6, OnCheck6) - ON_COMMAND(IDC_CHECK_PT1X, OnCheckPT1x) ON_CBN_SELCHANGE(IDC_COMBO1,UpdateDialog) -// -! NEW_FEATURE#0023 ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, &CModTypeDlg::OnToolTipNotify) ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, &CModTypeDlg::OnToolTipNotify) @@ -49,16 +39,6 @@ DDX_Control(pDX, IDC_COMBO2, m_ChannelsBox); DDX_Control(pDX, IDC_COMBO_TEMPOMODE, m_TempoModeBox); DDX_Control(pDX, IDC_COMBO_MIXLEVELS, m_PlugMixBox); - DDX_Control(pDX, IDC_CHECK1, m_CheckBox1); - DDX_Control(pDX, IDC_CHECK2, m_CheckBox2); - DDX_Control(pDX, IDC_CHECK3, m_CheckBox3); - DDX_Control(pDX, IDC_CHECK4, m_CheckBox4); - DDX_Control(pDX, IDC_CHECK5, m_CheckBox5); -// -> CODE#0023 -// -> DESC="IT project files (.itp)" - DDX_Control(pDX, IDC_CHECK6, m_CheckBox6); -// -! NEW_FEATURE#0023 - DDX_Control(pDX, IDC_CHECK_PT1X, m_CheckBoxPT1x); //}}AFX_DATA_MAP } @@ -69,7 +49,6 @@ CDialog::OnInitDialog(); m_nType = m_pSndFile->GetType(); m_nChannels = m_pSndFile->GetNumChannels(); - m_dwSongFlags = m_pSndFile->m_dwSongFlags; // Mod types @@ -80,8 +59,8 @@ // -> CODE#0023 // -> DESC="IT project files (.itp)" m_TypeBox.SetItemData(m_TypeBox.AddString("Impulse Tracker Project ITP"), MOD_TYPE_IT); + // -! NEW_FEATURE#0023 m_TypeBox.SetItemData(m_TypeBox.AddString("OpenMPT MPTM"), MOD_TYPE_MPT); -// -! NEW_FEATURE#0023 switch(m_nType) { case MOD_TYPE_S3M: m_TypeBox.SetCurSel(1); break; @@ -216,12 +195,13 @@ m_CheckBox6.SetCheck((m_pSndFile->m_dwSongFlags & SONG_ITPEMBEDIH) ? MF_CHECKED : 0); // -! NEW_FEATURE#0023 - m_CheckBox1.EnableWindow((type & (MOD_TYPE_XM|MOD_TYPE_IT|MOD_TYPE_MPT)) ? TRUE : FALSE); - m_CheckBox2.EnableWindow((type == MOD_TYPE_S3M) ? TRUE : FALSE); - m_CheckBox3.EnableWindow((type & (MOD_TYPE_IT|MOD_TYPE_MPT)) ? TRUE : FALSE); - m_CheckBox4.EnableWindow((type & (MOD_TYPE_IT|MOD_TYPE_MPT)) ? TRUE : FALSE); - m_CheckBox5.EnableWindow((type & (MOD_TYPE_XM|MOD_TYPE_IT|MOD_TYPE_MPT)) ? TRUE : FALSE); - m_CheckBoxPT1x.EnableWindow((type & (MOD_TYPE_MOD)) ? TRUE : FALSE); + const DWORD allowedFlags = m_pSndFile->GetModSpecifications(type).songFlags; + m_CheckBox1.EnableWindow((allowedFlags & SONG_LINEARSLIDES) != 0); + m_CheckBox2.EnableWindow((allowedFlags & SONG_FASTVOLSLIDES) != 0); + m_CheckBox3.EnableWindow((allowedFlags & SONG_ITOLDEFFECTS) != 0); + m_CheckBox4.EnableWindow((allowedFlags & SONG_ITCOMPATGXX) != 0); + m_CheckBox5.EnableWindow((allowedFlags & SONG_EXFILTERRANGE) != 0); + m_CheckBoxPT1x.EnableWindow((allowedFlags & SONG_PT1XMODE) != 0); // -> CODE#0023 // -> DESC="IT project files (.itp)" @@ -282,76 +262,7 @@ } -void CModTypeDlg::OnCheck1() -//-------------------------- -{ - if (m_CheckBox1.GetCheck()) - m_pSndFile->m_dwSongFlags |= SONG_LINEARSLIDES; - else - m_pSndFile->m_dwSongFlags &= ~SONG_LINEARSLIDES; -} - - -void CModTypeDlg::OnCheck2() -//-------------------------- -{ - if (m_CheckBox2.GetCheck()) - m_pSndFile->m_dwSongFlags |= SONG_FASTVOLSLIDES; - else - m_pSndFile->m_dwSongFlags &= ~SONG_FASTVOLSLIDES; -} - - -void CModTypeDlg::OnCheck3() -//-------------------------- -{ - if (m_CheckBox3.GetCheck()) - m_pSndFile->m_dwSongFlags |= SONG_ITOLDEFFECTS; - else - m_pSndFile->m_dwSongFlags &= ~SONG_ITOLDEFFECTS; -} - - -void CModTypeDlg::OnCheck4() -//-------------------------- -{ - if (m_CheckBox4.GetCheck()) - m_pSndFile->m_dwSongFlags |= SONG_ITCOMPATGXX; - else - m_pSndFile->m_dwSongFlags &= ~SONG_ITCOMPATGXX; -} - - -void CModTypeDlg::OnCheck5() -//-------------------------- -{ - if (m_CheckBox5.GetCheck()) - m_pSndFile->m_dwSongFlags |= SONG_EXFILTERRANGE; - else - m_pSndFile->m_dwSongFlags &= ~SONG_EXFILTERRANGE; -} - - -void CModTypeDlg::OnCheck6() -//-------------------------- -{ - if (m_CheckBox6.GetCheck()) - m_pSndFile->m_dwSongFlags |= SONG_ITPEMBEDIH; - else - m_pSndFile->m_dwSongFlags &= ~SONG_ITPEMBEDIH; -} - -void CModTypeDlg::OnCheckPT1x() -//----------------------------- -{ - if (m_CheckBoxPT1x.GetCheck()) - m_pSndFile->m_dwSongFlags |= SONG_PT1XMODE; - else - m_pSndFile->m_dwSongFlags &= ~SONG_PT1XMODE; -} - - -bool CModTypeDlg::VerifyData() +bool CModTypeDlg::VerifyData() //---------------------------- { @@ -406,6 +317,37 @@ if(sel == 4) m_pSndFile->m_dwSongFlags |= SONG_ITPROJECT; // -! NEW_FEATURE#0023 } + + if (m_CheckBox1.GetCheck()) + m_pSndFile->m_dwSongFlags |= SONG_LINEARSLIDES; + else + m_pSndFile->m_dwSongFlags &= ~SONG_LINEARSLIDES; + if (m_CheckBox2.GetCheck()) + m_pSndFile->m_dwSongFlags |= SONG_FASTVOLSLIDES; + else + m_pSndFile->m_dwSongFlags &= ~SONG_FASTVOLSLIDES; + if (m_CheckBox3.GetCheck()) + m_pSndFile->m_dwSongFlags |= SONG_ITOLDEFFECTS; + else + m_pSndFile->m_dwSongFlags &= ~SONG_ITOLDEFFECTS; + if (m_CheckBox4.GetCheck()) + m_pSndFile->m_dwSongFlags |= SONG_ITCOMPATGXX; + else + m_pSndFile->m_dwSongFlags &= ~SONG_ITCOMPATGXX; + if (m_CheckBox5.GetCheck()) + m_pSndFile->m_dwSongFlags |= SONG_EXFILTERRANGE; + else + m_pSndFile->m_dwSongFlags &= ~SONG_EXFILTERRANGE; + if (m_CheckBox6.GetCheck()) + m_pSndFile->m_dwSongFlags |= SONG_ITPEMBEDIH; + else + m_pSndFile->m_dwSongFlags &= ~SONG_ITPEMBEDIH; + if (m_CheckBoxPT1x.GetCheck()) + m_pSndFile->m_dwSongFlags |= SONG_PT1XMODE; + else + m_pSndFile->m_dwSongFlags &= ~SONG_PT1XMODE; + + sel = m_ChannelsBox.GetCurSel(); if (sel >= 0) { @@ -445,15 +387,7 @@ CDialog::OnOK(); } -void CModTypeDlg::OnCancel() -//-------------------------- -{ - // Reset mod flags - m_pSndFile->m_dwSongFlags = m_dwSongFlags; - CDialog::OnCancel(); -} - BOOL CModTypeDlg::OnToolTipNotify(UINT id, NMHDR* pNMHDR, LRESULT* pResult) //------------------------------------------------------------------------- { @@ -487,7 +421,7 @@ strTipText = "Gxx and Exx/Fxx won't share effect memory. Gxx resets instrument envelopes."; break; case IDC_CHECK5: - strTipText = "The resonant filter's frequency range is increased from about 4KHz to 10KHz."; + strTipText = "The resonant filter's frequency range is increased from about 5KHz to 10KHz."; break; case IDC_CHECK6: strTipText = "The instrument settings of the external ITI files will be ignored."; @@ -607,9 +541,11 @@ if (!m_bKeepMask[n]) m_RemChansList.SetSel(n); } - if (m_nRemove > 0) { + if (m_nRemove > 0) + { wsprintf(label, "Select %d channel%s to remove:", m_nRemove, (m_nRemove != 1) ? "s" : ""); - } else { + } else + { wsprintf(label, "Select channels to remove (the minimum number of remaining channels is %d)", m_pSndFile->GetModSpecifications().channelsMin); } @@ -968,13 +904,13 @@ nInsertPos = m_CbnSample.AddString("0: No sample"); m_CbnSample.SetItemData(nInsertPos, 0); - for (UINT i=1; i<=m_pSndFile->m_nSamples; i++) + for (SAMPLEINDEX i = 1; i <= m_pSndFile->GetNumSamples(); i++) { bool isUsed = showAll; if (!isUsed) { - for (UINT j=0; j<NOTE_MAX; j++) + for (size_t j = 0; j < CountOf(KeyboardMap); j++) { if (KeyboardMap[j] == i) { @@ -1057,7 +993,7 @@ KeyboardMap[iNote] = pIns->Keyboard[iNote]; } else { - KeyboardMap[iNote] = (WORD)nSample; + KeyboardMap[iNote] = (SAMPLEINDEX)nSample; } /* rewbs.note: I don't think we need this with cust keys. // -> CODE#0009 Modified: trunk/OpenMPT/mptrack/dlg_misc.h =================================================================== --- trunk/OpenMPT/mptrack/dlg_misc.h 2011-11-22 19:46:44 UTC (rev 1141) +++ trunk/OpenMPT/mptrack/dlg_misc.h 2011-12-03 15:54:55 UTC (rev 1142) @@ -15,7 +15,6 @@ CSoundFile *m_pSndFile; CHANNELINDEX m_nChannels; MODTYPE m_nType; - DWORD m_dwSongFlags; // -> CODE#0023 // -> DESC="IT project files (.itp)" @@ -36,24 +35,11 @@ virtual void DoDataExchange(CDataExchange* pDX); virtual BOOL OnInitDialog(); virtual void OnOK(); - virtual void OnCancel(); //}}AFX_VIRTUAL BOOL OnToolTipNotify(UINT id, NMHDR* pNMHDR, LRESULT* pResult); - //{{AFX_MSG(CModTypeDlg) - afx_msg void OnCheck1(); - afx_msg void OnCheck2(); - afx_msg void OnCheck3(); - afx_msg void OnCheck4(); - afx_msg void OnCheck5(); -// -> CODE#0023 -// -> DESC="IT project files (.itp)" - afx_msg void OnCheck6(); -// -! NEW_FEATURE#0023 - afx_msg void OnCheckPT1x(); - //}}AFX_MSG DECLARE_MESSAGE_MAP() }; @@ -184,7 +170,7 @@ CSliderCtrl m_SbOctave; CSoundFile *m_pSndFile; UINT m_nInstrument; - WORD KeyboardMap[NOTE_MAX]; + SAMPLEINDEX KeyboardMap[NOTE_MAX]; public: CSampleMapDlg(CSoundFile *pSndFile, UINT nInstr, CWnd *parent=NULL):CDialog(IDD_EDITSAMPLEMAP, parent) Modified: trunk/OpenMPT/mptrack/version.h =================================================================== --- trunk/OpenMPT/mptrack/version.h 2011-11-22 19:46:44 UTC (rev 1141) +++ trunk/OpenMPT/mptrack/version.h 2011-12-03 15:54:55 UTC (rev 1142) @@ -15,7 +15,7 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 20 #define VER_MINOR 00 -#define VER_MINORMINOR 55 +#define VER_MINORMINOR 56 //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/mptrack/view_com.cpp =================================================================== --- trunk/OpenMPT/mptrack/view_com.cpp 2011-11-22 19:46:44 UTC (rev 1141) +++ trunk/OpenMPT/mptrack/view_com.cpp 2011-12-03 15:54:55 UTC (rev 1142) @@ -251,10 +251,10 @@ switch(iCol) { case SMPLIST_SAMPLENAME: - lstrcpyn(s, pSndFile->m_szNames[iSmp+1], MAX_SAMPLENAME); + lstrcpyn(s, pSndFile->m_szNames[iSmp + 1], MAX_SAMPLENAME); break; case SMPLIST_SAMPLENO: - wsprintf(s, "%02d", iSmp+1); + wsprintf(s, "%02d", iSmp + 1); break; case SMPLIST_SIZE: if (sample.nLength) @@ -268,16 +268,16 @@ case SMPLIST_TYPE: if (sample.nLength) { - wsprintf(s, "%d Bit", sample.GetElementarySampleSize() << 3); + wsprintf(s, "%d Bit", sample.GetElementarySampleSize() * 8); } break; case SMPLIST_INSTR: if (pSndFile->GetNumInstruments()) { bool first = true; - for (INSTRUMENTINDEX i = 0; i < pSndFile->GetNumInstruments(); i++) if (pSndFile->Instruments[i + 1]) + for (INSTRUMENTINDEX i = 1; i <= pSndFile->GetNumInstruments(); i++) if (pSndFile->Instruments[i]) { - MODINSTRUMENT *pIns = pSndFile->Instruments[i + 1]; + const MODINSTRUMENT *pIns = pSndFile->Instruments[i]; for (size_t j = 0; j < CountOf(pIns->Keyboard); j++) { if (pIns->Keyboard[j] == (iSmp + 1)) @@ -285,7 +285,7 @@ if (!first) strcat(s, ","); first = false; - wsprintf(stmp, "%d", i + 1); + wsprintf(stmp, "%d", i); strcat(s, stmp); break; } Modified: trunk/OpenMPT/soundlib/Load_psm.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_psm.cpp 2011-11-22 19:46:44 UTC (rev 1141) +++ trunk/OpenMPT/soundlib/Load_psm.cpp 2011-12-03 15:54:55 UTC (rev 1142) @@ -813,6 +813,12 @@ // PSM16 support starts here. // +// 32-Bit chunk identifiers +#define PSM16_PORD 0x44524f50 +#define PSM16_PPAN 0x4E415050 +#define PSM16_PSAH 0x48415350 +#define PSM16_PPAT 0x54415050 + #pragma pack(1) struct PSM16HEADER @@ -823,7 +829,7 @@ uint8 songType; // Song Type bitfield uint8 formatVersion; // $10 uint8 patternVersion; // 0 or 1 - uint8 songSpeed; // + uint8 songSpeed; // 1 ... 255 uint8 songTempo; // 32 ... 255 uint8 masterVolume; // 0 ... 255 uint16 songLength; // 0 ... 255 (number of patterns to play in the song) @@ -832,11 +838,11 @@ uint16 numSamples; // 1 ... 255 uint16 numChannelsPlay; // 0 ... 32 (max. number of channels to play) uint16 numChannelsReal; // 0 ... 32 (max. number of channels to process) - uint32 orderOffset; - uint32 panOffset; - uint32 patOffset; - uint32 smpOffset; - uint32 commentsOffset; + uint32 orderOffset; // Pointer to order list + uint32 panOffset; // Pointer to pan table + uint32 patOffset; // Pointer to pattern data + uint32 smpOffset; // Pointer to sample headers + uint32 commentsOffset; // Pointer to song comment uint32 patSize; // Size of all patterns uint8 filler[40]; }; @@ -852,31 +858,31 @@ uint32 length; // in bytes uint32 loopStart; // in samples? uint32 loopEnd; // in samples? - int8 finetune; // 0 ... 15 (high nibble is 7 in most cases, but why? is it maybe some transpose value?) + int8 finetune; // Low nibble = MOD finetune, high nibble = transpose (7 = center) uint8 volume; // default volume - uint16 c2freq; + uint16 c2freq; // Middle-C frequency, which has to be combined with the finetune and transpose. }; struct PSM16PATHEADER { uint16 size; // includes header bytes uint8 numRows; // 1 ... 64 - uint8 numChans; // 1 ... 31 + uint8 numChans; // 1 ... 32 }; #pragma pack() bool CSoundFile::ReadPSM16(const LPCBYTE lpStream, const DWORD dwMemLength) -//----------------------------------------------------------------------- +//------------------------------------------------------------------------- { DWORD dwMemPos = 0; ASSERT_CAN_READ(sizeof(PSM16HEADER)); - PSM16HEADER *shdr = (PSM16HEADER *)lpStream; + const PSM16HEADER *shdr = (PSM16HEADER *)lpStream; // Check header - if((LittleEndian(shdr->formatID) != PSM16HEAD_PSM_) // "PSM\xFE" + if((shdr->formatID != LittleEndian(PSM16HEAD_PSM_)) // "PSM\xFE" || (shdr->lineEnd != 0x1A) || (shdr->formatVersion != 0x10 && shdr->formatVersion != 0x01) // why is this sometimes 0x01? || (shdr->patternVersion != 0) // 255ch pattern version not supported (did anyone use this?) @@ -893,14 +899,14 @@ m_nDefaultSpeed = shdr->songSpeed; m_nDefaultTempo = shdr->songTempo; - memset(m_szNames, 0, sizeof(m_szNames)); + MemsetZero(m_szNames); memcpy(m_szNames[0], shdr->songName, 31); StringFixer::SpaceToNullStringFixed<31>(m_szNames[0]); // Read orders dwMemPos = LittleEndian(shdr->orderOffset); ASSERT_CAN_READ((DWORD)LittleEndianW(shdr->songOrders) + 2); - if(LittleEndian(shdr->orderOffset) > 4 && LittleEndian(*(uint32 *)(lpStream + dwMemPos - 4)) == 0x44524f50) // PORD + if(LittleEndian(shdr->orderOffset) > 4 && *(uint32 *)(lpStream + dwMemPos - 4) == LittleEndian(PSM16_PORD)) // PORD { Order.ReadAsByte(lpStream + dwMemPos, LittleEndianW(shdr->songOrders), dwMemLength - dwMemPos); } @@ -908,11 +914,11 @@ // Read pan positions dwMemPos = LittleEndian(shdr->panOffset); ASSERT_CAN_READ(32); - if(LittleEndian(shdr->panOffset) > 4 && LittleEndian(*(uint32 *)(lpStream + dwMemPos - 4)) == 0x4E415050) // PPAN + if(LittleEndian(shdr->panOffset) > 4 && LittleEndian(*(uint32 *)(lpStream + dwMemPos - 4)) == PSM16_PPAN) // PPAN { for(CHANNELINDEX i = 0; i < 32; i++) { - ChnSettings[i].nPan = lpStream[dwMemPos + i] << 4; + ChnSettings[i].nPan = ((15 - (lpStream[dwMemPos + i] & 0x0F)) * 256 + 8) / 15; // 15 seems to be left and 0 seems to be right... ChnSettings[i].nVolume = 64; ChnSettings[i].dwFlags = 0; // (i >= shdr->numChannelsPlay) ? CHN_MUTE : 0; // don't mute channels, as muted channels are completely ignored in S3M } @@ -921,14 +927,14 @@ // Read samples dwMemPos = LittleEndian(shdr->smpOffset); ASSERT_CAN_READ(0); - if(LittleEndian(shdr->smpOffset) > 4 && LittleEndian(*(uint32 *)(lpStream + dwMemPos - 4)) == 0x48415350) // PSAH + if(LittleEndian(shdr->smpOffset) > 4 && *(uint32 *)(lpStream + dwMemPos - 4) == LittleEndian(PSM16_PSAH)) // PSAH { SAMPLEINDEX iSmpCount = 0; m_nSamples = LittleEndianW(shdr->numSamples); while(iSmpCount < LittleEndianW(shdr->numSamples)) { ASSERT_CAN_READ(sizeof(PSM16SMPHEADER)); - PSM16SMPHEADER *smphdr = (PSM16SMPHEADER *)(lpStream + dwMemPos); + const PSM16SMPHEADER *smphdr = (PSM16SMPHEADER *)(lpStream + dwMemPos); dwMemPos += sizeof(PSM16SMPHEADER); SAMPLEINDEX iSmp = LittleEndianW(smphdr->sampleNumber); @@ -943,39 +949,34 @@ Samples[iSmp].nLoopStart = LittleEndian(smphdr->loopStart); Samples[iSmp].nLoopEnd = LittleEndian(smphdr->loopEnd); Samples[iSmp].nC5Speed = LittleEndianW(smphdr->c2freq); - if(smphdr->finetune & 0x0F) - { - int finetune = smphdr->finetune & 0x0F; - if(finetune >= 8) - { - finetune -= 16; - } - // Copied over from DUMB - Samples[iSmp].nC5Speed = double(Samples[iSmp].nC5Speed) * pow(1.000225659305069791926712241547647863626, finetune * 32); - } + + // It seems like that finetune and transpose are added to the already given c2freq... That's a double WTF! Why on earth would you want to use both systems at the same time? + FrequencyToTranspose(&Samples[iSmp]); + Samples[iSmp].nC5Speed = TransposeToFrequency(Samples[iSmp].RelativeTone + (smphdr->finetune >> 4) - 7, MOD2XMFineTune(smphdr->finetune & 0x0F)); + Samples[iSmp].nVolume = smphdr->volume << 2; Samples[iSmp].nGlobalVol = 256; - UINT iSampleFormat = RS_PCM8S; + UINT sampleFormat = RS_PCM8S; if(smphdr->flags & 0x04) // 16-Bit { Samples[iSmp].uFlags |= CHN_16BIT; Samples[iSmp].nLength >>= 1; - iSampleFormat = RS_PCM16S; + sampleFormat = RS_PCM16S; } if(smphdr->flags & 0x08) // Signed/Unsigned { if(Samples[iSmp].uFlags & CHN_16BIT) - iSampleFormat = RS_PCM16U; + sampleFormat = RS_PCM16U; else - iSampleFormat = RS_PCM8U; + sampleFormat = RS_PCM8U; } if(smphdr->flags & 0x10) // Delta/Raw { if(Samples[iSmp].uFlags & CHN_16BIT) - iSampleFormat = RS_PCM16D; + sampleFormat = RS_PCM16D; else - iSampleFormat = RS_PCM8D; + sampleFormat = RS_PCM8D; } if(smphdr->flags & 0x20) // Bidi Loop { @@ -986,9 +987,9 @@ Samples[iSmp].uFlags |= CHN_LOOP; } if((smphdr->flags & 0x7F) == 0) - iSampleFormat = RS_PCM8D; + sampleFormat = RS_PCM8D; - ReadSample(&Samples[iSmp], iSampleFormat, reinterpret_cast<LPCSTR>(lpStream + LittleEndianW(smphdr->offset)), dwMemLength - LittleEndianW(smphdr->offset)); + ReadSample(&Samples[iSmp], sampleFormat, reinterpret_cast<LPCSTR>(lpStream + LittleEndianW(smphdr->offset)), dwMemLength - LittleEndianW(smphdr->offset)); iSmpCount++; } @@ -997,7 +998,7 @@ // Read patterns dwMemPos = LittleEndian(shdr->patOffset); ASSERT_CAN_READ(LittleEndian(shdr->patSize)); - if(LittleEndian(shdr->patOffset) > 4 && LittleEndian(*(DWORD *)(lpStream + dwMemPos - 4)) == 0x54415050) // PPAT + if(LittleEndian(shdr->patOffset) > 4 && *(uint32 *)(lpStream + dwMemPos - 4) == LittleEndian(PSM16_PPAT)) // PPAT { DWORD dwPatEndPos = LittleEndian(shdr->patOffset) + LittleEndian(shdr->patSize); @@ -1013,34 +1014,33 @@ if(Patterns.Insert(nPat, phdr->numRows)) break; - MODCOMMAND *row_data; - ROWINDEX iRow = 0; + ROWINDEX curRow = 0; - while(dwMemPos < dwNextPattern && iRow < phdr->numRows) + while(dwMemPos < dwNextPattern && curRow < phdr->numRows) { ASSERT_CAN_READ(1); - BYTE bChnFlag = lpStream[dwMemPos++]; + uint8 bChnFlag = lpStream[dwMemPos++]; if(bChnFlag == 0) { - iRow++; + curRow++; continue; } - row_data = Patterns[nPat].GetpModCommand(iRow, min(bChnFlag & 0x1F, m_nChannels - 1)); + MODCOMMAND *rowData = Patterns[nPat].GetpModCommand(curRow, min(bChnFlag & 0x1F, m_nChannels - 1)); if(bChnFlag & 0x80) { // note + instr present ASSERT_CAN_READ(2); - row_data->note = lpStream[dwMemPos++] + 36; - row_data->instr = lpStream[dwMemPos++]; + rowData->note = lpStream[dwMemPos++] + 36; + rowData->instr = lpStream[dwMemPos++]; } if(bChnFlag & 0x40) { // volume present ASSERT_CAN_READ(1); - row_data->volcmd = VOLCMD_VOLUME; - row_data->vol = lpStream[dwMemPos++]; + rowData->volcmd = VOLCMD_VOLUME; + rowData->vol = lpStream[dwMemPos++]; } if(bChnFlag & 0x20) { @@ -1140,9 +1140,9 @@ command = CMD_S3MCMDEX; if(param == 0) // in S3M mode, SC0 is ignored, so we convert it to a note cut. { - if(row_data->note == NOTE_NONE) + if(rowData->note == NOTE_NONE) { - row_data->note = NOTE_NOTECUT; + rowData->note = NOTE_NOTECUT; command = CMD_NONE; } else { @@ -1198,8 +1198,8 @@ break; } - row_data->command = command; - row_data->param = param; + rowData->command = command; + rowData->param = param; } } // Pattern break for short patterns (so saving the modules as S3M won't break it) Modified: trunk/OpenMPT/soundlib/mod_specifications.h =================================================================== --- trunk/OpenMPT/soundlib/mod_specifications.h 2011-11-22 19:46:44 UTC (rev 1141) +++ trunk/OpenMPT/soundlib/mod_specifications.h 2011-12-03 15:54:55 UTC (rev 1142) @@ -43,8 +43,8 @@ uint16 sampleFilenameLengthMax; // Dito uint16 instrNameLengthMax; // Dito uint16 instrFilenameLengthMax; // Dito - SAMPLEINDEX samplesMax; - INSTRUMENTINDEX instrumentsMax; + SAMPLEINDEX samplesMax; // Max number of samples == Highest possible sample index + INSTRUMENTINDEX instrumentsMax; // Max number of instruments == Highest possible instrument index BYTE defaultMixLevels; BYTE MIDIMappingDirectivesMax; UINT speedMin; // Minimum ticks per frame @@ -58,6 +58,7 @@ bool hasRestartPos; bool supportsPlugins; bool hasPatternSignatures; // Can patterns have a custom time signature? + DWORD songFlags; // Supported song flags }; @@ -91,8 +92,8 @@ 12, // Max sample filename length 26, // Max instrument name length 12, // Max instrument filename length - 4000, // SamplesMax - 256, // instrumentMax + 3999, // SamplesMax + 255, // instrumentMax mixLevels_117RC3, // defaultMixLevels 200, // Max MIDI mapping directives 1, // Min Speed @@ -106,6 +107,7 @@ true, // Has restart position (order) true, // Supports plugins true, // Custom pattern time signatures + SONG_LINEARSLIDES | SONG_EXFILTERRANGE | SONG_ITOLDEFFECTS | SONG_ITCOMPATGXX | SONG_EMBEDMIDICFG, // Supported song flags }; @@ -149,6 +151,7 @@ true, // Has restart position (order) false, // Doesn't support plugins false, // No custom pattern time signatures + SONG_PT1XMODE, // Supported song flags }; @@ -190,6 +193,7 @@ true, // Has restart position (order) false, // Doesn't support plugins false, // No custom pattern time signatures + SONG_LINEARSLIDES, // Supported song flags }; // XM with MPT extensions @@ -216,8 +220,8 @@ 0, // Max sample filename length 22, // Max instrument name length 0, // Max instrument filename length - MAX_SAMPLES, // SamplesMax (actually 32 per instrument(256 * 32 = 8192), but limited to MAX_SAMPLES = 4000) - 256, // instrumentMax + MAX_SAMPLES - 1, // SamplesMax (actually 32 per instrument(256 * 32 = 8192), but limited to MAX_SAMPLES = 4000) + 255, // instrumentMax mixLevels_compatible, // defaultMixLevels 200, // Max MIDI mapping directives 1, // Min Speed @@ -231,6 +235,7 @@ true, // Has restart position (order) true, // Supports plugins false, // No custom pattern time signatures + SONG_LINEARSLIDES | SONG_EXFILTERRANGE | SONG_EMBEDMIDICFG, // Supported song flags }; const CModSpecifications s3m = @@ -271,6 +276,7 @@ false, // Doesn't have restart position (order) false, // Doesn't support plugins false, // No custom pattern time signatures + SONG_FASTVOLSLIDES | SONG_AMIGALIMITS, // Supported song flags }; // S3M with MPT extensions @@ -312,6 +318,7 @@ false, // Doesn't have restart position (order) false, // Doesn't support plugins false, // No custom pattern time signatures + SONG_FASTVOLSLIDES | SONG_AMIGALIMITS, // Supported song flags }; const CModSpecifications it = @@ -352,6 +359,7 @@ false, // Doesn't have restart position (order) false, // Doesn't support plugins false, // No custom pattern time signatures + SONG_LINEARSLIDES | SONG_ITOLDEFFECTS | SONG_ITCOMPATGXX | SONG_EMBEDMIDICFG, // Supported song flags }; const CModSpecifications itEx = @@ -377,8 +385,8 @@ 12, // Max sample filename length 25, // Max instrument name length 12, // Max instrument filename length - 4000, // SamplesMax - 256, // instrumentMax + 3999, // SamplesMax + 255, // instrumentMax mixLevels_compatible, // defaultMixLevels 200, // Max MIDI mapping directives 1, // Min Speed @@ -392,6 +400,7 @@ false, // Doesn't have restart position (order) true, // Supports plugins false, // No custom pattern time signatures + SONG_LINEARSLIDES | SONG_EXFILTERRANGE | SONG_ITOLDEFFECTS | SONG_ITCOMPATGXX | SONG_EMBEDMIDICFG | SONG_ITPROJECT | SONG_ITPEMBEDIH, // Supported song flags }; static const CModSpecifications *Collection[] = { &mptm, &mod, &s3m, &s3mEx, &xm, &xmEx, &it, &itEx }; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2011-12-10 17:34:27
|
Revision: 1145 http://modplug.svn.sourceforge.net/modplug/?rev=1145&view=rev Author: saga-games Date: 2011-12-10 17:34:18 +0000 (Sat, 10 Dec 2011) Log Message: ----------- [Mod] Loading an instrument will not put samples into slots references by other instruments, even if those slots are empty (http://bugs.openmpt.org/view.php?id=213). Still kind of experimental. Modified Paths: -------------- trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/soundlib/Sampleio.cpp trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/Sndfile.h Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2011-12-10 14:59:35 UTC (rev 1144) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2011-12-10 17:34:18 UTC (rev 1145) @@ -934,8 +934,7 @@ m_SndFile.ResetChannelEnvelopes(pChn); m_SndFile.InstrumentChange(pChn, nins); pChn->nFadeOutVol = 0x10000; // Needed for XM files, as the nRowInstr check in NoteChange() will fail. - } - else if ((nsmp) && (nsmp < MAX_SAMPLES)) // Or set sample + } else if ((nsmp) && (nsmp < MAX_SAMPLES)) // Or set sample { MODSAMPLE &sample = m_SndFile.GetSample(nsmp); pChn->pCurrentSample = sample.pSample; @@ -1414,16 +1413,7 @@ bool CModDoc::IsChildSample(INSTRUMENTINDEX nIns, SAMPLEINDEX nSmp) const //----------------------------------------------------------------------- { - if((nIns < 1) || (nIns > m_SndFile.GetNumInstruments())) return false; - MODINSTRUMENT *pIns = m_SndFile.Instruments[nIns]; - if(pIns != nullptr) - { - for(UINT i = 0; i < NOTE_MAX; i++) - { - if(pIns->Keyboard[i] == nSmp) return true; - } - } - return false; + return m_SndFile.IsSampleReferencedByInstrument(nSmp, nIns); } Modified: trunk/OpenMPT/mptrack/Modedit.cpp =================================================================== --- trunk/OpenMPT/mptrack/Modedit.cpp 2011-12-10 14:59:35 UTC (rev 1144) +++ trunk/OpenMPT/mptrack/Modedit.cpp 2011-12-10 17:34:18 UTC (rev 1145) @@ -487,18 +487,10 @@ SAMPLEINDEX CModDoc::InsertSample(bool bLimit) //-------------------------------------------- { - SAMPLEINDEX i = 1; - for(i = 1; i <= m_SndFile.m_nSamples; i++) + SAMPLEINDEX i = m_SndFile.GetNextFreeSample(); + + if ((bLimit && i >= 200 && !m_SndFile.GetNumInstruments()) || i == SAMPLEINDEX_INVALID) { - if ((!m_SndFile.m_szNames[i][0]) && (m_SndFile.GetSample(i).pSample == NULL)) - { - if ((!m_SndFile.m_nInstruments) || (!m_SndFile.IsSampleUsed(i))) - break; - } - } - if (((bLimit) && (i >= 200) && (!m_SndFile.m_nInstruments)) - || (i > m_SndFile.GetModSpecifications().samplesMax)) - { ErrorBox(IDS_ERR_TOOMANYSMP, CMainFrame::GetMainFrame()); return SAMPLEINDEX_INVALID; } @@ -518,7 +510,7 @@ if (m_SndFile.GetModSpecifications().instrumentsMax == 0) return INSTRUMENTINDEX_INVALID; MODINSTRUMENT *pDup = nullptr; - const INSTRUMENTINDEX nInstrumentMax = m_SndFile.GetModSpecifications().instrumentsMax; + if ((nDuplicate > 0) && (nDuplicate <= m_SndFile.m_nInstruments)) { pDup = m_SndFile.Instruments[nDuplicate]; @@ -539,23 +531,15 @@ } } } - UINT newins = 0; - for (INSTRUMENTINDEX i = 1; i <= m_SndFile.m_nInstruments; i++) + + const INSTRUMENTINDEX newins = m_SndFile.GetNextFreeInstrument(); + if(newins == INSTRUMENTINDEX_INVALID) { - if (!m_SndFile.Instruments[i]) - { - newins = i; - break; - } - } - if (!newins) + ErrorBox(IDS_ERR_TOOMANYINS, CMainFrame::GetMainFrame()); + return INSTRUMENTINDEX_INVALID; + } else if(newins > m_SndFile.GetNumInstruments()) { - if (m_SndFile.m_nInstruments >= nInstrumentMax) - { - ErrorBox(IDS_ERR_TOOMANYINS, CMainFrame::GetMainFrame()); - return INSTRUMENTINDEX_INVALID; - } - newins = ++m_SndFile.m_nInstruments; + m_SndFile.m_nInstruments = newins; } // Determine which sample slot to use @@ -712,7 +696,7 @@ { bool instrumentsLeft = false; - if(m_SndFile.DestroyInstrument(nIns, askdeleteAssociatedSamples)) + if(m_SndFile.DestroyInstrument(nIns, askDeleteAssociatedSamples)) { CriticalSection cs; if (nIns == m_SndFile.m_nInstruments) m_SndFile.m_nInstruments--; @@ -745,13 +729,13 @@ if (!bCopy) { m_SndFile.Order.SetSequence(nSourceSeq); - for (ORDERINDEX i = nSourceNdx; i < m_SndFile.Order.size() - 1; i++) m_SndFile.Order[i] = m_SndFile.Order[i + 1]; - if (nSourceNdx < nDestNdx) nDestNdx--; + m_SndFile.Order.Remove(nSourceNdx, nSourceNdx); + if (nSourceNdx < nDestNdx && nSourceSeq == nDestSeq) nDestNdx--; } // Insert at dest m_SndFile.Order.SetSequence(nDestSeq); - for (ORDERINDEX nOrd = m_SndFile.Order.size() - 1; nOrd > nDestNdx; nOrd--) m_SndFile.Order[nOrd] = m_SndFile.Order[nOrd - 1]; - m_SndFile.Order[nDestNdx] = nSourcePat; + m_SndFile.Order.Insert(nDestNdx, 1, nSourcePat); + if (bUpdate) { UpdateAllViews(NULL, HINT_MODSEQUENCE, NULL); Modified: trunk/OpenMPT/soundlib/Sampleio.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sampleio.cpp 2011-12-10 14:59:35 UTC (rev 1144) +++ trunk/OpenMPT/soundlib/Sampleio.cpp 2011-12-10 17:34:18 UTC (rev 1145) @@ -54,8 +54,8 @@ bool CSoundFile::ReadSampleAsInstrument(INSTRUMENTINDEX nInstr, LPBYTE lpMemFile, DWORD dwFileLength) //--------------------------------------------------------------------------------------------------- { - uint32 *psig = (uint32 *)lpMemFile; - if ((!lpMemFile) || (dwFileLength < 128)) return false; + uint32 *psig = reinterpret_cast<uint32 *>(lpMemFile); + if ((!lpMemFile) || (dwFileLength < 80)) return false; if (((psig[0] == LittleEndian(0x46464952)) && (psig[2] == LittleEndian(0x45564157))) // RIFF....WAVE signature || ((psig[0] == LittleEndian(0x5453494C)) && (psig[2] == LittleEndian(0x65766177))) // LIST....wave || (psig[76/4] == LittleEndian(0x53524353)) // S3I signature @@ -66,23 +66,11 @@ { // Loading Instrument - // Scanning free sample - SAMPLEINDEX nSample = 0; - for (SAMPLEINDEX iscan = 1; iscan < MAX_SAMPLES; iscan++) - { - if ((!Samples[iscan].pSample) && (!m_szNames[iscan][0])) - { - nSample = iscan; - if (nSample > m_nSamples) m_nSamples = nSample; - break; - } - } - MODINSTRUMENT *pIns; try { - pIns = new MODINSTRUMENT(nSample); + pIns = new MODINSTRUMENT(); } catch(MPTMemoryException) { return false; @@ -91,7 +79,19 @@ DestroyInstrument(nInstr, deleteAssociatedSamples); Instruments[nInstr] = pIns; - if (nSample) ReadSampleFromFile(nSample, lpMemFile, dwFileLength); + // Scanning free sample + SAMPLEINDEX nSample = GetNextFreeSample(nInstr); + if(nSample == SAMPLEINDEX_INVALID) + { + return false; + } else if(nSample > GetNumSamples()) + { + m_nSamples = nSample; + } + + Instruments[nInstr]->AssignSample(nSample); + + ReadSampleFromFile(nSample, lpMemFile, dwFileLength); return true; } return false; @@ -104,7 +104,8 @@ if ((!nInstr) || (nInstr > m_nInstruments)) return false; if (!Instruments[nInstr]) return true; - if(removeSamples == askdeleteAssociatedSamples) +#ifdef MODPLUG_TRACKER + if(removeSamples == askDeleteAssociatedSamples) { ConfirmAnswer result = Reporting::Confirm("Remove samples associated with an instrument if they are unused?", "Removing instrument", true); if(result == cnfCancel) @@ -113,6 +114,7 @@ } removeSamples = (result == cnfYes) ? deleteAssociatedSamples : doNoDeleteAssociatedSamples; } +#endif // MODPLUG_TRACKER if(removeSamples == deleteAssociatedSamples) { RemoveInstrumentSamples(nInstr); @@ -213,7 +215,7 @@ vector<SAMPLEINDEX> sourceSample; // Sample index in source song vector<SAMPLEINDEX> targetSample; // Sample index in target song - SAMPLEINDEX targetIndex = 1; // Next index for inserting sample + SAMPLEINDEX targetIndex = 0; // Next index for inserting sample for(size_t i = 0; i < CountOf(pIns->Keyboard); i++) { @@ -224,12 +226,12 @@ if(entry == sourceSample.end()) { // Didn't consider this sample yet, so add it to our map. - while((targetIndex < MAX_SAMPLES) && ((Samples[targetIndex].pSample) || (m_szNames[targetIndex][0]))) targetIndex++; + targetIndex = GetNextFreeSample(targetInstr, targetIndex + 1); if(targetIndex <= GetModSpecifications().samplesMax) { sourceSample.push_back(sourceIndex); targetSample.push_back(targetIndex); - pIns->Keyboard[i] = targetIndex++; + pIns->Keyboard[i] = targetIndex; } else { pIns->Keyboard[i] = 0; @@ -548,8 +550,8 @@ /////////////////////////////////////////////////////////////// // Save WAV -bool CSoundFile::SaveWAVSample(UINT nSample, LPCSTR lpszFileName) -//--------------------------------------------------------------- +bool CSoundFile::SaveWAVSample(UINT nSample, LPCSTR lpszFileName) const +//--------------------------------------------------------------------- { LPCSTR lpszMPT = "Modplug Tracker\0"; WAVEFILEHEADER header; @@ -558,7 +560,7 @@ WAVESAMPLERINFO smpl; WAVELISTHEADER list; WAVEEXTRAHEADER extra; - MODSAMPLE *pSmp = &Samples[nSample]; + const MODSAMPLE *pSmp = &Samples[nSample]; FILE *f; if ((f = fopen(lpszFileName, "wb")) == NULL) return false; @@ -572,7 +574,7 @@ format.hdrlen = 16; format.format = 1; format.freqHz = pSmp->nC5Speed; - if (m_nType & (MOD_TYPE_MOD|MOD_TYPE_XM)) format.freqHz = TransposeToFrequency(pSmp->RelativeTone, pSmp->nFineTune); + if (GetType() & (MOD_TYPE_MOD|MOD_TYPE_XM)) format.freqHz = TransposeToFrequency(pSmp->RelativeTone, pSmp->nFineTune); format.channels = pSmp->GetNumChannels(); format.bitspersample = pSmp->GetElementarySampleSize() * 8; format.samplesize = pSmp->GetBytesPerSample() * 8; @@ -648,7 +650,7 @@ extra.nVibSweep = pSmp->nVibSweep; extra.nVibDepth = pSmp->nVibDepth; extra.nVibRate = pSmp->nVibRate; - if(GetType() & MOD_TYPE_XM && (extra.nVibDepth | extra.nVibRate)) + if((GetType() & MOD_TYPE_XM) && (extra.nVibDepth | extra.nVibRate)) { // XM vibrato is upside down extra.nVibSweep = 255 - extra.nVibSweep; @@ -662,10 +664,10 @@ /////////////////////////////////////////////////////////////// // Save RAW -bool CSoundFile::SaveRAWSample(UINT nSample, LPCSTR lpszFileName) -//--------------------------------------------------------------- +bool CSoundFile::SaveRAWSample(UINT nSample, LPCSTR lpszFileName) const +//--------------------------------------------------------------------- { - MODSAMPLE *pSmp = &Samples[nSample]; + const MODSAMPLE *pSmp = &Samples[nSample]; FILE *f; if ((f = fopen(lpszFileName, "wb")) == NULL) return false; @@ -735,7 +737,7 @@ // -- GF1 Envelopes -- // -// It can be represented like this (the enveloppe is totally bogus, it is +// It can be represented like this (the envelope is totally bogus, it is // just to show the concept): // // | @@ -760,7 +762,7 @@ // bit 3: off/on bidirectionnal looping // bit 4: off/on backward looping // bit 5: off/on sustaining (3rd point in env.) -// bit 6: off/on enveloppes +// bit 6: off/on envelopes // bit 7: off/on clamped release (6th point, env) typedef struct GF1LAYER @@ -900,19 +902,19 @@ memcpy(pIns->name, pih->name, 16); pIns->name[16] = 0; pIns->nFadeOut = 2048; - if (m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT)) + if (GetType() & (MOD_TYPE_IT|MOD_TYPE_MPT)) { pIns->nNNA = NNA_NOTEOFF; pIns->nDNA = DNA_NOTEFADE; } - UINT nFreeSmp = 1; + UINT nFreeSmp = 0; UINT nMinSmpNote = 0xff; UINT nMinSmp = 0; for (UINT iSmp=0; iSmp<nSamples; iSmp++) { // Find a free sample - while ((nFreeSmp < MAX_SAMPLES) && ((Samples[nFreeSmp].pSample) || (m_szNames[nFreeSmp][0]))) nFreeSmp++; - if (nFreeSmp >= MAX_SAMPLES) break; + nFreeSmp = GetNextFreeSample(nInstr, nFreeSmp + 1); + if (nFreeSmp == SAMPLEINDEX_INVALID) break; if (m_nSamples < nFreeSmp) m_nSamples = nFreeSmp; if (!nMinSmp) nMinSmp = nFreeSmp; // Load it @@ -930,10 +932,9 @@ && ((LONG)k >= nMinNote) && ((LONG)k <= nMaxNote))) { - if (psh->scale_factor) - pIns->NoteMap[k] = (BYTE)(k+1); - else - pIns->NoteMap[k] = 5*12+1; + if(!psh->scale_factor) + pIns->NoteMap[k] = NOTE_MIDDLEC; + pIns->Keyboard[k] = nFreeSmp; if (k < nMinSmpNote) { @@ -1123,24 +1124,23 @@ nsamples = 0; for (UINT i=0; i<96; i++) { - pIns->NoteMap[i+12] = i+1+12; if (pih->snum[i] > nsamples) nsamples = pih->snum[i]; } nsamples++; if (nsamples > 32) nsamples = 32; // Allocate samples MemsetZero(samplemap); - UINT nsmp = 1; + SAMPLEINDEX nsmp = 0; for (UINT j=0; j<nsamples; j++) { - while ((nsmp < MAX_SAMPLES) && ((Samples[nsmp].pSample) || (m_szNames[nsmp][0]))) nsmp++; - if (nsmp >= MAX_SAMPLES) break; + nsmp = GetNextFreeSample(nInstr, nsmp + 1); + if (nsmp == SAMPLEINDEX_INVALID) break; samplemap[j] = nsmp; - if (m_nSamples < nsmp) m_nSamples = nsmp; - nsmp++; } + if (m_nSamples < nsmp) m_nSamples = nsmp; + // Setting up instrument header - for (UINT k=0; k<96; k++) + for (size_t k = 0; k < 96; k++) { UINT n = pih->snum[k]; if (n < nsamples) pIns->Keyboard[k+12] = samplemap[n]; @@ -1243,7 +1243,7 @@ pSmp->nFineTune = psh->finetune; pSmp->nC5Speed = 8363; pSmp->RelativeTone = (int)psh->relnote; - if (m_nType != MOD_TYPE_XM) + if (GetType() != MOD_TYPE_XM) { pSmp->nC5Speed = TransposeToFrequency(pSmp->RelativeTone, pSmp->nFineTune); pSmp->RelativeTone = 0; @@ -1287,8 +1287,8 @@ } -bool CSoundFile::SaveXIInstrument(INSTRUMENTINDEX nInstr, LPCSTR lpszFileName) -//---------------------------------------------------------------------------- +bool CSoundFile::SaveXIInstrument(INSTRUMENTINDEX nInstr, LPCSTR lpszFileName) const +//---------------------------------------------------------------------------------- { XIFILEHEADER xfh; XIINSTRUMENTHEADER xih; @@ -1365,38 +1365,38 @@ // XI Sample Headers for (UINT ismp=0; ismp<nsamples; ismp++) { - MODSAMPLE *pSmp = &Samples[smptable[ismp]]; - xsh.samplen = pSmp->nLength; - xsh.loopstart = pSmp->nLoopStart; - xsh.looplen = pSmp->nLoopEnd - pSmp->nLoopStart; - xsh.vol = pSmp->nVolume >> 2; - xsh.finetune = (signed char)pSmp->nFineTune; + const MODSAMPLE &sample = Samples[smptable[ismp]]; + xsh.samplen = sample.nLength; + xsh.loopstart = sample.nLoopStart; + xsh.looplen = sample.nLoopEnd - sample.nLoopStart; + xsh.vol = sample.nVolume >> 2; + xsh.finetune = (signed char)sample.nFineTune; xsh.type = 0; - if (pSmp->uFlags & CHN_16BIT) + if (sample.uFlags & CHN_16BIT) { xsh.type |= 0x10; xsh.samplen *= 2; xsh.loopstart *= 2; xsh.looplen *= 2; } - if (pSmp->uFlags & CHN_STEREO) + if (sample.uFlags & CHN_STEREO) { xsh.type |= 0x20; xsh.samplen *= 2; xsh.loopstart *= 2; xsh.looplen *= 2; } - if (pSmp->uFlags & CHN_LOOP) + if (sample.uFlags & CHN_LOOP) { - xsh.type |= (pSmp->uFlags & CHN_PINGPONGLOOP) ? 0x02 : 0x01; + xsh.type |= (sample.uFlags & CHN_PINGPONGLOOP) ? 0x02 : 0x01; } - xsh.pan = (BYTE)pSmp->nPan; - if (pSmp->nPan > 0xFF) xsh.pan = 0xFF; - if ((m_nType & MOD_TYPE_XM) || (!pSmp->nC5Speed)) - xsh.relnote = (signed char) pSmp->RelativeTone; + xsh.pan = (BYTE)sample.nPan; + if (sample.nPan > 0xFF) xsh.pan = 0xFF; + if ((GetType() & MOD_TYPE_XM) || (!sample.nC5Speed)) + xsh.relnote = (signed char) sample.RelativeTone; else { - int f2t = FrequencyToTranspose(pSmp->nC5Speed); + int f2t = FrequencyToTranspose(sample.nC5Speed); xsh.relnote = (signed char)(f2t >> 7); xsh.finetune = (signed char)(f2t & 0x7F); } @@ -1414,8 +1414,8 @@ WriteSample(f, pSmp, smpflags); } - __int32 code = 'MPTX'; - fwrite(&code, 1, sizeof(__int32), f); // Write extension tag + int32 code = 'MPTX'; + fwrite(&code, 1, sizeof(int32), f); // Write extension tag WriteInstrumentHeaderStruct(pIns, f); // Write full extended header. @@ -1616,10 +1616,10 @@ pSmp->nGlobalVol = 64; pSmp->uFlags = (pcomm->wSampleSize > 0x0800) ? CHN_16BIT : 0; if (pcomm->wChannels >= 0x0200) pSmp->uFlags |= CHN_STEREO; - if (m_nType & MOD_TYPE_XM) pSmp->uFlags |= CHN_PANNING; + if (GetType() & MOD_TYPE_XM) pSmp->uFlags |= CHN_PANNING; pSmp->RelativeTone = 0; pSmp->nFineTune = 0; - if (m_nType & MOD_TYPE_XM) FrequencyToTranspose(pSmp); + if (GetType() & MOD_TYPE_XM) FrequencyToTranspose(pSmp); pSmp->nVibType = pSmp->nVibSweep = pSmp->nVibDepth = pSmp->nVibRate = 0; pSmp->filename[0] = 0; m_szNames[nSample][0] = 0; @@ -1721,9 +1721,8 @@ //---------------------------------------------------------------------------------------------- { ITINSTRUMENT *pinstr = (ITINSTRUMENT *)lpMemFile; - WORD samplemap[NOTE_MAX]; //rewbs.noSamplePerInstroLimit (120 was 64) DWORD dwMemPos; - UINT nsmp, nsamples; + UINT nsmp = 0, nsamples; if ((!lpMemFile) || (dwFileLength < sizeof(ITINSTRUMENT)) || (pinstr->id != LittleEndian(IT_IMPI))) return false; @@ -1742,15 +1741,9 @@ DestroyInstrument(nInstr, deleteAssociatedSamples); Instruments[nInstr] = pIns; - MemsetZero(samplemap); dwMemPos = 554; dwMemPos += ITInstrToMPT(pinstr, pIns, pinstr->trkvers); nsamples = pinstr->nos; -// -> CODE#0019 -// -> DESC="correctly load ITI & XI instruments sample note map" -// if (nsamples >= 64) nsamples = 64; -// -! BUG_FIX#0019 - nsmp = 1; // -> CODE#0027 // -> DESC="per-instrument volume ramping setup (refered as attack)" @@ -1761,11 +1754,11 @@ // -! NEW_FEATURE#0027 // Reading Samples + vector<SAMPLEINDEX> samplemap(nsamples, 0); for (UINT i=0; i<nsamples; i++) { - while ((nsmp < MAX_SAMPLES) && ((Samples[nsmp].pSample) || (m_szNames[nsmp][0]))) nsmp++; - if (nsmp >= MAX_SAMPLES) break; - if (m_nSamples < nsmp) m_nSamples = nsmp; + nsmp = GetNextFreeSample(nInstr, nsmp + 1); + if (nsmp == SAMPLEINDEX_INVALID) break; samplemap[i] = nsmp; // -> CODE#0027 // -> DESC="per-instrument volume ramping setup (refered as attack)" @@ -1773,17 +1766,14 @@ lastSampleSize = ReadITSSample(nsmp, lpMemFile + dwMemPos, dwFileLength - dwMemPos, dwMemPos); // -! NEW_FEATURE#0027 dwMemPos += sizeof(ITSAMPLESTRUCT); - nsmp++; } - for (UINT j=0; j<128; j++) + if (m_nSamples < nsmp) m_nSamples = nsmp; + + for(size_t j = 0; j < CountOf(pIns->Keyboard); j++) { -// -> CODE#0019 -// -> DESC="correctly load ITI & XI instruments sample note map" -// if ((pIns->Keyboard[j]) && (pIns->Keyboard[j] <= 64)) - if (pIns->Keyboard[j]) -// -! BUG_FIX#0019 + if(pIns->Keyboard[j] && pIns->Keyboard[j] <= nsamples) { - pIns->Keyboard[j] = samplemap[pIns->Keyboard[j]-1]; + pIns->Keyboard[j] = samplemap[pIns->Keyboard[j] - 1]; } } @@ -1810,8 +1800,8 @@ } -bool CSoundFile::SaveITIInstrument(INSTRUMENTINDEX nInstr, LPCSTR lpszFileName) -//----------------------------------------------------------------------------- +bool CSoundFile::SaveITIInstrument(INSTRUMENTINDEX nInstr, LPCSTR lpszFileName) const +//----------------------------------------------------------------------------------- { BYTE buffer[554]; ITINSTRUMENT *iti = (ITINSTRUMENT *)buffer; @@ -1922,40 +1912,40 @@ UINT smpsize = 0; UINT nsmp = smptable[j]; MemsetZero(itss); - MODSAMPLE *psmp = &Samples[nsmp]; + const MODSAMPLE &sample = Samples[nsmp]; itss.id = LittleEndian(IT_IMPS); - memcpy(itss.filename, psmp->filename, 12); + memcpy(itss.filename, sample.filename, 12); StringFixer::FixNullString(itss.filename); memcpy(itss.name, m_szNames[nsmp], 26); StringFixer::FixNullString(itss.name); - itss.gvl = (BYTE)psmp->nGlobalVol; + itss.gvl = (BYTE)sample.nGlobalVol; itss.flags = 0x01; - if (psmp->uFlags & CHN_LOOP) itss.flags |= 0x10; - if (psmp->uFlags & CHN_SUSTAINLOOP) itss.flags |= 0x20; - if (psmp->uFlags & CHN_PINGPONGLOOP) itss.flags |= 0x40; - if (psmp->uFlags & CHN_PINGPONGSUSTAIN) itss.flags |= 0x80; - itss.C5Speed = psmp->nC5Speed; + if (sample.uFlags & CHN_LOOP) itss.flags |= 0x10; + if (sample.uFlags & CHN_SUSTAINLOOP) itss.flags |= 0x20; + if (sample.uFlags & CHN_PINGPONGLOOP) itss.flags |= 0x40; + if (sample.uFlags & CHN_PINGPONGSUSTAIN) itss.flags |= 0x80; + itss.C5Speed = sample.nC5Speed; if (!itss.C5Speed) itss.C5Speed = 8363; - itss.length = psmp->nLength; - itss.loopbegin = psmp->nLoopStart; - itss.loopend = psmp->nLoopEnd; - itss.susloopbegin = psmp->nSustainStart; - itss.susloopend = psmp->nSustainEnd; - itss.vol = psmp->nVolume >> 2; - itss.dfp = psmp->nPan >> 2; - itss.vit = autovibxm2it[psmp->nVibType & 7]; - itss.vir = min(psmp->nVibSweep, 255); + itss.length = sample.nLength; + itss.loopbegin = sample.nLoopStart; + itss.loopend = sample.nLoopEnd; + itss.susloopbegin = sample.nSustainStart; + itss.susloopend = sample.nSustainEnd; + itss.vol = sample.nVolume >> 2; + itss.dfp = sample.nPan >> 2; + itss.vit = autovibxm2it[sample.nVibType & 7]; + itss.vir = min(sample.nVibSweep, 255); if((itss.vid | itss.vis) && (GetType() & MOD_TYPE_XM)) { // Sweep is upside down in XM itss.vir = 255 - itss.vir; } - itss.vid = min(psmp->nVibDepth, 32); - itss.vis = min(psmp->nVibRate, 64); - if (psmp->uFlags & CHN_PANNING) itss.dfp |= 0x80; + itss.vid = min(sample.nVibDepth, 32); + itss.vis = min(sample.nVibRate, 64); + if (sample.uFlags & CHN_PANNING) itss.dfp |= 0x80; itss.cvt = 0x01; - smpsize = psmp->nLength; - if (psmp->uFlags & CHN_16BIT) + smpsize = sample.nLength; + if (sample.uFlags & CHN_16BIT) { itss.flags |= 0x02; smpsize <<= 1; @@ -1964,7 +1954,7 @@ itss.flags &= ~(0x02); } //rewbs.enableStereoITI - if (psmp->uFlags & CHN_STEREO) + if (sample.uFlags & CHN_STEREO) { itss.flags |= 0x04; smpsize <<= 1; @@ -1990,15 +1980,15 @@ //UINT nsmp = smptable[k]; //MODINSTRUMENT *psmp = &Ins[nsmp]; //WriteSample(f, psmp, (psmp->uFlags & CHN_16BIT) ? RS_PCM16S : RS_PCM8S); - MODSAMPLE *pSmp = &Samples[smptable[k]]; + const MODSAMPLE *pSmp = &Samples[smptable[k]]; UINT smpflags = (pSmp->uFlags & CHN_16BIT) ? RS_PCM16S : RS_PCM8S; if (pSmp->uFlags & CHN_STEREO) smpflags = (pSmp->uFlags & CHN_16BIT) ? RS_STPCM16S : RS_STPCM8S; WriteSample(f, pSmp, smpflags); // -! BUG_FIX#0001 } - __int32 code = 'MPTX'; - fwrite(&code, 1, sizeof(__int32), f); // Write extension tag + int32 code = 'MPTX'; + fwrite(&code, 1, sizeof(int32), f); // Write extension tag WriteInstrumentHeaderStruct(pIns, f); // Write full extended header. fclose(f); @@ -2169,7 +2159,7 @@ if (!pSmp->nC5Speed) pSmp->nC5Speed = 22050; pSmp->RelativeTone = 0; pSmp->nFineTune = 0; - if (m_nType & MOD_TYPE_XM) FrequencyToTranspose(pSmp); + if (GetType() & MOD_TYPE_XM) FrequencyToTranspose(pSmp); dwMemPos += BigEndian(pvh->dwSize) + 8; while (dwMemPos + 8 < dwFileLength) { @@ -2316,10 +2306,7 @@ if(toType & MOD_TYPE_XM) { - for(size_t i = 0; i < CountOf(pIns->NoteMap); i++) - { - pIns->NoteMap[i] = static_cast<BYTE>(i + 1); - } + pIns->ResetNoteMap(); // Convert sustain loops to sustain "points" pIns->VolEnv.nSustainEnd = pIns->VolEnv.nSustainStart; Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2011-12-10 14:59:35 UTC (rev 1144) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2011-12-10 17:34:18 UTC (rev 1145) @@ -2389,7 +2389,7 @@ int f2t = FrequencyToTranspose(psmp->nC5Speed); int transp = f2t >> 7; int ftune = f2t & 0x7F; //0x7F == 111 1111 - if (ftune > 80) + if (ftune > 80) // XXX I'm pretty sure this is supposed to be 0x80. { transp++; ftune -= 128; @@ -2823,6 +2823,89 @@ } +// Find an unused sample slot. If it is going to be assigned to an instrument, targetInstrument should be specified. +// SAMPLEINDEX_INVLAID is returned if no free sample slot could be found. +SAMPLEINDEX CSoundFile::GetNextFreeSample(INSTRUMENTINDEX targetInstrument, SAMPLEINDEX start) const +//-------------------------------------------------------------------------------------------------- +{ + // Find empty slot in two passes - in the first pass, we only search for samples with empty sample names, + // in the second pass we check all samples with non-empty sample names. + for(int passes = 0; passes < 2; passes++) + { + for(SAMPLEINDEX i = start; i <= GetModSpecifications().samplesMax; i++) + { + // When loading into an instrument, ignore non-empty sample names. Else, only use this slot if the sample name is empty or we're in second pass. + if(Samples[i].pSample == nullptr && (!m_szNames[i][0] || passes == 1 || targetInstrument != INSTRUMENTINDEX_INVALID)) + { + // Empty slot, so it's a good candidate already. + + // In instrument mode, check whether any instrument references this sample slot. If that is the case, we won't use it as it could lead to unwanted conflicts. + // If we are loading the sample *into* an instrument, we should also not consider that instrument's sample map, since it might be inconsistent at this time. + bool isReferenced = false; + for(INSTRUMENTINDEX ins = 1; ins < GetNumInstruments(); ins++) + { + if(ins == targetInstrument) + { + continue; + } + if(IsSampleReferencedByInstrument(i, ins)) + { + isReferenced = true; + break; + } + } + if(!isReferenced) + { + return i; + } + } + } + } + + return SAMPLEINDEX_INVALID; +} + + +// Find an unused instrument slot. +// INSTRUMENTINDEX_INVALID is returned if no free instrument slot could be found. +INSTRUMENTINDEX CSoundFile::GetNextFreeInstrument(INSTRUMENTINDEX start) const +//---------------------------------------------------------------------------- +{ + for(INSTRUMENTINDEX i = start; i <= GetModSpecifications().instrumentsMax; i++) + { + if(Instruments[i] == nullptr) + { + return i; + } + } + + return INSTRUMENTINDEX_INVALID; +} + + +// Check whether a given sample is used by a given instrument. +bool CSoundFile::IsSampleReferencedByInstrument(SAMPLEINDEX sample, INSTRUMENTINDEX instr) const +//---------------------------------------------------------------------------------------------- +{ + MODINSTRUMENT *targetIns = nullptr; + if(instr > 0 && instr <= GetNumInstruments()) + { + targetIns = Instruments[instr]; + } + if(targetIns != nullptr) + { + for(size_t note = 0; note < NOTE_MAX /*CountOf(targetIns->Keyboard)*/; note++) + { + if(targetIns->Keyboard[note] == sample) + { + return true; + } + } + } + return false; +} + + // Set up channel panning and volume suitable for MOD + similar files. If the current mod type is not MOD, bForceSetup has to be set to true. void CSoundFile::SetupMODPanning(bool bForceSetup) //------------------------------------------------ Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2011-12-10 14:59:35 UTC (rev 1144) +++ trunk/OpenMPT/soundlib/Sndfile.h 2011-12-10 17:34:18 UTC (rev 1145) @@ -198,14 +198,29 @@ pTuning = s_DefaultTuning; + AssignSample(sample); + ResetNoteMap(); + + MemsetZero(name); + MemsetZero(filename); + } + + // Assign all notes to a given sample. + void AssignSample(SAMPLEINDEX sample) + { for(size_t n = 0; n < CountOf(Keyboard); n++) { Keyboard[n] = sample; - NoteMap[n] = (BYTE)(n + 1); } + } - MemsetZero(name); - MemsetZero(filename); + // Reset note mapping (i.e. every note is mapped to itself) + void ResetNoteMap() + { + for(size_t n = 0; n < CountOf(NoteMap); n++) + { + NoteMap[n] = static_cast<BYTE>(n + 1); + } } bool IsCutoffEnabled() const { return (nIFC & 0x80) != 0; } @@ -250,7 +265,7 @@ // First 32-bytes: Most used mixing information: don't change it // These fields are accessed directly by the MMX mixing code (look out for CHNOFS_PCURRENTSAMPLE), so the order is crucial // In the meantime, MMX mixing has been removed because it interfered with the new resonant filter code, and the byte offsets are also no longer hardcoded... - LPSTR pCurrentSample; + LPSTR pCurrentSample; // Currently playing sample (nullptr if no sample is playing) DWORD nPos; DWORD nPosLo; // actually 16-bit (fractional part) LONG nInc; // 16.16 fixed point @@ -271,7 +286,7 @@ LONG nROfs, nLOfs; LONG nRampLength; // Information not used in the mixer - LPSTR pSample; + LPSTR pSample; // Currently playing sample, or previously played sample if no sample is playing. LONG nNewRightVol, nNewLeftVol; LONG nRealVolume, nRealPan; LONG nVolume, nPan, nFadeOutVol; @@ -599,7 +614,9 @@ { deleteAssociatedSamples, doNoDeleteAssociatedSamples, - askdeleteAssociatedSamples, +#ifdef MODPLUG_TRACKER + askDeleteAssociatedSamples, +#endif // MODPLUG_TRACKER }; @@ -1062,6 +1079,15 @@ bool MoveSample(SAMPLEINDEX from, SAMPLEINDEX to); // -! NEW_FEATURE#0020 + // Find an unused sample slot. If it is going to be assigned to an instrument, targetInstrument should be specified. + // SAMPLEINDEX_INVLAID is returned if no free sample slot could be found. + SAMPLEINDEX GetNextFreeSample(INSTRUMENTINDEX targetInstrument = INSTRUMENTINDEX_INVALID, SAMPLEINDEX start = 1) const; + // Find an unused instrument slot. + // INSTRUMENTINDEX_INVALID is returned if no free instrument slot could be found. + INSTRUMENTINDEX GetNextFreeInstrument(INSTRUMENTINDEX start = 1) const; + // Check whether a given sample is used by a given instrument. + bool IsSampleReferencedByInstrument(SAMPLEINDEX sample, INSTRUMENTINDEX instr) const; + bool DestroyInstrument(INSTRUMENTINDEX nInstr, deleteInstrumentSamples removeSamples); bool IsSampleUsed(SAMPLEINDEX nSample) const; bool IsInstrumentUsed(INSTRUMENTINDEX nInstr) const; @@ -1084,16 +1110,16 @@ // -! NEW_FEATURE#0027 bool Read8SVXSample(UINT nInstr, LPBYTE lpMemFile, DWORD dwFileLength); - bool SaveWAVSample(UINT nSample, LPCSTR lpszFileName); - bool SaveRAWSample(UINT nSample, LPCSTR lpszFileName); + bool SaveWAVSample(UINT nSample, LPCSTR lpszFileName) const; + bool SaveRAWSample(UINT nSample, LPCSTR lpszFileName) const; // Instrument file I/O bool ReadInstrumentFromFile(INSTRUMENTINDEX nInstr, LPBYTE lpMemFile, DWORD dwFileLength); bool ReadXIInstrument(INSTRUMENTINDEX nInstr, LPBYTE lpMemFile, DWORD dwFileLength); bool ReadITIInstrument(INSTRUMENTINDEX nInstr, LPBYTE lpMemFile, DWORD dwFileLength); bool ReadPATInstrument(INSTRUMENTINDEX nInstr, LPBYTE lpMemFile, DWORD dwFileLength); bool ReadSampleAsInstrument(INSTRUMENTINDEX nInstr, LPBYTE lpMemFile, DWORD dwFileLength); - bool SaveXIInstrument(INSTRUMENTINDEX nInstr, LPCSTR lpszFileName); - bool SaveITIInstrument(INSTRUMENTINDEX nInstr, LPCSTR lpszFileName); + bool SaveXIInstrument(INSTRUMENTINDEX nInstr, LPCSTR lpszFileName) const; + bool SaveITIInstrument(INSTRUMENTINDEX nInstr, LPCSTR lpszFileName) const; // I/O from another sound file bool ReadInstrumentFromSong(INSTRUMENTINDEX targetInstr, const CSoundFile *pSrcSong, INSTRUMENTINDEX sourceInstr); bool ReadSampleFromSong(SAMPLEINDEX targetSample, const CSoundFile *pSrcSong, SAMPLEINDEX sourceSample); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2011-12-10 18:53:53
|
Revision: 1146 http://modplug.svn.sourceforge.net/modplug/?rev=1146&view=rev Author: saga-games Date: 2011-12-10 18:53:45 +0000 (Sat, 10 Dec 2011) Log Message: ----------- [Ref] Various small rewrites. [Mod] OpenMPT: Version is now 1.20.00.57 Modified Paths: -------------- trunk/OpenMPT/mptrack/Ctrl_ins.cpp trunk/OpenMPT/mptrack/Ctrl_seq.cpp trunk/OpenMPT/mptrack/ModConvert.cpp trunk/OpenMPT/mptrack/Mptrack.cpp trunk/OpenMPT/mptrack/Vstplug.cpp trunk/OpenMPT/mptrack/version.h trunk/OpenMPT/soundlib/Dlsbank.cpp trunk/OpenMPT/soundlib/Load_imf.cpp trunk/OpenMPT/soundlib/Load_it.cpp trunk/OpenMPT/soundlib/Load_mdl.cpp trunk/OpenMPT/soundlib/Load_mod.cpp trunk/OpenMPT/soundlib/Load_xm.cpp trunk/OpenMPT/soundlib/PlaybackEventer.cpp trunk/OpenMPT/soundlib/Sndfile.h trunk/OpenMPT/soundlib/Sndmix.cpp Modified: trunk/OpenMPT/mptrack/Ctrl_ins.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2011-12-10 17:34:18 UTC (rev 1145) +++ trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2011-12-10 18:53:45 UTC (rev 1146) @@ -382,7 +382,7 @@ { bool bModified = false; BYTE n = pIns->NoteMap[m_nNote]; - for (NOTEINDEXTYPE i = 0; i < NOTE_MAX; i++) if (pIns->NoteMap[i] != n) + for (NOTEINDEXTYPE i = 0; i < CountOf(pIns->NoteMap); i++) if (pIns->NoteMap[i] != n) { pIns->NoteMap[i] = n; bModified = true; @@ -408,7 +408,7 @@ { bool bModified = false; SAMPLEINDEX n = pIns->Keyboard[m_nNote]; - for (NOTEINDEXTYPE i = 0; i < NOTE_MAX; i++) if (pIns->Keyboard[i] != n) + for (NOTEINDEXTYPE i = 0; i < CountOf(pIns->Keyboard); i++) if (pIns->Keyboard[i] != n) { pIns->Keyboard[i] = n; bModified = true; @@ -435,7 +435,7 @@ if (pIns) { bool bModified = false; - for (NOTEINDEXTYPE i = 0; i < NOTE_MAX; i++) if (pIns->NoteMap[i] != i + 1) + for (NOTEINDEXTYPE i = 0; i < CountOf(pIns->NoteMap); i++) if (pIns->NoteMap[i] != i + 1) { pIns->NoteMap[i] = i + 1; bModified = true; Modified: trunk/OpenMPT/mptrack/Ctrl_seq.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_seq.cpp 2011-12-10 17:34:18 UTC (rev 1145) +++ trunk/OpenMPT/mptrack/Ctrl_seq.cpp 2011-12-10 18:53:45 UTC (rev 1146) @@ -902,8 +902,10 @@ { CRect rect; GetClientRect(&rect); - bool bSelection = IsSelectionKeyPressed(); + // Copy or move orders? + const bool copyOrders = IsSelectionKeyPressed(); + if (m_bDragging) { m_bDragging = false; @@ -916,46 +918,47 @@ // drag multiple orders (not quite as easy...) ORD_SELECTION selection = GetCurSel(false); // move how many orders from where? - ORDERINDEX nMoveCount = (selection.nOrdHi - selection.nOrdLo), nMovePos = selection.nOrdLo; + ORDERINDEX moveCount = (selection.nOrdHi - selection.nOrdLo), nMovePos = selection.nOrdLo; // drop before or after the selection - bool bMoveBack = !(m_nDragOrder < (UINT)m_nDropPos); + bool moveBack = !(m_nDragOrder < m_nDropPos); // don't do anything if drop position is inside the selection if((m_nDropPos >= selection.nOrdLo && m_nDropPos <= selection.nOrdHi) || m_nDragOrder == m_nDropPos) return; // drag one order or multiple orders? - bool bMultiSelection = (selection.nOrdLo != selection.nOrdHi); + bool multiSelection = (selection.nOrdLo != selection.nOrdHi); - for(int i = 0; i <= nMoveCount; i++) + for(int i = 0; i <= moveCount; i++) { - if(!m_pModDoc->MoveOrder(nMovePos, m_nDropPos, true, bSelection)) return; - if((bMoveBack ^ bSelection) == true && bMultiSelection) + if(!m_pModDoc->MoveOrder(nMovePos, m_nDropPos, true, copyOrders)) return; + if((moveBack ^ copyOrders) == true && multiSelection) { nMovePos++; m_nDropPos++; } - if(bMoveBack && bSelection && bMultiSelection) { + if(moveBack && copyOrders && multiSelection) + { nMovePos += 2; m_nDropPos++; } } - if(bMultiSelection) + + if(multiSelection) { // adjust selection m_nScrollPos2nd = m_nDropPos - 1; - m_nDropPos -= nMoveCount + (bMoveBack ? 0 : 1); - SetCurSel((bMoveBack && (!bSelection)) ? m_nDropPos - 1 : m_nDropPos); + m_nDropPos -= moveCount + (moveBack ? 0 : 1); + SetCurSel((moveBack && !copyOrders) ? m_nDropPos - 1 : m_nDropPos); } else { - SetCurSel(((m_nDragOrder < m_nDropPos) && (!bSelection)) ? m_nDropPos - 1 : m_nDropPos); + SetCurSel((m_nDragOrder < m_nDropPos && !copyOrders) ? m_nDropPos - 1 : m_nDropPos); } m_pModDoc->SetModified(); - } - else + } else { ORDERINDEX nOrder = GetOrderFromPoint(rect, pt); ORD_SELECTION selection = GetCurSel(false); // this should actually have equal signs but that breaks multiselect: nOrder >= selection.nOrdLo && nOrder <= section.nOrdHi - if (pt.y < rect.bottom && m_nScrollPos2nd != ORDERINDEX_INVALID && nOrder > selection.nOrdLo && nOrder < selection.nOrdHi) + if(pt.y < rect.bottom && m_nScrollPos2nd != ORDERINDEX_INVALID && nOrder > selection.nOrdLo && nOrder < selection.nOrdHi) { // Remove selection if we didn't drag anything but multiselect was active m_nScrollPos2nd = ORDERINDEX_INVALID; Modified: trunk/OpenMPT/mptrack/ModConvert.cpp =================================================================== --- trunk/OpenMPT/mptrack/ModConvert.cpp 2011-12-10 17:34:18 UTC (rev 1145) +++ trunk/OpenMPT/mptrack/ModConvert.cpp 2011-12-10 18:53:45 UTC (rev 1146) @@ -312,7 +312,7 @@ { for (size_t i = 0; i < CountOf(pIns->NoteMap); i++) { - if ((pIns->NoteMap[i]) && (pIns->NoteMap[i] != (BYTE)(i + 1))) + if (pIns->NoteMap[i] && pIns->NoteMap[i] != static_cast<BYTE>(i + 1)) { CHANGEMODTYPE_WARNING(wBrokenNoteMap); break; Modified: trunk/OpenMPT/mptrack/Mptrack.cpp =================================================================== --- trunk/OpenMPT/mptrack/Mptrack.cpp 2011-12-10 17:34:18 UTC (rev 1145) +++ trunk/OpenMPT/mptrack/Mptrack.cpp 2011-12-10 18:53:45 UTC (rev 1146) @@ -2163,14 +2163,15 @@ { RelativePathToAbsolute(s); - if(failedPlugin.Compare(s) != 0) + if(!failedPlugin.Compare(s)) { - m_pPluginManager->AddPlugin(s, TRUE, true, &nonFoundPlugs); - } else - { - const CString text = "The following plugin has previously crashed OpenMPT during initialisation and will thus not be loaded:\n\n" + failedPlugin; - Reporting::Information(text); + const CString text = "The following plugin has previously crashed OpenMPT during initialisation:\n\n" + failedPlugin + "\n\nDo you still want to load it?"; + if(Reporting::Confirm(text, false, true) == cnfNo) + { + continue; + } } + m_pPluginManager->AddPlugin(s, TRUE, true, &nonFoundPlugs); } } if(nonFoundPlugs.GetLength() > 0) @@ -2458,6 +2459,7 @@ } void CTrackApp::RemoveMruItem(const int nItem) +//-------------------------------------------- { if (m_pRecentFileList && nItem >= 0 && nItem < m_pRecentFileList->GetSize()) m_pRecentFileList->Remove(nItem); Modified: trunk/OpenMPT/mptrack/Vstplug.cpp =================================================================== --- trunk/OpenMPT/mptrack/Vstplug.cpp 2011-12-10 17:34:18 UTC (rev 1145) +++ trunk/OpenMPT/mptrack/Vstplug.cpp 2011-12-10 18:53:45 UTC (rev 1146) @@ -1693,7 +1693,6 @@ if (minParam == 0 && maxParam == 0) { - minParam = 0; maxParam = m_pEffect->numParams; } @@ -1986,11 +1985,14 @@ //reset some stuff m_MixState.nVolDecayL = 0; m_MixState.nVolDecayR = 0; - Dispatch(effStopProcess, 0, 0, NULL, 0.0f); - Dispatch(effMainsChanged, 0, 0, NULL, 0.0f); // calls plugin's suspend + if(m_bPlugResumed) + { + Dispatch(effStopProcess, 0, 0, NULL, 0.0f); + Dispatch(effMainsChanged, 0, 0, NULL, 0.0f); // calls plugin's suspend + } if (sampleRate != m_nSampleRate) { - m_nSampleRate=sampleRate; + m_nSampleRate = sampleRate; Dispatch(effSetSampleRate, 0, 0, NULL, static_cast<float>(m_nSampleRate)); } Dispatch(effSetBlockSize, 0, MIXBUFFERSIZE, NULL, 0); @@ -2014,7 +2016,7 @@ if(m_bPlugResumed) { Dispatch(effStopProcess, 0, 0, NULL, 0.0f); - Dispatch(effMainsChanged, 0, 0, NULL, 0.0f); // calls plugin's suspend + Dispatch(effMainsChanged, 0, 0, NULL, 0.0f); // calls plugin's suspend (theoretically, plugins should clean their buffers here, but oh well, the number of plugins which don't do this is surprisingly high.) m_bPlugResumed = false; } } catch (...) @@ -2139,6 +2141,8 @@ // SetEvent(processCalled); } + ASSERT(m_pTempBuffer != nullptr); + //mix outputs of multi-output VSTs: if(m_nOutputs>2) { @@ -2813,7 +2817,7 @@ && (Dispatch(effIdentify, 0,0, NULL, 0) == 'NvEf') && (m_pEffect->uniqueID != CCONST('S', 'y', 't', 'r'))) //special case: imageline sytrus pretends to support chunks but gives us garbage. { - PVOID p = NULL; + void *p = NULL; LONG nByteSize = 0; // Try to get whole bank @@ -2898,7 +2902,7 @@ if ((Dispatch(effIdentify, 0, nullptr, nullptr, 0) == 'NvEf') && (nType == 'NvEf')) { - PVOID p = NULL; + void *p = NULL; Dispatch(effGetChunk, 0,0, &p, 0); //init plug for chunk reception if ((nProgram>=0) && (nProgram < m_pEffect->numPrograms)) @@ -3765,7 +3769,7 @@ break; case effClose: - m_Effect.object = NULL; + m_Effect.object = nullptr; delete this; return 0; @@ -3854,7 +3858,7 @@ wfx.wFormatTag = WAVE_FORMAT_IEEE_FLOAT; wfx.nChannels = 2; wfx.nSamplesPerSec = m_nSamplesPerSec; - wfx.wBitsPerSample = 32; + wfx.wBitsPerSample = sizeof(float) * 8; wfx.nBlockAlign = wfx.nChannels * (wfx.wBitsPerSample >> 3); wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; wfx.cbSize = 0; @@ -3934,7 +3938,7 @@ fMax = 1; } fValue -= fMin; - if (fMax > fMin) fValue /= (fMax-fMin); + if (fMax > fMin) fValue /= (fMax - fMin); return fValue; } } @@ -3986,7 +3990,8 @@ WCHAR w[100]; CLSID clsid; - MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pLib->szDllPath,-1,(LPWSTR)w,98); + MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pLib->szDllPath, -1, (LPWSTR)w, CountOf(w)); + w[99] = 0; if (CLSIDFromString(w, &clsid) == S_OK) { IMediaObject *pMO = NULL; @@ -3998,12 +4003,10 @@ if ((pMO) && (pMOIP)) { DWORD dwInputs, dwOutputs; - BOOL bError; dwInputs = dwOutputs = 0; pMO->GetStreamCount(&dwInputs, &dwOutputs); - bError = ((dwInputs == 1) && (dwOutputs == 1)) ? FALSE : TRUE; - if (!bError) + if (dwInputs == 1 && dwOutputs == 1) { CDmo2Vst *p = new CDmo2Vst(pMO, pMOIP, clsid.Data1); return (p) ? p->GetEffect() : NULL; Modified: trunk/OpenMPT/mptrack/version.h =================================================================== --- trunk/OpenMPT/mptrack/version.h 2011-12-10 17:34:18 UTC (rev 1145) +++ trunk/OpenMPT/mptrack/version.h 2011-12-10 18:53:45 UTC (rev 1146) @@ -15,7 +15,7 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 20 #define VER_MINOR 00 -#define VER_MINORMINOR 56 +#define VER_MINORMINOR 57 //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/Dlsbank.cpp =================================================================== --- trunk/OpenMPT/soundlib/Dlsbank.cpp 2011-12-10 17:34:18 UTC (rev 1145) +++ trunk/OpenMPT/soundlib/Dlsbank.cpp 2011-12-10 18:53:45 UTC (rev 1146) @@ -1683,10 +1683,9 @@ int nTranspose = 0; for (UINT iNoteMap=0; iNoteMap<NOTE_MAX; iNoteMap++) { - pIns->NoteMap[iNoteMap] = (BYTE)(iNoteMap+1); if (pDlsIns->ulBank & F_INSTRUMENT_DRUMS) { - if (pSndFile->m_nType & (MOD_TYPE_IT|MOD_TYPE_MID|MOD_TYPE_MPT)) + if (pSndFile->GetType() & (MOD_TYPE_IT|MOD_TYPE_MID|MOD_TYPE_MPT)) { if (iNoteMap < pDlsIns->Regions[nDrumRgn].uKeyMin) pIns->NoteMap[iNoteMap] = (BYTE)(pDlsIns->Regions[nDrumRgn].uKeyMin + 1); if (iNoteMap > pDlsIns->Regions[nDrumRgn].uKeyMax) pIns->NoteMap[iNoteMap] = (BYTE)(pDlsIns->Regions[nDrumRgn].uKeyMax + 1); Modified: trunk/OpenMPT/soundlib/Load_imf.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_imf.cpp 2011-12-10 17:34:18 UTC (rev 1145) +++ trunk/OpenMPT/soundlib/Load_imf.cpp 2011-12-10 18:53:45 UTC (rev 1146) @@ -38,7 +38,7 @@ uint8 unused2[8]; char im10[4]; // 'IM10' IMFCHANNEL channels[32]; // Channel settings - uint8 orderlist[256]; // Order list (0xff = +++; blank out anything beyond ordnum) + uint8 orderlist[256]; // Order list (0xFF = +++; blank out anything beyond ordnum) }; enum @@ -80,9 +80,9 @@ { char filename[13]; // Sample filename (12345678.ABC) */ uint8 unused1[3]; - uint32 length; // Length - uint32 loop_start; // Loop start - uint32 loop_end; // Loop end + uint32 length; // Length (in bytes) + uint32 loop_start; // Loop start (in bytes) + uint32 loop_end; // Loop end (in bytes) uint32 C5Speed; // Samplerate uint8 volume; // Default volume (0...64) uint8 panning; // Default pan (0...255) @@ -152,27 +152,27 @@ // fix some of them switch (note->command) { - case 0xe: // fine volslide + case 0xE: // fine volslide // hackaround to get almost-right behavior for fine slides (i think!) - if (note->param == 0) + if(note->param == 0) /* nothing */; - else if (note->param == 0xf0) - note->param = 0xef; - else if (note->param == 0x0f) - note->param = 0xfe; - else if (note->param & 0xf0) - note->param |= 0xf; + else if(note->param == 0xF0) + note->param = 0xEF; + else if(note->param == 0x0F) + note->param = 0xFE; + else if(note->param & 0xF0) + note->param |= 0x0F; else - note->param |= 0xf0; + note->param |= 0xF0; break; - case 0xf: // set finetune + case 0xF: // set finetune // we don't implement this, but let's at least import the value note->param = 0x20 | min(note->param >> 4, 0xf); break; case 0x14: // fine slide up case 0x15: // fine slide down // this is about as close as we can do... - if (note->param >> 4) + if(note->param >> 4) note->param = 0xf0 | min(note->param >> 4, 0xf); else note->param |= 0xe0; @@ -180,7 +180,7 @@ case 0x16: // cutoff note->param >>= 1; break; - case 0x1f: // set global volume + case 0x1F: // set global volume note->param = min(note->param << 1, 0xff); break; case 0x21: @@ -194,7 +194,7 @@ break; default: // undefined case 0x1: // set filter - case 0xf: // invert loop + case 0xF: // invert loop note->command = CMD_NONE; break; case 0x3: // glissando @@ -206,17 +206,17 @@ case 0x8: // tremolo waveform n = 0x40; break; - case 0xa: // pattern loop - n = 0xb0; + case 0xA: // pattern loop + n = 0xB0; break; - case 0xb: // pattern delay - n = 0xe0; + case 0xB: // pattern delay + n = 0xE0; break; - case 0xc: // note cut - case 0xd: // note delay + case 0xC: // note cut + case 0xD: // note delay // no change break; - case 0xe: // ignore envelope + case 0xE: // ignore envelope /* predicament: we can only disable one envelope at a time. volume is probably most noticeable, so let's go with that. (... actually, orpheus doesn't even seem to implement this at all) */ @@ -224,16 +224,16 @@ break; case 0x18: // sample offset // O00 doesn't pick up the previous value - if (!note->param) + if(!note->param) note->command = CMD_NONE; break; } - if (n) - note->param = n | (note->param & 0xf); + if(n) + note->param = n | (note->param & 0x0F); break; } note->command = (note->command < CountOf(imfEffects)) ? imfEffects[note->command] : CMD_NONE; - if (note->command == CMD_VOLUME && note->volcmd == VOLCMD_NONE) + if(note->command == CMD_VOLUME && note->volcmd == VOLCMD_NONE) { note->volcmd = VOLCMD_VOLUME; note->vol = note->param; @@ -249,7 +249,8 @@ const int shift = (e == IMF_ENV_VOL) ? 0 : 2; env->dwFlags = ((imfins->env[e].flags & 1) ? ENV_ENABLED : 0) | ((imfins->env[e].flags & 2) ? ENV_SUSTAIN : 0) | ((imfins->env[e].flags & 4) ? ENV_LOOP : 0); - env->nNodes = CLAMP(imfins->env[e].points, 2, 25); + env->nNodes = imfins->env[e].points; + Limit(env->nNodes, 2u, 16u); env->nLoopStart = imfins->env[e].loop_start; env->nLoopEnd = imfins->env[e].loop_end; env->nSustainStart = env->nSustainEnd = imfins->env[e].sustain; @@ -269,12 +270,10 @@ //----------------------------------------------------------------------- { DWORD dwMemPos = 0; - IMFHEADER hdr; - MODSAMPLE *pSample = Samples + 1; - WORD firstsample = 1; // first pSample for the current instrument vector<bool> ignoreChannels(32, false); // bit set for each channel that's completely disabled ASSERT_CAN_READ(sizeof(IMFHEADER)); + IMFHEADER hdr; memcpy(&hdr, lpStream, sizeof(IMFHEADER)); dwMemPos = sizeof(IMFHEADER); @@ -290,11 +289,11 @@ SetModFlag(MSF_COMPATIBLE_PLAY, true); // song name - memset(m_szNames, 0, sizeof(m_szNames)); + MemsetZero(m_szNames); memcpy(m_szNames[0], hdr.title, 31); StringFixer::SpaceToNullStringFixed<31>(m_szNames[0]); - if (hdr.flags & 1) + if(hdr.flags & 1) m_dwSongFlags |= SONG_LINEARSLIDES; m_nDefaultSpeed = hdr.tempo; m_nDefaultTempo = hdr.bpm; @@ -335,29 +334,29 @@ if(!m_nChannels) return false; //From mikmod: work around an Orpheus bug - if (hdr.channels[0].status == 0) + if(hdr.channels[0].status == 0) { CHANNELINDEX nChn; for(nChn = 1; nChn < 16; nChn++) if(hdr.channels[nChn].status != 1) break; - if (nChn == 16) + if(nChn == 16) for(nChn = 1; nChn < 16; nChn++) ChnSettings[nChn].dwFlags &= ~CHN_MUTE; } Order.resize(hdr.ordnum); for(ORDERINDEX nOrd = 0; nOrd < hdr.ordnum; nOrd++) - Order[nOrd] = ((hdr.orderlist[nOrd] == 0xff) ? Order.GetIgnoreIndex() : (PATTERNINDEX)hdr.orderlist[nOrd]); + Order[nOrd] = ((hdr.orderlist[nOrd] == 0xFF) ? Order.GetIgnoreIndex() : (PATTERNINDEX)hdr.orderlist[nOrd]); // read patterns for(PATTERNINDEX nPat = 0; nPat < hdr.patnum; nPat++) { uint16 length, nrows; - BYTE mask, channel; + uint8 mask, channel; int row; unsigned int lostfx = 0; - MODCOMMAND *row_data, *note, junk_note; + MODCOMMAND *note, junk_note; ASSERT_CAN_READ(4); length = LittleEndianW(*((uint16 *)(lpStream + dwMemPos))); @@ -367,22 +366,19 @@ if(Patterns.Insert(nPat, nrows)) break; - row_data = Patterns[nPat]; - row = 0; while(row < nrows) { ASSERT_CAN_READ(1); - mask = *((BYTE *)(lpStream + dwMemPos)); + mask = *((uint8 *)(lpStream + dwMemPos)); dwMemPos += 1; - if (mask == 0) + if(mask == 0) { row++; - row_data += m_nChannels; continue; } - channel = mask & 0x1f; + channel = mask & 0x1F; if(ignoreChannels[channel]) { @@ -392,7 +388,7 @@ note = &junk_note; } else { - note = row_data + channel; + note = Patterns[nPat].GetpModCommand(row, channel); } if(mask & 0x20) @@ -403,15 +399,15 @@ note->instr = *((BYTE *)(lpStream + dwMemPos + 1)); dwMemPos += 2; - if (note->note == 160) + if(note->note == 160) { note->note = NOTE_KEYOFF; /* ??? */ - } else if (note->note == 255) + } else if(note->note == 255) { note->note = NOTE_NONE; /* ??? */ } else { - note->note = (note->note >> 4) * 12 + (note->note & 0xf) + 12 + 1; + note->note = (note->note >> 4) * 12 + (note->note & 0x0F) + 12 + 1; if(note->note > NOTE_MAX) { /*printf("%d.%d.%d: funny note 0x%02x\n", @@ -420,37 +416,35 @@ } } } - if((mask & 0xc0) == 0xc0) + if((mask & 0xc0) == 0xC0) { - uint8 e1c, e1d, e2c, e2d; - // read both effects and figure out what to do with them ASSERT_CAN_READ(4); - e1c = *((uint8 *)(lpStream + dwMemPos)); - e1d = *((uint8 *)(lpStream + dwMemPos + 1)); - e2c = *((uint8 *)(lpStream + dwMemPos + 2)); - e2d = *((uint8 *)(lpStream + dwMemPos + 3)); + uint8 e1c = *((uint8 *)(lpStream + dwMemPos)); // Command 1 + uint8 e1d = *((uint8 *)(lpStream + dwMemPos + 1)); // Data 1 + uint8 e2c = *((uint8 *)(lpStream + dwMemPos + 2)); // Command 2 + uint8 e2d = *((uint8 *)(lpStream + dwMemPos + 3)); // Data 2 dwMemPos += 4; - if (e1c == 0xc) + if(e1c == 0x0C) { note->vol = min(e1d, 0x40); note->volcmd = VOLCMD_VOLUME; note->command = e2c; note->param = e2d; - } else if (e2c == 0xc) + } else if(e2c == 0x0C) { note->vol = min(e2d, 0x40); note->volcmd = VOLCMD_VOLUME; note->command = e1c; note->param = e1d; - } else if (e1c == 0xa) + } else if(e1c == 0x0A) { note->vol = e1d * 64 / 255; note->volcmd = VOLCMD_PANNING; note->command = e2c; note->param = e2d; - } else if (e2c == 0xa) + } else if(e2c == 0x0A) { note->vol = e2d * 64 / 255; note->volcmd = VOLCMD_PANNING; @@ -465,7 +459,7 @@ note->command = e2c; note->param = e2d; } - } else if(mask & 0xc0) + } else if(mask & 0xC0) { // there's one effect, just stick it in the effect column ASSERT_CAN_READ(2); @@ -478,8 +472,10 @@ } } + SAMPLEINDEX firstsample = 1; // first sample index of the current instrument + // read instruments - for (INSTRUMENTINDEX nIns = 0; nIns < hdr.insnum; nIns++) + for(INSTRUMENTINDEX nIns = 0; nIns < hdr.insnum; nIns++) { IMFINSTRUMENT imfins; MODINSTRUMENT *pIns; @@ -510,9 +506,9 @@ if(imfins.smpnum) { - for(BYTE cNote = 0; cNote < 120; cNote++) + STATIC_ASSERT(CountOf(pIns->Keyboard) >= CountOf(imfins.map)); + for(size_t cNote = 0; cNote < CountOf(imfins.map); cNote++) { - pIns->NoteMap[cNote] = cNote + 1; pIns->Keyboard[cNote] = firstsample + imfins.map[cNote]; } } @@ -532,9 +528,8 @@ // read this instrument's samples for(SAMPLEINDEX nSmp = 0; nSmp < imfins.smpnum; nSmp++) { - IMFSAMPLE imfsmp; - uint32 blen; ASSERT_CAN_READ(sizeof(IMFSAMPLE)); + IMFSAMPLE imfsmp; memcpy(&imfsmp, lpStream + dwMemPos, sizeof(IMFSAMPLE)); dwMemPos += sizeof(IMFSAMPLE); m_nSamples++; @@ -542,39 +537,40 @@ if(memcmp(imfsmp.is10, "IS10", 4) != 0) return false; - memcpy(pSample->filename, imfsmp.filename, 12); - StringFixer::SpaceToNullStringFixed<12>(pSample->filename); - strcpy(m_szNames[m_nSamples], pSample->filename); + MODSAMPLE &sample = Samples[firstsample + nSmp]; - blen = pSample->nLength = LittleEndian(imfsmp.length); - pSample->nLoopStart = LittleEndian(imfsmp.loop_start); - pSample->nLoopEnd = LittleEndian(imfsmp.loop_end); - pSample->nC5Speed = LittleEndian(imfsmp.C5Speed); - pSample->nVolume = imfsmp.volume * 4; - pSample->nGlobalVol = 256; - pSample->nPan = imfsmp.panning; - if (imfsmp.flags & 1) - pSample->uFlags |= CHN_LOOP; - if (imfsmp.flags & 2) - pSample->uFlags |= CHN_PINGPONGLOOP; - if (imfsmp.flags & 4) + memcpy(sample.filename, imfsmp.filename, 12); + StringFixer::SpaceToNullStringFixed<12>(sample.filename); + strcpy(m_szNames[m_nSamples], sample.filename); + + uint32 byteLen = sample.nLength = LittleEndian(imfsmp.length); + sample.nLoopStart = LittleEndian(imfsmp.loop_start); + sample.nLoopEnd = LittleEndian(imfsmp.loop_end); + sample.nC5Speed = LittleEndian(imfsmp.C5Speed); + sample.nVolume = imfsmp.volume * 4; + sample.nGlobalVol = 256; + sample.nPan = imfsmp.panning; + if(imfsmp.flags & 1) + sample.uFlags |= CHN_LOOP; + if(imfsmp.flags & 2) + sample.uFlags |= CHN_PINGPONGLOOP; + if(imfsmp.flags & 4) { - pSample->uFlags |= CHN_16BIT; - pSample->nLength >>= 1; - pSample->nLoopStart >>= 1; - pSample->nLoopEnd >>= 1; + sample.uFlags |= CHN_16BIT; + sample.nLength /= 2; + sample.nLoopStart /= 2; + sample.nLoopEnd /= 2; } - if (imfsmp.flags & 8) - pSample->uFlags |= CHN_PANNING; + if(imfsmp.flags & 8) + sample.uFlags |= CHN_PANNING; - if(blen) + if(byteLen) { - ASSERT_CAN_READ(blen); - ReadSample(pSample, (imfsmp.flags & 4) ? RS_PCM16S : RS_PCM8S, reinterpret_cast<LPCSTR>(lpStream + dwMemPos), blen); + ASSERT_CAN_READ(byteLen); + ReadSample(&sample, (imfsmp.flags & 4) ? RS_PCM16S : RS_PCM8S, reinterpret_cast<LPCSTR>(lpStream + dwMemPos), byteLen); } - dwMemPos += blen; - pSample++; + dwMemPos += byteLen; } firstsample += imfins.smpnum; } Modified: trunk/OpenMPT/soundlib/Load_it.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_it.cpp 2011-12-10 17:34:18 UTC (rev 1145) +++ trunk/OpenMPT/soundlib/Load_it.cpp 2011-12-10 18:53:45 UTC (rev 1146) @@ -2476,28 +2476,26 @@ if (nInstruments == 0) return; - MODINSTRUMENT *sizeIns = nullptr; + WriteInstrumentPropertyForAllInstruments('VR..', sizeof(MODINSTRUMENT().nVolRampUp), f, nInstruments); + WriteInstrumentPropertyForAllInstruments('MiP.', sizeof(MODINSTRUMENT().nMixPlug), f, nInstruments); + WriteInstrumentPropertyForAllInstruments('MC..', sizeof(MODINSTRUMENT().nMidiChannel),f, nInstruments); + WriteInstrumentPropertyForAllInstruments('MP..', sizeof(MODINSTRUMENT().nMidiProgram),f, nInstruments); + WriteInstrumentPropertyForAllInstruments('MB..', sizeof(MODINSTRUMENT().wMidiBank), f, nInstruments); + WriteInstrumentPropertyForAllInstruments('P...', sizeof(MODINSTRUMENT().nPan), f, nInstruments); + WriteInstrumentPropertyForAllInstruments('GV..', sizeof(MODINSTRUMENT().nGlobalVol), f, nInstruments); + WriteInstrumentPropertyForAllInstruments('FO..', sizeof(MODINSTRUMENT().nFadeOut), f, nInstruments); + WriteInstrumentPropertyForAllInstruments('R...', sizeof(MODINSTRUMENT().nResampling), f, nInstruments); + WriteInstrumentPropertyForAllInstruments('CS..', sizeof(MODINSTRUMENT().nCutSwing), f, nInstruments); + WriteInstrumentPropertyForAllInstruments('RS..', sizeof(MODINSTRUMENT().nResSwing), f, nInstruments); + WriteInstrumentPropertyForAllInstruments('FM..', sizeof(MODINSTRUMENT().nFilterMode), f, nInstruments); + WriteInstrumentPropertyForAllInstruments('PERN', sizeof(MODINSTRUMENT().PitchEnv.nReleaseNode ), f, nInstruments); + WriteInstrumentPropertyForAllInstruments('AERN', sizeof(MODINSTRUMENT().PanEnv.nReleaseNode), f, nInstruments); + WriteInstrumentPropertyForAllInstruments('VERN', sizeof(MODINSTRUMENT().VolEnv.nReleaseNode), f, nInstruments); + WriteInstrumentPropertyForAllInstruments('PTTL', sizeof(MODINSTRUMENT().wPitchToTempoLock), f, nInstruments); + WriteInstrumentPropertyForAllInstruments('PVEH', sizeof(MODINSTRUMENT().nPluginVelocityHandling), f, nInstruments); + WriteInstrumentPropertyForAllInstruments('PVOH', sizeof(MODINSTRUMENT().nPluginVolumeHandling), f, nInstruments); - WriteInstrumentPropertyForAllInstruments('VR..', sizeof(sizeIns->nVolRampUp), f, nInstruments); - WriteInstrumentPropertyForAllInstruments('MiP.', sizeof(sizeIns->nMixPlug), f, nInstruments); - WriteInstrumentPropertyForAllInstruments('MC..', sizeof(sizeIns->nMidiChannel),f, nInstruments); - WriteInstrumentPropertyForAllInstruments('MP..', sizeof(sizeIns->nMidiProgram),f, nInstruments); - WriteInstrumentPropertyForAllInstruments('MB..', sizeof(sizeIns->wMidiBank), f, nInstruments); - WriteInstrumentPropertyForAllInstruments('P...', sizeof(sizeIns->nPan), f, nInstruments); - WriteInstrumentPropertyForAllInstruments('GV..', sizeof(sizeIns->nGlobalVol), f, nInstruments); - WriteInstrumentPropertyForAllInstruments('FO..', sizeof(sizeIns->nFadeOut), f, nInstruments); - WriteInstrumentPropertyForAllInstruments('R...', sizeof(sizeIns->nResampling), f, nInstruments); - WriteInstrumentPropertyForAllInstruments('CS..', sizeof(sizeIns->nCutSwing), f, nInstruments); - WriteInstrumentPropertyForAllInstruments('RS..', sizeof(sizeIns->nResSwing), f, nInstruments); - WriteInstrumentPropertyForAllInstruments('FM..', sizeof(sizeIns->nFilterMode), f, nInstruments); - WriteInstrumentPropertyForAllInstruments('PERN', sizeof(sizeIns->PitchEnv.nReleaseNode ), f, nInstruments); - WriteInstrumentPropertyForAllInstruments('AERN', sizeof(sizeIns->PanEnv.nReleaseNode), f, nInstruments); - WriteInstrumentPropertyForAllInstruments('VERN', sizeof(sizeIns->VolEnv.nReleaseNode), f, nInstruments); - WriteInstrumentPropertyForAllInstruments('PTTL', sizeof(sizeIns->wPitchToTempoLock), f, nInstruments); - WriteInstrumentPropertyForAllInstruments('PVEH', sizeof(sizeIns->nPluginVelocityHandling), f, nInstruments); - WriteInstrumentPropertyForAllInstruments('PVOH', sizeof(sizeIns->nPluginVolumeHandling), f, nInstruments); - - if(m_nType & MOD_TYPE_MPT) + if(GetType() & MOD_TYPE_MPT) { UINT maxNodes = 0; for(INSTRUMENTINDEX nIns = 1; nIns <= m_nInstruments; nIns++) if(Instruments[nIns] != nullptr) @@ -2509,17 +2507,17 @@ // write full envelope information for MPTM files (more env points) if(maxNodes > 25) { - WriteInstrumentPropertyForAllInstruments('VE..', sizeof(sizeIns->VolEnv.nNodes), f, nInstruments); - WriteInstrumentPropertyForAllInstruments('VP[.', sizeof(sizeIns->VolEnv.Ticks ), f, nInstruments); - WriteInstrumentPropertyForAllInstruments('VE[.', sizeof(sizeIns->VolEnv.Values), f, nInstruments); + WriteInstrumentPropertyForAllInstruments('VE..', sizeof(MODINSTRUMENT().VolEnv.nNodes), f, nInstruments); + WriteInstrumentPropertyForAllInstruments('VP[.', sizeof(MODINSTRUMENT().VolEnv.Ticks ), f, nInstruments); + WriteInstrumentPropertyForAllInstruments('VE[.', sizeof(MODINSTRUMENT().VolEnv.Values), f, nInstruments); - WriteInstrumentPropertyForAllInstruments('PE..', sizeof(sizeIns->PanEnv.nNodes), f, nInstruments); - WriteInstrumentPropertyForAllInstruments('PP[.', sizeof(sizeIns->PanEnv.Ticks), f, nInstruments); - WriteInstrumentPropertyForAllInstruments('PE[.', sizeof(sizeIns->PanEnv.Values), f, nInstruments); + WriteInstrumentPropertyForAllInstruments('PE..', sizeof(MODINSTRUMENT().PanEnv.nNodes), f, nInstruments); + WriteInstrumentPropertyForAllInstruments('PP[.', sizeof(MODINSTRUMENT().PanEnv.Ticks), f, nInstruments); + WriteInstrumentPropertyForAllInstruments('PE[.', sizeof(MODINSTRUMENT().PanEnv.Values), f, nInstruments); - WriteInstrumentPropertyForAllInstruments('PiE.', sizeof(sizeIns->PitchEnv.nNodes), f, nInstruments); - WriteInstrumentPropertyForAllInstruments('PiP[', sizeof(sizeIns->PitchEnv.Ticks), f, nInstruments); - WriteInstrumentPropertyForAllInstruments('PiE[', sizeof(sizeIns->PitchEnv.Values), f, nInstruments); + WriteInstrumentPropertyForAllInstruments('PiE.', sizeof(MODINSTRUMENT().PitchEnv.nNodes), f, nInstruments); + WriteInstrumentPropertyForAllInstruments('PiP[', sizeof(MODINSTRUMENT().PitchEnv.Ticks), f, nInstruments); + WriteInstrumentPropertyForAllInstruments('PiE[', sizeof(MODINSTRUMENT().PitchEnv.Values), f, nInstruments); } } Modified: trunk/OpenMPT/soundlib/Load_mdl.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_mdl.cpp 2011-12-10 17:34:18 UTC (rev 1145) +++ trunk/OpenMPT/soundlib/Load_mdl.cpp 2011-12-10 18:53:45 UTC (rev 1146) @@ -81,11 +81,14 @@ break; case 0x0F: command = CMD_SPEED; break; case 0x10: - if ((param & 0xF0) != 0xE0) { + if ((param & 0xF0) != 0xE0) + { command = CMD_VOLUMESLIDE; - if ((param & 0xF0) == 0xF0) { + if ((param & 0xF0) == 0xF0) + { param = ((param << 4) | 0x0F); - } else { + } else + { param >>= 2; if (param > 0xF) param = 0xF; @@ -94,9 +97,11 @@ } break; case 0x20: - if ((param & 0xF0) != 0xE0) { + if ((param & 0xF0) != 0xE0) + { command = CMD_VOLUMESLIDE; - if ((param & 0xF0) != 0xF0) { + if ((param & 0xF0) != 0xF0) + { param >>= 2; if (param > 0xF) param = 0xF; @@ -419,7 +424,7 @@ pIns->nFadeOut = 8192; } } - dwPos += 34 + 14*lpStream[dwPos+1]; + dwPos += 34 + 14 * lpStream[dwPos + 1]; } for (j=1; j<=m_nInstruments; j++) if (!Instruments[j]) { Modified: trunk/OpenMPT/soundlib/Load_mod.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_mod.cpp 2011-12-10 17:34:18 UTC (rev 1145) +++ trunk/OpenMPT/soundlib/Load_mod.cpp 2011-12-10 18:53:45 UTC (rev 1146) @@ -219,7 +219,7 @@ #pragma pack() -bool IsMagic(LPCSTR s1, LPCSTR s2) +bool IsMagic(const LPCSTR s1, const LPCSTR s2) { return ((*(DWORD *)s1) == (*(DWORD *)s2)); } Modified: trunk/OpenMPT/soundlib/Load_xm.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_xm.cpp 2011-12-10 17:34:18 UTC (rev 1145) +++ trunk/OpenMPT/soundlib/Load_xm.cpp 2011-12-10 18:53:45 UTC (rev 1146) @@ -306,7 +306,7 @@ XMINSTRUMENTHEADER pih; BYTE flags[32]; DWORD samplesize[32]; - UINT samplemap[32]; + vector<SAMPLEINDEX>samplemap(32, 0); WORD nsamples; if (dwMemPos + sizeof(DWORD) >= dwMemLength) return true; @@ -359,7 +359,6 @@ else dwMemPos += sizeof(XMINSTRUMENTHEADER); - MemsetZero(samplemap); if (nsamples > 32) return true; UINT newsamples = m_nSamples; @@ -380,7 +379,7 @@ for (UINT clrs=1; clrs<iIns; clrs++) if (Instruments[clrs]) { MODINSTRUMENT *pks = Instruments[clrs]; - for (UINT ks=0; ks<128; ks++) + for (size_t ks = 0; ks < CountOf(pks->Keyboard); ks++) { if (pks->Keyboard[ks] == n) pks->Keyboard[ks] = 0; } @@ -484,7 +483,7 @@ } } } - for (UINT j=0; j<96; j++) + for (size_t j = 0; j < CountOf(xmsh.snum); j++) { if (xmsh.snum[j] < nsamples) pIns->Keyboard[j + 12] = samplemap[xmsh.snum[j]]; Modified: trunk/OpenMPT/soundlib/PlaybackEventer.cpp =================================================================== --- trunk/OpenMPT/soundlib/PlaybackEventer.cpp 2011-12-10 17:34:18 UTC (rev 1145) +++ trunk/OpenMPT/soundlib/PlaybackEventer.cpp 2011-12-10 18:53:45 UTC (rev 1146) @@ -17,7 +17,7 @@ { m_rSndFile.m_bChannelMuteTogglePending[i] = (m_rSndFile.ChnSettings[i].dwFlags & CHN_MUTE) ? false : true; } - m_rSndFile.m_bChannelMuteTogglePending[chnIndex] = (m_rSndFile.ChnSettings[chnIndex].dwFlags & CHN_MUTE) ? true : false; + m_rSndFile.m_bChannelMuteTogglePending[chnIndex] = (m_rSndFile.ChnSettings[chnIndex].dwFlags & CHN_MUTE) != 0; } @@ -26,6 +26,6 @@ { for(CHANNELINDEX i = 0; i<m_rSndFile.m_nChannels; i++) { - m_rSndFile.m_bChannelMuteTogglePending[i] = (m_rSndFile.ChnSettings[i].dwFlags & CHN_MUTE) ? true : false; + m_rSndFile.m_bChannelMuteTogglePending[i] = (m_rSndFile.ChnSettings[i].dwFlags & CHN_MUTE) != 0; } -} \ No newline at end of file +} Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2011-12-10 17:34:18 UTC (rev 1145) +++ trunk/OpenMPT/soundlib/Sndfile.h 2011-12-10 18:53:45 UTC (rev 1146) @@ -996,6 +996,8 @@ protected: // Channel effect processing + int GetVibratoDelta(int type, int position) const; + void ProcessVolumeSwing(MODCHANNEL *pChn, int &vol); void ProcessPanningSwing(MODCHANNEL *pChn); void ProcessTremolo(MODCHANNEL *pChn, int &vol); Modified: trunk/OpenMPT/soundlib/Sndmix.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndmix.cpp 2011-12-10 17:34:18 UTC (rev 1145) +++ trunk/OpenMPT/soundlib/Sndmix.cpp 2011-12-10 18:53:45 UTC (rev 1146) @@ -69,9 +69,9 @@ extern short int ModRampDownTable[64]; extern short int ModSquareTable[64]; extern short int ModRandomTable[64]; -extern short int ITSinusTable[64]; -extern short int ITRampDownTable[64]; -extern short int ITSquareTable[64]; +extern short int ITSinusTable[256]; +extern short int ITRampDownTable[256]; +extern short int ITSquareTable[256]; extern DWORD LinearSlideUpTable[256]; extern DWORD LinearSlideDownTable[256]; extern DWORD FineLinearSlideUpTable[16]; @@ -910,6 +910,36 @@ // Channel effect processing +// Calculate delta for Vibrato / Tremolo / Panbrello effect +int CSoundFile::GetVibratoDelta(int type, int position) const +//----------------------------------------------------------- +{ + switch(type & 0x03) + { + case 0: + default: + // IT compatibility: IT has its own, more precise tables + return IsCompatibleMode(TRK_IMPULSETRACKER) ? ITSinusTable[position] : ModSinusTable[position]; + + case 1: + // IT compatibility: IT has its own, more precise tables + return IsCompatibleMode(TRK_IMPULSETRACKER) ? ITRampDownTable[position] : ModRampDownTable[position]; + + case 2: + // IT compatibility: IT has its own, more precise tables + return IsCompatibleMode(TRK_IMPULSETRACKER) ? ITSquareTable[position] : ModSquareTable[position]; + + case 3: + //IT compatibility 19. Use random values + if(IsCompatibleMode(TRK_IMPULSETRACKER)) + // TODO delay is not taken into account! + return (rand() & 0x7F) - 0x40; + else + return ModRandomTable[position]; + } +} + + void CSoundFile::ProcessVolumeSwing(MODCHANNEL *pChn, int &vol) //------------------------------------------------------------- { @@ -959,27 +989,8 @@ { // IT compatibility: We don't need a different attenuation here because of the different tables we're going to use const int tremattn = ((GetType() & MOD_TYPE_XM) || IsCompatibleMode(TRK_IMPULSETRACKER)) ? 5 : 6; - switch (pChn->nTremoloType & 0x03) - { - case 1: - // IT compatibility: IT has its own, more precise tables - vol += ((IsCompatibleMode(TRK_IMPULSETRACKER) ? ITRampDownTable[trempos] : ModRampDownTable[trempos]) * (int)pChn->nTremoloDepth) >> tremattn; - break; - case 2: - // IT compatibility: IT has its own, more precise tables - vol += ((IsCompatibleMode(TRK_IMPULSETRACKER) ? ITSquareTable[trempos] : ModSquareTable[trempos]) * (int)pChn->nTremoloDepth) >> tremattn; - break; - case 3: - //IT compatibility 19. Use random values - if(IsCompatibleMode(TRK_IMPULSETRACKER)) - vol += (((rand() & 0x7F) - 0x40) * (int)pChn->nTremoloDepth) >> tremattn; - else - vol += (ModRandomTable[trempos] * (int)pChn->nTremoloDepth) >> tremattn; - break; - default: - // IT compatibility: IT has its own, more precise tables - vol += ((IsCompatibleMode(TRK_IMPULSETRACKER) ? ITSinusTable[trempos] : ModSinusTable[trempos]) * (int)pChn->nTremoloDepth) >> tremattn; - } + + vol += (GetVibratoDelta(pChn->nTremoloType, trempos) * (int)pChn->nTremoloDepth) >> tremattn; } if (!(m_dwSongFlags & SONG_FIRSTTICK) || ((GetType() & (MOD_TYPE_STM|MOD_TYPE_S3M|MOD_TYPE_IT|MOD_TYPE_MPT)) && (!(m_dwSongFlags & SONG_ITOLDEFFECTS)))) { @@ -1390,33 +1401,14 @@ panpos = pChn->nPanbrelloPos & 0xFF; else panpos = ((pChn->nPanbrelloPos + 0x10) >> 2) & 0x3F; - LONG pdelta; - switch (pChn->nPanbrelloType & 0x03) - { - case 1: - // IT compatibility: IT has its own, more precise tables - pdelta = IsCompatibleMode(TRK_IMPULSETRACKER) ? ITRampDownTable[panpos] : ModRampDownTable[panpos]; - break; - case 2: - // IT compatibility: IT has its own, more precise tables - pdelta = IsCompatibleMode(TRK_IMPULSETRACKER) ? ITSquareTable[panpos] : ModSquareTable[panpos]; - break; - case 3: - //IT compatibility 19. Use random values - if(IsCompatibleMode(TRK_IMPULSETRACKER)) - pdelta = (rand() & 0x7f) - 0x40; - else - pdelta = ModRandomTable[panpos]; - break; - default: - // IT compatibility: IT has its own, more precise tables - pdelta = IsCompatibleMode(TRK_IMPULSETRACKER) ? ITSinusTable[panpos] : ModSinusTable[panpos]; - } + + LONG pdelta = GetVibratoDelta(pChn->nPanbrelloType, panpos); + pChn->nPanbrelloPos += pChn->nPanbrelloSpeed; pdelta = ((pdelta * (int)pChn->nPanbrelloDepth) + 2) >> 3; pdelta += pChn->nRealPan; - pChn->nRealPan = CLAMP(pdelta, 0, 256); + pChn->nRealPan = Clamp(pdelta, 0, 256); //if(IsCompatibleMode(TRK_IMPULSETRACKER)) pChn->nPan = pChn->nRealPan; // TODO } } @@ -1477,7 +1469,7 @@ arpeggioSteps = pChn->nArpeggio >> 4; // >> 4 <-> division by 16. This gives the first number in the parameter. break; case 2: - arpeggioSteps = pChn->nArpeggio % 16; //Gives the latter number in the parameter. + arpeggioSteps = pChn->nArpeggio & 0x0F; //Gives the latter number in the parameter. break; } pChn->m_CalculateFreq = true; @@ -1540,30 +1532,10 @@ if (pChn->dwFlags & CHN_VIBRATO) { UINT vibpos = pChn->nVibratoPos; - LONG vdelta; - switch (pChn->nVibratoType & 0x03) - { - case 1: - // IT compatibility: IT has its own, more precise tables - vdelta = IsCompatibleMode(TRK_IMPULSETRACKER) ? ITRampDownTable[vibpos] : ModRampDownTable[vibpos]; - break; - case 2: - // IT compatibility: IT has its own, more precise tables - vdelta = IsCompatibleMode(TRK_IMPULSETRACKER) ? ITSquareTable[vibpos] : ModSquareTable[vibpos]; - break; - case 3: - //IT compatibility 19. Use random values - if(IsCompatibleMode(TRK_IMPULSETRACKER)) - vdelta = (rand() & 0x7F) - 0x40; - else - vdelta = ModRandomTable[vibpos]; - break; - default: - // IT compatibility: IT has its own, more precise tables - vdelta = IsCompatibleMode(TRK_IMPULSETRACKER) ? ITSinusTable[vibpos] : ModSinusTable[vibpos]; - } - if(m_nType == MOD_TYPE_MPT && pChn->pModInstrument && pChn->pModInstrument->pTuning) + LONG vdelta = GetVibratoDelta(pChn->nVibratoType, vibpos); + + if(GetType() == MOD_TYPE_MPT && pChn->pModInstrument && pChn->pModInstrument->pTuning) { //Hack implementation: Scaling vibratofactor to [0.95; 1.05] //using figure from above tables and vibratodepth parameter @@ -1592,7 +1564,7 @@ } else { - vdepth = ((!(m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT))) || (m_dwSongFlags & SONG_ITOLDEFFECTS)) ? 6 : 7; + vdepth = ((!(GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT))) || (m_dwSongFlags & SONG_ITOLDEFFECTS)) ? 6 : 7; } vdelta = (vdelta * (int)pChn->nVibratoDepth) >> vdepth; if ((m_dwSongFlags & SONG_LINEARSLIDES) && (m_nType & (MOD_TYPE_IT | MOD_TYPE_MPT))) @@ -1611,7 +1583,7 @@ } period += vdelta; } - if ((m_nTickCount) || ((m_nType & (MOD_TYPE_IT | MOD_TYPE_MPT)) && (!(m_dwSongFlags & SONG_ITOLDEFFECTS)))) + if ((m_nTickCount) || ((GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)) && (!(m_dwSongFlags & SONG_ITOLDEFFECTS)))) { // IT compatibility: IT has its own, more precise tables if(IsCompatibleMode(TRK_IMPULSETRACKER)) @@ -1624,7 +1596,7 @@ void CSoundFile::ProcessSampleAutoVibrato(MODCHANNEL *pChn, int &period, CTuning::RATIOTYPE &vibratoFactor, int &nPeriodFrac) -//-------------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------------- { // Sample Auto-Vibrato if ((pChn->pModSample) && (pChn->pModSample->nVibDepth)) @@ -1730,7 +1702,7 @@ vdelta = ((0x40 - (pChn->nAutoVibPos >> 1)) & 0x7F) - 0x40; break; case VIB_RAMP_UP: - vdelta = ((0x40 + (pChn->nAutoVibPos >> 1)) & 0x7f) - 0x40; + vdelta = ((0x40 + (pChn->nAutoVibPos >> 1)) & 0x7F) - 0x40; break; case VIB_SQUARE: vdelta = (pChn->nAutoVibPos & 128) ? +64 : -64; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rel...@us...> - 2011-12-29 17:13:22
|
Revision: 1148 http://modplug.svn.sourceforge.net/modplug/?rev=1148&view=rev Author: relabsoluness Date: 2011-12-29 17:13:15 +0000 (Thu, 29 Dec 2011) Log Message: ----------- [Fix] Instrument editor: When dragging instruments from tree view, new instrument could override sample from existing instrument (broken in rev 1022). [Mod] Instrument editor: When adding new instruments, the new instrument can't no longer get sample index which points to existing but unreferenced sample. Revision Links: -------------- http://modplug.svn.sourceforge.net/modplug/?rev=1022&view=rev Modified Paths: -------------- trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/soundlib/Dlsbank.cpp Modified: trunk/OpenMPT/mptrack/Modedit.cpp =================================================================== --- trunk/OpenMPT/mptrack/Modedit.cpp 2011-12-11 22:50:59 UTC (rev 1147) +++ trunk/OpenMPT/mptrack/Modedit.cpp 2011-12-29 17:13:15 UTC (rev 1148) @@ -550,6 +550,8 @@ newsmp = nSample; } else if (!pDup) { + newsmp = m_SndFile.GetNextFreeSample(newins); + /* for(SAMPLEINDEX k = 1; k <= m_SndFile.GetNumSamples(); k++) { if (!m_SndFile.IsSampleUsed(k)) @@ -560,9 +562,11 @@ } } if (!newsmp) + */ + if (newsmp > m_SndFile.GetNumSamples()) { // Add a new sample - int inssmp = InsertSample(); + const SAMPLEINDEX inssmp = InsertSample(); if (inssmp != SAMPLEINDEX_INVALID) newsmp = inssmp; } } Modified: trunk/OpenMPT/soundlib/Dlsbank.cpp =================================================================== --- trunk/OpenMPT/soundlib/Dlsbank.cpp 2011-12-11 22:50:59 UTC (rev 1147) +++ trunk/OpenMPT/soundlib/Dlsbank.cpp 2011-12-29 17:13:15 UTC (rev 1148) @@ -1739,11 +1739,7 @@ nSmp = RgnToSmp[nRgn-1]; } else { - // Find a nice sample slot - do - { - nSample++; - } while (nSample < pSndFile->GetNumSamples() && (pSndFile->GetSample(nSample).pSample != nullptr || pSndFile->m_szNames[nSample][0])); + nSample = pSndFile->GetNextFreeSample(nInstr); if (nSample >= MAX_SAMPLES) break; if (nSample > pSndFile->GetNumSamples()) pSndFile->m_nSamples = nSample; nSmp = nSample; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2011-12-30 21:28:15
|
Revision: 1149 http://modplug.svn.sourceforge.net/modplug/?rev=1149&view=rev Author: saga-games Date: 2011-12-30 21:28:08 +0000 (Fri, 30 Dec 2011) Log Message: ----------- [Fix] VSTi levels in compatible mode broke in rev 1147 [Fix] IT Compatibility: Envelope pausing behaved incorrectly when pausing the envelope directly when triggering it. [Mod] Installer: When scanning VSTs, files that don't have the .dll extension are now skipped. [Mod] BPM Calculation: Reduced number of displayed decimals to avoid confusion because of float imprecision. [Mod] OpenMPT: Version is now 1.20.00.58 Revision Links: -------------- http://modplug.svn.sourceforge.net/modplug/?rev=1147&view=rev Modified Paths: -------------- trunk/OpenMPT/installer/vst_scan.iss trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/SoundFilePlayConfig.cpp trunk/OpenMPT/mptrack/version.h trunk/OpenMPT/soundlib/Sndmix.cpp Modified: trunk/OpenMPT/installer/vst_scan.iss =================================================================== --- trunk/OpenMPT/installer/vst_scan.iss 2011-12-29 17:13:15 UTC (rev 1148) +++ trunk/OpenMPT/installer/vst_scan.iss 2011-12-30 21:28:08 UTC (rev 1149) @@ -32,7 +32,7 @@ FilePath := NewRoot + FindRec.Name; if FindRec.Attributes AND FILE_ATTRIBUTE_DIRECTORY > 0 then ProcessDirectory (FilePath, Progress, INIFile) - else + else if(CompareText('.dll', Copy(FindRec.Name, Length(FindRec.Name) - 3, 4)) = 0) then begin // Start action --> // . @@ -43,7 +43,7 @@ // as this could take a very long time. // . SetIniString('VST Plugins', 'Plugin' + IntToStr(VSTPluginNumber), FilePath, INIFile); - VSTPluginNumber := VSTPluginNumber +1; + VSTPluginNumber := VSTPluginNumber + 1; // <-- End action. ArrayLen := ArrayLen + 1; Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2011-12-29 17:13:15 UTC (rev 1148) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2011-12-30 21:28:08 UTC (rev 1149) @@ -2135,17 +2135,17 @@ switch(m_SndFile.m_nTempoMode) { case tempo_mode_alternative: - Message.Format("Using alternative tempo interpretation.\n\nAssuming:\n. %d ticks per second\n. %d ticks per row\n. %d rows per beat\nthe tempo is approximately: %.20g BPM", + Message.Format("Using alternative tempo interpretation.\n\nAssuming:\n. %d ticks per second\n. %d ticks per row\n. %d rows per beat\nthe tempo is approximately: %.8g BPM", m_SndFile.m_nMusicTempo, m_SndFile.m_nMusicSpeed, m_SndFile.m_nCurrentRowsPerBeat, bpm); break; case tempo_mode_modern: - Message.Format("Using modern tempo interpretation.\n\nThe tempo is: %.20g BPM", bpm); + Message.Format("Using modern tempo interpretation.\n\nThe tempo is: %.8g BPM", bpm); break; case tempo_mode_classic: default: - Message.Format("Using standard tempo interpretation.\n\nAssuming:\n. A mod tempo (tick duration factor) of %d\n. %d ticks per row\n. %d rows per beat\nthe tempo is approximately: %.20g BPM", + Message.Format("Using standard tempo interpretation.\n\nAssuming:\n. A mod tempo (tick duration factor) of %d\n. %d ticks per row\n. %d rows per beat\nthe tempo is approximately: %.8g BPM", m_SndFile.m_nMusicTempo, m_SndFile.m_nMusicSpeed, m_SndFile.m_nCurrentRowsPerBeat, bpm); break; } @@ -2165,7 +2165,7 @@ DWORD dwParamValue; // 0 = default DWORD dwFlags; // FXINFO_XXXX DWORD dwFormats; // MOD_TYPE_XXX combo - LPCSTR pszName; // ie "Tone Portamento" + LPCSTR pszName; // e.g. "Tone Portamento" } MPTEFFECTINFO; #define MOD_TYPE_MODXM (MOD_TYPE_MOD|MOD_TYPE_XM) Modified: trunk/OpenMPT/mptrack/SoundFilePlayConfig.cpp =================================================================== --- trunk/OpenMPT/mptrack/SoundFilePlayConfig.cpp 2011-12-29 17:13:15 UTC (rev 1148) +++ trunk/OpenMPT/mptrack/SoundFilePlayConfig.cpp 2011-12-30 21:28:08 UTC (rev 1149) @@ -89,7 +89,7 @@ // This is basically derived from mixmode 1.17 RC3, with panning mode and volume levels changed. // Sample attenuation is the same as in Schism Tracker (more attenuation than with RC3, thus VSTi attenuation is also higher). case mixLevels_compatible: - setVSTiAttenuation(4.0f); + setVSTiAttenuation(0.75f); setIntToFloat(1.0f/static_cast<float>(MIXING_CLIPMAX)); setFloatToInt(static_cast<float>(MIXING_CLIPMAX)); setGlobalVolumeAppliesToMaster(true); Modified: trunk/OpenMPT/mptrack/version.h =================================================================== --- trunk/OpenMPT/mptrack/version.h 2011-12-29 17:13:15 UTC (rev 1148) +++ trunk/OpenMPT/mptrack/version.h 2011-12-30 21:28:08 UTC (rev 1149) @@ -15,7 +15,7 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 20 #define VER_MINOR 00 -#define VER_MINORMINOR 57 +#define VER_MINORMINOR 58 //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/Sndmix.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndmix.cpp 2011-12-29 17:13:15 UTC (rev 1148) +++ trunk/OpenMPT/soundlib/Sndmix.cpp 2011-12-30 21:28:08 UTC (rev 1149) @@ -1069,7 +1069,12 @@ // IT Compatibility: S77 does not disable the volume envelope, it just pauses the counter if (((pChn->VolEnv.flags & ENV_ENABLED) || ((pIns->VolEnv.dwFlags & ENV_ENABLED) && IsCompatibleMode(TRK_IMPULSETRACKER))) && (pIns->VolEnv.nNodes)) { - const int envpos = pChn->VolEnv.nEnvPosition - ((IsCompatibleMode(TRK_IMPULSETRACKER) && pChn->VolEnv.nEnvPosition > 0) ? 1 : 0); + if(IsCompatibleMode(TRK_IMPULSETRACKER) && pChn->VolEnv.nEnvPosition == 0) + { + // If the envelope is disabled at the very same moment as it is triggered, we do not process anything. + return; + } + const int envpos = pChn->VolEnv.nEnvPosition - (IsCompatibleMode(TRK_IMPULSETRACKER) ? 1 : 0); int envvol = GetVolEnvValueFromPosition(envpos, pIns); // if we are in the release portion of the envelope, @@ -1091,7 +1096,7 @@ int relativeVolumeChange = (envvol - envValueAtReleaseNode) * 2; envvol = envValueAtReleaseJump + relativeVolumeChange; } - vol = (vol * CLAMP(envvol, 0, 512)) >> 8; + vol = (vol * Clamp(envvol, 0, 512)) >> 8; } } @@ -1105,9 +1110,15 @@ // IT Compatibility: S79 does not disable the panning envelope, it just pauses the counter if (((pChn->PanEnv.flags & ENV_ENABLED) || ((pIns->PanEnv.dwFlags & ENV_ENABLED) && IsCompatibleMode(TRK_IMPULSETRACKER))) && (pIns->PanEnv.nNodes)) { - const int envpos = pChn->PanEnv.nEnvPosition - ((IsCompatibleMode(TRK_IMPULSETRACKER) && pChn->VolEnv.nEnvPosition > 0) ? 1 : 0); + if(IsCompatibleMode(TRK_IMPULSETRACKER) && pChn->VolEnv.nEnvPosition == 0) + { + // If the envelope is disabled at the very same moment as it is triggered, we do not process anything. + return; + } + const int envpos = pChn->PanEnv.nEnvPosition - (IsCompatibleMode(TRK_IMPULSETRACKER) ? 1 : 0); + UINT pt = pIns->PanEnv.nNodes - 1; - for (UINT i=0; i<(UINT)(pIns->PanEnv.nNodes-1); i++) + for (UINT i = 0; i < (UINT)(pIns->PanEnv.nNodes - 1); i++) { if (envpos <= pIns->PanEnv.Ticks[i]) { @@ -1123,8 +1134,8 @@ x1 = x2; } else if (pt) { - envpan = pIns->PanEnv.Values[pt-1]; - x1 = pIns->PanEnv.Ticks[pt-1]; + envpan = pIns->PanEnv.Values[pt - 1]; + x1 = pIns->PanEnv.Ticks[pt - 1]; } else { envpan = 128; @@ -1135,7 +1146,7 @@ envpan += ((envpos - x1) * (y2 - envpan)) / (x2 - x1); } - envpan = CLAMP(envpan, 0, 64); + envpan = Clamp(envpan, 0, 64); int pan = pChn->nPan; if (pan >= 128) { @@ -1145,7 +1156,7 @@ pan += ((envpan - 32) * (pan)) / 32; } - pChn->nRealPan = CLAMP(pan, 0, 256); + pChn->nRealPan = Clamp(pan, 0, 256); } } @@ -1158,7 +1169,13 @@ // IT Compatibility: S7B does not disable the pitch envelope, it just pauses the counter if ((pIns) && ((pChn->PitchEnv.flags & ENV_ENABLED) || ((pIns->PitchEnv.dwFlags & ENV_ENABLED) && IsCompatibleMode(TRK_IMPULSETRACKER))) && (pChn->pModInstrument->PitchEnv.nNodes)) { - int envpos = pChn->PitchEnv.nEnvPosition - ((IsCompatibleMode(TRK_IMPULSETRACKER) && pChn->VolEnv.nEnvPosition > 0) ? 1 : 0); + if(IsCompatibleMode(TRK_IMPULSETRACKER) && pChn->VolEnv.nEnvPosition == 0) + { + // If the envelope is disabled at the very same moment as it is triggered, we do not process anything. + return; + } + int envpos = pChn->PitchEnv.nEnvPosition - (IsCompatibleMode(TRK_IMPULSETRACKER) ? 1 : 0); + UINT pt = pIns->PitchEnv.nNodes - 1; for (UINT i=0; i<(UINT)(pIns->PitchEnv.nNodes-1); i++) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2012-01-01 21:52:47
|
Revision: 1150 http://modplug.svn.sourceforge.net/modplug/?rev=1150&view=rev Author: saga-games Date: 2012-01-01 21:52:39 +0000 (Sun, 01 Jan 2012) Log Message: ----------- [Fix] VST Plugins with more than 32 outputs should now work better (at least I got told so). [Mod] OpenMPT: Version is now 1.20.00.59 Modified Paths: -------------- trunk/OpenMPT/mptrack/Vstplug.cpp trunk/OpenMPT/mptrack/Vstplug.h trunk/OpenMPT/mptrack/mptrack.vcproj trunk/OpenMPT/mptrack/mptrack_08.vcproj trunk/OpenMPT/mptrack/mptrack_10.vcxproj trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters trunk/OpenMPT/mptrack/version.h Added Paths: ----------- trunk/OpenMPT/soundlib/PluginMixBuffer.h Modified: trunk/OpenMPT/mptrack/Vstplug.cpp =================================================================== --- trunk/OpenMPT/mptrack/Vstplug.cpp 2011-12-30 21:28:08 UTC (rev 1149) +++ trunk/OpenMPT/mptrack/Vstplug.cpp 2012-01-01 21:52:39 UTC (rev 1150) @@ -1327,20 +1327,18 @@ { m_hLibrary = hLibrary; m_nRefCount = 1; - m_pPrev = NULL; - m_pNext = NULL; + m_pPrev = nullptr; + m_pNext = nullptr; m_pFactory = pFactory; m_pMixStruct = pMixStruct; m_pEffect = pEffect; - m_pInputs = NULL; - m_pOutputs = NULL; - m_pEditor = NULL; + m_pEditor = nullptr; m_nInputs = m_nOutputs = 0; m_nEditorX = m_nEditorY = -1; - m_pEvList = NULL; - m_pModDoc = NULL; //rewbs.plugDocAware + m_pEvList = nullptr; + m_pModDoc = nullptr; //rewbs.plugDocAware m_nPreviousMidiChan = nInvalidMidiChan; //rewbs.VSTCompliance - m_pProcessFP = NULL; + m_pProcessFP = nullptr; // Insert ourselves in the beginning of the list if (m_pFactory) @@ -1356,14 +1354,9 @@ m_MixState.nVolDecayL = 0; m_MixState.nVolDecayR = 0; m_MixState.pMixBuffer = (int *)((((DWORD)m_MixBuffer)+7)&~7); - m_MixState.pOutBufferL = (float *)((((DWORD)&m_FloatBuffer[0]) + 7) & ~7); - m_MixState.pOutBufferR = (float *)((((DWORD)&m_FloatBuffer[MIXBUFFERSIZE]) + 7) & ~7); - MemsetZero(dummyBuffer_); + m_MixState.pOutBufferL = mixBuffer.GetInputBuffer(0); + m_MixState.pOutBufferR = mixBuffer.GetInputBuffer(1); - - //rewbs.dryRatio: we now initialise this in CVstPlugin::Initialize(). - //m_pTempBuffer = (float *)((((DWORD)&m_FloatBuffer[MIXBUFFERSIZE*2])+7)&~7); - m_bSongPlaying = false; //rewbs.VSTCompliance m_bPlugResumed = false; m_bModified = false; @@ -1474,34 +1467,12 @@ m_nInputs = m_pEffect->numInputs; m_nOutputs = m_pEffect->numOutputs; - //32 is the maximum output count due to the size of m_FloatBuffer. - //TODO: How to handle properly plugs with numOutputs > 32? - if(m_nOutputs > 32) - { - m_nOutputs = 32; - CString str; - str.Format("Plugin has unsupported number(=%d) of outputs; plugin may malfunction.", m_pEffect->numOutputs); - Reporting::Warning(str); - } + // Input pointer array size must be >= 2 for now - the input buffer assignment might write to non allocated mem. otherwise + mixBuffer.Initialize(max(m_nInputs, 2), m_nOutputs); + m_MixState.pOutBufferL = mixBuffer.GetInputBuffer(0); + m_MixState.pOutBufferR = mixBuffer.GetInputBuffer(1); - //input pointer array size must be >=2 for now - the input buffer assignment might write to non allocated mem. otherwise - m_pInputs = (m_nInputs >= 2) ? new (float *[m_nInputs]) : new (float*[2]); - m_pInputs[0] = m_MixState.pOutBufferL; - m_pInputs[1] = m_MixState.pOutBufferR; - // Assign dummy inputs - for(size_t i = 2; i < m_nInputs; i++) - { - m_pInputs[i] = dummyBuffer_; - } - m_pOutputs = new (float *[m_nOutputs]); - m_pTempBuffer = new (float *[m_nOutputs]); //rewbs.dryRatio - - for (UINT iOut=0; iOut<m_nOutputs; iOut++) - { - m_pTempBuffer[iOut]=(float *)((((DWORD_PTR)&m_FloatBuffer[MIXBUFFERSIZE*(2+iOut)])+7)&~7); //rewbs.dryRatio - } - #ifdef VST_LOG Log("%s: vst ver %d.0, flags=%04X, %d programs, %d parameters\n", m_pFactory->szLibraryName, (m_bIsVst2) ? 2 : 1, m_pEffect->flags, @@ -1565,17 +1536,8 @@ m_hLibrary = NULL; } - delete[] m_pTempBuffer; - m_pTempBuffer = NULL; - - delete[] m_pInputs; - m_pInputs = NULL; - - delete[] m_pOutputs; - m_pOutputs = NULL; - delete[] (char *)m_pEvList; - m_pEvList = NULL; + m_pEvList = nullptr; CloseHandle(processCalled); } @@ -2098,7 +2060,7 @@ // MIX_R += dryRatio * (WET_L - DRY_L) + wetRatio * (DRY_R - WET_R) //If the plug is found & ok, continue - if ((m_pEffect) && (m_pProcessFP) && (m_pInputs) && (m_pOutputs) && (m_pMixStruct)) + if ((m_pEffect) && (m_pProcessFP) && (mixBuffer.GetInputBufferArray()) && (mixBuffer.GetOutputBufferArray()) && (m_pMixStruct)) { int mixop; if (m_bIsInstrument) @@ -2114,24 +2076,21 @@ //Merge stereo input before sending to the plug if the plug can only handle one input. if (m_pEffect->numInputs == 1) { - for (UINT i=0; i<nSamples; i++) + for (size_t i = 0; i < nSamples; i++) { - m_MixState.pOutBufferL[i] = 0.5f*m_MixState.pOutBufferL[i] + 0.5f*m_MixState.pOutBufferR[i]; + m_MixState.pOutBufferL[i] = 0.5f * m_MixState.pOutBufferL[i] + 0.5f * m_MixState.pOutBufferR[i]; } } - for (UINT iOut=0; iOut<m_nOutputs; iOut++) - { - memset(m_pTempBuffer[iOut], 0, nSamples * sizeof(float)); - m_pOutputs[iOut] = m_pTempBuffer[iOut]; - } + float **outputBuffers = mixBuffer.GetOutputBufferArray(); + mixBuffer.ClearOutputBuffers(nSamples); m_dwTimeAtStartOfProcess = timeGetTime(); //Do the VST processing magic try { ASSERT(nSamples <= MIXBUFFERSIZE); - m_pProcessFP(m_pEffect, m_pInputs, m_pOutputs, nSamples); + m_pProcessFP(m_pEffect, mixBuffer.GetInputBufferArray(), outputBuffers, nSamples); } catch (...) { Bypass(); @@ -2141,7 +2100,7 @@ // SetEvent(processCalled); } - ASSERT(m_pTempBuffer != nullptr); + ASSERT(outputBuffers != nullptr); //mix outputs of multi-output VSTs: if(m_nOutputs>2) @@ -2155,7 +2114,7 @@ for(UINT iOut = 2; iOut < nOuts; iOut++) { for(UINT i = 0; i < nSamples; i++) - m_pTempBuffer[iOut % 2][i] += m_pTempBuffer[iOut][i]; //assumed stereo. + outputBuffers[iOut % 2][i] += outputBuffers[iOut][i]; //assumed stereo. } // if m_nOutputs is odd, mix half the signal of last output to each channel @@ -2164,9 +2123,9 @@ // trick : if we are here, nOuts = m_nOutputs - 1 !!! for(UINT i=0; i<nSamples; i++) { - float v = 0.5f * m_pTempBuffer[nOuts][i]; - m_pTempBuffer[0][i] += v; - m_pTempBuffer[1][i] += v; + float v = 0.5f * outputBuffers[nOuts][i]; + outputBuffers[0][i] += v; + outputBuffers[1][i] += v; } } } @@ -2183,8 +2142,8 @@ for (UINT i=0; i<nSamples; i++) { //rewbs.wetratio - added the factors. [20040123] - pOutL[i] += m_pTempBuffer[0][i]*wetRatio + m_MixState.pOutBufferL[i]*dryRatio; - pOutR[i] += m_pTempBuffer[0][i]*wetRatio + m_MixState.pOutBufferR[i]*dryRatio; + pOutL[i] += outputBuffers[0][i]*wetRatio + m_MixState.pOutBufferL[i]*dryRatio; + pOutR[i] += outputBuffers[0][i]*wetRatio + m_MixState.pOutBufferR[i]*dryRatio; //If dry mix is ticked we add the unprocessed buffer, //except if this is an instrument since this it already been done: @@ -2214,8 +2173,8 @@ for(UINT i = 0; i < nSamples; i++) { //rewbs.wetratio - added the factors. [20040123] - pOutL[i] += m_pTempBuffer[0][i]*wetRatio + m_MixState.pOutBufferL[i]*dryRatio; - pOutR[i] += m_pTempBuffer[0][i]*wetRatio + m_MixState.pOutBufferR[i]*dryRatio; + pOutL[i] += outputBuffers[0][i]*wetRatio + m_MixState.pOutBufferL[i]*dryRatio; + pOutR[i] += outputBuffers[0][i]*wetRatio + m_MixState.pOutBufferR[i]*dryRatio; } break; @@ -2223,8 +2182,8 @@ case 1: for(UINT i = 0; i < nSamples; i++) { - pOutL[i] += m_MixState.pOutBufferL[i] - m_pTempBuffer[0][i]*wetRatio; - pOutR[i] += m_MixState.pOutBufferR[i] - m_pTempBuffer[0][i]*wetRatio; + pOutL[i] += m_MixState.pOutBufferL[i] - outputBuffers[0][i]*wetRatio; + pOutR[i] += m_MixState.pOutBufferR[i] - outputBuffers[0][i]*wetRatio; } break; @@ -2232,8 +2191,8 @@ case 2: for(UINT i = 0; i < nSamples; i++) { - pOutL[i] += m_pTempBuffer[0][i] - m_MixState.pOutBufferL[i]*dryRatio; - pOutR[i] += m_pTempBuffer[0][i] - m_MixState.pOutBufferR[i]*dryRatio; + pOutL[i] += outputBuffers[0][i] - m_MixState.pOutBufferL[i]*dryRatio; + pOutR[i] += outputBuffers[0][i] - m_MixState.pOutBufferR[i]*dryRatio; } break; @@ -2241,8 +2200,8 @@ case 3: for(UINT i = 0; i < nSamples; i++) { - pOutL[i] -= m_pTempBuffer[0][i] - m_MixState.pOutBufferL[i]*wetRatio; - pOutR[i] -= m_pTempBuffer[0][i] - m_MixState.pOutBufferR[i]*wetRatio; + pOutL[i] -= outputBuffers[0][i] - m_MixState.pOutBufferL[i]*wetRatio; + pOutR[i] -= outputBuffers[0][i] - m_MixState.pOutBufferR[i]*wetRatio; } break; @@ -2251,8 +2210,8 @@ for(UINT i = 0; i < nSamples; i++) { float middle = ( pOutL[i] + m_MixState.pOutBufferL[i] + pOutR[i] + m_MixState.pOutBufferR[i] )/2.0f; - pOutL[i] -= middle - m_pTempBuffer[0][i]*wetRatio + middle - m_MixState.pOutBufferL[i]; - pOutR[i] -= middle - m_pTempBuffer[0][i]*wetRatio + middle - m_MixState.pOutBufferR[i]; + pOutL[i] -= middle - outputBuffers[0][i]*wetRatio + middle - m_MixState.pOutBufferL[i]; + pOutR[i] -= middle - outputBuffers[0][i]*wetRatio + middle - m_MixState.pOutBufferR[i]; } break; @@ -2265,8 +2224,8 @@ } for(UINT i = 0; i < nSamples; i++) { - pOutL[i] += wetRatio * (m_pTempBuffer[0][i] - m_MixState.pOutBufferL[i]) + dryRatio * (m_MixState.pOutBufferR[i] - m_pTempBuffer[0][i]); - pOutR[i] += dryRatio * (m_pTempBuffer[0][i] - m_MixState.pOutBufferL[i]) + wetRatio * (m_MixState.pOutBufferR[i] - m_pTempBuffer[0][i]); + pOutL[i] += wetRatio * (outputBuffers[0][i] - m_MixState.pOutBufferL[i]) + dryRatio * (m_MixState.pOutBufferR[i] - outputBuffers[0][i]); + pOutR[i] += dryRatio * (outputBuffers[0][i] - m_MixState.pOutBufferL[i]) + wetRatio * (m_MixState.pOutBufferR[i] - outputBuffers[0][i]); } break; } @@ -2298,8 +2257,8 @@ //rewbs.wetratio - added the factors. [20040123] - pOutL[i] += m_pTempBuffer[0][i]*wetRatio + m_MixState.pOutBufferL[i]*dryRatio; - pOutR[i] += m_pTempBuffer[1][i]*wetRatio + m_MixState.pOutBufferR[i]*dryRatio; + pOutL[i] += outputBuffers[0][i]*wetRatio + m_MixState.pOutBufferL[i]*dryRatio; + pOutR[i] += outputBuffers[1][i]*wetRatio + m_MixState.pOutBufferR[i]*dryRatio; //If dry mix is ticked, we add the unprocessed buffer, //except if this is an instrument since it has already been done: @@ -2328,8 +2287,8 @@ for(UINT i=0; i<nSamples; i++) { //rewbs.wetratio - added the factors. [20040123] - pOutL[i] += m_pTempBuffer[0][i]*wetRatio + m_MixState.pOutBufferL[i]*dryRatio; - pOutR[i] += m_pTempBuffer[1][i]*wetRatio + m_MixState.pOutBufferR[i]*dryRatio; + pOutL[i] += outputBuffers[0][i]*wetRatio + m_MixState.pOutBufferL[i]*dryRatio; + pOutR[i] += outputBuffers[1][i]*wetRatio + m_MixState.pOutBufferR[i]*dryRatio; } break; @@ -2337,8 +2296,8 @@ case 1: for(UINT i=0; i<nSamples; i++) { - pOutL[i] += m_MixState.pOutBufferL[i] - m_pTempBuffer[0][i]*wetRatio; - pOutR[i] += m_MixState.pOutBufferR[i] - m_pTempBuffer[1][i]*wetRatio; + pOutL[i] += m_MixState.pOutBufferL[i] - outputBuffers[0][i]*wetRatio; + pOutR[i] += m_MixState.pOutBufferR[i] - outputBuffers[1][i]*wetRatio; } break; @@ -2346,8 +2305,8 @@ case 2: for(UINT i=0; i<nSamples; i++) { - pOutL[i] += m_pTempBuffer[0][i] - m_MixState.pOutBufferL[i]*dryRatio; - pOutR[i] += m_pTempBuffer[1][i] - m_MixState.pOutBufferR[i]*dryRatio; + pOutL[i] += outputBuffers[0][i] - m_MixState.pOutBufferL[i]*dryRatio; + pOutR[i] += outputBuffers[1][i] - m_MixState.pOutBufferR[i]*dryRatio; } break; @@ -2355,8 +2314,8 @@ case 3: for(UINT i=0; i<nSamples; i++) { - pOutL[i] -= m_pTempBuffer[0][i] - m_MixState.pOutBufferL[i]*wetRatio; - pOutR[i] -= m_pTempBuffer[1][i] - m_MixState.pOutBufferR[i]*wetRatio; + pOutL[i] -= outputBuffers[0][i] - m_MixState.pOutBufferL[i]*wetRatio; + pOutR[i] -= outputBuffers[1][i] - m_MixState.pOutBufferR[i]*wetRatio; } break; @@ -2365,8 +2324,8 @@ for(UINT i=0; i<nSamples; i++) { float middle = ( pOutL[i] + m_MixState.pOutBufferL[i] + pOutR[i] + m_MixState.pOutBufferR[i] )/2.0f; - pOutL[i] -= middle - m_pTempBuffer[0][i]*wetRatio + middle - m_MixState.pOutBufferL[i]; - pOutR[i] -= middle - m_pTempBuffer[1][i]*wetRatio + middle - m_MixState.pOutBufferR[i]; + pOutL[i] -= middle - outputBuffers[0][i]*wetRatio + middle - m_MixState.pOutBufferL[i]; + pOutR[i] -= middle - outputBuffers[1][i]*wetRatio + middle - m_MixState.pOutBufferR[i]; } break; @@ -2379,8 +2338,8 @@ } for(UINT i=0; i<nSamples; i++) { - pOutL[i] += wetRatio * (m_pTempBuffer[0][i] - m_MixState.pOutBufferL[i]) + dryRatio * (m_MixState.pOutBufferR[i] - m_pTempBuffer[1][i]); - pOutR[i] += dryRatio * (m_pTempBuffer[0][i] - m_MixState.pOutBufferL[i]) + wetRatio * (m_MixState.pOutBufferR[i] - m_pTempBuffer[1][i]); + pOutL[i] += wetRatio * (outputBuffers[0][i] - m_MixState.pOutBufferL[i]) + dryRatio * (m_MixState.pOutBufferR[i] - outputBuffers[1][i]); + pOutR[i] += dryRatio * (outputBuffers[0][i] - m_MixState.pOutBufferL[i]) + wetRatio * (m_MixState.pOutBufferR[i] - outputBuffers[1][i]); } break; } Modified: trunk/OpenMPT/mptrack/Vstplug.h =================================================================== --- trunk/OpenMPT/mptrack/Vstplug.h 2011-12-30 21:28:08 UTC (rev 1149) +++ trunk/OpenMPT/mptrack/Vstplug.h 2012-01-01 21:52:39 UTC (rev 1150) @@ -8,6 +8,8 @@ #include <vstfxstore.h> #endif +#include "../soundlib/PluginMixBuffer.h" + #define kBuzzMagic 'Buzz' #define kDmoMagic 'DXMO' @@ -79,12 +81,10 @@ VstEvents *m_pEvList; VSTINSTCH m_MidiCh[16]; short m_nMidiPitchBendPos[16]; - float **m_pTempBuffer; //rewbs.dryRatio: changed from * to ** - float **m_pInputs; - float **m_pOutputs; - int m_MixBuffer[MIXBUFFERSIZE*2+2]; // Stereo interleaved - float m_FloatBuffer[MIXBUFFERSIZE*(2+32)+34]; // 2ch separated + up to 32 VSTi outputs... - float dummyBuffer_[MIXBUFFERSIZE + 2]; // Other (unused) inputs + + int m_MixBuffer[MIXBUFFERSIZE*2+2]; // Stereo interleaved + PluginMixBuffer<float> mixBuffer; // Float buffers (input and output) for plugins + VstMidiEvent m_ev_queue[VSTEVENT_QUEUE_LEN]; CModDoc* m_pModDoc; //rewbs.plugDocAware CSoundFile* m_pSndFile; //rewbs.plugDocAware Modified: trunk/OpenMPT/mptrack/mptrack.vcproj =================================================================== --- trunk/OpenMPT/mptrack/mptrack.vcproj 2011-12-30 21:28:08 UTC (rev 1149) +++ trunk/OpenMPT/mptrack/mptrack.vcproj 2012-01-01 21:52:39 UTC (rev 1150) @@ -849,6 +849,9 @@ RelativePath=".\PSRatioCalc.h"> </File> <File + RelativePath=".\soundlib\PluginMixBuffer.h"> + </File> + <File RelativePath="..\common\Reporting.h"> </File> <File Modified: trunk/OpenMPT/mptrack/mptrack_08.vcproj =================================================================== --- trunk/OpenMPT/mptrack/mptrack_08.vcproj 2011-12-30 21:28:08 UTC (rev 1149) +++ trunk/OpenMPT/mptrack/mptrack_08.vcproj 2012-01-01 21:52:39 UTC (rev 1150) @@ -1127,6 +1127,10 @@ > </File> <File + RelativePath=".\soundlib\PluginMixBuffer.h" + > + </File> + <File RelativePath="..\common\Reporting.h" > </File> Modified: trunk/OpenMPT/mptrack/mptrack_10.vcxproj =================================================================== --- trunk/OpenMPT/mptrack/mptrack_10.vcxproj 2011-12-30 21:28:08 UTC (rev 1149) +++ trunk/OpenMPT/mptrack/mptrack_10.vcxproj 2012-01-01 21:52:39 UTC (rev 1150) @@ -328,6 +328,7 @@ <ClInclude Include="..\common\StringFixer.h" /> <ClInclude Include="..\common\typedefs.h" /> <ClInclude Include="..\soundlib\MIDIMacros.h" /> + <ClInclude Include="..\soundlib\PluginMixBuffer.h" /> <ClInclude Include="ACMConvert.h" /> <ClInclude Include="Autotune.h" /> <ClInclude Include="ExceptionHandler.h" /> Modified: trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters =================================================================== --- trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters 2011-12-30 21:28:08 UTC (rev 1149) +++ trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters 2012-01-01 21:52:39 UTC (rev 1150) @@ -771,6 +771,9 @@ <ClInclude Include="..\soundlib\MIDIMacros.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="..\soundlib\PluginMixBuffer.h"> + <Filter>Header Files</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <None Include="res\bitmap1.bmp"> Modified: trunk/OpenMPT/mptrack/version.h =================================================================== --- trunk/OpenMPT/mptrack/version.h 2011-12-30 21:28:08 UTC (rev 1149) +++ trunk/OpenMPT/mptrack/version.h 2012-01-01 21:52:39 UTC (rev 1150) @@ -15,7 +15,7 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 20 #define VER_MINOR 00 -#define VER_MINORMINOR 58 +#define VER_MINORMINOR 59 //Creates version number from version parts that appears in version string. //For example MAKE_VERSION_NUMERIC(1,17,02,28) gives version number of Added: trunk/OpenMPT/soundlib/PluginMixBuffer.h =================================================================== --- trunk/OpenMPT/soundlib/PluginMixBuffer.h (rev 0) +++ trunk/OpenMPT/soundlib/PluginMixBuffer.h 2012-01-01 21:52:39 UTC (rev 1150) @@ -0,0 +1,132 @@ +/* + * PluginMixBuffer.h + * ----------------- + * Purpose: Helper class for managing plugin audio input and output buffers. + * Notes : (currently none) + * Authors: OpenMPT Devs + */ + +#pragma once +#ifndef PLUGINMIXBUFFER_H +#define PLUGINMIXBUFFER_H + +// At least this part of the code is ready for double-precision rendering... :> +template<typename buffer_t> +//=================== +class PluginMixBuffer +//=================== +{ +protected: + + buffer_t *mixBuffer; // Actual buffer, contains all input and output buffers + buffer_t **inputsArray; // Pointers to input buffers + buffer_t **outputsArray; // Pointers to output buffers + + size_t inputs, outputs; // Number of input and output buffers + + // Buffers on 32-Bit platforms: Aligned to 32 bytes + // Buffers on 64-Bit platforms: Aligned to 64 bytes + static_assert(sizeof(intptr_t) * 8 >= sizeof(buffer_t), "Check buffer alignment code"); + static const size_t bufferAlignmentInBytes = (sizeof(intptr_t) * 8) - 1; + static const size_t additionalBuffer = ((sizeof(intptr_t) * 8) / sizeof(buffer_t)); + + // Return pointer to an aligned buffer + buffer_t *GetBuffer(size_t index) + //------------------------------- + { + ASSERT(index < inputs + outputs); + return reinterpret_cast<buffer_t *>((reinterpret_cast<intptr_t>(&mixBuffer[MIXBUFFERSIZE * index]) + bufferAlignmentInBytes) & ~bufferAlignmentInBytes); + } + +public: + + // Allocate input and output buffers + bool Initialize(size_t inputs, size_t outputs) + //-------------------------------------------- + { + Free(); + this->inputs = inputs; + this->outputs = outputs; + try + { + // Create inputs + outputs buffers with additional alignment. + const size_t bufferSize = MIXBUFFERSIZE * (inputs + outputs) + additionalBuffer; + mixBuffer = new buffer_t[bufferSize]; + memset(mixBuffer, 0, bufferSize * sizeof(buffer_t)); + + inputsArray = new (buffer_t *[inputs]); + outputsArray = new (buffer_t *[outputs]); + } catch(MPTMemoryException) + { + return false; + } + + for(size_t i = 0; i < inputs; i++) + { + inputsArray[i] = GetInputBuffer(i); + } + + for(size_t i = 0; i < outputs; i++) + { + outputsArray[i] = GetOutputBuffer(i); + } + + return true; + } + + // Free previously allocated buffers. + bool Free() + //--------- + { + delete[] mixBuffer; + mixBuffer = nullptr; + + delete[] inputsArray; + inputsArray = nullptr; + + delete[] outputsArray; + outputsArray = nullptr; + + inputs = outputs = 0; + + return true; + } + + // Silence all output buffers. + void ClearOutputBuffers(size_t numSamples) + //---------------------------------------- + { + ASSERT(numSamples <= MIXBUFFERSIZE); + for(size_t i = 0; i < outputs; i++) + { + memset(outputsArray[i], 0, numSamples * sizeof(buffer_t)); + } + } + + PluginMixBuffer() + //--------------- + { + mixBuffer = nullptr; + inputsArray = nullptr; + outputsArray = nullptr; + Initialize(2, 0); + } + + ~PluginMixBuffer() + //---------------- + { + Free(); + } + + // Return pointer to a given input or output buffer + buffer_t *GetInputBuffer(size_t index) { return GetBuffer(index); } + buffer_t *GetOutputBuffer(size_t index) { return GetBuffer(inputs + index); } + + // Return pointer array to all input or output buffers + buffer_t **GetInputBufferArray() { return inputsArray; } + buffer_t **GetOutputBufferArray() { return outputsArray; } + +}; + +#endif // PLUGINMIXBUFFER_H + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2012-01-02 20:16:15
|
Revision: 1152 http://modplug.svn.sourceforge.net/modplug/?rev=1152&view=rev Author: saga-games Date: 2012-01-02 20:16:08 +0000 (Mon, 02 Jan 2012) Log Message: ----------- [Fix] Revision 1149 broke IT Pan / Pitch envelopes. [Fix] VST: effSetProcessPrecision code was wrong Revision Links: -------------- http://modplug.svn.sourceforge.net/modplug/?rev=1149&view=rev Modified Paths: -------------- trunk/OpenMPT/mptrack/Vstplug.cpp trunk/OpenMPT/soundlib/Sndmix.cpp Modified: trunk/OpenMPT/mptrack/Vstplug.cpp =================================================================== --- trunk/OpenMPT/mptrack/Vstplug.cpp 2012-01-02 00:14:12 UTC (rev 1151) +++ trunk/OpenMPT/mptrack/Vstplug.cpp 2012-01-02 20:16:08 UTC (rev 1152) @@ -1107,7 +1107,7 @@ // Floating point processing precision case effSetProcessPrecision: - return kVstProcessPrecision32; + return (value == kVstProcessPrecision32 ? 1 : 0); } Modified: trunk/OpenMPT/soundlib/Sndmix.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndmix.cpp 2012-01-02 00:14:12 UTC (rev 1151) +++ trunk/OpenMPT/soundlib/Sndmix.cpp 2012-01-02 20:16:08 UTC (rev 1152) @@ -1110,7 +1110,7 @@ // IT Compatibility: S79 does not disable the panning envelope, it just pauses the counter if (((pChn->PanEnv.flags & ENV_ENABLED) || ((pIns->PanEnv.dwFlags & ENV_ENABLED) && IsCompatibleMode(TRK_IMPULSETRACKER))) && (pIns->PanEnv.nNodes)) { - if(IsCompatibleMode(TRK_IMPULSETRACKER) && pChn->VolEnv.nEnvPosition == 0) + if(IsCompatibleMode(TRK_IMPULSETRACKER) && pChn->PanEnv.nEnvPosition == 0) { // If the envelope is disabled at the very same moment as it is triggered, we do not process anything. return; @@ -1169,7 +1169,7 @@ // IT Compatibility: S7B does not disable the pitch envelope, it just pauses the counter if ((pIns) && ((pChn->PitchEnv.flags & ENV_ENABLED) || ((pIns->PitchEnv.dwFlags & ENV_ENABLED) && IsCompatibleMode(TRK_IMPULSETRACKER))) && (pChn->pModInstrument->PitchEnv.nNodes)) { - if(IsCompatibleMode(TRK_IMPULSETRACKER) && pChn->VolEnv.nEnvPosition == 0) + if(IsCompatibleMode(TRK_IMPULSETRACKER) && pChn->PitchEnv.nEnvPosition == 0) { // If the envelope is disabled at the very same moment as it is triggered, we do not process anything. return; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2012-01-03 17:08:11
|
Revision: 1155 http://modplug.svn.sourceforge.net/modplug/?rev=1155&view=rev Author: saga-games Date: 2012-01-03 17:08:04 +0000 (Tue, 03 Jan 2012) Log Message: ----------- [Mod] VST: Knob mode is set to linear for plugins that support it. [Fix] IT Loader: Instruments in IT files with no samples are now loaded correctly. [Fix] MPTM: Last character in sample / instrument names was lost. [Fix] Bidi loop reset fix is now also applied to XM modules. [Ref] Smaller changes. Modified Paths: -------------- trunk/OpenMPT/mptrack/VSTEditor.cpp trunk/OpenMPT/soundlib/Dlsbank.cpp trunk/OpenMPT/soundlib/Load_it.cpp trunk/OpenMPT/soundlib/PluginMixBuffer.h trunk/OpenMPT/soundlib/Snd_fx.cpp trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/mod_specifications.h Modified: trunk/OpenMPT/mptrack/VSTEditor.cpp =================================================================== --- trunk/OpenMPT/mptrack/VSTEditor.cpp 2012-01-03 15:58:51 UTC (rev 1154) +++ trunk/OpenMPT/mptrack/VSTEditor.cpp 2012-01-03 17:08:04 UTC (rev 1155) @@ -64,6 +64,9 @@ m_pVstPlugin->Dispatch(effEditTop, 0,0, NULL, 0); m_pVstPlugin->Dispatch(effEditIdle, 0,0, NULL, 0); + + // Set knob mode to linear (2) instead of circular (0) for those plugins that support it (e.g. Steinberg VB-1) + m_pVstPlugin->Dispatch(effSetEditKnobMode, 0, 2, nullptr, 0.0f); } ShowWindow(SW_SHOW); Modified: trunk/OpenMPT/soundlib/Dlsbank.cpp =================================================================== --- trunk/OpenMPT/soundlib/Dlsbank.cpp 2012-01-03 15:58:51 UTC (rev 1154) +++ trunk/OpenMPT/soundlib/Dlsbank.cpp 2012-01-03 17:08:04 UTC (rev 1155) @@ -1740,7 +1740,7 @@ } else { nSample = pSndFile->GetNextFreeSample(nInstr); - if (nSample >= MAX_SAMPLES) break; + if (nSample == SAMPLEINDEX_INVALID) break; if (nSample > pSndFile->GetNumSamples()) pSndFile->m_nSamples = nSample; nSmp = nSample; nLoadedSmp++; Modified: trunk/OpenMPT/soundlib/Load_it.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_it.cpp 2012-01-03 15:58:51 UTC (rev 1154) +++ trunk/OpenMPT/soundlib/Load_it.cpp 2012-01-03 17:08:04 UTC (rev 1155) @@ -368,10 +368,10 @@ if (pis->mpr<=128) pIns->nMidiProgram = pis->mpr; pIns->nMidiChannel = pis->mch; - if (pIns->nMidiChannel > 16) //rewbs.instroVSTi + if (pIns->nMidiChannel >= 128) //rewbs.instroVSTi { //(handle old format where midichan // and mixplug are 1 value) - pIns->nMixPlug = pIns->nMidiChannel-128; + pIns->nMixPlug = pIns->nMidiChannel - 128; pIns->nMidiChannel = 0; } if (pis->mbank<=128) @@ -952,7 +952,7 @@ if (m_nInstruments >= MAX_INSTRUMENTS) m_nInstruments = MAX_INSTRUMENTS-1; for (UINT nins=0; nins<m_nInstruments; nins++) { - if ((inspos[nins] > 0) && (inspos[nins] < dwMemLength - (pifh->cmwt < 0x200 ? sizeof(ITOLDINSTRUMENT) : sizeof(ITINSTRUMENT)))) + if ((inspos[nins] > 0) && (inspos[nins] <= dwMemLength - (pifh->cmwt < 0x200 ? sizeof(ITOLDINSTRUMENT) : sizeof(ITINSTRUMENT)))) { try { Modified: trunk/OpenMPT/soundlib/PluginMixBuffer.h =================================================================== --- trunk/OpenMPT/soundlib/PluginMixBuffer.h 2012-01-03 15:58:51 UTC (rev 1154) +++ trunk/OpenMPT/soundlib/PluginMixBuffer.h 2012-01-03 17:08:04 UTC (rev 1155) @@ -31,8 +31,8 @@ static const size_t additionalBuffer = ((sizeof(intptr_t) * 8) / sizeof(buffer_t)); // Return pointer to an aligned buffer - buffer_t *GetBuffer(size_t index) - //------------------------------- + buffer_t *GetBuffer(size_t index) const + //------------------------------------- { ASSERT(index < inputs + outputs); return reinterpret_cast<buffer_t *>((reinterpret_cast<intptr_t>(&mixBuffer[MIXBUFFERSIZE * index]) + bufferAlignmentInBytes) & ~bufferAlignmentInBytes); @@ -44,9 +44,17 @@ bool Initialize(size_t inputs, size_t outputs) //-------------------------------------------- { + // Short cut - we do not need to recreate the buffers. + if(this->inputs == inputs && this->outputs == outputs) + { + return true; + } + Free(); + this->inputs = inputs; this->outputs = outputs; + try { // Create inputs + outputs buffers with additional alignment. @@ -109,6 +117,9 @@ mixBuffer = nullptr; inputsArray = nullptr; outputsArray = nullptr; + + inputs = outputs = 0; + Initialize(2, 0); } @@ -119,14 +130,13 @@ } // Return pointer to a given input or output buffer - buffer_t *GetInputBuffer(size_t index) { return GetBuffer(index); } - buffer_t *GetOutputBuffer(size_t index) { return GetBuffer(inputs + index); } + buffer_t *GetInputBuffer(size_t index) const { return GetBuffer(index); } + buffer_t *GetOutputBuffer(size_t index) const { return GetBuffer(inputs + index); } // Return pointer array to all input or output buffers - buffer_t **GetInputBufferArray() { return inputsArray; } - buffer_t **GetOutputBufferArray() { return outputsArray; } + buffer_t **GetInputBufferArray() const { return inputsArray; } + buffer_t **GetOutputBufferArray() const { return outputsArray; } }; #endif // PLUGINMIXBUFFER_H - Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp =================================================================== --- trunk/OpenMPT/soundlib/Snd_fx.cpp 2012-01-03 15:58:51 UTC (rev 1154) +++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2012-01-03 17:08:04 UTC (rev 1155) @@ -749,7 +749,7 @@ //IT compatibility tentative fix: Don't change bidi loop direction when //no sample nor instrument is changed. - if(IsCompatibleMode(TRK_IMPULSETRACKER) && pSmp == pChn->pModSample && !bInstrumentChanged) + if(IsCompatibleMode(TRK_ALLTRACKERS) && pSmp == pChn->pModSample && !bInstrumentChanged) pChn->dwFlags = (pChn->dwFlags & (CHN_CHANNELFLAGS | CHN_PINGPONGFLAG)) | (pSmp->uFlags & CHN_SAMPLEFLAGS); else pChn->dwFlags = (pChn->dwFlags & CHN_CHANNELFLAGS) | (pSmp->uFlags & CHN_SAMPLEFLAGS); @@ -819,10 +819,10 @@ // Fix sample position on instrument change. This is needed for PT1x MOD and IT "on the fly" sample change. if(pChn->nPos >= pChn->nLength) { - if((m_nType & MOD_TYPE_IT)) + if((GetType() & MOD_TYPE_IT)) { pChn->nPos = pChn->nPosLo = 0; - } else if((m_nType & MOD_TYPE_MOD)) // TODO does not always seem to work, especially with short chip samples? + } else if((GetType() & MOD_TYPE_MOD)) // TODO does not always seem to work, especially with short chip samples? { pChn->nPos = pChn->nLoopStart; pChn->nPosLo = 0; @@ -853,7 +853,7 @@ if (note > NOTE_MAX) { // Key Off (+ Invalid Note for XM - TODO is this correct?) - if (note == NOTE_KEYOFF || !(m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT))) + if (note == NOTE_KEYOFF || !(GetType() & (MOD_TYPE_IT|MOD_TYPE_MPT))) { KeyOff(nChn); } @@ -991,11 +991,11 @@ else bPorta = false; - if ((!bPorta) || (!(m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT))) + if ((!bPorta) || (!(GetType() & (MOD_TYPE_IT|MOD_TYPE_MPT))) || ((pChn->dwFlags & CHN_NOTEFADE) && (!pChn->nFadeOutVol)) || ((m_dwSongFlags & SONG_ITCOMPATGXX) && (pChn->rowCommand.instr))) { - if ((m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT)) && (pChn->dwFlags & CHN_NOTEFADE) && (!pChn->nFadeOutVol)) + if ((GetType() & (MOD_TYPE_IT|MOD_TYPE_MPT)) && (pChn->dwFlags & CHN_NOTEFADE) && (!pChn->nFadeOutVol)) { ResetChannelEnvelopes(pChn); // IT Compatibility: Autovibrato reset @@ -1009,7 +1009,7 @@ } if ((!bPorta) || (!(m_dwSongFlags & SONG_ITCOMPATGXX)) || (pChn->rowCommand.instr)) { - if ((!(m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2))) || (pChn->rowCommand.instr)) + if ((!(GetType() & (MOD_TYPE_XM|MOD_TYPE_MT2))) || (pChn->rowCommand.instr)) { pChn->dwFlags &= ~CHN_NOTEFADE; pChn->nFadeOutVol = 65536; @@ -1043,7 +1043,7 @@ if (!(pIns->VolEnv.dwFlags & ENV_CARRY)) pChn->VolEnv.nEnvPosition = 0; if (!(pIns->PanEnv.dwFlags & ENV_CARRY)) pChn->PanEnv.nEnvPosition = 0; if (!(pIns->PitchEnv.dwFlags & ENV_CARRY)) pChn->PitchEnv.nEnvPosition = 0; - if (m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT)) + if (GetType() & (MOD_TYPE_IT|MOD_TYPE_MPT)) { // Volume Swing if (pIns->nVolSwing) @@ -3909,7 +3909,7 @@ if (pChn->pModInstrument) { const MODINSTRUMENT *pIns = pChn->pModInstrument; - if (((pIns->VolEnv.dwFlags & ENV_LOOP) || (m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2))) && (pIns->nFadeOut)) + if (((pIns->VolEnv.dwFlags & ENV_LOOP) || (GetType() & (MOD_TYPE_XM|MOD_TYPE_MT2))) && (pIns->nFadeOut)) { pChn->dwFlags |= CHN_NOTEFADE; } @@ -3935,7 +3935,7 @@ #ifndef MODPLUG_TRACKER #ifndef FASTSOUNDLIB // Big Hack!!! - if ((!param) || (param >= 0x80) || ((m_nType & (MOD_TYPE_MOD|MOD_TYPE_XM|MOD_TYPE_MT2)) && (param >= 0x1E))) + if ((!param) || (param >= 0x80) || ((GetType() & (MOD_TYPE_MOD|MOD_TYPE_XM|MOD_TYPE_MT2)) && (param >= 0x1E))) { if ((!m_nRepeatCount) && (IsSongFinished(m_nCurrentPattern, m_nRow+1))) { @@ -3944,9 +3944,8 @@ } #endif // FASTSOUNDLIB #endif // MODPLUG_TRACKER - //if ((m_nType & MOD_TYPE_S3M) && (param > 0x80)) param -= 0x80; // Allow high speed values here for VBlank MODs. (Maybe it would be better to have a "VBlank MOD" flag somewhere? Is it worth the effort?) - if ((param) && (param <= GetModSpecifications().speedMax || (m_nType & MOD_TYPE_MOD))) m_nMusicSpeed = param; + if ((param) && (param <= GetModSpecifications().speedMax || (GetType() & MOD_TYPE_MOD))) m_nMusicSpeed = param; } @@ -3956,12 +3955,8 @@ const CModSpecifications& specs = GetModSpecifications(); if(setAsNonModcommand) { - if(param < specs.tempoMin) m_nMusicTempo = specs.tempoMin; - else - { - if(param > specs.tempoMax) m_nMusicTempo = specs.tempoMax; - else m_nMusicTempo = param; - } + // Set tempo from UI - ignore slide commands and such. + m_nMusicTempo = CLAMP(param, specs.tempoMin, specs.tempoMax); } else { @@ -4439,21 +4434,22 @@ void CSoundFile::InitializeVisitedRows(bool bReset, VisitedRowsType *pRowVector) //------------------------------------------------------------------------------ { + const ORDERINDEX nMaxOrd = Order.GetLengthTailTrimmed(); if(pRowVector == nullptr) { pRowVector = &m_VisitedRows; } - pRowVector->resize(Order.GetLengthTailTrimmed()); + pRowVector->resize(nMaxOrd); - for(ORDERINDEX nOrd = 0; nOrd < Order.GetLengthTailTrimmed(); nOrd++) + for(ORDERINDEX nOrd = 0; nOrd < nMaxOrd; nOrd++) { - VisitedRowsBaseType *pRow = &(pRowVector->at(nOrd)); + VisitedRowsBaseType &row = pRowVector->at(nOrd); // If we want to reset the vectors completely, we overwrite existing items with false. if(bReset) { - pRow->assign(pRow->size(), false); + row.assign(row.size(), false); } - pRow->resize(GetVisitedRowsVectorSize(Order[nOrd]), false); + row.resize(GetVisitedRowsVectorSize(Order[nOrd]), false); } } @@ -4482,7 +4478,7 @@ InitializeVisitedRows(false, pRowVector); } - pRowVector->at(nOrd)[nRow] = bVisited; + pRowVector->at(nOrd).at(nRow) = bVisited; } @@ -4514,7 +4510,7 @@ return false; } - if(pRowVector->at(nOrd)[nRow]) + if(pRowVector->at(nOrd).at(nRow)) { // we visited this row already - this module must be looping. return true; @@ -4522,7 +4518,7 @@ if(bAutoSet) { - pRowVector->at(nOrd)[nRow] = true; + pRowVector->at(nOrd).at(nRow) = true; } return false; Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2012-01-03 15:58:51 UTC (rev 1154) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2012-01-03 17:08:04 UTC (rev 1155) @@ -2441,17 +2441,16 @@ if ((!nSample) || (nSample > GetNumSamples())) return false; if (GetNumInstruments()) { - for (UINT i = 1; i <= GetNumInstruments(); i++) if (Instruments[i]) + for (INSTRUMENTINDEX i = 1; i <= GetNumInstruments(); i++) { - MODINSTRUMENT *pIns = Instruments[i]; - for (UINT j = 0; j < CountOf(pIns->Keyboard); j++) + if(IsSampleReferencedByInstrument(nSample, i)) { - if (pIns->Keyboard[j] == nSample) return true; + return true; } } } else { - for (UINT i=0; i<Patterns.Size(); i++) if (Patterns[i]) + for (PATTERNINDEX i = 0; i < Patterns.Size(); i++) if (Patterns[i]) { const MODCOMMAND *m = Patterns[i]; for (UINT j=m_nChannels*Patterns[i].GetNumRows(); j; m++, j--) Modified: trunk/OpenMPT/soundlib/mod_specifications.h =================================================================== --- trunk/OpenMPT/soundlib/mod_specifications.h 2012-01-03 15:58:51 UTC (rev 1154) +++ trunk/OpenMPT/soundlib/mod_specifications.h 2012-01-03 17:08:04 UTC (rev 1155) @@ -88,9 +88,9 @@ 1, // Min pattern rows 1024, // Max pattern rows 25, // Max mod name length - 26, // Max sample name length + 25, // Max sample name length 12, // Max sample filename length - 26, // Max instrument name length + 25, // Max instrument name length 12, // Max instrument filename length 3999, // SamplesMax 255, // instrumentMax This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2012-01-03 18:26:21
|
Revision: 1156 http://modplug.svn.sourceforge.net/modplug/?rev=1156&view=rev Author: saga-games Date: 2012-01-03 18:26:14 +0000 (Tue, 03 Jan 2012) Log Message: ----------- [New] VST: Added "mappped" MIDI channels (like in Impulse Tracker). If a plugin's MIDI Channel is set to "mapped", note data is transmitted on a triggered note's pattern channel modulo 16. [Mod] OpenMPT: Version is now 1.20.00.60 Modified Paths: -------------- trunk/OpenMPT/mptrack/Ctrl_ins.cpp trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/Moddoc.h trunk/OpenMPT/mptrack/View_smp.cpp trunk/OpenMPT/mptrack/Vstplug.cpp trunk/OpenMPT/mptrack/Vstplug.h trunk/OpenMPT/mptrack/version.h trunk/OpenMPT/soundlib/Sampleio.cpp trunk/OpenMPT/soundlib/Snd_defs.h trunk/OpenMPT/soundlib/Snd_fx.cpp trunk/OpenMPT/soundlib/Sndfile.h trunk/OpenMPT/soundlib/Sndmix.cpp Modified: trunk/OpenMPT/mptrack/Ctrl_ins.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2012-01-03 17:08:04 UTC (rev 1155) +++ trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2012-01-03 18:26:14 UTC (rev 1156) @@ -926,17 +926,7 @@ m_SpinMidiPR.SetRange(0, 128); // rewbs.MidiBank m_SpinMidiBK.SetRange(0, 128); - // Midi Channel - //rewbs.instroVSTi: we no longer combine midi chan and FX in same cbbox - for (UINT ich=0; ich<17; ich++) - { - UINT n = 0; - s[0] = 0; - if (!ich) { strcpy(s, "None"); n=0; } - else { wsprintf(s, "%d", ich); n=ich; } - if (s[0]) m_CbnMidiCh.SetItemData(m_CbnMidiCh.AddString(s), n); - } - //end rewbs.instroVSTi + m_CbnResampling.SetItemData(m_CbnResampling.AddString("Default"), SRCMODE_DEFAULT); m_CbnResampling.SetItemData(m_CbnResampling.AddString("None"), SRCMODE_NEAREST); m_CbnResampling.SetItemData(m_CbnResampling.AddString("Linear"), SRCMODE_LINEAR); @@ -1228,6 +1218,22 @@ m_ComboTuning.EnableWindow(bMPTOnly); m_EditPitchTempoLock.EnableWindow(bMPTOnly); m_CheckPitchTempoLock.EnableWindow(bMPTOnly); + + // MIDI Channel + // XM has no "mapped" MIDI channels. + m_CbnMidiCh.ResetContent(); + for (UINT ich = MidiNoChannel; ich <= (bITandMPT ? MidiMappedChannel : MidiLastChannel); ich++) + { + CString s; + if (ich == MidiNoChannel) + s = "None"; + else if (ich == MidiMappedChannel) + s = "Mapped"; + else + s.Format("%d", ich); + m_CbnMidiCh.SetItemData(m_CbnMidiCh.AddString(s), ich); + } + } if (dwHintMask & (HINT_INSTRUMENT|HINT_MODTYPE)) { @@ -1256,13 +1262,8 @@ SetDlgItemInt(IDC_EDIT11, pIns->wMidiBank); else SetDlgItemText(IDC_EDIT11, "---"); - //rewbs.instroVSTi - //was: - //if (pIns->nMidiChannel < 17) m_CbnMidiCh.SetCurSel(pIns->nMidiChannel); else - //if (pIns->nMidiChannel & 0x80) m_CbnMidiCh.SetCurSel((pIns->nMidiChannel&0x7f)+16); else - // m_CbnMidiCh.SetCurSel(0); - //now: - if (pIns->nMidiChannel < 17) + + if (pIns->nMidiChannel < 18) { m_CbnMidiCh.SetCurSel(pIns->nMidiChannel); } else Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2012-01-03 17:08:04 UTC (rev 1155) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2012-01-03 18:26:14 UTC (rev 1156) @@ -866,9 +866,27 @@ return IDCANCEL; } -UINT CModDoc::PlayNote(UINT note, UINT nins, UINT nsmp, BOOL bpause, LONG nVol, LONG loopstart, LONG loopend, int nCurrentChn, const uint32 nStartPos) //rewbs.vstiLive: added current chan param -//---------------------------------------------------------------------------------------------------------------------------------------------------- + +UINT CModDoc::GetPlaybackMidiChannel(const MODINSTRUMENT *pIns, CHANNELINDEX nChn) const +//--------------------------------------------------------------------------------------- { + if(pIns->nMidiChannel == MidiMappedChannel) + { + if(nChn != CHANNELINDEX_INVALID) + { + return nChn % 16; + } + } else if(pIns->HasValidMIDIChannel()) + { + return pIns->nMidiChannel - 1; + } + return 0; +} + + +UINT CModDoc::PlayNote(UINT note, UINT nins, UINT nsmp, BOOL bpause, LONG nVol, LONG loopstart, LONG loopend, CHANNELINDEX nCurrentChn, const uint32 nStartPos) //rewbs.vstiLive: added current chan param +//------------------------------------------------------------------------------------------------------------------------------------------------------------- +{ CMainFrame *pMainFrm = CMainFrame::GetMainFrame(); UINT nChn = GetNumChannels(); @@ -906,9 +924,10 @@ CriticalSection cs; //find a channel if required - //if (nCurrentChn<0) { + /* if (nCurrentChn == CHANNELINDEX_INVALID) + { nChn = FindAvailableChannel(); - //} + } */ MODCHANNEL *pChn = &m_SndFile.Chn[nChn]; @@ -985,7 +1004,6 @@ pChn->nLength = pChn->nLoopEnd = pChn->pModSample->nLength; } - //rewbs.vstiLive if (nins <= m_SndFile.GetNumInstruments()) { @@ -997,13 +1015,17 @@ UINT nPlugin = 0; if (pChn->pModInstrument) nPlugin = pChn->pModInstrument->nMixPlug; // first try instrument VST - if ((!nPlugin) || (nPlugin > MAX_MIXPLUGINS) && (nCurrentChn >=0)) + if ((!nPlugin) || (nPlugin > MAX_MIXPLUGINS) && (nCurrentChn != CHANNELINDEX_INVALID)) nPlugin = m_SndFile.ChnSettings[nCurrentChn].nMixPlugin; // Then try Channel VST if ((nPlugin) && (nPlugin <= MAX_MIXPLUGINS)) { IMixPlugin *pPlugin = m_SndFile.m_MixPlugins[nPlugin - 1].pMixPlugin; - if (pPlugin) pPlugin->MidiCommand(pIns->nMidiChannel, pIns->nMidiProgram, pIns->wMidiBank, pIns->NoteMap[note - 1], pChn->nVolume, MAX_BASECHANNELS); + + if (pPlugin) + { + pPlugin->MidiCommand(GetPlaybackMidiChannel(pIns, nCurrentChn), pIns->nMidiProgram, pIns->wMidiBank, pIns->NoteMap[note - 1], pChn->nVolume, MAX_BASECHANNELS); + } } } } @@ -1019,8 +1041,8 @@ } -BOOL CModDoc::NoteOff(UINT note, BOOL bFade, UINT nins, UINT nCurrentChn) //rewbs.vstiLive: added chan and nins -//----------------------------------------------------------------------- +BOOL CModDoc::NoteOff(UINT note, BOOL bFade, UINT nins, CHANNELINDEX nCurrentChn) //rewbs.vstiLive: added chan and nins +//------------------------------------------------------------------------------- { CriticalSection cs; @@ -1034,14 +1056,16 @@ UINT nPlugin = pIns->nMixPlug; // First try intrument VST if (((!nPlugin) || (nPlugin > MAX_MIXPLUGINS)) && //no good plug yet - (nCurrentChn<MAX_CHANNELS)) // chan OK + (nCurrentChn < MAX_BASECHANNELS)) // chan OK nPlugin = m_SndFile.ChnSettings[nCurrentChn].nMixPlugin;// Then try Channel VST if ((nPlugin) && (nPlugin <= MAX_MIXPLUGINS)) { IMixPlugin *pPlugin = m_SndFile.m_MixPlugins[nPlugin-1].pMixPlugin; - if (pPlugin) pPlugin->MidiCommand(pIns->nMidiChannel, pIns->nMidiProgram, pIns->wMidiBank, pIns->NoteMap[note - 1] + NOTE_KEYOFF, 0, MAX_BASECHANNELS); - + if (pPlugin) + { + pPlugin->MidiCommand(GetPlaybackMidiChannel(pIns, nCurrentChn), pIns->nMidiProgram, pIns->wMidiBank, pIns->NoteMap[note - 1] + NOTE_KEYOFF, 0, MAX_BASECHANNELS); + } } } } @@ -1139,7 +1163,7 @@ MODINSTRUMENT* pIns = m_SndFile.Chn[nChn].pModInstrument; if (pPlug && pIns) { - pPlug->MidiCommand(pIns->nMidiChannel, pIns->nMidiProgram, pIns->wMidiBank, NOTE_KEYOFF, 0, nChn); + pPlug->MidiCommand(m_SndFile.GetBestMidiChannel(nChn), pIns->nMidiProgram, pIns->wMidiBank, NOTE_KEYOFF, 0, nChn); } } } else Modified: trunk/OpenMPT/mptrack/Moddoc.h =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.h 2012-01-03 17:08:04 UTC (rev 1155) +++ trunk/OpenMPT/mptrack/Moddoc.h 2012-01-03 18:26:14 UTC (rev 1156) @@ -268,8 +268,8 @@ bool RemovePattern(PATTERNINDEX nPat); bool RemoveSample(SAMPLEINDEX nSmp); bool RemoveInstrument(INSTRUMENTINDEX nIns); - UINT PlayNote(UINT note, UINT nins, UINT nsmp, BOOL bpause, LONG nVol=-1, LONG loopstart=0, LONG loopend=0, int nCurrentChn=-1, const uint32 nStartPos = uint32_max); //rewbs.vstiLive: added current chan param - BOOL NoteOff(UINT note, BOOL bFade=FALSE, UINT nins=-1, UINT nCurrentChn=-1); //rewbs.vstiLive: add params + UINT PlayNote(UINT note, UINT nins, UINT nsmp, BOOL bpause, LONG nVol=-1, LONG loopstart=0, LONG loopend=0, CHANNELINDEX nCurrentChn = CHANNELINDEX_INVALID, const uint32 nStartPos = uint32_max); //rewbs.vstiLive: added current chan param + BOOL NoteOff(UINT note, BOOL bFade=FALSE, UINT nins=-1, CHANNELINDEX nCurrentChn = CHANNELINDEX_INVALID); //rewbs.vstiLive: add params BOOL IsNotePlaying(UINT note, UINT nsmp=0, UINT nins=0); bool MuteChannel(CHANNELINDEX nChn, bool bMute); @@ -374,7 +374,9 @@ virtual void SetModifiedFlag(BOOL bModified=TRUE); //}}AFX_VIRTUAL + UINT GetPlaybackMidiChannel(const MODINSTRUMENT *pIns, CHANNELINDEX nChn) const; + // Implementation public: virtual ~CModDoc(); Modified: trunk/OpenMPT/mptrack/View_smp.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_smp.cpp 2012-01-03 17:08:04 UTC (rev 1155) +++ trunk/OpenMPT/mptrack/View_smp.cpp 2012-01-03 18:26:14 UTC (rev 1156) @@ -1939,7 +1939,7 @@ pxh->nVibSweep = sample.nVibSweep; pxh->nVibDepth = sample.nVibDepth; pxh->nVibRate = sample.nVibRate; - if(pSndFile->GetType() & MOD_TYPE_XM && (pxh->nVibDepth | pxh->nVibRate)) + if((pSndFile->GetType() & MOD_TYPE_XM) && (pxh->nVibDepth | pxh->nVibRate)) { // XM vibrato is upside down pxh->nVibSweep = 255 - pxh->nVibSweep; @@ -2187,7 +2187,7 @@ loopend = loopstart = 0; // selection is too small -> no loop if(nStartPos != uint32_max) - pModDoc->PlayNote(note, 0, m_nSample, FALSE, -1, loopstart, loopend, -1, nStartPos); + pModDoc->PlayNote(note, 0, m_nSample, FALSE, -1, loopstart, loopend, CHANNELINDEX_INVALID, nStartPos); else pModDoc->PlayNote(note, 0, m_nSample, FALSE, -1, loopstart, loopend); Modified: trunk/OpenMPT/mptrack/Vstplug.cpp =================================================================== --- trunk/OpenMPT/mptrack/Vstplug.cpp 2012-01-03 17:08:04 UTC (rev 1155) +++ trunk/OpenMPT/mptrack/Vstplug.cpp 2012-01-03 18:26:14 UTC (rev 1156) @@ -1010,20 +1010,23 @@ //"receiveVstEvents", //"receiveVstMidiEvent", //"receiveVstTimeInfo", - //"reportConnectionChanges", - //"acceptIOChanges", //"asyncProcessing", //"offline", //"supportShell" + //"shellCategory" //"editFile" //"startStopProcess" + //"sendVstMidiEventFlagIsRealtime" + if ((strcmp((char*)ptr,"sendVstEvents") == 0 || strcmp((char*)ptr,"sendVstMidiEvent") == 0 || strcmp((char*)ptr,"sendVstTimeInfo") == 0 || strcmp((char*)ptr,"supplyIdle") == 0 || strcmp((char*)ptr,"sizeWindow") == 0 || strcmp((char*)ptr,"openFileSelector") == 0 || - strcmp((char*)ptr,"closeFileSelector") == 0 + strcmp((char*)ptr,"closeFileSelector") == 0 || + strcmp((char*)ptr,"acceptIOChanges") == 0 || + strcmp((char*)ptr,"reportConnectionChanges") == 0 )) return HostCanDo; else @@ -1470,6 +1473,8 @@ InitializeIOBuffers(); + Dispatch(effSetProcessPrecision, 0, kVstProcessPrecision32, nullptr, 0.0f); + #ifdef VST_LOG Log("%s: vst ver %d.0, flags=%04X, %d programs, %d parameters\n", m_pFactory->szLibraryName, (m_bIsVst2) ? 2 : 1, m_pEffect->flags, @@ -2497,11 +2502,6 @@ //------------------------------------------------------------------------------------------ { //Error checking - // Decrement midi chan cos we recieve a value in [1,17]; we want [0,16]. - if (--nMidiCh>16) - { - nMidiCh=16; - } if (nController>127) { nController=127; @@ -2541,8 +2541,6 @@ void CVstPlugin::MidiPitchBend(UINT nMidiCh, int nParam, UINT /*trackChannel*/) //----------------------------------------------------------------------------- { - nMidiCh--; // move from 1-17 range to 0-16 range - const int16 increment = static_cast<int16>(nParam * 0x2000/0xFF); int16 newPitchBendPos = m_nMidiPitchBendPos[nMidiCh] + increment; Limit(newPitchBendPos, int16(MIDI_PitchBend_Min), int16(MIDI_PitchBend_Max)); @@ -2564,8 +2562,7 @@ void CVstPlugin::MidiCommand(UINT nMidiCh, UINT nMidiProg, WORD wMidiBank, UINT note, UINT vol, UINT trackChannel) //---------------------------------------------------------------------------------------------------------------- { - UINT nCh = (--nMidiCh) & 0x0f; - PVSTINSTCH pCh = &m_MidiCh[nCh]; + PVSTINSTCH pCh = &m_MidiCh[nMidiCh]; DWORD dwMidiCode = 0; bool bankChanged = (pCh->wMidiBank != --wMidiBank) && (wMidiBank < 0x80); bool progChanged = (pCh->nProgram != --nMidiProg) && (nMidiProg < 0x80); @@ -2582,7 +2579,7 @@ if ((wMidiBank < 0x80) && ( bankChanged /*|| chanChanged */)) { pCh->wMidiBank = wMidiBank; - MidiSend(((wMidiBank<<16)|(0x20<<8))|(0xB0|nCh)); + MidiSend(((wMidiBank<<16)|(0x20<<8))|(0xB0|nMidiCh)); } // Program change // Note: Some plugs (Edirol Orchestral) don't update on bank change only - @@ -2591,14 +2588,14 @@ { pCh->nProgram = nMidiProg; //GetSoundFile()->ProcessMIDIMacro(trackChannel, false, GetSoundFile()->m_MidiCfg.szMidiGlb[MIDIOUT_PROGRAM], 0); - MidiSend((nMidiProg<<8)|(0xC0|nCh)); + MidiSend((nMidiProg<<8)|(0xC0|nMidiCh)); } // Specific Note Off if (note > NOTE_KEYOFF) //rewbs.vstiLive { - dwMidiCode = 0x80|nCh; //note off, on chan nCh + dwMidiCode = 0x80|nMidiCh; //note off, on chan nCh note--; UINT i = note - NOTE_KEYOFF; @@ -2615,10 +2612,10 @@ else if (note == NOTE_NOTECUT) // ^^ { //MidiSend(0xB0|nCh|(0x79<<8)); // reset all controllers - MidiSend(0xB0|nCh|(0x7b<<8)); // all notes off - MidiSend(0xB0|nCh|(0x78<<8)); // all sounds off + MidiSend(0xB0|nMidiCh|(0x7b<<8)); // all notes off + MidiSend(0xB0|nMidiCh|(0x78<<8)); // all sounds off - dwMidiCode = 0x80|nCh|(vol<<16); //note off, on chan nCh; vol is note off velocity. + dwMidiCode = 0x80|nMidiCh|(vol<<16); //note off, on chan nCh; vol is note off velocity. for (UINT i=0; i<128; i++) //all notes { pCh->uNoteOnMap[i][trackChannel]=0; @@ -2631,7 +2628,7 @@ // using note mask. else if (note > 0x80) // == { - dwMidiCode = 0x80|nCh|(vol<<16); //note off, on chan nCh; vol is note off velocity. + dwMidiCode = 0x80|nMidiCh|(vol<<16); //note off, on chan nCh; vol is note off velocity. for (UINT i=0; i<128; i++) { @@ -2654,14 +2651,14 @@ // Note On else if (note > 0) { - dwMidiCode = 0x90|nCh; //note on, on chan nCh + dwMidiCode = 0x90|nMidiCh; //note on, on chan nCh note--; //reset pitch bend on each new note, tracker style. - if (m_nMidiPitchBendPos[nCh] != MIDI_PitchBend_Centre) + if (m_nMidiPitchBendPos[nMidiCh] != MIDI_PitchBend_Centre) { - MidiPitchBend(nCh, MIDI_PitchBend_Centre); + MidiPitchBend(nMidiCh, MIDI_PitchBend_Centre); } // count instances of active notes. @@ -2677,23 +2674,25 @@ MidiSend(dwMidiCode|(note<<8)|(vol<<16)); } - m_nPreviousMidiChan = nCh; + m_nPreviousMidiChan = nMidiCh; } + bool CVstPlugin::isPlaying(UINT note, UINT midiChn, UINT trackerChn) //------------------------------------------------------------------ { note--; - PVSTINSTCH pMidiCh = &m_MidiCh[(midiChn-1) & 0x0f]; - return (pMidiCh->uNoteOnMap[note][trackerChn] != 0); + PVSTINSTCH pMidiCh = &m_MidiCh[midiChn]; + return (pMidiCh->uNoteOnMap[note][trackerChn] != 0); } + bool CVstPlugin::MoveNote(UINT note, UINT midiChn, UINT sourceTrackerChn, UINT destTrackerChn) //--------------------------------------------------------------------------------------------- { note--; - PVSTINSTCH pMidiCh = &m_MidiCh[(midiChn-1) & 0x0f]; + PVSTINSTCH pMidiCh = &m_MidiCh[midiChn & 0x0f]; if (!(pMidiCh->uNoteOnMap[note][sourceTrackerChn])) return false; Modified: trunk/OpenMPT/mptrack/Vstplug.h =================================================================== --- trunk/OpenMPT/mptrack/Vstplug.h 2012-01-03 17:08:04 UTC (rev 1155) +++ trunk/OpenMPT/mptrack/Vstplug.h 2012-01-03 18:26:14 UTC (rev 1156) @@ -153,8 +153,6 @@ CAbstractVstEditor* GetEditor(); //rewbs.defaultPlugGUI bool GetSpeakerArrangement(); //rewbs.VSTCompliance - bool InitializeIOBuffers(); - bool Bypass(bool bypass = true); //rewbs.defaultPlugGUI bool IsBypassed() const { return m_pMixStruct->IsBypassed(); }; //rewbs.defaultPlugGUI @@ -207,6 +205,9 @@ // Helper function for retreiving parameter name / label / display CString GetParamPropertyString(VstInt32 param, VstInt32 opcode); + // Set up input / output buffers. + bool InitializeIOBuffers(); + #else // case: NO_VST public: PlugParamIndex GetNumParameters() {return 0;} Modified: trunk/OpenMPT/mptrack/version.h =================================================================== --- trunk/OpenMPT/mptrack/version.h 2012-01-03 17:08:04 UTC (rev 1155) +++ trunk/OpenMPT/mptrack/version.h 2012-01-03 18:26:14 UTC (rev 1156) @@ -15,7 +15,7 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 20 #define VER_MINOR 00 -#define VER_MINORMINOR 59 +#define VER_MINORMINOR 60 //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/Sampleio.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sampleio.cpp 2012-01-03 17:08:04 UTC (rev 1155) +++ trunk/OpenMPT/soundlib/Sampleio.cpp 2012-01-03 18:26:14 UTC (rev 1156) @@ -2330,6 +2330,11 @@ pIns->nDCT = DCT_NONE; pIns->nDNA = DNA_NOTECUT; + if(pIns->nMidiChannel == MidiMappedChannel) + { + pIns->nMidiChannel == 1; + } + pIns->nGlobalVol = 64; pIns->nPan = 128; Modified: trunk/OpenMPT/soundlib/Snd_defs.h =================================================================== --- trunk/OpenMPT/soundlib/Snd_defs.h 2012-01-03 17:08:04 UTC (rev 1155) +++ trunk/OpenMPT/soundlib/Snd_defs.h 2012-01-03 18:26:14 UTC (rev 1156) @@ -295,7 +295,7 @@ #define SONG_EMBEDMIDICFG 0x0001 // Embed macros in file #define SONG_FASTVOLSLIDES 0x0002 // Old Scream Tracker 3.0 volume slides #define SONG_ITOLDEFFECTS 0x0004 // Old Impulse Tracker effect implementations -#define SONG_ITCOMPATGXX 0x0008 // IT "Compatible Gxx" (IT's flag to behave more like other trackers when it comes to portamento effects) +#define SONG_ITCOMPATGXX 0x0008 // IT "Compatible Gxx" (IT's flag to behave more like other trackers w/r/t portamento effects) #define SONG_LINEARSLIDES 0x0010 // Linear slides vs. Amiga slides #define SONG_PATTERNLOOP 0x0020 // Loop current pattern (pattern editor) #define SONG_STEP 0x0040 // Song is in "step" mode (pattern editor) @@ -408,7 +408,15 @@ INST_NUMFILTERMODES };*/ +enum MidiChannel +{ + MidiNoChannel = 0, + MidiFirstChannel = 1, + MidiLastChannel = 16, + MidiMappedChannel = 17, +}; + // Vibrato Types enum VibratoType { Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp =================================================================== --- trunk/OpenMPT/soundlib/Snd_fx.cpp 2012-01-03 17:08:04 UTC (rev 1155) +++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2012-01-03 18:26:14 UTC (rev 1156) @@ -1266,7 +1266,7 @@ //switch off duplicated note played on this plugin IMixPlugin *pPlugin = m_MixPlugins[pHeader->nMixPlug-1].pMixPlugin; if (pPlugin && p->nNote) - pPlugin->MidiCommand(p->pModInstrument->nMidiChannel, p->pModInstrument->nMidiProgram, p->pModInstrument->wMidiBank, p->nNote + NOTE_KEYOFF, 0, i); + pPlugin->MidiCommand(GetBestMidiChannel(i), p->pModInstrument->nMidiProgram, p->pModInstrument->wMidiBank, p->nNote + NOTE_KEYOFF, 0, i); break; } } @@ -1323,7 +1323,7 @@ { note = pChn->pModInstrument->NoteMap[note - 1]; } - applyNNAtoPlug = pPlugin->isPlaying(note, pChn->pModInstrument->nMidiChannel, nChn); + applyNNAtoPlug = pPlugin->isPlaying(note, GetBestMidiChannel(nChn), nChn); } } } @@ -1360,7 +1360,7 @@ case NNA_NOTEFADE: //switch off note played on this plugin, on this tracker channel and midi channel //pPlugin->MidiCommand(pChn->pModInstrument->nMidiChannel, pChn->pModInstrument->nMidiProgram, pChn->nNote+0xFF, 0, n); - pPlugin->MidiCommand(pChn->pModInstrument->nMidiChannel, pChn->pModInstrument->nMidiProgram, pChn->pModInstrument->wMidiBank, /*pChn->nNote+*/NOTE_KEYOFF, 0, nChn); + pPlugin->MidiCommand(GetBestMidiChannel(nChn), pChn->pModInstrument->nMidiProgram, pChn->pModInstrument->wMidiBank, /*pChn->nNote+*/NOTE_KEYOFF, 0, nChn); break; } } @@ -1745,7 +1745,7 @@ } #ifdef MODPLUG_TRACKER - if (m_nInstruments) ProcessMidiOut(nChn, pChn); + if (m_nInstruments) ProcessMidiOut(nChn); #endif // MODPLUG_TRACKER } @@ -1840,12 +1840,12 @@ case VOLCMD_PORTAUP: // IT compatibility (one of the first testcases - link effect memory) - PortamentoUp(pChn, vol << 2, IsCompatibleMode(TRK_IMPULSETRACKER)); + PortamentoUp(nChn, vol << 2, IsCompatibleMode(TRK_IMPULSETRACKER)); break; case VOLCMD_PORTADOWN: // IT compatibility (one of the first testcases - link effect memory) - PortamentoDown(pChn, vol << 2, IsCompatibleMode(TRK_IMPULSETRACKER)); + PortamentoDown(nChn, vol << 2, IsCompatibleMode(TRK_IMPULSETRACKER)); break; case VOLCMD_OFFSET: //rewbs.volOff @@ -1876,13 +1876,13 @@ // Portamento Up case CMD_PORTAMENTOUP: if ((!param) && (m_nType & MOD_TYPE_MOD)) break; - PortamentoUp(pChn, param); + PortamentoUp(nChn, param); break; // Portamento Down case CMD_PORTAMENTODOWN: if ((!param) && (m_nType & MOD_TYPE_MOD)) break; - PortamentoDown(pChn, param); + PortamentoDown(nChn, param); break; // Volume Slide @@ -2360,10 +2360,11 @@ } -void CSoundFile::PortamentoUp(MODCHANNEL *pChn, UINT param, const bool doFinePortamentoAsRegular) -//----------------------------------------------------------------------------------------------- +void CSoundFile::PortamentoUp(CHANNELINDEX nChn, UINT param, const bool doFinePortamentoAsRegular) +//------------------------------------------------------------------------------------------------ { - MidiPortamento(pChn, param); //Send midi pitch bend event if there's a plugin + MODCHANNEL *pChn = &Chn[nChn]; + MidiPortamento(nChn, param); //Send midi pitch bend event if there's a plugin if(param) pChn->nOldPortaUpDown = param; @@ -2402,10 +2403,11 @@ } -void CSoundFile::PortamentoDown(MODCHANNEL *pChn, UINT param, const bool doFinePortamentoAsRegular) -//------------------------------------------------------------------------------------------------- +void CSoundFile::PortamentoDown(CHANNELINDEX nChn, UINT param, const bool doFinePortamentoAsRegular) +//-------------------------------------------------------------------------------------------------- { - MidiPortamento(pChn, -1*param); //Send midi pitch bend event if there's a plugin + MODCHANNEL *pChn = &Chn[nChn]; + MidiPortamento(nChn, -param); //Send midi pitch bend event if there's a plugin if(param) pChn->nOldPortaUpDown = param; @@ -2442,11 +2444,11 @@ } } -void CSoundFile::MidiPortamento(MODCHANNEL *pChn, int param) -//---------------------------------------------------------- +void CSoundFile::MidiPortamento(CHANNELINDEX nChn, int param) +//----------------------------------------------------------- { //Send midi pitch bend event if there's a plugin: - const MODINSTRUMENT *pIns = pChn->pModInstrument; + const MODINSTRUMENT *pIns = Chn[nChn].pModInstrument; if (pIns && pIns->HasValidMIDIChannel()) { // instro sends to a midi chan @@ -2456,7 +2458,7 @@ IMixPlugin *pPlug = (IMixPlugin*)m_MixPlugins[nPlug-1].pMixPlugin; if (pPlug) { - pPlug->MidiPitchBend(pIns->nMidiChannel, param, 0); + pPlug->MidiPitchBend(GetBestMidiChannel(nChn), param, 0); } } } @@ -3247,7 +3249,7 @@ } else if(macro[pos] == 'c') // c: MIDI channel { isNibble = true; - data = (unsigned char)GetBestMidiChan(pChn); + data = (unsigned char)GetBestMidiChannel(nChn); } else if(macro[pos] == 'n') // n: note value (last triggered note) { if(pChn->nLastNote != NOTE_NONE && NOTE_IS_VALID(pChn->nLastNote)) @@ -3755,7 +3757,7 @@ NoteChange(nChn, nNote, IsCompatibleMode(TRK_IMPULSETRACKER), bResetEnv); if (m_nInstruments) { - ProcessMidiOut(nChn, pChn); //Send retrig to Midi + ProcessMidiOut(nChn); //Send retrig to Midi } if ((GetType() & (MOD_TYPE_IT|MOD_TYPE_MPT)) && (!pChn->rowCommand.note) && (nOldPeriod)) pChn->nPeriod = nOldPeriod; if (!(GetType() & (MOD_TYPE_S3M|MOD_TYPE_IT|MOD_TYPE_MPT))) nRetrigCount = 0; @@ -3859,7 +3861,7 @@ IMixPlugin *pPlug = (IMixPlugin*)m_MixPlugins[nPlug-1].pMixPlugin; if (pPlug) { - pPlug->MidiCommand(pIns->nMidiChannel, pIns->nMidiProgram, pIns->wMidiBank, /*pChn->nNote+*/NOTE_KEYOFF, 0, nChn); + pPlug->MidiCommand(GetBestMidiChannel(nChn), pIns->nMidiProgram, pIns->wMidiBank, /*pChn->nNote+*/NOTE_KEYOFF, 0, nChn); } } } @@ -4320,13 +4322,26 @@ } -UINT CSoundFile::GetBestMidiChan(const MODCHANNEL *pChn) const -//------------------------------------------------------------ +UINT CSoundFile::GetBestMidiChannel(CHANNELINDEX nChn) const +//---------------------------------------------------------- { - if (pChn && pChn->pModInstrument && pChn->pModInstrument->HasValidMIDIChannel()) + if(nChn == CHANNELINDEX_INVALID) { - return (pChn->pModInstrument->nMidiChannel - 1) & 0x0F; + return 0; } + + const MODINSTRUMENT *ins = Chn[nChn].pModInstrument; + if(ins != nullptr) + { + if(ins->nMidiChannel == MidiMappedChannel) + { + // For mapped channels, return their pattern channel, modulo 16 (because there are only 16 MIDI channels) + return (Chn[nChn].nMasterChn ? (Chn[nChn].nMasterChn - 1) : nChn) % 16; + } else if(ins->HasValidMIDIChannel()) + { + return (ins->nMidiChannel - 1) & 0x0F; + } + } return 0; } Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2012-01-03 17:08:04 UTC (rev 1155) +++ trunk/OpenMPT/soundlib/Sndfile.h 2012-01-03 18:26:14 UTC (rev 1156) @@ -125,7 +125,7 @@ uint16 wMidiBank; // MIDI Bank (1...16384). 0 = Don't send. uint8 nMidiProgram; // MIDI Program (1...128). 0 = Don't send. - uint8 nMidiChannel; // MIDI Channel (1...16). 0 = Don't send. + uint8 nMidiChannel; // MIDI Channel (1...16). 0 = Don't send. 17 = Mapped (Send to tracker channel modulo 16). uint8 nMidiDrumKey; // Drum set note mapping (currently only used by the .MID loader) int8 nPPS; //Pitch/Pan separation (i.e. how wide the panning spreads) @@ -230,7 +230,7 @@ void SetCutoff(uint8 cutoff, bool enable) { nIFC = min(cutoff, 0x7F) | (enable ? 0x80 : 0x00); } void SetResonance(uint8 resonance, bool enable) { nIFR = min(resonance, 0x7F) | (enable ? 0x80 : 0x00); } - bool HasValidMIDIChannel() const { return (nMidiChannel >= 1 && nMidiChannel <= 16); } + bool HasValidMIDIChannel() const { return (nMidiChannel >= 1 && nMidiChannel <= 17); } }; @@ -1025,9 +1025,9 @@ protected: // Channel Effects void UpdateS3MEffectMemory(MODCHANNEL *pChn, UINT param) const; - void PortamentoUp(MODCHANNEL *pChn, UINT param, const bool fineAsRegular = false); - void PortamentoDown(MODCHANNEL *pChn, UINT param, const bool fineAsRegular = false); - void MidiPortamento(MODCHANNEL *pChn, int param); + void PortamentoUp(CHANNELINDEX nChn, UINT param, const bool fineAsRegular = false); + void PortamentoDown(CHANNELINDEX nChn, UINT param, const bool fineAsRegular = false); + void MidiPortamento(CHANNELINDEX nChn, int param); void FinePortamentoUp(MODCHANNEL *pChn, UINT param); void FinePortamentoDown(MODCHANNEL *pChn, UINT param); void ExtraFinePortamentoUp(MODCHANNEL *pChn, UINT param); @@ -1142,7 +1142,7 @@ DWORD CutOffToFrequency(UINT nCutOff, int flt_modifier=256) const; // [0-127] => [1-10KHz] #endif #ifdef MODPLUG_TRACKER - void ProcessMidiOut(CHANNELINDEX nChn, MODCHANNEL *pChn); //rewbs.VSTdelay : added arg. + void ProcessMidiOut(CHANNELINDEX nChn); #endif void ApplyGlobalVolume(int SoundBuffer[], int RearBuffer[], long lTotalSampleCount); @@ -1196,16 +1196,17 @@ int GetVolEnvValueFromPosition(int position, const MODINSTRUMENT* pIns) const; void ResetChannelEnvelopes(MODCHANNEL *pChn) const; void ResetChannelEnvelope(MODCHANNEL_ENVINFO &env) const; + private: PLUGINDEX __cdecl GetChannelPlugin(CHANNELINDEX nChn, PluginMutePriority respectMutes) const; PLUGINDEX __cdecl GetActiveInstrumentPlugin(CHANNELINDEX, PluginMutePriority respectMutes) const; - UINT GetBestMidiChan(const MODCHANNEL *pChn) const; void HandlePatternTransitionEvents(); long GetSampleOffset(); public: PLUGINDEX GetBestPlugin(CHANNELINDEX nChn, PluginPriority priority, PluginMutePriority respectMutes) const; + UINT GetBestMidiChannel(CHANNELINDEX nChn) const; // A couple of functions for handling backwards jumps and stuff to prevent infinite loops when counting the mod length or rendering to wav. public: Modified: trunk/OpenMPT/soundlib/Sndmix.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndmix.cpp 2012-01-03 17:08:04 UTC (rev 1155) +++ trunk/OpenMPT/soundlib/Sndmix.cpp 2012-01-03 18:26:14 UTC (rev 1156) @@ -2418,9 +2418,11 @@ #ifdef MODPLUG_TRACKER -void CSoundFile::ProcessMidiOut(CHANNELINDEX nChn, MODCHANNEL *pChn) //rewbs.VSTdelay: added arg -//------------------------------------------------------------------ +void CSoundFile::ProcessMidiOut(CHANNELINDEX nChn) +//------------------------------------------------ { + MODCHANNEL *pChn = &Chn[nChn]; + // Do we need to process midi? // For now there is no difference between mute and sync mute with VSTis. if (pChn->dwFlags & (CHN_MUTE|CHN_SYNCMUTE)) return; @@ -2462,10 +2464,10 @@ MODCOMMAND::NOTE realNote = note; if(NOTE_IS_VALID(note)) realNote = pIns->NoteMap[note - 1]; - pPlugin->MidiCommand(pIns->nMidiChannel, pIns->nMidiProgram, pIns->wMidiBank, realNote, pChn->nVolume, nChn); + pPlugin->MidiCommand(GetBestMidiChannel(nChn), pIns->nMidiProgram, pIns->wMidiBank, realNote, pChn->nVolume, nChn); } else if (volcmd == VOLCMD_VOLUME) { - pPlugin->MidiCC(pIns->nMidiChannel, MIDICC_Volume_Fine, vol, nChn); + pPlugin->MidiCC(GetBestMidiChannel(nChn), MIDICC_Volume_Fine, vol, nChn); } return; } @@ -2491,7 +2493,7 @@ realNote = pIns->NoteMap[note - 1]; // Experimental VST panning //ProcessMIDIMacro(nChn, false, m_MidiCfg.szMidiGlb[MIDIOUT_PAN], 0, nPlugin); - pPlugin->MidiCommand(pIns->nMidiChannel, pIns->nMidiProgram, pIns->wMidiBank, realNote, velocity, nChn); + pPlugin->MidiCommand(GetBestMidiChannel(nChn), pIns->nMidiProgram, pIns->wMidiBank, realNote, velocity, nChn); } @@ -2507,8 +2509,8 @@ break; case PLUGIN_VOLUMEHANDLING_MIDI: - if(hasVolCommand) pPlugin->MidiCC(pIns->nMidiChannel, MIDICC_Volume_Coarse, min(127, 2*vol), nChn); - else pPlugin->MidiCC(pIns->nMidiChannel, MIDICC_Volume_Coarse, min(127, 2*defaultVolume), nChn); + if(hasVolCommand) pPlugin->MidiCC(GetBestMidiChannel(nChn), MIDICC_Volume_Coarse, min(127, 2*vol), nChn); + else pPlugin->MidiCC(GetBestMidiChannel(nChn), MIDICC_Volume_Coarse, min(127, 2*defaultVolume), nChn); break; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2012-01-08 01:24:01
|
Revision: 1160 http://modplug.svn.sourceforge.net/modplug/?rev=1160&view=rev Author: saga-games Date: 2012-01-08 01:23:51 +0000 (Sun, 08 Jan 2012) Log Message: ----------- [Imp] Added channel and polyphonic aftertouch to MIDI Macro presets. [Mod] Fixed some shortcut names. [Mod] OpenMPT: Version is now 1.20.00.61 Modified Paths: -------------- trunk/OpenMPT/mptrack/CommandSet.cpp trunk/OpenMPT/mptrack/KeyConfigDlg.cpp trunk/OpenMPT/mptrack/MIDIMacroDialog.cpp trunk/OpenMPT/mptrack/View_smp.h trunk/OpenMPT/mptrack/version.h trunk/OpenMPT/soundlib/MIDIMacros.cpp trunk/OpenMPT/soundlib/MIDIMacros.h Modified: trunk/OpenMPT/mptrack/CommandSet.cpp =================================================================== --- trunk/OpenMPT/mptrack/CommandSet.cpp 2012-01-04 00:30:49 UTC (rev 1159) +++ trunk/OpenMPT/mptrack/CommandSet.cpp 2012-01-08 01:23:51 UTC (rev 1160) @@ -70,12 +70,12 @@ { //TODO: make this hideous list a bit nicer, with a constructor or somthing. //NOTE: isHidden implies automatically set, since the user will not be able to see it. - DefineKeyCommand(kcPatternRecord, 1001, _T("Enable recording")); - DefineKeyCommand(kcPatternPlayRow, 1002, _T("Play row")); - DefineKeyCommand(kcCursorCopy, 1003, _T("Quick copy")); - DefineKeyCommand(kcCursorPaste, 1004, _T("Quick paste")); - DefineKeyCommand(kcChannelMute, 1005, _T("Mute current channel")); - DefineKeyCommand(kcChannelSolo, 1006, _T("Solo current channel")); + DefineKeyCommand(kcPatternRecord, 1001, _T("Enable Recording")); + DefineKeyCommand(kcPatternPlayRow, 1002, _T("Play Row")); + DefineKeyCommand(kcCursorCopy, 1003, _T("Quick Copy")); + DefineKeyCommand(kcCursorPaste, 1004, _T("Quick Paste")); + DefineKeyCommand(kcChannelMute, 1005, _T("Mute current Channel")); + DefineKeyCommand(kcChannelSolo, 1006, _T("Solo current Channel")); DefineKeyCommand(kcTransposeUp, 1007, _T("Transpose +1")); DefineKeyCommand(kcTransposeDown, 1008, _T("Transpose -1")); DefineKeyCommand(kcTransposeOctUp, 1009, _T("Transpose +12")); @@ -83,9 +83,9 @@ DefineKeyCommand(kcSelectColumn, 1011, _T("Select channel / Select all")); DefineKeyCommand(kcPatternAmplify, 1012, _T("Amplify selection")); DefineKeyCommand(kcPatternSetInstrument, 1013, _T("Apply current instrument")); - DefineKeyCommand(kcPatternInterpolateVol, 1014, _T("Interpolate volume")); - DefineKeyCommand(kcPatternInterpolateEffect, 1015, _T("Interpolate effect")); - DefineKeyCommand(kcPatternVisualizeEffect, 1016, _T("Open effect visualizer")); + DefineKeyCommand(kcPatternInterpolateVol, 1014, _T("Interpolate Volume")); + DefineKeyCommand(kcPatternInterpolateEffect, 1015, _T("Interpolate Effect")); + DefineKeyCommand(kcPatternVisualizeEffect, 1016, _T("Open Effect Visualizer")); DefineKeyCommand(kcPatternJumpDownh1, 1017, _T("Jump down by measure")); DefineKeyCommand(kcPatternJumpUph1, 1018, _T("Jump up by measure")); DefineKeyCommand(kcPatternSnapDownh1, 1019, _T("Snap down to measure")); @@ -97,16 +97,16 @@ DefineKeyCommand(kcViewComments, 1025, _T("View Comments")); DefineKeyCommand(kcPlayPatternFromCursor, 1026, _T("Play pattern from cursor")); DefineKeyCommand(kcPlayPatternFromStart, 1027, _T("Play pattern from start")); - DefineKeyCommand(kcPlaySongFromCursor, 1028, _T("Play song from cursor")); - DefineKeyCommand(kcPlaySongFromStart, 1029, _T("Play song from start")); - DefineKeyCommand(kcPlayPauseSong, 1030, _T("Play song/Pause song")); - DefineKeyCommand(kcPauseSong, 1031, _T("Pause song")); - DefineKeyCommand(kcPrevInstrument, 1032, _T("Previous instrument")); - DefineKeyCommand(kcNextInstrument, 1033, _T("Next instrument")); - DefineKeyCommand(kcPrevOrder, 1034, _T("Previous order")); - DefineKeyCommand(kcNextOrder, 1035, _T("Next order")); - DefineKeyCommand(kcPrevOctave, 1036, _T("Previous octave")); - DefineKeyCommand(kcNextOctave, 1037, _T("Next octave")); + DefineKeyCommand(kcPlaySongFromCursor, 1028, _T("Play Song from Cursor")); + DefineKeyCommand(kcPlaySongFromStart, 1029, _T("Play Song from Start")); + DefineKeyCommand(kcPlayPauseSong, 1030, _T("Play Song / Pause song")); + DefineKeyCommand(kcPauseSong, 1031, _T("Pause Song")); + DefineKeyCommand(kcPrevInstrument, 1032, _T("Previous Instrument")); + DefineKeyCommand(kcNextInstrument, 1033, _T("Next Instrument")); + DefineKeyCommand(kcPrevOrder, 1034, _T("Previous Order")); + DefineKeyCommand(kcNextOrder, 1035, _T("Next Order")); + DefineKeyCommand(kcPrevOctave, 1036, _T("Previous Octave")); + DefineKeyCommand(kcNextOctave, 1037, _T("Next Octave")); DefineKeyCommand(kcNavigateDown, 1038, _T("Navigate down by 1 row")); DefineKeyCommand(kcNavigateUp, 1039, _T("Navigate up by 1 row")); DefineKeyCommand(kcNavigateLeft, 1040, _T("Navigate left")); @@ -131,8 +131,8 @@ DefineKeyCommand(kcClearRowStep, 1059, _T("Clear row and step")); DefineKeyCommand(kcClearFieldStep, 1060, _T("Clear field and step")); DefineKeyCommand(kcDeleteRows, 1061, _T("Delete rows")); - DefineKeyCommand(kcShowNoteProperties, 1062, _T("Show note properties")); - DefineKeyCommand(kcShowEditMenu, 1063, _T("Show context (right-click) menu")); + DefineKeyCommand(kcShowNoteProperties, 1062, _T("Show Note Properties")); + DefineKeyCommand(kcShowEditMenu, 1063, _T("Show Context (Right-Click) Menu")); DefineKeyCommand(kcVPNoteC_0, 1064, _T("Base octave C")); DefineKeyCommand(kcVPNoteCS0, 1065, _T("Base octave C#")); DefineKeyCommand(kcVPNoteD_0, 1066, _T("Base octave D")); @@ -301,37 +301,37 @@ DefineKeyCommand(kcSetVolume7, 1229, _T("Set volume digit 7")); DefineKeyCommand(kcSetVolume8, 1230, _T("Set volume digit 8")); DefineKeyCommand(kcSetVolume9, 1231, _T("Set volume digit 9")); - DefineKeyCommand(kcSetVolumeVol, 1232, _T("Vol command - volume")); - DefineKeyCommand(kcSetVolumePan, 1233, _T("Vol command - pan")); - DefineKeyCommand(kcSetVolumeVolSlideUp, 1234, _T("Vol command - vol slide up")); - DefineKeyCommand(kcSetVolumeVolSlideDown, 1235, _T("Vol command - vol slide down")); - DefineKeyCommand(kcSetVolumeFineVolUp, 1236, _T("Vol command - vol fine slide up")); - DefineKeyCommand(kcSetVolumeFineVolDown, 1237, _T("Vol command - vol fine slide down")); - DefineKeyCommand(kcSetVolumeVibratoSpd, 1238, _T("Vol command - vibrato speed")); - DefineKeyCommand(kcSetVolumeVibrato, 1239, _T("Vol command - vibrato")); - DefineKeyCommand(kcSetVolumeXMPanLeft, 1240, _T("Vol command - XM pan left")); - DefineKeyCommand(kcSetVolumeXMPanRight, 1241, _T("Vol command - XM pan right")); - DefineKeyCommand(kcSetVolumePortamento, 1242, _T("Vol command - Portamento")); - DefineKeyCommand(kcSetVolumeITPortaUp, 1243, _T("Vol command - Portamento Up")); - DefineKeyCommand(kcSetVolumeITPortaDown, 1244, _T("Vol command - Portamento Down")); - DefineKeyCommand(kcSetVolumeITUnused, 1245, _T("Vol command - Unused"), kcHidden, kcNoDummy); - DefineKeyCommand(kcSetVolumeITOffset, 1246, _T("Vol command - Offset")); - DefineKeyCommand(kcSetFXParam0, 1247, _T("FX Param digit 0")); - DefineKeyCommand(kcSetFXParam1, 1248, _T("FX Param digit 1")); - DefineKeyCommand(kcSetFXParam2, 1249, _T("FX Param digit 2")); - DefineKeyCommand(kcSetFXParam3, 1250, _T("FX Param digit 3")); - DefineKeyCommand(kcSetFXParam4, 1251, _T("FX Param digit 4")); - DefineKeyCommand(kcSetFXParam5, 1252, _T("FX Param digit 5")); - DefineKeyCommand(kcSetFXParam6, 1253, _T("FX Param digit 6")); - DefineKeyCommand(kcSetFXParam7, 1254, _T("FX Param digit 7")); - DefineKeyCommand(kcSetFXParam8, 1255, _T("FX Param digit 8")); - DefineKeyCommand(kcSetFXParam9, 1256, _T("FX Param digit 9")); - DefineKeyCommand(kcSetFXParamA, 1257, _T("FX Param digit A")); - DefineKeyCommand(kcSetFXParamB, 1258, _T("FX Param digit B")); - DefineKeyCommand(kcSetFXParamC, 1259, _T("FX Param digit C")); - DefineKeyCommand(kcSetFXParamD, 1260, _T("FX Param digit D")); - DefineKeyCommand(kcSetFXParamE, 1261, _T("FX Param digit E")); - DefineKeyCommand(kcSetFXParamF, 1262, _T("FX Param digit F")); + DefineKeyCommand(kcSetVolumeVol, 1232, _T("Volume Command - Volume")); + DefineKeyCommand(kcSetVolumePan, 1233, _T("Volume Command - Panning")); + DefineKeyCommand(kcSetVolumeVolSlideUp, 1234, _T("Volume Command - Volume Slide Up")); + DefineKeyCommand(kcSetVolumeVolSlideDown, 1235, _T("Volume Command - Volume Slide Down")); + DefineKeyCommand(kcSetVolumeFineVolUp, 1236, _T("Volume Command - Fine Volume Slide Up")); + DefineKeyCommand(kcSetVolumeFineVolDown, 1237, _T("Volume Command - Fine Volume Slide Down")); + DefineKeyCommand(kcSetVolumeVibratoSpd, 1238, _T("Volume Command - Vibrato Speed")); + DefineKeyCommand(kcSetVolumeVibrato, 1239, _T("Volume Command - Vibrato Depth")); + DefineKeyCommand(kcSetVolumeXMPanLeft, 1240, _T("Volume Command - XM Pan Slide Left")); + DefineKeyCommand(kcSetVolumeXMPanRight, 1241, _T("Volume Command - XM Pan Slide Right")); + DefineKeyCommand(kcSetVolumePortamento, 1242, _T("Volume Command - Portamento")); + DefineKeyCommand(kcSetVolumeITPortaUp, 1243, _T("Volume Command - Portamento Up")); + DefineKeyCommand(kcSetVolumeITPortaDown, 1244, _T("Volume Command - Portamento Down")); + DefineKeyCommand(kcSetVolumeITUnused, 1245, _T("Volume Command - Unused"), kcHidden, kcNoDummy); + DefineKeyCommand(kcSetVolumeITOffset, 1246, _T("Volume Command - Offset")); + DefineKeyCommand(kcSetFXParam0, 1247, _T("Effect Parameter Digit 0")); + DefineKeyCommand(kcSetFXParam1, 1248, _T("Effect Parameter Digit 1")); + DefineKeyCommand(kcSetFXParam2, 1249, _T("Effect Parameter Digit 2")); + DefineKeyCommand(kcSetFXParam3, 1250, _T("Effect Parameter Digit 3")); + DefineKeyCommand(kcSetFXParam4, 1251, _T("Effect Parameter Digit 4")); + DefineKeyCommand(kcSetFXParam5, 1252, _T("Effect Parameter Digit 5")); + DefineKeyCommand(kcSetFXParam6, 1253, _T("Effect Parameter Digit 6")); + DefineKeyCommand(kcSetFXParam7, 1254, _T("Effect Parameter Digit 7")); + DefineKeyCommand(kcSetFXParam8, 1255, _T("Effect Parameter Digit 8")); + DefineKeyCommand(kcSetFXParam9, 1256, _T("Effect Parameter Digit 9")); + DefineKeyCommand(kcSetFXParamA, 1257, _T("Effect Parameter Digit A")); + DefineKeyCommand(kcSetFXParamB, 1258, _T("Effect Parameter Digit B")); + DefineKeyCommand(kcSetFXParamC, 1259, _T("Effect Parameter Digit C")); + DefineKeyCommand(kcSetFXParamD, 1260, _T("Effect Parameter Digit D")); + DefineKeyCommand(kcSetFXParamE, 1261, _T("Effect Parameter Digit E")); + DefineKeyCommand(kcSetFXParamF, 1262, _T("Effect Parameter Digit F")); DefineKeyCommand(kcSetFXarp, 1263, _T("FX arpeggio"), kcHidden, kcNoDummy); DefineKeyCommand(kcSetFXportUp, 1264, _T("FX portamentao Up"), kcHidden, kcNoDummy); DefineKeyCommand(kcSetFXportDown, 1265, _T("FX portamentao Down"), kcHidden, kcNoDummy); @@ -362,9 +362,9 @@ DefineKeyCommand(kcSetFXextendedXM, 1290, _T("FX extended XM effects "), kcHidden, kcNoDummy); DefineKeyCommand(kcSetFXpanSlide, 1291, _T("FX pan slide"), kcHidden, kcNoDummy); DefineKeyCommand(kcSetFXsetEnvPos, 1292, _T("FX set envelope position (XM only)"), kcHidden, kcNoDummy); - DefineKeyCommand(kcSetFXmacro, 1293, _T("FX midi macro"), kcHidden, kcNoDummy); - DefineKeyCommand(kcSetFXmacroSlide, 1294, _T("FX midi macro slide")); - DefineKeyCommand(kcSetFXdelaycut, 1295, _T("FX combined note delay and note cut")); + DefineKeyCommand(kcSetFXmacro, 1293, _T("FX MIDI Macro"), kcHidden, kcNoDummy); + DefineKeyCommand(kcSetFXmacroSlide, 1294, _T("Smooth MIDI Macro Slide")); + DefineKeyCommand(kcSetFXdelaycut, 1295, _T("Combined Note Delay and Note Cut")); DefineKeyCommand(kcPatternJumpDownh1Select, 1296, _T("kcPatternJumpDownh1Select"), kcHidden, kcNoDummy); DefineKeyCommand(kcPatternJumpUph1Select, 1297, _T("kcPatternJumpUph1Select"), kcHidden, kcNoDummy); DefineKeyCommand(kcPatternSnapDownh1Select, 1298, _T("kcPatternSnapDownh1Select"), kcHidden, kcNoDummy); @@ -425,11 +425,8 @@ DefineKeyCommand(kcFileSaveAsWave, 1351, _T("File/Export as Wave")); DefineKeyCommand(kcFileSaveAsMP3, 1352, _T("File/Export as MP3")); DefineKeyCommand(kcFileSaveMidi, 1353, _T("File/Export as MIDI")); - DefineKeyCommand(kcFileImportMidiLib, 1354, _T("File/Import Midi Lib")); + DefineKeyCommand(kcFileImportMidiLib, 1354, _T("File/Import MIDI Library")); DefineKeyCommand(kcFileAddSoundBank, 1355, _T("File/Add Sound Bank")); - DefineKeyCommand(kcStopSong, 1356, _T("Stop Song")); - DefineKeyCommand(kcMidiRecord, 1357, _T("Toggle Midi Record")); - DefineKeyCommand(kcEstimateSongLength, 1358, _T("Estimate Song Length")); DefineKeyCommand(kcEditUndo, 1359, _T("Undo")); DefineKeyCommand(kcEditCut, 1360, _T("Cut")); DefineKeyCommand(kcEditCopy, 1361, _T("Copy")); @@ -450,14 +447,14 @@ */ DefineKeyCommand(kcEstimateSongLength, 1374, _T("Estimate Song Length")); DefineKeyCommand(kcStopSong, 1375, _T("Stop Song")); - DefineKeyCommand(kcMidiRecord, 1376, _T("Toggle Midi Record")); + DefineKeyCommand(kcMidiRecord, 1376, _T("Toggle MIDI Record")); DefineKeyCommand(kcDeleteAllRows, 1377, _T("Delete all rows")); DefineKeyCommand(kcInsertRow, 1378, _T("Insert Row")); DefineKeyCommand(kcInsertAllRows, 1379, _T("Insert All Rows")); DefineKeyCommand(kcSampleTrim, 1380, _T("Trim sample around loop points")); - DefineKeyCommand(kcSampleReverse, 1381, _T("Reverse sample")); - DefineKeyCommand(kcSampleDelete, 1382, _T("Delete sample selection")); - DefineKeyCommand(kcSampleSilence, 1383, _T("Silence sample selection")); + DefineKeyCommand(kcSampleReverse, 1381, _T("Reverse Sample")); + DefineKeyCommand(kcSampleDelete, 1382, _T("Delete Sample Selection")); + DefineKeyCommand(kcSampleSilence, 1383, _T("Silence Sample Selection")); DefineKeyCommand(kcSampleNormalize, 1384, _T("Normalise Sample")); DefineKeyCommand(kcSampleAmplify, 1385, _T("Amplify Sample")); DefineKeyCommand(kcSampleZoomUp, 1386, _T("Zoom Out")); @@ -474,30 +471,30 @@ DefineKeyCommand(kcToggleFollowSong, 1663, _T("Toggle follow song")); DefineKeyCommand(kcClearFieldITStyle, 1664, _T("Clear field (IT Style)")); DefineKeyCommand(kcClearFieldStepITStyle, 1665, _T("Clear field and step (IT Style)")); - DefineKeyCommand(kcSetFXextension, 1666, _T("FX parameter extension command")); + DefineKeyCommand(kcSetFXextension, 1666, _T("Parameter Extension Command")); DefineKeyCommand(kcNoteCutOld, 1667, _T("Note Cut (without instrument number)")); DefineKeyCommand(kcNoteOffOld, 1668, _T("Note Off (without instrument number)")); DefineKeyCommand(kcViewAddPlugin, 1669, _T("View Plugin Manager")); DefineKeyCommand(kcViewChannelManager, 1670, _T("View Channel Manager")); DefineKeyCommand(kcCopyAndLoseSelection, 1671, _T("Copy and lose selection")); DefineKeyCommand(kcNewPattern, 1672, _T("Insert new pattern")); - DefineKeyCommand(kcSampleLoad, 1673, _T("Load a Sample")); + DefineKeyCommand(kcSampleLoad, 1673, _T("Load Sample")); DefineKeyCommand(kcSampleSave, 1674, _T("Save Sample")); DefineKeyCommand(kcSampleNew, 1675, _T("New Sample")); - DefineKeyCommand(kcSampleCtrlLoad, 1676, _T("Load a Sample"), kcHidden, kcNoDummy); - DefineKeyCommand(kcSampleCtrlSave, 1677, _T("Save Sample"), kcHidden, kcNoDummy); - DefineKeyCommand(kcSampleCtrlNew, 1678, _T("New Sample"), kcHidden, kcNoDummy); - DefineKeyCommand(kcInstrumentLoad, 1679, _T("Load an instrument"), kcHidden, kcNoDummy); - DefineKeyCommand(kcInstrumentSave, 1680, _T("Save instrument"), kcHidden, kcNoDummy); - DefineKeyCommand(kcInstrumentNew, 1681, _T("New instrument"), kcHidden, kcNoDummy); - DefineKeyCommand(kcInstrumentCtrlLoad, 1682, _T("Load an instrument"), kcHidden, kcNoDummy); - DefineKeyCommand(kcInstrumentCtrlSave, 1683, _T("Save instrument"), kcHidden, kcNoDummy); - DefineKeyCommand(kcInstrumentCtrlNew, 1684, _T("New instrument"), kcHidden, kcNoDummy); - DefineKeyCommand(kcSwitchToOrderList, 1685, _T("Switch to order list")); + DefineKeyCommand(kcSampleCtrlLoad, 1676, _T("Load Sample"), kcHidden); + DefineKeyCommand(kcSampleCtrlSave, 1677, _T("Save Sample"), kcHidden); + DefineKeyCommand(kcSampleCtrlNew, 1678, _T("New Sample"), kcHidden); + DefineKeyCommand(kcInstrumentLoad, 1679, _T("Load an instrument"), kcHidden); + DefineKeyCommand(kcInstrumentSave, 1680, _T("Save instrument"), kcHidden); + DefineKeyCommand(kcInstrumentNew, 1681, _T("New instrument"), kcHidden); + DefineKeyCommand(kcInstrumentCtrlLoad, 1682, _T("Load an instrument"), kcHidden); + DefineKeyCommand(kcInstrumentCtrlSave, 1683, _T("Save instrument"), kcHidden); + DefineKeyCommand(kcInstrumentCtrlNew, 1684, _T("New instrument"), kcHidden); + DefineKeyCommand(kcSwitchToOrderList, 1685, _T("Switch to Order List")); DefineKeyCommand(kcEditMixPasteITStyle, 1686, _T("Mix Paste (old IT Style)")); DefineKeyCommand(kcApproxRealBPM, 1687, _T("Show approx. real BPM")); - DefineKeyCommand(kcNavigateDownBySpacingSelect, 1689, _T("kcNavigateDownBySpacingSelect"), kcHidden, kcNoDummy); - DefineKeyCommand(kcNavigateUpBySpacingSelect, 1690, _T("kcNavigateUpBySpacingSelect"), kcHidden, kcNoDummy); + DefineKeyCommand(kcNavigateDownBySpacingSelect, 1689, _T("kcNavigateDownBySpacingSelect"), kcHidden); + DefineKeyCommand(kcNavigateUpBySpacingSelect, 1690, _T("kcNavigateUpBySpacingSelect"), kcHidden); DefineKeyCommand(kcNavigateDownBySpacing, 1691, _T("Navigate down by spacing")); DefineKeyCommand(kcNavigateUpBySpacing, 1692, _T("Navigate up by spacing")); DefineKeyCommand(kcPrevDocument, 1693, _T("Previous Document")); @@ -508,31 +505,31 @@ DefineKeyCommand((CommandID)j, 1695 + j - kcVSTGUIStartNotes, _T("Auto Note in some context"), kcHidden, kcNoDummy); } //end hack - DefineKeyCommand(kcVSTGUIPrevPreset, 1763, _T("Previous plugin preset")); - DefineKeyCommand(kcVSTGUINextPreset, 1764, _T("Next plugin preset")); - DefineKeyCommand(kcVSTGUIRandParams, 1765, _T("Randomize plugin parameters")); + DefineKeyCommand(kcVSTGUIPrevPreset, 1763, _T("Previous Plugin Preset")); + DefineKeyCommand(kcVSTGUINextPreset, 1764, _T("Next Plugin Preset")); + DefineKeyCommand(kcVSTGUIRandParams, 1765, _T("Randomize Plugin Parameters")); DefineKeyCommand(kcPatternGoto, 1766, _T("Go to row/channel/...")); - DefineKeyCommand(kcPatternOpenRandomizer, 1767, _T("Go to row/channel/..."), kcHidden, kcNoDummy); // while there's not randomizer yet, let's just disable it for now - DefineKeyCommand(kcPatternInterpolateNote, 1768, _T("Interpolate note")); + DefineKeyCommand(kcPatternOpenRandomizer, 1767, _T("Pattern Randomizer"), kcHidden, kcNoDummy); // while there's not randomizer yet, let's just disable it for now + DefineKeyCommand(kcPatternInterpolateNote, 1768, _T("Interpolate Note")); //rewbs.graph DefineKeyCommand(kcViewGraph, 1769, _T("View Graph"), kcHidden, kcNoDummy); // while there's no graph yet, let's just disable it for now //end rewbs.graph DefineKeyCommand(kcToggleChanMuteOnPatTransition, 1770, _T("(Un)mute chan on pat transition")); DefineKeyCommand(kcChannelUnmuteAll, 1771, _T("Unmute all channels")); - DefineKeyCommand(kcShowPatternProperties, 1772, _T("Show pattern properties window")); - DefineKeyCommand(kcShowMacroConfig, 1773, _T("Show macro configuration")); - DefineKeyCommand(kcViewSongProperties, 1775, _T("Show song properties window")); - DefineKeyCommand(kcChangeLoopStatus, 1776, _T("Toggle loop pattern")); - DefineKeyCommand(kcFileExportCompat, 1777, _T("File/Export to standard IT/XM/S3M")); + DefineKeyCommand(kcShowPatternProperties, 1772, _T("Show Pattern Properties")); + DefineKeyCommand(kcShowMacroConfig, 1773, _T("Show MIDI Macro Configuration")); + DefineKeyCommand(kcViewSongProperties, 1775, _T("Show Song Properties")); + DefineKeyCommand(kcChangeLoopStatus, 1776, _T("Toggle Loop Pattern")); + DefineKeyCommand(kcFileExportCompat, 1777, _T("File/Compatibility Export")); DefineKeyCommand(kcUnmuteAllChnOnPatTransition, 1778, _T("Unmute all channels on pattern transition")); DefineKeyCommand(kcSoloChnOnPatTransition, 1779, _T("Solo channel on pattern transition")); DefineKeyCommand(kcTimeAtRow, 1780, _T("Show playback time at current row")); - DefineKeyCommand(kcViewMIDImapping, 1781, _T("View MIDI mapping")); + DefineKeyCommand(kcViewMIDImapping, 1781, _T("View MIDI Mapping")); DefineKeyCommand(kcVSTGUIPrevPresetJump, 1782, _T("Plugin preset backward jump")); DefineKeyCommand(kcVSTGUINextPresetJump, 1783, _T("Plugin preset forward jump")); - DefineKeyCommand(kcSampleInvert, 1784, _T("Invert sample phase")); - DefineKeyCommand(kcSampleSignUnsign, 1785, _T("Signed/Unsigned conversion")); - DefineKeyCommand(kcChannelReset, 1786, _T("Reset channel")); + DefineKeyCommand(kcSampleInvert, 1784, _T("Invert Sample Phase")); + DefineKeyCommand(kcSampleSignUnsign, 1785, _T("Signed / Unsigned Conversion")); + DefineKeyCommand(kcChannelReset, 1786, _T("Reset Channel")); DefineKeyCommand(kcSwitchOverflowPaste, 1787, _T("Toggle overflow paste")); DefineKeyCommand(kcNotePC, 1788, _T("Parameter control(MPTm only)")); DefineKeyCommand(kcNotePCS, 1789, _T("Parameter control(smooth)(MPTm only)")); @@ -573,43 +570,43 @@ DefineKeyCommand(kcInstrumentEnvelopePointMoveDown, 1824, _T("Move envelope point down")); DefineKeyCommand(kcInstrumentEnvelopePointPrev, 1825, _T("Select previous envelope point")); DefineKeyCommand(kcInstrumentEnvelopePointNext, 1826, _T("Select next envelope point")); - DefineKeyCommand(kcInstrumentEnvelopePointInsert, 1827, _T("Insert envelope point")); - DefineKeyCommand(kcInstrumentEnvelopePointRemove, 1828, _T("Remove envelope point")); - DefineKeyCommand(kcInstrumentEnvelopeSetLoopStart, 1829, _T("Set loop start")); - DefineKeyCommand(kcInstrumentEnvelopeSetLoopEnd, 1830, _T("Set loop end")); + DefineKeyCommand(kcInstrumentEnvelopePointInsert, 1827, _T("Insert Envelope Point")); + DefineKeyCommand(kcInstrumentEnvelopePointRemove, 1828, _T("Remove Envelope Point")); + DefineKeyCommand(kcInstrumentEnvelopeSetLoopStart, 1829, _T("Set Loop Start")); + DefineKeyCommand(kcInstrumentEnvelopeSetLoopEnd, 1830, _T("Set Loop End")); DefineKeyCommand(kcInstrumentEnvelopeSetSustainLoopStart, 1831, _T("Set sustain loop start")); DefineKeyCommand(kcInstrumentEnvelopeSetSustainLoopEnd, 1832, _T("Set sustain loop end")); DefineKeyCommand(kcInstrumentEnvelopeToggleReleaseNode, 1833, _T("Toggle release node")); - DefineKeyCommand(kcInstrumentEnvelopePointMoveUp8, 1834, _T("Move envelope point up (big step)")); - DefineKeyCommand(kcInstrumentEnvelopePointMoveDown8, 1835, _T("Move envelope point down (big step)")); - DefineKeyCommand(kcPatternEditPCNotePlugin, 1836, _T("Edit plugin assigned to PC note")); + DefineKeyCommand(kcInstrumentEnvelopePointMoveUp8, 1834, _T("Move envelope point up (Coarse)")); + DefineKeyCommand(kcInstrumentEnvelopePointMoveDown8, 1835, _T("Move envelope point down (Coarse)")); + DefineKeyCommand(kcPatternEditPCNotePlugin, 1836, _T("Edit Plugin assigned to PC Event")); DefineKeyCommand(kcInstrumentEnvelopeZoomIn, 1837, _T("Zoom In")); DefineKeyCommand(kcInstrumentEnvelopeZoomOut, 1838, _T("Zoom Out")); DefineKeyCommand(kcVSTGUIToggleRecordParams, 1839, _T("Toggle parameter recording")); DefineKeyCommand(kcVSTGUIToggleSendKeysToPlug, 1840, _T("Pass key presses to plugin")); DefineKeyCommand(kcVSTGUIBypassPlug, 1841, _T("Bypass plugin")); - DefineKeyCommand(kcInsNoteMapTransposeDown, 1842, _T("Transpose -1 (note map)")); - DefineKeyCommand(kcInsNoteMapTransposeUp, 1843, _T("Transpose +1 (note map)")); - DefineKeyCommand(kcInsNoteMapTransposeOctDown, 1844, _T("Transpose -12 (note map)")); - DefineKeyCommand(kcInsNoteMapTransposeOctUp, 1845, _T("Transpose +12 (note map)")); + DefineKeyCommand(kcInsNoteMapTransposeDown, 1842, _T("Transpose -1 (Note Map)")); + DefineKeyCommand(kcInsNoteMapTransposeUp, 1843, _T("Transpose +1 (Note Map)")); + DefineKeyCommand(kcInsNoteMapTransposeOctDown, 1844, _T("Transpose -12 (Note Map)")); + DefineKeyCommand(kcInsNoteMapTransposeOctUp, 1845, _T("Transpose +12 (Note Map)")); DefineKeyCommand(kcInsNoteMapCopyCurrentNote, 1846, _T("Map all notes to selected note")); DefineKeyCommand(kcInsNoteMapCopyCurrentSample, 1847, _T("Map all notes to selected sample")); - DefineKeyCommand(kcInsNoteMapReset, 1848, _T("Reset note mapping")); - DefineKeyCommand(kcInsNoteMapEditSample, 1849, _T("Edit current sample")); - DefineKeyCommand(kcInsNoteMapEditSampleMap, 1850, _T("Edit sample map")); - DefineKeyCommand(kcInstrumentCtrlDuplicate, 1851, _T("Duplicate instrument")); + DefineKeyCommand(kcInsNoteMapReset, 1848, _T("Reset Note nMapping")); + DefineKeyCommand(kcInsNoteMapEditSample, 1849, _T("Edit Current Sample")); + DefineKeyCommand(kcInsNoteMapEditSampleMap, 1850, _T("Edit Sample Map")); + DefineKeyCommand(kcInstrumentCtrlDuplicate, 1851, _T("Duplicate Instrument")); DefineKeyCommand(kcPanic, 1852, _T("Panic")); DefineKeyCommand(kcOrderlistPatIgnore, 1853, _T("Separator (+++) Index")); DefineKeyCommand(kcOrderlistPatInvalid, 1854, _T("Stop (---) Index")); DefineKeyCommand(kcViewEditHistory, 1855, _T("View Edit History")); - DefineKeyCommand(kcSampleQuickFade, 1856, _T("Quick fade")); - DefineKeyCommand(kcSampleXFade, 1857, _T("Crossfade sample loop")); - DefineKeyCommand(kcSelectBeat, 1858, _T("Select beat")); - DefineKeyCommand(kcSelectMeasure, 1859, _T("Select measure")); + DefineKeyCommand(kcSampleQuickFade, 1856, _T("Quick Fade")); + DefineKeyCommand(kcSampleXFade, 1857, _T("Crossfade Sample Loop")); + DefineKeyCommand(kcSelectBeat, 1858, _T("Select Beat")); + DefineKeyCommand(kcSelectMeasure, 1859, _T("Select Measure")); DefineKeyCommand(kcFileSaveTemplate, 1860, _T("File/Save As Template")); - DefineKeyCommand(kcIncreaseSpacing, 1861, _T("Increase row spacing")); - DefineKeyCommand(kcDecreaseSpacing, 1862, _T("Decrease row spacing")); - DefineKeyCommand(kcSampleAutotune, 1863, _T("Autotune sample to C")); + DefineKeyCommand(kcIncreaseSpacing, 1861, _T("Increase Row Spacing")); + DefineKeyCommand(kcDecreaseSpacing, 1862, _T("Decrease Row Spacing")); + DefineKeyCommand(kcSampleAutotune, 1863, _T("Tune Sample to given Note")); // Add new key commands here. #ifdef _DEBUG Modified: trunk/OpenMPT/mptrack/KeyConfigDlg.cpp =================================================================== --- trunk/OpenMPT/mptrack/KeyConfigDlg.cpp 2012-01-04 00:30:49 UTC (rev 1159) +++ trunk/OpenMPT/mptrack/KeyConfigDlg.cpp 2012-01-08 01:23:51 UTC (rev 1160) @@ -203,7 +203,7 @@ commandCategories.Add(*newCat); delete newCat; - newCat = new CommandCategory(" Pattern Editor - Orderlist", kCtxCtrlOrderlist); + newCat = new CommandCategory(" Pattern Editor - Order List", kCtxCtrlOrderlist); for (int c=kcStartOrderlistCommands; c<=kcEndOrderlistCommands; c++) newCat->commands.Add(c); @@ -250,7 +250,7 @@ commandCategories.Add(*newCat); delete newCat; - newCat = new CommandCategory(" Pattern Editor - Note col", kCtxViewPatternsNote); + newCat = new CommandCategory(" Pattern Editor - Note Column", kCtxViewPatternsNote); for (int c=kcVPStartNotes; c<=kcVPEndNotes; c++) newCat->commands.Add(c); newCat->separators.Add(kcVPEndNotes); //-------------------------------------- @@ -262,25 +262,25 @@ commandCategories.Add(*newCat); delete newCat; - newCat = new CommandCategory(" Pattern Editor - Volume col", kCtxViewPatternsVol); - for (int c=kcSetVolumeStart; c<=kcSetVolumeEnd; c++) + newCat = new CommandCategory(" Pattern Editor - Instrument Column", kCtxViewPatternsIns); + for (int c=kcSetIns0; c<=kcSetIns9; c++) newCat->commands.Add(c); commandCategories.Add(*newCat); delete newCat; - newCat = new CommandCategory(" Pattern Editor - Instrument col", kCtxViewPatternsIns); - for (int c=kcSetIns0; c<=kcSetIns9; c++) + newCat = new CommandCategory(" Pattern Editor - Volume Column", kCtxViewPatternsVol); + for (int c=kcSetVolumeStart; c<=kcSetVolumeEnd; c++) newCat->commands.Add(c); commandCategories.Add(*newCat); delete newCat; - newCat = new CommandCategory(" Pattern Editor - FX col", kCtxViewPatternsFX); + newCat = new CommandCategory(" Pattern Editor - Effect Column", kCtxViewPatternsFX); for (int c=kcSetFXStart; c<=kcSetFXEnd; c++) newCat->commands.Add(c); commandCategories.Add(*newCat); delete newCat; - newCat = new CommandCategory(" Pattern Editor - FX param col", kCtxViewPatternsFXparam); + newCat = new CommandCategory(" Pattern Editor - Effect Parameter Column", kCtxViewPatternsFXparam); for (int c=kcSetFXParam0; c<=kcSetFXParamF; c++) newCat->commands.Add(c); commandCategories.Add(*newCat); Modified: trunk/OpenMPT/mptrack/MIDIMacroDialog.cpp =================================================================== --- trunk/OpenMPT/mptrack/MIDIMacroDialog.cpp 2012-01-04 00:30:49 UTC (rev 1159) +++ trunk/OpenMPT/mptrack/MIDIMacroDialog.cpp 2012-01-08 01:23:51 UTC (rev 1160) @@ -13,7 +13,6 @@ #include "mptrack.h" #include "Vstplug.h" #include "resource.h" -#include "MIDIMacros.h" #include "MIDIMacroDialog.h" @@ -63,11 +62,14 @@ m_EditSFx.SetLimitText(MACRO_LENGTH - 1); m_EditZxx.SetLimitText(MACRO_LENGTH - 1); + // Parametered macro selection for (UINT isfx=0; isfx<16; isfx++) { wsprintf(s, "%d (SF%X)", isfx, isfx); m_CbnSFx.AddString(s); } + + // Parametered macro presets m_CbnSFx.SetCurSel(0); for(int i = 0; i < sfx_max; i++) { @@ -75,38 +77,41 @@ } OnSFxChanged(); + // MIDI CC selection box for (int cc = MIDICC_start; cc <= MIDICC_end; cc++) { wsprintf(s, "CC %02d %s", cc, MidiCCNames[cc]); m_CbnMacroCC.SetItemData(m_CbnMacroCC.AddString(s), cc); } + // Z80...ZFF box for (int zxx = 0; zxx < 128; zxx++) { wsprintf(s, "Z%02X", zxx | 0x80); m_CbnZxx.AddString(s); } + + // Fixed macro presets m_CbnZxx.SetCurSel(0); - m_CbnZxxPreset.AddString("Custom"); - m_CbnZxxPreset.AddString("Z80-Z8F controls resonance"); - m_CbnZxxPreset.AddString("Z80-ZFF controls resonance"); - m_CbnZxxPreset.AddString("Z80-ZFF controls cutoff"); - m_CbnZxxPreset.AddString("Z80-ZFF controls filter mode"); - m_CbnZxxPreset.AddString("Z80-Z9F controls resonance+mode"); + for(int i = 0; i < zxx_max; i++) + { + m_CbnZxxPreset.SetItemData(m_CbnZxxPreset.AddString(macroTools.GetZxxName(static_cast<enmFixedMacroType>(i))), i); + } m_CbnZxxPreset.SetCurSel(macroTools.GetZxxType(m_MidiCfg.szMidiZXXExt)); + UpdateDialog(); int offsetx=108, offsety=30, separatorx=4, separatory=2, height=18, widthMacro=30, widthVal=90, widthType=135, widthBtn=70; - for (UINT m = 0; m < NUM_MACROS; m++) + for(UINT m = 0; m < NUM_MACROS; m++) { m_EditMacro[m].Create("", /*BS_FLAT |*/ WS_CHILD | WS_VISIBLE | WS_TABSTOP /*| WS_BORDER*/, CRect(offsetx, offsety + m * (separatory + height), offsetx + widthMacro, offsety + m * (separatory + height) + height), this, ID_PLUGSELECT + NUM_MACROS + m); m_EditMacro[m].SetFont(GetFont()); m_EditMacroType[m].Create(ES_READONLY | WS_CHILD| WS_VISIBLE | WS_TABSTOP | WS_BORDER, - CRect(offsetx + separatorx + widthMacro, offsety + m* (separatory + height), offsetx + widthMacro + widthType, offsety + m * (separatory + height) + height), this, ID_PLUGSELECT + NUM_MACROS + m); + CRect(offsetx + separatorx + widthMacro, offsety + m * (separatory + height), offsetx + widthMacro + widthType, offsety + m * (separatory + height) + height), this, ID_PLUGSELECT + NUM_MACROS + m); m_EditMacroType[m].SetFont(GetFont()); m_EditMacroValue[m].Create(ES_CENTER | ES_READONLY | WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER, @@ -114,18 +119,18 @@ m_EditMacroValue[m].SetFont(GetFont()); m_BtnMacroShowAll[m].Create("Show All...", WS_CHILD | WS_TABSTOP | WS_VISIBLE, - CRect(offsetx + separatorx + widthType + widthMacro + widthVal, offsety + m *(separatory + height), offsetx + widthMacro + widthType + widthVal + widthBtn, offsety + m * (separatory + height) + height), this, ID_PLUGSELECT + m); + CRect(offsetx + separatorx + widthType + widthMacro + widthVal, offsety + m * (separatory + height), offsetx + widthMacro + widthType + widthVal + widthBtn, offsety + m * (separatory + height) + height), this, ID_PLUGSELECT + m); m_BtnMacroShowAll[m].SetFont(GetFont()); } UpdateMacroList(); - for (UINT plug=0; plug<MAX_MIXPLUGINS; plug++) + for(PLUGINDEX plug = 0; plug < MAX_MIXPLUGINS; plug++) { PSNDMIXPLUGIN p = &(m_SndFile.m_MixPlugins[plug]); StringFixer::SetNullTerminator(p->Info.szLibraryName); if (p->Info.szLibraryName[0]) { - wsprintf(s, "FX%d: %s", plug+1, p->Info.szName); + wsprintf(s, "FX%d: %s", plug + 1, p->Info.szName); m_CbnMacroPlug.SetItemData(m_CbnMacroPlug.AddString(s), plug); } } @@ -300,7 +305,7 @@ void CMidiMacroSetup::OnZxxPresetChanged() //---------------------------------------- { - enmFixedMacroType zxx_preset = static_cast<enmFixedMacroType>(m_CbnZxxPreset.GetCurSel()); + enmFixedMacroType zxx_preset = static_cast<enmFixedMacroType>(m_CbnZxxPreset.GetItemData(m_CbnZxxPreset.GetCurSel())); if (zxx_preset != zxx_custom) { Modified: trunk/OpenMPT/mptrack/View_smp.h =================================================================== --- trunk/OpenMPT/mptrack/View_smp.h 2012-01-04 00:30:49 UTC (rev 1159) +++ trunk/OpenMPT/mptrack/View_smp.h 2012-01-08 01:23:51 UTC (rev 1160) @@ -37,7 +37,7 @@ BOOL SetZoom(UINT nZoom); LONG SampleToScreen(LONG n) const; DWORD ScreenToSample(LONG x) const; - void PlayNote(UINT note, const uint32 nStartPos = uint32_max); //rewbs.customKeys + void PlayNote(UINT note, const uint32 nStartPos = 0); //rewbs.customKeys void InvalidateSample(); void SetCurSel(DWORD nBegin, DWORD nEnd); void ScrollToPosition(int x); Modified: trunk/OpenMPT/mptrack/version.h =================================================================== --- trunk/OpenMPT/mptrack/version.h 2012-01-04 00:30:49 UTC (rev 1159) +++ trunk/OpenMPT/mptrack/version.h 2012-01-08 01:23:51 UTC (rev 1160) @@ -15,7 +15,7 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 20 #define VER_MINOR 00 -#define VER_MINORMINOR 60 +#define VER_MINORMINOR 61 //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/MIDIMacros.cpp =================================================================== --- trunk/OpenMPT/soundlib/MIDIMacros.cpp 2012-01-04 00:30:49 UTC (rev 1159) +++ trunk/OpenMPT/soundlib/MIDIMacros.cpp 2012-01-08 01:23:51 UTC (rev 1160) @@ -105,6 +105,10 @@ return _T("Control Plugin Parameter..."); case sfx_cc: return _T("MIDI CC..."); + case sfx_channelAT: + return _T("Channel Aftertouch"); + case sfx_polyAT: + return _T("Polyphonic Aftertouch"); case sfx_custom: default: return _T("Custom"); @@ -112,6 +116,33 @@ } +// Returns generic macro description. +CString MIDIMacroTools::GetZxxName(enmFixedMacroType macro) +//--------------------------------------------------------- +{ + switch(macro) + { + case zxx_reso4Bit: + return _T("Z80 - Z8F controls resonant filter resonance"); + case zxx_reso7Bit: + return _T("Z80 - ZFF controls resonant filter resonance"); + case zxx_cutoff: + return _T("Z80 - ZFF controls resonant filter cutoff"); + case zxx_mode: + return _T("Z80 - ZFF controls resonant filter mode"); + case zxx_resomode: + return _T("Z80 - Z9F controls resonance + filter mode"); + case zxx_channelAT: + return _T("Z80 - ZFF controls Channel Aftertouch"); + case zxx_polyAT: + return _T("Z80 - ZFF controls Poly Aftertouch"); + case zxx_custom: + default: + return _T("Custom"); + } +} + + int MIDIMacroTools::MacroToPlugParam(CString macro) //------------------------------------------------- { @@ -224,6 +255,16 @@ else if (i < 32) wsprintf(szMidiZXXExt[i], "F0F002%02X", (i - 16) * 8); else strcpy(szMidiZXXExt[i], ""); break; + + case zxx_channelAT: + // Type 6 - Z80 - ZFF controls Channel Aftertouch + wsprintf(szMidiZXXExt[i], "Dc%02X", i); + break; + + case zxx_polyAT: + // Type 7 - Z80 - ZFF controls Poly Aftertouch + wsprintf(szMidiZXXExt[i], "Acn%02X", i); + break; } } } @@ -257,6 +298,12 @@ case sfx_plug: result.Format("F0F%03Xz", subType + 0x80); break; + case sfx_channelAT: + result.Format("Dcz"); + break; + case sfx_polyAT: + result.Format("Acnz"); + break; } return result; } Modified: trunk/OpenMPT/soundlib/MIDIMacros.h =================================================================== --- trunk/OpenMPT/soundlib/MIDIMacros.h 2012-01-04 00:30:49 UTC (rev 1159) +++ trunk/OpenMPT/soundlib/MIDIMacros.h 2012-01-08 01:23:51 UTC (rev 1160) @@ -20,6 +20,8 @@ sfx_drywet, // Type 4 - Z00 - Z7F controls plugin Dry / Wet ratio sfx_plug, // Type 5 - Z00 - Z7F controls a plugin parameter sfx_cc, // Type 6 - Z00 - Z7F controls MIDI CC + sfx_channelAT, // Type 7 - Z00 - Z7F controls Channel Aftertouch + sfx_polyAT, // Type 8 - Z00 - Z7F controls Poly Aftertouch sfx_custom, sfx_max @@ -35,6 +37,8 @@ zxx_cutoff, // Type 3 - Z80 - ZFF controls resonant filter cutoff zxx_mode, // Type 4 - Z80 - ZFF controls resonant filter mode (lowpass / highpass) zxx_resomode, // Type 5 - Z80 - Z9F controls resonance + filter mode + zxx_channelAT, // Type 6 - Z80 - ZFF controls Channel Aftertouch + zxx_polyAT, // Type 7 - Z80 - ZFF controls Poly Aftertouch zxx_max }; @@ -53,6 +57,7 @@ // Translate macro type or macro string to macro name static CString GetMacroName(enmParameteredMacroType macro); CString GetMacroName(CString value, PLUGINDEX plugin) const; + static CString GetZxxName(enmFixedMacroType macro); // Extract information from a macro string. static int MacroToPlugParam(CString value); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2012-01-08 22:04:40
|
Revision: 1162 http://modplug.svn.sourceforge.net/modplug/?rev=1162&view=rev Author: saga-games Date: 2012-01-08 22:04:33 +0000 (Sun, 08 Jan 2012) Log Message: ----------- [Ref] Refactored some plugin mixing code [Mod] Minor other changes Modified Paths: -------------- trunk/OpenMPT/mptrack/Vstplug.cpp trunk/OpenMPT/mptrack/Vstplug.h trunk/OpenMPT/soundlib/MIDIMacros.cpp trunk/OpenMPT/soundlib/PluginMixBuffer.h trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/Sndfile.h Modified: trunk/OpenMPT/mptrack/Vstplug.cpp =================================================================== --- trunk/OpenMPT/mptrack/Vstplug.cpp 2012-01-08 21:28:20 UTC (rev 1161) +++ trunk/OpenMPT/mptrack/Vstplug.cpp 2012-01-08 22:04:33 UTC (rev 1162) @@ -2060,37 +2060,18 @@ } -void CVstPlugin::Process(float *pOutL, float *pOutR, unsigned long nSamples) -//-------------------------------------------------------------------------- +void CVstPlugin::Process(float *pOutL, float *pOutR, size_t nSamples) +//------------------------------------------------------------------- { - float wetRatio, dryRatio; // rewbs.dryRatio [20040123] - ProcessVSTEvents(); -// -> DESC="effect plugin mixing mode combo" -// -> mixop == 0 : normal processing -// -> mixop == 1 : MIX += DRY - WET * wetRatio -// -> mixop == 2 : MIX += WET - DRY * dryRatio -// -> mixop == 3 : MIX -= WET - DRY * wetRatio -// -> mixop == 4 : MIX -= middle - WET * wetRatio + middle - DRY -// -> mixop == 5 : MIX_L += wetRatio * (WET_L - DRY_L) + dryRatio * (DRY_R - WET_R) -// MIX_R += dryRatio * (WET_L - DRY_L) + wetRatio * (DRY_R - WET_R) - //If the plug is found & ok, continue if ((m_pEffect) && (m_pProcessFP) && (mixBuffer.GetInputBufferArray()) && (mixBuffer.GetOutputBufferArray()) && (m_pMixStruct)) { - int mixop; - if (m_bIsInstrument) - { - mixop = 0; //force normal mix mode for instruments - } else - { - mixop = m_pMixStruct ? (m_pMixStruct->Info.dwInputRouting>>8) & 0xff : 0; - } //RecalculateGain(); - //Merge stereo input before sending to the plug if the plug can only handle one input. + // Merge stereo input before sending to the plug if the plug can only handle one input. if (m_pEffect->numInputs == 1) { for (size_t i = 0; i < nSamples; i++) @@ -2103,7 +2084,7 @@ mixBuffer.ClearOutputBuffers(nSamples); m_dwTimeAtStartOfProcess = timeGetTime(); - //Do the VST processing magic + // Do the VST processing magic try { ASSERT(nSamples <= MIXBUFFERSIZE); @@ -2119,8 +2100,8 @@ ASSERT(outputBuffers != nullptr); - //mix outputs of multi-output VSTs: - if(m_nOutputs>2) + // Mix outputs of multi-output VSTs: + if(m_nOutputs > 2) { // first, mix extra outputs on a stereo basis UINT nOuts = m_nOutputs; @@ -2130,15 +2111,17 @@ // mix extra stereo outputs for(UINT iOut = 2; iOut < nOuts; iOut++) { - for(UINT i = 0; i < nSamples; i++) - outputBuffers[iOut % 2][i] += outputBuffers[iOut][i]; //assumed stereo. + for(size_t i = 0; i < nSamples; i++) + { + outputBuffers[iOut % 2][i] += outputBuffers[iOut][i]; // assumed stereo. + } } // if m_nOutputs is odd, mix half the signal of last output to each channel if(nOuts != m_nOutputs) { // trick : if we are here, nOuts = m_nOutputs - 1 !!! - for(UINT i=0; i<nSamples; i++) + for(size_t i = 0; i < nSamples; i++) { float v = 0.5f * outputBuffers[nOuts][i]; outputBuffers[0][i] += v; @@ -2147,237 +2130,141 @@ } } - // If there was just the one plugin output we copy it into our 2 outputs - if(m_pEffect->numOutputs == 1) - { - wetRatio = 1 - m_pMixStruct->fDryRatio; //rewbs.dryRatio - dryRatio = m_bIsInstrument ? 1 : m_pMixStruct->fDryRatio; //always mix full dry if this is an instrument + ProcessMixOps(pOutL, pOutR, nSamples); -// -> CODE#0028 -// -> DESC="effect plugin mixing mode combo" -/* - for (UINT i=0; i<nSamples; i++) + // If dry mix is ticked, we add the unprocessed buffer, + // except if this is an instrument since this it has already been done: + if((m_pMixStruct->Info.dwInputRouting & MIXPLUG_INPUTF_WETMIX) && !m_bIsInstrument) + { + for(size_t i = 0; i < nSamples; i++) { - //rewbs.wetratio - added the factors. [20040123] - pOutL[i] += outputBuffers[0][i]*wetRatio + m_MixState.pOutBufferL[i]*dryRatio; - pOutR[i] += outputBuffers[0][i]*wetRatio + m_MixState.pOutBufferR[i]*dryRatio; - - //If dry mix is ticked we add the unprocessed buffer, - //except if this is an instrument since this it already been done: - if ((m_pMixStruct->Info.dwInputRouting & MIXPLUG_INPUTF_WETMIX) && !isInstrument) - { - pOutL[i] += m_MixState.pOutBufferL[i]; - pOutR[i] += m_MixState.pOutBufferR[i]; - } + pOutL[i] += m_MixState.pOutBufferL[i]; + pOutR[i] += m_MixState.pOutBufferR[i]; } -*/ - // Wet/Dry range expansion [0,1] -> [-1,1] update#02 - if(m_pEffect->numInputs > 0 && m_pMixStruct->Info.dwInputRouting & MIXPLUG_INPUTF_MIXEXPAND) - { - wetRatio = 2.0f * wetRatio - 1.0f; - dryRatio = -wetRatio; - } + } + } - wetRatio *= m_fGain; // update#02 - dryRatio *= m_fGain; // update#02 + ClearVSTEvents(); + //SetEvent(processCalled); +} - // Mix operation - switch(mixop) - { - // Default mix (update#02) - case 0: - for(UINT i = 0; i < nSamples; i++) - { - //rewbs.wetratio - added the factors. [20040123] - pOutL[i] += outputBuffers[0][i]*wetRatio + m_MixState.pOutBufferL[i]*dryRatio; - pOutR[i] += outputBuffers[0][i]*wetRatio + m_MixState.pOutBufferR[i]*dryRatio; - } - break; +void CVstPlugin::ProcessMixOps(float *pOutL, float *pOutR, size_t nSamples) +//------------------------------------------------------------------------- +{ + float *leftPlugOutput; + float *rightPlugOutput; - // Wet subtract - case 1: - for(UINT i = 0; i < nSamples; i++) - { - pOutL[i] += m_MixState.pOutBufferL[i] - outputBuffers[0][i]*wetRatio; - pOutR[i] += m_MixState.pOutBufferR[i] - outputBuffers[0][i]*wetRatio; - } - break; + if(m_pEffect->numOutputs == 1) + { + // If there was just the one plugin output we copy it into our 2 outputs + leftPlugOutput = rightPlugOutput = mixBuffer.GetOutputBuffer(0); + } else if(m_pEffect->numOutputs > 1) + { + // Otherwise we actually only cater for two outputs max (outputs > 2 have been mixed together already). + leftPlugOutput = mixBuffer.GetOutputBuffer(0); + rightPlugOutput = mixBuffer.GetOutputBuffer(1); + } else + { + return; + } - // Dry subtract - case 2: - for(UINT i = 0; i < nSamples; i++) - { - pOutL[i] += outputBuffers[0][i] - m_MixState.pOutBufferL[i]*dryRatio; - pOutR[i] += outputBuffers[0][i] - m_MixState.pOutBufferR[i]*dryRatio; - } - break; + // -> mixop == 0 : normal processing + // -> mixop == 1 : MIX += DRY - WET * wetRatio + // -> mixop == 2 : MIX += WET - DRY * dryRatio + // -> mixop == 3 : MIX -= WET - DRY * wetRatio + // -> mixop == 4 : MIX -= middle - WET * wetRatio + middle - DRY + // -> mixop == 5 : MIX_L += wetRatio * (WET_L - DRY_L) + dryRatio * (DRY_R - WET_R) + // MIX_R += dryRatio * (WET_L - DRY_L) + wetRatio * (DRY_R - WET_R) - // Mix subtract - case 3: - for(UINT i = 0; i < nSamples; i++) - { - pOutL[i] -= outputBuffers[0][i] - m_MixState.pOutBufferL[i]*wetRatio; - pOutR[i] -= outputBuffers[0][i] - m_MixState.pOutBufferR[i]*wetRatio; - } - break; + int mixop; + if(m_bIsInstrument) + { + mixop = 0; // Force normal mix mode for instruments + } else + { + mixop = m_pMixStruct ? (m_pMixStruct->Info.dwInputRouting >> 8) & 0xFF : 0; + } - // Middle subtract - case 4: - for(UINT i = 0; i < nSamples; i++) - { - float middle = ( pOutL[i] + m_MixState.pOutBufferL[i] + pOutR[i] + m_MixState.pOutBufferR[i] )/2.0f; - pOutL[i] -= middle - outputBuffers[0][i]*wetRatio + middle - m_MixState.pOutBufferL[i]; - pOutR[i] -= middle - outputBuffers[0][i]*wetRatio + middle - m_MixState.pOutBufferR[i]; - } - break; + float wetRatio = 1 - m_pMixStruct->fDryRatio; + float dryRatio = m_bIsInstrument ? 1 : m_pMixStruct->fDryRatio; // Always mix full dry if this is an instrument - // Left/Right balance - case 5: - if(m_pMixStruct->Info.dwInputRouting & MIXPLUG_INPUTF_MIXEXPAND) - { - wetRatio /= 2.0f; - dryRatio /= 2.0f; - } - for(UINT i = 0; i < nSamples; i++) - { - pOutL[i] += wetRatio * (outputBuffers[0][i] - m_MixState.pOutBufferL[i]) + dryRatio * (m_MixState.pOutBufferR[i] - outputBuffers[0][i]); - pOutR[i] += dryRatio * (outputBuffers[0][i] - m_MixState.pOutBufferL[i]) + wetRatio * (m_MixState.pOutBufferR[i] - outputBuffers[0][i]); - } - break; - } + // Wet / Dry range expansion [0,1] -> [-1,1] + if(m_pEffect->numInputs > 0 && m_pMixStruct->Info.dwInputRouting & MIXPLUG_INPUTF_MIXEXPAND) + { + wetRatio = 2.0f * wetRatio - 1.0f; + dryRatio = -wetRatio; + } - //If dry mix is ticked we add the unprocessed buffer, - //except if this is an instrument since this it has already been done: - if((m_pMixStruct->Info.dwInputRouting & MIXPLUG_INPUTF_WETMIX) && !m_bIsInstrument) - { - for (UINT i=0; i<nSamples; i++) - { - pOutL[i] += m_MixState.pOutBufferL[i]; - pOutR[i] += m_MixState.pOutBufferR[i]; - } - } -// -! BEHAVIOUR_CHANGE#0028 + wetRatio *= m_fGain; + dryRatio *= m_fGain; + // Mix operation + switch(mixop) + { + + // Default mix + case 0: + for(size_t i = 0; i < nSamples; i++) + { + //rewbs.wetratio - added the factors. [20040123] + pOutL[i] += leftPlugOutput[i] * wetRatio + m_MixState.pOutBufferL[i] * dryRatio; + pOutR[i] += rightPlugOutput[i] * wetRatio + m_MixState.pOutBufferR[i] * dryRatio; } - //Otherwise we actually only cater for two outputs max. - else if (m_pEffect->numOutputs > 1) + break; + + // Wet subtract + case 1: + for(size_t i = 0; i < nSamples; i++) { - wetRatio = 1-m_pMixStruct->fDryRatio; //rewbs.dryRatio - dryRatio = m_bIsInstrument ? 1 : m_pMixStruct->fDryRatio; //always mix full dry if this is an instrument + pOutL[i] += m_MixState.pOutBufferL[i] - leftPlugOutput[i] * wetRatio; + pOutR[i] += m_MixState.pOutBufferR[i] - rightPlugOutput[i] * wetRatio; + } + break; -// -> CODE#0028 -// -> DESC="effect plugin mixing mode combo" -/* - for (UINT i=0; i<nSamples; i++) - { + // Dry subtract + case 2: + for(size_t i = 0; i < nSamples; i++) + { + pOutL[i] += leftPlugOutput[i] - m_MixState.pOutBufferL[i] * dryRatio; + pOutR[i] += rightPlugOutput[i] - m_MixState.pOutBufferR[i] * dryRatio; + } + break; - //rewbs.wetratio - added the factors. [20040123] + // Mix subtract + case 3: + for(size_t i = 0; i < nSamples; i++) + { + pOutL[i] -= leftPlugOutput[i] - m_MixState.pOutBufferL[i] * wetRatio; + pOutR[i] -= rightPlugOutput[i] - m_MixState.pOutBufferR[i] * wetRatio; + } + break; - pOutL[i] += outputBuffers[0][i]*wetRatio + m_MixState.pOutBufferL[i]*dryRatio; - pOutR[i] += outputBuffers[1][i]*wetRatio + m_MixState.pOutBufferR[i]*dryRatio; + // Middle subtract + case 4: + for(size_t i = 0; i < nSamples; i++) + { + float middle = (pOutL[i] + m_MixState.pOutBufferL[i] + pOutR[i] + m_MixState.pOutBufferR[i]) / 2.0f; + pOutL[i] -= middle - leftPlugOutput[i] * wetRatio + middle - m_MixState.pOutBufferL[i]; + pOutR[i] -= middle - rightPlugOutput[i] * wetRatio + middle - m_MixState.pOutBufferR[i]; + } + break; - //If dry mix is ticked, we add the unprocessed buffer, - //except if this is an instrument since it has already been done: - if ((m_pMixStruct->Info.dwInputRouting & MIXPLUG_INPUTF_WETMIX) && !isInstrument) - { - pOutL[i] += m_MixState.pOutBufferL[i]; - pOutR[i] += m_MixState.pOutBufferR[i]; - } - } -*/ - // Wet/Dry range expansion [0,1] -> [-1,1] update#02 - if(m_pEffect->numInputs > 0 && m_pMixStruct->Info.dwInputRouting & MIXPLUG_INPUTF_MIXEXPAND) - { - wetRatio = 2.0f * wetRatio - 1.0f; - dryRatio = -wetRatio; - } - - wetRatio *= m_fGain; // update#02 - dryRatio *= m_fGain; // update#02 - - // Mix operation - switch(mixop){ - - // Default mix (update#02) - case 0: - for(UINT i=0; i<nSamples; i++) - { - //rewbs.wetratio - added the factors. [20040123] - pOutL[i] += outputBuffers[0][i]*wetRatio + m_MixState.pOutBufferL[i]*dryRatio; - pOutR[i] += outputBuffers[1][i]*wetRatio + m_MixState.pOutBufferR[i]*dryRatio; - } - break; - - // Wet subtract - case 1: - for(UINT i=0; i<nSamples; i++) - { - pOutL[i] += m_MixState.pOutBufferL[i] - outputBuffers[0][i]*wetRatio; - pOutR[i] += m_MixState.pOutBufferR[i] - outputBuffers[1][i]*wetRatio; - } - break; - - // Dry subtract - case 2: - for(UINT i=0; i<nSamples; i++) - { - pOutL[i] += outputBuffers[0][i] - m_MixState.pOutBufferL[i]*dryRatio; - pOutR[i] += outputBuffers[1][i] - m_MixState.pOutBufferR[i]*dryRatio; - } - break; - - // Mix subtract - case 3: - for(UINT i=0; i<nSamples; i++) - { - pOutL[i] -= outputBuffers[0][i] - m_MixState.pOutBufferL[i]*wetRatio; - pOutR[i] -= outputBuffers[1][i] - m_MixState.pOutBufferR[i]*wetRatio; - } - break; - - // Middle subtract - case 4: - for(UINT i=0; i<nSamples; i++) - { - float middle = ( pOutL[i] + m_MixState.pOutBufferL[i] + pOutR[i] + m_MixState.pOutBufferR[i] )/2.0f; - pOutL[i] -= middle - outputBuffers[0][i]*wetRatio + middle - m_MixState.pOutBufferL[i]; - pOutR[i] -= middle - outputBuffers[1][i]*wetRatio + middle - m_MixState.pOutBufferR[i]; - } - break; - - // Left/Right balance - case 5: - if(m_pMixStruct->Info.dwInputRouting & MIXPLUG_INPUTF_MIXEXPAND) - { - wetRatio /= 2.0f; - dryRatio /= 2.0f; - } - for(UINT i=0; i<nSamples; i++) - { - pOutL[i] += wetRatio * (outputBuffers[0][i] - m_MixState.pOutBufferL[i]) + dryRatio * (m_MixState.pOutBufferR[i] - outputBuffers[1][i]); - pOutR[i] += dryRatio * (outputBuffers[0][i] - m_MixState.pOutBufferL[i]) + wetRatio * (m_MixState.pOutBufferR[i] - outputBuffers[1][i]); - } - break; - } - - //If dry mix is ticked we add the unprocessed buffer, - //except if this is an instrument since this it has already been done: - if((m_pMixStruct->Info.dwInputRouting & MIXPLUG_INPUTF_WETMIX) && !m_bIsInstrument) - { - for (UINT i=0; i<nSamples; i++) - { - pOutL[i] += m_MixState.pOutBufferL[i]; - pOutR[i] += m_MixState.pOutBufferR[i]; - } - } -// -! BEHAVIOUR_CHANGE#0028 + // Left / Right balance + case 5: + if(m_pMixStruct->Info.dwInputRouting & MIXPLUG_INPUTF_MIXEXPAND) + { + wetRatio /= 2.0f; + dryRatio /= 2.0f; } + for(size_t i = 0; i < nSamples; i++) + { + pOutL[i] += wetRatio * (leftPlugOutput[i] - m_MixState.pOutBufferL[i]) + dryRatio * (m_MixState.pOutBufferR[i] - rightPlugOutput[i]); + pOutR[i] += dryRatio * (leftPlugOutput[i] - m_MixState.pOutBufferL[i]) + wetRatio * (m_MixState.pOutBufferR[i] - rightPlugOutput[i]); + } + break; } - - ClearVSTEvents(); - //SetEvent(processCalled); } @@ -2464,13 +2351,13 @@ MidiSend(0xB0|mc|(0x7b<<8)); // all notes off MidiSend(0xB0|mc|(0x78<<8)); // all sounds off - for (UINT i=0; i<128; i++) //all notes + for (size_t i = 0; i < CountOf(pCh->uNoteOnMap); i++) //all notes { - for (UINT c=0; c<MAX_CHANNELS; c++) + for (CHANNELINDEX c = 0; c < CountOf(pCh->uNoteOnMap[i]); c++) { while (pCh->uNoteOnMap[i][c] && !overflow) { - overflow=!(MidiSend(dwMidiCode|(i<<8))); + overflow=!(MidiSend(dwMidiCode | (i << 8))); pCh->uNoteOnMap[i][c]--; } if (overflow) break; //yuck @@ -2502,19 +2389,13 @@ //------------------------------------------------------------------------------------------ { //Error checking - if (nController>127) - { - nController=127; - } - if (nParam>127) - { - nParam=127; - } + LimitMax(nController, 127u); + LimitMax(nParam, 127u); if(m_pSndFile && m_pSndFile->GetModFlag(MSF_MIDICC_BUGEMULATION)) - MidiSend(nController<<16 | nParam<<8 | 0xB0|nMidiCh); + MidiSend((nController << 16) | (nParam << 8) | (0xB0 | nMidiCh)); else - MidiSend(nParam<<16 | nController<<8 | 0xB0|nMidiCh); + MidiSend((nParam << 16) | (nController << 8) | (0xB0 | nMidiCh)); } short CVstPlugin::getMIDI14bitValueFromShort(short value) Modified: trunk/OpenMPT/mptrack/Vstplug.h =================================================================== --- trunk/OpenMPT/mptrack/Vstplug.h 2012-01-08 21:28:20 UTC (rev 1161) +++ trunk/OpenMPT/mptrack/Vstplug.h 2012-01-08 22:04:33 UTC (rev 1162) @@ -82,8 +82,8 @@ VSTINSTCH m_MidiCh[16]; short m_nMidiPitchBendPos[16]; - int m_MixBuffer[MIXBUFFERSIZE*2+2]; // Stereo interleaved - PluginMixBuffer<float> mixBuffer; // Float buffers (input and output) for plugins + int m_MixBuffer[MIXBUFFERSIZE*2+2]; // Stereo interleaved + PluginMixBuffer<float, MIXBUFFERSIZE> mixBuffer; // Float buffers (input and output) for plugins VstMidiEvent m_ev_queue[VSTEVENT_QUEUE_LEN]; CModDoc* m_pModDoc; //rewbs.plugDocAware @@ -172,7 +172,7 @@ void ProcessVSTEvents(); //rewbs.VSTiNoteHoldonStopFix void ClearVSTEvents(); //rewbs.VSTiNoteHoldonStopFix void RecalculateGain(); - void Process(float *pOutL, float *pOutR, unsigned long nSamples); + void Process(float *pOutL, float *pOutR, size_t nSamples); void Init(unsigned long nFreq, int bReset); bool MidiSend(DWORD dwMidiCode); void MidiCC(UINT nMidiCh, UINT nController, UINT nParam, UINT trackChannel); @@ -208,6 +208,8 @@ // Set up input / output buffers. bool InitializeIOBuffers(); + void ProcessMixOps(float *pOutL, float *pOutR, size_t nSamples); + #else // case: NO_VST public: PlugParamIndex GetNumParameters() {return 0;} Modified: trunk/OpenMPT/soundlib/MIDIMacros.cpp =================================================================== --- trunk/OpenMPT/soundlib/MIDIMacros.cpp 2012-01-08 21:28:20 UTC (rev 1161) +++ trunk/OpenMPT/soundlib/MIDIMacros.cpp 2012-01-08 22:04:33 UTC (rev 1162) @@ -123,19 +123,19 @@ switch(macro) { case zxx_reso4Bit: - return _T("Z80 - Z8F controls resonant filter resonance"); + return _T("Z80 - Z8F controls Resonant Filter Resonance"); case zxx_reso7Bit: - return _T("Z80 - ZFF controls resonant filter resonance"); + return _T("Z80 - ZFF controls Resonant Filter Resonance"); case zxx_cutoff: - return _T("Z80 - ZFF controls resonant filter cutoff"); + return _T("Z80 - ZFF controls Resonant Filter Cutoff"); case zxx_mode: - return _T("Z80 - ZFF controls resonant filter mode"); + return _T("Z80 - ZFF controls Resonant Filter Mode"); case zxx_resomode: - return _T("Z80 - Z9F controls resonance + filter mode"); + return _T("Z80 - Z9F controls Resonance + Filter Mode"); case zxx_channelAT: return _T("Z80 - ZFF controls Channel Aftertouch"); case zxx_polyAT: - return _T("Z80 - ZFF controls Poly Aftertouch"); + return _T("Z80 - ZFF controls Polyphonic Aftertouch"); case zxx_custom: default: return _T("Custom"); Modified: trunk/OpenMPT/soundlib/PluginMixBuffer.h =================================================================== --- trunk/OpenMPT/soundlib/PluginMixBuffer.h 2012-01-08 21:28:20 UTC (rev 1161) +++ trunk/OpenMPT/soundlib/PluginMixBuffer.h 2012-01-08 22:04:33 UTC (rev 1162) @@ -11,7 +11,9 @@ #define PLUGINMIXBUFFER_H // At least this part of the code is ready for double-precision rendering... :> -template<typename buffer_t> +// buffer_t: Sample buffer type (float, double, ...) +// bufferSize: Buffer size in samples +template<typename buffer_t, size_t bufferSize> //=================== class PluginMixBuffer //=================== @@ -19,6 +21,7 @@ protected: buffer_t *mixBuffer; // Actual buffer, contains all input and output buffers + buffer_t *alignedBuffer; // Aligned pointer to the buffer buffer_t **inputsArray; // Pointers to input buffers buffer_t **outputsArray; // Pointers to output buffers @@ -35,7 +38,7 @@ //------------------------------------- { ASSERT(index < inputs + outputs); - return reinterpret_cast<buffer_t *>((reinterpret_cast<intptr_t>(&mixBuffer[MIXBUFFERSIZE * index]) + bufferAlignmentInBytes) & ~bufferAlignmentInBytes); + return &alignedBuffer[bufferSize * index]; } public: @@ -58,10 +61,13 @@ try { // Create inputs + outputs buffers with additional alignment. - const size_t bufferSize = MIXBUFFERSIZE * (inputs + outputs) + additionalBuffer; - mixBuffer = new buffer_t[bufferSize]; - memset(mixBuffer, 0, bufferSize * sizeof(buffer_t)); + const size_t totalBufferSize = bufferSize * (inputs + outputs) + additionalBuffer; + mixBuffer = new buffer_t[totalBufferSize]; + memset(mixBuffer, 0, totalBufferSize * sizeof(buffer_t)); + // Align buffer start. + alignedBuffer = reinterpret_cast<buffer_t *>((reinterpret_cast<intptr_t>(mixBuffer) + bufferAlignmentInBytes) & ~bufferAlignmentInBytes); + inputsArray = new (buffer_t *[inputs]); outputsArray = new (buffer_t *[outputs]); } catch(MPTMemoryException) @@ -87,7 +93,7 @@ //--------- { delete[] mixBuffer; - mixBuffer = nullptr; + mixBuffer = alignedBuffer = nullptr; delete[] inputsArray; inputsArray = nullptr; @@ -104,7 +110,7 @@ void ClearOutputBuffers(size_t numSamples) //---------------------------------------- { - ASSERT(numSamples <= MIXBUFFERSIZE); + ASSERT(numSamples <= bufferSize); for(size_t i = 0; i < outputs; i++) { memset(outputsArray[i], 0, numSamples * sizeof(buffer_t)); @@ -115,6 +121,7 @@ //--------------- { mixBuffer = nullptr; + alignedBuffer = nullptr; inputsArray = nullptr; outputsArray = nullptr; Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2012-01-08 21:28:20 UTC (rev 1161) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2012-01-08 22:04:33 UTC (rev 1162) @@ -2933,15 +2933,20 @@ { SetModFlag(MSF_COMPATIBLE_PLAY, false); SetModFlag(MSF_MIDICC_BUGEMULATION, false); - // If there are any plugins, enable volume bug emulation. - for(PLUGINDEX i = 0; i < MAX_MIXPLUGINS; i++) + + if(m_dwLastSavedWithVersion >= MAKE_VERSION_NUMERIC(1, 17, 00, 00)) { - if(m_MixPlugins[i].Info.dwPluginId1 | m_MixPlugins[i].Info.dwPluginId2) + // If there are any plugins, enable volume bug emulation. + for(PLUGINDEX i = 0; i < MAX_MIXPLUGINS; i++) { - SetModFlag(MSF_MIDICC_BUGEMULATION, true); - break; + if(m_MixPlugins[i].Info.dwPluginId1 | m_MixPlugins[i].Info.dwPluginId2) + { + SetModFlag(MSF_MIDICC_BUGEMULATION, true); + break; + } } } + // If there are any instruments with random variation, enable the old random variation behaviour. for(INSTRUMENTINDEX i = 1; i <= GetNumInstruments(); i++) { Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2012-01-08 21:28:20 UTC (rev 1161) +++ trunk/OpenMPT/soundlib/Sndfile.h 2012-01-08 22:04:33 UTC (rev 1162) @@ -392,7 +392,7 @@ virtual int Release() = 0; virtual void SaveAllParameters() = 0; virtual void RestoreAllParameters(long nProg=-1) = 0; //rewbs.plugDefaultProgram: added param - virtual void Process(float *pOutL, float *pOutR, unsigned long nSamples) = 0; + virtual void Process(float *pOutL, float *pOutR, size_t nSamples) = 0; virtual void Init(unsigned long nFreq, int bReset) = 0; virtual bool MidiSend(DWORD dwMidiCode) = 0; virtual void MidiCC(UINT nMidiCh, UINT nController, UINT nParam, UINT trackChannel) = 0; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2012-01-09 23:08:20
|
Revision: 1163 http://modplug.svn.sourceforge.net/modplug/?rev=1163&view=rev Author: saga-games Date: 2012-01-09 23:08:13 +0000 (Mon, 09 Jan 2012) Log Message: ----------- [Fix] XM Compatibility: Out-of-range notes should actually not be played at all (http://bugs.openmpt.org/view.php?id=217). Test case: note-limit.xm [Mod] OpenMPT: Version is now 1.20.00.62 Modified Paths: -------------- trunk/OpenMPT/mptrack/version.h trunk/OpenMPT/soundlib/Snd_fx.cpp Modified: trunk/OpenMPT/mptrack/version.h =================================================================== --- trunk/OpenMPT/mptrack/version.h 2012-01-08 22:04:33 UTC (rev 1162) +++ trunk/OpenMPT/mptrack/version.h 2012-01-09 23:08:13 UTC (rev 1163) @@ -15,7 +15,7 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 20 #define VER_MINOR 00 -#define VER_MINORMINOR 61 +#define VER_MINORMINOR 62 //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/Snd_fx.cpp =================================================================== --- trunk/OpenMPT/soundlib/Snd_fx.cpp 2012-01-08 22:04:33 UTC (rev 1162) +++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2012-01-09 23:08:13 UTC (rev 1163) @@ -793,8 +793,7 @@ pChn->nC5Speed = pSmp->nC5Speed; pChn->m_CalculateFreq = true; pChn->nFineTune = 0; - } - else + } else { pChn->nC5Speed = pSmp->nC5Speed; pChn->nFineTune = pSmp->nFineTune; @@ -839,7 +838,7 @@ MODSAMPLE *pSmp = pChn->pModSample; MODINSTRUMENT *pIns = pChn->pModInstrument; - const bool bNewTuning = (GetType() == MOD_TYPE_MPT && pIns != nullptr && pIns->pTuning); + const bool newTuning = (GetType() == MOD_TYPE_MPT && pIns != nullptr && pIns->pTuning); // save the note that's actually used, as it's necessary to properly calculate PPS and stuff const int realnote = note; @@ -879,7 +878,7 @@ return; } - if(bNewTuning) + if(newTuning) { if(!bPorta || pChn->nNote == NOTE_NONE) pChn->nPortamentoDest = 0; @@ -921,7 +920,7 @@ if (GetType() & (MOD_TYPE_XM|MOD_TYPE_MT2|MOD_TYPE_MED)) { note += pChn->nTranspose; - Limit(note, NOTE_MIN, 131); // why 131? 120+11, how does this make sense? + Limit(note, NOTE_MIN + 11, NOTE_MIN + 130); // why 131? 120+11, how does this make sense? } else { Limit(note, NOTE_MIN, NOTE_MAX); @@ -945,7 +944,7 @@ if (period) { if ((!bPorta) || (!pChn->nPeriod)) pChn->nPeriod = period; - if(!bNewTuning) pChn->nPortamentoDest = period; + if(!newTuning) pChn->nPortamentoDest = period; if ((!bPorta) || ((!pChn->nLength) && (!(GetType() & MOD_TYPE_S3M)))) { pChn->pModSample = pSmp; @@ -1549,8 +1548,27 @@ { UINT note = pChn->rowCommand.note; if (instr) pChn->nNewIns = instr; - bool retrigEnv = (!note) && (instr); + // Notes that exceed FT2's limit are completely ignored. + // Test case: note-limit.xm + if(note != NOTE_NONE && NOTE_IS_VALID(note) && IsCompatibleMode(TRK_FASTTRACKER2)) + { + const int computedNote = note + pChn->nTranspose; + if((computedNote < NOTE_MIN + 11 || computedNote > NOTE_MIN + 130)) + { + note = NOTE_NONE; + } + } + + // XM: FT2 ignores a note next to a K00 effect, and a fade-out seems to be done when no volume envelope is present (not exactly the Kxx behaviour) + if(cmd == CMD_KEYOFF && param == 0 && IsCompatibleMode(TRK_FASTTRACKER2)) + { + note = NOTE_NONE; + instr = 0; + } + + bool retrigEnv = note == NOTE_NONE && instr != 0; + // Apparently, any note number in a pattern causes instruments to recall their original volume settings - no matter if there's a Note Off next to it or whatever. // Test cases: keyoff+instr.xm, delay.xm bool reloadSampleSettings = (IsCompatibleMode(TRK_FASTTRACKER2) && instr != 0); @@ -1559,19 +1577,14 @@ // Now it's time for some FT2 crap... if (GetType() & (MOD_TYPE_XM | MOD_TYPE_MT2)) { - // XM: FT2 ignores a note next to a K00 effect, and a fade-out seems to be done when no volume envelope is present (not exactly the Kxx behaviour) - if(cmd == CMD_KEYOFF && param == 0 && IsCompatibleMode(TRK_FASTTRACKER2)) - { - note = instr = 0; - retrigEnv = false; - } // XM: Key-Off + Sample == Note Cut (BUT: Only if no instr number or volume effect is present!) if ((note == NOTE_KEYOFF) && ((!instr && volcmd == VOLCMD_NONE && cmd != CMD_VOLUME) || !IsCompatibleMode(TRK_FASTTRACKER2)) && ((!pChn->pModInstrument) || (!(pChn->pModInstrument->VolEnv.dwFlags & ENV_ENABLED)))) { pChn->dwFlags |= CHN_FASTVOLRAMP; pChn->nVolume = 0; - note = instr = 0; + note = NOTE_NONE; + instr = 0; retrigEnv = false; } else if(IsCompatibleMode(TRK_FASTTRACKER2) && !(m_dwSongFlags & SONG_FIRSTTICK)) { @@ -1604,6 +1617,7 @@ reloadSampleSettings = true; } } + } if((retrigEnv && !IsCompatibleMode(TRK_FASTTRACKER2)) || reloadSampleSettings) @@ -1703,8 +1717,8 @@ InstrumentChange(pChn, instr, bPorta, true); pChn->nNewIns = 0; // Special IT case: portamento+note causes sample change -> ignore portamento - if ((m_nType & (MOD_TYPE_S3M|MOD_TYPE_IT|MOD_TYPE_MPT)) - && (psmp != pChn->pModSample) && (note) && (note < 0x80)) + if ((GetType() & (MOD_TYPE_S3M|MOD_TYPE_IT|MOD_TYPE_MPT)) + && (psmp != pChn->pModSample) && (note) && (note < 0x80)) { bPorta = false; } @@ -1714,11 +1728,11 @@ { if ((!instr) && (pChn->nNewIns) && (note < 0x80)) { - InstrumentChange(pChn, pChn->nNewIns, bPorta, false, (m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2)) ? false : true); + InstrumentChange(pChn, pChn->nNewIns, bPorta, false, (GetType() & (MOD_TYPE_XM|MOD_TYPE_MT2)) == 0); pChn->nNewIns = 0; } - NoteChange(nChn, note, bPorta, (m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2)) ? false : true); - if ((bPorta) && (m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2)) && (instr)) + NoteChange(nChn, note, bPorta, (GetType() & (MOD_TYPE_XM|MOD_TYPE_MT2)) == 0); + if ((bPorta) && (GetType() & (MOD_TYPE_XM|MOD_TYPE_MT2)) && (instr)) { pChn->dwFlags |= CHN_FASTVOLRAMP; ResetChannelEnvelopes(pChn); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2012-01-14 14:58:58
|
Revision: 1164 http://modplug.svn.sourceforge.net/modplug/?rev=1164&view=rev Author: saga-games Date: 2012-01-14 14:58:51 +0000 (Sat, 14 Jan 2012) Log Message: ----------- [Ref] Added some GetEnvelope() functions to instrument and channel structs to retrieve a specified envelope. [Fix] Offset effect: Fractional offset wasn't reset (this could produce a very tiny but audible difference when having a portamento effect next to an offset effect in IT files). Modified Paths: -------------- trunk/OpenMPT/mptrack/MainFrm.cpp trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/mptrack/View_ins.cpp trunk/OpenMPT/soundlib/Snd_fx.cpp trunk/OpenMPT/soundlib/Sndfile.h trunk/OpenMPT/soundlib/Sndmix.cpp Modified: trunk/OpenMPT/mptrack/MainFrm.cpp =================================================================== --- trunk/OpenMPT/mptrack/MainFrm.cpp 2012-01-09 23:08:13 UTC (rev 1163) +++ trunk/OpenMPT/mptrack/MainFrm.cpp 2012-01-14 14:58:51 UTC (rev 1164) @@ -1053,12 +1053,12 @@ p->nPattern = m_pSndFile->m_nPattern; if (m_dwNotifyType & MPTNOTIFY_SAMPLE) { - UINT nSmp = m_dwNotifyType & 0xFFFF; - for (UINT k=0; k<MAX_CHANNELS; k++) + SAMPLEINDEX nSmp = m_dwNotifyType & 0xFFFF; + for (CHANNELINDEX k = 0; k < MAX_CHANNELS; k++) { MODCHANNEL *pChn = &m_pSndFile->Chn[k]; p->dwPos[k] = 0; - if ((nSmp) && (nSmp <= m_pSndFile->m_nSamples) && (pChn->nLength) + if ((nSmp) && (nSmp <= m_pSndFile->GetNumSamples()) && (pChn->nLength) && (pChn->pSample) && (pChn->pSample == m_pSndFile->GetSample(nSmp).pSample) && ((!(pChn->dwFlags & CHN_NOTEFADE)) || (pChn->nFadeOutVol))) { @@ -1069,7 +1069,7 @@ if (m_dwNotifyType & (MPTNOTIFY_VOLENV|MPTNOTIFY_PANENV|MPTNOTIFY_PITCHENV)) { UINT nIns = m_dwNotifyType & 0xFFFF; - for (UINT k=0; k<MAX_CHANNELS; k++) + for (CHANNELINDEX k = 0; k < MAX_CHANNELS; k++) { MODCHANNEL *pChn = &m_pSndFile->Chn[k]; p->dwPos[k] = 0; @@ -1077,18 +1077,17 @@ && (pChn->pModInstrument) && (pChn->pModInstrument == m_pSndFile->Instruments[nIns]) && ((!(pChn->dwFlags & CHN_NOTEFADE)) || (pChn->nFadeOutVol))) { - MODCHANNEL_ENVINFO *env = &pChn->VolEnv; + enmEnvelopeTypes notifyEnv = ENV_VOLUME; if (m_dwNotifyType & MPTNOTIFY_PITCHENV) - { - env = &pChn->PitchEnv; - } else if (m_dwNotifyType & MPTNOTIFY_PANENV) - { - env = &pChn->PanEnv; - } + notifyEnv = ENV_PITCH; + else if (m_dwNotifyType & MPTNOTIFY_PANENV) + notifyEnv = ENV_PANNING; - if (env->flags & ENV_ENABLED) + const MODCHANNEL_ENVINFO &chnEnv = pChn->GetEnvelope(notifyEnv); + + if (chnEnv.flags & ENV_ENABLED) { - DWORD pos = env->nEnvPosition; + DWORD pos = chnEnv.nEnvPosition; if(m_pSndFile->IsCompatibleMode(TRK_IMPULSETRACKER) && pos > 0) { // Impulse Tracker envelope handling (see SndMix.cpp for details) @@ -1607,7 +1606,7 @@ m[63*4].note = NOTE_KEYOFF; m[63*4+1].note = NOTE_KEYOFF; } - if ((nInstrument) && (nInstrument <= pSong->m_nInstruments)) + if ((nInstrument) && (nInstrument <= pSong->GetNumInstruments())) { m_WaveFile.ReadInstrumentFromSong(1, pSong, nInstrument); } else Modified: trunk/OpenMPT/mptrack/Modedit.cpp =================================================================== --- trunk/OpenMPT/mptrack/Modedit.cpp 2012-01-09 23:08:13 UTC (rev 1163) +++ trunk/OpenMPT/mptrack/Modedit.cpp 2012-01-14 14:58:51 UTC (rev 1164) @@ -1245,38 +1245,25 @@ pIns = m_SndFile.Instruments[nIns]; if(pIns == nullptr) return false; - INSTRUMENTENVELOPE *pEnv = nullptr; + const INSTRUMENTENVELOPE &env = pIns->GetEnvelope(nEnv); - switch(nEnv) - { - case ENV_PANNING: - pEnv = &pIns->PanEnv; - break; - case ENV_PITCH: - pEnv = &pIns->PitchEnv; - break; - default: - pEnv = &pIns->VolEnv; - break; - } - // We don't want to copy empty envelopes - if(pEnv->nNodes == 0) + if(env.nNodes == 0) { return false; } strcpy(s, pszEnvHdr); - wsprintf(s + strlen(s), pszEnvFmt, pEnv->nNodes, pEnv->nSustainStart, pEnv->nSustainEnd, pEnv->nLoopStart, pEnv->nLoopEnd, (pEnv->dwFlags & ENV_SUSTAIN) ? 1 : 0, (pEnv->dwFlags & ENV_LOOP) ? 1 : 0, (pEnv->dwFlags & ENV_CARRY) ? 1 : 0); - for (UINT i = 0; i < pEnv->nNodes; i++) + wsprintf(s + strlen(s), pszEnvFmt, env.nNodes, env.nSustainStart, env.nSustainEnd, env.nLoopStart, env.nLoopEnd, (env.dwFlags & ENV_SUSTAIN) ? 1 : 0, (env.dwFlags & ENV_LOOP) ? 1 : 0, (env.dwFlags & ENV_CARRY) ? 1 : 0); + for (UINT i = 0; i < env.nNodes; i++) { if (strlen(s) >= sizeof(s)-32) break; - wsprintf(s+strlen(s), "%d,%d\r\n", pEnv->Ticks[i], pEnv->Values[i]); + wsprintf(s+strlen(s), "%d,%d\r\n", env.Ticks[i], env.Values[i]); } //Writing release node if(strlen(s) < sizeof(s) - 32) - wsprintf(s+strlen(s), "%u\r\n", pEnv->nReleaseNode); + wsprintf(s+strlen(s), "%u\r\n", env.nReleaseNode); dwMemSize = strlen(s)+1; if ((pMainFrm->OpenClipboard()) && ((hCpy = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE, dwMemSize))!=NULL)) @@ -1310,7 +1297,6 @@ if ((hCpy) && ((p = (LPSTR)GlobalLock(hCpy)) != NULL)) { MODINSTRUMENT *pIns = m_SndFile.Instruments[nIns]; - INSTRUMENTENVELOPE *pEnv = nullptr; UINT susBegin = 0, susEnd = 0, loopBegin = 0, loopEnd = 0, bSus = 0, bLoop = 0, bCarry = 0, nPoints = 0, releaseNode = ENV_RELEASE_NODE_UNSET; DWORD dwMemSize = GlobalSize(hCpy), dwPos = strlen(pszEnvHdr); @@ -1325,26 +1311,16 @@ if (loopEnd >= nPoints) loopEnd = 0; if (loopBegin > loopEnd) loopBegin = loopEnd; - switch(nEnv) - { - case ENV_PANNING: - pEnv = &pIns->PanEnv; - break; - case ENV_PITCH: - pEnv = &pIns->PitchEnv; - break; - default: - pEnv = &pIns->VolEnv; - break; - } - pEnv->nNodes = nPoints; - pEnv->nSustainStart = susBegin; - pEnv->nSustainEnd = susEnd; - pEnv->nLoopStart = loopBegin; - pEnv->nLoopEnd = loopEnd; - pEnv->nReleaseNode = releaseNode; - pEnv->dwFlags = (pEnv->dwFlags & ~(ENV_LOOP|ENV_SUSTAIN|ENV_CARRY)) | (bLoop ? ENV_LOOP : 0) | (bSus ? ENV_SUSTAIN : 0) | (bCarry ? ENV_CARRY: 0) | (nPoints > 0 ? ENV_ENABLED : 0); + INSTRUMENTENVELOPE &env = pIns->GetEnvelope(nEnv); + env.nNodes = nPoints; + env.nSustainStart = susBegin; + env.nSustainEnd = susEnd; + env.nLoopStart = loopBegin; + env.nLoopEnd = loopEnd; + env.nReleaseNode = releaseNode; + env.dwFlags = (env.dwFlags & ~(ENV_LOOP|ENV_SUSTAIN|ENV_CARRY)) | (bLoop ? ENV_LOOP : 0) | (bSus ? ENV_SUSTAIN : 0) | (bCarry ? ENV_CARRY: 0) | (nPoints > 0 ? ENV_ENABLED : 0); + int oldn = 0; for (UINT i=0; i<nPoints; i++) { @@ -1356,8 +1332,8 @@ if (dwPos >= dwMemSize) break; int n2 = atoi(p+dwPos); if ((n1 < oldn) || (n1 > ENVELOPE_MAX_LENGTH)) n1 = oldn + 1; - pEnv->Ticks[i] = (WORD)n1; - pEnv->Values[i] = (BYTE)n2; + env.Ticks[i] = (WORD)n1; + env.Values[i] = (BYTE)n2; oldn = n1; while ((dwPos < dwMemSize) && (p[dwPos] != '\r') && (p[dwPos] != '\n')) dwPos++; if (dwPos >= dwMemSize) break; @@ -1369,7 +1345,7 @@ BYTE r = static_cast<BYTE>(atoi(p + dwPos)); if(r == 0 || r >= nPoints || !m_SndFile.GetModSpecifications().hasReleaseNode) r = ENV_RELEASE_NODE_UNSET; - pEnv->nReleaseNode = r; + env.nReleaseNode = r; } } GlobalUnlock(hCpy); Modified: trunk/OpenMPT/mptrack/View_ins.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_ins.cpp 2012-01-09 23:08:13 UTC (rev 1163) +++ trunk/OpenMPT/mptrack/View_ins.cpp 2012-01-14 14:58:51 UTC (rev 1164) @@ -548,38 +548,24 @@ return false; } - INSTRUMENTENVELOPE *env; + INSTRUMENTENVELOPE &env = pIns->GetEnvelope(envelope); - switch(envelope) - { - case ENV_VOLUME: - default: - env = &pIns->VolEnv; - break; - case ENV_PANNING: - env = &pIns->PanEnv; - break; - case ENV_PITCH: - env = &pIns->PitchEnv; - break; - } - const DWORD flags = (ENV_ENABLED | extraFlags); if (enable) { - env->dwFlags |= flags; - if(!env->nNodes) + env.dwFlags |= flags; + if(!env.nNodes) { - env->Values[0] = env->Values[1] = defaultValue; - env->Ticks[0] = 0; - env->Ticks[1] = 10; - env->nNodes = 2; + env.Values[0] = env.Values[1] = defaultValue; + env.Ticks[0] = 0; + env.Ticks[1] = 10; + env.nNodes = 2; InvalidateRect(NULL, FALSE); } } else { - env->dwFlags &= ~flags; + env.dwFlags &= ~flags; } CriticalSection cs; @@ -589,28 +575,14 @@ { if(pSndFile->Chn[nChn].pModInstrument == pIns) { - MODCHANNEL_ENVINFO *envInfo; + MODCHANNEL_ENVINFO &chnEnv = pSndFile->Chn[nChn].GetEnvelope(envelope); - switch(envelope) - { - case ENV_VOLUME: - default: - envInfo = &pSndFile->Chn[nChn].VolEnv; - break; - case ENV_PANNING: - envInfo = &pSndFile->Chn[nChn].PanEnv; - break; - case ENV_PITCH: - envInfo = &pSndFile->Chn[nChn].PitchEnv; - break; - } - if(enable) { - envInfo->flags |= flags; + chnEnv.flags |= flags; } else { - envInfo->flags &= ~flags; + chnEnv.flags &= ~flags; } } } @@ -1181,7 +1153,7 @@ } if (pnotify->dwType & MPTNOTIFY_STOP) { - for (UINT i=0; i<MAX_CHANNELS; i++) + for (CHANNELINDEX i = 0; i < MAX_CHANNELS; i++) { if (m_dwNotifyPos[i]) { @@ -1196,7 +1168,7 @@ if ((pnotify->dwType & dwType) && ((pnotify->dwType & 0xFFFF) == m_nInstrument)) { BOOL bUpdate = FALSE; - for (UINT i=0; i<MAX_CHANNELS; i++) + for (CHANNELINDEX i = 0; i < MAX_CHANNELS; i++) { //DWORD newpos = (pSndFile->m_dwSongFlags & SONG_PAUSED) ? pnotify->dwPos[i] : 0; DWORD newpos = pnotify->dwPos[i]; @@ -1210,7 +1182,7 @@ { HDC hdc = ::GetDC(m_hWnd); DrawPositionMarks(hdc); - for (UINT j=0; j<MAX_CHANNELS; j++) + for (CHANNELINDEX j = 0; j < MAX_CHANNELS; j++) { //DWORD newpos = (pSndFile->m_dwSongFlags & SONG_PAUSED) ? pnotify->dwPos[j] : 0; DWORD newpos = pnotify->dwPos[j]; @@ -2552,23 +2524,7 @@ MODINSTRUMENT *pIns = GetInstrumentPtr(); if(pIns == nullptr) return nullptr; - // Now for the real thing. - INSTRUMENTENVELOPE *envelope = nullptr; - - switch(m_nEnv) - { - case ENV_VOLUME: - envelope = &pIns->VolEnv; - break; - case ENV_PANNING: - envelope = &pIns->PanEnv; - break; - case ENV_PITCH: - envelope = &pIns->PitchEnv; - break; - } - - return envelope; + return &pIns->GetEnvelope(m_nEnv); } Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp =================================================================== --- trunk/OpenMPT/soundlib/Snd_fx.cpp 2012-01-09 23:08:13 UTC (rev 1163) +++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2012-01-14 14:58:51 UTC (rev 1164) @@ -1889,19 +1889,19 @@ // Portamento Up case CMD_PORTAMENTOUP: - if ((!param) && (m_nType & MOD_TYPE_MOD)) break; + if ((!param) && (GetType() & MOD_TYPE_MOD)) break; PortamentoUp(nChn, param); break; // Portamento Down case CMD_PORTAMENTODOWN: - if ((!param) && (m_nType & MOD_TYPE_MOD)) break; + if ((!param) && (GetType() & MOD_TYPE_MOD)) break; PortamentoDown(nChn, param); break; // Volume Slide case CMD_VOLUMESLIDE: - if ((param) || (m_nType != MOD_TYPE_MOD)) VolumeSlide(pChn, param); + if ((param) || (GetType() != MOD_TYPE_MOD)) VolumeSlide(pChn, param); break; // Tone-Portamento @@ -1911,7 +1911,7 @@ // Tone-Portamento + Volume Slide case CMD_TONEPORTAVOL: - if ((param) || (m_nType != MOD_TYPE_MOD)) VolumeSlide(pChn, param); + if ((param) || (GetType() != MOD_TYPE_MOD)) VolumeSlide(pChn, param); TonePortamento(pChn, 0); break; @@ -1922,7 +1922,7 @@ // Vibrato + Volume Slide case CMD_VIBRATOVOL: - if ((param) || (m_nType != MOD_TYPE_MOD)) VolumeSlide(pChn, param); + if ((param) || (GetType() != MOD_TYPE_MOD)) VolumeSlide(pChn, param); Vibrato(pChn, 0); break; @@ -1936,10 +1936,10 @@ case CMD_TEMPO: // -> CODE#0010 // -> DESC="add extended parameter mechanism to pattern effects" - m = NULL; + m = nullptr; if (m_nRow < Patterns[m_nPattern].GetNumRows()-1) { - m = Patterns[m_nPattern] + (m_nRow+1) * m_nChannels + nChn; + m = Patterns[m_nPattern].GetpModCommand(m_nRow + 1, nChn); } if (m && m->command == CMD_XPARAM) { @@ -1950,7 +1950,7 @@ param = (param << 8) + m->param; } // -! NEW_FEATURE#0010 - if (m_nType & (MOD_TYPE_S3M|MOD_TYPE_IT|MOD_TYPE_MPT)) + if (GetType() & (MOD_TYPE_S3M|MOD_TYPE_IT|MOD_TYPE_MPT)) { if (param) pChn->nOldTempo = param; else param = pChn->nOldTempo; } @@ -3603,15 +3603,15 @@ MODCOMMAND *m; m = NULL; - if(m_nRow < Patterns[m_nPattern].GetNumRows()-1) m = Patterns[m_nPattern] + (m_nRow+1) * m_nChannels + nChn; + if(m_nRow < Patterns[m_nPattern].GetNumRows() - 1) m = Patterns[m_nPattern].GetpModCommand(m_nRow + 1, nChn); if(m && m->command == CMD_XPARAM) { UINT tmp = m->param; m = NULL; - if(m_nRow < Patterns[m_nPattern].GetNumRows()-2) m = Patterns[m_nPattern] + (m_nRow+2) * m_nChannels + nChn; + if(m_nRow < Patterns[m_nPattern].GetNumRows() - 2) m = Patterns[m_nPattern].GetpModCommand(m_nRow + 2, nChn); - if(m && m->command == CMD_XPARAM) param = (param<<16) + (tmp<<8) + m->param; + if(m && m->command == CMD_XPARAM) param = (param << 16) + (tmp << 8) + m->param; else param = (param<<8) + tmp; } else @@ -3625,11 +3625,12 @@ if ((pChn->rowCommand.note >= NOTE_MIN) && (pChn->rowCommand.note <= NOTE_MAX)) { pChn->nPos = param; + pChn->nPosLo = 0; if (pChn->nPos >= pChn->nLength) { // Offset beyond sample size - if (!(m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2))) + if (!(GetType() & (MOD_TYPE_XM|MOD_TYPE_MT2))) { // IT Compatibility: Offset if(IsCompatibleMode(TRK_IMPULSETRACKER)) @@ -3659,6 +3660,7 @@ { // XXX what's this? pChn->nPos = param; + pChn->nPosLo = 0; } return; @@ -3936,7 +3938,7 @@ if (pIns->VolEnv.nReleaseNode != ENV_RELEASE_NODE_UNSET) { - pChn->VolEnv.nEnvValueAtReleaseJump = GetVolEnvValueFromPosition(pChn->VolEnv.nEnvPosition, pIns); + pChn->VolEnv.nEnvValueAtReleaseJump = GetVolEnvValueFromPosition(pChn->VolEnv.nEnvPosition, pIns->VolEnv); pChn->VolEnv.nEnvPosition = pIns->VolEnv.Ticks[pIns->VolEnv.nReleaseNode]; } Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2012-01-09 23:08:13 UTC (rev 1163) +++ trunk/OpenMPT/soundlib/Sndfile.h 2012-01-14 14:58:51 UTC (rev 1164) @@ -232,6 +232,20 @@ bool HasValidMIDIChannel() const { return (nMidiChannel >= 1 && nMidiChannel <= 17); } + INSTRUMENTENVELOPE &GetEnvelope(enmEnvelopeTypes envType) + { + switch(envType) + { + case ENV_VOLUME: + default: + return VolEnv; + case ENV_PANNING: + return PanEnv; + case ENV_PITCH: + return PitchEnv; + } + } + }; //MODINSTRUMENT; @@ -340,6 +354,20 @@ void ClearRowCmd() { rowCommand = MODCOMMAND::Empty(); } + MODCHANNEL_ENVINFO &GetEnvelope(enmEnvelopeTypes envType) + { + switch(envType) + { + case ENV_VOLUME: + default: + return VolEnv; + case ENV_PANNING: + return PanEnv; + case ENV_PITCH: + return PitchEnv; + } + } + typedef UINT VOLUME; VOLUME GetVSTVolume() {return (pModInstrument) ? pModInstrument->nGlobalVol * 4 : nVolume;} @@ -1193,7 +1221,7 @@ bool ReadFixedLineLengthMessage(const BYTE *data, const size_t length, const size_t lineLength, const size_t lineEndingLength, void (*pTextConverter)(char &) = nullptr); public: - int GetVolEnvValueFromPosition(int position, const MODINSTRUMENT* pIns) const; + int GetVolEnvValueFromPosition(int position, const INSTRUMENTENVELOPE &env) const; void ResetChannelEnvelopes(MODCHANNEL *pChn) const; void ResetChannelEnvelope(MODCHANNEL_ENVINFO &env) const; Modified: trunk/OpenMPT/soundlib/Sndmix.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndmix.cpp 2012-01-09 23:08:13 UTC (rev 1163) +++ trunk/OpenMPT/soundlib/Sndmix.cpp 2012-01-14 14:58:51 UTC (rev 1164) @@ -1075,7 +1075,7 @@ return; } const int envpos = pChn->VolEnv.nEnvPosition - (IsCompatibleMode(TRK_IMPULSETRACKER) ? 1 : 0); - int envvol = GetVolEnvValueFromPosition(envpos, pIns); + int envvol = GetVolEnvValueFromPosition(envpos, pIns->VolEnv); // if we are in the release portion of the envelope, // rescale envelope factor so that it is proportional to the release point @@ -2405,8 +2405,7 @@ if(pChn->rowCommand.command == CMD_MIDI || pChn->rowCommand.command == CMD_SMOOTHMIDI) { - // Only smooth MIDI macros are processed on every tick - //if((pChn->nRowCommand == CMD_MIDI) && !(m_dwSongFlags & SONG_FIRSTTICK)) return; + // Also non-smooth MIDI Macros are processed on every row to update macros with volume or panning variables. if(pChn->rowCommand.param < 0x80) ProcessMIDIMacro(nChn, (pChn->rowCommand.command == CMD_SMOOTHMIDI), m_MidiCfg.szMidiSFXExt[pChn->nActiveMacro], pChn->rowCommand.param); else @@ -2505,12 +2504,12 @@ { case PLUGIN_VOLUMEHANDLING_DRYWET: if(hasVolCommand) pPlugin->SetDryRatio(2*vol); - else pPlugin->SetDryRatio(2*defaultVolume); + else pPlugin->SetDryRatio(2 * defaultVolume); break; case PLUGIN_VOLUMEHANDLING_MIDI: - if(hasVolCommand) pPlugin->MidiCC(GetBestMidiChannel(nChn), MIDICC_Volume_Coarse, min(127, 2*vol), nChn); - else pPlugin->MidiCC(GetBestMidiChannel(nChn), MIDICC_Volume_Coarse, min(127, 2*defaultVolume), nChn); + if(hasVolCommand) pPlugin->MidiCC(GetBestMidiChannel(nChn), MIDICC_Volume_Coarse, min(127, 2 * vol), nChn); + else pPlugin->MidiCC(GetBestMidiChannel(nChn), MIDICC_Volume_Coarse, min(127, 2 * defaultVolume), nChn); break; } @@ -2518,35 +2517,33 @@ } -int CSoundFile::GetVolEnvValueFromPosition(int position, const MODINSTRUMENT* pIns) const -//--------------------------------------------------------------------------------------- +int CSoundFile::GetVolEnvValueFromPosition(int position, const INSTRUMENTENVELOPE &env) const +//------------------------------------------------------------------------------------------- { - UINT pt = pIns->VolEnv.nNodes - 1; + UINT pt = env.nNodes - 1; - //Checking where current 'tick' is relative to the - //envelope points. - for (UINT i=0; i<(UINT)(pIns->VolEnv.nNodes-1); i++) + // Checking where current 'tick' is relative to the + // envelope points. + for (UINT i = 0; i < (UINT)(env.nNodes-1); i++) { - if (position <= pIns->VolEnv.Ticks[i]) + if (position <= env.Ticks[i]) { pt = i; break; } } - int x2 = pIns->VolEnv.Ticks[pt]; + int x2 = env.Ticks[pt]; int x1, envvol; - if (position >= x2) //Case: current 'tick' is on a envelope point. + if (position >= x2) // Case: current 'tick' is on a envelope point. { - envvol = pIns->VolEnv.Values[pt] << 2; - x1 = x2; - } - else //Case: current 'tick' is between two envelope points. + envvol = env.Values[pt] * 4; + } else // Case: current 'tick' is between two envelope points. { if (pt) { - envvol = pIns->VolEnv.Values[pt-1] << 2; - x1 = pIns->VolEnv.Ticks[pt-1]; + envvol = env.Values[pt - 1] * 4; + x1 = env.Ticks[pt - 1]; } else { envvol = 0; @@ -2555,9 +2552,9 @@ if(x2 > x1 && position > x1) { - //Linear approximation between the points; - //f(x+d) ~ f(x) + f'(x)*d, where f'(x) = (y2-y1)/(x2-x1) - envvol += ((position - x1) * (((int)pIns->VolEnv.Values[pt]<<2) - envvol)) / (x2 - x1); + // Linear approximation between the points; + // f(x+d) ~ f(x) + f'(x)*d, where f'(x) = (y2-y1)/(x2-x1) + envvol += ((position - x1) * (((int)env.Values[pt] * 4) - envvol)) / (x2 - x1); } } return envvol; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2012-01-14 20:57:23
|
Revision: 1165 http://modplug.svn.sourceforge.net/modplug/?rev=1165&view=rev Author: saga-games Date: 2012-01-14 20:57:16 +0000 (Sat, 14 Jan 2012) Log Message: ----------- [Fix] IT Compatibility: A Z7F next to a note seems to reset the filter immediately (test cases: filter-reset.it, filter-reset-carry.it) [Fix] IT Compatibility: Envelope carry pickup after SCx (test case: cut-carry.it) [Mod] OpenMPT: Version is now 1.20.00.63 Modified Paths: -------------- trunk/OpenMPT/mptrack/version.h trunk/OpenMPT/soundlib/Snd_flt.cpp trunk/OpenMPT/soundlib/Snd_fx.cpp Modified: trunk/OpenMPT/mptrack/version.h =================================================================== --- trunk/OpenMPT/mptrack/version.h 2012-01-14 14:58:51 UTC (rev 1164) +++ trunk/OpenMPT/mptrack/version.h 2012-01-14 20:57:16 UTC (rev 1165) @@ -15,7 +15,7 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 20 #define VER_MINOR 00 -#define VER_MINORMINOR 62 +#define VER_MINORMINOR 63 //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/Snd_flt.cpp =================================================================== --- trunk/OpenMPT/soundlib/Snd_flt.cpp 2012-01-14 14:58:51 UTC (rev 1164) +++ trunk/OpenMPT/soundlib/Snd_flt.cpp 2012-01-14 20:57:16 UTC (rev 1165) @@ -57,26 +57,31 @@ float d, e; - if(UseITFilterMode()) - { + // flt_modifier is in [-256, 256], so cutoff is in [0, 127 * 2] after this calculation. + const int computedCutoff = cutoff * (flt_modifier + 256) / 256; - // flt_modifier is in [-256, 256], so cutoff is in [0, 127 * 2] after this calculation - cutoff = cutoff * (flt_modifier + 256) / 256; - - // Filtering is only ever done if either cutoff is not full or if resonance is set. - if(cutoff < 254 || resonance != 0) + // Filtering is only ever done in IT if either cutoff is not full or if resonance is set. + if(IsCompatibleMode(TRK_IMPULSETRACKER) && resonance == 0 && computedCutoff >= 254) + { + if(pChn->rowCommand.note != NOTE_NONE && NOTE_IS_VALID(pChn->rowCommand.note) && !(pChn->dwFlags & CHN_PORTAMENTO)) { - pChn->dwFlags |= CHN_FILTER; - } else - { - return; + // Z7F next to a note disables the filter, however in other cases this should not happen. + // Test cases: filter-reset.it, filter-reset-carry.it + pChn->dwFlags &= ~CHN_FILTER; } + return; + } + pChn->dwFlags |= CHN_FILTER; + + if(UseITFilterMode()) + { + static const float freqMultiplier = 2.0f * (float)M_PI * 110.0f * pow(2.0f, 0.25f); static const float freqParameterMultiplier = 128.0f / (24.0f * 256.0f); // 2 ^ (i / 24 * 256) - const float r = (float)gdwMixingFreq / (freqMultiplier * pow(2.0f, (float)cutoff * freqParameterMultiplier)); + const float r = (float)gdwMixingFreq / (freqMultiplier * pow(2.0f, (float)computedCutoff * freqParameterMultiplier)); d = ITResonanceTable[resonance] * r + ITResonanceTable[resonance] - 1.0f; e = r * r; @@ -84,14 +89,6 @@ } else { - // We might end up here even if IT compatible playback mode is enabled and if extended filter range flag is set. - // We'd still want compatible behaviour then, but at the same time use MPT's cutoff / resonance settings - if(IsCompatibleMode(TRK_IMPULSETRACKER) && resonance == 0 && cutoff * (flt_modifier + 256) >= 254 * 256) - { - return; - } - pChn->dwFlags |= CHN_FILTER; - float fc = (float)CutOffToFrequency(cutoff, flt_modifier); const float dmpfac = pow(10.0f, -((24.0f / 128.0f) * (float)resonance) / 20.0f); Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp =================================================================== --- trunk/OpenMPT/soundlib/Snd_fx.cpp 2012-01-14 14:58:51 UTC (rev 1164) +++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2012-01-14 20:57:16 UTC (rev 1165) @@ -466,7 +466,7 @@ } else if (((param & 0xF0) == 0xF0) && (param & 0x0F)) { - if (memory.chnVols[nChn] > (int)(param & 0x0F)) param = memory.chnVols[nChn] - (param & 0x0F); + if (memory.chnVols[nChn] > (param & 0x0F)) param = memory.chnVols[nChn] - (param & 0x0F); else param = 0; } else if (param & 0x0F) @@ -643,6 +643,13 @@ } } + // IT Compatibility: Envelope pickup after SCx cut + // Test case: cut-carry.it + if(pChn->nInc == 0 && IsCompatibleMode(TRK_IMPULSETRACKER)) + { + bInstrumentChanged = true; + } + // XM compatibility: new instrument + portamento = ignore new instrument number, but reload old instrument settings (the world of XM is upside down...) // And this does *not* happen if volume column portamento is used together with note delay... (handled in ProcessEffects(), where all the other note delay stuff is.) // Test case: porta-delay.xm @@ -2421,7 +2428,7 @@ //-------------------------------------------------------------------------------------------------- { MODCHANNEL *pChn = &Chn[nChn]; - MidiPortamento(nChn, -param); //Send midi pitch bend event if there's a plugin + MidiPortamento(nChn, -(int)param); //Send midi pitch bend event if there's a plugin if(param) pChn->nOldPortaUpDown = param; @@ -3472,7 +3479,7 @@ if(oldcutoff < 0) oldcutoff = -oldcutoff; if((pChn->nVolume > 0) || (oldcutoff < 0x10) || (!(pChn->dwFlags & CHN_FILTER)) || (!(pChn->nLeftVol|pChn->nRightVol))) - SetupChannelFilter(pChn, (pChn->dwFlags & CHN_FILTER) ? false : true); + SetupChannelFilter(pChn, !(pChn->dwFlags & CHN_FILTER)); #endif // NO_FILTER return 4; @@ -3493,7 +3500,7 @@ } #ifndef NO_FILTER - SetupChannelFilter(pChn, (pChn->dwFlags & CHN_FILTER) ? false : true); + SetupChannelFilter(pChn, !(pChn->dwFlags & CHN_FILTER)); #endif // NO_FILTER return 4; @@ -3505,7 +3512,7 @@ { pChn->nFilterMode = (param >> 4); #ifndef NO_FILTER - SetupChannelFilter(pChn, (pChn->dwFlags & CHN_FILTER) ? false : true); + SetupChannelFilter(pChn, !(pChn->dwFlags & CHN_FILTER)); #endif // NO_FILTER } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2012-01-22 16:52:10
|
Revision: 1166 http://modplug.svn.sourceforge.net/modplug/?rev=1166&view=rev Author: saga-games Date: 2012-01-22 16:52:03 +0000 (Sun, 22 Jan 2012) Log Message: ----------- [Ref] Instruments now have a GetSamples() method to retrieved a set of all referenced samples. [Ref] Unified code to calculate row duration (used by GetLength() and time stretch calculator). [Imp] When changing XM autovibrato settings, they are now automatically propagated to other samples refererred by the same instrument. Modified Paths: -------------- trunk/OpenMPT/mptrack/Ctrl_ins.cpp trunk/OpenMPT/mptrack/Ctrl_smp.cpp trunk/OpenMPT/mptrack/Ctrl_smp.h trunk/OpenMPT/mptrack/MainFrm.cpp trunk/OpenMPT/mptrack/PSRatioCalc.cpp trunk/OpenMPT/mptrack/PSRatioCalc.h trunk/OpenMPT/mptrack/dlg_misc.cpp trunk/OpenMPT/mptrack/view_com.cpp trunk/OpenMPT/soundlib/Fastmix.cpp trunk/OpenMPT/soundlib/Snd_fx.cpp trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/Sndfile.h Modified: trunk/OpenMPT/mptrack/Ctrl_ins.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2012-01-14 20:57:16 UTC (rev 1165) +++ trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2012-01-22 16:52:03 UTC (rev 1166) @@ -322,24 +322,21 @@ AppendMenu(hMenu, MF_STRING, ID_INSTRUMENT_SAMPLEMAP, "Edit Sample &Map\t" + ih->GetKeyTextFromCommand(kcInsNoteMapEditSampleMap)); if (hSubMenu) { - const SAMPLEINDEX numSamps = pSndFile->GetNumSamples(); - vector<bool> smpused(numSamps + 1, false); - for (UINT i=1; i<NOTE_MAX; i++) + // Create sub menu with a list of all samples that are referenced by this instrument. + const std::set<SAMPLEINDEX> referencedSamples = pIns->GetSamples(); + + for(std::set<SAMPLEINDEX>::const_iterator sample = referencedSamples.begin(); sample != referencedSamples.end(); sample++) { - SAMPLEINDEX nsmp = pIns->Keyboard[i]; - if (nsmp <= numSamps) smpused[nsmp] = true; - } - for (SAMPLEINDEX j = 1; j <= numSamps; j++) - { - if (smpused[j]) + if(*sample <= pSndFile->GetNumSamples()) { - wsprintf(s, "%d: ", j); - UINT l = strlen(s); - memcpy(s + l, pSndFile->m_szNames[j], MAX_SAMPLENAME); - s[l + MAX_SAMPLENAME] = 0; - AppendMenu(hSubMenu, MF_STRING, ID_NOTEMAP_EDITSAMPLE+j, s); + wsprintf(s, "%d: ", *sample); + size_t l = strlen(s); + memcpy(s + l, pSndFile->m_szNames[*sample], MAX_SAMPLENAME); + s[l + MAX_SAMPLENAME] = '\0'; + AppendMenu(hSubMenu, MF_STRING, ID_NOTEMAP_EDITSAMPLE + *sample, s); } } + AppendMenu(hMenu, MF_POPUP, (UINT)hSubMenu, "&Edit Sample\t" + ih->GetKeyTextFromCommand(kcInsNoteMapEditSample)); AppendMenu(hMenu, MF_SEPARATOR, 0, NULL); } @@ -888,7 +885,6 @@ BOOL CCtrlInstruments::OnInitDialog() //----------------------------------- { - CHAR s[64]; CModControlDlg::OnInitDialog(); m_bInitialized = FALSE; if ((!m_pModDoc) || (!m_pSndFile)) return TRUE; @@ -1901,15 +1897,18 @@ if(b && m_pSndFile->GetType() & (MOD_TYPE_IT|MOD_TYPE_MPT)) { bool smpPanningInUse = false; - for(BYTE i = 0; i < CountOf(pIns->Keyboard); i++) + + const std::set<SAMPLEINDEX> referencedSamples = pIns->GetSamples(); + + for(std::set<SAMPLEINDEX>::const_iterator sample = referencedSamples.begin(); sample != referencedSamples.end(); sample++) { - const SAMPLEINDEX smp = pIns->Keyboard[i]; - if(smp <= m_pSndFile->GetNumSamples() && m_pSndFile->GetSample(smp).uFlags & CHN_PANNING) + if(*sample <= m_pSndFile->GetNumSamples() && m_pSndFile->GetSample(*sample).uFlags & CHN_PANNING) { smpPanningInUse = true; break; } } + if(smpPanningInUse) { if(Reporting::Confirm(_T("Some of the samples used in the instrument have \"Set Pan\" enabled. " Modified: trunk/OpenMPT/mptrack/Ctrl_smp.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2012-01-14 20:57:16 UTC (rev 1165) +++ trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2012-01-22 16:52:03 UTC (rev 1166) @@ -1755,22 +1755,13 @@ //--------------------------------------- { if((!m_pSndFile) || (m_pSndFile->GetSample(m_nSample).pSample == nullptr)) return; - MODSAMPLE &sample = m_pSndFile->GetSample(m_nSample); //rewbs.timeStretchMods //Ensure m_dTimeStretchRatio is up-to-date with textbox content UpdateData(TRUE); - //Calculate/verify samplerate at C5. - long lSampleRate = sample.GetSampleRate(m_pSndFile->GetType()); - if(lSampleRate <= 0) - lSampleRate = 8363; - //Open dialog - CPSRatioCalc dlg(sample.nLength, lSampleRate, - m_pSndFile->m_nMusicSpeed, m_pSndFile->m_nMusicTempo, - m_pSndFile->m_nDefaultRowsPerBeat, m_pSndFile->m_nTempoMode, - m_dTimeStretchRatio, this); + CPSRatioCalc dlg(*m_pSndFile, m_nSample, m_dTimeStretchRatio, this); if (dlg.DoModal() != IDOK) return; //Update ratio value&textbox @@ -2571,8 +2562,13 @@ { if (IsLocked()) return; int n = m_ComboAutoVib.GetCurSel(); - if (n >= 0) m_pSndFile->GetSample(m_nSample).nVibType = (BYTE)n; - m_pModDoc->SetModified(); + if (n >= 0) + { + m_pSndFile->GetSample(m_nSample).nVibType = (BYTE)n; + + PropagateAutoVibratoChanges(); + m_pModDoc->SetModified(); + } } @@ -2586,6 +2582,8 @@ if ((n >= lmin) && (n <= lmax)) { m_pSndFile->GetSample(m_nSample).nVibDepth = (BYTE)n; + + PropagateAutoVibratoChanges(); m_pModDoc->SetModified(); } } @@ -2601,6 +2599,8 @@ if ((n >= lmin) && (n <= lmax)) { m_pSndFile->GetSample(m_nSample).nVibSweep = (BYTE)n; + + PropagateAutoVibratoChanges(); m_pModDoc->SetModified(); } } @@ -2616,6 +2616,8 @@ if ((n >= lmin) && (n <= lmax)) { m_pSndFile->GetSample(m_nSample).nVibRate = (BYTE)n; + + PropagateAutoVibratoChanges(); m_pModDoc->SetModified(); } } @@ -3222,3 +3224,35 @@ } } } + + +// When changing auto vibrato properties, propagate them to other samples of the same instrument in XM edit mode. +void CCtrlSamples::PropagateAutoVibratoChanges() const +//---------------------------------------------------- +{ + if(!(m_pSndFile->GetType() & MOD_TYPE_XM)) + { + return; + } + + for(INSTRUMENTINDEX i = 1; i < m_pSndFile->GetNumInstruments(); i++) + { + if(m_pSndFile->IsSampleReferencedByInstrument(m_nSample, i)) + { + const std::set<SAMPLEINDEX> referencedSamples = m_pSndFile->Instruments[i]->GetSamples(); + + // Propagate changes to all samples that belong to this instrument. + for(std::set<SAMPLEINDEX>::const_iterator sample = referencedSamples.begin(); sample != referencedSamples.end(); sample++) + { + if(*sample <= m_pSndFile->GetNumSamples()) + { + m_pSndFile->GetSample(*sample).nVibDepth = m_pSndFile->GetSample(m_nSample).nVibDepth; + m_pSndFile->GetSample(*sample).nVibType = m_pSndFile->GetSample(m_nSample).nVibType; + m_pSndFile->GetSample(*sample).nVibRate = m_pSndFile->GetSample(m_nSample).nVibRate; + m_pSndFile->GetSample(*sample).nVibSweep = m_pSndFile->GetSample(m_nSample).nVibSweep; + } + } + } + } + +} Modified: trunk/OpenMPT/mptrack/Ctrl_smp.h =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_smp.h 2012-01-14 20:57:16 UTC (rev 1165) +++ trunk/OpenMPT/mptrack/Ctrl_smp.h 2012-01-22 16:52:03 UTC (rev 1166) @@ -48,6 +48,8 @@ SELECTIONPOINTS GetSelectionPoints(); void SetSelectionPoints(UINT nStart, UINT nEnd); + void PropagateAutoVibratoChanges() const; + public: CCtrlSamples(); ~CCtrlSamples(); Modified: trunk/OpenMPT/mptrack/MainFrm.cpp =================================================================== --- trunk/OpenMPT/mptrack/MainFrm.cpp 2012-01-14 20:57:16 UTC (rev 1165) +++ trunk/OpenMPT/mptrack/MainFrm.cpp 2012-01-22 16:52:03 UTC (rev 1166) @@ -1088,10 +1088,13 @@ if (chnEnv.flags & ENV_ENABLED) { DWORD pos = chnEnv.nEnvPosition; - if(m_pSndFile->IsCompatibleMode(TRK_IMPULSETRACKER) && pos > 0) + if(m_pSndFile->IsCompatibleMode(TRK_IMPULSETRACKER)) { // Impulse Tracker envelope handling (see SndMix.cpp for details) - pos--; + if(pos > 0) + pos--; + else + continue; } p->dwPos[k] = MPTNOTIFY_POSVALID | pos; } Modified: trunk/OpenMPT/mptrack/PSRatioCalc.cpp =================================================================== --- trunk/OpenMPT/mptrack/PSRatioCalc.cpp 2012-01-14 20:57:16 UTC (rev 1165) +++ trunk/OpenMPT/mptrack/PSRatioCalc.cpp 2012-01-22 16:52:03 UTC (rev 1166) @@ -11,12 +11,21 @@ // CPSRatioCalc dialog IMPLEMENT_DYNAMIC(CPSRatioCalc, CDialog) -CPSRatioCalc::CPSRatioCalc(ULONGLONG samples, ULONGLONG sampleRate, UINT speed, UINT tempo, UINT rowsPerBeat, BYTE tempoMode, double ratio, CWnd* pParent /*=NULL*/) +CPSRatioCalc::CPSRatioCalc(const CSoundFile &sndFile, SAMPLEINDEX sample, double ratio, CWnd* pParent /*=NULL*/) : CDialog(CPSRatioCalc::IDD, pParent) - , m_lSamplesOrig(samples), m_nSpeed(speed), m_nTempo(tempo), m_dRatio(ratio), m_nRowsPerBeat(rowsPerBeat), m_nTempoMode(tempoMode) + , sndFile(sndFile), sampleIndex(sample), m_dRatio(ratio) { - //Sample rate will not change. We can calculate original duration once and disgard sampleRate. - m_lMsOrig= static_cast<ULONGLONG>(1000.0*((double)m_lSamplesOrig / sampleRate)); + // 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_nMusicSpeed; + m_nTempo = sndFile.m_nMusicTempo; + + // Sample rate will not change. We can calculate original duration once and disgard sampleRate. + m_lMsOrig = static_cast<ULONGLONG>(1000.0 * ((double)smp.nLength / sampleRate)); CalcSamples(); CalcMs(); CalcRows(); @@ -31,7 +40,8 @@ CWnd* hasFocus = GetFocus(); CDialog::DoDataExchange(pDX); - DDX_Text(pDX, IDC_SAMPLE_LENGTH_ORIGINAL, m_lSamplesOrig); + 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); @@ -62,9 +72,9 @@ void CPSRatioCalc::OnEnChangeSamples() { UpdateData(); - if (m_lSamplesOrig && m_lSamplesOrig) + if (m_lSamplesNew && sndFile.GetSample(sampleIndex).nLength) { - m_dRatio = (double)m_lSamplesNew/(double)m_lSamplesOrig*100; + m_dRatio = (double)m_lSamplesNew / (double)sndFile.GetSample(sampleIndex).nLength * 100; CalcMs(); CalcRows(); UpdateData(FALSE); @@ -76,7 +86,7 @@ UpdateData(); if (m_lMsOrig && m_lMsNew) { - m_dRatio = (double)m_lMsNew/(double)m_lMsOrig*100; + m_dRatio = (double)m_lMsNew / (double)m_lMsOrig * 100; CalcSamples(); CalcRows(); UpdateData(FALSE); @@ -87,9 +97,9 @@ void CPSRatioCalc::OnEnChangeRows() { UpdateData(); - if (m_dRowsOrig && m_dRowsNew && m_nTempo && m_nSpeed) + if (m_dRowsOrig && m_dRowsNew) { - m_dRatio = m_dRowsNew/m_dRowsOrig*100.0; + m_dRatio = m_dRowsNew/m_dRowsOrig * 100.0; CalcSamples(); CalcMs(); UpdateData(FALSE); @@ -100,8 +110,8 @@ void CPSRatioCalc::OnEnChangeSpeed() { UpdateData(); - if (m_nTempo == 0) m_nTempo=1; - if (m_nSpeed == 0) m_nSpeed=1; + if (m_nTempo == 0) m_nTempo = 1; + if (m_nSpeed == 0) m_nSpeed = 1; CalcRows(); UpdateData(FALSE); } @@ -122,39 +132,23 @@ void CPSRatioCalc::CalcSamples() { - m_lSamplesNew = static_cast<ULONGLONG>(m_lSamplesOrig*(m_dRatio/100.0)); + m_lSamplesNew = static_cast<ULONGLONG>(sndFile.GetSample(sampleIndex).nLength * (m_dRatio / 100.0)); return; } void CPSRatioCalc::CalcMs() { - m_lMsNew = static_cast<ULONGLONG>(m_lMsOrig*(m_dRatio/100.0)); + m_lMsNew = static_cast<ULONGLONG>(m_lMsOrig * (m_dRatio / 100.0)); return; } void CPSRatioCalc::CalcRows() { - double rowTime; + double rowTime = sndFile.GetRowDuration(sndFile.m_nMusicSpeed, sndFile.m_nMusicTempo); - switch(m_nTempoMode) { + m_dRowsOrig = (double)m_lMsOrig / rowTime; + m_dRowsNew = m_dRowsOrig*(m_dRatio / 100); - case tempo_mode_alternative: - rowTime = 60000.0 / (1.65625 * (double)(m_nSpeed * m_nTempo)); - break; - - case tempo_mode_modern: - rowTime = 60000.0/(double)m_nTempo / (double)m_nRowsPerBeat; - break; - - case tempo_mode_classic: - default: - rowTime = 2500.0 * (double)m_nSpeed/(double)m_nTempo; - break; - } - - m_dRowsOrig = (double)m_lMsOrig/rowTime; - m_dRowsNew = m_dRowsOrig*(m_dRatio/100); - return; } Modified: trunk/OpenMPT/mptrack/PSRatioCalc.h =================================================================== --- trunk/OpenMPT/mptrack/PSRatioCalc.h 2012-01-14 20:57:16 UTC (rev 1165) +++ trunk/OpenMPT/mptrack/PSRatioCalc.h 2012-01-22 16:52:03 UTC (rev 1166) @@ -8,19 +8,21 @@ public: enum { IDD = IDD_PITCHSHIFT }; - CPSRatioCalc(ULONGLONG samples, ULONGLONG sampleRate, UINT speed, UINT tempo, UINT rowsPerBeat, BYTE tempoMode, double ratio, CWnd* pParent = NULL); // standard constructor + CPSRatioCalc(const CSoundFile &sndFile, SAMPLEINDEX sample, double ratio, CWnd* pParent = NULL); // standard constructor virtual ~CPSRatioCalc(); double m_dRatio; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - ULONGLONG m_lSamplesNew, m_lSamplesOrig; + const CSoundFile &sndFile; + SAMPLEINDEX sampleIndex; + + ULONGLONG m_lSamplesNew; ULONGLONG m_lMsNew, m_lMsOrig; - UINT m_nTempo, m_nSpeed, m_nRowsPerBeat; - BYTE m_nTempoMode; - double m_dRowsOrig, m_dRowsNew; - + double m_dRowsOrig, m_dRowsNew; + UINT m_nTempo, m_nSpeed; + afx_msg void OnEnChangeSamples(); afx_msg void OnEnChangeMs(); afx_msg void OnEnChangeSpeed(); Modified: trunk/OpenMPT/mptrack/dlg_misc.cpp =================================================================== --- trunk/OpenMPT/mptrack/dlg_misc.cpp 2012-01-14 20:57:16 UTC (rev 1165) +++ trunk/OpenMPT/mptrack/dlg_misc.cpp 2012-01-22 16:52:03 UTC (rev 1166) @@ -579,7 +579,7 @@ { m_bKeepMask[aryListBoxSel[n]] = false; } - if ((static_cast<UINT>(nCount) == m_nRemove && nCount > 0) || (m_nRemove == 0 && (m_pSndFile->GetNumChannels() >= nCount + m_pSndFile->GetModSpecifications().channelsMin))) + if ((static_cast<CHANNELINDEX>(nCount) == m_nRemove && nCount > 0) || (m_nRemove == 0 && (m_pSndFile->GetNumChannels() >= nCount + m_pSndFile->GetModSpecifications().channelsMin))) CDialog::OnOK(); else CDialog::OnCancel(); @@ -903,7 +903,8 @@ bool showAll; if ((!m_pSndFile) || (m_nInstrument >= MAX_INSTRUMENTS)) return; - if (m_CbnSample.GetCount() > 0) { + if (m_CbnSample.GetCount() > 0) + { nOldPos = m_CbnSample.GetItemData(m_CbnSample.GetCurSel()); } m_CbnSample.ResetContent(); @@ -980,15 +981,14 @@ //------------------------------------------------------------------- { CHAR s[32] = "--"; - const size_t sizeofS = CountOf(s); if ((lParam >= 0) && (lParam < 3*12) && (m_pSndFile)) { - UINT nSample = m_CbnSample.GetItemData(m_CbnSample.GetCurSel()); + SAMPLEINDEX nSample = m_CbnSample.GetItemData(m_CbnSample.GetCurSel()); UINT nBaseOctave = m_SbOctave.GetPos() & 7; const std::string temp = m_pSndFile->GetNoteName(lParam+1+12*nBaseOctave, m_nInstrument).c_str(); - if(temp.size() >= sizeofS) + if(temp.size() >= CountOf(s)) wsprintf(s, "%s", "..."); else wsprintf(s, "%s", temp.c_str()); @@ -996,13 +996,13 @@ MODINSTRUMENT *pIns = m_pSndFile->Instruments[m_nInstrument]; if ((wParam == KBDNOTIFY_LBUTTONDOWN) && (nSample < MAX_SAMPLES) && (pIns)) { - UINT iNote = nBaseOctave*12+lParam; + UINT iNote = nBaseOctave * 12 + lParam; if (KeyboardMap[iNote] == nSample) { KeyboardMap[iNote] = pIns->Keyboard[iNote]; } else { - KeyboardMap[iNote] = (SAMPLEINDEX)nSample; + KeyboardMap[iNote] = nSample; } /* rewbs.note: I don't think we need this with cust keys. // -> CODE#0009 Modified: trunk/OpenMPT/mptrack/view_com.cpp =================================================================== --- trunk/OpenMPT/mptrack/view_com.cpp 2012-01-14 20:57:16 UTC (rev 1165) +++ trunk/OpenMPT/mptrack/view_com.cpp 2012-01-22 16:52:03 UTC (rev 1166) @@ -275,26 +275,22 @@ if (pSndFile->GetNumInstruments()) { bool first = true; - for (INSTRUMENTINDEX i = 1; i <= pSndFile->GetNumInstruments(); i++) if (pSndFile->Instruments[i]) + for (INSTRUMENTINDEX i = 1; i <= pSndFile->GetNumInstruments(); i++) { - const MODINSTRUMENT *pIns = pSndFile->Instruments[i]; - for (size_t j = 0; j < CountOf(pIns->Keyboard); j++) + if (pSndFile->IsSampleReferencedByInstrument(iSmp + 1, i)) { - if (pIns->Keyboard[j] == (iSmp + 1)) - { - if (!first) strcat(s, ","); - first = false; + if (!first) strcat(s, ","); + first = false; - wsprintf(stmp, "%d", i); - strcat(s, stmp); + wsprintf(stmp, "%d", i); + strcat(s, stmp); + + if (strlen(s) > sizeof(s) - 10) + { + strcat(s, "..."); break; } } - if (strlen(s) > sizeof(s) - 10) - { - strcat(s, "..."); - break; - } } } break; @@ -363,18 +359,10 @@ case INSLIST_SAMPLES: if (pIns) { - std::set<SAMPLEINDEX> referencedSamples; - for(size_t i = 0; i < CountOf(pIns->Keyboard); i++) - { - // 0 isn't a sample. - if(pIns->Keyboard[i] != 0) - { - referencedSamples.insert(pIns->Keyboard[i]); - } - } + const std::set<SAMPLEINDEX> referencedSamples = pIns->GetSamples(); bool first = true; - for(std::set<SAMPLEINDEX>::iterator iter = referencedSamples.begin(); iter != referencedSamples.end(); iter++) + for(std::set<SAMPLEINDEX>::const_iterator sample = referencedSamples.begin(); sample != referencedSamples.end(); sample++) { if(!first) strcat(s, ","); first = false; @@ -386,7 +374,7 @@ break; } - wsprintf(s + l, "%d", *iter); + wsprintf(s + l, "%d", *sample); } } break; Modified: trunk/OpenMPT/soundlib/Fastmix.cpp =================================================================== --- trunk/OpenMPT/soundlib/Fastmix.cpp 2012-01-14 20:57:16 UTC (rev 1165) +++ trunk/OpenMPT/soundlib/Fastmix.cpp 2012-01-22 16:52:03 UTC (rev 1166) @@ -1811,7 +1811,7 @@ pMixR = pOutR; } - if (pPlugin->Info.dwInputRouting & MIXPLUG_INPUTF_BYPASS) + if (pPlugin->IsBypassed()) { const FLOAT * const pInL = pState->pOutBufferL; const FLOAT * const pInR = pState->pOutBufferR; @@ -1836,8 +1836,6 @@ // -float CSoundFile::m_nMaxSample = 0; - VOID CSoundFile::StereoMixToFloat(const int *pSrc, float *pOut1, float *pOut2, UINT nCount) //----------------------------------------------------------------------------------------- { Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp =================================================================== --- trunk/OpenMPT/soundlib/Snd_fx.cpp 2012-01-14 20:57:16 UTC (rev 1165) +++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2012-01-22 16:52:03 UTC (rev 1166) @@ -490,15 +490,7 @@ nSpeedCount += memory.musicSpeed; - switch(m_nTempoMode) - { - case tempo_mode_alternative: - memory.elapsedTime += 60000.0 / (1.65625 * (double)(memory.musicSpeed * memory.musicTempo)); break; - case tempo_mode_modern: - memory.elapsedTime += 60000.0 / (double)memory.musicTempo / (double)m_nCurrentRowsPerBeat; break; - case tempo_mode_classic: default: - memory.elapsedTime += (2500.0 * (double)nSpeedCount) / (double)memory.musicTempo; - } + memory.elapsedTime += GetRowDuration(nSpeedCount, memory.musicTempo); } if(retval.targetReached || endOrder == ORDERINDEX_INVALID || endRow == ROWINDEX_INVALID) @@ -568,8 +560,6 @@ void CSoundFile::InstrumentChange(MODCHANNEL *pChn, UINT instr, bool bPorta, bool bUpdVol, bool bResetEnv) //-------------------------------------------------------------------------------------------------------- { - bool bInstrumentChanged = false; - if (instr >= MAX_INSTRUMENTS) return; MODINSTRUMENT *pIns = Instruments[instr]; MODSAMPLE *pSmp = &Samples[instr]; @@ -577,7 +567,7 @@ if(note == NOTE_NONE && IsCompatibleMode(TRK_IMPULSETRACKER)) return; - if ((pIns) && (note) && (note <= 128)) + if (pIns != nullptr && note != NOTE_NONE && NOTE_IS_VALID(note)) { if(bPorta && pIns == pChn->pModInstrument && (pChn->pModSample != nullptr && pChn->pModSample->pSample != nullptr) && IsCompatibleMode(TRK_IMPULSETRACKER)) { @@ -611,11 +601,11 @@ UINT n = pIns->Keyboard[note - 1]; pSmp = ((n) && (n < MAX_SAMPLES)) ? &Samples[n] : nullptr; } - } else - if (GetNumInstruments()) + } else if (GetNumInstruments()) { + // No valid instrument, or not a valid note. if (note >= NOTE_MIN_SPECIAL) return; - pSmp = NULL; + pSmp = nullptr; } const bool bNewTuning = (GetType() == MOD_TYPE_MPT && pIns && pIns->pTuning); @@ -625,13 +615,11 @@ return; bool returnAfterVolumeAdjust = false; - // bInstrumentChanged is used for IT carry-on env option - if (pIns != pChn->pModInstrument) - { - bInstrumentChanged = true; - // we will set the new instrument later. - } - else + + // instrumentChanged is used for IT carry-on env option + bool instrumentChanged = (pIns != pChn->pModInstrument); + + if(!instrumentChanged) { // Special XM hack if ((bPorta) && (GetType() & (MOD_TYPE_XM|MOD_TYPE_MT2)) && (pIns) @@ -645,19 +633,19 @@ // IT Compatibility: Envelope pickup after SCx cut // Test case: cut-carry.it - if(pChn->nInc == 0 && IsCompatibleMode(TRK_IMPULSETRACKER)) + if(pChn->nInc == 0 && (GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT))) { - bInstrumentChanged = true; + instrumentChanged = true; } // XM compatibility: new instrument + portamento = ignore new instrument number, but reload old instrument settings (the world of XM is upside down...) // And this does *not* happen if volume column portamento is used together with note delay... (handled in ProcessEffects(), where all the other note delay stuff is.) // Test case: porta-delay.xm - if(bInstrumentChanged && bPorta && IsCompatibleMode(TRK_FASTTRACKER2)) + if(instrumentChanged && bPorta && IsCompatibleMode(TRK_FASTTRACKER2)) { pIns = pChn->pModInstrument; pSmp = pChn->pModSample; - bInstrumentChanged = false; + instrumentChanged = false; } else { pChn->pModInstrument = pIns; @@ -706,10 +694,10 @@ if ((!bPorta) || (!(GetType() & (MOD_TYPE_IT|MOD_TYPE_MPT))) || (m_dwSongFlags & SONG_ITCOMPATGXX) || (!pChn->nLength) || ((pChn->dwFlags & CHN_NOTEFADE) && (!pChn->nFadeOutVol)) //IT compatibility tentative fix: Reset envelopes when instrument changes. - || (IsCompatibleMode(TRK_IMPULSETRACKER) && bInstrumentChanged)) + || (IsCompatibleMode(TRK_IMPULSETRACKER) && instrumentChanged)) { pChn->dwFlags |= CHN_FASTVOLRAMP; - if ((GetType() & (MOD_TYPE_IT|MOD_TYPE_MPT)) && (!bInstrumentChanged) && (pIns) && (!(pChn->dwFlags & (CHN_KEYOFF|CHN_NOTEFADE)))) + if ((GetType() & (MOD_TYPE_IT|MOD_TYPE_MPT)) && (!instrumentChanged) && (pIns) && (!(pChn->dwFlags & (CHN_KEYOFF|CHN_NOTEFADE)))) { if (!(pIns->VolEnv.dwFlags & ENV_CARRY)) ResetChannelEnvelope(pChn->VolEnv); if (!(pIns->PanEnv.dwFlags & ENV_CARRY)) ResetChannelEnvelope(pChn->PanEnv); @@ -756,7 +744,7 @@ //IT compatibility tentative fix: Don't change bidi loop direction when //no sample nor instrument is changed. - if(IsCompatibleMode(TRK_ALLTRACKERS) && pSmp == pChn->pModSample && !bInstrumentChanged) + if(IsCompatibleMode(TRK_ALLTRACKERS) && pSmp == pChn->pModSample && !instrumentChanged) pChn->dwFlags = (pChn->dwFlags & (CHN_CHANNELFLAGS | CHN_PINGPONGFLAG)) | (pSmp->uFlags & CHN_SAMPLEFLAGS); else pChn->dwFlags = (pChn->dwFlags & CHN_CHANNELFLAGS) | (pSmp->uFlags & CHN_SAMPLEFLAGS); @@ -892,7 +880,7 @@ else { pChn->nPortamentoDest = pIns->pTuning->GetStepDistance(pChn->nNote, pChn->m_PortamentoFineSteps, note, 0); - //Here pCnh->nPortamentoDest means 'steps to slide'. + //Here pChn->nPortamentoDest means 'steps to slide'. pChn->m_PortamentoFineSteps = -pChn->nPortamentoDest; } } @@ -3901,7 +3889,7 @@ //---------------------------------------- { MODCHANNEL *pChn = &Chn[nChn]; - const bool bKeyOn = (pChn->dwFlags & CHN_KEYOFF) ? false : true; + const bool bKeyOn = !(pChn->dwFlags & CHN_KEYOFF); pChn->dwFlags |= CHN_KEYOFF; //if ((!pChn->pModInstrument) || (!(pChn->VolEnv.flags & CHN_VOLENV))) if ((pChn->pModInstrument) && (!(pChn->VolEnv.flags & ENV_ENABLED))) @@ -4176,7 +4164,7 @@ //------------------------------------------------------------------------------- { if ((!note) || (note >= NOTE_MIN_SPECIAL)) return 0; - if (m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT|MOD_TYPE_S3M|MOD_TYPE_STM|MOD_TYPE_MDL|MOD_TYPE_ULT|MOD_TYPE_WAV + if (GetType() & (MOD_TYPE_IT|MOD_TYPE_MPT|MOD_TYPE_S3M|MOD_TYPE_STM|MOD_TYPE_MDL|MOD_TYPE_ULT|MOD_TYPE_WAV |MOD_TYPE_FAR|MOD_TYPE_DMF|MOD_TYPE_PTM|MOD_TYPE_AMS|MOD_TYPE_DBM|MOD_TYPE_AMF|MOD_TYPE_PSM|MOD_TYPE_J2B|MOD_TYPE_IMF)) { note--; @@ -4191,7 +4179,7 @@ //8363 * freq[note%12] / nC5Speed * 2^(5-note/12) } } else - if (m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2)) + if (GetType() & (MOD_TYPE_XM|MOD_TYPE_MT2)) { if (note < 13) note = 13; note -= 13; @@ -4207,8 +4195,7 @@ UINT roct = note / 12; int rfine = finetune / 16; int i = rnote + rfine + 8; - if (i < 0) i = 0; - if (i >= 104) i = 103; + Limit(i , 0, 103); UINT per1 = XMPeriodTable[i]; if ( finetune < 0 ) { @@ -4330,19 +4317,18 @@ PLUGINDEX CSoundFile::GetActiveInstrumentPlugin(CHANNELINDEX nChn, PluginMutePriority respectMutes) const //------------------------------------------------------------------------------------------------------- { - const MODCHANNEL *pChn = &Chn[nChn]; // Unlike channel settings, pModInstrument is copied from the original chan to the NNA chan, // so we don't need to worry about finding the master chan. PLUGINDEX nPlugin = 0; - if (pChn && pChn->pModInstrument) + if (Chn[nChn].pModInstrument) { - if (respectMutes == RespectMutes && pChn->pModSample && (pChn->pModSample->uFlags & CHN_MUTE)) + if (respectMutes == RespectMutes && Chn[nChn].pModSample && (Chn[nChn].pModSample->uFlags & CHN_MUTE)) { nPlugin = 0; } else { - nPlugin = pChn->pModInstrument->nMixPlug; + nPlugin = Chn[nChn].pModInstrument->nMixPlug; } } return nPlugin; Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2012-01-14 20:57:16 UTC (rev 1165) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2012-01-22 16:52:03 UTC (rev 1166) @@ -469,7 +469,6 @@ m_nDefaultRowsPerMeasure = m_nCurrentRowsPerMeasure = (CMainFrame::GetSettings().m_nRowHighlightMeasures >= m_nDefaultRowsPerBeat) ? CMainFrame::GetSettings().m_nRowHighlightMeasures : m_nDefaultRowsPerBeat * 4; m_nTempoMode = tempo_mode_classic; m_bIsRendering = false; - m_nMaxSample = 0; m_ModFlags = 0; m_bITBidiMode = false; @@ -2807,6 +2806,24 @@ } +// Get the duration of a row in milliseconds, based on the current rows per beat and given speed and tempo settings. +double CSoundFile::GetRowDuration(UINT speed, UINT tempo) const +//------------------------------------------------------------- +{ + switch(m_nTempoMode) + { + case tempo_mode_alternative: + return 60000.0 / (1.65625 * static_cast<double>(speed * tempo)); + case tempo_mode_modern: + // XXX We cannot calculate any row delays with this, since speed is not considered! + return 60000.0 / static_cast<double>(tempo) / static_cast<double>(m_nCurrentRowsPerBeat); + case tempo_mode_classic: + default: + return (2500.0 * static_cast<double>(speed)) / static_cast<double>(tempo); + } +} + + const CModSpecifications& CSoundFile::GetModSpecifications(const MODTYPE type) //---------------------------------------------------------------------------- { Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2012-01-14 20:57:16 UTC (rev 1165) +++ trunk/OpenMPT/soundlib/Sndfile.h 2012-01-22 16:52:03 UTC (rev 1166) @@ -15,6 +15,7 @@ #include "mod_specifications.h" #include <vector> #include <bitset> +#include <set> #include "midi.h" #include "Snd_defs.h" #include "Endianness.h" @@ -232,6 +233,7 @@ bool HasValidMIDIChannel() const { return (nMidiChannel >= 1 && nMidiChannel <= 17); } + // Get a reference to a specific envelope of this instrument INSTRUMENTENVELOPE &GetEnvelope(enmEnvelopeTypes envType) { switch(envType) @@ -246,6 +248,23 @@ } } + // Get a set of all samples referenced by this instrument + std::set<SAMPLEINDEX> GetSamples() const + { + std::set<SAMPLEINDEX> referencedSamples; + + for(size_t i = 0; i < CountOf(Keyboard); i++) + { + // 0 isn't a sample. + if(Keyboard[i] != 0) + { + referencedSamples.insert(Keyboard[i]); + } + } + + return referencedSamples; + } + }; //MODINSTRUMENT; @@ -736,7 +755,6 @@ public: // Static Members static UINT m_nXBassDepth, m_nXBassRange; - static float m_nMaxSample; static UINT m_nReverbDepth, gnReverbType; static UINT m_nProLogicDepth, m_nProLogicDelay; static UINT m_nStereoSeparation; @@ -795,9 +813,9 @@ MODSAMPLE Samples[MAX_SAMPLES]; // Sample Headers public: MODINSTRUMENT *Instruments[MAX_INSTRUMENTS]; // Instrument Headers - CHAR m_szNames[MAX_SAMPLES][MAX_SAMPLENAME]; // Song and sample names MODMIDICFG m_MidiCfg; // Midi macro config table SNDMIXPLUGIN m_MixPlugins[MAX_MIXPLUGINS]; // Mix plugins + CHAR m_szNames[MAX_SAMPLES][MAX_SAMPLENAME]; // Song and sample names CHAR CompressionTable[16]; // ADPCM compression LUT std::bitset<MAX_BASECHANNELS> m_bChannelMuteTogglePending; @@ -859,6 +877,8 @@ //Returns song length in seconds. DWORD GetSongTime() { return static_cast<DWORD>((m_nTempoMode == tempo_mode_alternative) ? GetLength(eNoAdjust).duration + 1.0 : GetLength(eNoAdjust).duration + 0.5); } + double GetRowDuration(UINT speed, UINT tempo) const; + // A repeat count value of -1 means infinite loop void SetRepeatCount(int n) { m_nRepeatCount = n; } int GetRepeatCount() const { return m_nRepeatCount; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2012-01-22 16:59:44
|
Revision: 1167 http://modplug.svn.sourceforge.net/modplug/?rev=1167&view=rev Author: saga-games Date: 2012-01-22 16:59:37 +0000 (Sun, 22 Jan 2012) Log Message: ----------- [Mod] New XM and IT files have compatible playback mode enabled by default. [Imp] Rewrote MOD magic parsing code a bit; can handle anything from 1CHN to 99CH / 99CN now. [Ref] Reference vs pointer refactoring in the J2B loader. [Mod] OpenMPT: Version is now 1.20.00.64 Modified Paths: -------------- trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/version.h trunk/OpenMPT/soundlib/Load_mod.cpp trunk/OpenMPT/soundlib/load_j2b.cpp Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2012-01-22 16:52:03 UTC (rev 1166) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2012-01-22 16:59:37 UTC (rev 1167) @@ -187,12 +187,6 @@ } - // Refresh mix levels now that the correct mod type has been set - m_SndFile.m_nMixLevels = m_SndFile.GetModSpecifications().defaultMixLevels; - m_SndFile.m_pConfig->SetMixLevels(m_SndFile.m_nMixLevels); - // ...and the order length - m_SndFile.Order.resize(min(ModSequenceSet::s_nCacheSize, m_SndFile.GetModSpecifications().ordersMax)); - ReinitRecordState(); InitializeMod(); SetModifiedFlag(FALSE); @@ -687,6 +681,12 @@ break; } + // Refresh mix levels now that the correct mod type has been set + m_SndFile.m_nMixLevels = m_SndFile.GetModSpecifications().defaultMixLevels; + m_SndFile.m_pConfig->SetMixLevels(m_SndFile.m_nMixLevels); + // ...and the order length + m_SndFile.Order.resize(min(ModSequenceSet::s_nCacheSize, m_SndFile.GetModSpecifications().ordersMax)); + if (m_SndFile.Order[0] >= m_SndFile.Patterns.Size()) m_SndFile.Order[0] = 0; @@ -713,6 +713,11 @@ m_SndFile.m_nSamplePreAmp = m_SndFile.m_nVSTiVolume = 128; }*/ + if(m_SndFile.GetType() & (MOD_TYPE_IT | MOD_TYPE_XM)) + { + m_SndFile.SetModFlag(MSF_COMPATIBLE_PLAY, true); + } + for (CHANNELINDEX nChn = 0; nChn < MAX_BASECHANNELS; nChn++) { m_SndFile.ChnSettings[nChn].dwFlags = 0; @@ -868,7 +873,7 @@ UINT CModDoc::GetPlaybackMidiChannel(const MODINSTRUMENT *pIns, CHANNELINDEX nChn) const -//--------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------- { if(pIns->nMidiChannel == MidiMappedChannel) { @@ -1462,14 +1467,14 @@ //------------------------------------------------ { MODINSTRUMENT *pIns; - if ((!nIns) || (nIns > m_SndFile.m_nInstruments)) return 0; + if ((!nIns) || (nIns > m_SndFile.GetNumInstruments())) return 0; pIns = m_SndFile.Instruments[nIns]; if (pIns) { for (UINT i=0; i<NOTE_MAX; i++) { UINT n = pIns->Keyboard[i]; - if ((n) && (n <= m_SndFile.m_nSamples)) return n; + if ((n) && (n <= m_SndFile.GetNumSamples())) return n; } } return 0; Modified: trunk/OpenMPT/mptrack/version.h =================================================================== --- trunk/OpenMPT/mptrack/version.h 2012-01-22 16:52:03 UTC (rev 1166) +++ trunk/OpenMPT/mptrack/version.h 2012-01-22 16:59:37 UTC (rev 1167) @@ -15,7 +15,7 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 20 #define VER_MINOR 00 -#define VER_MINORMINOR 63 +#define VER_MINORMINOR 64 //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/Load_mod.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_mod.cpp 2012-01-22 16:52:03 UTC (rev 1166) +++ trunk/OpenMPT/soundlib/Load_mod.cpp 2012-01-22 16:59:37 UTC (rev 1167) @@ -271,22 +271,25 @@ dwMemPos = 20; m_nSamples = 31; m_nChannels = 4; + pMagic = (PMODMAGIC)(lpStream + dwMemPos + sizeof(MODSAMPLEHEADER) * 31); + // Check Mod Magic memcpy(s, pMagic->Magic, 4); if ((IsMagic(s, "M.K.")) || (IsMagic(s, "M!K!")) - || (IsMagic(s, "M&K!")) || (IsMagic(s, "N.T.")) || (IsMagic(s, "FEST"))) m_nChannels = 4; else - if ((IsMagic(s, "CD81")) || (IsMagic(s, "OKTA"))) m_nChannels = 8; else - if ((s[0]=='F') && (s[1]=='L') && (s[2]=='T') && (s[3]>='4') && (s[3]<='9')) m_nChannels = s[3] - '0'; else - if ((s[0]>='4') && (s[0]<='9') && (s[1]=='C') && (s[2]=='H') && (s[3]=='N')) m_nChannels = s[0] - '0'; else - if ((s[0]=='1') && (s[1]>='0') && (s[1]<='9') && (s[2]=='C') && (s[3]=='H')) m_nChannels = s[1] - '0' + 10; else - if ((s[0]=='2') && (s[1]>='0') && (s[1]<='9') && (s[2]=='C') && (s[3]=='H')) m_nChannels = s[1] - '0' + 20; else - if ((s[0]=='3') && (s[1]>='0') && (s[1]<='2') && (s[2]=='C') && (s[3]=='H')) m_nChannels = s[1] - '0' + 30; else - if ((s[0]=='T') && (s[1]=='D') && (s[2]=='Z') && (s[3]>='4') && (s[3]<='9')) m_nChannels = s[3] - '0'; else - if (IsMagic(s,"16CN")) m_nChannels = 16; else - if (IsMagic(s,"32CN")) m_nChannels = 32; else m_nSamples = 15; + || (IsMagic(s, "M&K!")) || (IsMagic(s, "N.T.")) || (IsMagic(s, "FEST"))) m_nChannels = 4; + else if ((IsMagic(s, "CD81")) || (IsMagic(s, "OKTA"))) m_nChannels = 8; + + else if (!memcmp(s, "FLT", 3) && s[3] >= '4' && s[3] <= '9') m_nChannels = s[3] - '0'; + else if (s[0] >= '1' && s[0] <= '9' && !memcmp(s + 1, "CHN", 3)) m_nChannels = s[0] - '0'; + else if (s[0] >= '1' && s[0] <= '9' && s[1]>='0' && s[1] <= '9' && (!memcmp(s + 2, "CH", 2) || !memcmp(s + 2, "CN", 2))) m_nChannels = s[0] * 10 + s[1] - '0'; + else if (!memcmp(s, "TDZ", 3) && s[3] >= '4' && s[3] <= '9') m_nChannels = s[3] - '0'; + else m_nSamples = 15; // Ultimate SoundTracker MODs + + LimitMax(m_nChannels, MAX_BASECHANNELS); + // Startrekker 8 channel mod (needs special treatment, see below) - bool bFLT8 = IsMagic(s, "FLT8"); + bool isFLT8 = IsMagic(s, "FLT8"); // Only apply VBlank tests to M.K. (ProTracker) modules. const bool bMdKd = IsMagic(s, "M.K."); @@ -372,10 +375,10 @@ if (i >= nbpbuggy2) nbpbuggy2 = i+1; // from mikmod: if the file says FLT8, but the orderlist has odd numbers, it's probably really an FLT4 - if(bFLT8 && (Order[iord] & 1)) + if(isFLT8 && (Order[iord] & 1)) { m_nChannels = 4; - bFLT8 = false; + isFLT8 = false; } // chances are very high that we're dealing with a non-MOD file here. @@ -383,7 +386,7 @@ return false; } - if(bFLT8) + if(isFLT8) { // FLT8 has only even order items, so divide by two. for(ORDERINDEX nOrd = 0; nOrd < Order.GetLength(); nOrd++) @@ -421,10 +424,10 @@ // Setup channel pan positions and volume SetupMODPanning(); - const CHANNELINDEX nMaxChn = (bFLT8) ? 4 : m_nChannels; // 4 channels per pattern in FLT8 format. - if(bFLT8) nbp++; // as one logical pattern consists of two real patterns in FLT8 format, the highest pattern number has to be increased by one. - bool bHasTempoCommands = false; // for detecting VBlank MODs - bool bLeftPanning = false, bExtendedPanning = false; // for detecting 800-880 panning + const CHANNELINDEX nMaxChn = (isFLT8) ? 4 : m_nChannels; // 4 channels per pattern in FLT8 format. + if(isFLT8) nbp++; // as one logical pattern consists of two real patterns in FLT8 format, the highest pattern number has to be increased by one. + bool hasTempoCommands = false; // for detecting VBlank MODs + bool leftPanning = false, extendedPanning = false; // for detecting 800-880 panning // Reading patterns for (PATTERNINDEX ipat = 0; ipat < nbp; ipat++) @@ -434,7 +437,7 @@ if (dwMemPos + nMaxChn * 256 > dwMemLength) break; MODCOMMAND *m; - if(bFLT8) + if(isFLT8) { if((ipat & 1) == 0) { @@ -455,7 +458,7 @@ for(ROWINDEX nRow = 0; nRow < 64; nRow++) { - if(bFLT8) + if(isFLT8) { // FLT8: either write to channel 1 to 4 (even patterns) or 5 to 8 (odd patterns). m = Patterns[ipat >> 1] + nRow * 8 + ((ipat & 1) ? 4 : 0); @@ -471,12 +474,12 @@ if ((m->command) || (m->param)) ConvertModCommand(m); if (m->command == CMD_TEMPO && m->param < 100) - bHasTempoCommands = true; + hasTempoCommands = true; if (m->command == CMD_PANNING8 && m->param < 0x80) - bLeftPanning = true; + leftPanning = true; if (m->command == CMD_PANNING8 && m->param > 0x80 && m->param != 0xA4) - bExtendedPanning = true; - if (m->note == NOTE_NONE && m->instr > 0 && !bFLT8) + extendedPanning = true; + if (m->note == NOTE_NONE && m->instr > 0 && !isFLT8) { if(lastInstrument[nChn] > 0 && lastInstrument[nChn] != m->instr) { @@ -532,8 +535,8 @@ // below 100 BPM are taken into account. Furthermore, only M.K. (ProTracker) // modules are checked. // The same check is also applied to original Ultimate Soundtracker 15 sample mods. - const bool bVBlank = ((bMdKd && bHasTempoCommands && GetSongTime() >= 10 * 60) || m_nSamples == 15); - const bool b7BitPanning = bLeftPanning && !bExtendedPanning; + const bool bVBlank = ((bMdKd && hasTempoCommands && GetSongTime() >= 10 * 60) || m_nSamples == 15); + const bool b7BitPanning = leftPanning && !extendedPanning; if(bVBlank || b7BitPanning) { Patterns.ForEachModCommand(FixMODPatterns(bVBlank, b7BitPanning)); Modified: trunk/OpenMPT/soundlib/load_j2b.cpp =================================================================== --- trunk/OpenMPT/soundlib/load_j2b.cpp 2012-01-22 16:52:03 UTC (rev 1166) +++ trunk/OpenMPT/soundlib/load_j2b.cpp 2012-01-22 16:59:37 UTC (rev 1167) @@ -387,53 +387,55 @@ // Convert envelope data from a RIFF AM module (new format) to MPT envelope data. -void Convert_RIFF_AM_Envelope(const AMINST_ENVELOPE *pAMEnv, INSTRUMENTENVELOPE *pMPTEnv, const enmEnvelopeTypes env) -//------------------------------------------------------------------------------------------------------------------- +void Convert_RIFF_AM_Envelope(const AMINST_ENVELOPE *pAMEnv, MODINSTRUMENT *instr, enmEnvelopeTypes env) +//------------------------------------------------------------------------------------------------------ { - if(pAMEnv == nullptr || pMPTEnv == nullptr) + if(pAMEnv == nullptr || instr == nullptr) return; if(pAMEnv->numpoints == 0xFF || pAMEnv->numpoints == 0x00) return; + INSTRUMENTENVELOPE &mptEnv = instr->GetEnvelope(env); + uint16 flags = LittleEndianW(pAMEnv->flags); - pMPTEnv->dwFlags = (flags & AMENV_ENABLED) ? ENV_ENABLED : 0; - if(flags & AMENV_SUSTAIN) pMPTEnv->dwFlags |= ENV_SUSTAIN; - if(flags & AMENV_LOOP) pMPTEnv->dwFlags |= ENV_LOOP; + mptEnv.dwFlags = (flags & AMENV_ENABLED) ? ENV_ENABLED : 0; + if(flags & AMENV_SUSTAIN) mptEnv.dwFlags |= ENV_SUSTAIN; + if(flags & AMENV_LOOP) mptEnv.dwFlags |= ENV_LOOP; - pMPTEnv->nNodes = min(pAMEnv->numpoints + 1, 10); + mptEnv.nNodes = min(pAMEnv->numpoints + 1, 10); - pMPTEnv->nSustainStart = pMPTEnv->nSustainEnd = pAMEnv->suslooppoint; - if(pMPTEnv->nSustainStart > pMPTEnv->nNodes) - pMPTEnv->dwFlags &= ~ENV_SUSTAIN; + mptEnv.nSustainStart = mptEnv.nSustainEnd = pAMEnv->suslooppoint; + if(mptEnv.nSustainStart > mptEnv.nNodes) + mptEnv.dwFlags &= ~ENV_SUSTAIN; - pMPTEnv->nLoopStart = pAMEnv->loopstart; - pMPTEnv->nLoopEnd = pAMEnv->loopend; - if(pMPTEnv->nLoopStart > pMPTEnv->nLoopEnd || pMPTEnv->nLoopStart > pMPTEnv->nNodes) - pMPTEnv->dwFlags &= ~ENV_LOOP; + mptEnv.nLoopStart = pAMEnv->loopstart; + mptEnv.nLoopEnd = pAMEnv->loopend; + if(mptEnv.nLoopStart > mptEnv.nLoopEnd || mptEnv.nLoopStart > mptEnv.nNodes) + mptEnv.dwFlags &= ~ENV_LOOP; for(size_t i = 0; i < 10; i++) { - pMPTEnv->Ticks[i] = LittleEndianW(pAMEnv->values[i].tick >> 4); + mptEnv.Ticks[i] = LittleEndianW(pAMEnv->values[i].tick >> 4); if(i == 0) - pMPTEnv->Ticks[i] = 0; - else if(pMPTEnv->Ticks[i] < pMPTEnv->Ticks[i - 1]) - pMPTEnv->Ticks[i] = pMPTEnv->Ticks[i - 1] + 1; + mptEnv.Ticks[i] = 0; + else if(mptEnv.Ticks[i] < mptEnv.Ticks[i - 1]) + mptEnv.Ticks[i] = mptEnv.Ticks[i - 1] + 1; const uint16 val = LittleEndianW(pAMEnv->values[i].pointval); switch(env) { case ENV_VOLUME: // 0....32767 - pMPTEnv->Values[i] = (BYTE)((val + 1) >> 9); + mptEnv.Values[i] = (BYTE)((val + 1) >> 9); break; case ENV_PITCH: // -4096....4096 - pMPTEnv->Values[i] = (BYTE)((((int16)val) + 0x1001) >> 7); + mptEnv.Values[i] = (BYTE)((((int16)val) + 0x1001) >> 7); break; case ENV_PANNING: // -32768...32767 - pMPTEnv->Values[i] = (BYTE)((((int16)val) + 0x8001) >> 10); + mptEnv.Values[i] = (BYTE)((((int16)val) + 0x8001) >> 10); break; } - pMPTEnv->Values[i] = CLAMP(pMPTEnv->Values[i], ENVELOPE_MIN, ENVELOPE_MAX); + mptEnv.Values[i] = CLAMP(mptEnv.Values[i], ENVELOPE_MIN, ENVELOPE_MAX); } } @@ -679,9 +681,9 @@ pIns->nFadeOut = LittleEndianW(instheader->volenv.fadeout) << 5; - Convert_RIFF_AM_Envelope(&instheader->volenv, &pIns->VolEnv, ENV_VOLUME); - Convert_RIFF_AM_Envelope(&instheader->pitchenv, &pIns->PitchEnv, ENV_PITCH); - Convert_RIFF_AM_Envelope(&instheader->panenv, &pIns->PanEnv, ENV_PANNING); + Convert_RIFF_AM_Envelope(&instheader->volenv, pIns, ENV_VOLUME); + Convert_RIFF_AM_Envelope(&instheader->pitchenv, pIns, ENV_PITCH); + Convert_RIFF_AM_Envelope(&instheader->panenv, pIns, ENV_PANNING); const size_t nTotalSmps = LittleEndianW(instheader->numsamples); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2012-01-28 14:22:49
|
Revision: 1168 http://modplug.svn.sourceforge.net/modplug/?rev=1168&view=rev Author: saga-games Date: 2012-01-28 14:22:41 +0000 (Sat, 28 Jan 2012) Log Message: ----------- [Imp] General Tab: Global volume display is now limited to 0...64 (instead of 0...128) for XM / S3M (http://forum.openmpt.org/index.php?topic=4658.0) [Fix] MIDI Export: Exporting is no longer limited to the first 64 channels. [Imp] MIDI Import: MIDI files with any number of tracks can now be imported (previous limit was 64 tracks). [Fix] MOD Loader: Loading of MODs with a xxCH or xxCN signature broke in previous revision. [Ref] Refactored some more instrument loading / saving code. [Mod] OpenMPT: Version is now 1.20.00.65 Modified Paths: -------------- trunk/OpenMPT/mptrack/Ctrl_gen.cpp trunk/OpenMPT/mptrack/Ctrl_gen.h trunk/OpenMPT/mptrack/MPTHacks.cpp trunk/OpenMPT/mptrack/mod2midi.cpp trunk/OpenMPT/mptrack/version.h trunk/OpenMPT/soundlib/Load_mid.cpp trunk/OpenMPT/soundlib/Load_mod.cpp trunk/OpenMPT/soundlib/Sampleio.cpp Modified: trunk/OpenMPT/mptrack/Ctrl_gen.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_gen.cpp 2012-01-22 16:59:37 UTC (rev 1167) +++ trunk/OpenMPT/mptrack/Ctrl_gen.cpp 2012-01-28 14:22:41 UTC (rev 1168) @@ -104,7 +104,8 @@ m_SpinTempo.SetRange((short)specs.tempoMin, (short)specs.tempoMax); // -! BEHAVIOUR_CHANGE#0016 - m_SpinGlobalVol.SetRange(0, 128); + + m_SpinGlobalVol.SetRange(0, (short)(256 / GetGlobalVolumeFactor())); m_SpinSamplePA.SetRange(0, 2000); m_SpinVSTiVol.SetRange(0, 2000); m_SpinRestartPos.SetRange(0, 255); @@ -183,13 +184,14 @@ } if (dwHint & HINT_MODGENERAL) { - if (!m_bEditsLocked) { + if (!m_bEditsLocked) + { m_EditTitle.SetWindowText(m_pSndFile->m_szNames[0]); wsprintf(s, "%d", m_pSndFile->m_nDefaultTempo); m_EditTempo.SetWindowText(s); wsprintf(s, "%d", m_pSndFile->m_nDefaultSpeed); m_EditSpeed.SetWindowText(s); - wsprintf(s, "%d", m_pSndFile->m_nDefaultGlobalVolume / 2); + wsprintf(s, "%d", m_pSndFile->m_nDefaultGlobalVolume / GetGlobalVolumeFactor()); m_EditGlobalVol.SetWindowText(s); wsprintf(s, "%d", m_pSndFile->m_nRestartPos); m_EditRestartPos.SetWindowText(s); @@ -282,11 +284,13 @@ { CSliderCtrl* pSlider = (CSliderCtrl*) pscroll; - if (pSlider==&m_SliderTempo) { + if (pSlider==&m_SliderTempo) + { int min, max; m_SpinTempo.GetRange(min, max); const UINT tempo = max - m_SliderTempo.GetPos(); - if ((tempo >= m_pSndFile->GetModSpecifications().tempoMin) && (tempo <= m_pSndFile->GetModSpecifications().tempoMax) && (tempo != m_pSndFile->m_nDefaultTempo)) { + if ((tempo >= m_pSndFile->GetModSpecifications().tempoMin) && (tempo <= m_pSndFile->GetModSpecifications().tempoMax) && (tempo != m_pSndFile->m_nDefaultTempo)) + { m_pSndFile->m_nDefaultTempo = tempo; m_pSndFile->m_nMusicTempo = tempo; m_pModDoc->SetModified(); @@ -295,9 +299,11 @@ } } - else if (pSlider==&m_SliderGlobalVol) { + else if (pSlider==&m_SliderGlobalVol) + { const UINT gv = MAX_SLIDER_GLOBAL_VOL - m_SliderGlobalVol.GetPos(); - if ((gv >= 0) && (gv <= MAX_SLIDER_GLOBAL_VOL) && (gv != m_pSndFile->m_nDefaultGlobalVolume)) { + if ((gv >= 0) && (gv <= MAX_SLIDER_GLOBAL_VOL) && (gv != m_pSndFile->m_nDefaultGlobalVolume)) + { m_pSndFile->m_nGlobalVolume = gv; m_pSndFile->m_nDefaultGlobalVolume = gv; m_pModDoc->SetModified(); @@ -306,9 +312,11 @@ } } - else if (pSlider==&m_SliderSamplePreAmp) { + else if (pSlider==&m_SliderSamplePreAmp) + { const UINT spa = MAX_SLIDER_SAMPLE_VOL - m_SliderSamplePreAmp.GetPos(); - if ((spa >= 0) && (spa <= MAX_SLIDER_SAMPLE_VOL) && (spa != m_pSndFile->m_nSamplePreAmp)) { + if ((spa >= 0) && (spa <= MAX_SLIDER_SAMPLE_VOL) && (spa != m_pSndFile->m_nSamplePreAmp)) + { m_pSndFile->m_nSamplePreAmp = spa; if(m_pSndFile->GetType() != MOD_TYPE_MOD) m_pModDoc->SetModified(); @@ -318,7 +326,8 @@ else if (pSlider==&m_SliderVSTiVol) { const UINT vv = MAX_SLIDER_VSTI_VOL - m_SliderVSTiVol.GetPos(); - if ((vv >= 0) && (vv <= MAX_SLIDER_VSTI_VOL) && (vv != m_pSndFile->m_nVSTiVolume)) { + if ((vv >= 0) && (vv <= MAX_SLIDER_VSTI_VOL) && (vv != m_pSndFile->m_nVSTiVolume)) + { m_pSndFile->m_nVSTiVolume = vv; m_pSndFile->RecalculateGainForAllPlugs(); m_pModDoc->SetModified(); @@ -459,13 +468,13 @@ if (s[0]) { UINT n = atoi(s); - Limit(n, 0u, 128u); + Limit(n, 0u, 256u / GetGlobalVolumeFactor()); if (n != (m_pSndFile->m_nDefaultGlobalVolume >> 1)) { m_bEditsLocked=true; m_EditGlobalVol.SetModify(FALSE); - m_pSndFile->m_nDefaultGlobalVolume = n << 1; - m_pSndFile->m_nGlobalVolume = n << 1; + m_pSndFile->m_nDefaultGlobalVolume = n * GetGlobalVolumeFactor(); + m_pSndFile->m_nGlobalVolume = n * GetGlobalVolumeFactor(); m_pModDoc->SetModified(); m_pModDoc->UpdateAllViews(NULL, HINT_MODGENERAL, this); UpdateView(HINT_MODGENERAL, NULL); Modified: trunk/OpenMPT/mptrack/Ctrl_gen.h =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_gen.h 2012-01-22 16:59:37 UTC (rev 1167) +++ trunk/OpenMPT/mptrack/Ctrl_gen.h 2012-01-28 14:22:41 UTC (rev 1168) @@ -38,6 +38,13 @@ private: void setAsDecibels(LPSTR stringToSet, double value, double valueAtZeroDB); + // Determine how the global volume slider should be scaled to actual global volume. + // Display range for XM / S3M should be 0...64, for other formats it's 0...256. + UINT GetGlobalVolumeFactor() + { + return (m_pSndFile->GetType() & (MOD_TYPE_XM | MOD_TYPE_S3M)) ? UINT(MAX_SLIDER_GLOBAL_VOL / 64) : UINT(MAX_SLIDER_GLOBAL_VOL / 128); + } + public: bool m_bEditsLocked; //{{AFX_DATA(CCtrlGeneral) Modified: trunk/OpenMPT/mptrack/MPTHacks.cpp =================================================================== --- trunk/OpenMPT/mptrack/MPTHacks.cpp 2012-01-22 16:59:37 UTC (rev 1167) +++ trunk/OpenMPT/mptrack/MPTHacks.cpp 2012-01-28 14:22:41 UTC (rev 1168) @@ -12,8 +12,6 @@ /* TODO: out-of range sample pre-amp -song flags and properties (just look at the song properties window) -+++/--- orders in XM/MOD sequence comments in XM files AUTOFIX actions! Modified: trunk/OpenMPT/mptrack/mod2midi.cpp =================================================================== --- trunk/OpenMPT/mptrack/mod2midi.cpp 2012-01-22 16:59:37 UTC (rev 1167) +++ trunk/OpenMPT/mptrack/mod2midi.cpp 2012-01-28 14:22:41 UTC (rev 1168) @@ -88,7 +88,9 @@ static int LinearToDLSMidiVolume(int nVolume) //------------------------------------------- { - const float kLin2Mid = 127.0f*127.0f/65536.0f; + const float kLin2Mid = 127.0f * 127.0f / 65536.0f; + //return static_cast<int>(sqrtf(static_cast<float>(nVolume) * kLin2Mid)); + int result; _asm { @@ -339,7 +341,7 @@ RMIDDATACHUNK rmid; MTHDCHUNK mthd; MTRKCHUNK mtrk; - DYNMIDITRACK Tracks[64]; + vector<DYNMIDITRACK> Tracks(m_pSndFile->GetNumChannels()); UINT nMidiChCurPrg[16]; BYTE tmp[256]; CHAR s[256]; @@ -347,15 +349,11 @@ UINT nSpeed; CFile f; - const CHANNELINDEX chnCount = min(64, m_pSndFile->GetNumChannels()); - if(chnCount < m_pSndFile->GetNumChannels()) - Reporting::Information("Note: Only 64 channels will be exported."); - if (!f.Open(m_szFileName, CFile::modeCreate | CFile::modeWrite)) { return FALSE; } - MemsetZero(Tracks); + if (!m_pSndFile->m_nDefaultTempo) m_pSndFile->m_nDefaultTempo = 125; nTickMultiplier = MOD2MIDI_TEMPOFACTOR; const uint16 wPPQN = static_cast<uint16>((m_pSndFile->m_nDefaultTempo*nTickMultiplier) / 5); @@ -367,14 +365,12 @@ mthd.id = 0x6468544d; // "MThd" mthd.len = BigEndian(sizeof(mthd)-8); mthd.wFmt = BigEndianW(1); - mthd.wTrks = static_cast<uint16>(chnCount); // 1 track/channel + mthd.wTrks = static_cast<uint16>(Tracks.size()); // 1 track/channel mthd.wTrks = BigEndianW(mthd.wTrks); //Convert to big endian value. mthd.wDivision = BigEndianW(wPPQN); if (m_bRmi) f.Write(&rmid, sizeof(rmid)); f.Write(&mthd, sizeof(mthd)); - - // Add Song Name on track 0 const CHAR *modTitle = m_pSndFile->GetTitle(); if (modTitle[0]) @@ -384,6 +380,7 @@ Tracks[0].WriteLen(strlen(modTitle)); Tracks[0].Write(modTitle, strlen(modTitle)); } + // Add Song comments on track 0 if ((m_pSndFile->m_lpszSongComments) && (m_pSndFile->m_lpszSongComments[0])) { @@ -392,20 +389,21 @@ Tracks[0].WriteLen(strlen(m_pSndFile->m_lpszSongComments)); Tracks[0].Write(m_pSndFile->m_lpszSongComments, strlen(m_pSndFile->m_lpszSongComments)); } + // Add channel names - for (UINT iInit=0; iInit<chnCount; iInit++) + for (CHANNELINDEX iInit = 0; iInit < m_pSndFile->GetNumChannels(); iInit++) { - PDYNMIDITRACK pTrk = &Tracks[iInit]; + DYNMIDITRACK &track = Tracks[iInit]; lstrcpyn(s, m_pSndFile->ChnSettings[iInit].szName, MAX_CHANNELNAME); - pTrk->nMidiChannel = iInit & 7; + track.nMidiChannel = iInit & 7; if (s[0]) { tmp[0] = 0x00; tmp[1] = 0xff; tmp[2] = 0x03; - pTrk->Write(tmp, 3); - pTrk->WriteLen(strlen(s)); - pTrk->Write(s, strlen(s)); + track.Write(tmp, 3); + track.WriteLen(strlen(s)); + track.Write(s, strlen(s)); } } for (UINT iMidiCh=0; iMidiCh<16; iMidiCh++) @@ -428,7 +426,7 @@ continue; } PatternRow patternRow = m_pSndFile->Patterns[nPat].GetRow(nRow); - for (UINT nChn=0; nChn<chnCount; nChn++) + for (CHANNELINDEX nChn = 0; nChn < m_pSndFile->GetNumChannels(); nChn++) { PDYNMIDITRACK pTrk = &Tracks[nChn]; //MODCOMMAND *m = m_pSndFile->Patterns[nPat].GetpModCommand(nRow, nChn); @@ -534,7 +532,7 @@ } } // Write midi tracks - for (UINT iTrk=0; iTrk<chnCount; iTrk++) + for (UINT iTrk = 0; iTrk < Tracks.size(); iTrk++) { tmp[0] = 0x00; tmp[1] = 0xff; Modified: trunk/OpenMPT/mptrack/version.h =================================================================== --- trunk/OpenMPT/mptrack/version.h 2012-01-22 16:59:37 UTC (rev 1167) +++ trunk/OpenMPT/mptrack/version.h 2012-01-28 14:22:41 UTC (rev 1168) @@ -15,7 +15,7 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 20 #define VER_MINOR 00 -#define VER_MINORMINOR 64 +#define VER_MINORMINOR 65 //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/Load_mid.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_mid.cpp 2012-01-22 16:59:37 UTC (rev 1167) +++ trunk/OpenMPT/soundlib/Load_mid.cpp 2012-01-28 14:22:41 UTC (rev 1168) @@ -28,7 +28,6 @@ #endif #define MIDI_DRUMCHANNEL 10 -#define MIDI_MAXTRACKS 64 //UINT gnMidiImportSpeed = 3; //UINT gnMidiPatternLen = 128; @@ -496,7 +495,7 @@ const MIDITRACKHEADER *pmth; MODCHANNELSTATE chnstate[MAX_BASECHANNELS]; MIDICHANNELSTATE midichstate[16]; - MIDITRACK miditracks[MIDI_MAXTRACKS]; + vector<MIDITRACK> miditracks; DWORD dwMemPos, dwGlobalFlags, tracks, tempo; UINT row, pat, midimastervol; short int division; @@ -545,7 +544,8 @@ pmth = (MIDITRACKHEADER *)(lpStream+dwMemPos); tracks = BigEndianW(pmfh->wTrks); if ((pmth->id != 0x6B72544D) || (!tracks)) return false; - if (tracks > MIDI_MAXTRACKS) tracks = MIDI_MAXTRACKS; + miditracks.resize(tracks); + // Reading File... m_nType = MOD_TYPE_MID; m_nChannels = 32; @@ -553,6 +553,7 @@ m_nInstruments = 0; m_dwSongFlags |= SONG_LINEARSLIDES; m_szNames[0][0] = 0; + // MIDI->MOD Tempo Conversion division = BigEndianW(pmfh->wDivision); if (division < 0) @@ -577,9 +578,8 @@ #endif // Initializing Order.resize(MAX_ORDERS, Order.GetInvalidPatIndex()); - memset(chnstate, 0, sizeof(chnstate)); - memset(miditracks, 0, sizeof(miditracks)); - memset(midichstate, 0, sizeof(midichstate)); + MemsetZero(chnstate); + MemsetZero(midichstate); // Initializing Patterns Order[0] = 0; // Initializing Channels @@ -610,7 +610,7 @@ // Initializing midi tracks miditracks[itrk].ptracks = lpStream+dwMemPos+8; miditracks[itrk].ptrmax = miditracks[itrk].ptracks + len; - miditracks[itrk].nexteventtime = getmidilong(miditracks[itrk].ptracks, miditracks[itrk].ptrmax); + miditracks[itrk].ptracks += ConvertMIDI2Int(miditracks[itrk].nexteventtime, (uint8 *)miditracks[itrk].ptracks, len); #ifdef MIDI_DETAILED_LOG Log(" init time=%d\n", miditracks[itrk].nexteventtime); #endif @@ -673,7 +673,8 @@ case 0xF0: case 0xF7: { - LONG len = getmidilong(ptrk->ptracks, ptrk->ptrmax); + LONG len; + ptrk->ptracks += ConvertMIDI2Int(len, (uint8 *)ptrk->ptracks, (size_t)(ptrk->ptrmax - ptrk->ptracks)); if ((len > 1) && (ptrk->ptracks + len <ptrk->ptrmax) && (ptrk->ptracks[len-1] == 0xF7)) { DWORD dwSysEx1 = 0, dwSysEx2 = 0; @@ -725,7 +726,8 @@ case 0xFF: { UINT i = *(ptrk->ptracks++); - LONG len = getmidilong(ptrk->ptracks, ptrk->ptrmax); + LONG len; + ptrk->ptracks += ConvertMIDI2Int(len, (uint8 *)ptrk->ptracks, (size_t)(ptrk->ptrmax - ptrk->ptracks)); if (ptrk->ptracks+len > ptrk->ptrmax) { // EOF @@ -1106,7 +1108,9 @@ // Process to next event if (ptrk->ptracks) { - ptrk->nexteventtime += getmidilong(ptrk->ptracks, ptrk->ptrmax); + LONG inc; + ptrk->ptracks += ConvertMIDI2Int(inc, (uint8 *)ptrk->ptracks, (size_t)(ptrk->ptrmax - ptrk->ptracks)); + ptrk->nexteventtime += inc; } if (ptrk->ptracks >= ptrk->ptrmax) ptrk->ptracks = NULL; } Modified: trunk/OpenMPT/soundlib/Load_mod.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_mod.cpp 2012-01-22 16:59:37 UTC (rev 1167) +++ trunk/OpenMPT/soundlib/Load_mod.cpp 2012-01-28 14:22:41 UTC (rev 1168) @@ -282,7 +282,7 @@ else if (!memcmp(s, "FLT", 3) && s[3] >= '4' && s[3] <= '9') m_nChannels = s[3] - '0'; else if (s[0] >= '1' && s[0] <= '9' && !memcmp(s + 1, "CHN", 3)) m_nChannels = s[0] - '0'; - else if (s[0] >= '1' && s[0] <= '9' && s[1]>='0' && s[1] <= '9' && (!memcmp(s + 2, "CH", 2) || !memcmp(s + 2, "CN", 2))) m_nChannels = s[0] * 10 + s[1] - '0'; + else if (s[0] >= '1' && s[0] <= '9' && s[1]>='0' && s[1] <= '9' && (!memcmp(s + 2, "CH", 2) || !memcmp(s + 2, "CN", 2))) m_nChannels = (s[0] - '0') * 10 + s[1] - '0'; else if (!memcmp(s, "TDZ", 3) && s[3] >= '4' && s[3] <= '9') m_nChannels = s[3] - '0'; else m_nSamples = 15; // Ultimate SoundTracker MODs @@ -502,26 +502,18 @@ } // Reading samples - bool bSamplesPresent = false; for (UINT ismp = 1; ismp <= m_nSamples; ismp++) if (Samples[ismp].nLength) { - LPSTR p = (LPSTR)(lpStream + dwMemPos); - UINT flags = 0; + UINT flags = RS_PCM8S; if (dwMemPos + 5 <= dwMemLength) { - if (!_strnicmp(p, "ADPCM", 5)) + if (!_strnicmp((LPSTR)(lpStream + dwMemPos), "ADPCM", 5)) { - flags = 3; - p += 5; + flags = RS_ADPCM4; dwMemPos += 5; } } - DWORD dwSize = ReadSample(&Samples[ismp], flags, p, dwMemLength - dwMemPos); - if (dwSize) - { - dwMemPos += dwSize; - bSamplesPresent = true; - } + dwMemPos += ReadSample(&Samples[ismp], flags, (LPSTR)(lpStream + dwMemPos), dwMemLength - dwMemPos); } // Fix VBlank MODs. Arbitrary threshold: 10 minutes. @@ -542,11 +534,7 @@ Patterns.ForEachModCommand(FixMODPatterns(bVBlank, b7BitPanning)); } -#ifdef MODPLUG_TRACKER return true; -#else - return bSamplesPresent; -#endif // MODPLUG_TRACKER } @@ -675,14 +663,19 @@ p[3] = param; } fwrite(s, m_nChannels, 4, f); - } else { //if row does not exist - memset(s, 0, m_nChannels*4); //invent blank row + } else + { + // if row does not exist, invent blank row + memset(s, 0, m_nChannels * 4); fwrite(s, m_nChannels, 4, f); } } //end for all rows - } else { - memset(s, 0, m_nChannels*4); //if pattern does not exist - for (UINT i=0; i<64; i++) { //invent blank pattern + } else + { + // if pattern does not exist, invent blank pattern + memset(s, 0, m_nChannels * 4); + for(size_t i = 0; i < 64; i++) + { fwrite(s, m_nChannels, 4, f); } } @@ -692,7 +685,7 @@ #ifdef MODPLUG_TRACKER if(GetpModDoc() != nullptr) { - for(UINT ipat = nbp; ipat < MAX_PATTERNS; ipat++) + for(UINT ipat = nbp; ipat < Patterns.Size(); ipat++) { if(Patterns[ipat]) { Modified: trunk/OpenMPT/soundlib/Sampleio.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sampleio.cpp 2012-01-22 16:59:37 UTC (rev 1167) +++ trunk/OpenMPT/soundlib/Sampleio.cpp 2012-01-28 14:22:41 UTC (rev 1168) @@ -1808,15 +1808,14 @@ ITSAMPLESTRUCT itss; MODINSTRUMENT *pIns = Instruments[nInstr]; vector<bool> smpcount(GetNumSamples(), false); - UINT smptable[MAX_SAMPLES], smpmap[MAX_SAMPLES]; + vector<SAMPLEINDEX> smptable; + vector<SAMPLEINDEX> smpmap(GetNumSamples() + 1, 0); DWORD dwPos; FILE *f; if ((!pIns) || (!lpszFileName)) return false; if ((f = fopen(lpszFileName, "wb")) == NULL) return false; MemsetZero(buffer); - MemsetZero(smptable); - MemsetZero(smpmap); iti->id = LittleEndian(IT_IMPI); // "IMPI" memcpy(iti->filename, pIns->filename, 12); StringFixer::FixNullString(iti->filename); @@ -1843,20 +1842,15 @@ iti->nos = 0; for (UINT i=0; i<NOTE_MAX; i++) if (pIns->Keyboard[i] < MAX_SAMPLES) { - const UINT smp = pIns->Keyboard[i]; + const SAMPLEINDEX smp = pIns->Keyboard[i]; if (smp && smp <= GetNumSamples() && !smpcount[smp - 1]) { smpcount[smp - 1] = true; - smptable[iti->nos] = smp; - smpmap[smp] = iti->nos; - iti->nos++; + smptable.push_back(smp); + smpmap[smp] = iti->nos++; } - iti->keyboard[i*2] = pIns->NoteMap[i] - 1; -// -> CODE#0019 -// -> DESC="correctly load ITI & XI instruments sample note map" -// iti->keyboard[i*2+1] = smpmap[smp] + 1; - iti->keyboard[i*2+1] = smp ? smpmap[smp] + 1 : 0; -// -! BUG_FIX#0019 + iti->keyboard[i * 2] = pIns->NoteMap[i] - 1; + iti->keyboard[i * 2 + 1] = smp ? smpmap[smp] + 1 : 0; } // Writing Volume envelope if (pIns->VolEnv.dwFlags & ENV_ENABLED) iti->volenv.flags |= 0x01; @@ -1890,7 +1884,7 @@ iti->pitchenv.slb = (BYTE)pIns->PitchEnv.nSustainStart; iti->pitchenv.sle = (BYTE)pIns->PitchEnv.nSustainEnd; // Writing Envelopes data - for (UINT ev=0; ev<25; ev++) + for (UINT ev = 0; ev < 25; ev++) { iti->volenv.data[ev*3] = pIns->VolEnv.Values[ev]; iti->volenv.data[ev*3+1] = pIns->VolEnv.Ticks[ev] & 0xFF; @@ -1972,19 +1966,12 @@ WORD sampleType=0; if (itss.flags | 0x02) sampleType=RS_PCM16S; else sampleType=RS_PCM8S; //8 or 16 bit signed if (itss.flags | 0x04) sampleType |= RSF_STEREO; //mono or stereo - for (UINT k=0; k<iti->nos; k++) + for (UINT k = 0; k < iti->nos; k++) { -//rewbs.enableStereoITI - using eric's code as it is better here. -// -> CODE#0001 -// -> DESC="enable saving stereo ITI" - //UINT nsmp = smptable[k]; - //MODINSTRUMENT *psmp = &Ins[nsmp]; - //WriteSample(f, psmp, (psmp->uFlags & CHN_16BIT) ? RS_PCM16S : RS_PCM8S); const MODSAMPLE *pSmp = &Samples[smptable[k]]; UINT smpflags = (pSmp->uFlags & CHN_16BIT) ? RS_PCM16S : RS_PCM8S; if (pSmp->uFlags & CHN_STEREO) smpflags = (pSmp->uFlags & CHN_16BIT) ? RS_STPCM16S : RS_STPCM8S; WriteSample(f, pSmp, smpflags); -// -! BUG_FIX#0001 } int32 code = 'MPTX'; @@ -2008,7 +1995,7 @@ void ReadInstrumentExtensionField(MODINSTRUMENT* pIns, LPCBYTE& ptr, const int32 code, const int16 size) -//------------------------------------------------------------------------------------------------------------ +//------------------------------------------------------------------------------------------------------ { // get field's address in instrument's header BYTE* fadr = GetInstrumentHeaderFieldPointer(pIns, code, size); @@ -2023,7 +2010,7 @@ void ReadExtendedInstrumentProperty(MODINSTRUMENT* pIns, const int32 code, LPCBYTE& pData, const LPCBYTE pEnd) -//--------------------------------------------------------------------------------------------------------------- +//------------------------------------------------------------------------------------------------------------ { if(pEnd < pData || uintptr_t(pEnd - pData) < 2) return; @@ -2040,7 +2027,7 @@ void ReadExtendedInstrumentProperties(MODINSTRUMENT* pIns, const LPCBYTE pDataStart, const size_t nMemLength) -//-------------------------------------------------------------------------------------------------------------- +//----------------------------------------------------------------------------------------------------------- { if(pIns == 0 || pDataStart == 0 || nMemLength < 4) return; @@ -2332,7 +2319,7 @@ if(pIns->nMidiChannel == MidiMappedChannel) { - pIns->nMidiChannel == 1; + pIns->nMidiChannel = 1; } pIns->nGlobalVol = 64; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2012-02-06 23:55:11
|
Revision: 1172 http://modplug.svn.sourceforge.net/modplug/?rev=1172&view=rev Author: saga-games Date: 2012-02-06 23:55:02 +0000 (Mon, 06 Feb 2012) Log Message: ----------- [Ref] Lots of refactoring regarding to MIDI macros again. Now all MIDI macro operations are in the same class as the MIDI macros themselves, yay. [Ref] Moved around some plugin interface stuff to escape forward referencing hell. Modified Paths: -------------- trunk/OpenMPT/mptrack/AbstractVstEditor.cpp trunk/OpenMPT/mptrack/CleanupSong.cpp trunk/OpenMPT/mptrack/Ctrl_pat.cpp trunk/OpenMPT/mptrack/Ctrl_smp.cpp trunk/OpenMPT/mptrack/MIDIMacroDialog.cpp trunk/OpenMPT/mptrack/MIDIMacroDialog.h trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/Mptrack.cpp trunk/OpenMPT/mptrack/Mptrack.h trunk/OpenMPT/mptrack/TrackerSettings.cpp trunk/OpenMPT/mptrack/View_pat.cpp trunk/OpenMPT/mptrack/Vstplug.h trunk/OpenMPT/mptrack/mptrack.vcproj trunk/OpenMPT/mptrack/mptrack_08.vcproj trunk/OpenMPT/mptrack/mptrack_10.vcxproj trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters trunk/OpenMPT/mptrack/test/test.cpp trunk/OpenMPT/soundlib/Load_it.cpp trunk/OpenMPT/soundlib/Load_itp.cpp trunk/OpenMPT/soundlib/Load_xm.cpp trunk/OpenMPT/soundlib/MIDIMacros.cpp trunk/OpenMPT/soundlib/MIDIMacros.h trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/Sndfile.h Added Paths: ----------- trunk/OpenMPT/soundlib/PlugInterface.h Modified: trunk/OpenMPT/mptrack/AbstractVstEditor.cpp =================================================================== --- trunk/OpenMPT/mptrack/AbstractVstEditor.cpp 2012-02-06 18:26:37 UTC (rev 1171) +++ trunk/OpenMPT/mptrack/AbstractVstEditor.cpp 2012-02-06 23:55:02 UTC (rev 1172) @@ -566,7 +566,7 @@ void CAbstractVstEditor::UpdateMacroMenu() //---------------------------------------- { - CString label, macroName, macroText; + CString label, macroName; bool greyed; int action; @@ -590,13 +590,13 @@ for (int nMacro = 0; nMacro < NUM_MACROS; nMacro++) { - MIDIMacroTools macroTools(*pModDoc->GetSoundFile()); - action = NULL; greyed = true; - macroText = pModDoc->GetSoundFile()->m_MidiCfg.szMidiSFXExt[nMacro]; - const enmParameteredMacroType macroType = macroTools.GetMacroType(macroText); + const MIDIMacroConfig &midiCfg = pModDoc->GetSoundFile()->m_MidiCfg; + + const parameteredMacroType macroType = midiCfg.GetParameteredMacroType(nMacro); + if(macroType == sfx_unused) { macroName = "Unused. Learn Param..."; @@ -604,7 +604,7 @@ greyed = false; } else { - macroName = macroTools.GetMacroName(macroText, m_pVstPlugin->GetSlot()); + macroName = midiCfg.GetParameteredMacroName(nMacro, m_pVstPlugin->GetSlot(), *pModDoc->GetSoundFile()); if(macroType != sfx_plug || macroName.Left(3) != "N/A") { greyed = false; Modified: trunk/OpenMPT/mptrack/CleanupSong.cpp =================================================================== --- trunk/OpenMPT/mptrack/CleanupSong.cpp 2012-02-06 18:26:37 UTC (rev 1171) +++ trunk/OpenMPT/mptrack/CleanupSong.cpp 2012-02-06 23:55:02 UTC (rev 1172) @@ -900,7 +900,7 @@ pSndFile->m_nMixLevels = mixLevels_compatible; pSndFile->m_nTempoMode = tempo_mode_classic; pSndFile->m_dwSongFlags = SONG_LINEARSLIDES; - CSoundFile::ResetMidiCfg(pSndFile->m_MidiCfg); + pSndFile->m_MidiCfg.Reset(); // Global vars pSndFile->m_nDefaultTempo = 125; Modified: trunk/OpenMPT/mptrack/Ctrl_pat.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_pat.cpp 2012-02-06 18:26:37 UTC (rev 1171) +++ trunk/OpenMPT/mptrack/Ctrl_pat.cpp 2012-02-06 23:55:02 UTC (rev 1172) @@ -1142,8 +1142,7 @@ m_pSndFile->m_dwSongFlags &= ~SONG_EMBEDMIDICFG; // If this macro is not the default IT macro, display a warning. - MIDIMacroTools macroTools(*m_pSndFile); - if(!macroTools.IsMacroDefaultSetupUsed()) + if(!m_pSndFile->m_MidiCfg.IsMacroDefaultSetupUsed()) { if(Reporting::Confirm(_T("You have chosen not to embed MIDI macros. However, the current macro configuration differs from the default macro configuration that is assumed when loading a file that has no macros embedded. This can result in data loss and broken playback.\nWould you like to embed MIDI macros now?")) == cnfYes) { Modified: trunk/OpenMPT/mptrack/Ctrl_smp.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2012-02-06 18:26:37 UTC (rev 1171) +++ trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2012-02-06 23:55:02 UTC (rev 1172) @@ -379,7 +379,7 @@ { if (pSndFile->GetNumInstruments()) { - UINT k = m_pParent->GetInstrumentChange(); + INSTRUMENTINDEX k = m_pParent->GetInstrumentChange(); if (!pModDoc->IsChildSample(k, lParam)) { UINT nins = pModDoc->FindSampleParent(lParam); Modified: trunk/OpenMPT/mptrack/MIDIMacroDialog.cpp =================================================================== --- trunk/OpenMPT/mptrack/MIDIMacroDialog.cpp 2012-02-06 18:26:37 UTC (rev 1171) +++ trunk/OpenMPT/mptrack/MIDIMacroDialog.cpp 2012-02-06 23:55:02 UTC (rev 1172) @@ -73,7 +73,7 @@ m_CbnSFx.SetCurSel(0); for(int i = 0; i < sfx_max; i++) { - m_CbnSFxPreset.SetItemData(m_CbnSFxPreset.AddString(macroTools.GetMacroName(static_cast<enmParameteredMacroType>(i))), i); + m_CbnSFxPreset.SetItemData(m_CbnSFxPreset.AddString(m_MidiCfg.GetParameteredMacroName(static_cast<parameteredMacroType>(i))), i); } OnSFxChanged(); @@ -95,9 +95,9 @@ m_CbnZxx.SetCurSel(0); for(int i = 0; i < zxx_max; i++) { - m_CbnZxxPreset.SetItemData(m_CbnZxxPreset.AddString(macroTools.GetZxxName(static_cast<enmFixedMacroType>(i))), i); + m_CbnZxxPreset.SetItemData(m_CbnZxxPreset.AddString(m_MidiCfg.GetFixedMacroName(static_cast<fixedMacroType>(i))), i); } - m_CbnZxxPreset.SetCurSel(macroTools.GetZxxType(m_MidiCfg.szMidiZXXExt)); + m_CbnZxxPreset.SetCurSel(m_MidiCfg.GetFixedMacroType()); UpdateDialog(); @@ -171,24 +171,23 @@ m_EditMacro[m].SetWindowText(s); // Macro value: - CString macroText = m_MidiCfg.szMidiSFXExt[m]; - m_EditMacroValue[m].SetWindowText(macroText); + m_EditMacroValue[m].SetWindowText(m_MidiCfg.szMidiSFXExt[m]); m_EditMacroValue[m].SetBackColor(m == selectedMacro ? RGB(200, 200, 225) : RGB(245, 245, 245)); // Macro Type: - const enmParameteredMacroType macroType = macroTools.GetMacroType(macroText); + const parameteredMacroType macroType = m_MidiCfg.GetParameteredMacroType(m); switch (macroType) { case sfx_cc: - s.Format("MIDI CC %d", macroTools.MacroToMidiCC(macroText)); + s.Format("MIDI CC %d", m_MidiCfg.MacroToMidiCC(m)); break; case sfx_plug: - s.Format("Control Plugin Param %d", macroTools.MacroToPlugParam(macroText)); + s.Format("Control Plugin Param %d", m_MidiCfg.MacroToPlugParam(m)); break; default: - s = macroTools.GetMacroName(macroType); + s = m_MidiCfg.GetParameteredMacroName(macroType); break; } m_EditMacroType[m].SetWindowText(s); @@ -276,9 +275,7 @@ UINT sfx = m_CbnSFx.GetCurSel(); if (sfx < 16) { - CString macroText; - memcpy(macroText.GetBuffer(MACRO_LENGTH), m_MidiCfg.szMidiSFXExt[sfx], MACRO_LENGTH); - int preset = macroTools.GetMacroType(macroText); + int preset = m_MidiCfg.GetParameteredMacroType(sfx); m_CbnSFxPreset.SetCurSel(preset); } UpdateDialog(); @@ -289,13 +286,13 @@ //---------------------------------------- { UINT sfx = m_CbnSFx.GetCurSel(); - enmParameteredMacroType sfx_preset = static_cast<enmParameteredMacroType>(m_CbnSFxPreset.GetItemData(m_CbnSFxPreset.GetCurSel())); + parameteredMacroType sfx_preset = static_cast<parameteredMacroType>(m_CbnSFxPreset.GetItemData(m_CbnSFxPreset.GetCurSel())); if (sfx < 16) { if(sfx_preset != sfx_custom) { - strcpy(m_MidiCfg.szMidiSFXExt[sfx], macroTools.CreateParameteredMacroFromType(sfx_preset)); + m_MidiCfg.CreateParameteredMacro(sfx, sfx_preset); } UpdateDialog(); } @@ -305,11 +302,11 @@ void CMidiMacroSetup::OnZxxPresetChanged() //---------------------------------------- { - enmFixedMacroType zxx_preset = static_cast<enmFixedMacroType>(m_CbnZxxPreset.GetItemData(m_CbnZxxPreset.GetCurSel())); + fixedMacroType zxx_preset = static_cast<fixedMacroType>(m_CbnZxxPreset.GetItemData(m_CbnZxxPreset.GetCurSel())); if (zxx_preset != zxx_custom) { - macroTools.CreateZxxFromType(m_MidiCfg.szMidiZXXExt, zxx_preset); + m_MidiCfg.CreateFixedMacro(zxx_preset); UpdateDialog(); } } @@ -329,7 +326,7 @@ StringFixer::SetNullTerminator(s); memcpy(m_MidiCfg.szMidiSFXExt[sfx], s, MACRO_LENGTH); - int sfx_preset = macroTools.GetMacroType(m_MidiCfg.szMidiSFXExt[sfx]); + int sfx_preset = m_MidiCfg.GetParameteredMacroType(sfx); m_CbnSFxPreset.SetCurSel(sfx_preset); ToggleBoxes(sfx_preset, sfx); UpdateMacroList(sfx); @@ -367,7 +364,7 @@ { CString message, plugName, line; int sfx = id - ID_PLUGSELECT; - int param = macroTools.MacroToPlugParam(m_MidiCfg.szMidiSFXExt[sfx]); + int param = m_MidiCfg.MacroToPlugParam(sfx); CVstPlugin *pVstPlugin; message.Format("These are the parameters that can be controlled by macro SF%X:\n\n", sfx); @@ -407,7 +404,7 @@ AddPluginParameternamesToCombobox(m_CbnMacroParam, *pVstPlugin); m_CbnMacroParam.SetRedraw(TRUE); - int param = macroTools.MacroToPlugParam(m_MidiCfg.szMidiSFXExt[m_CbnSFx.GetCurSel()]); + int param = m_MidiCfg.MacroToPlugParam(m_CbnSFx.GetCurSel()); m_CbnMacroParam.SetCurSel(param); } //OnPlugParamChanged(); @@ -416,17 +413,12 @@ void CMidiMacroSetup::OnPlugParamChanged() //---------------------------------------- { - CString macroText; UINT param = m_CbnMacroParam.GetItemData(m_CbnMacroParam.GetCurSel()); - if(param < 128) + if(param < 384) { - macroText.Format("F0F0%02Xz",param + 128); - m_EditSFx.SetWindowText(macroText); - } else if(param < 384) - { - macroText.Format("F0F1%02Xz",param - 128); - m_EditSFx.SetWindowText(macroText); + const std::string macroText = m_MidiCfg.CreateParameteredMacro(sfx_plug, param); + m_EditSFx.SetWindowText(macroText.c_str()); } else { Reporting::Notification("Only parameters 0 to 383 can be controlled using MIDI Macros. Use Parameter Control Events to automate higher parameters."); @@ -436,10 +428,9 @@ void CMidiMacroSetup::OnCCChanged() //--------------------------------- { - CString macroText; UINT cc = m_CbnMacroCC.GetItemData(m_CbnMacroCC.GetCurSel()); - macroText.Format("Bc%02Xz", cc & 0xFF); - m_EditSFx.SetWindowText(macroText); + const std::string macroText = m_MidiCfg.CreateParameteredMacro(sfx_cc, cc); + m_EditSFx.SetWindowText(macroText.c_str()); } void CMidiMacroSetup::ToggleBoxes(UINT sfx_preset, UINT sfx) @@ -454,7 +445,7 @@ m_CbnMacroPlug.EnableWindow(TRUE); m_CbnMacroParam.EnableWindow(TRUE); SetDlgItemText(IDC_GENMACROLABEL, "Plug/Param"); - m_CbnMacroParam.SetCurSel(macroTools.MacroToPlugParam(m_MidiCfg.szMidiSFXExt[sfx])); + m_CbnMacroParam.SetCurSel(m_MidiCfg.MacroToPlugParam(sfx)); } else { m_CbnMacroPlug.EnableWindow(FALSE); @@ -468,7 +459,7 @@ m_CbnMacroPlug.ShowWindow(FALSE); m_CbnMacroParam.ShowWindow(FALSE); SetDlgItemText(IDC_GENMACROLABEL, "MIDI CC"); - m_CbnMacroCC.SetCurSel(macroTools.MacroToMidiCC(m_MidiCfg.szMidiSFXExt[sfx])); + m_CbnMacroCC.SetCurSel(m_MidiCfg.MacroToMidiCC(sfx)); } else { m_CbnMacroCC.EnableWindow(FALSE); Modified: trunk/OpenMPT/mptrack/MIDIMacroDialog.h =================================================================== --- trunk/OpenMPT/mptrack/MIDIMacroDialog.h 2012-02-06 18:26:37 UTC (rev 1171) +++ trunk/OpenMPT/mptrack/MIDIMacroDialog.h 2012-02-06 23:55:02 UTC (rev 1172) @@ -19,13 +19,13 @@ //=================================== { public: - CMidiMacroSetup(CSoundFile &sndFile, CWnd *parent = NULL) : CDialog(IDD_MIDIMACRO, parent), m_SndFile(sndFile), macroTools(sndFile), m_MidiCfg(sndFile.m_MidiCfg) + CMidiMacroSetup(CSoundFile &sndFile, CWnd *parent = NULL) : CDialog(IDD_MIDIMACRO, parent), m_SndFile(sndFile), m_MidiCfg(sndFile.m_MidiCfg) { m_bEmbed = (m_SndFile.m_dwSongFlags & SONG_EMBEDMIDICFG) != 0; } bool m_bEmbed; - MODMIDICFG m_MidiCfg; + MIDIMacroConfig m_MidiCfg; protected: @@ -35,7 +35,6 @@ CButton m_EditMacro[NUM_MACROS], m_BtnMacroShowAll[NUM_MACROS]; CSoundFile &m_SndFile; - MIDIMacroTools macroTools; bool ValidateMacroString(CEdit &wnd, char *lastMacro, bool isParametric); Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2012-02-06 18:26:37 UTC (rev 1171) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2012-02-06 23:55:02 UTC (rev 1172) @@ -15,7 +15,6 @@ #include "version.h" #include "modsmp_ctrl.h" #include "CleanupSong.h" -#include "MIDIMacros.h" #include "../common/StringFixer.h" #include <shlwapi.h> @@ -179,8 +178,7 @@ { m_SndFile.m_dwSongFlags |= SONG_LINEARSLIDES; - MIDIMacroTools macroTools(m_SndFile); - if(!macroTools.IsMacroDefaultSetupUsed()) + if(!m_SndFile.m_MidiCfg.IsMacroDefaultSetupUsed()) { m_SndFile.m_dwSongFlags |= SONG_EMBEDMIDICFG; } @@ -2307,7 +2305,7 @@ bool CModDoc::GetEffectName(LPSTR pszDescription, MODCOMMAND::COMMAND command, UINT param, bool bXX, CHANNELINDEX nChn) //rewbs.xinfo: added chan arg -//------------------------------------------------------------------------------------------------------ +//--------------------------------------------------------------------------------------------------------------------- { bool bSupported; UINT fxndx = MAX_FXINFO; @@ -2342,22 +2340,24 @@ if (nChn < m_SndFile.m_nChannels) { CString chanSpec = ""; - CString macroText= "_no macro_"; + size_t macroIndex = size_t(-1); + switch (command) { case CMD_MODCMDEX: case CMD_S3MCMDEX: if ((param & 0xF0) == 0xF0 && !(m_SndFile.GetType() & MOD_TYPE_MOD)) //Set Macro { - macroText = m_SndFile.m_MidiCfg.szMidiSFXExt[(param & 0x0F)]; + macroIndex = (param & 0x0F); chanSpec.Format(" to %d: ", param & 0x0F); } break; + case CMD_MIDI: case CMD_SMOOTHMIDI: if (param < 0x80 && nChn != CHANNELINDEX_INVALID) { - macroText = m_SndFile.m_MidiCfg.szMidiSFXExt[m_SndFile.Chn[nChn].nActiveMacro]; + macroIndex = m_SndFile.Chn[nChn].nActiveMacro; chanSpec.Format(": currently %d: ", m_SndFile.Chn[nChn].nActiveMacro); } else @@ -2367,11 +2367,10 @@ break; } - if (macroText != "_no macro_") + if(macroIndex != size_t(-1)) { - MIDIMacroTools macroTools(m_SndFile); const PLUGINDEX plugin = m_SndFile.GetBestPlugin(nChn, PrioritiseChannel, EvenIfMuted) - 1; - chanSpec.Append(macroTools.GetMacroName(macroText, plugin)); + chanSpec.Append(m_SndFile.m_MidiCfg.GetParameteredMacroName(macroIndex, plugin, *(this->GetSoundFile()))); } if (chanSpec != "") { @@ -3574,10 +3573,9 @@ //if macro already exists for this param, alert user and return for (int checkMacro = 0; checkMacro < NUM_MACROS; checkMacro++) { - CString macroText = GetSoundFile()->m_MidiCfg.szMidiSFXExt[checkMacro]; - int macroType = MIDIMacroTools::GetMacroType(macroText); + int macroType = GetSoundFile()->m_MidiCfg.GetParameteredMacroType(checkMacro); - if (macroType==sfx_plug && MIDIMacroTools::MacroToPlugParam(macroText) == paramToUse) + if (macroType == sfx_plug && GetSoundFile()->m_MidiCfg.MacroToPlugParam(checkMacro) == paramToUse) { CString message; message.Format("Parameter %02d can already be controlled with macro %X.", paramToUse, checkMacro); @@ -3752,7 +3750,7 @@ } // Macros - m_SndFile.SanitizeMacros(); + m_SndFile.m_MidiCfg.Sanitize(); // Pattern names // Those are CStrings and don't need to be fixed. Modified: trunk/OpenMPT/mptrack/Mptrack.cpp =================================================================== --- trunk/OpenMPT/mptrack/Mptrack.cpp 2012-02-06 18:26:37 UTC (rev 1171) +++ trunk/OpenMPT/mptrack/Mptrack.cpp 2012-02-06 23:55:02 UTC (rev 1172) @@ -591,9 +591,7 @@ m_bDebugMode = FALSE; m_hAlternateResourceHandle = NULL; m_szConfigFileName[0] = 0; - for (UINT i=0; i<MAX_DLS_BANKS; i++) gpDLSBanks[i] = NULL; - // Reset default macro config - CSoundFile::ResetMidiCfg(m_MidiCfg); + for (size_t i = 0; i < MAX_DLS_BANKS; i++) gpDLSBanks[i] = NULL; } ///////////////////////////////////////////////////////////////////////////// Modified: trunk/OpenMPT/mptrack/Mptrack.h =================================================================== --- trunk/OpenMPT/mptrack/Mptrack.h 2012-02-06 18:26:37 UTC (rev 1171) +++ trunk/OpenMPT/mptrack/Mptrack.h 2012-02-06 23:55:02 UTC (rev 1172) @@ -131,7 +131,7 @@ DWORD m_dwTimeStarted, m_dwLastPluginIdleCall; HANDLE m_hAlternateResourceHandle; // Default macro configuration - MODMIDICFG m_MidiCfg; + MIDIMacroConfig m_MidiCfg; static TCHAR m_szExePath[_MAX_PATH]; TCHAR m_szConfigDirectory[_MAX_PATH]; TCHAR m_szConfigFileName[_MAX_PATH]; @@ -171,8 +171,8 @@ public: CDocTemplate *GetModDocTemplate() const { return m_pModTemplate; } CVstPluginManager *GetPluginManager() const { return m_pPluginManager; } - void GetDefaultMidiMacro(MODMIDICFG *pcfg) const { *pcfg = m_MidiCfg; } - void SetDefaultMidiMacro(const MODMIDICFG *pcfg) { m_MidiCfg = *pcfg; } + void GetDefaultMidiMacro(MIDIMacroConfig *pcfg) const { *pcfg = m_MidiCfg; } + void SetDefaultMidiMacro(const MIDIMacroConfig *pcfg) { m_MidiCfg = *pcfg; } void LoadChords(PMPTCHORD pChords); void SaveChords(PMPTCHORD pChords); BOOL CanEncodeLayer3() const { return acmConvert.IsLayer3Present(); } Modified: trunk/OpenMPT/mptrack/TrackerSettings.cpp =================================================================== --- trunk/OpenMPT/mptrack/TrackerSettings.cpp 2012-02-06 18:26:37 UTC (rev 1171) +++ trunk/OpenMPT/mptrack/TrackerSettings.cpp 2012-02-06 23:55:02 UTC (rev 1172) @@ -194,7 +194,7 @@ theApp.LoadChords(Chords); // Load default macro configuration - MODMIDICFG macros; + MIDIMacroConfig macros; theApp.GetDefaultMidiMacro(¯os); for(int isfx = 0; isfx < 16; isfx++) { @@ -785,7 +785,7 @@ theApp.SaveChords(Chords); // Save default macro configuration - MODMIDICFG macros; + MIDIMacroConfig macros; theApp.GetDefaultMidiMacro(¯os); for(int isfx = 0; isfx < 16; isfx++) { Modified: trunk/OpenMPT/mptrack/View_pat.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_pat.cpp 2012-02-06 18:26:37 UTC (rev 1171) +++ trunk/OpenMPT/mptrack/View_pat.cpp 2012-02-06 23:55:02 UTC (rev 1172) @@ -3216,8 +3216,6 @@ return 0; } - MIDIMacroTools macroTools(*pSndFile); - //Work out where to put the new data const UINT nChn = GetChanFromCursor(m_dwCursor); const bool bUsePlaybackPosition = IsLiveRecord(*pModDoc, *pSndFile); @@ -3253,16 +3251,17 @@ //Figure out which plug param (if any) is controllable using the active macro on this channel. long activePlugParam = -1; BYTE activeMacro = pSndFile->Chn[nChn].nActiveMacro; - CString activeMacroString = pSndFile->m_MidiCfg.szMidiSFXExt[activeMacro]; - if (macroTools.GetMacroType(activeMacroString) == sfx_plug) + + if (pSndFile->m_MidiCfg.GetParameteredMacroType(activeMacro) == sfx_plug) { - activePlugParam = macroTools.MacroToPlugParam(activeMacroString); + activePlugParam = pSndFile->m_MidiCfg.MacroToPlugParam(activeMacro); } + //If the wrong macro is active, see if we can find the right one. //If we can, activate it for this chan by writing appropriate SFx command it. if (activePlugParam != paramIndex) { - int foundMacro = macroTools.FindMacroForParam(paramIndex); + int foundMacro = pSndFile->m_MidiCfg.FindMacroForParam(paramIndex); if (foundMacro >= 0) { pSndFile->Chn[nChn].nActiveMacro = foundMacro; @@ -3271,7 +3270,7 @@ pModDoc->GetPatternUndo().PrepareUndo(nPattern, nChn, nRow, 1, 1); pRow->command = (pSndFile->m_nType & (MOD_TYPE_IT | MOD_TYPE_MPT)) ? CMD_S3MCMDEX : CMD_MODCMDEX;; - pRow->param = 0xF0 + (foundMacro&0x0F); + pRow->param = 0xF0 + (foundMacro & 0x0F); InvalidateRow(nRow); } Modified: trunk/OpenMPT/mptrack/Vstplug.h =================================================================== --- trunk/OpenMPT/mptrack/Vstplug.h 2012-02-06 18:26:37 UTC (rev 1171) +++ trunk/OpenMPT/mptrack/Vstplug.h 2012-02-06 23:55:02 UTC (rev 1172) @@ -8,6 +8,7 @@ #include <vstfxstore.h> #endif +#include "../soundlib/Snd_defs.h" #include "../soundlib/PluginMixBuffer.h" #define kBuzzMagic 'Buzz' Modified: trunk/OpenMPT/mptrack/mptrack.vcproj =================================================================== --- trunk/OpenMPT/mptrack/mptrack.vcproj 2012-02-06 18:26:37 UTC (rev 1171) +++ trunk/OpenMPT/mptrack/mptrack.vcproj 2012-02-06 23:55:02 UTC (rev 1172) @@ -852,6 +852,9 @@ RelativePath=".\soundlib\PluginMixBuffer.h"> </File> <File + RelativePath=".\soundlib\PlugInterface.h"> + </File> + <File RelativePath="..\common\Reporting.h"> </File> <File Modified: trunk/OpenMPT/mptrack/mptrack_08.vcproj =================================================================== --- trunk/OpenMPT/mptrack/mptrack_08.vcproj 2012-02-06 18:26:37 UTC (rev 1171) +++ trunk/OpenMPT/mptrack/mptrack_08.vcproj 2012-02-06 23:55:02 UTC (rev 1172) @@ -1131,6 +1131,10 @@ > </File> <File + RelativePath=".\soundlib\PlugInterface.h" + > + </File> + <File RelativePath="..\common\Reporting.h" > </File> Modified: trunk/OpenMPT/mptrack/mptrack_10.vcxproj =================================================================== --- trunk/OpenMPT/mptrack/mptrack_10.vcxproj 2012-02-06 18:26:37 UTC (rev 1171) +++ trunk/OpenMPT/mptrack/mptrack_10.vcxproj 2012-02-06 23:55:02 UTC (rev 1172) @@ -329,6 +329,7 @@ <ClInclude Include="..\common\typedefs.h" /> <ClInclude Include="..\soundlib\MIDIMacros.h" /> <ClInclude Include="..\soundlib\PluginMixBuffer.h" /> + <ClInclude Include="..\soundlib\PlugInterface.h" /> <ClInclude Include="ACMConvert.h" /> <ClInclude Include="Autotune.h" /> <ClInclude Include="ExceptionHandler.h" /> Modified: trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters =================================================================== --- trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters 2012-02-06 18:26:37 UTC (rev 1171) +++ trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters 2012-02-06 23:55:02 UTC (rev 1172) @@ -774,6 +774,9 @@ <ClInclude Include="..\soundlib\PluginMixBuffer.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="..\soundlib\PlugInterface.h"> + <Filter>Header Files</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <None Include="res\bitmap1.bmp"> Modified: trunk/OpenMPT/mptrack/test/test.cpp =================================================================== --- trunk/OpenMPT/mptrack/test/test.cpp 2012-02-06 18:26:37 UTC (rev 1171) +++ trunk/OpenMPT/mptrack/test/test.cpp 2012-02-06 23:55:02 UTC (rev 1172) @@ -283,9 +283,9 @@ VERIFY_EQUAL_NONCONT(pSndFile->m_nRestartPos, 1); // Macros - VERIFY_EQUAL_NONCONT(MIDIMacroTools::GetMacroType(pSndFile->m_MidiCfg.szMidiSFXExt[0]), sfx_reso); - VERIFY_EQUAL_NONCONT(MIDIMacroTools::GetMacroType(pSndFile->m_MidiCfg.szMidiSFXExt[1]), sfx_drywet); - VERIFY_EQUAL_NONCONT(MIDIMacroTools::GetZxxType(pSndFile->m_MidiCfg.szMidiZXXExt), zxx_resomode); + VERIFY_EQUAL_NONCONT(pSndFile->m_MidiCfg.GetParameteredMacroType(0, sfx_reso); + VERIFY_EQUAL_NONCONT(pSndFile->m_MidiCfg.GetParameteredMacroType(1, sfx_drywet); + VERIFY_EQUAL_NONCONT(pSndFile->m_MidiCfg.GetFixedMacroType(), zxx_resomode); // Channels VERIFY_EQUAL_NONCONT(pSndFile->GetNumChannels(), 2); @@ -478,9 +478,9 @@ VERIFY_EQUAL_NONCONT((uint32)((double)fh.openTime / HISTORY_TIMER_PRECISION), 31); // Macros - VERIFY_EQUAL_NONCONT(MIDIMacroTools::GetMacroType(pSndFile->m_MidiCfg.szMidiSFXExt[0]), sfx_reso); - VERIFY_EQUAL_NONCONT(MIDIMacroTools::GetMacroType(pSndFile->m_MidiCfg.szMidiSFXExt[1]), sfx_drywet); - VERIFY_EQUAL_NONCONT(MIDIMacroTools::GetZxxType(pSndFile->m_MidiCfg.szMidiZXXExt), zxx_resomode); + VERIFY_EQUAL_NONCONT(pSndFile->m_MidiCfg.GetParameteredMacroType(0, sfx_reso); + VERIFY_EQUAL_NONCONT(pSndFile->m_MidiCfg.GetParameteredMacroType(1, sfx_drywet); + VERIFY_EQUAL_NONCONT(pSndFile->m_MidiCfg.GetFixedMacroType(), zxx_resomode); // Channels VERIFY_EQUAL_NONCONT(pSndFile->GetNumChannels(), 2); Modified: trunk/OpenMPT/soundlib/Load_it.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_it.cpp 2012-02-06 18:26:37 UTC (rev 1171) +++ trunk/OpenMPT/soundlib/Load_it.cpp 2012-02-06 23:55:02 UTC (rev 1172) @@ -812,11 +812,11 @@ // Reading MIDI Output & Macros if (m_dwSongFlags & SONG_EMBEDMIDICFG) { - if (dwMemPos + sizeof(MODMIDICFG) < dwMemLength) + if (dwMemPos + sizeof(MIDIMacroConfig) < dwMemLength) { - memcpy(&m_MidiCfg, lpStream + dwMemPos, sizeof(MODMIDICFG)); - SanitizeMacros(); - dwMemPos += sizeof(MODMIDICFG); + memcpy(&m_MidiCfg, lpStream + dwMemPos, sizeof(MIDIMacroConfig)); + m_MidiCfg.Sanitize(); + dwMemPos += sizeof(MIDIMacroConfig); } } // Ignore MIDI data. Fixes some files like denonde.it that were made with old versions of Impulse Tracker (which didn't support Zxx filters) and have Zxx effects in the patterns. @@ -1491,7 +1491,7 @@ { header.flags |= 0x80; header.special |= 0x08; - dwExtra += sizeof(MODMIDICFG); + dwExtra += sizeof(MIDIMacroConfig); } // Pattern Names @@ -1531,7 +1531,7 @@ // Writing midi cfg if (header.flags & 0x80) { - fwrite(&m_MidiCfg, 1, sizeof(MODMIDICFG), f); + fwrite(&m_MidiCfg, 1, sizeof(MIDIMacroConfig), f); } // Writing pattern names Modified: trunk/OpenMPT/soundlib/Load_itp.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_itp.cpp 2012-02-06 18:26:37 UTC (rev 1171) +++ trunk/OpenMPT/soundlib/Load_itp.cpp 2012-02-06 23:55:02 UTC (rev 1172) @@ -176,7 +176,7 @@ if (id <= sizeof(m_MidiCfg)) { memcpy(&m_MidiCfg, lpStream + dwMemPos, id); - SanitizeMacros(); + m_MidiCfg.Sanitize(); dwMemPos += id; } @@ -552,11 +552,11 @@ // Song midi config // midi cfg data length - id = sizeof(MODMIDICFG); + id = sizeof(MIDIMacroConfig); fwrite(&id, 1, sizeof(id), f); // midi cfg - fwrite(&m_MidiCfg, 1, sizeof(MODMIDICFG), f); + fwrite(&m_MidiCfg, 1, sizeof(MIDIMacroConfig), f); // Song Instruments Modified: trunk/OpenMPT/soundlib/Load_xm.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_xm.cpp 2012-02-06 18:26:37 UTC (rev 1171) +++ trunk/OpenMPT/soundlib/Load_xm.cpp 2012-02-06 23:55:02 UTC (rev 1172) @@ -609,10 +609,10 @@ { UINT len = *((DWORD *)(lpStream+dwMemPos+4)); dwMemPos += 8; - if (len == sizeof(MODMIDICFG)) + if (len == sizeof(MIDIMacroConfig)) { memcpy(&m_MidiCfg, lpStream + dwMemPos, len); - SanitizeMacros(); + m_MidiCfg.Sanitize(); m_dwSongFlags |= SONG_EMBEDMIDICFG; dwMemPos += len; //rewbs.fix36946 } @@ -1092,9 +1092,9 @@ { DWORD d = 0x4944494D; fwrite(&d, 1, 4, f); - d = sizeof(MODMIDICFG); + d = sizeof(MIDIMacroConfig); fwrite(&d, 1, 4, f); - fwrite(&m_MidiCfg, 1, sizeof(MODMIDICFG), f); + fwrite(&m_MidiCfg, 1, sizeof(MIDIMacroConfig), f); } // Writing Pattern Names const PATTERNINDEX numNamedPats = Patterns.GetNumNamedPatterns(); Modified: trunk/OpenMPT/soundlib/MIDIMacros.cpp =================================================================== --- trunk/OpenMPT/soundlib/MIDIMacros.cpp 2012-02-06 18:26:37 UTC (rev 1171) +++ trunk/OpenMPT/soundlib/MIDIMacros.cpp 2012-02-06 23:55:02 UTC (rev 1172) @@ -8,51 +8,169 @@ #include "stdafx.h" #include "midi.h" +#include "MIDIMacros.h" +#include "../common/StringFixer.h" + +#ifdef MODPLUG_TRACKER #include "Sndfile.h" -#include "MIDIMacros.h" -#ifndef NO_VST #include "../mptrack/Vstplug.h" -#endif // NO_VST +#endif // MODPLUG_TRACKER +parameteredMacroType MIDIMacroConfig::GetParameteredMacroType(size_t macroIndex) const +//------------------------------------------------------------------------------------ +{ + const std::string macro = GetSafeMacro(szMidiSFXExt[macroIndex]); -enmParameteredMacroType MIDIMacroTools::GetMacroType(CString value) -//----------------------------------------------------------------- -{ - value.Remove(' '); for(size_t i = 0; i < sfx_max; i++) { - enmParameteredMacroType sfx = static_cast<enmParameteredMacroType>(i); + parameteredMacroType sfx = static_cast<parameteredMacroType>(i); if(sfx != sfx_custom) { - if(value.Compare(CreateParameteredMacroFromType(sfx)) == 0) return sfx; + if(macro.compare(CreateParameteredMacro(sfx)) == 0) return sfx; } } + // Special macros with additional "parameter": - if (value.Compare(CreateParameteredMacroFromType(sfx_cc, MIDICC_start)) >= 0 && value.Compare(CreateParameteredMacroFromType(sfx_cc, MIDICC_end)) <= 0 && value.GetLength() == 5) + if (macro.compare(CreateParameteredMacro(sfx_cc, MIDICC_start)) >= 0 && macro.compare(CreateParameteredMacro(sfx_cc, MIDICC_end)) <= 0 && macro.size() == 5) return sfx_cc; - if (value.Compare(CreateParameteredMacroFromType(sfx_plug, 0)) >= 0 && value.Compare(CreateParameteredMacroFromType(sfx_plug, 0x17F)) <= 0 && value.GetLength() == 7) + if (macro.compare(CreateParameteredMacro(sfx_plug, 0)) >= 0 && macro.compare(CreateParameteredMacro(sfx_plug, 0x17F)) <= 0 && macro.size() == 7) return sfx_plug; + return sfx_custom; // custom / unknown } +// Retrieve Zxx (Z80-ZFF) type from current macro configuration +fixedMacroType MIDIMacroConfig::GetFixedMacroType() const +//------------------------------------------------------- +{ + // Compare with all possible preset patterns + for(size_t i = 1; i < zxx_max; i++) + { + // Prepare macro pattern to compare + char macros[128][MACRO_LENGTH]; + CreateFixedMacro(macros, static_cast<fixedMacroType>(i)); + + bool bFound = true; + for(size_t j = 0; j < 128; j++) + { + if(strncmp(macros[j], szMidiZXXExt[j], MACRO_LENGTH)) + { + bFound = false; + break; + } + } + if(bFound) return static_cast<fixedMacroType>(i); + } + return zxx_custom; // Custom setup +} + + +void MIDIMacroConfig::CreateParameteredMacro(char (¶meteredMacro)[MACRO_LENGTH], parameteredMacroType macroType, int subType) const +//------------------------------------------------------------------------------------------------------------------------------------- +{ + switch(macroType) + { + case sfx_unused: + strcpy(parameteredMacro, ""); + break; + case sfx_cutoff: + strcpy(parameteredMacro, "F0F000z"); + break; + case sfx_reso: + strcpy(parameteredMacro, "F0F001z"); + break; + case sfx_mode: + strcpy(parameteredMacro, "F0F002z"); + break; + case sfx_drywet: + strcpy(parameteredMacro, "F0F003z"); + break; + case sfx_cc: + sprintf(parameteredMacro, "Bc%02Xz", (subType & 0x7F)); + break; + case sfx_plug: + sprintf(parameteredMacro, "F0F%03Xz", min(subType, 0x17F) + 0x80); + break; + case sfx_channelAT: + strcpy(parameteredMacro, "Dcz"); + break; + case sfx_polyAT: + strcpy(parameteredMacro, "Acnz"); + break; + } +} + + +// Create Zxx (Z80 - ZFF) from one out of five presets +void MIDIMacroConfig::CreateFixedMacro(char (&fixedMacros)[128][MACRO_LENGTH], fixedMacroType macroType) const +//------------------------------------------------------------------------------------------------------------ +{ + for(size_t i = 0; i < 128; i++) + { + switch(macroType) + { + case zxx_reso4Bit: + // Type 1 - Z80 - Z8F controls resonance + if (i < 16) sprintf(fixedMacros[i], "F0F001%02X", i * 8); + else strcpy(fixedMacros[i], ""); + break; + + case zxx_reso7Bit: + // Type 2 - Z80 - ZFF controls resonance + sprintf(fixedMacros[i], "F0F001%02X", i); + break; + + case zxx_cutoff: + // Type 3 - Z80 - ZFF controls cutoff + sprintf(fixedMacros[i], "F0F000%02X", i); + break; + + case zxx_mode: + // Type 4 - Z80 - ZFF controls filter mode + sprintf(fixedMacros[i], "F0F002%02X", i); + break; + + case zxx_resomode: + // Type 5 - Z80 - Z9F controls resonance + filter mode + if (i < 16) sprintf(fixedMacros[i], "F0F001%02X", i * 8); + else if (i < 32) sprintf(fixedMacros[i], "F0F002%02X", (i - 16) * 8); + else strcpy(fixedMacros[i], ""); + break; + + case zxx_channelAT: + // Type 6 - Z80 - ZFF controls Channel Aftertouch + sprintf(fixedMacros[i], "Dc%02X", i); + break; + + case zxx_polyAT: + // Type 7 - Z80 - ZFF controls Poly Aftertouch + sprintf(fixedMacros[i], "Acn%02X", i); + break; + } + } +} + + +#ifdef MODPLUG_TRACKER + // Returns macro description including plugin parameter / MIDI CC information -CString MIDIMacroTools::GetMacroName(CString value, PLUGINDEX plugin) const -//------------------------------------------------------------------------- +CString MIDIMacroConfig::GetParameteredMacroName(size_t macroIndex, PLUGINDEX plugin, const CSoundFile &sndFile) const +//-------------------------------------------------------------------------------------------------------------------- { - const enmParameteredMacroType macroType = GetMacroType(value); + const parameteredMacroType macroType = GetParameteredMacroType(macroIndex); switch(macroType) { case sfx_plug: { - const int param = MacroToPlugParam(value); + const int param = MacroToPlugParam(macroIndex); CString paramName; #ifndef NO_VST if(plugin < MAX_MIXPLUGINS) { - CVstPlugin *pPlug = reinterpret_cast<CVstPlugin *>(m_SndFile.m_MixPlugins[plugin].pMixPlugin); + CVstPlugin *pPlug = reinterpret_cast<CVstPlugin *>(sndFile.m_MixPlugins[plugin].pMixPlugin); if(pPlug) { paramName = pPlug->GetParamName(param); @@ -64,7 +182,7 @@ CString formattedName; formattedName.Format(_T("Param %d (%s)"), param, paramName); - return CString(formattedName); + return formattedName; } else #endif // NO_VST { @@ -75,21 +193,21 @@ case sfx_cc: { CString formattedCC; - formattedCC.Format(_T("MIDI CC %d"), MacroToMidiCC(value)); + formattedCC.Format(_T("MIDI CC %d"), MacroToMidiCC(macroIndex)); return formattedCC; } default: - return GetMacroName(macroType); + return GetParameteredMacroName(macroType); } } // Returns generic macro description. -CString MIDIMacroTools::GetMacroName(enmParameteredMacroType macro) -//----------------------------------------------------------------- +CString MIDIMacroConfig::GetParameteredMacroName(parameteredMacroType macroType) const +//------------------------------------------------------------------------------------ { - switch(macro) + switch(macroType) { case sfx_unused: return _T("Unused"); @@ -117,10 +235,10 @@ // Returns generic macro description. -CString MIDIMacroTools::GetZxxName(enmFixedMacroType macro) -//--------------------------------------------------------- +CString MIDIMacroConfig::GetFixedMacroName(fixedMacroType macroType) const +//------------------------------------------------------------------------ { - switch(macro) + switch(macroType) { case zxx_reso4Bit: return _T("Z80 - Z8F controls Resonant Filter Resonance"); @@ -143,31 +261,33 @@ } -int MIDIMacroTools::MacroToPlugParam(CString macro) -//------------------------------------------------- +int MIDIMacroConfig::MacroToPlugParam(size_t macroIndex) const +//------------------------------------------------------------ { - macro.Remove(' '); - int code=0; - char* param = (char *) (LPCTSTR) macro; + const std::string macro = GetSafeMacro(szMidiSFXExt[macroIndex]); + + int code = 0; + const char *param = macro.c_str(); param += 4; if ((param[0] >= '0') && (param[0] <= '9')) code = (param[0] - '0') << 4; else if ((param[0] >= 'A') && (param[0] <= 'F')) code = (param[0] - 'A' + 0x0A) << 4; if ((param[1] >= '0') && (param[1] <= '9')) code += (param[1] - '0'); else if ((param[1] >= 'A') && (param[1] <= 'F')) code += (param[1] - 'A' + 0x0A); - if (macro.GetLength() >= 4 && macro.GetAt(3) == '0') + if (macro.size() >= 4 && macro.at(3) == '0') return (code - 128); else return (code + 128); } -int MIDIMacroTools::MacroToMidiCC(CString macro) -//---------------------------------------------- +int MIDIMacroConfig::MacroToMidiCC(size_t macroIndex) const +//--------------------------------------------------------- { - macro.Remove(' '); - int code=0; - char* param = (char *) (LPCTSTR) macro; + const std::string macro = GetSafeMacro(szMidiSFXExt[macroIndex]); + + int code = 0; + const char *param = macro.c_str(); param += 2; if ((param[0] >= '0') && (param[0] <= '9')) code = (param[0] - '0') << 4; else if ((param[0] >= 'A') && (param[0] <= 'F')) code = (param[0] - 'A' + 0x0A) << 4; @@ -178,161 +298,101 @@ } -int MIDIMacroTools::FindMacroForParam(long param) const -//----------------------------------------------------- +int MIDIMacroConfig::FindMacroForParam(PlugParamIndex param) const +//---------------------------------------------------------------- { - for (size_t macro = 0; macro < NUM_MACROS; macro++) + for(size_t macroIndex = 0; macroIndex < NUM_MACROS; macroIndex++) { - CString macroString = m_SndFile.m_MidiCfg.szMidiSFXExt[macro]; - if (GetMacroType(macroString) == sfx_plug && MacroToPlugParam(macroString) == param) + if (GetParameteredMacroType(macroIndex) == sfx_plug && MacroToPlugParam(macroIndex) == param) { - return macro; + return macroIndex; } } return -1; } +#endif // MODPLUG_TRACKER -// Retrieve Zxx (Z80-ZFF) type from current macro configuration -enmFixedMacroType MIDIMacroTools::GetZxxType(const char (&szMidiZXXExt)[128][MACRO_LENGTH]) -//----------------------------------------------------------------------------------------- + +// Check if the MIDI Macro configuration used is the default one, +// i.e. the configuration that is assumed when loading a file that has no macros embedded. +bool MIDIMacroConfig::IsMacroDefaultSetupUsed() const +//--------------------------------------------------- { - // Compare with all possible preset patterns - for(size_t i = 1; i < zxx_max; i++) + const MIDIMacroConfig defaultConfig; + + // TODO - Global macros (currently not checked because they are not editable) + + // SF0: Z00-Z7F controls cutoff, all other parametered macros are unused + for(size_t i = 0; i < NUM_MACROS; i++) { - // Prepare pattern to compare - char szPatterns[128][MACRO_LENGTH]; - CreateZxxFromType(szPatterns, static_cast<enmFixedMacroType>(i)); - - bool bFound = true; - for(size_t j = 0; j < 128; j++) + if(GetParameteredMacroType(i) != defaultConfig.GetParameteredMacroType(i)) { - if(strncmp(szPatterns[j], szMidiZXXExt[j], MACRO_LENGTH)) - { - bFound = false; - break; - } + return false; } - if(bFound) return static_cast<enmFixedMacroType>(i); } - return zxx_custom; // Custom setup -} - -// Create Zxx (Z80 - ZFF) from one out of five presets -void MIDIMacroTools::CreateZxxFromType(char (&szMidiZXXExt)[128][MACRO_LENGTH], enmFixedMacroType iZxxType) -//--------------------------------------------------------------------------------------------------------- -{ - for(size_t i = 0; i < 128; i++) + // Z80-Z8F controls resonance + if(GetFixedMacroType() != defaultConfig.GetFixedMacroType()) { - switch(iZxxType) - { - case zxx_reso4Bit: - // Type 1 - Z80 - Z8F controls resonance - if (i < 16) wsprintf(szMidiZXXExt[i], "F0F001%02X", i * 8); - else strcpy(szMidiZXXExt[i], ""); - break; + return false; + } - case zxx_reso7Bit: - // Type 2 - Z80 - ZFF controls resonance - wsprintf(szMidiZXXExt[i], "F0F001%02X", i); - break; + return true; +} - case zxx_cutoff: - // Type 3 - Z80 - ZFF controls cutoff - wsprintf(szMidiZXXExt[i], "F0F000%02X", i); - break; - case zxx_mode: - // Type 4 - Z80 - ZFF controls filter mode - wsprintf(szMidiZXXExt[i], "F0F002%02X", i); - break; +// Reset MIDI macro config to default values. +void MIDIMacroConfig::Reset() +//--------------------------- +{ + MemsetZero(szMidiGlb); + MemsetZero(szMidiSFXExt); + MemsetZero(szMidiZXXExt); - case zxx_resomode: - // Type 5 - Z80 - Z9F controls resonance + filter mode - if (i < 16) wsprintf(szMidiZXXExt[i], "F0F001%02X", i * 8); - else if (i < 32) wsprintf(szMidiZXXExt[i], "F0F002%02X", (i - 16) * 8); - else strcpy(szMidiZXXExt[i], ""); - break; - - case zxx_channelAT: - // Type 6 - Z80 - ZFF controls Channel Aftertouch - wsprintf(szMidiZXXExt[i], "Dc%02X", i); - break; - - case zxx_polyAT: - // Type 7 - Z80 - ZFF controls Poly Aftertouch - wsprintf(szMidiZXXExt[i], "Acn%02X", i); - break; - } - } + strcpy(szMidiGlb[MIDIOUT_START], "FF"); + strcpy(szMidiGlb[MIDIOUT_STOP], "FC"); + strcpy(szMidiGlb[MIDIOUT_NOTEON], "9c n v"); + strcpy(szMidiGlb[MIDIOUT_NOTEOFF], "9c n 0"); + strcpy(szMidiGlb[MIDIOUT_PROGRAM], "Cc p"); + // SF0: Z00-Z7F controls cutoff + CreateParameteredMacro(0, sfx_cutoff); + // Z80-Z8F controls resonance + CreateFixedMacro(zxx_reso4Bit); } -CString MIDIMacroTools::CreateParameteredMacroFromType(enmParameteredMacroType type, int subType) -//----------------------------------------------------------------------------------------------- +// Sanitize all macro config strings. +void MIDIMacroConfig::Sanitize() +//------------------------------ { - CString result; - - switch(type) + for(size_t i = 0; i < CountOf(szMidiGlb); i++) { - case sfx_unused: - result = ""; - break; - case sfx_cutoff: - result = "F0F000z"; - break; - case sfx_reso: - result = "F0F001z"; - break; - case sfx_mode: - result = "F0F002z"; - break; - case sfx_drywet: - result = "F0F003z"; - break; - case sfx_cc: - result.Format("Bc%02Xz", subType); - break; - case sfx_plug: - result.Format("F0F%03Xz", subType + 0x80); - break; - case sfx_channelAT: - result.Format("Dcz"); - break; - case sfx_polyAT: - result.Format("Acnz"); - break; + StringFixer::FixNullString(szMidiGlb[i]); } - return result; + for(size_t i = 0; i < CountOf(szMidiSFXExt); i++) + { + StringFixer::FixNullString(szMidiSFXExt[i]); + } + for(size_t i = 0; i < CountOf(szMidiZXXExt); i++) + { + StringFixer::FixNullString(szMidiZXXExt[i]); + } } -// Check if the MIDI Macro configuration used is the default one, -// i.e. the configuration that is assumed when loading a file that has no macros embedded. -bool MIDIMacroTools::IsMacroDefaultSetupUsed() const -//-------------------------------------------------- +// Remove blanks and other unwanted characters from macro strings for internal usage. +std::string MIDIMacroConfig::GetSafeMacro(const char *macro) const +//---------------------------------------------------------------- { - // TODO - Global macros + std::string sanitizedMacro = std::string(macro); - // SF0: Z00-Z7F controls cutoff - if(GetMacroType(m_SndFile.m_MidiCfg.szMidiSFXExt[0]) != sfx_cutoff) + std::string::size_type pos; + while((pos = sanitizedMacro.find_first_not_of("0123456789ABCDEFabpcnuvxyz")) != std::string::npos) { - return false; + sanitizedMacro.erase(pos, 1); } - // Z80-Z8F controls resonance - if(GetZxxType(m_SndFile.m_MidiCfg.szMidiZXXExt) != zxx_reso4Bit) - { - return false; - } - // All other parametered macros are unused - for(size_t i = 1; i < NUM_MACROS; i++) - { - if(GetMacroType(m_SndFile.m_MidiCfg.szMidiSFXExt[i]) != sfx_unused) - { - return false; - } - } - return true; + + return sanitizedMacro; } Modified: trunk/OpenMPT/soundlib/MIDIMacros.h =================================================================== --- trunk/OpenMPT/soundlib/MIDIMacros.h 2012-02-06 18:26:37 UTC (rev 1171) +++ trunk/OpenMPT/soundlib/MIDIMacros.h 2012-02-06 23:55:02 UTC (rev 1172) @@ -10,8 +10,14 @@ #ifndef MIDIMACROS_H #define MIDIMACROS_H -// parametered macro presets: -enum enmParameteredMacroType +#ifdef MODPLUG_TRACKER +class CSoundFile; +#include "PlugInterface.h" +#include "Snd_defs.h" +#endif // MODPLUG_TRACKER + +// Parametered macro presets +enum parameteredMacroType { sfx_unused = 0, sfx_cutoff, // Type 1 - Z00 - Z7F controls resonant filter cutoff @@ -28,8 +34,8 @@ }; -// fixed macro presets: -enum enmFixedMacroType +// Fixed macro presets +enum fixedMacroType { zxx_custom = 0, zxx_reso4Bit, // Type 1 - Z80 - Z8F controls resonant filter resonance @@ -44,36 +50,94 @@ }; -class MIDIMacroTools +// Global macro types +enum { -protected: - CSoundFile &m_SndFile; + MIDIOUT_START = 0, + MIDIOUT_STOP, + MIDIOUT_TICK, + MIDIOUT_NOTEON, + MIDIOUT_NOTEOFF, + MIDIOUT_VOLUME, + MIDIOUT_PAN, + MIDIOUT_BANKSEL, + MIDIOUT_PROGRAM, +}; + +#define NUM_MACROS 16 // number of parametered macros +#define MACRO_LENGTH 32 // max number of chars per macro + +//=================== +class MIDIMacroConfig +//=================== +{ + public: + + char szMidiGlb[9][MACRO_LENGTH]; // Global MIDI macros + char szMidiSFXExt[16][MACRO_LENGTH]; // Parametric MIDI macros + char szMidiZXXExt[128][MACRO_LENGTH]; // Fixed MIDI macros + +public: + + MIDIMacroConfig() { Reset(); }; + // Get macro type from a macro string - static enmParameteredMacroType GetMacroType(CString value); - static enmFixedMacroType GetZxxType(const char (&szMidiZXXExt)[128][MACRO_LENGTH]); + parameteredMacroType GetParameteredMacroType(size_t macroIndex) const; + fixedMacroType GetFixedMacroType() const; + // Create a new macro + void CreateParameteredMacro(char (¶meteredMacro)[MACRO_LENGTH], parameteredMacroType macroType, int subType) const; + void CreateParameteredMacro(size_t macroIndex, parameteredMacroType macroType, int subType = 0) + { + CreateParameteredMacro(szMidiSFXExt[macroIndex], macroType, subType); + }; + std::string CreateParameteredMacro(parameteredMacroType macroType, int subType = 0) const + { + char parameteredMacro[MACRO_LENGTH]; + CreateParameteredMacro(parameteredMacro, macroType, subType); + return std::string(parameteredMacro); + }; + + void CreateFixedMacro(char (&fixedMacros)[128][MACRO_LENGTH], fixedMacroType macroType) const; + void CreateFixedMacro(fixedMacroType macroType) + { + CreateFixedMacro(szMidiZXXExt, macroType); + }; + +#ifdef MODPLUG_TRACKER + // Translate macro type or macro string to macro name - static CString GetMacroName(enmParameteredMacroType macro); - CString GetMacroName(CString value, PLUGINDEX plugin) const; - static CString GetZxxName(enmFixedMacroType macro); + CString GetParameteredMacroName(size_t macroIndex, PLUGINDEX plugin, const CSoundFile &sndFile) const; + CString GetParameteredMacroName(parameteredMacroType macroType) const; + CString GetFixedMacroName(fixedMacroType macroType) const; - // Extract information from a macro string. - static int MacroToPlugParam(CString value); - static int MacroToMidiCC(CString value); + // Extract information from a parametered macro string. + int MacroToPlugParam(size_t macroIndex) const; + int MacroToMidiCC(size_t macroIndex) const; // Check if any macro can automate a given plugin parameter - int FindMacroForParam(long param) const; + int FindMacroForParam(PlugParamIndex param) const; - // Create a new macro - static void CreateZxxFromType(char (&szMidiZXXExt)[128][MACRO_LENGTH], enmFixedMacroType iZxxType); - static CString CreateParameteredMacroFromType(enmParameteredMacroType type, int subType = 0); - +#endif // MODPLUG_TRACKER + // Check if a given set of macros is the default IT macro set. bool IsMacroDefaultSetupUsed() const; - MIDIMacroTools(CSoundFile &sndFile) : m_SndFile(sndFile) { }; + // Reset MIDI macro config to default values. + void Reset(); + + // Sanitize all macro config strings. + void Sanitize(); + +protected: + + // Remove blanks and other unwanted characters from macro strings for internal usage. + std::string GetSafeMacro(const char *macro) const; + }; +STATIC_ASSERT(sizeof(MIDIMacroConfig) == 4896); // this is directly written to files, so the size must be correct! + #endif // MIDIMACROS_H Added: trunk/OpenMPT/soundlib/PlugInterface.h =================================================================== --- trunk/OpenMPT/soundlib/PlugInterface.h (rev 0) +++ trunk/OpenMPT/soundlib/PlugInterface.h 2012-02-06 23:55:02 UTC (rev 1172) @@ -0,0 +1,138 @@ +/* + * PlugInterface.h + * --------------- + * Purpose: Interface class and helpers for plugin handling + * Notes : (currently none) + * Authors: OpenMPT Devs + */ + +#pragma once +#ifndef PLUGINTERFACE_H +#define PLUGINTERFACE_H + +// For VstInt32 and stuff - a stupid workaround. +#ifndef NO_VST +#define VST_FORCE_DEPRECATED 0 +#include <aeffect.h> // VST +#else +typedef int32 VstInt32; +typedef intptr_t VstIntPtr; +#endif + +#include "../common/misc_util.h" + +//////////////////////////////////////////////////////////////////// +// Mix Plugins + +#define MIXPLUG_MIXREADY 0x01 // Set when cleared + +typedef VstInt32 PlugParamIndex; +typedef float PlugParamValue; + +//============== +class IMixPlugin +//============== +{ +public: + virtual int AddRef() = 0; + virtual int Release() = 0; + virtual void SaveAllParameters() = 0; + virtual void RestoreAllParameters(long nProg=-1) = 0; //rewbs.plugDefaultProgram: added param + virtual void Process(float *pOutL, float *pOutR, size_t nSamples) = 0; + virtual void Init(unsigned long nFreq, int bReset) = 0; + virtual bool MidiSend(DWORD dwMidiCode) = 0; + virtual void MidiCC(UINT nMidiCh, UINT nController, UINT nParam, UINT trackChannel) = 0; + virtual void MidiPitchBend(UINT nMidiCh, int nParam, UINT trackChannel) = 0; + virtual void MidiCommand(UINT nMidiCh, UINT nMidiProg, WORD wMidiBank, UINT note, UINT vol, UINT trackChan) = 0; + virtual void HardAllNotesOff() = 0; //rewbs.VSTCompliance + virtual void RecalculateGain() = 0; + virtual bool isPlaying(UINT note, UINT midiChn, UINT trackerChn) = 0; //rewbs.VSTiNNA + virtual bool MoveNote(UINT note, UINT midiChn, UINT sourceTrackerChn, UINT destTrackerChn) = 0; //rewbs.VSTiNNA + virtual void SetParameter(PlugParamIndex paramindex, PlugParamValue paramvalue) = 0; + virtual void SetZxxParameter(UINT nParam, UINT nValue) = 0; + virtual PlugParamValue GetParameter(PlugParamIndex nIndex) = 0; + virtual UINT GetZxxParameter(UINT nParam) = 0; //rewbs.smoothVST + virtual void ModifyParameter(PlugParamIndex nIndex, PlugParamValue diff); + virtual void AutomateParameter(PlugParamIndex param) = 0; + virtual VstIntPtr Dispatch(VstInt32 opCode, VstInt32 index, VstIntPtr value, void *ptr, float opt) =0; //rewbs.VSTCompliance + virtual void NotifySongPlaying(bool) = 0; //rewbs.VSTCompliance + virtual bool IsSongPlaying() = 0; + virtual bool IsResumed() = 0; + virtual void Resume() = 0; + virtual void Suspend() = 0; + virtual bool Bypass(bool = true) = 0; + virtual bool IsBypassed() const = 0; + bool ToggleBypass() { return Bypass(!IsBypassed()); }; + virtual bool isInstrument() = 0; + virtual bool CanRecieveMidiEvents() = 0; + virtual void SetDryRatio(UINT param) = 0; + +}; + + +inline void IMixPlugin::ModifyParameter(PlugParamIndex nIndex, PlugParamValue diff) +//--------------------------------------------------------------------------------- +{ + float val = GetParameter(nIndex) + diff; + Limit(val, PlugParamValue(0), PlugParamValue(1)); + SetParameter(nIndex, val); +} + + +/////////////////////////////////////////////////// +// !!! bits 8 -> 15 reserved for mixing mode !!! // +/////////////////////////////////////////////////// +#define MIXPLUG_INPUTF_MASTEREFFECT 0x01 // Apply to master mix +#define MIXPLUG_INPUTF_BYPASS 0x02 // Bypass effect +#define MIXPLUG_INPUTF_WETMIX 0x04 // Wet Mix (dry added) +// -> CODE#0028 +// -> DESC="effect plugin mixing mode combo" +#define MIXPLUG_INPUTF_MIXEXPAND 0x08 // [0%,100%] -> [-200%,200%] +// -! BEHAVIOUR_CHANGE#0028 + + +struct SNDMIXPLUGINSTATE +{ + DWORD dwFlags; // MIXPLUG_XXXX + LONG nVolDecayL, nVolDecayR; // Buffer click removal + int *pMixBuffer; // Stereo effect send buffer + float *pOutBufferL; // Temp storage for int -> float conversion + float *pOutBufferR; +}; +typedef SNDMIXPLUGINSTATE* PSNDMIXPLUGINSTATE; + +struct SNDMIXPLUGININFO +{ + DWORD dwPluginId1; + DWORD dwPluginId2; + DWORD dwInputRouting; // MIXPLUG_INPUTF_XXXX, bits 16-23 = gain + DWORD dwOutputRouting; // 0=mix 0x80+=fx + DWORD dwReserved[4]; // Reserved for routing info + CHAR szName[32]; + CHAR szLibraryName[64]; // original DLL name +}; // Size should be 128 +typedef SNDMIXPLUGININFO* PSNDMIXPLUGININFO; +STATIC_ASSERT(sizeof(SNDMIXPLUGININFO) == 128); // this is directly written to files, so the size must be correct! + +struct SNDMIXPLUGIN +{ + const char* GetName() const { return Info.szName; } + const char* GetLibraryName(); + CString GetParamName(const UINT index) const; + bool Bypass(bool bypass); + bool IsBypassed() const { return (Info.dwInputRouting & MIXPLUG_INPUTF_BYPASS) != 0; }; + + IMixPlugin *pMixPlugin; + PSNDMIXPLUGINSTATE pMixState; + ULONG nPluginDataSize; + PVOID pPluginData; + SNDMIXPLUGININFO Info; + float fDryRatio; // rewbs.dryRatio [20040123] + long defaultProgram; // rewbs.plugDefaultProgram +}; // rewbs.dryRatio: Hopefully this doesn't need to be a fixed size. +typedef SNDMIXPLUGIN* PSNDMIXPLUGIN; + +class CSoundFile; +typedef BOOL (__cdecl *PMIXPLUGINCREATEPROC)(PSNDMIXPLUGIN, CSoundFile*); + +#endif // PLUGINTERFACE_H Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2012-02-06 18:26:37 UTC (rev 1171) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2012-02-06 23:55:02 UTC (rev 1172) @@ -16,7 +16,6 @@ #include "sndfile.h" #include "wavConverter.h" #include "tuningcollection.h" -#include "MIDIMacros.h" #include "../common/StringFixer.h" #include <vector> #include <list> @@ -555,7 +554,6 @@ //Order.assign(MAX_ORDERS, Order.GetInvalidPatIndex()); Order.resize(1); Patterns.ClearPatterns(); - ResetMidiCfg(m_MidiCfg); for (CHANNELINDEX nChn = 0; nChn < MAX_BASECHANNELS; nChn++) { @@ -913,39 +911,7 @@ ////////////////////////////////////////////////////////////////////////// // Misc functions -void CSoundFile::ResetMidiCfg(MODMIDICFG &midiConfig) -//--------------------------------------------------- -{ - MemsetZero(midiConfig); - strcpy(midiConfig.szMidiGlb[MIDIOUT_START], "FF"); - strcpy(midiConfig.szMidiGlb[MIDIOUT_STOP], "FC"); - strcpy(midiConfig.szMidiGlb[MIDIOUT_NOTEON], "9c n v"); - strcpy(midiConfig.szMidiGlb[MIDIOUT_NOTEOFF], "9c n 0"); - strcpy(midiConfig.szMidiGlb[MIDIOUT_PROGRAM], "Cc p"); - strcpy(midiConfig.szMidiSFXExt[0], "F0F000z"); - MIDIMacroTools::CreateZxxFromType(midiConfig.szMidiZXXExt, zxx_reso4Bit); -} - -// Set null terminator for all MIDI macros -void CSoundFile::SanitizeMacros() -//------------------------------- -{ - for(size_t i = 0; i < CountOf(m_MidiCfg.szMidiGlb); i++) - { - StringFixer::FixNullString(m_MidiCfg.szMidiGlb[i]); - } - for(size_t i = 0; i < CountOf(m_MidiCfg.szMidiSFXExt); i++) - { - StringFixer::FixNullString(m_MidiCfg.szMidiSFXExt[i]); - } - for(size_t i = 0; i < CountOf(m_MidiCfg.szMidiZXXExt); i++) - { - StringFixer::FixNullString(m_MidiCfg.szMidiZXXExt[i]); - } -} - - BOOL CSoundFile::SetWaveConfig(UINT nRate,UINT nBits,UINT nChannels,BOOL bMMX) //---------------------------------------------------------------------------- { @@ -3117,7 +3083,7 @@ // Fix old-format (not conforming to IT's MIDI macro definitions) MIDI config strings. -void CSoundFile::FixMIDIConfigStrings(MODMIDICFG &midiCfg) +void CSoundFile::FixMIDIConfigStrings(MIDIMacroConfig &midiCfg) //-------------------------------------------------------- { for(size_t i = 0; i < CountOf(midiCfg.szMidiSFXExt); i++) Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2012-02-06 18:26:37 UTC (rev 1171) +++ trunk/OpenMPT/soundlib/Sndfile.h 2012-02-06 23:55:02 UTC (rev 1172) @@ -20,15 +20,8 @@ #include "Snd_defs.h" #include "Endianness.h" #include "tuning.h" +#include "MIDIMacros.h" -// For VstInt32 and stuff - a stupid workaround for IMixPlugin. -#ifndef NO_VST -#define VST_FORCE_DEPRECATED 0 -#include <aeffect.h> // VST -#else -typedef int32 VstInt32; -typedef intptr_t VstIntPtr; -#endif //class CTuningBase; //typedef CTuningBase CTuning; @@ -424,119 +417,8 @@ #include "modcommand.h" +#include "PlugInterface.h" -//////////////////////////////////////////////////////////////////// -// Mix Plugins -#define MIXPLUG_MIXREADY 0x01 // Set when cleared - -typedef VstInt32 PlugParamIndex; -typedef float PlugParamValue; - -class IMixPlugin -{ -public: - virtual int AddRef() = 0; - virtual int Release() = 0; - virtual void SaveAllParameters() = 0; - virtual void RestoreAllParameters(long nProg=-1) = 0; //rewbs.plugDefaultProgram: added param - virtual void Process(float *pOutL, float *pOutR, size_t nSamples) = 0; - virtual void Init(unsigned long nFreq, int bReset) = 0; - virtual bool MidiSend(DWORD dwMidiCode) = 0; - virtual void MidiCC(UINT nMidiCh, UINT nController, UINT nParam, UINT trackChannel) = 0; - virtual void MidiPitchBend(UINT nMidiCh, int nParam, UINT trackChannel) = 0; - virtual void MidiCommand(UINT nMidiCh, UINT nMidiProg, WORD wMidiBank, UINT note, UINT vol, UINT trackChan) = 0; - virtual void HardAllNotesOff() = 0; //rewbs.VSTCompliance - virtual void RecalculateGain() = 0; - virtual bool isPlaying(UINT note, UINT midiChn, UINT trackerChn) = 0; //rewbs.VSTiNNA - virtual bool MoveNote(UINT note, UINT midiChn, UINT sourceTrackerChn, UINT destTrackerChn) = 0; //rewbs.VSTiNNA - virtual void SetParameter(PlugParamIndex paramindex, PlugParamValue paramvalue) = 0; - virtual void SetZxxParameter(UINT nParam, UINT nValue) = 0; - virtual PlugParamValue GetParameter(PlugParamIndex nIndex) = 0; - virtual UINT GetZxxParameter(UINT nParam) = 0; //rewbs.smoothVST - virtual void ModifyParameter(PlugParamIndex nIndex, PlugParamValue diff); - virtual void AutomateParameter(PlugParamIndex param) = 0; - virtual VstIntPtr Dispatch(VstInt32 opCode, VstInt32 index, VstIntPtr value, void *ptr, float opt) =0; //rewbs.VSTCompliance - virtual void NotifySongPlaying(bool) = 0; //rewbs.VSTCompliance - virtual bool IsSongPlaying() = 0; - virtual bool IsResumed() = 0; - virtual void Resume() = 0; - virtual void Suspend() = 0; - virtual bool Bypass(bool = true) = 0; - virtual bool IsBypassed() const = 0; - bool ToggleBypass() { return Bypass(!IsBypassed()); }; - virtual bool isInstrument() = 0; - virtual bool CanRecieveMidiEvents() = 0; - virtual void SetDryRatio(UINT param) = 0; - -}; - -inline void IMixPlugin::ModifyParameter(PlugParamIndex nIndex, PlugParamValue diff) -//--------------------------------------------------------------------------------- -{ - float val = GetParameter(nIndex) + diff; - Limit(val, PlugParamValue(0), PlugParamValue(1)); - SetParameter(nIndex, val); -} - - - /////////////////////////////////////////////////// - // !!! bits 8 -> 15 reserved for mixing mode !!! // - /////////////////////////////////////////////////// -#define MIXPLUG_INPUTF_MASTEREFFECT 0x01 // Apply to master mix -#define MIXPLUG_INPUTF_BYPASS 0x02 // Bypass effect -#define MIXPLUG_INPUTF_WETMIX 0x04 // Wet Mix (dry added) -// -> CODE#0028 -// -> DESC="effect plugin mixing mode combo" -#define MIXPLUG_INPUTF_MIXEXPAND 0x08 // [0%,100%] -> [-200%,200%] -// -! BEHAVIOUR_CHANGE#0028 - - -struct SNDMIXPLUGINSTATE -{ - DWORD dwFlags; // MIXPLUG_XXXX - LONG nVolDecayL, nVolDecayR; // Buffer click removal - int *pMixBuffer; // Stereo effect send buffer - float *pOutBufferL; // Temp storage for int -> float conversion - float *pOutBufferR; -}; -typedef SNDMIXPLUGINSTATE* PSNDMIXPLUGINSTATE; - -struct SNDMIXPLUGININFO -{ - DWORD dwPluginId1; - DWORD dwPluginId2; - DWORD dwInputRouting; // MIXPLUG_INPUTF_XXXX, bits 16-23 = gain - DWORD dwOutputRouting; // 0=mix 0x80+=fx - DWORD dwReserved[4]; // Reserved for routing info - CHAR szName[32]; - CHAR szLibraryName[64]; // original DLL name -}; // Size should be 128 -typedef SNDMIXPLUGININFO* PSNDMIXPLUGININFO; -STATIC_ASSERT(sizeof(SNDMIXPLUGININFO) == 128); // this is directly written to files, so the size must be correct! - -struct SNDMIXPLUGIN -{ - const char* GetName() const { return Info.szName; } - const char* GetLibraryName(); - CString GetParamName(const U... [truncated message content] |
From: <sag...@us...> - 2012-02-07 00:11:45
|
Revision: 1173 http://modplug.svn.sourceforge.net/modplug/?rev=1173&view=rev Author: saga-games Date: 2012-02-07 00:11:38 +0000 (Tue, 07 Feb 2012) Log Message: ----------- [Fix] Envelope Editor: Two envelope points cannot be inserted on the same tick anymore. [Imp] VST: audioMasterUpdateDisplay opcode is handled (again?). [Mod] VST: Removed check for TuneFish 2.0 (seems superfluous). [Ref] A bit of refactoring a day keeps the doctor away. Modified Paths: -------------- trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/Moddoc.h trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/mptrack/View_ins.cpp trunk/OpenMPT/mptrack/Vstplug.cpp trunk/OpenMPT/soundlib/Load_mid.cpp Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2012-02-06 23:55:02 UTC (rev 1172) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2012-02-07 00:11:38 UTC (rev 1173) @@ -891,7 +891,7 @@ //---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- { CMainFrame *pMainFrm = CMainFrame::GetMainFrame(); - UINT nChn = GetNumChannels(); + CHANNELINDEX nChn = GetNumChannels(); if ((!pMainFrm) || (!note)) return FALSE; if (nVol > 256) nVol = 256; @@ -1096,18 +1096,18 @@ // Check if a given note of an instrument or sample is playing. // If note == 0, just check if an instrument or sample is playing. -BOOL CModDoc::IsNotePlaying(UINT note, UINT nsmp, UINT nins) -//---------------------------------------------------------- +bool CModDoc::IsNotePlaying(UINT note, SAMPLEINDEX nsmp, INSTRUMENTINDEX nins) +//---------------------------------------------------------------------------- { - MODCHANNEL *pChn = &m_SndFile.Chn[m_SndFile.m_nChannels]; - for (UINT i=m_SndFile.m_nChannels; i<MAX_CHANNELS; i++, pChn++) if (!pChn->nMasterChn) + MODCHANNEL *pChn = &m_SndFile.Chn[m_SndFile.GetNumChannels()]; + for (CHANNELINDEX i = m_SndFile.GetNumChannels(); i < MAX_CHANNELS; i++, pChn++) if (!pChn->nMasterChn) { if ((pChn->nLength) && (!(pChn->dwFlags & (CHN_NOTEFADE|CHN_KEYOFF|CHN_MUTE))) && ((note == pChn->nNewNote) || (!note)) && ((pChn->pModSample == &m_SndFile.GetSample(nsmp)) || (!nsmp)) - && ((pChn->pModInstrument == m_SndFile.Instruments[nins]) || (!nins))) return TRUE; + && ((pChn->pModInstrument == m_SndFile.Instruments[nins]) || (!nins))) return true; } - return FALSE; + return false; } @@ -3534,8 +3534,8 @@ -UINT CModDoc::FindAvailableChannel() -//---------------------------------- +CHANNELINDEX CModDoc::FindAvailableChannel() +//------------------------------------------ { CHANNELINDEX nStoppedChannel = CHANNELINDEX_INVALID; // Search for available channel Modified: trunk/OpenMPT/mptrack/Moddoc.h =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.h 2012-02-06 23:55:02 UTC (rev 1172) +++ trunk/OpenMPT/mptrack/Moddoc.h 2012-02-07 00:11:38 UTC (rev 1173) @@ -252,7 +252,6 @@ bool ChangeNumChannels(CHANNELINDEX nNewChannels, const bool showCancelInRemoveDlg = true); bool RemoveChannels(const vector<bool> &keepMask); CHANNELINDEX ReArrangeChannels(const vector<CHANNELINDEX> &fromToArray, const bool createUndoPoint = true); - bool MoveChannel(CHANNELINDEX chn_from, CHANNELINDEX chn_to); void CheckUsedChannels(vector<bool> &usedMask, CHANNELINDEX maxRemoveCount = MAX_BASECHANNELS) const; bool ConvertInstrumentsToSamples(); @@ -272,7 +271,7 @@ UINT PlayNote(UINT note, INSTRUMENTINDEX nins, SAMPLEINDEX nsmp, bool pause, LONG nVol=-1, SmpLength loopStart = 0, SmpLength loopEnd = 0, CHANNELINDEX nCurrentChn = CHANNELINDEX_INVALID, const SmpLength sampleOffset = 0); //rewbs.vstiLive: added current chan param BOOL NoteOff(UINT note, bool fade = false, INSTRUMENTINDEX nins = INSTRUMENTINDEX_INVALID, CHANNELINDEX nCurrentChn = CHANNELINDEX_INVALID); //rewbs.vstiLive: add params - BOOL IsNotePlaying(UINT note, UINT nsmp=0, UINT nins=0); + bool IsNotePlaying(UINT note, SAMPLEINDEX nsmp = 0, INSTRUMENTINDEX nins = 0); bool MuteChannel(CHANNELINDEX nChn, bool bMute); bool UpdateChannelMuteStatus(CHANNELINDEX nChn); bool MuteSample(SAMPLEINDEX nSample, bool bMute); @@ -426,7 +425,7 @@ private: void ChangeFileExtension(MODTYPE nNewType); - UINT FindAvailableChannel(); + CHANNELINDEX FindAvailableChannel(); }; ///////////////////////////////////////////////////////////////////////////// Modified: trunk/OpenMPT/mptrack/Modedit.cpp =================================================================== --- trunk/OpenMPT/mptrack/Modedit.cpp 2012-02-06 23:55:02 UTC (rev 1172) +++ trunk/OpenMPT/mptrack/Modedit.cpp 2012-02-07 00:11:38 UTC (rev 1173) @@ -256,51 +256,6 @@ } -bool CModDoc::MoveChannel(CHANNELINDEX chnFrom, CHANNELINDEX chnTo) -//----------------------------------------------------------------- -{ - //Implementation of move channel using ReArrangeChannels(...). So this function - //only creates correct newOrder-vector used in the ReArrangeChannels(...). - if(chnFrom == chnTo) return false; - if(chnFrom >= GetNumChannels() || chnTo >= GetNumChannels()) - { - Reporting::Error("Error: Bad move indexes in CSoundFile::MoveChannel(...)" , "MoveChannel(...)"); - return true; - } - vector<CHANNELINDEX> newOrder; - //First creating new order identical to current order... - for(CHANNELINDEX i = 0; i < GetNumChannels(); i++) - { - newOrder.push_back(i); - } - //...and then add the move channel effect. - if(chnFrom < chnTo) - { - CHANNELINDEX temp = newOrder[chnFrom]; - for(CHANNELINDEX i = chnFrom; i < chnTo; i++) - { - newOrder[i] = newOrder[i + 1]; - } - newOrder[chnTo] = temp; - } - else //case chnFrom > chnTo(can't be equal, since it has been examined earlier.) - { - CHANNELINDEX temp = newOrder[chnFrom]; - for(CHANNELINDEX i = chnFrom; i >= chnTo + 1; i--) - { - newOrder[i] = newOrder[i - 1]; - } - newOrder[chnTo] = temp; - } - - if(newOrder.size() != ReArrangeChannels(newOrder)) - { - Reporting::Error("BUG: Channel number changed in MoveChannel()"); - } - return false; -} - - // Functor for converting instrument numbers to sample numbers in the patterns struct ConvertInstrumentsToSamplesInPatterns //========================================== Modified: trunk/OpenMPT/mptrack/View_ins.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_ins.cpp 2012-02-06 23:55:02 UTC (rev 1172) +++ trunk/OpenMPT/mptrack/View_ins.cpp 2012-02-07 00:11:38 UTC (rev 1173) @@ -1066,11 +1066,18 @@ if (pIns) { if(nTick < 0) return 0; + nValue = Clamp(nValue, 0, 64); - nValue = CLAMP(nValue, 0, 64); - INSTRUMENTENVELOPE *envelope = GetEnvelopePtr(); if(envelope == nullptr) return 0; + + if(std::binary_search(envelope->Ticks, envelope->Ticks + envelope->nNodes, nTick)) + { + // Don't want to insert a node at the same position as another node. + return 0; + } + + BYTE cDefaultValue; switch(m_nEnv) @@ -1639,14 +1646,14 @@ if (rect.PtInRect(pt)) m_nDragItem = ENV_DRAGLOOPEND; } } + if (m_nDragItem) { SetCapture(); m_dwStatus |= INSSTATUS_DRAGGING; // refresh active node colour InvalidateRect(NULL, FALSE); - } - else + } else { // Shift-Click: Insert envelope point here if(CMainFrame::GetMainFrame()->GetInputHandler()->ShiftPressed()) @@ -1896,7 +1903,6 @@ void CViewInstrument::OnEnvInsertPoint() //-------------------------------------- { - EnvInsertPoint(ScreenToTick(m_ptMenu.x), ScreenToValue(m_ptMenu.y)); } Modified: trunk/OpenMPT/mptrack/Vstplug.cpp =================================================================== --- trunk/OpenMPT/mptrack/Vstplug.cpp 2012-02-06 23:55:02 UTC (rev 1172) +++ trunk/OpenMPT/mptrack/Vstplug.cpp 2012-02-07 00:11:38 UTC (rev 1173) @@ -362,12 +362,6 @@ pEffect->flags, pEffect->realQualities, pEffect->offQualities); #endif // VST_LOG - // Tunefish 2.0 doesn't seem to like that we call effClose at this point... - if(CCONST('T', 'F', '2', '0') != pEffect->uniqueID) - { - pEffect->dispatcher(pEffect, effClose, 0,0,0,0); - } - bOk = TRUE; } } catch(...) @@ -1054,16 +1048,12 @@ case audioMasterUpdateDisplay: if (pVstPlugin != nullptr) { -// pVstPlugin->GetModDoc()->UpdateAllViews(NULL, HINT_MIXPLUGINS, NULL); //No Need. - -/* CAbstractVstEditor *pVstEditor = pVstPlugin->GetEditor(); + // Note to self for testing: Electri-Q sends opcode. + CAbstractVstEditor *pVstEditor = pVstPlugin->GetEditor(); if (pVstEditor && ::IsWindow(pVstEditor->m_hWnd)) { - //pVstEditor->SetupMenu(); + pVstEditor->SetupMenu(); } -*/ -// effect->dispatcher(effect, effEditIdle, 0, 0, NULL, 0.0f); -// effect->dispatcher(effect, effEditTop, 0,0, NULL, 0); } return 0; @@ -1169,7 +1159,7 @@ } FileDlgResult files = CTrackApp::ShowOpenSaveFileDialog( - (pFileSel->command == kVstFileSave ? false : true), + (pFileSel->command != kVstFileSave), "", "", extensions, workingDir, (pFileSel->command == kVstMultipleFilesLoad) ); Modified: trunk/OpenMPT/soundlib/Load_mid.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_mid.cpp 2012-02-06 23:55:02 UTC (rev 1172) +++ trunk/OpenMPT/soundlib/Load_mid.cpp 2012-02-07 00:11:38 UTC (rev 1173) @@ -341,23 +341,6 @@ /////////////////////////////////////////////////////////////////////////// // Helper functions -static LONG __fastcall getmidilong(LPCBYTE &p, LPCBYTE pmax) -//---------------------------------------------------------- -{ - DWORD n; - UINT a; - - a = (p < pmax) ? *(p++) : 0; - n = 0; - while (a&0x80) - { - n = (n<<7)|(a&0x7F); - a = (p < pmax) ? *(p++) : 0; - } - return (n<<7)|(LONG)a; -} - - // Returns MOD tempo and tick multiplier static int ConvertMidiTempo(int tempo_us, int &tickMultiplier, int importSpeed) //------------------------------------------------------------------------------ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2012-02-07 00:16:32
|
Revision: 1174 http://modplug.svn.sourceforge.net/modplug/?rev=1174&view=rev Author: saga-games Date: 2012-02-07 00:16:25 +0000 (Tue, 07 Feb 2012) Log Message: ----------- [New] Added "Close All" short cut + menu item (tx Wayfinder). [Mod] Even when a module is not playing, the estimated tempo is now updated after a speed change in the GUI [Mod] Changed maximum width of pattern display to allow for wider displays than 4096 pixels (http://bugs.openmpt.org/view.php?id=215). [Ref] Moved samples per tick calculation around to fix the point above. [Mod] OpenMPT: Version is now 1.20.00.66 Modified Paths: -------------- trunk/OpenMPT/mptrack/CloseMainDialog.cpp trunk/OpenMPT/mptrack/CommandSet.cpp trunk/OpenMPT/mptrack/CommandSet.h trunk/OpenMPT/mptrack/InputHandler.cpp trunk/OpenMPT/mptrack/MainFrm.cpp trunk/OpenMPT/mptrack/Mptrack.cpp trunk/OpenMPT/mptrack/Mptrack.h trunk/OpenMPT/mptrack/mptrack.rc trunk/OpenMPT/mptrack/resource.h trunk/OpenMPT/mptrack/version.h trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/Sndfile.h Modified: trunk/OpenMPT/mptrack/CloseMainDialog.cpp =================================================================== --- trunk/OpenMPT/mptrack/CloseMainDialog.cpp 2012-02-07 00:11:38 UTC (rev 1173) +++ trunk/OpenMPT/mptrack/CloseMainDialog.cpp 2012-02-07 00:16:25 UTC (rev 1174) @@ -51,20 +51,15 @@ CheckDlgButton(IDC_CHECK1, BST_CHECKED); - CDocTemplate *pDocTmpl = theApp.GetModDocTemplate(); - if(pDocTmpl) + vector<CModDoc *> documents = theApp.GetOpenDocuments(); + for(vector<CModDoc *>::iterator doc = documents.begin(); doc != documents.end(); doc++) { - POSITION pos = pDocTmpl->GetFirstDocPosition(); - CDocument *pDoc; - while((pos != NULL) && ((pDoc = pDocTmpl->GetNextDoc(pos)) != NULL)) + CModDoc *pModDoc = *doc; + if(pModDoc->IsModified()) { - CModDoc *pModDoc = (CModDoc *)pDoc; - if(pModDoc->IsModified()) - { - int item = m_List.AddString(FormatTitle(pModDoc, true)); - m_List.SetItemDataPtr(item, pModDoc); - m_List.SetSel(item, TRUE); - } + int item = m_List.AddString(FormatTitle(pModDoc, true)); + m_List.SetItemDataPtr(item, pModDoc); + m_List.SetSel(item, TRUE); } } Modified: trunk/OpenMPT/mptrack/CommandSet.cpp =================================================================== --- trunk/OpenMPT/mptrack/CommandSet.cpp 2012-02-07 00:11:38 UTC (rev 1173) +++ trunk/OpenMPT/mptrack/CommandSet.cpp 2012-02-07 00:16:25 UTC (rev 1174) @@ -607,6 +607,7 @@ DefineKeyCommand(kcIncreaseSpacing, 1861, _T("Increase Row Spacing")); DefineKeyCommand(kcDecreaseSpacing, 1862, _T("Decrease Row Spacing")); DefineKeyCommand(kcSampleAutotune, 1863, _T("Tune Sample to given Note")); + DefineKeyCommand(kcFileCloseAll, 1864, _T("File/Close All")); // Add new key commands here. #ifdef _DEBUG Modified: trunk/OpenMPT/mptrack/CommandSet.h =================================================================== --- trunk/OpenMPT/mptrack/CommandSet.h 2012-02-07 00:11:38 UTC (rev 1173) +++ trunk/OpenMPT/mptrack/CommandSet.h 2012-02-07 00:16:25 UTC (rev 1174) @@ -54,6 +54,7 @@ kcFileNew=kcGlobalStart, kcFileOpen, kcFileClose, + kcFileCloseAll, kcFileSave, kcFileSaveAs, kcFileSaveTemplate, Modified: trunk/OpenMPT/mptrack/InputHandler.cpp =================================================================== --- trunk/OpenMPT/mptrack/InputHandler.cpp 2012-02-07 00:11:38 UTC (rev 1173) +++ trunk/OpenMPT/mptrack/InputHandler.cpp 2012-02-07 00:16:25 UTC (rev 1174) @@ -410,11 +410,12 @@ { case FILENEW: s="&New\t"; c = kcFileNew; break; case ID_FILE_OPEN: s="&Open...\t"; c = kcFileOpen; break; - case ID_FILE_OPENTEMPLATE: return "Open Template\t"; + case ID_FILE_OPENTEMPLATE: return "Open &Template\t"; case ID_FILE_CLOSE: s="&Close\t"; c = kcFileClose; break; + case ID_FILE_CLOSEALL: s="C&lose All\t"; c = kcFileCloseAll; break; case ID_FILE_SAVE: s="&Save\t"; c = kcFileSave; break; case ID_FILE_SAVE_AS: s="Save &As...\t"; c = kcFileSaveAs; break; - case ID_FILE_SAVEASTEMPLATE:s="Save as &Template\t"; c = kcFileSaveTemplate; break; + case ID_FILE_SAVEASTEMPLATE:s="Sa&ve as Template\t"; c = kcFileSaveTemplate; break; case ID_FILE_SAVEASWAVE: s="Export as &Wave...\t"; c = kcFileSaveAsWave; break; case ID_FILE_SAVEASMP3: s="Export as M&P3...\t"; c = kcFileSaveAsMP3; break; case ID_FILE_SAVEMIDI: s="Export as M&IDI...\t"; c = kcFileSaveMidi; break; Modified: trunk/OpenMPT/mptrack/MainFrm.cpp =================================================================== --- trunk/OpenMPT/mptrack/MainFrm.cpp 2012-02-07 00:11:38 UTC (rev 1173) +++ trunk/OpenMPT/mptrack/MainFrm.cpp 2012-02-07 00:16:25 UTC (rev 1174) @@ -2377,6 +2377,7 @@ case kcViewEditHistory: OnViewEditHistory(); break; case kcNextDocument: MDINext(); break; case kcPrevDocument: MDIPrev(); break; + case kcFileCloseAll: theApp.OnFileCloseAll(); break; //D'oh!! moddoc isn't a CWnd so we have to handle its messages and pass them on. @@ -2463,6 +2464,7 @@ pSndFile = GetActiveDoc()->GetSoundFile(); if (pSndFile) { + pSndFile->RecalculateSamplesPerTick(); return pSndFile->GetCurrentBPM(); } return 0; Modified: trunk/OpenMPT/mptrack/Mptrack.cpp =================================================================== --- trunk/OpenMPT/mptrack/Mptrack.cpp 2012-02-07 00:11:38 UTC (rev 1173) +++ trunk/OpenMPT/mptrack/Mptrack.cpp 2012-02-07 00:16:25 UTC (rev 1174) @@ -20,6 +20,7 @@ #include "UpdateCheck.h" #include "../common/StringFixer.h" #include "ExceptionHandler.h" +#include "CloseMainDialog.h" // rewbs.memLeak #define _CRTDBG_MAP_ALLOC @@ -203,6 +204,48 @@ } +void CTrackApp::OnFileCloseAll() +//------------------------------ +{ + if(!(CMainFrame::GetSettings().m_dwPatternSetup & PATTERN_NOCLOSEDIALOG)) + { + // Show modified documents window + CloseMainDialog dlg; + if(dlg.DoModal() != IDOK) + { + return; + } + } + + vector<CModDoc *> documents = theApp.GetOpenDocuments(); + for(vector<CModDoc *>::iterator doc = documents.begin(); doc != documents.end(); doc++) + { + (*doc)->SafeFileClose(); + } +} + + +// Retrieve a list of all open modules. +vector<CModDoc *> CTrackApp::GetOpenDocuments() +//--------------------------------------------- +{ + vector<CModDoc *> documents; + + CDocTemplate *pDocTmpl = theApp.GetModDocTemplate(); + if(pDocTmpl) + { + POSITION pos = pDocTmpl->GetFirstDocPosition(); + CDocument *pDoc; + while((pos != NULL) && ((pDoc = pDocTmpl->GetNextDoc(pos)) != NULL)) + { + documents.push_back(dynamic_cast<CModDoc *>(pDoc)); + } + } + + return documents; +} + + ///////////////////////////////////////////////////////////////////////////// // Common Tables @@ -563,6 +606,7 @@ // -! NEW_FEATURE#0023 ON_COMMAND(ID_NEW_MPT, OnFileNewMPT) ON_COMMAND(ID_FILE_OPEN, OnFileOpen) + ON_COMMAND(ID_FILE_CLOSEALL, OnFileCloseAll) ON_COMMAND(ID_APP_ABOUT, OnAppAbout) ON_COMMAND(ID_HELP_INDEX, CWinApp::OnHelpIndex) ON_COMMAND(ID_HELP_FINDER, CWinApp::OnHelpFinder) @@ -1528,12 +1572,12 @@ const char* const pArrCredit = { "OpenMPT / ModPlug Tracker|" - "Copyright \xA9 2004-2011 Contributors|" + "Copyright \xA9 2004-2012 Contributors|" "Copyright \xA9 1997-2003 Olivier Lapicque (ol...@mo...)|" "|" "Contributors:|" + "Johannes Schultz (2008-2012)|" "Ahti Lepp\xE4nen (2005-2011)|" - "Johannes Schultz (2008-2011)|" "Robin Fernandes (2004-2007)|" "Sergiy Pylypenko (2007)|" "Eric Chavanon (2004-2005)|" Modified: trunk/OpenMPT/mptrack/Mptrack.h =================================================================== --- trunk/OpenMPT/mptrack/Mptrack.h 2012-02-07 00:11:38 UTC (rev 1173) +++ trunk/OpenMPT/mptrack/Mptrack.h 2012-02-07 00:16:25 UTC (rev 1174) @@ -168,6 +168,8 @@ static FileDlgResult ShowOpenSaveFileDialog(const bool load, const std::string defaultExtension, const std::string defaultFilename, const std::string extFilter, const std::string workingDirectory = "", const bool allowMultiSelect = false, int *filterIndex = nullptr); + vector<CModDoc *>GetOpenDocuments(); + public: CDocTemplate *GetModDocTemplate() const { return m_pModTemplate; } CVstPluginManager *GetPluginManager() const { return m_pPluginManager; } @@ -233,6 +235,8 @@ afx_msg void OnFileOpen(); afx_msg void OnAppAbout(); afx_msg void OnHelpSearch(); + + afx_msg void OnFileCloseAll(); //}}AFX_MSG DECLARE_MESSAGE_MAP() @@ -282,16 +286,17 @@ ////////////////////////////////////////////////////////////////// // More Bitmap Helpers -#define FASTBMP_XSHIFT 12 // 4K pixels +//#define FASTBMP_XSHIFT 12 // 4K pixels +#define FASTBMP_XSHIFT 13 // 8K pixels #define FASTBMP_MAXWIDTH (1 << FASTBMP_XSHIFT) #define FASTBMP_MAXHEIGHT 16 -typedef struct MODPLUGFASTDIB +struct MODPLUGFASTDIB { BITMAPINFOHEADER bmiHeader; RGBQUAD bmiColors[256]; BYTE DibBits[FASTBMP_MAXWIDTH*FASTBMP_MAXHEIGHT]; -} MODPLUGFASTDIB, *LPMODPLUGFASTDIB; +}; //=============== class CFastBitmap Modified: trunk/OpenMPT/mptrack/mptrack.rc =================================================================== --- trunk/OpenMPT/mptrack/mptrack.rc 2012-02-07 00:11:38 UTC (rev 1173) +++ trunk/OpenMPT/mptrack/mptrack.rc 2012-02-07 00:16:25 UTC (rev 1174) @@ -2035,6 +2035,7 @@ MENUITEM "&Open...\tCtrl+O", ID_FILE_OPEN MENUITEM "Open template", 65535 MENUITEM "&Close", ID_FILE_CLOSE + MENUITEM "C&lose All", ID_FILE_CLOSEALL MENUITEM "&Save\tCtrl+S", ID_FILE_SAVE MENUITEM "Save &As...", ID_FILE_SAVE_AS MENUITEM "Save as Template...", ID_FILE_SAVEASTEMPLATE Modified: trunk/OpenMPT/mptrack/resource.h =================================================================== --- trunk/OpenMPT/mptrack/resource.h 2012-02-07 00:11:38 UTC (rev 1173) +++ trunk/OpenMPT/mptrack/resource.h 2012-02-07 00:16:25 UTC (rev 1174) @@ -1204,13 +1204,14 @@ #define ID_HELP_EXAMPLEMODULES 44459 #define ID_FILE_SAVEASTEMPLATE 44460 #define ID_ORDERLIST_INSERT_SEPARATOR 44461 -#define ID_FXCOMMANDS_BASE 44462 +#define ID_FXCOMMANDS_BASE 44462 // From here: Command range [ID_FXCOMMANDS_BASE, ID_FXCOMMANDS_BASE + 10] #define ID_PLUGINEDITOR_SLIDERS_BASE 44500 // From here: Command range [ID_PLUGINEDITOR_SLIDERS_BASE, ID_PLUGINEDITOR_SLIDERS_BASE + NUM_PLUGINEDITOR_PARAMETERS] #define ID_PLUGINEDITOR_EDIT_BASE 44550 // From here: Command range [ID_PLUGINEDITOR_EDIT_BASE, ID_PLUGINEDITOR_EDIT_BASE + NUM_PLUGINEDITOR_PARAMETERS] #define ID_HELP_SHOWSETTINGSFOLDER 44600 +#define ID_FILE_CLOSEALL 44601 // Next default values for new objects // @@ -1218,7 +1219,7 @@ #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_3D_CONTROLS 1 #define _APS_NEXT_RESOURCE_VALUE 535 -#define _APS_NEXT_COMMAND_VALUE 44601 +#define _APS_NEXT_COMMAND_VALUE 44602 #define _APS_NEXT_CONTROL_VALUE 2448 #define _APS_NEXT_SYMED_VALUE 901 #endif Modified: trunk/OpenMPT/mptrack/version.h =================================================================== --- trunk/OpenMPT/mptrack/version.h 2012-02-07 00:11:38 UTC (rev 1173) +++ trunk/OpenMPT/mptrack/version.h 2012-02-07 00:16:25 UTC (rev 1174) @@ -15,7 +15,7 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 20 #define VER_MINOR 00 -#define VER_MINORMINOR 65 +#define VER_MINORMINOR 66 //Creates version number from version parts that appears in version string. //For example MAKE_VERSION_NUMERIC(1,17,02,28) gives version number of @@ -35,7 +35,7 @@ const char* const str = MPT_VERSION_STR; // Returns numerical version value from given version string. - static VersionNum ToNum(const char* const s) + static VersionNum ToNum(const char *const s) { int v1, v2, v3, v4; sscanf(s, "%x.%x.%x.%x", &v1, &v2, &v3, &v4); Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2012-02-07 00:11:38 UTC (rev 1173) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2012-02-07 00:16:25 UTC (rev 1174) @@ -742,15 +742,7 @@ InitializeVisitedRows(true); - switch(m_nTempoMode) - { - case tempo_mode_alternative: - m_nSamplesPerTick = gdwMixingFreq / m_nMusicTempo; break; - case tempo_mode_modern: - m_nSamplesPerTick = gdwMixingFreq * (60/m_nMusicTempo / (m_nMusicSpeed * m_nCurrentRowsPerBeat)); break; - case tempo_mode_classic: default: - m_nSamplesPerTick = (gdwMixingFreq * 5 * m_nTempoFactor) / (m_nMusicTempo << 8); - } + RecalculateSamplesPerTick(); if ((m_nRestartPos >= Order.size()) || (Order[m_nRestartPos] >= Patterns.Size())) m_nRestartPos = 0; @@ -1007,8 +999,8 @@ return pos + m_nRow; } -double CSoundFile::GetCurrentBPM() const -//--------------------------------------- +double CSoundFile::GetCurrentBPM() const +//-------------------------------------- { double bpm; @@ -2290,6 +2282,7 @@ DWORD CSoundFile::TransposeToFrequency(int transp, int ftune) //----------------------------------------------------------- { + // return (unsigned int) (8363.0 * pow(2, (transp * 128.0 + ftune) / 1536.0)); const float _fbase = 8363; const float _factor = 1.0f/(12.0f*128.0f); int result; @@ -2325,6 +2318,8 @@ int CSoundFile::FrequencyToTranspose(DWORD freq) //---------------------------------------------- { + // return (int) (1536.0 * (log(freq / 8363.0) / log(2))); + const float _f1_8363 = 1.0f / 8363.0f; const float _factor = 128 * 12; LONG result; @@ -2348,7 +2343,7 @@ int f2t = FrequencyToTranspose(psmp->nC5Speed); int transp = f2t >> 7; int ftune = f2t & 0x7F; //0x7F == 111 1111 - if (ftune > 80) // XXX I'm pretty sure this is supposed to be 0x80. + if (ftune > 80) // XXX Why is this 80? { transp++; ftune -= 128; @@ -2772,6 +2767,24 @@ } +// Calculate the length of a tick, depending on the tempo mode. +void CSoundFile::RecalculateSamplesPerTick() +//------------------------------------------ +{ + switch(m_nTempoMode) + { + case tempo_mode_alternative: + m_nSamplesPerTick = gdwMixingFreq / m_nMusicTempo; + break; + case tempo_mode_modern: + m_nSamplesPerTick = gdwMixingFreq * (60/m_nMusicTempo / (m_nMusicSpeed * m_nCurrentRowsPerBeat)); + break; + case tempo_mode_classic: default: + m_nSamplesPerTick = (gdwMixingFreq * 5 * m_nTempoFactor) / (m_nMusicTempo << 8); + } +} + + // Get the duration of a row in milliseconds, based on the current rows per beat and given speed and tempo settings. double CSoundFile::GetRowDuration(UINT speed, UINT tempo) const //------------------------------------------------------------- Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2012-02-07 00:11:38 UTC (rev 1173) +++ trunk/OpenMPT/soundlib/Sndfile.h 2012-02-07 00:16:25 UTC (rev 1174) @@ -732,6 +732,7 @@ //Returns song length in seconds. DWORD GetSongTime() { return static_cast<DWORD>((m_nTempoMode == tempo_mode_alternative) ? GetLength(eNoAdjust).duration + 1.0 : GetLength(eNoAdjust).duration + 0.5); } + void RecalculateSamplesPerTick(); double GetRowDuration(UINT speed, UINT tempo) const; // A repeat count value of -1 means infinite loop @@ -844,7 +845,6 @@ static BOOL SetWaveConfig(UINT nRate,UINT nBits,UINT nChannels,BOOL bMMX=FALSE); static BOOL SetDspEffects(BOOL bSurround,BOOL bReverb,BOOL xbass,BOOL dolbynr=FALSE,BOOL bEQ=FALSE); static BOOL SetResamplingMode(UINT nMode); // SRCMODE_XXXX - static BOOL IsStereo() { return (gnChannels > 1) ? TRUE : FALSE; } static DWORD GetSampleRate() { return gdwMixingFreq; } static DWORD GetBitsPerSample() { return gnBitsPerSample; } static DWORD InitSysInfo(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |