|
From: <man...@us...> - 2013-06-06 23:16:38
|
Revision: 2310
http://sourceforge.net/p/modplug/code/2310
Author: manxorist
Date: 2013-06-06 23:16:28 +0000 (Thu, 06 Jun 2013)
Log Message:
-----------
[Fix] In ApplyGlobalVolume, ramping up and down lengths were mixed up.
[Fix] For stereo or quad output, the global volume ramping length in ApplyGlobalVolume was only half the configured length.
[Fix] For stereo or quad output, the ramped volume that got applied to the left and right channels differed slightly.
[Ref] Make the last parameter of ApplyGlobalVolume the number of samples per channel instead of the total number of samples in the mix buffer.
Modified Paths:
--------------
trunk/OpenMPT/soundlib/Sndfile.h
trunk/OpenMPT/soundlib/Sndmix.cpp
Modified: trunk/OpenMPT/soundlib/Sndfile.h
===================================================================
--- trunk/OpenMPT/soundlib/Sndfile.h 2013-06-06 18:42:34 UTC (rev 2309)
+++ trunk/OpenMPT/soundlib/Sndfile.h 2013-06-06 23:16:28 UTC (rev 2310)
@@ -785,7 +785,7 @@
#ifdef MODPLUG_TRACKER
void ProcessMidiOut(CHANNELINDEX nChn);
#endif // MODPLUG_TRACKER
- void ApplyGlobalVolume(int SoundBuffer[], int RearBuffer[], long lTotalSampleCount);
+ void ApplyGlobalVolume(int *SoundBuffer, int *RearBuffer, long lCount);
#ifndef MODPLUG_TRACKER
void ApplyFinalOutputGain(int SoundBuffer[], int RearBuffer[], long lCount); // lCount meaning the number of frames, totally independet from the numer of channels
Modified: trunk/OpenMPT/soundlib/Sndmix.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Sndmix.cpp 2013-06-06 18:42:34 UTC (rev 2309)
+++ trunk/OpenMPT/soundlib/Sndmix.cpp 2013-06-06 23:16:28 UTC (rev 2310)
@@ -310,7 +310,7 @@
// Apply global volume
if (m_PlayConfig.getGlobalVolumeAppliesToMaster())
{
- ApplyGlobalVolume(MixSoundBuffer, MixRearBuffer, lSampleCount);
+ ApplyGlobalVolume(MixSoundBuffer, MixRearBuffer, lCount);
}
} else
{
@@ -326,7 +326,7 @@
// Apply global volume
if (m_PlayConfig.getGlobalVolumeAppliesToMaster())
{
- ApplyGlobalVolume(MixSoundBuffer, nullptr, lSampleCount);
+ ApplyGlobalVolume(MixSoundBuffer, MixRearBuffer, lCount);
}
}
@@ -2270,11 +2270,41 @@
#endif // MODPLUG_TRACKER
-void CSoundFile::ApplyGlobalVolume(int SoundBuffer[], int RearBuffer[], long lTotalSampleCount)
-//---------------------------------------------------------------------------------------------
+template<int channels>
+forceinline void ApplyGlobalVolumeWithRamping(int *SoundBuffer, int *RearBuffer, long lCount, UINT m_nGlobalVolume, long step, UINT &m_nSamplesToGlobalVolRampDest, long &m_lHighResRampingGlobalVolume)
{
- long step = 0;
+ const bool isStereo = (channels >= 2);
+ const bool hasRear = (channels >= 4);
+ for(int pos = 0; pos < lCount; ++pos)
+ {
+ if(m_nSamplesToGlobalVolRampDest > 0)
+ {
+ // Ramping required
+ m_lHighResRampingGlobalVolume += step;
+ SoundBuffer[0] = Util::muldiv(SoundBuffer[0], m_lHighResRampingGlobalVolume, MAX_GLOBAL_VOLUME << VOLUMERAMPPRECISION);
+ if(isStereo) SoundBuffer[1] = Util::muldiv(SoundBuffer[1], m_lHighResRampingGlobalVolume, MAX_GLOBAL_VOLUME << VOLUMERAMPPRECISION);
+ if(hasRear) RearBuffer[0] = Util::muldiv(RearBuffer[0] , m_lHighResRampingGlobalVolume, MAX_GLOBAL_VOLUME << VOLUMERAMPPRECISION);
+ if(hasRear) RearBuffer[1] = Util::muldiv(RearBuffer[1] , m_lHighResRampingGlobalVolume, MAX_GLOBAL_VOLUME << VOLUMERAMPPRECISION);
+ m_nSamplesToGlobalVolRampDest--;
+ } else
+ {
+ SoundBuffer[0] = Util::muldiv(SoundBuffer[0], m_nGlobalVolume, MAX_GLOBAL_VOLUME);
+ if(isStereo) SoundBuffer[1] = Util::muldiv(SoundBuffer[1], m_nGlobalVolume, MAX_GLOBAL_VOLUME);
+ if(hasRear) RearBuffer[0] = Util::muldiv(RearBuffer[0] , m_nGlobalVolume, MAX_GLOBAL_VOLUME);
+ if(hasRear) RearBuffer[1] = Util::muldiv(RearBuffer[1] , m_nGlobalVolume, MAX_GLOBAL_VOLUME);
+ m_lHighResRampingGlobalVolume = m_nGlobalVolume << VOLUMERAMPPRECISION;
+ }
+ SoundBuffer += isStereo ? 2 : 1;
+ if(hasRear) RearBuffer += 2;
+ }
+}
+
+void CSoundFile::ApplyGlobalVolume(int *SoundBuffer, int *RearBuffer, long lCount)
+//--------------------------------------------------------------------------------
+{
+
+ // should we ramp?
if(IsGlobalVolumeUnset())
{
// do not ramp if no global volume was set before (which is the case at song start), to prevent audible glitches when default volume is > 0 and it is set to 0 in the first row
@@ -2284,13 +2314,20 @@
} else if(m_nGlobalVolumeDestination != m_nGlobalVolume)
{
// User has provided new global volume
- const bool rampUp = m_nGlobalVolumeDestination > m_nGlobalVolume;
+
+ // m_nGlobalVolume: the last global volume which got set e.g. by a pattern command
+ // m_nGlobalVolumeDestination: the current target of the ramping algorithm
+ const bool rampUp = m_nGlobalVolume > m_nGlobalVolumeDestination;
+
m_nGlobalVolumeDestination = m_nGlobalVolume;
m_nSamplesToGlobalVolRampDest = m_nGlobalVolumeRampAmount = rampUp ? m_MixerSettings.glVolumeRampUpSamples : m_MixerSettings.glVolumeRampDownSamples;
}
+ // calculate ramping step
+ long step = 0;
if (m_nSamplesToGlobalVolRampDest > 0)
{
+
// Still some ramping left to do.
long highResGlobalVolumeDestination = static_cast<long>(m_nGlobalVolumeDestination) << VOLUMERAMPPRECISION;
@@ -2307,32 +2344,18 @@
}
}
- const long highResVolume = m_lHighResRampingGlobalVolume;
- const UINT samplesToRamp = m_nSamplesToGlobalVolRampDest;
-
- // SoundBuffer has interleaved left/right channels for the front channels; RearBuffer has the rear left/right channels.
- // So we process the pairs independently for ramping.
- for (int pairs = MAX(m_MixerSettings.gnChannels / 2, 1); pairs > 0; pairs--)
+ // apply volume and ramping
+ if(m_MixerSettings.gnChannels == 1)
{
- int *sample = (pairs == 1) ? SoundBuffer : RearBuffer;
- m_lHighResRampingGlobalVolume = highResVolume;
- m_nSamplesToGlobalVolRampDest = samplesToRamp;
+ ApplyGlobalVolumeWithRamping<1>(SoundBuffer, RearBuffer, lCount, m_nGlobalVolume, step, m_nSamplesToGlobalVolRampDest, m_lHighResRampingGlobalVolume);
+ } else if(m_MixerSettings.gnChannels == 2)
+ {
+ ApplyGlobalVolumeWithRamping<2>(SoundBuffer, RearBuffer, lCount, m_nGlobalVolume, step, m_nSamplesToGlobalVolRampDest, m_lHighResRampingGlobalVolume);
+ } else if(m_MixerSettings.gnChannels == 4)
+ {
+ ApplyGlobalVolumeWithRamping<4>(SoundBuffer, RearBuffer, lCount, m_nGlobalVolume, step, m_nSamplesToGlobalVolRampDest, m_lHighResRampingGlobalVolume);
+ }
- for (int pos = lTotalSampleCount; pos > 0; pos--, sample++)
- {
- if (m_nSamplesToGlobalVolRampDest > 0)
- {
- // Ramping required
- m_lHighResRampingGlobalVolume += step;
- *sample = Util::muldiv(*sample, m_lHighResRampingGlobalVolume, MAX_GLOBAL_VOLUME << VOLUMERAMPPRECISION);
- m_nSamplesToGlobalVolRampDest--;
- } else
- {
- *sample = Util::muldiv(*sample, m_nGlobalVolume, MAX_GLOBAL_VOLUME);
- m_lHighResRampingGlobalVolume = m_nGlobalVolume << VOLUMERAMPPRECISION;
- }
- }
- }
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|