Fix: don't chop off the first 26ms of each MP3 (but don't change sync,
either).
This commit is contained in:
@@ -520,7 +520,7 @@ void RageSound::StopPlaying()
|
||||
if(!playing)
|
||||
return;
|
||||
|
||||
stopped_position = GetPositionSeconds();
|
||||
stopped_position = GetPositionSecondsInternal();
|
||||
|
||||
/* Tell the sound manager to stop mixing this sound. */
|
||||
SOUNDMAN->StopMixing(this);
|
||||
@@ -555,7 +555,8 @@ float RageSound::GetLengthSeconds()
|
||||
return len / 1000.f; /* ms -> secs */
|
||||
}
|
||||
|
||||
float RageSound::GetPositionSeconds() const
|
||||
/* Get the position, not counting GetOffsetFix. */
|
||||
float RageSound::GetPositionSecondsInternal() const
|
||||
{
|
||||
LockMut(SOUNDMAN->lock);
|
||||
|
||||
@@ -624,6 +625,13 @@ float RageSound::GetPositionSeconds() const
|
||||
return GetPlaybackRate() * closest_position / float(samplerate());
|
||||
}
|
||||
|
||||
float RageSound::GetPositionSeconds() const
|
||||
{
|
||||
LOG->Trace("XXX fix %f", Sample->GetOffsetFix());
|
||||
return GetPositionSecondsInternal() + Sample->GetOffsetFix();
|
||||
}
|
||||
|
||||
|
||||
bool RageSound::SetPositionSeconds( float fSeconds )
|
||||
{
|
||||
return SetPositionSamples( fSeconds == -1? -1: int(fSeconds * samplerate()) );
|
||||
|
||||
@@ -132,6 +132,7 @@ private:
|
||||
|
||||
CString error;
|
||||
|
||||
float GetPositionSecondsInternal() const;
|
||||
bool SetPositionSamples( int samples = -1 );
|
||||
int GetData(char *buffer, int size);
|
||||
void Fail(CString reason);
|
||||
|
||||
@@ -10,6 +10,8 @@ protected:
|
||||
void SetError(string e) const { error = e; }
|
||||
|
||||
public:
|
||||
virtual float GetOffsetFix() const { return 0; }
|
||||
|
||||
virtual int GetLength() const = 0; /* ms */
|
||||
virtual int GetLength_Fast() const { return GetLength(); } /* ms */
|
||||
virtual int SetPosition_Accurate(int ms) = 0;
|
||||
|
||||
@@ -604,12 +604,24 @@ SoundReader_FileReader::OpenResult RageSoundReader_MP3::Open( CString filename_
|
||||
|
||||
SampleRate = mad->Frame.header.samplerate;
|
||||
mad->framelength = mad->Frame.header.duration;
|
||||
this->Channels = 0;
|
||||
this->Channels = MAD_NCHANNELS( &mad->Frame.header );
|
||||
|
||||
/* Since we've already decoded a frame, just synth it instead of rewinding
|
||||
* the stream. */
|
||||
synth_output();
|
||||
this->Channels = MAD_NCHANNELS( &mad->Frame.header );
|
||||
|
||||
/*
|
||||
* Hack: Old code was setting Channels = 0 before synth_output. This caused
|
||||
* the first synthed frame to not be written to the output buffer, offsetting
|
||||
* the whole song by a buffer. On one test song, it was 1152/44100, or 26ms.
|
||||
* This affects all MP3s. We can't leave the bug in, since we need to handle
|
||||
* seeks properly, too. So, let's make the offset to fix seeks available.
|
||||
*
|
||||
* This is negative: if we have 26ms of extra data, then song offsets are
|
||||
* fixed by subtracting 26ms.
|
||||
*/
|
||||
|
||||
this->OffsetFix = - (float) mad->Synth.pcm.length / mad->Frame.header.samplerate;
|
||||
|
||||
if(mad->length == -1)
|
||||
{
|
||||
|
||||
@@ -11,6 +11,7 @@ class RageSoundReader_MP3: public SoundReader_FileReader
|
||||
public:
|
||||
int SampleRate;
|
||||
int Channels;
|
||||
float OffsetFix;
|
||||
|
||||
CString filename;
|
||||
FILE *rw;
|
||||
@@ -40,6 +41,8 @@ public:
|
||||
int SetPosition_Fast(int ms);
|
||||
int Read(char *buf, unsigned len);
|
||||
int GetSampleRate() const { return SampleRate; }
|
||||
float GetOffsetFix() const { return OffsetFix; }
|
||||
|
||||
RageSoundReader_MP3();
|
||||
~RageSoundReader_MP3();
|
||||
RageSoundReader_MP3( const RageSoundReader_MP3 & ); /* not defined; don't use */
|
||||
|
||||
@@ -17,6 +17,7 @@ bool SoundReader_Preload::Open(SoundReader *source)
|
||||
{
|
||||
ASSERT(source);
|
||||
samplerate = source->GetSampleRate();
|
||||
OffsetFix = source->GetOffsetFix(); // propagate upwards
|
||||
|
||||
/* Check the length, and see if we think it'll fit in the buffer. */
|
||||
int len = source->GetLength_Fast();
|
||||
|
||||
@@ -30,6 +30,7 @@ class SoundReader_Preload: public SoundReader {
|
||||
int total_samples() const;
|
||||
|
||||
int samplerate;
|
||||
float OffsetFix;
|
||||
|
||||
public:
|
||||
/* Return true if the sound has been preloaded, in which case source will
|
||||
@@ -41,6 +42,7 @@ public:
|
||||
int SetPosition_Fast(int ms);
|
||||
int Read(char *buf, unsigned len);
|
||||
int GetSampleRate() const { return samplerate; }
|
||||
float GetOffsetFix() const { return OffsetFix; }
|
||||
|
||||
SoundReader *Copy() const;
|
||||
~SoundReader_Preload() { }
|
||||
|
||||
@@ -27,6 +27,7 @@ public:
|
||||
RageSoundReader_Resample_Fast();
|
||||
virtual ~RageSoundReader_Resample_Fast();
|
||||
SoundReader *Copy() const;
|
||||
float GetOffsetFix() const { return source->GetOffsetFix(); }
|
||||
|
||||
/* Change the actual sample rate of a sound. */
|
||||
void SetSampleRate(int hz);
|
||||
|
||||
@@ -35,6 +35,7 @@ public:
|
||||
RageSoundReader_Resample_Good();
|
||||
virtual ~RageSoundReader_Resample_Good();
|
||||
SoundReader *Copy() const;
|
||||
float GetOffsetFix() const { return source->GetOffsetFix(); }
|
||||
|
||||
/* Change the actual sample rate of a sound. */
|
||||
void SetSampleRate( int hz );
|
||||
|
||||
Reference in New Issue
Block a user