From: <sag...@us...> - 2012-05-25 18:04:33
|
Revision: 1282 http://modplug.svn.sourceforge.net/modplug/?rev=1282&view=rev Author: saga-games Date: 2012-05-25 18:04:20 +0000 (Fri, 25 May 2012) Log Message: ----------- [Imp] Correct playback position is now also sent to plugins when jumping around in the order list. [Fix] Song length estimation also takes per-pattern time signatures into account now. [Mod] OpenMPT: Version is now 1.20.01.04 Modified Paths: -------------- trunk/OpenMPT/mptrack/Ctrl_seq.cpp trunk/OpenMPT/mptrack/MainFrm.cpp trunk/OpenMPT/mptrack/Mainfrm.h trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/Vstplug.cpp trunk/OpenMPT/mptrack/version.h trunk/OpenMPT/soundlib/Snd_fx.cpp trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/Sndfile.h trunk/OpenMPT/soundlib/Sndmix.cpp Modified: trunk/OpenMPT/mptrack/Ctrl_seq.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_seq.cpp 2012-05-25 17:04:28 UTC (rev 1281) +++ trunk/OpenMPT/mptrack/Ctrl_seq.cpp 2012-05-25 18:04:20 UTC (rev 1282) @@ -328,13 +328,13 @@ DWORD dwPaused = pSndFile->m_dwSongFlags & (SONG_PAUSED|SONG_STEP|SONG_PATTERNLOOP); - //if (!(dwPaused & SONG_PATTERNLOOP)) // why? // update channel parameters and play time m_pModDoc->SetElapsedTime(m_nScrollPos, 0); pSndFile->m_nCurrentOrder = m_nScrollPos; pSndFile->SetCurrentOrder(m_nScrollPos); pSndFile->m_dwSongFlags |= dwPaused; + if (bIsPlaying) pMainFrm->ResetNotificationBuffer(); } m_pParent->SetCurrentPattern(n); Modified: trunk/OpenMPT/mptrack/MainFrm.cpp =================================================================== --- trunk/OpenMPT/mptrack/MainFrm.cpp 2012-05-25 17:04:28 UTC (rev 1281) +++ trunk/OpenMPT/mptrack/MainFrm.cpp 2012-05-25 18:04:20 UTC (rev 1282) @@ -2449,13 +2449,6 @@ return CSoundFile::GetSampleRate(); } -long CMainFrame::GetTotalSampleCount() -//------------------------------------ -{ - if (GetModPlaying()) - return GetModPlaying()->GetSoundFile()->m_lTotalSampleCount; - return 0; -} double CMainFrame::GetApproxBPM() //------------------------------- Modified: trunk/OpenMPT/mptrack/Mainfrm.h =================================================================== --- trunk/OpenMPT/mptrack/Mainfrm.h 2012-05-25 17:04:28 UTC (rev 1281) +++ trunk/OpenMPT/mptrack/Mainfrm.h 2012-05-25 18:04:20 UTC (rev 1282) @@ -531,7 +531,6 @@ CWnd *m_pNoteMapHasFocus; //rewbs.customKeys CWnd* m_pOrderlistHasFocus; long GetSampleRate(); //rewbs.VSTTimeInfo - long GetTotalSampleCount(); //rewbs.VSTTimeInfo double GetApproxBPM(); //rewbs.VSTTimeInfo void ThreadSafeSetModified(CModDoc* modified) {m_pJustModifiedDoc=modified;} Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2012-05-25 17:04:28 UTC (rev 1281) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2012-05-25 18:04:20 UTC (rev 1282) @@ -1898,7 +1898,7 @@ //User has sent play song command: set loop pattern checkbox to false. pChildFrm->SendViewMessage(VIEWMSG_PATTERNLOOP, 0); } - + bool isPlaying = (pMainFrm->GetModPlaying() == this); if ((isPlaying) && (!(m_SndFile.m_dwSongFlags & (SONG_PAUSED|SONG_STEP/*|SONG_PATTERNLOOP*/)))) { @@ -1908,11 +1908,14 @@ CriticalSection cs; - for (UINT i=m_SndFile.m_nChannels; i<MAX_CHANNELS; i++) if (!m_SndFile.Chn[i].nMasterChn) + for(CHANNELINDEX i = m_SndFile.GetNumChannels(); i < MAX_CHANNELS; i++) if (!m_SndFile.Chn[i].nMasterChn) { m_SndFile.Chn[i].dwFlags |= (CHN_NOTEFADE|CHN_KEYOFF); if (!isPlaying) m_SndFile.Chn[i].nLength = 0; } + + m_SndFile.m_bPositionChanged = true; + if (isPlaying) { m_SndFile.StopAllVsti(); @@ -2005,9 +2008,14 @@ m_SndFile.SetCurrentPos(0); m_SndFile.visitedSongRows.Initialize(true); pMainFrm->ResetElapsedTime(); + m_SndFile.m_lTotalSampleCount = 0; + m_SndFile.m_bPositionChanged = true; CriticalSection cs; + + m_SndFile.m_bPositionChanged = true; m_SndFile.ResumePlugins(); + cs.Leave(); pMainFrm->PlayMod(this, m_hWndFollow, m_dwNotifyType); @@ -2285,7 +2293,7 @@ //User has sent play pattern command: set loop pattern checkbox to true. pChildFrm->SendViewMessage(VIEWMSG_PATTERNLOOP, 1); } - + CSoundFile *pSndFile = GetSoundFile(); ROWINDEX nRow; @@ -2299,11 +2307,8 @@ CriticalSection cs; - // set playback timer in the status bar (and update channel status) - SetElapsedTime(nOrd, 0); - // Cut instruments/samples - for (UINT i=0; i<MAX_CHANNELS; i++) + for(CHANNELINDEX i = 0; i < MAX_CHANNELS; i++) { pSndFile->Chn[i].nPatternLoopCount = 0; pSndFile->Chn[i].nPatternLoop = 0; @@ -2314,7 +2319,10 @@ pSndFile->m_dwSongFlags &= ~(SONG_PAUSED|SONG_STEP); pSndFile->LoopPattern(nPat); pSndFile->m_nNextRow = 0; - //rewbs.vstCompliance + + // set playback timer in the status bar (and update channel status) + SetElapsedTime(nOrd, 0); + if (pModPlaying == this) { pSndFile->StopAllVsti(); @@ -2322,7 +2330,7 @@ { pSndFile->ResumePlugins(); } - //end rewbs.vstCompliance + cs.Leave(); if (pModPlaying != this) @@ -2346,7 +2354,7 @@ //User has sent play pattern command: set loop pattern checkbox to true. pChildFrm->SendViewMessage(VIEWMSG_PATTERNLOOP, 1); } - + CSoundFile *pSndFile = GetSoundFile(); ROWINDEX nRow; @@ -2360,11 +2368,8 @@ CriticalSection cs; - // set playback timer in the status bar (and update channel status) - SetElapsedTime(nOrd, nRow); - // Cut instruments/samples - for (UINT i=pSndFile->m_nChannels; i<MAX_CHANNELS; i++) + for(CHANNELINDEX i = pSndFile->GetNumChannels(); i < MAX_CHANNELS; i++) { pSndFile->Chn[i].dwFlags |= CHN_NOTEFADE | CHN_KEYOFF; } @@ -2372,7 +2377,10 @@ pSndFile->m_dwSongFlags &= ~(SONG_PAUSED|SONG_STEP); pSndFile->LoopPattern(nPat); pSndFile->m_nNextRow = nRow; - //rewbs.VSTCompliance + + // set playback timer in the status bar (and update channel status) + SetElapsedTime(nOrd, nRow); + if (pModPlaying == this) { pSndFile->StopAllVsti(); @@ -2380,7 +2388,7 @@ { pSndFile->ResumePlugins(); } - //end rewbs.VSTCompliance + cs.Leave(); if (pModPlaying != this) @@ -2405,7 +2413,7 @@ //User has sent play song command: set loop pattern checkbox to false. pChildFrm->SendViewMessage(VIEWMSG_PATTERNLOOP, 0); } - + CSoundFile *pSndFile = GetSoundFile(); ROWINDEX nRow; @@ -2418,12 +2426,8 @@ CModDoc *pModPlaying = pMainFrm->GetModPlaying(); CriticalSection cs; - - // set playback timer in the status bar (and update channel status) - SetElapsedTime(nOrd, nRow); - // Cut instruments/samples - for (UINT i=pSndFile->m_nChannels; i<MAX_CHANNELS; i++) + for(CHANNELINDEX i = pSndFile->GetNumChannels(); i < MAX_CHANNELS; i++) { pSndFile->Chn[i].dwFlags |= CHN_NOTEFADE | CHN_KEYOFF; } @@ -2434,13 +2438,18 @@ else pSndFile->LoopPattern(nPat); pSndFile->m_nNextRow = nRow; - //end rewbs.VSTCompliance - if (pModPlaying == this) { - pSndFile->StopAllVsti(); - } else { + + // set playback timer in the status bar (and update channel status) + SetElapsedTime(nOrd, nRow); + + if (pModPlaying == this) + { + pSndFile->StopAllVsti(); + } else + { pSndFile->ResumePlugins(); } - //rewbs.VSTCompliance + cs.Leave(); if (pModPlaying != this) @@ -2689,12 +2698,12 @@ void CModDoc::SetElapsedTime(ORDERINDEX nOrd, ROWINDEX nRow) //---------------------------------------------------------- { + const double dPatternPlaytime = m_SndFile.GetPlaybackTimeAt(nOrd, nRow, true); CMainFrame *pMainFrm = CMainFrame::GetMainFrame(); - if(pMainFrm == NULL) - return; - - const double dPatternPlaytime = m_SndFile.GetPlaybackTimeAt(nOrd, nRow, true); - pMainFrm->SetElapsedTime((DWORD) (max(0, dPatternPlaytime) * 1000)); + if(pMainFrm != nullptr) + { + pMainFrm->SetElapsedTime(static_cast<DWORD>(Util::Max(0.0, dPatternPlaytime) * 1000.0)); + } } Modified: trunk/OpenMPT/mptrack/Vstplug.cpp =================================================================== --- trunk/OpenMPT/mptrack/Vstplug.cpp 2012-05-25 17:04:28 UTC (rev 1281) +++ trunk/OpenMPT/mptrack/Vstplug.cpp 2012-05-25 18:04:20 UTC (rev 1282) @@ -715,15 +715,14 @@ MemsetZero(timeInfo); timeInfo.sampleRate = CMainFrame::GetMainFrame()->GetSampleRate(); - if (pVstPlugin) + CSoundFile *pSndFile; + if(pVstPlugin && (pSndFile = pVstPlugin->GetSoundFile()) != nullptr) { - CSoundFile* pSndFile = pVstPlugin->GetSoundFile(); - - if (pVstPlugin->IsSongPlaying()) + if(pVstPlugin->IsSongPlaying()) { timeInfo.flags |= kVstTransportPlaying; - timeInfo.samplePos = CMainFrame::GetMainFrame()->GetTotalSampleCount(); - if (timeInfo.samplePos == 0) //samplePos=0 means we just started playing + timeInfo.samplePos = pSndFile->GetTotalSampleCount(); + if(pSndFile->HasPositionChanged()) { timeInfo.flags |= kVstTransportChanged; } @@ -732,12 +731,12 @@ timeInfo.flags |= kVstTransportChanged; //just stopped. timeInfo.samplePos = 0; } - if ((value & kVstNanosValid)) + if((value & kVstNanosValid)) { timeInfo.flags |= kVstNanosValid; timeInfo.nanoSeconds = timeGetTime() * 1000000; } - if ((value & kVstPpqPosValid) && pSndFile) + if((value & kVstPpqPosValid)) { timeInfo.flags |= kVstPpqPosValid; if (timeInfo.flags & kVstTransportPlaying) @@ -748,7 +747,7 @@ timeInfo.ppqPos = 0; } } - if ((value & kVstTempoValid) && pSndFile) + if ((value & kVstTempoValid)) { timeInfo.tempo = pSndFile->GetCurrentBPM(); if (timeInfo.tempo) @@ -756,7 +755,7 @@ timeInfo.flags |= kVstTempoValid; } } - if ((value & kVstTimeSigValid) && pSndFile) + if ((value & kVstTimeSigValid)) { timeInfo.flags |= kVstTimeSigValid; @@ -2284,7 +2283,7 @@ VSTInstrChannel &channel = m_MidiCh[mc]; MidiPitchBend(mc, MIDIEvents::pitchBendCentre); // centre pitch bend - MidiSend(MIDIEvents::BuildCCEvent(MIDIEvents::MIDICC_AllControllersOff, mc, 0)); // reset all controllers + MidiSend(MIDIEvents::BuildCCEvent(MIDIEvents::MIDICC_AllControllersOff, mc, 0)); // reset all controllers MidiSend(MIDIEvents::BuildCCEvent(MIDIEvents::MIDICC_AllNotesOff, mc, 0)); // all notes off MidiSend(MIDIEvents::BuildCCEvent(MIDIEvents::MIDICC_AllSoundOff, mc, 0)); // all sounds off Modified: trunk/OpenMPT/mptrack/version.h =================================================================== --- trunk/OpenMPT/mptrack/version.h 2012-05-25 17:04:28 UTC (rev 1281) +++ trunk/OpenMPT/mptrack/version.h 2012-05-25 18:04:20 UTC (rev 1282) @@ -19,7 +19,7 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 20 #define VER_MINOR 01 -#define VER_MINORMINOR 03 +#define VER_MINORMINOR 04 //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-05-25 17:04:28 UTC (rev 1281) +++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2012-05-25 18:04:20 UTC (rev 1282) @@ -161,6 +161,8 @@ // Temporary visited rows vector (so that GetLength() won't interfere with the player code if the module is playing at the same time) RowVisitor visitedRows(*this); + samplecount_t renderedSamples = 0; + for (;;) { UINT rowDelay = 0, tickDelay = 0; @@ -528,8 +530,17 @@ nNextPatStartRow = 0; } - // XXX this does not take per-pattern time signatures into consideration! - memory.elapsedTime += GetRowDuration(memory.musicTempo, memory.musicSpeed, (memory.musicSpeed + tickDelay) * max(rowDelay, 1)); + ROWINDEX rowsPerBeat = m_nDefaultRowsPerBeat; + if(Patterns[nPattern].GetOverrideSignature()) + { + rowsPerBeat = Patterns[nPattern].GetRowsPerBeat(); + } + + const UINT tickDuration = GetTickDuration(memory.musicTempo, memory.musicSpeed, rowsPerBeat); + const UINT rowDuration = tickDuration * (memory.musicSpeed + tickDelay) * max(rowDelay, 1); + + memory.elapsedTime += static_cast<double>(rowDuration) / static_cast<double>(gdwMixingFreq); + renderedSamples += rowDuration; } if(retval.targetReached || endOrder == ORDERINDEX_INVALID || endRow == ROWINDEX_INVALID) @@ -537,15 +548,17 @@ retval.lastOrder = nCurrentOrder; retval.lastRow = nRow; } - retval.duration = memory.elapsedTime / 1000.0; + retval.duration = memory.elapsedTime; // Store final variables - if ((adjustMode & eAdjust)) + if((adjustMode & eAdjust)) { - if (retval.targetReached || endOrder == ORDERINDEX_INVALID || endRow == ROWINDEX_INVALID) + if(retval.targetReached || endOrder == ORDERINDEX_INVALID || endRow == ROWINDEX_INVALID) { // Target found, or there is no target (i.e. play whole song)... m_nGlobalVolume = memory.glbVol; + m_lTotalSampleCount = renderedSamples; + m_bPositionChanged = true; if(IsCompatibleMode(TRK_IMPULSETRACKER | TRK_FASTTRACKER2)) { //IT compatibility 16. Global volume slide params are stored per channel (FT2/IT) @@ -559,10 +572,10 @@ } m_nMusicSpeed = memory.musicSpeed; m_nMusicTempo = memory.musicTempo; - for (CHANNELINDEX n = 0; n < GetNumChannels(); n++) + for(CHANNELINDEX n = 0; n < GetNumChannels(); n++) { Chn[n].nGlobalVol = memory.chnVols[n]; - if (memory.notes[n] != NOTE_NONE) + if(memory.notes[n] != NOTE_NONE) { Chn[n].nNewNote = memory.notes[n]; if(ModCommand::IsNote(memory.notes[n])) @@ -570,10 +583,10 @@ Chn[n].nLastNote = memory.notes[n]; } } - if (memory.instr[n]) Chn[n].nNewIns = memory.instr[n]; - if (memory.vols[n] != 0xFF) + if(memory.instr[n]) Chn[n].nNewIns = memory.instr[n]; + if(memory.vols[n] != 0xFF) { - if (memory.vols[n] > 64) memory.vols[n] = 64; + if(memory.vols[n] > 64) memory.vols[n] = 64; Chn[n].nVolume = memory.vols[n] * 4; } } Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2012-05-25 17:04:28 UTC (rev 1281) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2012-05-25 18:04:20 UTC (rev 1282) @@ -486,7 +486,8 @@ MemsetZero(m_MixPlugins); Order.Init(); Patterns.ClearPatterns(); - m_lTotalSampleCount=0; + m_lTotalSampleCount = 0; + m_bPositionChanged = true; m_pConfig = new CSoundFilePlayConfig(); m_pTuningsTuneSpecific = new CTuningCollection("Tune specific tunings"); @@ -1153,7 +1154,6 @@ pPlugin->Suspend(); } } - m_lTotalSampleCount=0; } void CSoundFile::ResumePlugins() @@ -1171,8 +1171,6 @@ pPlugin->Resume(); } } - m_lTotalSampleCount=GetSampleOffset(); - } @@ -1190,7 +1188,6 @@ pPlugin->HardAllNotesOff(); } } - m_lTotalSampleCount = GetSampleOffset(); } @@ -1768,16 +1765,6 @@ } -long CSoundFile::GetSampleOffset() -//-------------------------------- -{ - //TODO: This is where we could inform patterns of the exact song position when playback starts. - //order: m_nNextPattern - //long ticksFromStartOfPattern = m_nRow*m_nMusicSpeed; - //return ticksFromStartOfPattern*m_nSamplesPerTick; - return 0; -} - string CSoundFile::GetNoteName(const CTuning::NOTEINDEXTYPE& note, const INSTRUMENTINDEX inst) const //-------------------------------------------------------------------------------------------------- { @@ -1899,30 +1886,60 @@ } +// Get length of a tick in sample, with tick-to-tick tempo correction in modern tempo mode. +UINT CSoundFile::GetTickDuration(UINT tempo, UINT speed, ROWINDEX rowsPerBeat) +//---------------------------------------------------------------------------- +{ + switch(m_nTempoMode) + { + case tempo_mode_classic: + default: + return (gdwMixingFreq * 5 * m_nTempoFactor) / (tempo << 8); + + case tempo_mode_alternative: + return gdwMixingFreq / tempo; + + case tempo_mode_modern: + { + double accurateBufferCount = static_cast<double>(gdwMixingFreq) * (60.0 / static_cast<double>(tempo) / (static_cast<double>(speed * rowsPerBeat))); + UINT bufferCount = static_cast<int>(accurateBufferCount); + m_dBufferDiff += accurateBufferCount - bufferCount; + + //tick-to-tick tempo correction: + if(m_dBufferDiff >= 1) + { + bufferCount++; + m_dBufferDiff--; + } else if(m_dBufferDiff <= -1) + { + bufferCount--; + m_dBufferDiff++; + } + ASSERT(abs(m_dBufferDiff) < 1); + return bufferCount; + } + } +} + + // Get the duration of a row in milliseconds, based on the current rows per beat and given speed and tempo settings. -// "speedIncludingPatternDelays" is the total row length, including the ticks from Row Delay effects. -// It is required because modern tempo mode normally doesn't consider "speed", so "speedIncludingPatternDelays" is -// used as a ratio. -double CSoundFile::GetRowDuration(UINT tempo, UINT speed, UINT speedIncludingPatternDelays) const -//----------------------------------------------------------------------------------------------- +double CSoundFile::GetRowDuration(UINT tempo, UINT speed) const +//------------------------------------------------------------- { - speedIncludingPatternDelays = Util::Max(speedIncludingPatternDelays, speed); - switch(m_nTempoMode) { case tempo_mode_classic: default: - return static_cast<double>(2500 * speedIncludingPatternDelays) / static_cast<double>(tempo); + return static_cast<double>(2500 * speed) / static_cast<double>(tempo); case tempo_mode_modern: { // If there are any row delay effects, the row length factor compensates for those. - const double rowLength = static_cast<double>(speedIncludingPatternDelays) / static_cast<double>(speed); - return 60000.0 * rowLength / static_cast<double>(tempo) / static_cast<double>(m_nCurrentRowsPerBeat); + return 60000.0 / static_cast<double>(tempo) / static_cast<double>(m_nCurrentRowsPerBeat); } case tempo_mode_alternative: - return static_cast<double>(1000 * speedIncludingPatternDelays) / static_cast<double>(tempo); + return static_cast<double>(1000 * speed) / static_cast<double>(tempo); } } Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2012-05-25 17:04:28 UTC (rev 1281) +++ trunk/OpenMPT/soundlib/Sndfile.h 2012-05-25 18:04:20 UTC (rev 1282) @@ -243,6 +243,7 @@ static PMIXPLUGINCREATEPROC gpMixPluginCreateProc; static uint8 s_DefaultPlugVolumeHandling; + typedef uint32 samplecount_t; // Number of rendered samples public: // for Editing CModDoc *m_pModDoc; // Can be a null pointer for example when previewing samples from the treeview. @@ -253,11 +254,13 @@ UINT m_nDefaultSpeed, m_nDefaultTempo, m_nDefaultGlobalVolume; DWORD m_dwSongFlags; // Song flags SONG_XXXX bool m_bIsRendering; - UINT m_nMixChannels, m_nMixStat, m_nBufferCount; + UINT m_nMixChannels, m_nMixStat; + samplecount_t m_nBufferCount; double m_dBufferDiff; UINT m_nTickCount; UINT m_nPatternDelay, m_nFrameDelay; // m_nPatternDelay = pattern delay (rows), m_nFrameDelay = fine pattern delay (ticks) - ULONG m_lTotalSampleCount; // rewbs.VSTTimeInfo + samplecount_t m_lTotalSampleCount; // rewbs.VSTTimeInfo + bool m_bPositionChanged; // Report to plugins that we jumped around in the module UINT m_nSamplesPerTick; // rewbs.betterBPM ROWINDEX m_nDefaultRowsPerBeat, m_nDefaultRowsPerMeasure; // default rows per beat and measure for this module // rewbs.betterBPM ROWINDEX m_nCurrentRowsPerBeat, m_nCurrentRowsPerMeasure; // current rows per beat and measure for this module @@ -319,8 +322,14 @@ bool TypeIsS3M_IT_MPT() const { return (m_nType & (MOD_TYPE_S3M | MOD_TYPE_IT | MOD_TYPE_MPT)) != 0; } bool TypeIsXM_MOD() const { return (m_nType & (MOD_TYPE_XM | MOD_TYPE_MOD)) != 0; } bool TypeIsMOD_S3M() const { return (m_nType & (MOD_TYPE_MOD | MOD_TYPE_S3M)) != 0; } - CModDoc* GetpModDoc() const { return m_pModDoc; } + // Get parent CModDoc. Can be nullptr if previewing from tree view, and is always nullptr if we're not actually compiling OpenMPT. +#ifdef MODPLUG_TRACKER + CModDoc *GetpModDoc() const { return m_pModDoc; } +#else + void *GetpModDoc() const { return nullptr; } +#endif // MODPLUG_TRACKER + void SetMasterVolume(UINT vol, bool adjustAGC = false); UINT GetMasterVolume() const { return m_nMasterVolume; } @@ -354,7 +363,8 @@ DWORD GetSongTime() { return static_cast<DWORD>(GetLength(eNoAdjust).duration + 0.5); } void RecalculateSamplesPerTick(); - double GetRowDuration(UINT tempo, UINT speed, UINT speedIncludingPatternDelays = 0) const; + double GetRowDuration(UINT tempo, UINT speed) const; + UINT GetTickDuration(UINT tempo, UINT speed, ROWINDEX rowsPerBeat); // A repeat count value of -1 means infinite loop void SetRepeatCount(int n) { m_nRepeatCount = n; } @@ -448,6 +458,8 @@ BOOL FadeSong(UINT msec); BOOL GlobalFadeSong(UINT msec); void ProcessPlugins(UINT nCount); + size_t GetTotalSampleCount() const { return m_lTotalSampleCount; } + bool HasPositionChanged() { bool b = m_bPositionChanged; m_bPositionChanged = false; return b; } public: // Mixer Config @@ -662,7 +674,7 @@ // System-Dependant functions public: static LPSTR AllocateSample(UINT nbytes); - static void FreeSample(LPVOID p); + static void FreeSample(void *p); // WAV export static UINT Normalize24BitBuffer(LPBYTE pbuffer, UINT cbsizebytes, DWORD lmax24, DWORD dwByteInc); @@ -722,7 +734,6 @@ PLUGINDEX __cdecl GetActiveInstrumentPlugin(CHANNELINDEX, PluginMutePriority respectMutes) const; void HandlePatternTransitionEvents(); - long GetSampleOffset(); public: PLUGINDEX GetBestPlugin(CHANNELINDEX nChn, PluginPriority priority, PluginMutePriority respectMutes) const; Modified: trunk/OpenMPT/soundlib/Sndmix.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndmix.cpp 2012-05-25 17:04:28 UTC (rev 1281) +++ trunk/OpenMPT/soundlib/Sndmix.cpp 2012-05-25 18:04:20 UTC (rev 1282) @@ -250,11 +250,11 @@ BOOL CSoundFile::FadeSong(UINT msec) //---------------------------------- { - LONG nsamples = _muldiv(msec, gdwMixingFreq, 1000); + samplecount_t nsamples = _muldiv(msec, gdwMixingFreq, 1000); if (nsamples <= 0) return FALSE; if (nsamples > 0x100000) nsamples = 0x100000; m_nBufferCount = nsamples; - LONG nRampLength = m_nBufferCount; + samplecount_t nRampLength = m_nBufferCount; // Ramp everything down for (UINT noff=0; noff < m_nMixChannels; noff++) { @@ -289,7 +289,9 @@ { LPBYTE lpBuffer = (LPBYTE)lpDestBuffer; LPCONVERTPROC pCvt = X86_Convert32To8; - UINT lRead, lMax, lSampleSize, lCount, lSampleCount, nStat=0; + samplecount_t lMax, lCount, lSampleCount; + size_t lSampleSize; + UINT nStat = 0; UINT nMaxPlugins; nMaxPlugins = MAX_MIXPLUGINS; @@ -305,7 +307,7 @@ lMax = cbBuffer / lSampleSize; if ((!lMax) || (!lpBuffer) || (!m_nChannels)) return 0; - lRead = lMax; + samplecount_t lRead = lMax; if (m_dwSongFlags & SONG_ENDREACHED) goto MixDone; @@ -1847,44 +1849,12 @@ //////////////////////////////////////////////////////////////////////////////////// if (!m_nMusicTempo) return FALSE; - switch(m_nTempoMode) - { + m_nSamplesPerTick = m_nBufferCount = GetTickDuration(m_nMusicTempo, m_nMusicSpeed, m_nCurrentRowsPerBeat); - case tempo_mode_alternative: - m_nBufferCount = gdwMixingFreq / m_nMusicTempo; - break; - - case tempo_mode_modern: - { - double accurateBufferCount = (double)gdwMixingFreq * (60.0 / (double)m_nMusicTempo / ((double)m_nMusicSpeed * (double)m_nCurrentRowsPerBeat)); - m_nBufferCount = static_cast<int>(accurateBufferCount); - m_dBufferDiff += accurateBufferCount-m_nBufferCount; - //tick-to-tick tempo correction: - if (m_dBufferDiff >= 1) - { - m_nBufferCount++; - m_dBufferDiff--; - } else if (m_dBufferDiff <= -1) - { - m_nBufferCount--; - m_dBufferDiff++; - } - ASSERT(abs(m_dBufferDiff) < 1); - break; - } - - case tempo_mode_classic: - default: - m_nBufferCount = (gdwMixingFreq * 5 * m_nTempoFactor) / (m_nMusicTempo << 8); - } - - m_nSamplesPerTick = m_nBufferCount; //rewbs.flu - - // Master Volume + Pre-Amplification / Attenuation setup DWORD nMasterVol; { - int nchn32 = CLAMP(m_nChannels, 1, 31); + CHANNELINDEX nchn32 = Clamp(m_nChannels, CHANNELINDEX(1), CHANNELINDEX(31)); DWORD mastervol; @@ -1894,7 +1864,7 @@ if (realmastervol > 0x80) { //Attenuate global pre-amp depending on num channels - realmastervol = 0x80 + ((realmastervol - 0x80) * (nchn32+4)) / 16; + realmastervol = 0x80 + ((realmastervol - 0x80) * (nchn32 + 4)) / 16; } mastervol = (realmastervol * (m_nSamplePreAmp)) >> 6; } else @@ -1910,7 +1880,7 @@ if (m_pConfig->getUseGlobalPreAmp()) { - UINT attenuation = (gdwSoundSetup & SNDMIX_AGC) ? PreAmpAGCTable[nchn32>>1] : PreAmpTable[nchn32>>1]; + UINT attenuation = (gdwSoundSetup & SNDMIX_AGC) ? PreAmpAGCTable[nchn32 >> 1] : PreAmpTable[nchn32 >> 1]; if(attenuation < 1) attenuation = 1; nMasterVol = (mastervol << 7) / attenuation; } else @@ -2120,7 +2090,7 @@ } // Applying Pitch/Tempo lock. - if(GetType() & (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); } @@ -2456,11 +2426,11 @@ //If new note, determine notevelocity to use. if(note != NOTE_NONE) { - UINT velocity = 4 * defaultVolume; + uint16 velocity = static_cast<uint16>(4 * defaultVolume); switch(pIns->nPluginVelocityHandling) { case PLUGIN_VELOCITYHANDLING_CHANNEL: - velocity = pChn->nVolume; + velocity = static_cast<uint16>(pChn->nVolume); break; } @@ -2486,7 +2456,7 @@ case PLUGIN_VOLUMEHANDLING_MIDI: if(hasVolCommand) pPlugin->MidiCC(GetBestMidiChannel(nChn), MIDIEvents::MIDICC_Volume_Coarse, min(127, 2 * vol), nChn); - else pPlugin->MidiCC(GetBestMidiChannel(nChn), MIDIEvents::MIDICC_Volume_Coarse, min(127, 2 * defaultVolume), nChn); + else pPlugin->MidiCC(GetBestMidiChannel(nChn), MIDIEvents::MIDICC_Volume_Coarse, static_cast<uint8>(min(127, 2 * defaultVolume)), nChn); break; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |