From: <sag...@us...> - 2011-11-05 15:15:57
|
Revision: 1132 http://modplug.svn.sourceforge.net/modplug/?rev=1132&view=rev Author: saga-games Date: 2011-11-05 15:15:50 +0000 (Sat, 05 Nov 2011) Log Message: ----------- [Mod] Further cleanup of mod cleanup code (lol) [Fix] When converting from IT / MPTM to other formats, the sustain loop's bidi flag is transferred. [Fix] IT Compatibility: A cutoff frequency of 0 should not be reset to "no cutoff" just because the filter envelope is enabled. Modified Paths: -------------- trunk/OpenMPT/mptrack/CleanupSong.cpp trunk/OpenMPT/mptrack/ModConvert.cpp trunk/OpenMPT/soundlib/Load_imf.cpp trunk/OpenMPT/soundlib/Snd_fx.cpp trunk/OpenMPT/soundlib/modsmp_ctrl.cpp trunk/OpenMPT/soundlib/modsmp_ctrl.h Modified: trunk/OpenMPT/mptrack/CleanupSong.cpp =================================================================== --- trunk/OpenMPT/mptrack/CleanupSong.cpp 2011-11-03 21:15:10 UTC (rev 1131) +++ trunk/OpenMPT/mptrack/CleanupSong.cpp 2011-11-05 15:15:50 UTC (rev 1132) @@ -97,7 +97,7 @@ CDialog::OnInitDialog(); for(int i = 0; i < CU_MAX_CLEANUP_OPTIONS; i++) { - CheckDlgButton(m_nCleanupIDtoDlgID[i], (m_bCheckBoxes[i]) ? MF_CHECKED : MF_UNCHECKED); + CheckDlgButton(m_nCleanupIDtoDlgID[i], (m_bCheckBoxes[i]) ? BST_CHECKED : BST_UNCHECKED); } CSoundFile *pSndFile = m_pModDoc->GetSoundFile(); @@ -183,17 +183,17 @@ if(hFocus == GetDlgItem(m_nCleanupIDtoDlgID[i])->m_hWnd) { // if we just unchecked it, there's nothing to verify. - if(IsDlgButtonChecked(m_nCleanupIDtoDlgID[i]) == FALSE) + if(IsDlgButtonChecked(m_nCleanupIDtoDlgID[i]) == BST_UNCHECKED) return; // now we can disable all elements that are mutually exclusive. if(m_nMutuallyExclusive[i] != CU_NONE) - CheckDlgButton(m_nCleanupIDtoDlgID[m_nMutuallyExclusive[i]], MF_UNCHECKED); + CheckDlgButton(m_nCleanupIDtoDlgID[m_nMutuallyExclusive[i]], BST_UNCHECKED); // find other elements which are mutually exclusive with the selected element. for(int j = 0; j < CU_MAX_CLEANUP_OPTIONS; j++) { if(m_nMutuallyExclusive[j] == i) - CheckDlgButton(m_nCleanupIDtoDlgID[j], MF_UNCHECKED); + CheckDlgButton(m_nCleanupIDtoDlgID[j], BST_UNCHECKED); } return; } @@ -205,50 +205,50 @@ //---------------------------------------- { // patterns - CheckDlgButton(IDC_CHK_CLEANUP_PATTERNS, MF_CHECKED); - CheckDlgButton(IDC_CHK_REMOVE_PATTERNS, MF_UNCHECKED); - CheckDlgButton(IDC_CHK_REARRANGE_PATTERNS, MF_CHECKED); + CheckDlgButton(IDC_CHK_CLEANUP_PATTERNS, BST_CHECKED); + CheckDlgButton(IDC_CHK_REMOVE_PATTERNS, BST_UNCHECKED); + CheckDlgButton(IDC_CHK_REARRANGE_PATTERNS, BST_CHECKED); // orders - CheckDlgButton(IDC_CHK_MERGE_SEQUENCES, MF_UNCHECKED); - CheckDlgButton(IDC_CHK_REMOVE_ORDERS, MF_UNCHECKED); + CheckDlgButton(IDC_CHK_MERGE_SEQUENCES, BST_UNCHECKED); + CheckDlgButton(IDC_CHK_REMOVE_ORDERS, BST_UNCHECKED); // samples - CheckDlgButton(IDC_CHK_CLEANUP_SAMPLES, MF_CHECKED); - CheckDlgButton(IDC_CHK_REMOVE_SAMPLES, MF_UNCHECKED); - CheckDlgButton(IDC_CHK_REARRANGE_SAMPLES, MF_UNCHECKED); - CheckDlgButton(IDC_CHK_OPTIMIZE_SAMPLES, MF_CHECKED); + CheckDlgButton(IDC_CHK_CLEANUP_SAMPLES, BST_CHECKED); + CheckDlgButton(IDC_CHK_REMOVE_SAMPLES, BST_UNCHECKED); + CheckDlgButton(IDC_CHK_REARRANGE_SAMPLES, BST_UNCHECKED); + CheckDlgButton(IDC_CHK_OPTIMIZE_SAMPLES, BST_CHECKED); // instruments - CheckDlgButton(IDC_CHK_CLEANUP_INSTRUMENTS, MF_CHECKED); - CheckDlgButton(IDC_CHK_REMOVE_INSTRUMENTS, MF_UNCHECKED); + CheckDlgButton(IDC_CHK_CLEANUP_INSTRUMENTS, BST_CHECKED); + CheckDlgButton(IDC_CHK_REMOVE_INSTRUMENTS, BST_UNCHECKED); // plugins - CheckDlgButton(IDC_CHK_CLEANUP_PLUGINS, MF_CHECKED); - CheckDlgButton(IDC_CHK_REMOVE_PLUGINS, MF_UNCHECKED); + CheckDlgButton(IDC_CHK_CLEANUP_PLUGINS, BST_CHECKED); + CheckDlgButton(IDC_CHK_REMOVE_PLUGINS, BST_UNCHECKED); // misc - CheckDlgButton(IDC_CHK_SAMPLEPACK, MF_UNCHECKED); + CheckDlgButton(IDC_CHK_SAMPLEPACK, BST_UNCHECKED); } void CModCleanupDlg::OnPresetCompoCleanup() //----------------------------------------- { // patterns - CheckDlgButton(IDC_CHK_CLEANUP_PATTERNS, MF_UNCHECKED); - CheckDlgButton(IDC_CHK_REMOVE_PATTERNS, MF_CHECKED); - CheckDlgButton(IDC_CHK_REARRANGE_PATTERNS, MF_UNCHECKED); + CheckDlgButton(IDC_CHK_CLEANUP_PATTERNS, BST_UNCHECKED); + CheckDlgButton(IDC_CHK_REMOVE_PATTERNS, BST_CHECKED); + CheckDlgButton(IDC_CHK_REARRANGE_PATTERNS, BST_UNCHECKED); // orders - CheckDlgButton(IDC_CHK_MERGE_SEQUENCES, MF_UNCHECKED); - CheckDlgButton(IDC_CHK_REMOVE_ORDERS, MF_CHECKED); + CheckDlgButton(IDC_CHK_MERGE_SEQUENCES, BST_UNCHECKED); + CheckDlgButton(IDC_CHK_REMOVE_ORDERS, BST_CHECKED); // samples - CheckDlgButton(IDC_CHK_CLEANUP_SAMPLES, MF_UNCHECKED); - CheckDlgButton(IDC_CHK_REMOVE_SAMPLES, MF_UNCHECKED); - CheckDlgButton(IDC_CHK_REARRANGE_SAMPLES, MF_CHECKED); - CheckDlgButton(IDC_CHK_OPTIMIZE_SAMPLES, MF_UNCHECKED); + CheckDlgButton(IDC_CHK_CLEANUP_SAMPLES, BST_UNCHECKED); + CheckDlgButton(IDC_CHK_REMOVE_SAMPLES, BST_UNCHECKED); + CheckDlgButton(IDC_CHK_REARRANGE_SAMPLES, BST_CHECKED); + CheckDlgButton(IDC_CHK_OPTIMIZE_SAMPLES, BST_UNCHECKED); // instruments - CheckDlgButton(IDC_CHK_CLEANUP_INSTRUMENTS, MF_UNCHECKED); - CheckDlgButton(IDC_CHK_REMOVE_INSTRUMENTS, MF_CHECKED); + CheckDlgButton(IDC_CHK_CLEANUP_INSTRUMENTS, BST_UNCHECKED); + CheckDlgButton(IDC_CHK_REMOVE_INSTRUMENTS, BST_CHECKED); // plugins - CheckDlgButton(IDC_CHK_CLEANUP_PLUGINS, MF_UNCHECKED); - CheckDlgButton(IDC_CHK_REMOVE_PLUGINS, MF_CHECKED); + CheckDlgButton(IDC_CHK_CLEANUP_PLUGINS, BST_UNCHECKED); + CheckDlgButton(IDC_CHK_REMOVE_PLUGINS, BST_CHECKED); // misc - CheckDlgButton(IDC_CHK_SAMPLEPACK, MF_CHECKED); + CheckDlgButton(IDC_CHK_SAMPLEPACK, BST_CHECKED); } BOOL CModCleanupDlg::OnToolTipNotify(UINT id, NMHDR* pNMHDR, LRESULT* pResult) @@ -352,7 +352,7 @@ CString name; // original pattern name }; -const OrigPatSettings defaultSettings = {false, 0, nullptr, 0, 0, 0, ""}; +const OrigPatSettings defaultSettings = { false, 0, nullptr, 0, 0, 0, "" }; // Remove unused patterns / rearrange patterns // If argument bRemove is true, unused patterns are removed. Else, patterns are only rearranged. @@ -409,7 +409,6 @@ nPatRemoved++; } } - cs.Leave(); // Number of unused patterns size_t nWaste = 0; @@ -420,10 +419,12 @@ if ((bRemove) && (nWaste)) { + cs.Leave(); EndWaitCursor(); wsprintf(s, "%d pattern%s present in file, but not used in the song\nDo you want to reorder the sequence list and remove these patterns?", nWaste, (nWaste == 1) ? "" : "s"); if (Reporting::Confirm(s, "Pattern Cleanup") != cnfYes) return false; BeginWaitCursor(); + cs.Enter(); } for(PATTERNINDEX i = 0; i < maxPatIndex; i++) @@ -466,7 +467,6 @@ pSndFile->Order.SetSequence(oldSequence); // Reorder patterns & Delete unused patterns - cs.Enter(); { for (PATTERNINDEX i = 0; i < maxPatIndex; i++) { @@ -496,6 +496,7 @@ pSndFile->Patterns[nPat].SetName(patternSettings[nPat].name); } } + cs.Leave(); EndWaitCursor(); if ((nPatRemoved) || (bReordered)) @@ -523,6 +524,9 @@ vector<bool> samplesUsed(pSndFile->GetNumSamples() + 1, true); BeginWaitCursor(); + + // Check if any samples are not referenced in the patterns (sample mode) or by an instrument (instrument mode). + // This doesn't check yet if a sample is referenced by an instrument, but actually unused in the patterns. for(SAMPLEINDEX nSmp = pSndFile->GetNumSamples(); nSmp >= 1; nSmp--) if (pSndFile->GetSample(nSmp).pSample) { if(!pSndFile->IsSampleUsed(nSmp)) @@ -532,8 +536,7 @@ } } - SAMPLEINDEX nRemoved; - nRemoved = pSndFile->RemoveSelectedSamples(samplesUsed); + SAMPLEINDEX nRemoved = pSndFile->RemoveSelectedSamples(samplesUsed); const SAMPLEINDEX unusedInsSamples = pSndFile->DetectUnusedSamples(samplesUsed); @@ -547,15 +550,6 @@ if(Reporting::Confirm(s, "Sample Cleanup") == cnfYes) { nRemoved += pSndFile->RemoveSelectedSamples(samplesUsed); - // Reduce the number of sample slots if possible. - for(SAMPLEINDEX nSmp = pSndFile->GetNumSamples(); nSmp >= 1; nSmp--) - { - if(samplesUsed[nSmp]) - { - pSndFile->m_nSamples = nSmp; - break; - } - } } } @@ -797,7 +791,7 @@ } } while ((pSndFile->m_nInstruments > 1) && (!pSndFile->Instruments[pSndFile->m_nInstruments])) pSndFile->m_nInstruments--; - cs.Leave(); + if (nSwap > 0) { for (PATTERNINDEX iPat = 0; iPat < pSndFile->Patterns.Size(); iPat++) if (pSndFile->Patterns[iPat]) @@ -985,17 +979,12 @@ if(pSndFile == nullptr) return false; if (pSndFile->GetNumSamples() == 0) return false; - vector<bool> keepSamples(pSndFile->GetNumSamples() + 1, false); - for (SAMPLEINDEX nSmp = 1; nSmp <= pSndFile->GetNumSamples(); nSmp++) - { - m_pModDoc->GetSampleUndo().PrepareUndo(nSmp, sundo_delete, 0, pSndFile->GetSample(nSmp).nLength); - } - ctrlSmp::ResetSamples(*pSndFile, ctrlSmp::SmpResetInit); - - CriticalSection cs; + vector<bool> keepSamples(pSndFile->GetNumSamples() + 1, false); pSndFile->RemoveSelectedSamples(keepSamples); + ctrlSmp::ResetSamples(*pSndFile, ctrlSmp::SmpResetInit, 1, MAX_SAMPLES - 1); + return true; } Modified: trunk/OpenMPT/mptrack/ModConvert.cpp =================================================================== --- trunk/OpenMPT/mptrack/ModConvert.cpp 2011-11-03 21:15:10 UTC (rev 1131) +++ trunk/OpenMPT/mptrack/ModConvert.cpp 2011-11-05 15:15:50 UTC (rev 1132) @@ -174,8 +174,7 @@ MODCOMMAND *m = m_SndFile.Patterns[nPat]; // This is used for -> MOD/XM conversion - vector<vector<MODCOMMAND::PARAM> > cEffectMemory; - cEffectMemory.resize(GetNumChannels()); + vector<vector<MODCOMMAND::PARAM> > cEffectMemory(GetNumChannels()); for(size_t i = 0; i < GetNumChannels(); i++) { cEffectMemory[i].resize(MAX_EFFECTS, 0); @@ -294,6 +293,13 @@ 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; Modified: trunk/OpenMPT/soundlib/Load_imf.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_imf.cpp 2011-11-03 21:15:10 UTC (rev 1131) +++ trunk/OpenMPT/soundlib/Load_imf.cpp 2011-11-05 15:15:50 UTC (rev 1132) @@ -95,7 +95,7 @@ }; #pragma pack() -static BYTE imf_efftrans[] = +static BYTE imfEffects[] = { CMD_NONE, CMD_SPEED, // 0x01 1xx Set Tempo @@ -145,8 +145,8 @@ CMD_NONE, // 0x23 Zxx Reverb - XXX }; -static void import_imf_effect(MODCOMMAND *note) -//--------------------------------------------- +static void ImportIMFEffect(MODCOMMAND *note) +//------------------------------------------- { uint8 n; // fix some of them @@ -232,7 +232,7 @@ note->param = n | (note->param & 0xf); break; } - note->command = (note->command < 0x24) ? imf_efftrans[note->command] : CMD_NONE; + note->command = (note->command < CountOf(imfEffects)) ? imfEffects[note->command] : CMD_NONE; if (note->command == CMD_VOLUME && note->volcmd == VOLCMD_NONE) { note->volcmd = VOLCMD_VOLUME; @@ -242,8 +242,8 @@ } } -static void load_imf_envelope(INSTRUMENTENVELOPE *env, const IMFINSTRUMENT *imfins, const int e) -//---------------------------------------------------------------------------------------------- +static void LoadIMFEnvelope(INSTRUMENTENVELOPE *env, const IMFINSTRUMENT *imfins, const int e) +//-------------------------------------------------------------------------------------------- { UINT min = 0; // minimum tick value for next node const int shift = (e == IMF_ENV_VOL) ? 0 : 2; @@ -272,10 +272,9 @@ IMFHEADER hdr; MODSAMPLE *pSample = Samples + 1; WORD firstsample = 1; // first pSample for the current instrument - uint32 ignore_channels = 0; // bit set for each channel that's completely disabled + vector<bool> ignoreChannels(32, false); // bit set for each channel that's completely disabled ASSERT_CAN_READ(sizeof(IMFHEADER)); - memset(&hdr, 0, sizeof(IMFHEADER)); memcpy(&hdr, lpStream, sizeof(IMFHEADER)); dwMemPos = sizeof(IMFHEADER); @@ -284,7 +283,7 @@ hdr.insnum = LittleEndianW(hdr.insnum); hdr.flags = LittleEndianW(hdr.flags); - if (memcmp(hdr.im10, "IM10", 4) != 0) + if(memcmp(hdr.im10, "IM10", 4) != 0) return false; m_nType = MOD_TYPE_IMF; @@ -326,7 +325,7 @@ break; case 2: // disabled ChnSettings[nChn].dwFlags |= CHN_MUTE; - ignore_channels |= (1 << nChn); + ignoreChannels[nChn] = true; break; default: // uhhhh.... freak out //fprintf(stderr, "imf: channel %d has unknown status %d\n", n, hdr.channels[n].status); @@ -376,7 +375,8 @@ ASSERT_CAN_READ(1); mask = *((BYTE *)(lpStream + dwMemPos)); dwMemPos += 1; - if (mask == 0) { + if (mask == 0) + { row++; row_data += m_nChannels; continue; @@ -384,7 +384,7 @@ channel = mask & 0x1f; - if(ignore_channels & (1 << channel)) + if(ignoreChannels[channel]) { /* should do this better, i.e. not go through the whole process of deciding what to do with the effects since they're just being thrown out */ @@ -474,7 +474,7 @@ dwMemPos += 2; } if(note->command) - import_imf_effect(note); + ImportIMFEffect(note); } } @@ -484,7 +484,6 @@ IMFINSTRUMENT imfins; MODINSTRUMENT *pIns; ASSERT_CAN_READ(sizeof(IMFINSTRUMENT)); - memset(&imfins, 0, sizeof(IMFINSTRUMENT)); memcpy(&imfins, lpStream + dwMemPos, sizeof(IMFINSTRUMENT)); dwMemPos += sizeof(IMFINSTRUMENT); m_nInstruments++; @@ -520,9 +519,9 @@ pIns->nFadeOut = imfins.fadeout; - load_imf_envelope(&pIns->VolEnv, &imfins, IMF_ENV_VOL); - load_imf_envelope(&pIns->PanEnv, &imfins, IMF_ENV_PAN); - load_imf_envelope(&pIns->PitchEnv, &imfins, IMF_ENV_FILTER); + LoadIMFEnvelope(&pIns->VolEnv, &imfins, IMF_ENV_VOL); + LoadIMFEnvelope(&pIns->PanEnv, &imfins, IMF_ENV_PAN); + LoadIMFEnvelope(&pIns->PitchEnv, &imfins, IMF_ENV_FILTER); if((pIns->PitchEnv.dwFlags & ENV_ENABLED) != 0) pIns->PitchEnv.dwFlags |= ENV_FILTER; @@ -536,7 +535,6 @@ IMFSAMPLE imfsmp; uint32 blen; ASSERT_CAN_READ(sizeof(IMFSAMPLE)); - memset(&imfsmp, 0, sizeof(IMFSAMPLE)); memcpy(&imfsmp, lpStream + dwMemPos, sizeof(IMFSAMPLE)); dwMemPos += sizeof(IMFSAMPLE); m_nSamples++; Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp =================================================================== --- trunk/OpenMPT/soundlib/Snd_fx.cpp 2011-11-03 21:15:10 UTC (rev 1131) +++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2011-11-05 15:15:50 UTC (rev 1132) @@ -761,10 +761,14 @@ pChn->VolEnv.flags = pIns->VolEnv.dwFlags; pChn->PanEnv.flags = pIns->PanEnv.dwFlags; pChn->PitchEnv.flags = pIns->PitchEnv.dwFlags; - if ((pIns->PitchEnv.dwFlags & ENV_ENABLED) && (pIns->PitchEnv.dwFlags & ENV_FILTER)) + + // A cutoff frequency of 0 should not be reset just because the filter envelope is enabled. + // Test case: FilterEnvReset.it + if ((pIns->PitchEnv.dwFlags & (ENV_ENABLED | ENV_FILTER)) == (ENV_ENABLED | ENV_FILTER) && !IsCompatibleMode(TRK_IMPULSETRACKER)) { if (!pChn->nCutOff) pChn->nCutOff = 0x7F; } + if (pIns->IsCutoffEnabled()) pChn->nCutOff = pIns->GetCutoff(); if (pIns->IsResonanceEnabled()) pChn->nResonance = pIns->GetResonance(); } Modified: trunk/OpenMPT/soundlib/modsmp_ctrl.cpp =================================================================== --- trunk/OpenMPT/soundlib/modsmp_ctrl.cpp 2011-11-03 21:15:10 UTC (rev 1131) +++ trunk/OpenMPT/soundlib/modsmp_ctrl.cpp 2011-11-05 15:15:50 UTC (rev 1132) @@ -217,12 +217,27 @@ } -void ResetSamples(CSoundFile &rSndFile, ResetFlag resetflag) -//---------------------------------------------------------- +void ResetSamples(CSoundFile &rSndFile, ResetFlag resetflag, SAMPLEINDEX minSample, SAMPLEINDEX maxSample) +//-------------------------------------------------------------------------------------------------------- { - const UINT nSamples = rSndFile.GetNumSamples(); - for(UINT i = 1; i <= nSamples; i++) + if(minSample == SAMPLEINDEX_INVALID) { + minSample = 1; + } + if(maxSample == SAMPLEINDEX_INVALID) + { + maxSample = rSndFile.GetNumSamples(); + } + Limit(minSample, SAMPLEINDEX(1), SAMPLEINDEX(MAX_SAMPLES - 1)); + Limit(maxSample, SAMPLEINDEX(1), SAMPLEINDEX(MAX_SAMPLES - 1)); + + if(minSample > maxSample) + { + std::swap(minSample, maxSample); + } + + for(SAMPLEINDEX i = minSample; i <= maxSample; i++) + { MODSAMPLE &sample = rSndFile.GetSample(i); switch(resetflag) { @@ -492,6 +507,51 @@ template <class T> +bool EnableSmartSampleRampingImpl(const T* pSample, const SmpLength smpCount) +//--------------------------------------------------------------------------- +{ + const T upperThreshold = (std::numeric_limits<T>::max)() / 2; // >= 50% + const T lowerThreshold = (std::numeric_limits<T>::max)() / 40; // <= 2.5% + + // Count backwards for a weighted mean (first samples have the most significant weight). + T average = pSample[smpCount - 1]; + for(SmpLength i = smpCount; i > 0; i--) + { + T data = pSample[i - 1]; + if(data < 0) data = -data; + average = (data + average) / 2; + } + if(average >= upperThreshold || average <= lowerThreshold) return true; + return false; +} + +// This function detects whether to enable smart sample ramping or not, based on the initial DC offset. +// If the DC offset is very high (>= 50%), we can assume that it is somehow intentional (imagine f.e. a typical square waveform sample). +// On the other side, if the initial DC offset is very low (<= 2.5%), we do not need to apply ramping, so we can retain the punch of properly aligned samples. +// Eventually, ramping will (hopefully) only be performed on "bad" samples. +// The function returns true if ramping should be forced off, false if it can stay enabled. +// TODO: It would be a lot nicer if this would pre-normalize samples. +bool EnableSmartSampleRamping(const MODSAMPLE &smp, SmpLength sampleOffset, const CSoundFile *pSndFile) +//----------------------------------------------------------------------------------------------------- +{ + // First two sample points are supposed to be 0 for unlooped MOD samples, so don't take them into account. + if((smp.uFlags & CHN_LOOP) && (pSndFile->GetType() & MOD_TYPE_MOD) && sampleOffset == 0) sampleOffset = 2; + + // Just look at the first four samples, starting from the given offset. + sampleOffset = min(sampleOffset, smp.nLength); + const SmpLength smpCount = min(4, smp.nLength - sampleOffset) * smp.GetNumChannels(); + + if(smp.pSample == nullptr || smpCount == 0) return false; + if(smp.GetElementarySampleSize() == 2) + return EnableSmartSampleRampingImpl(reinterpret_cast<int16*>(smp.pSample) + sampleOffset, smpCount); + else if(smp.GetElementarySampleSize() == 1) + return EnableSmartSampleRampingImpl(reinterpret_cast<int8*>(smp.pSample) + sampleOffset, smpCount); + else + return false; +} + + +template <class T> void XFadeSampleImpl(T* pStart, const SmpLength nOffset, SmpLength nFadeLength) //----------------------------------------------------------------------------- { Modified: trunk/OpenMPT/soundlib/modsmp_ctrl.h =================================================================== --- trunk/OpenMPT/soundlib/modsmp_ctrl.h 2011-11-03 21:15:10 UTC (rev 1131) +++ trunk/OpenMPT/soundlib/modsmp_ctrl.h 2011-11-05 15:15:50 UTC (rev 1132) @@ -39,7 +39,7 @@ inline SmpLength GetSampleCapacity(MODSAMPLE &smp) {return smp.GetSampleSizeInBytes();} // Resets samples. -void ResetSamples(CSoundFile &rSndFile, ResetFlag resetflag); +void ResetSamples(CSoundFile &rSndFile, ResetFlag resetflag, SAMPLEINDEX minSample = SAMPLEINDEX_INVALID, SAMPLEINDEX maxSample = SAMPLEINDEX_INVALID); // Remove DC offset and normalize. // Return: If DC offset was removed, returns original offset value, zero otherwise. @@ -51,6 +51,9 @@ // Volume adjustment is not done if this param is MOD_TYPE_NONE. CSoundFile* const pSndFile); // Passed to AdjustEndOfSample. +// Amplify / fade sample data +bool AmplifySample(MODSAMPLE &smp, SmpLength iStart, SmpLength iEnd, CSoundFile *pSndFile, double amplifyStart, double amplifyEnd); + // Reverse sample data bool ReverseSample(MODSAMPLE &smp, SmpLength iStart, SmpLength iEnd, CSoundFile *pSndFile); @@ -60,6 +63,9 @@ // Invert sample data (flip by 180 degrees) bool InvertSample(MODSAMPLE &smp, SmpLength iStart, SmpLength iEnd, CSoundFile *pSndFile); +// Detect whether to enable smart sample ramping. +bool EnableSmartSampleRamping(const MODSAMPLE &smp, SmpLength sampleOffset, const CSoundFile *pSndFile); + // Crossfade sample data to create smooth loops bool XFadeSample(MODSAMPLE &smp, SmpLength iFadeLength, CSoundFile *pSndFile); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |