Skip to content

Commit

Permalink
Add SpeedChange_Good
Browse files Browse the repository at this point in the history
Notable changes outside SpeedChange good:
- RageSound.cpp: Moving PostBuffering. This lets you change volume
  immediately. Before nothing buffered long enough for this to happen,
  but at rates of 0.05 the amount of buffering by SpeedChange_Good is
  very long, so if you have it really loud and try to reduce the volume,
  nothing happens. Very bad
- GameSoundManager.cpp: Initialising music with the current rate
  pre-applied. Without this the first few reads of a file often have
  no rate applied which is audible in the music wheel
  • Loading branch information
graemephi committed Sep 24, 2024
1 parent cd27b64 commit 4416f8f
Show file tree
Hide file tree
Showing 9 changed files with 660 additions and 11 deletions.
2 changes: 2 additions & 0 deletions src/Etterna/Singletons/GameSoundManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,8 @@ GameSoundManager::StartMusic(MusicToPlay& ToPlay)
p.m_fFadeOutSeconds = ToPlay.fFadeOutLengthSeconds;
p.m_StartTime = when;
p.m_bAccurateSync = ToPlay.bAccurateSync;
if (ToPlay.bApplyMusicRate)
p.m_fSpeed = GAMESTATE->m_SongOptions.GetPreferred().m_fMusicRate;
if (ToPlay.bForceLoop)
p.StopMode = RageSoundParams::M_LOOP;
NewMusic->m_Music->SetParams(p);
Expand Down
2 changes: 2 additions & 0 deletions src/RageUtil/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ list(APPEND SMDATA_RAGE_SOUND_SRC
"Sound/RageSoundReader_Preload.cpp"
"Sound/RageSoundReader_Resample_Good.cpp"
"Sound/RageSoundReader_SpeedChange.cpp"
"Sound/RageSoundReader_SpeedChange_Good.cpp"
"Sound/RageSoundReader_ThreadedBuffer.cpp"
"Sound/RageSoundReader_WAV.cpp"
"Sound/RageSoundUtil.cpp"
Expand All @@ -173,6 +174,7 @@ list(APPEND SMDATA_RAGE_SOUND_HPP
"Sound/RageSoundReader_Preload.h"
"Sound/RageSoundReader_Resample_Good.h"
"Sound/RageSoundReader_SpeedChange.h"
"Sound/RageSoundReader_SpeedChange_Good.h"
"Sound/RageSoundReader_ThreadedBuffer.h"
"Sound/RageSoundReader_WAV.h"
"Sound/RageSoundUtil.h"
Expand Down
2 changes: 1 addition & 1 deletion src/RageUtil/Sound/RageSound.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,12 +242,12 @@ RageSound::Load(const std::string& sSoundFilePath,
m_pSource = new RageSoundReader_Extend(m_pSource);
if (bNeedBuffer)
m_pSource = new RageSoundReader_ThreadedBuffer(m_pSource);
m_pSource = new RageSoundReader_PostBuffering(m_pSource);

if (pParams->m_bSupportRateChanging) {
auto* pRate = new RageSoundReader_PitchChange(m_pSource);
m_pSource = pRate;
}
m_pSource = new RageSoundReader_PostBuffering(m_pSource);

if (pParams->m_bSupportPan)
m_pSource = new RageSoundReader_Pan(m_pSource);
Expand Down
37 changes: 33 additions & 4 deletions src/RageUtil/Sound/RageSoundReader_PitchChange.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,23 @@
#include "RageSoundReader_PitchChange.h"
#include "RageSoundReader_Resample_Good.h"
#include "RageSoundReader_SpeedChange.h"
#include "RageSoundReader_SpeedChange_Good.h"

static Preference<bool> g_StepmaniaUnpitchRates("StepmaniaUnpitchRates", false);

RageSoundReader_PitchChange::RageSoundReader_PitchChange(
RageSoundReader* pSource)
: RageSoundReader_Filter(nullptr)
{
m_pSpeedChange = new RageSoundReader_SpeedChange(pSource);
m_pResample = new RageSoundReader_Resample_Good(
m_pSpeedChange, m_pSpeedChange->GetSampleRate());
bool bMepstania = g_StepmaniaUnpitchRates.Get();
if (bMepstania) {
m_pSpeedChange = new RageSoundReader_SpeedChange(pSource, bMepstania);
m_pResample = new RageSoundReader_Resample_Good(m_pSpeedChange, m_pSpeedChange->GetSampleRate());
} else {
m_pSpeedChangeGood = new RageSoundReader_SpeedChange_Good(pSource);
m_pSpeedChange = new RageSoundReader_SpeedChange(m_pSpeedChangeGood, bMepstania);
m_pResample = new RageSoundReader_Resample_Good(m_pSpeedChange, m_pSpeedChange->GetSampleRate());
}
m_pSource = std::unique_ptr<RageSoundReader_Resample_Good>(m_pResample);
m_fSpeedRatio = 1.0f;
m_fPitchRatio = 1.0f;
Expand All @@ -44,6 +53,11 @@ RageSoundReader_PitchChange::RageSoundReader_PitchChange(
ASSERT_M(pspdchng != nullptr,
"Dynamic cast to RageSoundReader SpeedChange failed at runtime.");
m_pSpeedChange = pspdchng;
auto pspdchnggd =
dynamic_cast<RageSoundReader_SpeedChange_Good*>(m_pSpeedChange->GetSource());
ASSERT_M(pspdchnggd != nullptr,
"Dynamic cast to RageSoundReader SpeedChange failed at runtime.");
m_pSpeedChangeGood = pspdchnggd;
m_fSpeedRatio = cpy.m_fSpeedRatio;
m_fPitchRatio = cpy.m_fPitchRatio;
m_fLastSetSpeedRatio = cpy.m_fLastSetSpeedRatio;
Expand Down Expand Up @@ -73,7 +87,22 @@ RageSoundReader_PitchChange::Read(float* pBuf, int iFrames)
m_pResample->SetRate(m_fPitchRatio);
float fActualPitchRatio = m_pResample->GetRate();
float fRequestedSpeedRatio = m_fSpeedRatio / fActualPitchRatio;
m_pSpeedChange->SetSpeedRatio(fRequestedSpeedRatio);

bool bMepstania = g_StepmaniaUnpitchRates.Get();
if (bMepstania) {
m_pSpeedChange->SetSpeedRatio(fRequestedSpeedRatio);
} else {
// SpeedChange_Good is bad at downrates, but bad in a different way than SpeedChange.
// And both sound okay for small down rates. So doing half the down rate in one and then the other
// sounds better than either one alone.......
if ((fRequestedSpeedRatio >= 0.5f) && (fRequestedSpeedRatio < 1.0f)) {
m_pSpeedChange->SetSpeedRatio(sqrtf(fRequestedSpeedRatio * 1.05f));
m_pSpeedChangeGood->SetSpeedRatio(sqrtf(fRequestedSpeedRatio / 1.05f));
} else {
m_pSpeedChange->SetSpeedRatio(1.0f);
m_pSpeedChangeGood->SetSpeedRatio(fRequestedSpeedRatio);
}
}

m_fLastSetSpeedRatio = m_fSpeedRatio;
m_fLastSetPitchRatio = m_fPitchRatio;
Expand Down
3 changes: 3 additions & 0 deletions src/RageUtil/Sound/RageSoundReader_PitchChange.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "RageSoundReader_Filter.h"

class RageSoundReader_SpeedChange;
class RageSoundReader_SpeedChange_Good;
class RageSoundReader_Resample_Good;

class RageSoundReader_PitchChange : public RageSoundReader_Filter
Expand All @@ -29,6 +30,8 @@ class RageSoundReader_PitchChange : public RageSoundReader_Filter
private:
RageSoundReader_SpeedChange*
m_pSpeedChange; // freed by RageSoundReader_Filter
RageSoundReader_SpeedChange_Good*
m_pSpeedChangeGood; // freed by RageSoundReader_Filter
RageSoundReader_Resample_Good*
m_pResample; // freed by RageSoundReader_Filter

Expand Down
8 changes: 3 additions & 5 deletions src/RageUtil/Sound/RageSoundReader_SpeedChange.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,11 @@

#include <algorithm>

static Preference<bool> g_StepmaniaUnpitchRates("StepmaniaUnpitchRates", false);

RageSoundReader_SpeedChange::RageSoundReader_SpeedChange(
RageSoundReader* pSource)
RageSoundReader* pSource, bool bStepMania)
: RageSoundReader_Filter(pSource)
, m_iWindowSize(g_StepmaniaUnpitchRates ? 30 : 70)
, m_bMidSideEncoding(!g_StepmaniaUnpitchRates)
, m_iWindowSize(bStepMania ? 30 : 70)
, m_bMidSideEncoding(!bStepMania)
{
m_Channels.resize(pSource->GetNumChannels());
m_fSpeedRatio = m_fTrailingSpeedRatio = 1.0f;
Expand Down
2 changes: 1 addition & 1 deletion src/RageUtil/Sound/RageSoundReader_SpeedChange.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
class RageSoundReader_SpeedChange : public RageSoundReader_Filter
{
public:
RageSoundReader_SpeedChange(RageSoundReader* pSource);
RageSoundReader_SpeedChange(RageSoundReader* pSource, bool bStepMania);

virtual int SetPosition(int iFrame);
virtual int Read(float* pBuf, int iFrames);
Expand Down
Loading

0 comments on commit 4416f8f

Please sign in to comment.