From: <sag...@us...> - 2014-10-26 15:28:05
|
Revision: 4504 http://sourceforge.net/p/modplug/code/4504 Author: saga-games Date: 2014-10-26 15:27:49 +0000 (Sun, 26 Oct 2014) Log Message: ----------- [New] MPTM files can now contain external (on-disk) samples. When checking the "Keep sample on disk" checkbox in the sample editor, the sample data is not stored directly in the MPTM file but a relative link to the original sample file is kept. [New] Tree view: Due to the change from external instruments in the ITP format to external samples in MPTM, "Set Path" and "Save" have been moved to samples, and "Reload" has been added to reload a waveform (also works in other formats as long as OpenMPT knows the sample path. External samples are marked with [external], missing external samples are marked with [missing]. [New] Instrument tab: ITI instruments can now (like MPTM files) contain external samples. Select "Impulse Tracker Instruments with external Samples" from the save dialog. [Reg] ITP support is now read-only, ITP files are imported as normal IT files. [Ref] Added new switch in BuildSettings.h: MPT_EXTERNAL_SAMPLES determines whether module loaders may load external samples / instruments (only supported in OpenMPT at the moment) [Mod] OpenMPT: Version is now 1.24.00.14 Modified Paths: -------------- trunk/OpenMPT/common/BuildSettings.h trunk/OpenMPT/common/mptIO.h trunk/OpenMPT/common/versionNumber.h trunk/OpenMPT/installer/filetypes.iss trunk/OpenMPT/mptrack/AutoSaver.cpp trunk/OpenMPT/mptrack/CleanupSong.cpp trunk/OpenMPT/mptrack/Ctrl_gen.cpp trunk/OpenMPT/mptrack/Ctrl_ins.cpp trunk/OpenMPT/mptrack/Ctrl_smp.cpp trunk/OpenMPT/mptrack/Ctrl_smp.h trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/Moddoc.h trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/mptrack/Mptrack.cpp trunk/OpenMPT/mptrack/Mptrack.h trunk/OpenMPT/mptrack/TrackerSettings.cpp trunk/OpenMPT/mptrack/View_ins.cpp trunk/OpenMPT/mptrack/View_smp.cpp trunk/OpenMPT/mptrack/View_smp.h trunk/OpenMPT/mptrack/View_tre.cpp trunk/OpenMPT/mptrack/View_tre.h trunk/OpenMPT/mptrack/dlg_misc.cpp trunk/OpenMPT/mptrack/dlg_misc.h trunk/OpenMPT/mptrack/mptrack.rc trunk/OpenMPT/mptrack/resource.h trunk/OpenMPT/mptrack/view_com.cpp trunk/OpenMPT/soundlib/ITTools.cpp trunk/OpenMPT/soundlib/ITTools.h trunk/OpenMPT/soundlib/Load_it.cpp trunk/OpenMPT/soundlib/Load_itp.cpp trunk/OpenMPT/soundlib/Load_mt2.cpp trunk/OpenMPT/soundlib/ModSample.cpp trunk/OpenMPT/soundlib/SampleFormats.cpp trunk/OpenMPT/soundlib/Snd_defs.h trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/Sndfile.h trunk/OpenMPT/soundlib/Tables.cpp trunk/OpenMPT/soundlib/mod_specifications.cpp trunk/OpenMPT/test/test.cpp trunk/OpenMPT/test/test.mptm Added Paths: ----------- trunk/OpenMPT/test/test.flac Modified: trunk/OpenMPT/common/BuildSettings.h =================================================================== --- trunk/OpenMPT/common/BuildSettings.h 2014-10-26 11:18:46 UTC (rev 4503) +++ trunk/OpenMPT/common/BuildSettings.h 2014-10-26 15:27:49 UTC (rev 4504) @@ -97,6 +97,9 @@ // Enable std::istream support in class FileReader (this is generally not needed for the tracker, local files can easily be mmapped as they have been before introducing std::istream support) //#define MPT_FILEREADER_STD_ISTREAM +// Support for externally linked samples e.g. in MPTM files +#define MPT_EXTERNAL_SAMPLES + // Disable unarchiving support //#define NO_ARCHIVE_SUPPORT @@ -160,6 +163,7 @@ //#define NO_ASSERTS //#define NO_LOGGING #define MPT_FILEREADER_STD_ISTREAM +//#define MPT_EXTERNAL_SAMPLES #define NO_ARCHIVE_SUPPORT #define NO_REVERB #define NO_DSP @@ -324,6 +328,10 @@ #define MPT_WITH_FILEIO // Tracker requires disk file io #endif +#if defined(MPT_EXTERNAL_SAMPLES) && !defined(MPT_WITH_FILEIO) +#define MPT_WITH_FILEIO // External samples require disk file io +#endif + #if defined(MPT_WITH_FILEIO) && !defined(MPT_WITH_PATHSTRING) #define MPT_WITH_PATHSTRING // disk file io requires PathString #endif Modified: trunk/OpenMPT/common/mptIO.h =================================================================== --- trunk/OpenMPT/common/mptIO.h 2014-10-26 11:18:46 UTC (rev 4503) +++ trunk/OpenMPT/common/mptIO.h 2014-10-26 15:27:49 UTC (rev 4504) @@ -267,7 +267,7 @@ template <typename T, typename Tfile> -inline bool WriteIntLE(Tfile & f, const T & v) +inline bool WriteIntLE(Tfile & f, const T v) { STATIC_ASSERT(std::numeric_limits<T>::is_integer); const T val = SwapBytesReturnLE(v); @@ -277,7 +277,7 @@ } template <typename T, typename Tfile> -inline bool WriteIntBE(Tfile & f, const T & v) +inline bool WriteIntBE(Tfile & f, const T v) { STATIC_ASSERT(std::numeric_limits<T>::is_integer); const T val = SwapBytesReturnBE(v); @@ -287,7 +287,7 @@ } template <typename Tfile> -inline bool WriteAdaptiveInt16LE(Tfile & f, const uint16 & v, std::size_t minSize = 0, std::size_t maxSize = 0) +inline bool WriteAdaptiveInt16LE(Tfile & f, const uint16 v, std::size_t minSize = 0, std::size_t maxSize = 0) { MPT_ASSERT(minSize == 0 || minSize == 1 || minSize == 2); MPT_ASSERT(maxSize == 0 || maxSize == 1 || maxSize == 2); @@ -306,7 +306,7 @@ } template <typename Tfile> -inline bool WriteAdaptiveInt32LE(Tfile & f, const uint32 & v, std::size_t minSize = 0, std::size_t maxSize = 0) +inline bool WriteAdaptiveInt32LE(Tfile & f, const uint32 v, std::size_t minSize = 0, std::size_t maxSize = 0) { MPT_ASSERT(minSize == 0 || minSize == 1 || minSize == 2 || minSize == 3 || minSize == 4); MPT_ASSERT(maxSize == 0 || maxSize == 1 || maxSize == 2 || maxSize == 3 || maxSize == 4); @@ -336,7 +336,7 @@ } template <typename Tfile> -inline bool WriteAdaptiveInt64LE(Tfile & f, const uint64 & v, std::size_t minSize = 0, std::size_t maxSize = 0) +inline bool WriteAdaptiveInt64LE(Tfile & f, const uint64 v, std::size_t minSize = 0, std::size_t maxSize = 0) { MPT_ASSERT(minSize == 0 || minSize == 1 || minSize == 2 || minSize == 4 || minSize == 8); MPT_ASSERT(maxSize == 0 || maxSize == 1 || maxSize == 2 || maxSize == 4 || maxSize == 8); @@ -360,6 +360,25 @@ } } +// Write a variable-length integer, as found in MIDI files. The number of written bytes is placed in the bytesWritten parameter. +template <typename Tfile, typename T> +bool WriteVarInt(Tfile & f, const T v, size_t *bytesWritten = nullptr) +{ + uint8 out[(sizeof(T) * 8 + 6) / 7]; + size_t numBytes = 0; + for(uint32 n = (sizeof(T) * 8) / 7; n > 0; n--) + { + if(v >= (1u << (n * 7u))) + { + out[numBytes++] = static_cast<uint8>(((v >> (n * 7u)) & 0x7F) | 0x80); + } + } + out[numBytes++] = static_cast<uint8>(v & 0x7F); + MPT_ASSERT(numBytes <= CountOf(out)); + if(bytesWritten != nullptr) *bytesWritten = numBytes; + return mpt::IO::WriteRaw(f, out, numBytes); +} + template <typename Tsize, typename Tfile> inline bool WriteSizedStringLE(Tfile & f, const std::string & str) { Modified: trunk/OpenMPT/common/versionNumber.h =================================================================== --- trunk/OpenMPT/common/versionNumber.h 2014-10-26 11:18:46 UTC (rev 4503) +++ trunk/OpenMPT/common/versionNumber.h 2014-10-26 15:27:49 UTC (rev 4504) @@ -19,7 +19,7 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 24 #define VER_MINOR 00 -#define VER_MINORMINOR 13 +#define VER_MINORMINOR 14 //Version string. For example "1.17.02.28" #define MPT_VERSION_STR VER_STRINGIZE(VER_MAJORMAJOR) "." VER_STRINGIZE(VER_MAJOR) "." VER_STRINGIZE(VER_MINOR) "." VER_STRINGIZE(VER_MINORMINOR) Modified: trunk/OpenMPT/installer/filetypes.iss =================================================================== --- trunk/OpenMPT/installer/filetypes.iss 2014-10-26 11:18:46 UTC (rev 4503) +++ trunk/OpenMPT/installer/filetypes.iss 2014-10-26 15:27:49 UTC (rev 4504) @@ -13,7 +13,6 @@ Name: "associate_common\s3m"; Description: "Scream Tracker 3 (S3M)"; Name: "associate_common\xm"; Description: "Fasttracker 2 (XM)"; Name: "associate_common\it"; Description: "Impulse Tracker (IT)"; -Name: "associate_common\itp"; Description: "Impulse Tracker Project (ITP)"; Name: "associate_common\mptm"; Description: "OpenMPT (MPTM)"; ; same, but compressed Name: "associate_common\compressed"; Description: "Above when compressed (MDR, MDZ, S3Z, XMZ, ITZ, MPTMZ)"; @@ -30,6 +29,7 @@ Name: "associate_exotic\gdm"; Description: "General Digital Music (GDM)"; Name: "associate_exotic\imf"; Description: "Imago Orpheus (IMF)"; Name: "associate_exotic\ice"; Description: "Ice Tracker (ICE)"; +Name: "associate_exotic\itp"; Description: "Impulse Tracker Project (ITP)"; Name: "associate_exotic\j2b"; Description: "Jazz Jackrabbit 2 Music (J2B)"; Name: "associate_exotic\m15"; Description: "Ultimate Soundtracker (M15)"; Name: "associate_exotic\mdl"; Description: "DigiTrakker (MDL)"; @@ -51,7 +51,6 @@ Root: HKCR; Subkey: ".s3m"; ValueType: string; ValueName: ""; ValueData: "OpenMPTFile"; Flags: uninsdeletevalue; Tasks: associate_common\s3m Root: HKCR; Subkey: ".xm"; ValueType: string; ValueName: ""; ValueData: "OpenMPTFile"; Flags: uninsdeletevalue; Tasks: associate_common\xm Root: HKCR; Subkey: ".it"; ValueType: string; ValueName: ""; ValueData: "OpenMPTFile"; Flags: uninsdeletevalue; Tasks: associate_common\it -Root: HKCR; Subkey: ".itp"; ValueType: string; ValueName: ""; ValueData: "OpenMPTFile"; Flags: uninsdeletevalue; Tasks: associate_common\itp Root: HKCR; Subkey: ".mptm"; ValueType: string; ValueName: ""; ValueData: "OpenMPTFile"; Flags: uninsdeletevalue; Tasks: associate_common\mptm ; same, but compressed Root: HKCR; Subkey: ".mdr"; ValueType: string; ValueName: ""; ValueData: "OpenMPTFile"; Flags: uninsdeletevalue; Tasks: associate_common\compressed @@ -72,6 +71,7 @@ Root: HKCR; Subkey: ".gdm"; ValueType: string; ValueName: ""; ValueData: "OpenMPTFile"; Flags: uninsdeletevalue; Tasks: associate_exotic\gdm Root: HKCR; Subkey: ".imf"; ValueType: string; ValueName: ""; ValueData: "OpenMPTFile"; Flags: uninsdeletevalue; Tasks: associate_exotic\imf Root: HKCR; Subkey: ".ice"; ValueType: string; ValueName: ""; ValueData: "OpenMPTFile"; Flags: uninsdeletevalue; Tasks: associate_exotic\ice +Root: HKCR; Subkey: ".itp"; ValueType: string; ValueName: ""; ValueData: "OpenMPTFile"; Flags: uninsdeletevalue; Tasks: associate_exotic\itp Root: HKCR; Subkey: ".j2b"; ValueType: string; ValueName: ""; ValueData: "OpenMPTFile"; Flags: uninsdeletevalue; Tasks: associate_exotic\j2b Root: HKCR; Subkey: ".m15"; ValueType: string; ValueName: ""; ValueData: "OpenMPTFile"; Flags: uninsdeletevalue; Tasks: associate_exotic\m15 Root: HKCR; Subkey: ".mdl"; ValueType: string; ValueName: ""; ValueData: "OpenMPTFile"; Flags: uninsdeletevalue; Tasks: associate_exotic\mdl Modified: trunk/OpenMPT/mptrack/AutoSaver.cpp =================================================================== --- trunk/OpenMPT/mptrack/AutoSaver.cpp 2014-10-26 11:18:46 UTC (rev 4503) +++ trunk/OpenMPT/mptrack/AutoSaver.cpp 2014-10-26 15:27:49 UTC (rev 4504) @@ -128,13 +128,7 @@ name += MPT_PATHSTRING(".AutoSave."); //append backup tag name += mpt::PathString::FromWide(timeStamp); //append timestamp name += MPT_PATHSTRING("."); //append extension - if(modDoc.GetrSoundFile().m_SongFlags[SONG_ITPROJECT]) - { - name += MPT_PATHSTRING("itp"); - } else - { - name += mpt::PathString::FromUTF8(modDoc.GetrSoundFile().GetModSpecifications().fileExtension); - } + name += mpt::PathString::FromUTF8(modDoc.GetrSoundFile().GetModSpecifications().fileExtension); return name; } @@ -168,9 +162,7 @@ break; case MOD_TYPE_IT: - success = sndFile.m_SongFlags[SONG_ITPROJECT] ? - sndFile.SaveITProject(fileName) : - sndFile.SaveIT(fileName); + success = sndFile.SaveIT(fileName); break; case MOD_TYPE_MPT: Modified: trunk/OpenMPT/mptrack/CleanupSong.cpp =================================================================== --- trunk/OpenMPT/mptrack/CleanupSong.cpp 2014-10-26 11:18:46 UTC (rev 4503) +++ trunk/OpenMPT/mptrack/CleanupSong.cpp 2014-10-26 15:27:49 UTC (rev 4504) @@ -513,7 +513,7 @@ EndWaitCursor(); - if(unusedInsSamples && !((sndFile.GetType() == MOD_TYPE_IT) && sndFile.m_SongFlags[SONG_ITPROJECT])) + if(unusedInsSamples) { // We don't remove an instrument's unused samples in an ITP. wsprintf(s, "OpenMPT detected %d sample%s referenced by an instrument,\n" @@ -696,15 +696,9 @@ return false; deleteInstrumentSamples removeSamples = doNoDeleteAssociatedSamples; - if(!sndFile.m_SongFlags[SONG_ITPROJECT]) // Never remove an instrument's samples in ITP. + if(Reporting::Confirm("Remove samples associated with unused instruments?", "Removing unused instruments", false, false, this) == cnfYes) { - if(Reporting::Confirm("Remove samples associated with unused instruments?", "Removing unused instruments", false, false, this) == cnfYes) - { - removeSamples = deleteAssociatedSamples; - } - } else - { - modDoc.AddToLog("Samples associated with an used instrument won't be removed in IT Project files."); + removeSamples = deleteAssociatedSamples; } BeginWaitCursor(); Modified: trunk/OpenMPT/mptrack/Ctrl_gen.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_gen.cpp 2014-10-26 11:18:46 UTC (rev 4503) +++ trunk/OpenMPT/mptrack/Ctrl_gen.cpp 2014-10-26 15:27:49 UTC (rev 4504) @@ -204,7 +204,6 @@ void CCtrlGeneral::UpdateView(DWORD dwHint, CObject *pHint) //--------------------------------------------------------- { - CHAR s[256]; if (pHint == this) return; if (dwHint & HINT_MODSEQUENCE) { @@ -216,20 +215,12 @@ if (!m_bEditsLocked) { m_EditTitle.SetWindowText(m_sndFile.GetTitle().c_str()); - wsprintf(s, "%d", m_sndFile.m_nDefaultTempo); - m_EditTempo.SetWindowText(s); - wsprintf(s, "%d", m_sndFile.m_nDefaultSpeed); - m_EditSpeed.SetWindowText(s); - wsprintf(s, "%d", m_sndFile.m_nDefaultGlobalVolume / GetGlobalVolumeFactor()); - m_EditGlobalVol.SetWindowText(s); - wsprintf(s, "%d", m_sndFile.m_nRestartPos); - m_EditRestartPos.SetWindowText(s); - wsprintf(s, "%d", m_sndFile.m_nVSTiVolume); - m_EditVSTiVol.SetWindowText(s); - wsprintf(s, "%d", m_sndFile.m_nSamplePreAmp); - m_EditSamplePA.SetWindowText(s); - wsprintf(s, "%d", m_sndFile.m_nRestartPos); - m_EditRestartPos.SetWindowText(s); + SetDlgItemInt(IDC_EDIT_TEMPO, m_sndFile.m_nDefaultTempo, FALSE); + SetDlgItemInt(IDC_EDIT_SPEED, m_sndFile.m_nDefaultSpeed, FALSE); + SetDlgItemInt(IDC_EDIT_GLOBALVOL, m_sndFile.m_nDefaultGlobalVolume / GetGlobalVolumeFactor(), FALSE); + SetDlgItemInt(IDC_EDIT_RESTARTPOS, m_sndFile.m_nRestartPos, FALSE); + SetDlgItemInt(IDC_EDIT_VSTIVOL, m_sndFile.m_nVSTiVolume, FALSE); + SetDlgItemInt(IDC_EDIT_SAMPLEPA, m_sndFile.m_nSamplePreAmp, FALSE); } m_SliderGlobalVol.SetPos(MAX_SLIDER_GLOBAL_VOL-m_sndFile.m_nDefaultGlobalVolume); @@ -270,20 +261,16 @@ //on purpose(can be used to control play volume) // MOD Type - LPCSTR pszModType = "MOD (ProTracker)"; + TCHAR *modType = _T("MOD (ProTracker)"); switch(m_sndFile.GetType()) { - case MOD_TYPE_S3M: pszModType = "S3M (ScreamTracker)"; break; - case MOD_TYPE_XM: pszModType = "XM (FastTracker 2)"; break; -// -> CODE#0023 -// -> DESC="IT project files (.itp)" -// case MOD_TYPE_IT: pszModType = "IT (Impulse Tracker)"; break; - case MOD_TYPE_IT: pszModType = m_sndFile.m_SongFlags[SONG_ITPROJECT] ? "ITP (IT Project)" : "IT (Impulse Tracker)"; break; - case MOD_TYPE_MPT: pszModType = "MPTM (OpenMPT)"; break; - -// -! NEW_FEATURE#0023 + case MOD_TYPE_S3M: modType = _T("S3M (ScreamTracker)"); break; + case MOD_TYPE_XM: modType = _T("XM (FastTracker 2)"); break; + case MOD_TYPE_IT: modType = _T("IT (Impulse Tracker)"); break; + case MOD_TYPE_MPT: modType = _T("MPTM (OpenMPT)"); break; } - wsprintf(s, "%s, %d channel%s", pszModType, m_sndFile.GetNumChannels(), (m_sndFile.GetNumChannels() != 1) ? "s" : ""); + TCHAR s[256]; + wsprintf(s, _T("%s, %d channel%s"), modType, m_sndFile.GetNumChannels(), (m_sndFile.GetNumChannels() != 1) ? _T("s") : _T("")); m_EditModType.SetWindowText(s); } CheckDlgButton(IDC_CHECK_LOOPSONG, (TrackerSettings::Instance().gbLoopSong) ? TRUE : FALSE); Modified: trunk/OpenMPT/mptrack/Ctrl_ins.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2014-10-26 11:18:46 UTC (rev 4503) +++ trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2014-10-26 15:27:49 UTC (rev 4504) @@ -985,18 +985,7 @@ void CCtrlInstruments::SetModified(DWORD mask, bool updateAll, bool modified) //--------------------------------------------------------------------------- { - // -> CODE#0023 - // -> DESC="IT project files (.itp)" - if(m_modDoc.GetrSoundFile().m_SongFlags[SONG_ITPROJECT]) - { - if(m_modDoc.m_bsInstrumentModified[m_nInstrument - 1] != modified) - { - m_modDoc.m_bsInstrumentModified.set(m_nInstrument - 1, modified); - mask |= HINT_INSNAMES; - } - } m_modDoc.UpdateAllViews(NULL, (m_nInstrument << HINT_SHIFT_INS) | mask, updateAll ? nullptr : this); - // -! NEW_FEATURE#0023 if(modified) m_modDoc.SetModified(); } @@ -1449,7 +1438,6 @@ if (!m_nInstrument) m_nInstrument = 1; if (m_sndFile.ReadInstrumentFromFile(m_nInstrument, file, TrackerSettings::Instance().m_MayNormalizeSamplesOnLoad)) { - m_sndFile.m_szInstrumentPath[m_nInstrument - 1] = fileName; SetModified(HINT_SAMPLEINFO | HINT_MODTYPE, true, false); bOk = TRUE; } @@ -1767,6 +1755,7 @@ "Compressed Impulse Tracker Instruments (*.iti)|*.iti||" : "Impulse Tracker Instruments (*.iti)|*.iti|" "Compressed Impulse Tracker Instruments (*.iti)|*.iti|" + "Impulse Tracker Instruments with external Samples (*.iti)|*.iti|" "FastTracker II Instruments (*.xi)|*.xi||") .WorkingDirectory(TrackerDirectories::Instance().GetWorkingDirectory(DIR_INSTRUMENTS)) .FilterIndex(&index); @@ -1778,9 +1767,8 @@ if(!mpt::PathString::CompareNoCase(dlg.GetExtension(), MPT_PATHSTRING("xi"))) ok = m_sndFile.SaveXIInstrument(m_nInstrument, dlg.GetFirstFile()); else - ok = m_sndFile.SaveITIInstrument(m_nInstrument, dlg.GetFirstFile(), index == (m_sndFile.GetType() == MOD_TYPE_XM ? 3 : 2)); + ok = m_sndFile.SaveITIInstrument(m_nInstrument, dlg.GetFirstFile(), index == (m_sndFile.GetType() == MOD_TYPE_XM ? 3 : 2), m_sndFile.GetType() != MOD_TYPE_XM && index == 3); - m_sndFile.m_szInstrumentPath[m_nInstrument - 1] = dlg.GetFirstFile(); SetModified(HINT_MODTYPE | HINT_INSNAMES, true, false); m_modDoc.UpdateAllViews(nullptr, HINT_SMPNAMES, this); @@ -2437,11 +2425,6 @@ } } } - -// -> CODE#0023 -// -> DESC="IT project files (.itp)" - m_modDoc.UpdateAllViews(NULL, HINT_INSNAMES, this); -// -! NEW_FEATURE#0023 } } if ((nCode == SB_ENDSCROLL) || (nCode == SB_THUMBPOSITION)) Modified: trunk/OpenMPT/mptrack/Ctrl_smp.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2014-10-26 11:18:46 UTC (rev 4503) +++ trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2014-10-26 15:27:49 UTC (rev 4504) @@ -87,6 +87,7 @@ ON_COMMAND(IDC_SAMPLE_XFADE, OnXFade) ON_COMMAND(IDC_SAMPLE_AUTOTUNE, OnAutotune) ON_COMMAND(IDC_CHECK1, OnSetPanningChanged) + ON_COMMAND(IDC_CHECK2, OnKeepSampleOnDisk) ON_COMMAND(ID_PREVINSTRUMENT, OnPrevInstrument) ON_COMMAND(ID_NEXTINSTRUMENT, OnNextInstrument) ON_COMMAND(IDC_BUTTON1, OnPitchShiftTimeStretch) @@ -515,8 +516,8 @@ } -BOOL CCtrlSamples::GetToolTipText(UINT uId, LPSTR pszText) -//-------------------------------------------------------- +BOOL CCtrlSamples::GetToolTipText(UINT uId, TCHAR *pszText) +//--------------------------------------------------------- { if ((pszText) && (uId)) { @@ -529,13 +530,16 @@ { const ModSample &sample = m_sndFile.GetSample(m_nSample); UINT nFreqHz = ModSample::TransposeToFrequency(sample.RelativeTone, sample.nFineTune); - wsprintf(pszText, "%ldHz", nFreqHz); + wsprintf(pszText, _T("%luHz"), nFreqHz); return TRUE; } break; case IDC_EDIT_STRETCHPARAMS: - wsprintf(pszText, "SequenceMs SeekwindowMs OverlapMs"); + _tcscpy(pszText, _T("SequenceMs SeekwindowMs OverlapMs")); return TRUE; + case IDC_CHECK2: + _tcscpy(pszText, _T("Keep a reference to the original waveform instead of saving it in the module.")); + return TRUE; } } return FALSE; @@ -662,7 +666,7 @@ DWORD d; m_SpinSample.SetRange(1, m_sndFile.GetNumSamples()); - + // Length / Type wsprintf(s, "%u-bit %s, len: %u", sample.GetElementarySampleSize() * 8, sample.uFlags[CHN_STEREO] ? "stereo" : "mono", sample.nLength); SetDlgItemText(IDC_TEXT5, s); @@ -750,6 +754,11 @@ wsprintf(s, "%lu", sample.nSustainEnd); m_EditSustainEnd.SetWindowText(s); } + if (dwHintMask & (HINT_MODTYPE | HINT_SAMPLEINFO | HINT_SMPNAMES)) + { + CheckDlgButton(IDC_CHECK2, m_sndFile.GetSample(m_nSample).uFlags[SMP_KEEPONDISK] ? BST_CHECKED : BST_UNCHECKED); + GetDlgItem(IDC_CHECK2)->EnableWindow((m_sndFile.SampleHasPath(m_nSample) && m_sndFile.GetType() == MOD_TYPE_MPT) ? TRUE : FALSE); + } if (!m_bInitialized) { // First update @@ -766,10 +775,18 @@ // updateAll: Update all views including this one. Otherwise, only update update other views. -void CCtrlSamples::SetModified(DWORD mask, bool updateAll) -//-------------------------------------------------------- +void CCtrlSamples::SetModified(DWORD mask, bool updateAll, bool waveformModified) +//------------------------------------------------------------------------------- { m_modDoc.SetModified(); + + if(waveformModified) + { + // Update on-disk sample status in tree + ModSample &sample = m_sndFile.GetSample(m_nSample); + if(sample.uFlags[SMP_KEEPONDISK] && !sample.uFlags[SMP_MODIFIED]) mask |= HINT_SMPNAMES; + sample.uFlags.set(SMP_MODIFIED); + } m_modDoc.UpdateAllViews(nullptr, mask | (m_nSample << HINT_SHIFT_SMP), updateAll ? nullptr : this); } @@ -856,6 +873,9 @@ { m_modDoc.GetSampleUndo().RemoveLastUndoStep(m_nSample); } + } else + { + m_sndFile.SetSamplePath(m_nSample, fileName); } EndWaitCursor(); @@ -877,7 +897,8 @@ sample.nPan = 128; sample.uFlags.set(CHN_PANNING); } - SetModified(HINT_SAMPLEDATA | HINT_SAMPLEINFO | HINT_SMPNAMES, true); + SetModified(HINT_SAMPLEDATA | HINT_SAMPLEINFO | HINT_SMPNAMES, true, false); + sample.uFlags.reset(SMP_MODIFIED | SMP_KEEPONDISK); } return true; } @@ -892,16 +913,10 @@ m_modDoc.GetSampleUndo().PrepareUndo(m_nSample, sundo_replace, "Replace"); m_sndFile.ReadSampleFromSong(m_nSample, sndFile, nSample); - ModSample &sample = m_sndFile.GetSample(m_nSample); - if((m_sndFile.GetType() & MOD_TYPE_XM) && (!sample.uFlags[CHN_PANNING])) - { - sample.nPan = 128; - sample.uFlags.set(CHN_PANNING); - } EndWaitCursor(); - SetModified(HINT_SAMPLEDATA | HINT_SAMPLEINFO | HINT_SMPNAMES, true); + SetModified(HINT_SAMPLEDATA | HINT_SAMPLEINFO | HINT_SMPNAMES, true, false); return true; } @@ -1128,6 +1143,27 @@ ok = m_sndFile.SaveFLACSample(smp, fileName); else ok = m_sndFile.SaveWAVSample(smp, fileName); + + if(ok && !doBatchSave) + { + m_sndFile.SetSamplePath(smp, fileName); + ModSample &sample = m_sndFile.GetSample(smp); + sample.uFlags.reset(SMP_MODIFIED); + UpdateView(HINT_SAMPLEINFO); + + // Check if any other samples refer to the same file - that would be dangerous. + if(sample.uFlags[SMP_KEEPONDISK]) + { + for(SAMPLEINDEX i = 1; i <= m_sndFile.GetNumSamples(); i++) + { + if(i != smp && m_sndFile.GetSample(i).uFlags[SMP_KEEPONDISK] && m_sndFile.GetSamplePath(i) == m_sndFile.GetSamplePath(smp)) + { + m_sndFile.GetSample(i).uFlags.reset(SMP_KEEPONDISK); + m_modDoc.UpdateAllViews(nullptr, HINT_SMPNAMES | HINT_SAMPLEINFO | (i << HINT_SHIFT_SMP), this); + } + } + } + } } } EndWaitCursor(); @@ -1264,7 +1300,7 @@ if(bModified) { - SetModified(HINT_SAMPLEDATA, false); + SetModified(HINT_SAMPLEDATA, false, true); } EndWaitCursor(); SwitchToView(); @@ -1312,7 +1348,7 @@ ApplyAmplifyImpl<int8>(sample.pSample8, selection.nStart, selection.nEnd, lAmp, fadeIn, fadeOut); } sample.PrecomputeLoops(m_sndFile, false); - SetModified(HINT_SAMPLEDATA, false); + SetModified(HINT_SAMPLEDATA, false, true); EndWaitCursor(); SwitchToView(); } @@ -1377,7 +1413,7 @@ CString dcInfo; if(numModified) { - SetModified(HINT_SAMPLEDATA | HINT_SAMPLEINFO, true); + SetModified(HINT_SAMPLEDATA | HINT_SAMPLEINFO, true, true); if(numModified == 1) { dcInfo.Format(GetStrI18N(TEXT("Removed DC offset (%.1f%%)")), fReportOffset * 100); @@ -1459,7 +1495,7 @@ const SmpLength newTotalLength = sample.nLength - selLength + newSelLength; const uint8 numChannels = sample.GetNumChannels(); - void *newSample = ModSample::AllocateSample(newTotalLength * numChannels, sample.GetElementarySampleSize()); + void *newSample = ModSample::AllocateSample(newTotalLength, sample.GetBytesPerSample()); if(newSample != nullptr) { @@ -1583,7 +1619,7 @@ { SetSelectionPoints(selection.nStart, newSelEnd); } - SetModified(HINT_SAMPLEDATA | HINT_SAMPLEINFO, true); + SetModified(HINT_SAMPLEDATA | HINT_SAMPLEINFO, true, true); } EndWaitCursor(); @@ -1732,7 +1768,7 @@ } // Update sample view - SetModified(HINT_SAMPLEDATA | HINT_SAMPLEINFO, true); + SetModified(HINT_SAMPLEDATA | HINT_SAMPLEINFO, true, true); } @@ -1854,7 +1890,7 @@ void *pNewSample = nullptr; if(nNewSampleLength <= MAX_SAMPLE_LENGTH) { - pNewSample = ModSample::AllocateSample(nNewSampleLength, nChn * smpsize); + pNewSample = ModSample::AllocateSample(nNewSampleLength, sample.GetBytesPerSample()); } if(pNewSample == nullptr) { @@ -2179,7 +2215,7 @@ m_modDoc.GetSampleUndo().PrepareUndo(m_nSample, sundo_reverse, "Reverse", selection.nStart, selection.nEnd); if(ctrlSmp::ReverseSample(sample, selection.nStart, selection.nEnd, m_sndFile)) { - SetModified(HINT_SAMPLEDATA, false); + SetModified(HINT_SAMPLEDATA, false, true); } else { m_modDoc.GetSampleUndo().RemoveLastUndoStep(m_nSample); @@ -2199,7 +2235,7 @@ m_modDoc.GetSampleUndo().PrepareUndo(m_nSample, sundo_invert, "Invert", selection.nStart, selection.nEnd); if(ctrlSmp::InvertSample(sample, selection.nStart, selection.nEnd, m_sndFile) == true) { - SetModified(HINT_SAMPLEDATA, false); + SetModified(HINT_SAMPLEDATA, false, true); } else { m_modDoc.GetSampleUndo().RemoveLastUndoStep(m_nSample); @@ -2224,7 +2260,7 @@ m_modDoc.GetSampleUndo().PrepareUndo(m_nSample, sundo_unsign, "Unsign", selection.nStart, selection.nEnd); if(ctrlSmp::UnsignSample(sample, selection.nStart, selection.nEnd, m_sndFile) == true) { - SetModified(HINT_SAMPLEDATA, false); + SetModified(HINT_SAMPLEDATA, false, true); } else { m_modDoc.GetSampleUndo().RemoveLastUndoStep(m_nSample); @@ -2277,7 +2313,7 @@ } } sample.PrecomputeLoops(m_sndFile, false); - SetModified(HINT_SAMPLEDATA, false); + SetModified(HINT_SAMPLEDATA, false, true); } EndWaitCursor(); @@ -2315,7 +2351,7 @@ if (_tcscmp(s, m_sndFile.m_szNames[m_nSample])) { mpt::String::Copy(m_sndFile.m_szNames[m_nSample], s); - SetModified(HINT_SMPNAMES | HINT_SAMPLEINFO, false); + SetModified(HINT_SMPNAMES | HINT_SAMPLEINFO, false, false); } } @@ -2331,7 +2367,7 @@ if (_tcscmp(s, m_sndFile.GetSample(m_nSample).filename)) { mpt::String::Copy(m_sndFile.GetSample(m_nSample).filename, s); - SetModified(HINT_SAMPLEINFO, false); + SetModified(HINT_SAMPLEINFO, false, false); } } @@ -2346,7 +2382,7 @@ if (nVol != m_sndFile.GetSample(m_nSample).nVolume) { m_sndFile.GetSample(m_nSample).nVolume = (WORD)nVol; - SetModified(HINT_SAMPLEINFO, false); + SetModified(HINT_SAMPLEINFO, false, false); } } @@ -2360,7 +2396,7 @@ if (nVol != m_sndFile.GetSample(m_nSample).nGlobalVol) { m_sndFile.GetSample(m_nSample).nGlobalVol = (uint16)nVol; - SetModified(HINT_SAMPLEINFO, false); + SetModified(HINT_SAMPLEINFO, false, false); } } @@ -2380,7 +2416,7 @@ if(b != sample.uFlags[CHN_PANNING]) { sample.uFlags.set(CHN_PANNING, b); - SetModified(HINT_SAMPLEINFO, false); + SetModified(HINT_SAMPLEINFO, false, false); } } @@ -2404,7 +2440,7 @@ if (nPan != m_sndFile.GetSample(m_nSample).nPan) { m_sndFile.GetSample(m_nSample).nPan = (uint16)nPan; - SetModified(HINT_SAMPLEINFO, false); + SetModified(HINT_SAMPLEINFO, false, false); } } @@ -2431,7 +2467,7 @@ m_CbnBaseNote.SetCurSel(basenote); UnlockControls(); } - SetModified(HINT_SAMPLEINFO, false); + SetModified(HINT_SAMPLEINFO, false, false); } } else { @@ -2440,7 +2476,7 @@ if ((n >= -128) && (n <= 127)) { m_sndFile.GetSample(m_nSample).nFineTune = (signed char)n; - SetModified(HINT_SAMPLEINFO, false); + SetModified(HINT_SAMPLEINFO, false, false); } } @@ -2468,14 +2504,14 @@ LockControls(); m_EditFineTune.SetWindowText(s); UnlockControls(); - SetModified(HINT_SAMPLEINFO, false); + SetModified(HINT_SAMPLEINFO, false, false); } } else { if ((n >= -128) && (n < 128)) { sample.RelativeTone = (int8)n; - SetModified(HINT_SAMPLEINFO, false); + SetModified(HINT_SAMPLEINFO, false, false); } } } @@ -2491,7 +2527,7 @@ m_sndFile.GetSample(m_nSample).nVibType = static_cast<uint8>(m_ComboAutoVib.GetItemData(n)); PropagateAutoVibratoChanges(); - SetModified(HINT_SAMPLEINFO, false); + SetModified(HINT_SAMPLEINFO, false, false); } } @@ -2508,7 +2544,7 @@ m_sndFile.GetSample(m_nSample).nVibDepth = static_cast<uint8>(n); PropagateAutoVibratoChanges(); - SetModified(HINT_SAMPLEINFO, false); + SetModified(HINT_SAMPLEINFO, false, false); } } @@ -2525,7 +2561,7 @@ m_sndFile.GetSample(m_nSample).nVibSweep = static_cast<uint8>(n); PropagateAutoVibratoChanges(); - SetModified(HINT_SAMPLEINFO, false); + SetModified(HINT_SAMPLEINFO, false, false); } } @@ -2542,7 +2578,7 @@ m_sndFile.GetSample(m_nSample).nVibRate = static_cast<uint8>(n); PropagateAutoVibratoChanges(); - SetModified(HINT_SAMPLEINFO, false); + SetModified(HINT_SAMPLEINFO, false, false); } } @@ -2576,7 +2612,7 @@ sample.PrecomputeLoops(m_sndFile); } ctrlSmp::UpdateLoopPoints(sample, m_sndFile); - SetModified(HINT_SAMPLEINFO, false); + SetModified(HINT_SAMPLEINFO, false, false); } @@ -2589,7 +2625,7 @@ if ((n >= 0) && (n < sample.nLength) && ((n < sample.nLoopEnd) || !sample.uFlags[CHN_LOOP])) { sample.SetLoop(n, sample.nLoopEnd, sample.uFlags[CHN_LOOP], sample.uFlags[CHN_PINGPONGLOOP], m_sndFile); - SetModified(HINT_SAMPLEINFO | HINT_SAMPLEDATA, false); + SetModified(HINT_SAMPLEINFO | HINT_SAMPLEDATA, false, false); } } @@ -2603,7 +2639,7 @@ if ((n >= 0) && (n <= sample.nLength) && ((n > sample.nLoopStart) || !sample.uFlags[CHN_LOOP])) { sample.SetLoop(sample.nLoopStart, n, sample.uFlags[CHN_LOOP], sample.uFlags[CHN_PINGPONGLOOP], m_sndFile); - SetModified(HINT_SAMPLEINFO | HINT_SAMPLEDATA, false); + SetModified(HINT_SAMPLEINFO | HINT_SAMPLEDATA, false, false); } } @@ -2637,7 +2673,7 @@ sample.PrecomputeLoops(m_sndFile); } ctrlSmp::UpdateLoopPoints(sample, m_sndFile); - SetModified(HINT_SAMPLEINFO, false); + SetModified(HINT_SAMPLEINFO, false, false); } @@ -2651,7 +2687,7 @@ && ((n < sample.nSustainEnd) || !sample.uFlags[CHN_SUSTAINLOOP])) { sample.SetSustainLoop(n, sample.nSustainEnd, sample.uFlags[CHN_SUSTAINLOOP], sample.uFlags[CHN_PINGPONGSUSTAIN], m_sndFile); - SetModified(HINT_SAMPLEINFO | HINT_SAMPLEDATA, false); + SetModified(HINT_SAMPLEINFO | HINT_SAMPLEDATA, false, false); } } @@ -2666,7 +2702,7 @@ && ((n > sample.nSustainStart) || !sample.uFlags[CHN_SUSTAINLOOP])) { sample.SetSustainLoop(sample.nSustainStart, n, sample.uFlags[CHN_SUSTAINLOOP], sample.uFlags[CHN_PINGPONGSUSTAIN], m_sndFile); - SetModified(HINT_SAMPLEINFO | HINT_SAMPLEDATA, false); + SetModified(HINT_SAMPLEINFO | HINT_SAMPLEDATA, false, false); } } @@ -2956,7 +2992,7 @@ if(nCode == SB_ENDSCROLL) SwitchToView(); if(redraw) { - SetModified(HINT_SAMPLEINFO | HINT_SAMPLEDATA, false); + SetModified(HINT_SAMPLEINFO | HINT_SAMPLEDATA, false, false); } UnlockControls(); } @@ -3111,7 +3147,7 @@ if(ctrlSmp::XFadeSample(sample, fadeLength, m_sndFile)) { - SetModified(HINT_SAMPLEINFO | HINT_SAMPLEDATA, true); + SetModified(HINT_SAMPLEINFO | HINT_SAMPLEDATA, true, true); } else { m_modDoc.GetSampleUndo().RemoveLastUndoStep(m_nSample); @@ -3139,13 +3175,32 @@ BeginWaitCursor(); m_modDoc.GetSampleUndo().PrepareUndo(m_nSample, sundo_none, "Automatic Sample Tuning"); at.Apply(static_cast<double>(dlg.GetPitchReference()), dlg.GetTargetNote()); - SetModified(HINT_SAMPLEINFO, true); + SetModified(HINT_SAMPLEINFO, true, false); EndWaitCursor(); } } } +void CCtrlSamples::OnKeepSampleOnDisk() +//------------------------------------- +{ + SAMPLEINDEX first = m_nSample, last = m_nSample; + if(CMainFrame::GetInputHandler()->ShiftPressed()) + { + first = 1; + last = m_sndFile.GetNumSamples(); + } + + const bool enable = IsDlgButtonChecked(IDC_CHECK2) != BST_UNCHECKED; + for(SAMPLEINDEX i = first; i <= last; i++) + { + m_sndFile.GetSample(i).uFlags.set(SMP_KEEPONDISK, enable && m_sndFile.SampleHasPath(i)); + m_modDoc.UpdateAllViews(nullptr, HINT_SAMPLEINFO | (i << HINT_SHIFT_SMP), this); + } +} + + // When changing auto vibrato properties, propagate them to other samples of the same instrument in XM edit mode. void CCtrlSamples::PropagateAutoVibratoChanges() const //---------------------------------------------------- Modified: trunk/OpenMPT/mptrack/Ctrl_smp.h =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_smp.h 2014-10-26 11:18:46 UTC (rev 4503) +++ trunk/OpenMPT/mptrack/Ctrl_smp.h 2014-10-26 15:27:49 UTC (rev 4504) @@ -80,7 +80,7 @@ virtual void OnDeactivatePage(); virtual void UpdateView(DWORD dwHintMask=0, CObject *pObj=NULL); virtual LRESULT OnModCtrlMsg(WPARAM wParam, LPARAM lParam); - virtual BOOL GetToolTipText(UINT uId, LPSTR pszText); + virtual BOOL GetToolTipText(UINT uId, TCHAR *pszText); virtual BOOL PreTranslateMessage(MSG* pMsg); //}}AFX_VIRTUAL protected: @@ -122,6 +122,7 @@ afx_msg void OnVibSweepChanged(); afx_msg void OnVibRateChanged(); afx_msg void OnXFade(); + afx_msg void OnKeepSampleOnDisk(); afx_msg void OnVScroll(UINT, UINT, CScrollBar *); afx_msg LRESULT OnCustomKeyMsg(WPARAM, LPARAM); //rewbs.customKeys @@ -129,7 +130,7 @@ afx_msg void OnEnableStretchToSize(); afx_msg void OnEstimateSampleSize(); - void SetModified(DWORD mask, bool updateAll); + void SetModified(DWORD mask, bool updateAll, bool waveformModified); //}}AFX_MSG DECLARE_MESSAGE_MAP() Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2014-10-26 11:18:46 UTC (rev 4503) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2014-10-26 15:27:49 UTC (rev 4504) @@ -48,7 +48,6 @@ const TCHAR FileFilterXM[] = _T("FastTracker Modules (*.xm)|*.xm||"); const TCHAR FileFilterS3M[] = _T("ScreamTracker Modules (*.s3m)|*.s3m||"); const TCHAR FileFilterIT[] = _T("Impulse Tracker Modules (*.it)|*.it||"); -const TCHAR FileFilterITP[] = _T("Impulse Tracker Projects (*.itp)|*.itp||"); const TCHAR FileFilterMPT[] = _T("OpenMPT Modules (*.mptm)|*.mptm||"); const TCHAR FileFilterNone[] = _T(""); @@ -61,7 +60,7 @@ case MOD_TYPE_MOD: return FileFilterMOD; case MOD_TYPE_XM: return FileFilterXM; case MOD_TYPE_S3M: return FileFilterS3M; - case MOD_TYPE_IT: return (sndFile.m_SongFlags[SONG_ITPROJECT] ? FileFilterITP : FileFilterIT); + case MOD_TYPE_IT: return FileFilterIT; case MOD_TYPE_MPT: return FileFilterMPT; default: return FileFilterNone; } @@ -143,8 +142,6 @@ // Set the creation date of this file (or the load time if we're loading an existing file) time(&m_creationTime); - m_bsInstrumentModified.reset(); - #ifdef _DEBUG ModChannel *p = m_SndFile.m_PlayState.Chn; if (((DWORD)p) & 7) Log("ModChannel struct is not aligned (0x%08X)\n", p); @@ -185,11 +182,6 @@ m_SndFile.Create(FileReader(), CSoundFile::loadCompleteModule, this); m_SndFile.ChangeModTypeTo(CTrackApp::GetDefaultDocType()); - if(CTrackApp::IsProject()) - { - m_SndFile.m_SongFlags.set(SONG_ITPROJECT); - } - theApp.GetDefaultMidiMacro(m_SndFile.m_MidiCfg); m_SndFile.m_SongFlags.set(SONG_LINEARSLIDES & m_SndFile.GetModSpecifications().songFlags); if(!m_SndFile.m_MidiCfg.IsMacroDefaultSetupUsed()) @@ -423,7 +415,7 @@ case MOD_TYPE_MOD: bOk = m_SndFile.SaveMod(filename); break; case MOD_TYPE_S3M: bOk = m_SndFile.SaveS3M(filename); break; case MOD_TYPE_XM: bOk = m_SndFile.SaveXM(filename); break; - case MOD_TYPE_IT: bOk = (m_SndFile.m_SongFlags[SONG_ITPROJECT] ? m_SndFile.SaveITProject(filename) : m_SndFile.SaveIT(filename)); break; + case MOD_TYPE_IT: bOk = m_SndFile.SaveIT(filename); break; case MOD_TYPE_MPT: bOk = m_SndFile.SaveIT(filename); break; } EndWaitCursor(); @@ -444,79 +436,77 @@ } } else { - if(type == MOD_TYPE_IT && m_SndFile.m_SongFlags[SONG_ITPROJECT]) - Reporting::Error(_T("ITP projects need to have a path set for each instrument...")); - else - ErrorBox(IDS_ERR_SAVESONG, CMainFrame::GetMainFrame()); + ErrorBox(IDS_ERR_SAVESONG, CMainFrame::GetMainFrame()); } return bOk; } -// -> CODE#0023 -// -> DESC="IT project files (.itp)" BOOL CModDoc::SaveModified() //-------------------------- { - if((m_SndFile.GetType() & MOD_TYPE_IT) && m_SndFile.m_SongFlags[SONG_ITPROJECT] && !m_SndFile.m_SongFlags[SONG_ITPEMBEDIH]) + BOOL result = CDocument::SaveModified(); + if(result && m_SndFile.GetType() == MOD_TYPE_MPT) { - bool unsavedInstrument = false; - - for(INSTRUMENTINDEX i = 0 ; i < m_SndFile.GetNumInstruments(); i++) + std::wstring prompt = L"The following external samples have been modified:\n"; + bool modified = false; + for(SAMPLEINDEX i = 1; i <= m_SndFile.GetNumSamples(); i++) { - if(m_bsInstrumentModified[i]) + if(m_SndFile.GetSample(i).uFlags.test_all(SMP_KEEPONDISK | SMP_MODIFIED)) { - unsavedInstrument = true; - break; + modified = true; + prompt += mpt::wfmt::dec0<2>(i) + L": " + m_SndFile.GetSamplePath(i).ToWide() + L"\n"; } } - if(unsavedInstrument && Reporting::Confirm("Do you want to save modified instruments?") == cnfYes) + ConfirmAnswer ans = cnfYes; + if(modified && (ans = Reporting::Confirm(prompt + L"Do you want to save them?", L"External Samples", true)) == cnfYes) { - for(INSTRUMENTINDEX i = 0; i < m_SndFile.GetNumInstruments(); i++) + for(SAMPLEINDEX i = 1; i <= m_SndFile.GetNumSamples(); i++) { - if(m_bsInstrumentModified[i]) + if(m_SndFile.GetSample(i).uFlags.test_all(SMP_KEEPONDISK | SMP_MODIFIED)) { - SaveInstrument(i + 1); + SaveSample(i); } } + } else if(ans == cnfCancel) + { + result = FALSE; } } - return CDocument::SaveModified(); + return result; } -bool CModDoc::SaveInstrument(INSTRUMENTINDEX instr) -//------------------------------------------------- +bool CModDoc::SaveSample(SAMPLEINDEX smp) +//--------------------------------------- { bool success = false; - if(instr > 0 && instr <= GetNumInstruments()) + if(smp > 0 && smp <= GetNumSamples()) { - instr--; - if(!m_SndFile.m_szInstrumentPath[instr].empty()) + const mpt::PathString filename = m_SndFile.GetSamplePath(smp); + if(!filename.empty()) { - const mpt::PathString dotExt = m_SndFile.m_szInstrumentPath[instr].GetFileExt(); - const bool iti = !mpt::PathString::CompareNoCase(dotExt, MPT_PATHSTRING(".iti")); - const bool xi = !mpt::PathString::CompareNoCase(dotExt, MPT_PATHSTRING(".xi")); + const mpt::PathString dotExt = filename.GetFileExt(); + const bool wav = !mpt::PathString::CompareNoCase(dotExt, MPT_PATHSTRING(".wav")); + const bool flac = !mpt::PathString::CompareNoCase(dotExt, MPT_PATHSTRING(".flac")); - if(iti || (!xi && m_SndFile.GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT))) - success = m_SndFile.SaveITIInstrument(instr + 1, m_SndFile.m_szInstrumentPath[instr], false); + if(flac || (!wav && TrackerSettings::Instance().m_defaultSampleFormat != dfWAV)) + success = m_SndFile.SaveFLACSample(smp, filename); else - success = m_SndFile.SaveXIInstrument(instr + 1, m_SndFile.m_szInstrumentPath[instr]); + success = m_SndFile.SaveWAVSample(smp, filename); if(success) - m_bsInstrumentModified.reset(instr); + m_SndFile.GetSample(smp).uFlags.reset(SMP_MODIFIED); else - Reporting::Error(L"Error while saving\n" + m_SndFile.m_szInstrumentPath[instr].ToWide() + L"!"); + Reporting::Error(L"Unable to save sample:\n" + filename.ToWide()); } } return success; } -// -! NEW_FEATURE#0023 - void CModDoc::OnCloseDocument() //----------------------------- { @@ -567,9 +557,8 @@ //--------------------------------------------------------- { const mpt::PathString docFileName = GetPathNameMpt(); + const std::string defaultExtension = m_SndFile.GetModSpecifications().fileExtension; - std::string defaultExtension = m_SndFile.GetModSpecifications().fileExtension; - switch(m_SndFile.GetBestSaveFormat()) { case MOD_TYPE_MOD: @@ -581,21 +570,7 @@ MsgBoxHidable(XMCompatibilityExportTip); break; case MOD_TYPE_IT: -// -> CODE#0023 -// -> DESC="IT project files (.itp)" -// lpszDefExt = "it"; -// lpszFilter = "Impulse Tracker Modules (*.it)|*.it||"; -// strcpy(fext, ".it"); - if(m_SndFile.m_SongFlags[SONG_ITPROJECT]) - { - // Special case... - defaultExtension = "itp"; - } - else - { - MsgBoxHidable(ItCompatibilityExportTip); - } -// -! NEW_FEATURE#0023 + MsgBoxHidable(ItCompatibilityExportTip); break; case MOD_TYPE_MPT: break; @@ -2649,26 +2624,12 @@ newPath += fname; } - if(nNewType == MOD_TYPE_IT) - { - newPath += m_SndFile.m_SongFlags[SONG_ITPROJECT] ? MPT_PATHSTRING(".itp") : MPT_PATHSTRING(".it"); - } else - { - newPath += MPT_PATHSTRING(".") + mpt::PathString::FromUTF8(CSoundFile::GetModSpecifications(nNewType).fileExtension); - } - - if(nNewType != MOD_TYPE_IT || - (nNewType == MOD_TYPE_IT && - ( - (!mpt::PathString::CompareNoCase(fext, MPT_PATHSTRING(".it")) && m_SndFile.m_SongFlags[SONG_ITPROJECT]) || - (!mpt::PathString::CompareNoCase(fext, MPT_PATHSTRING(".itp")) && !m_SndFile.m_SongFlags[SONG_ITPROJECT]) - ) - ) - ) - m_ShowSavedialog = true; - //Forcing savedialog to appear after extension change - otherwise - //unnotified file overwriting may occur. + newPath += MPT_PATHSTRING(".") + mpt::PathString::FromUTF8(CSoundFile::GetModSpecifications(nNewType).fileExtension); + //Forcing savedialog to appear after extension change - otherwise + //unnotified file overwriting may occur. + m_ShowSavedialog = true; + SetPathName(newPath, FALSE); } Modified: trunk/OpenMPT/mptrack/Moddoc.h =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.h 2014-10-26 11:18:46 UTC (rev 4503) +++ trunk/OpenMPT/mptrack/Moddoc.h 2014-10-26 15:27:49 UTC (rev 4504) @@ -189,8 +189,6 @@ protected: std::bitset<MAX_BASECHANNELS> m_bsMultiRecordMask; std::bitset<MAX_BASECHANNELS> m_bsMultiSplitRecordMask; -public: - std::bitset<MAX_INSTRUMENTS> m_bsInstrumentModified; // which instruments have been modified? (for ITP functionality) protected: // create from serialization only CModDoc(); @@ -410,11 +408,8 @@ return mpt::PathString::TunnelOutofCString(CDocument::GetPathName()); } -// -> CODE#0023 -// -> DESC="IT project files (.itp)" virtual BOOL SaveModified(); - bool SaveInstrument(INSTRUMENTINDEX instr); -// -! NEW_FEATURE#0023 + bool SaveSample(SAMPLEINDEX smp); #ifndef UNICODE // MFC checks for writeable filename in there and issues SaveAs dialog if not. Modified: trunk/OpenMPT/mptrack/Modedit.cpp =================================================================== --- trunk/OpenMPT/mptrack/Modedit.cpp 2014-10-26 11:18:46 UTC (rev 4503) +++ trunk/OpenMPT/mptrack/Modedit.cpp 2014-10-26 15:27:49 UTC (rev 4504) @@ -296,6 +296,7 @@ std::vector<ModSample> sampleHeaders(oldNumSamples + 1); std::vector<SAMPLEINDEX> newIndex(oldNumSamples + 1, 0); // One of the new indexes for the old sample std::vector<std::string> sampleNames(oldNumSamples + 1); + std::vector<mpt::PathString> samplePaths(oldNumSamples + 1); for(SAMPLEINDEX i = 0; i < newNumSamples; i++) { @@ -316,6 +317,7 @@ m_SndFile.DestroySample(i); } sampleNames[i] = m_SndFile.m_szNames[i]; + samplePaths[i] = m_SndFile.GetSamplePath(i); } // Remove sample data references from now unused slots. @@ -350,12 +352,14 @@ } } strcpy(m_SndFile.m_szNames[i + 1], sampleNames[origSlot].c_str()); + m_SndFile.SetSamplePath(i + 1, samplePaths[origSlot]); } else { // Invalid sample reference. target.Initialize(m_SndFile.GetType()); target.pSample = nullptr; strcpy(m_SndFile.m_szNames[i + 1], ""); + m_SndFile.ResetSamplePath(i + 1); } } @@ -694,6 +698,9 @@ if(newSlot || !m_SndFile.m_szNames[i][0]) strcpy(m_SndFile.m_szNames[i], "untitled"); if(newSlot) m_SndFile.m_nSamples = i; m_SndFile.GetSample(i).Initialize(m_SndFile.GetType()); + + m_SndFile.ResetSamplePath(i); + SetModified(); return i; } @@ -782,11 +789,6 @@ if (pDup) { *pIns = *pDup; - // -> CODE#0023 - // -> DESC="IT project files (.itp)" - m_SndFile.m_szInstrumentPath[newins - 1] = m_SndFile.m_szInstrumentPath[nDuplicate - 1]; - m_bsInstrumentModified.reset(newins - 1); - // -! NEW_FEATURE#0023 } SetModified(); Modified: trunk/OpenMPT/mptrack/Mptrack.cpp =================================================================== --- trunk/OpenMPT/mptrack/Mptrack.cpp 2014-10-26 11:18:46 UTC (rev 4503) +++ trunk/OpenMPT/mptrack/Mptrack.cpp 2014-10-26 15:27:49 UTC (rev 4504) @@ -610,11 +610,6 @@ MODTYPE CTrackApp::m_nDefaultDocType = MOD_TYPE_IT; -// -> CODE#0023 -// -> DESC="IT project files (.itp)" -BOOL CTrackApp::m_nProject = FALSE; -// -! NEW_FEATURE#0023 - BEGIN_MESSAGE_MAP(CTrackApp, CWinApp) //{{AFX_MSG_MAP(CTrackApp) ON_COMMAND(ID_FILE_NEW, OnFileNew) @@ -622,10 +617,6 @@ ON_COMMAND(ID_FILE_NEWS3M, OnFileNewS3M) ON_COMMAND(ID_FILE_NEWXM, OnFileNewXM) ON_COMMAND(ID_FILE_NEWIT, OnFileNewIT) -// -> CODE#0023 -// -> DESC="IT project files (.itp)" - ON_COMMAND(ID_NEW_ITPROJECT,OnFileNewITProject) -// -! NEW_FEATURE#0023 ON_COMMAND(ID_NEW_MPT, OnFileNewMPT) ON_COMMAND(ID_FILE_OPEN, OnFileOpen) ON_COMMAND(ID_FILE_CLOSEALL, OnFileCloseAll) @@ -1104,18 +1095,16 @@ // Default module type - MODTYPE nNewType = TrackerSettings::Instance().defaultModType; - bool bIsProject = false; + MODTYPE newType = TrackerSettings::Instance().defaultModType; // Get active document to make the new module of the same type CModDoc *pModDoc = CMainFrame::GetMainFrame()->GetActiveDoc(); if(pModDoc != nullptr) { - nNewType = pModDoc->GetrSoundFile().GetBestSaveFormat(); - bIsProject = pModDoc->GetrSoundFile().m_SongFlags[SONG_ITPROJECT]; + newType = pModDoc->GetrSoundFile().GetBestSaveFormat(); } - switch(nNewType) + switch(newType) { case MOD_TYPE_MOD: OnFileNewMOD(); @@ -1127,10 +1116,7 @@ OnFileNewXM(); break; case MOD_TYPE_IT: - if(bIsProject) - OnFileNewITProject(); - else - OnFileNewIT(); + OnFileNewIT(); break; case MOD_TYPE_MPT: default: @@ -1143,11 +1129,6 @@ void CTrackApp::OnFileNewMOD() //---------------------------- { -// -> CODE#0023 -// -> DESC="IT project files (.itp)" - SetAsProject(FALSE); -// -! NEW_FEATURE#0023 - SetDefaultDocType(MOD_TYPE_MOD); if (m_pModTemplate) m_pModTemplate->OpenDocumentFile(mpt::PathString()); } @@ -1156,11 +1137,6 @@ void CTrackApp::OnFileNewS3M() //---------------------------- { -// -> CODE#0023 -// -> DESC="IT project files (.itp)" - SetAsProject(FALSE); -// -! NEW_FEATURE#0023 - SetDefaultDocType(MOD_TYPE_S3M); if (m_pModTemplate) m_pModTemplate->OpenDocumentFile(mpt::PathString()); } @@ -1169,11 +1145,6 @@ void CTrackApp::OnFileNewXM() //--------------------------- { -// -> CODE#0023 -// -> DESC="IT project files (.itp)" - SetAsProject(FALSE); -// -! NEW_FEATURE#0023 - SetDefaultDocType(MOD_TYPE_XM); if (m_pModTemplate) m_pModTemplate->OpenDocumentFile(mpt::PathString()); } @@ -1182,11 +1153,6 @@ void CTrackApp::OnFileNewIT() //--------------------------- { -// -> CODE#0023 -// -> DESC="IT project files (.itp)" - SetAsProject(FALSE); -// -! NEW_FEATURE#0023 - SetDefaultDocType(MOD_TYPE_IT); if (m_pModTemplate) m_pModTemplate->OpenDocumentFile(mpt::PathString()); } @@ -1194,25 +1160,11 @@ void CTrackApp::OnFileNewMPT() //--------------------------- { - SetAsProject(FALSE); SetDefaultDocType(MOD_TYPE_MPT); if (m_pModTemplate) m_pModTemplate->OpenDocumentFile(mpt::PathString()); } - -// -> CODE#0023 -// -> DESC="IT project files (.itp)" -void CTrackApp::OnFileNewITProject() -//---------------------------------- -{ - SetAsProject(TRUE); - SetDefaultDocType(MOD_TYPE_IT); - if (m_pModTemplate) m_pModTemplate->OpenDocumentFile(mpt::PathString()); -} -// -! NEW_FEATURE#0023 - - void CTrackApp::OpenModulesDialog(std::vector<mpt::PathString> &files) //-------------------------------------------------------------------- { @@ -1243,12 +1195,8 @@ "ScreamTracker Modules (*.s3m,*.stm)|*.s3m;*.stm;*.s3z|" "FastTracker Modules (*.xm)|*.xm;*.xmz|" "Impulse Tracker Modules (*.it)|*.it;*.itz|" - // -> CODE#0023 - // -> DESC="IT project files (.itp)" - "Impulse Tracker Projects (*.itp)|*.itp;*.itpz|" - // -! NEW_FEATURE#0023 "OpenMPT Modules (*.mptm)|*.mptm;*.mptmz|" - "Other Modules (mtm,okt,mdl,669,far,...)|*.mtm;*.669;*.ult;*.wow;*.far;*.mdl;*.okt;*.dmf;*.ptm;*.med;*.ams;*.dbm;*.digi;*.dsm;*.umx;*.amf;*.psm;*.mt2;*.gdm;*.imf;*.j2b;*.ice;*.st26|" + "Other Modules (mtm,okt,mdl,669,far,...)|*.mtm;*.669;*.ult;*.wow;*.far;*.mdl;*.okt;*.dmf;*.ptm;*.med;*.ams;*.dbm;*.digi;*.dsm;*.umx;*.amf;*.psm;*.mt2;*.gdm;*.imf;*.itp;*.j2b;*.ice;*.st26|" "Wave Files (*.wav)|*.wav|" "MIDI Files (*.mid,*.rmi)|*.mid;*.rmi;*.smf|" "All Files (*.*)|*.*||") Modified: trunk/OpenMPT/mptrack/Mptrack.h =================================================================== --- trunk/OpenMPT/mptrack/Mptrack.h 2014-10-26 11:18:46 UTC (rev 4503) +++ trunk/OpenMPT/mptrack/Mptrack.h 2014-10-26 15:27:49 UTC (rev 4504) @@ -162,7 +162,6 @@ // static data protected: static MODTYPE m_nDefaultDocType; - static BOOL m_nProject; static MIDILIBSTRUCT midiLibrary; public: @@ -226,12 +225,6 @@ public: -// -> CODE#0023 -// -> DESC="IT project files (.itp)" - static BOOL IsProject() { return m_nProject; } - static VOID SetAsProject(BOOL n) { m_nProject = n; } -// -! NEW_FEATURE#0023 - mpt::PathString GetAppDirPath() {return m_szExePath;} // Returns '\'-ended executable directory path. static MODTYPE GetDefaultDocType() { return m_nDefaultDocType; } static void SetDefaultDocType(MODTYPE n) { m_nDefaultDocType = n; } @@ -318,10 +311,6 @@ afx_msg void OnFileNewXM(); afx_msg void OnFileNewIT(); afx_msg void OnFileNewMPT(); -// -> CODE#0023 -// -> DESC="IT project files (.itp)" - afx_msg void OnFileNewITProject(); -// -! NEW_FEATURE#0023 afx_msg void OnFileOpen(); afx_msg void OnAppAbout(); Modified: trunk/OpenMPT/mptrack/TrackerSettings.cpp =================================================================== --- trunk/OpenMPT/mptrack/TrackerSettings.cpp 2014-10-26 11:18:46 UTC (rev 4503) +++ trunk/OpenMPT/mptrack/TrackerSettings.cpp 2014-10-26 15:27:49 UTC (rev 4504) @@ -146,7 +146,7 @@ , glTreeWindowWidth(conf, "Display", "MDITreeWidth", 160) , glGeneralWindowHeight(conf, "Display", "MDIGeneralHeight", 178) , glPatternWindowHeight(conf, "Display", "MDIPatternHeight", 152) - , glSampleWindowHeight(conf, "Display", "MDISampleHeight", 188) + , glSampleWindowHeight(conf, "Display", "MDISampleHeight", 190) , glInstrumentWindowHeight(conf, "Display", "MDIInstrumentHeight", 300) , glCommentsWindowHeight(conf, "Display", "MDICommentsHeight", 288) , glGraphWindowHeight(conf, "Display", "MDIGraphHeight", 288) Modified: trunk/OpenMPT/mptrack/View_ins.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_ins.cpp 2014-10-26 11:18:46 UTC (rev 4503) +++ trunk/OpenMPT/mptrack/View_ins.cpp 2014-10-26 15:27:49 UTC (rev 4504) @@ -188,11 +188,7 @@ { CModDoc *pModDoc = GetDocument(); if(pModDoc == nullptr) return; -// -> CODE#0023 -// -> DESC="IT project files (.itp)" - pModDoc->m_bsInstrumentModified.set(m_nInstrument - 1, true); - pModDoc->UpdateAllViews(NULL, (m_nInstrument << HINT_SHIFT_INS) | HINT_INSNAMES | mask, updateAll ? nullptr : this); -// -! NEW_FEATURE#0023 + pModDoc->UpdateAllViews(NULL, (m_nInstrument << HINT_SHIFT_INS) | mask, updateAll ? nullptr : this); pModDoc->SetModified(); } Modified: trunk/OpenMPT/mptrack/View_smp.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_smp.cpp 2014-10-26 11:18:46 UTC (rev 4503) +++ trunk/OpenMPT/mptrack/View_smp.cpp 2014-10-26 15:27:49 UTC (rev 4504) @@ -168,11 +168,19 @@ // updateAll: Update all views including this one. Otherwise, only update update other views. -void CViewSample::SetModified(DWORD mask, bool updateAll) -//------------------------------------------------------- +void CViewSample::SetModified(DWORD mask, bool updateAll, bool waveformModified) +//------------------------------------------------------------------------------ { CModDoc *pModDoc = GetDocument(); pModDoc->SetModified(); + + if(waveformModified) + { + // Update on-disk sample status in tree + ModSample &sample = pModDoc->GetrSoundFile().GetSample(m_nSample); + if(sample.uFlags[SMP_KEEPONDISK] && !sample.uFlags[SMP_MODIFIED]) mask |= HINT_SMPNAMES; + sample.uFlags.set(SMP_MODIFIED); + } pModDoc->UpdateAllViews(nullptr, mask | (m_nSample << HINT_SHIFT_SMP), updateAll ? nullptr : this); } @@ -1624,7 +1632,7 @@ sndFile.GetSample(m_nSample).PrecomputeLoops(sndFile, false); InvalidateSample(); - SetModified(HINT_SAMPLEDATA, false); + SetModified(HINT_SAMPLEDATA, false, true); } } else if (old != m_dwEndDrag) @@ -1679,7 +1687,7 @@ sndFile.GetSample(m_nSample).PrecomputeLoops(sndFile, false); InvalidateSample(); - SetModified(HINT_SAMPLEDATA, false); + SetModified(HINT_SAMPLEDATA, false, true); } else { // ctrl + click = play from cursor pos @@ -1933,7 +1941,7 @@ if ((sample.nLoopStart != m_dwBeginSel) || (sample.nLoopEnd != m_dwEndSel)) { sample.SetLoop(m_dwBeginSel, m_dwEndSel, true, sample.uFlags[CHN_PINGPONGLOOP], sndFile); - SetModified(HINT_SAMPLEINFO | HINT_SAMPLEDATA, true); + SetModified(HINT_SAMPLEINFO | HINT_SAMPLEDATA, true, false); } } } @@ -1953,7 +1961,7 @@ if ((sample.nSustainStart != m_dwBeginSel) || (sample.nSustainEnd != m_dwEndSel)) { sample.SetSustainLoop(m_dwBeginSel, m_dwEndSel, true, sample.uFlags[CHN_PINGPONGSUSTAIN], sndFile); - SetModified(HINT_SAMPLEINFO | HINT_SAMPLEDATA, true); + SetModified(HINT_SAMPLEINFO | HINT_SAMPLEDATA, true, false); } } } @@ -2035,7 +2043,7 @@ sample.PrecomputeLoops(sndFile); } SetCurSel(0, 0); - SetModified(dwUpdateFlags, true); + SetModified(dwUpdateFlags, true, true); } @@ -2173,7 +2181,9 @@ GlobalUnlock(hCpy); SetCurSel(0, 0); sample.PrecomputeLoops(sndFile, true); - SetModified(HINT_SAMPLEINFO | HINT_SAMPLEDATA | HINT_SMPNAMES, true); + SetModified(HINT_SAMPLEINFO | HINT_SAMPLEDATA | HINT_SMPNAMES, true, false); + + sndFile.ResetSamplePath(m_nSample); } CloseClipboard(); } @@ -2188,7 +2198,7 @@ if(pModDoc == nullptr) return; if(pModDoc->GetSampleUndo().Undo(m_nSample)) { - SetModified(HINT_SAMPLEINFO | HINT_SAMPLEDATA | HINT_SMPNAMES, true); + SetModified(HINT_SAMPLEINFO | HINT_SAMPLEDATA | HINT_SMPNAMES, true, true); } } @@ -2200,7 +2210,7 @@ if(pModDoc == nullptr) return; if(pModDoc->GetSampleUndo().Redo(m_nSample)) { - SetModified(HINT_SAMPLEINFO | HINT_SAMPLEDATA | HINT_SMPNAMES, true); + SetModified(HINT_SAMPLEINFO | HINT_SAMPLEDATA | HINT_SMPNAMES, true, true); } } @@ -2236,7 +2246,7 @@ sample.PrecomputeLoops(sndFile, false); cs.Leave(); - SetModified(HINT_SAMPLEDATA | HINT_SAMPLEINFO, true); + SetModified(HINT_SAMPLEDATA | HINT_SAMPLEINFO, true, true); } } EndWaitCursor(); @@ -2255,17 +2265,16 @@ if(!sample.uFlags[CHN_16BIT] && sample.pSample != nullptr && sample.nLength != 0) { ASSERT(sample.GetElementarySampleSize() == 1); - const SmpLength numSamples = sample.nLength * sample.GetNumChannels(); - int16 *newSample = static_cast<int16 *>(ModSample::AllocateSample(numSamples, 2)); + int16 *newSample = static_cast<int16 *>(ModSample::AllocateSample(sample.nLength, 2 * sample.GetNumChannels())); if(newSample != nullptr) { pModDoc->GetSampleUndo().PrepareUndo(m_nSample, sundo_replace, "16-Bit Conversion"); - CopySample<SC::ConversionChain<SC::Convert<int16, int8>, SC::DecodeIdentity<int8> > >(newSample, numSamples, 1, sample.pSample8, sample.GetSampleSizeInBytes(), 1); + CopySample<SC::ConversionChain<SC::Convert<int16, int8>, SC::DecodeIdentity<int8> > >(newSample, sample.nLength * sample.GetNumChannels(), 1, sample.pSample8, sample.GetSampleSizeInBytes(), 1); sample.uFlags.set(CHN_16BIT); ctrlSmp::ReplaceSample(sample, newSample, sample.nLength, sndFile); sample.PrecomputeLoops(sndFile, false); - SetModified(HINT_SAMPLEDATA | HINT_SAMPLEINFO, true); + SetModified(HINT_SAMPLEDATA | HINT_SAMPLEINFO, true, true); } } } @@ -2334,7 +2343,7 @@ right.nPan = 256; } } - SetModified(HINT_SAMPLEDATA | HINT_SAMPLEINFO, true); + SetModified(HINT_SAMPLEDATA | HINT_SAMPLEINFO, true, true); } else { pModDoc->GetSampleUndo().RemoveLastUndoStep(m_nSample); @@ -2388,7 +2397,7 @@ cs.Leave(); SetCurSel(0, 0); - SetModified(HINT_SAMPLEDATA | HINT_SAMPLEINFO, true); + SetModified(HINT_SAMPLEDATA | HINT_SAMPLEINFO, true, true); } EndWaitCursor(); } @@ -2587,7 +2596,7 @@ } if (bUpdate) { - SetModified(HINT_SAMPLEDATA | HINT_SAMPLEINFO | HINT_SMPNAMES, true); + SetModified(HINT_SAMPLEDATA | HINT_SAMPLEINFO | HINT_SMPNAMES, true, false); } CMDIChildWnd *pMDIFrame = (CMDIChildWnd *)GetParentFrame(); if (pMDIFrame) @@ -2654,7 +2663,7 @@ { pModDoc->GetSampleUndo().PrepareUndo(m_nSample, sundo_none, "Set Loop Start"); sample.SetLoop(m_dwMenuParam, sample.nLoopEnd, true, sample.uFlags[CHN_PINGPONGLOOP], sndFile); - SetModified(HINT_SAMPLEDATA | HINT_SAMPLEINFO, true); + SetModified(HINT_SAMPLEDATA | HINT_SAMPLEINFO, true, false); } } } @@ -2672,7 +2681,7 @@ { pModDoc->GetSampleUndo().PrepareUndo(m_nSample, sundo_none, "Set Loop End"); sample.SetLoop(sample.nLoopStart, m_dwMenuParam, true, sample.uFlags[CHN_PINGPONGLOOP], sndFile); - SetModified(HINT_SAMPLEDATA | HINT_SAMPLEINFO, true); + SetModified(HINT_SAMPLEDATA | HINT_SAMPLEINFO, true, false); } } } @@ -2690,7 +2699,7 @@ { pModDoc->GetSampleUndo().PrepareUndo(m_nSample, sundo_none, "Set Sustain Start"); sample.SetSustainLoop(m_dwMenuParam, sample.nSustainEnd, true, sample.uFlags[CHN_PINGPONGSUSTAIN], sndFile); - SetModified(HINT_SAMPLEDATA | HINT_SAMPLEINFO, true); + SetModified(HINT_SAMPLEDATA | HINT_SAMPLEINFO, true, false); } } } @@ -2708,7 +2717,7 @@ { pModDoc->GetSampleUndo().PrepareUndo(m_nSample, sundo_none, "Set Sustain End"); sample.SetSustainLoop(sample.nSustainStart, m_dwMenuParam, true, sample.uFlags[CHN_PINGPONGSUSTAIN], sndFile); - SetModified(HINT_SAMPLEDATA | HINT_SAMPLEINFO, true); + SetModified(HINT_SAMPLEDATA | HINT_SAMPLEINFO, true, false); } } } @@ -2776,8 +2785,12 @@ if(dlg.m_nEditOption == addsilence_resize) { // resize - dlg.m_nSamples = new size - if(dlg.m_nSamples != sample.nLength) + if(dlg.m_nSamples == 0) { + pModDoc->GetSampleUndo().PrepareUndo(m_nSample, sundo_replace, "Delete Sample"); + sndFile.DestroySampleThreadsafe(m_nSample); + } else if(dlg.m_nSamples != sample.nLength) + { CriticalSection cs; if(dlg.m_nSamples < sample.nLength) // make it... [truncated message content] |