From 1bd5513698757476ae42abe27cb3717c43040fd8 Mon Sep 17 00:00:00 2001 From: Glenn Maynard Date: Sat, 27 Jan 2007 07:14:58 +0000 Subject: [PATCH] Switch to floating-point sound internally. This allows us to change the volume of sounds in filters ("volume", "fade" properties) without quantizing the audio prematurely. Previously, we had a hack to apply volume changes as a mixing-time step. This can be done at any point in the filter chain now. This also means we only need to worry about clipping at the very last mixing step, instead of at every place we change sound. Dithering for 16-bit audio and more intelligent gain control is possible, as we have full-resolution, unclipped sound at the mixing phase. We support high resolution source sounds; both Vorbis and MAD supply more than 16 bits. Several filters, such as resampling, are easier to implement as floats; these no longer need to convert back and forth. Negatives: - More memory use. The main case of this is in RageSoundReader_Preload, which will be fixed: we can preload in 16-bit without losing most of the above. - Some extra overhead for accessing more memory. --- stepmania/src/RageSoundMixBuffer.cpp | 33 +++++------ stepmania/src/RageSoundMixBuffer.h | 7 +-- stepmania/src/RageSoundReader.cpp | 2 +- stepmania/src/RageSoundReader.h | 4 +- stepmania/src/RageSoundReader_Chain.cpp | 6 +- stepmania/src/RageSoundReader_Chain.h | 2 +- .../src/RageSoundReader_ChannelSplit.cpp | 6 +- stepmania/src/RageSoundReader_ChannelSplit.h | 2 +- stepmania/src/RageSoundReader_Extend.cpp | 8 +-- stepmania/src/RageSoundReader_Extend.h | 4 +- stepmania/src/RageSoundReader_Filter.h | 2 +- stepmania/src/RageSoundReader_MP3.cpp | 33 +++++------ stepmania/src/RageSoundReader_MP3.h | 2 +- stepmania/src/RageSoundReader_Pan.cpp | 2 +- stepmania/src/RageSoundReader_Pan.h | 2 +- stepmania/src/RageSoundReader_PitchChange.cpp | 2 +- stepmania/src/RageSoundReader_PitchChange.h | 2 +- .../src/RageSoundReader_PostBuffering.cpp | 2 +- stepmania/src/RageSoundReader_PostBuffering.h | 2 +- stepmania/src/RageSoundReader_Preload.cpp | 6 +- stepmania/src/RageSoundReader_Preload.h | 2 +- .../src/RageSoundReader_Resample_Good.cpp | 10 ++-- stepmania/src/RageSoundReader_Resample_Good.h | 2 +- stepmania/src/RageSoundReader_SpeedChange.cpp | 34 +++++------ stepmania/src/RageSoundReader_SpeedChange.h | 4 +- .../src/RageSoundReader_ThreadedBuffer.cpp | 6 +- .../src/RageSoundReader_ThreadedBuffer.h | 4 +- stepmania/src/RageSoundReader_Vorbisfile.cpp | 53 +++++++++++++---- stepmania/src/RageSoundReader_Vorbisfile.h | 2 +- stepmania/src/RageSoundReader_WAV.cpp | 59 +++++++++++-------- stepmania/src/RageSoundReader_WAV.h | 2 +- stepmania/src/RageSoundUtil.cpp | 20 +++---- stepmania/src/RageSoundUtil.h | 8 +-- 33 files changed, 185 insertions(+), 150 deletions(-) diff --git a/stepmania/src/RageSoundMixBuffer.cpp b/stepmania/src/RageSoundMixBuffer.cpp index 2d4e876632..21deadc106 100644 --- a/stepmania/src/RageSoundMixBuffer.cpp +++ b/stepmania/src/RageSoundMixBuffer.cpp @@ -14,7 +14,6 @@ RageSoundMixBuffer::RageSoundMixBuffer() m_iBufSize = m_iBufUsed = 0; m_pMixbuf = NULL; m_iOffset = 0; - SetVolume( 1.0f ); #ifdef USE_VEC g_bVector = Vector::CheckForVector(); #endif @@ -25,11 +24,6 @@ RageSoundMixBuffer::~RageSoundMixBuffer() free( m_pMixbuf ); } -void RageSoundMixBuffer::SetVolume( float f ) -{ - m_iVolumeFactor = int(256*f); -} - /* write() will start mixing iOffset samples into the buffer. Be careful; this is * measured in samples, not frames, so if the data is stereo, multiply by two. */ void RageSoundMixBuffer::SetWriteOffset( int iOffset ) @@ -42,18 +36,18 @@ void RageSoundMixBuffer::Extend( unsigned iSamples ) const unsigned realsize = iSamples+m_iOffset; if( m_iBufSize < realsize ) { - m_pMixbuf = (int32_t *) realloc( m_pMixbuf, sizeof(int32_t) * realsize ); + m_pMixbuf = (float *) realloc( m_pMixbuf, sizeof(float) * realsize ); m_iBufSize = realsize; } if( m_iBufUsed < realsize ) { - memset( m_pMixbuf + m_iBufUsed, 0, (realsize - m_iBufUsed) * sizeof(int32_t) ); + memset( m_pMixbuf + m_iBufUsed, 0, (realsize - m_iBufUsed) * sizeof(float) ); m_iBufUsed = realsize; } } -void RageSoundMixBuffer::write( const int16_t *pBuf, unsigned iSize, int iSourceStride, int iDestStride ) +void RageSoundMixBuffer::write( const float *pBuf, unsigned iSize, int iSourceStride, int iDestStride ) { if( iSize == 0 ) return; @@ -63,17 +57,19 @@ void RageSoundMixBuffer::write( const int16_t *pBuf, unsigned iSize, int iSource Extend( iSize * iDestStride - (iDestStride-1) ); /* Scale volume and add. */ - int32_t *pDestBuf = m_pMixbuf+m_iOffset; -#ifdef USE_VEC + float *pDestBuf = m_pMixbuf+m_iOffset; + +/* #ifdef USE_VEC if( g_bVector && iSourceStride == 1 && iDestStride == 1 ) { - Vector::FastSoundWrite( pDestBuf, pBuf, iSize, m_iVolumeFactor ); + Vector::FastSoundWrite( pDestBuf, pBuf, iSize, 1 ); return; } -#endif +#endif */ + while( iSize ) { - *pDestBuf += *pBuf * m_iVolumeFactor; + *pDestBuf += *pBuf; pBuf += iSourceStride; pDestBuf += iDestStride; --iSize; @@ -92,8 +88,9 @@ void RageSoundMixBuffer::read( int16_t *pBuf ) #endif for( unsigned iPos = 0; iPos < m_iBufUsed; ++iPos ) { - int32_t iOut = (m_pMixbuf[iPos]) / 256; - pBuf[iPos] = (int16_t) clamp( iOut, -32768, 32767 ); + float iOut = m_pMixbuf[iPos]; + iOut = clamp( iOut, -1.0f, +1.0f ); + pBuf[iPos] = lrintf(iOut * 32767); } m_iBufUsed = 0; } @@ -108,11 +105,9 @@ void RageSoundMixBuffer::read( float *pBuf ) return; } #endif - const int iMinimum = -32768 * 256; - const int iMaximum = 32767 * 256; for( unsigned pos = 0; pos < m_iBufUsed; ++pos ) - pBuf[pos] = SCALE( (float)m_pMixbuf[pos], iMinimum, iMaximum, -1.0f, 1.0f ); + pBuf[pos] = m_pMixbuf[pos]; m_iBufUsed = 0; } diff --git a/stepmania/src/RageSoundMixBuffer.h b/stepmania/src/RageSoundMixBuffer.h index 95f77b2144..5a8c40ca02 100644 --- a/stepmania/src/RageSoundMixBuffer.h +++ b/stepmania/src/RageSoundMixBuffer.h @@ -10,22 +10,21 @@ public: ~RageSoundMixBuffer(); /* Mix the given buffer of samples. */ - void write( const int16_t *buf, unsigned size, int iSourceStride = 1, int iDestStride = 1 ); + void write( const float *pBuf, unsigned iSize, int iSourceStride = 1, int iDestStride = 1 ); /* Extend the buffer as if write() was called with a buffer of silence. */ void Extend( unsigned iSamples ); void read( int16_t *pBuf ); void read( float *pBuf ); + float *read() { return m_pMixbuf; } unsigned size() const { return m_iBufUsed; } - void SetVolume( float f ); void SetWriteOffset( int iOffset ); private: - int32_t *m_pMixbuf; + float *m_pMixbuf; unsigned m_iBufSize; /* actual allocated samples */ unsigned m_iBufUsed; /* used samples */ - int m_iVolumeFactor; /* vol * 256 */ int m_iOffset; }; diff --git a/stepmania/src/RageSoundReader.cpp b/stepmania/src/RageSoundReader.cpp index 69f46a1c05..1e3f983dc9 100644 --- a/stepmania/src/RageSoundReader.cpp +++ b/stepmania/src/RageSoundReader.cpp @@ -6,7 +6,7 @@ REGISTER_CLASS_TRAITS( RageSoundReader, pCopy->Copy() ); /* Read(), handling the STREAM_LOOPED and empty return cases. */ -int RageSoundReader::RetriedRead( int16_t *pBuffer, int iFrames, int *iSourceFrame, float *fRate ) +int RageSoundReader::RetriedRead( float *pBuffer, int iFrames, int *iSourceFrame, float *fRate ) { if( iFrames == 0 ) return 0; diff --git a/stepmania/src/RageSoundReader.h b/stepmania/src/RageSoundReader.h index d762ed2bf6..29e8186a73 100644 --- a/stepmania/src/RageSoundReader.h +++ b/stepmania/src/RageSoundReader.h @@ -9,7 +9,7 @@ public: virtual int GetLength() const = 0; /* ms */ virtual int GetLength_Fast() const { return GetLength(); } /* ms */ virtual int SetPosition( int iSample ) = 0; - virtual int Read( int16_t *pBuf, int iFrames ) = 0; + virtual int Read( float *pBuf, int iFrames ) = 0; virtual ~RageSoundReader() { } virtual RageSoundReader *Copy() const = 0; virtual int GetSampleRate() const = 0; @@ -40,7 +40,7 @@ public: virtual float GetStreamToSourceRatio() const = 0; virtual RString GetError() const = 0; - int RetriedRead( int16_t *pBuffer, int iFrames, int *iSourceFrame = NULL, float *fRate = NULL ); + int RetriedRead( float *pBuffer, int iFrames, int *iSourceFrame = NULL, float *fRate = NULL ); }; #endif diff --git a/stepmania/src/RageSoundReader_Chain.cpp b/stepmania/src/RageSoundReader_Chain.cpp index d996c40f5d..4d3c32dc89 100644 --- a/stepmania/src/RageSoundReader_Chain.cpp +++ b/stepmania/src/RageSoundReader_Chain.cpp @@ -299,7 +299,7 @@ float RageSoundReader_Chain::GetStreamToSourceRatio() const /* As we iterate through the sound tree, we'll find that we need data from different * sounds; a sound may be needed by more than one other sound. */ -int RageSoundReader_Chain::Read( int16_t *pBuffer, int iFrames ) +int RageSoundReader_Chain::Read( float *pBuffer, int iFrames ) { while( m_iNextSound < m_aSounds.size() && m_iCurrentFrame == m_aSounds[m_iNextSound].GetOffsetFrame(m_iActualSampleRate) ) { @@ -339,14 +339,14 @@ int RageSoundReader_Chain::Read( int16_t *pBuffer, int iFrames ) { /* If we have more sounds ahead of us, pretend we read the entire block, since * there's silence in between. Otherwise, we're at EOF. */ - memset( pBuffer, 0, iFrames * m_iChannels * sizeof(int16_t) ); + memset( pBuffer, 0, iFrames * m_iChannels * sizeof(float) ); m_iCurrentFrame += iFrames; return iFrames; } RageSoundMixBuffer mix; /* Read iFrames from each sound. */ - int16_t Buffer[2048]; + float Buffer[2048]; iFrames = min( iFrames, (int) (ARRAYLEN(Buffer) / m_iChannels) ); for( unsigned i = 0; i < m_apActiveSounds.size(); ) { diff --git a/stepmania/src/RageSoundReader_Chain.h b/stepmania/src/RageSoundReader_Chain.h index 2effc43e0e..f70127681d 100644 --- a/stepmania/src/RageSoundReader_Chain.h +++ b/stepmania/src/RageSoundReader_Chain.h @@ -34,7 +34,7 @@ public: int GetLength() const; int GetLength_Fast() const; int SetPosition( int iFrame ); - int Read( int16_t *pBuf, int iFrames ); + int Read( float *pBuf, int iFrames ); int GetSampleRate() const { return m_iActualSampleRate; } unsigned GetNumChannels() const { return m_iChannels; } bool SetProperty( const RString &sProperty, float fValue ); diff --git a/stepmania/src/RageSoundReader_ChannelSplit.cpp b/stepmania/src/RageSoundReader_ChannelSplit.cpp index fba0e63980..b8cffee22e 100644 --- a/stepmania/src/RageSoundReader_ChannelSplit.cpp +++ b/stepmania/src/RageSoundReader_ChannelSplit.cpp @@ -77,7 +77,7 @@ public: /* m_sBuffer[0] corresponds to frame number m_iBufferPositionFrames. */ int m_iBufferPositionFrames; - vector m_sBuffer; + vector m_sBuffer; }; int RageSoundReader_Split::GetLength() const { return m_pImpl->m_pSource->GetLength(); } @@ -132,13 +132,13 @@ bool RageSoundReader_Split::SetProperty( const RString &sProperty, float fValue return m_pImpl->m_pSource->SetProperty( sProperty, fValue ); } -int RageSoundReader_Split::Read( int16_t *pBuf, int iFrames ) +int RageSoundReader_Split::Read( float *pBuf, int iFrames ) { m_iRequestFrames = iFrames; int iRet = m_pImpl->ReadBuffer(); int iSamplesAvailable = m_pImpl->m_sBuffer.size(); - const int16_t *pSrc = &m_pImpl->m_sBuffer[0]; + const float *pSrc = &m_pImpl->m_sBuffer[0]; if( m_pImpl->m_iBufferPositionFrames < m_iPositionFrame ) { int iSkipFrames = m_iPositionFrame - m_pImpl->m_iBufferPositionFrames; diff --git a/stepmania/src/RageSoundReader_ChannelSplit.h b/stepmania/src/RageSoundReader_ChannelSplit.h index f130974846..e6cb9859ad 100644 --- a/stepmania/src/RageSoundReader_ChannelSplit.h +++ b/stepmania/src/RageSoundReader_ChannelSplit.h @@ -17,7 +17,7 @@ public: virtual int GetLength() const; virtual int GetLength_Fast() const; virtual int SetPosition( int iFrame ); - virtual int Read( int16_t *pBuf, int iFrames ); + virtual int Read( float *pBuf, int iFrames ); virtual int GetSampleRate() const; virtual unsigned GetNumChannels() const; virtual bool SetProperty( const RString &sProperty, float fValue ); diff --git a/stepmania/src/RageSoundReader_Extend.cpp b/stepmania/src/RageSoundReader_Extend.cpp index 05557525a2..31d88d8506 100644 --- a/stepmania/src/RageSoundReader_Extend.cpp +++ b/stepmania/src/RageSoundReader_Extend.cpp @@ -48,7 +48,7 @@ int RageSoundReader_Extend::GetEndFrame() const return m_iStartFrames + m_iLengthFrames; } -int RageSoundReader_Extend::GetData( int16_t *pBuffer, int iFrames ) +int RageSoundReader_Extend::GetData( float *pBuffer, int iFrames ) { int iFramesToRead = iFrames; if( m_iLengthFrames != -1 ) @@ -66,7 +66,7 @@ int RageSoundReader_Extend::GetData( int16_t *pBuffer, int iFrames ) iFramesToRead = min( iFramesToRead, -m_iPositionFrames ); m_iPositionFrames += iFramesToRead; - memset( pBuffer, 0, iFramesToRead * sizeof(int16_t) * this->GetNumChannels() ); + memset( pBuffer, 0, iFramesToRead * sizeof(float) * this->GetNumChannels() ); return iFramesToRead; } @@ -80,7 +80,7 @@ int RageSoundReader_Extend::GetData( int16_t *pBuffer, int iFrames ) return iRet; } -int RageSoundReader_Extend::Read( int16_t *pBuffer, int iFrames ) +int RageSoundReader_Extend::Read( float *pBuffer, int iFrames ) { int iFramesRead = GetData( pBuffer, iFrames ); if( iFramesRead == RageSoundReader::END_OF_FILE ) @@ -91,7 +91,7 @@ int RageSoundReader_Extend::Read( int16_t *pBuffer, int iFrames ) iFramesRead = iFrames; if( m_StopMode != M_CONTINUE ) iFramesRead = min( GetEndFrame() - m_iPositionFrames, iFramesRead ); - memset( pBuffer, 0, iFramesRead * sizeof(int16_t) * this->GetNumChannels() ); + memset( pBuffer, 0, iFramesRead * sizeof(float) * this->GetNumChannels() ); } } diff --git a/stepmania/src/RageSoundReader_Extend.h b/stepmania/src/RageSoundReader_Extend.h index 99f9859669..5b3bb74af2 100644 --- a/stepmania/src/RageSoundReader_Extend.h +++ b/stepmania/src/RageSoundReader_Extend.h @@ -10,7 +10,7 @@ class RageSoundReader_Extend: public RageSoundReader_Filter public: RageSoundReader_Extend( RageSoundReader *pSource ); virtual int SetPosition( int iFrame ); - virtual int Read( int16_t *pBuffer, int iFrames ); + virtual int Read( float *pBuffer, int iFrames ); virtual int GetNextSourceFrame() const; virtual bool SetProperty( const RString &sProperty, float fValue ); @@ -19,7 +19,7 @@ public: private: int GetEndFrame() const; - int GetData( int16_t *pBuffer, int iFrames ); + int GetData( float *pBuffer, int iFrames ); int m_iPositionFrames; diff --git a/stepmania/src/RageSoundReader_Filter.h b/stepmania/src/RageSoundReader_Filter.h index 79c1d524d7..c53a4e4f30 100644 --- a/stepmania/src/RageSoundReader_Filter.h +++ b/stepmania/src/RageSoundReader_Filter.h @@ -16,7 +16,7 @@ public: virtual int GetLength() const { return m_pSource->GetLength(); } virtual int GetLength_Fast() const { return m_pSource->GetLength_Fast(); } virtual int SetPosition( int iFrame ) { return m_pSource->SetPosition( iFrame ); } - virtual int Read( int16_t *pBuf, int iFrames ) { return m_pSource->Read( pBuf, iFrames ); } + virtual int Read( float *pBuf, int iFrames ) { return m_pSource->Read( pBuf, iFrames ); } virtual int GetSampleRate() const { return m_pSource->GetSampleRate(); } virtual unsigned GetNumChannels() const { return m_pSource->GetNumChannels(); } virtual bool SetProperty( const RString &sProperty, float fValue ) { return m_pSource->SetProperty( sProperty, fValue ); } diff --git a/stepmania/src/RageSoundReader_MP3.cpp b/stepmania/src/RageSoundReader_MP3.cpp index ec353f1b42..322a6962c8 100644 --- a/stepmania/src/RageSoundReader_MP3.cpp +++ b/stepmania/src/RageSoundReader_MP3.cpp @@ -204,7 +204,8 @@ struct madlib_t bitrate = 0; } - uint8_t inbuf[16384], outbuf[8192]; + uint8_t inbuf[16384]; + float outbuf[8192]; int outpos; unsigned outleft; @@ -268,7 +269,7 @@ struct madlib_t -static signed int scale(mad_fixed_t sample) +static float scale(mad_fixed_t sample) { /* round */ sample += (1L << (MAD_F_FRACBITS - 16)); @@ -279,8 +280,7 @@ static signed int scale(mad_fixed_t sample) else if (sample < -MAD_F_ONE) sample = -MAD_F_ONE; - /* quantize */ - return sample >> (MAD_F_FRACBITS + 1 - 16); + return (double) sample / (1<Channels; ++chan) { - short Sample = (short) scale(mad->Synth.pcm.samples[chan][i]); - *((short *) (mad->outbuf + mad->outleft)) = Sample; - mad->outleft += 2; + float Sample = scale(mad->Synth.pcm.samples[chan][i]); + mad->outbuf[mad->outleft] = Sample; + ++mad->outleft; } } } @@ -743,7 +743,7 @@ static void mono_to_stereo( char *dst, const char *src, unsigned len ) } } -int RageSoundReader_MP3::Read( int16_t *buf, int iFrames ) +int RageSoundReader_MP3::Read( float *buf, int iFrames ) { int iFramesWritten = 0; @@ -751,17 +751,17 @@ int RageSoundReader_MP3::Read( int16_t *buf, int iFrames ) { if( mad->outleft > 0 ) { - int iFramesToCopy = min( iFrames, int(mad->outleft / (sizeof(int16_t) * GetNumChannels())) ); + int iFramesToCopy = min( iFrames, int(mad->outleft / GetNumChannels()) ); const int iSamplesToCopy = iFramesToCopy * GetNumChannels(); - const int iBytesToCopy = iSamplesToCopy * sizeof(int16_t); + const int iBytesToCopy = iSamplesToCopy * sizeof(float); memcpy( buf, mad->outbuf + mad->outpos, iBytesToCopy ); buf += iSamplesToCopy; iFrames -= iFramesToCopy; iFramesWritten += iFramesToCopy; - mad->outpos += iBytesToCopy; - mad->outleft -= iBytesToCopy; + mad->outpos += iSamplesToCopy; + mad->outleft -= iSamplesToCopy; continue; } @@ -936,10 +936,9 @@ int RageSoundReader_MP3::SetPosition_hard( int iFrame ) int samples = mad_timer_count( skip, (mad_units) SampleRate ); - /* Skip 'samples' samples; each sample is 2 * channels bytes, since - * we're currently always using AUDIO_S16SYS. */ - mad->outpos = samples * 2 * this->Channels; - mad->outleft -= samples * 2 * this->Channels; + /* Skip 'samples' samples. */ + mad->outpos = samples * this->Channels; + mad->outleft -= samples * this->Channels; return 1; } @@ -1052,7 +1051,7 @@ bool RageSoundReader_MP3::SetProperty( const RString &sProperty, float fValue ) int RageSoundReader_MP3::GetNextSourceFrame() const { int iFrame = mad_timer_count( mad->Timer, mad_units(mad->Frame.header.samplerate) ); - iFrame += mad->outpos / (sizeof(int16_t) * this->Channels); + iFrame += mad->outpos / this->Channels; return iFrame; } diff --git a/stepmania/src/RageSoundReader_MP3.h b/stepmania/src/RageSoundReader_MP3.h index 3ff04031ac..42b737a1e8 100644 --- a/stepmania/src/RageSoundReader_MP3.h +++ b/stepmania/src/RageSoundReader_MP3.h @@ -16,7 +16,7 @@ public: int GetLength() const { return GetLengthConst(false); } int GetLength_Fast() const { return GetLengthConst(true); } int SetPosition( int iSample ); - int Read( int16_t *pBuf, int iFrames ); + int Read( float *pBuf, int iFrames ); unsigned GetNumChannels() const { return Channels; } int GetSampleRate() const { return SampleRate; } int GetNextSourceFrame() const; diff --git a/stepmania/src/RageSoundReader_Pan.cpp b/stepmania/src/RageSoundReader_Pan.cpp index 2f29f48b5b..ee592c2fff 100644 --- a/stepmania/src/RageSoundReader_Pan.cpp +++ b/stepmania/src/RageSoundReader_Pan.cpp @@ -9,7 +9,7 @@ RageSoundReader_Pan::RageSoundReader_Pan( RageSoundReader *pSource ): } -int RageSoundReader_Pan::Read( int16_t *pBuf, int iFrames ) +int RageSoundReader_Pan::Read( float *pBuf, int iFrames ) { iFrames = m_pSource->Read( pBuf, iFrames ); if( iFrames < 0 ) diff --git a/stepmania/src/RageSoundReader_Pan.h b/stepmania/src/RageSoundReader_Pan.h index 98db8d0209..930d38cf59 100644 --- a/stepmania/src/RageSoundReader_Pan.h +++ b/stepmania/src/RageSoundReader_Pan.h @@ -11,7 +11,7 @@ public: RageSoundReader_Pan( RageSoundReader *pSource ); RageSoundReader_Pan *Copy() const { return new RageSoundReader_Pan(*this); } virtual unsigned GetNumChannels() const; - virtual int Read( int16_t *pBuf, int iFrames ); + virtual int Read( float *pBuf, int iFrames ); virtual bool SetProperty( const RString &sProperty, float fValue ); private: diff --git a/stepmania/src/RageSoundReader_PitchChange.cpp b/stepmania/src/RageSoundReader_PitchChange.cpp index 45487a897f..9d54e0e214 100644 --- a/stepmania/src/RageSoundReader_PitchChange.cpp +++ b/stepmania/src/RageSoundReader_PitchChange.cpp @@ -40,7 +40,7 @@ RageSoundReader_PitchChange::RageSoundReader_PitchChange( const RageSoundReader_ m_fLastSetPitchRatio = cpy.m_fLastSetPitchRatio; } -int RageSoundReader_PitchChange::Read( int16_t *pBuf, int iFrames ) +int RageSoundReader_PitchChange::Read( float *pBuf, int iFrames ) { /* m_pSpeedChange->NextReadWillStep is true if speed changes will be applied * immediately on the next Read(). When this is true, apply the ratio to the diff --git a/stepmania/src/RageSoundReader_PitchChange.h b/stepmania/src/RageSoundReader_PitchChange.h index 39ee607381..9f28c87f35 100644 --- a/stepmania/src/RageSoundReader_PitchChange.h +++ b/stepmania/src/RageSoundReader_PitchChange.h @@ -13,7 +13,7 @@ public: RageSoundReader_PitchChange( RageSoundReader *pSource ); RageSoundReader_PitchChange( const RageSoundReader_PitchChange &cpy ); - virtual int Read( int16_t *pBuf, int iFrames ); + virtual int Read( float *pBuf, int iFrames ); virtual bool SetProperty( const RString &sProperty, float fValue ); void SetSpeedRatio( float fRatio ) { m_fSpeedRatio = fRatio; } diff --git a/stepmania/src/RageSoundReader_PostBuffering.cpp b/stepmania/src/RageSoundReader_PostBuffering.cpp index 9ca5f22a88..a93da53e20 100644 --- a/stepmania/src/RageSoundReader_PostBuffering.cpp +++ b/stepmania/src/RageSoundReader_PostBuffering.cpp @@ -15,7 +15,7 @@ RageSoundReader_PostBuffering::RageSoundReader_PostBuffering( RageSoundReader *p } -int RageSoundReader_PostBuffering::Read( int16_t *pBuf, int iFrames ) +int RageSoundReader_PostBuffering::Read( float *pBuf, int iFrames ) { iFrames = m_pSource->Read( pBuf, iFrames ); if( iFrames < 0 ) diff --git a/stepmania/src/RageSoundReader_PostBuffering.h b/stepmania/src/RageSoundReader_PostBuffering.h index 9bf6aa5a81..28668256c4 100644 --- a/stepmania/src/RageSoundReader_PostBuffering.h +++ b/stepmania/src/RageSoundReader_PostBuffering.h @@ -10,7 +10,7 @@ class RageSoundReader_PostBuffering: public RageSoundReader_Filter public: RageSoundReader_PostBuffering( RageSoundReader *pSource ); RageSoundReader_PostBuffering *Copy() const { return new RageSoundReader_PostBuffering(*this); } - virtual int Read( int16_t *pBuf, int iFrames ); + virtual int Read( float *pBuf, int iFrames ); virtual bool SetProperty( const RString &sProperty, float fValue ); private: diff --git a/stepmania/src/RageSoundReader_Preload.cpp b/stepmania/src/RageSoundReader_Preload.cpp index eea082ff05..6ddd1adfe4 100644 --- a/stepmania/src/RageSoundReader_Preload.cpp +++ b/stepmania/src/RageSoundReader_Preload.cpp @@ -5,7 +5,7 @@ #include "RageSoundReader_Preload.h" #include "RageUtil.h" -#define samplesize (sizeof(int16_t) * m_iChannels) /* 16-bit */ +#define samplesize (sizeof(float) * m_iChannels) /* 16-bit */ /* If a sound is smaller than this, we'll load it entirely into memory. */ const unsigned max_prebuf_size = 1024*256; @@ -61,7 +61,7 @@ bool RageSoundReader_Preload::Open( RageSoundReader *pSource ) if( pSource->GetStreamToSourceRatio() != m_fRate ) return false; /* Don't bother trying to preload it. */ - int16_t buffer[1024]; + float buffer[1024]; int iCnt = pSource->Read( buffer, ARRAYSIZE(buffer) / m_iChannels ); if( iCnt == END_OF_FILE ) @@ -110,7 +110,7 @@ int RageSoundReader_Preload::GetNextSourceFrame() const return lrintf(m_iPosition * m_fRate); } -int RageSoundReader_Preload::Read( int16_t *pBuffer, int iFrames ) +int RageSoundReader_Preload::Read( float *pBuffer, int iFrames ) { const int iSizeFrames = m_Buffer->size() / samplesize; const int iFramesAvail = iSizeFrames - m_iPosition; diff --git a/stepmania/src/RageSoundReader_Preload.h b/stepmania/src/RageSoundReader_Preload.h index c918601643..6cada40ab4 100644 --- a/stepmania/src/RageSoundReader_Preload.h +++ b/stepmania/src/RageSoundReader_Preload.h @@ -16,7 +16,7 @@ public: int GetLength() const; int GetLength_Fast() const; int SetPosition( int iFrame ); - int Read( int16_t *pBuffer, int iLength ); + int Read( float *pBuffer, int iLength ); int GetSampleRate() const { return m_iSampleRate; } unsigned GetNumChannels() const { return m_iChannels; } int GetNextSourceFrame() const; diff --git a/stepmania/src/RageSoundReader_Resample_Good.cpp b/stepmania/src/RageSoundReader_Resample_Good.cpp index d07087c534..4ad0e77bb3 100644 --- a/stepmania/src/RageSoundReader_Resample_Good.cpp +++ b/stepmania/src/RageSoundReader_Resample_Good.cpp @@ -647,7 +647,7 @@ int RageSoundReader_Resample_Good::SetPosition( int iFrame ) return m_pSource->SetPosition( iFrame ); } -int RageSoundReader_Resample_Good::Read( int16_t *pBuf, int iFrames ) +int RageSoundReader_Resample_Good::Read( float *pBuf, int iFrames ) { int iChannels = m_apResamplers.size(); @@ -663,7 +663,7 @@ int RageSoundReader_Resample_Good::Read( int16_t *pBuf, int iFrames ) { int iFramesNeeded = m_apResamplers[0]->NumInputsForOutputSamples(iFrames); - int16_t *pTmpBuf = (int16_t *) alloca( iFramesNeeded * sizeof(int16_t) * iChannels ); + float *pTmpBuf = (float *) alloca( iFramesNeeded * sizeof(float) * iChannels ); ASSERT( pTmpBuf ); int iFramesIn = m_pSource->Read( pTmpBuf, iFramesNeeded ); if( iFramesIn < 0 ) @@ -676,7 +676,7 @@ int RageSoundReader_Resample_Good::Read( int16_t *pBuf, int iFrames ) for( int iChannel = 0; iChannel < iChannels; ++iChannel ) { { - int16_t *pBufIn = pTmpBuf + iChannel; + float *pBufIn = pTmpBuf + iChannel; float *pBufOut = pFloatBuf; for( int i = 0; i < iSamplesIn; i += iChannels ) *(pBufOut++) = (float) pBufIn[i]; @@ -685,10 +685,10 @@ int RageSoundReader_Resample_Good::Read( int16_t *pBuf, int iFrames ) int iGotFrames = m_apResamplers[iChannel]->Run( pFloatBuf, iFramesIn, pFloatOut, iFrames ); ASSERT( iGotFrames <= iFrames ); - int16_t *pBufOut = pBuf + iChannel; + float *pBufOut = pBuf + iChannel; for( int i = 0; i < iGotFrames; ++i ) { - *pBufOut = int16_t(lrintf(clamp(pFloatOut[i], -32768, 32767))); + *pBufOut = pFloatOut[i]; pBufOut += iChannels; } if( iChannel == 0 ) diff --git a/stepmania/src/RageSoundReader_Resample_Good.h b/stepmania/src/RageSoundReader_Resample_Good.h index 9dfe4c1a39..cda94e9fb2 100644 --- a/stepmania/src/RageSoundReader_Resample_Good.h +++ b/stepmania/src/RageSoundReader_Resample_Good.h @@ -15,7 +15,7 @@ public: RageSoundReader_Resample_Good( RageSoundReader *pSource, int iSampleRate ); RageSoundReader_Resample_Good( const RageSoundReader_Resample_Good &cpy ); int SetPosition( int iFrame ); - int Read( int16_t *pBuf, int iFrames ); + int Read( float *pBuf, int iFrames ); virtual ~RageSoundReader_Resample_Good(); RageSoundReader_Resample_Good *Copy() const; bool SetProperty( const RString &sProperty, float fValue ); diff --git a/stepmania/src/RageSoundReader_SpeedChange.cpp b/stepmania/src/RageSoundReader_SpeedChange.cpp index 2081155d26..604fe71343 100644 --- a/stepmania/src/RageSoundReader_SpeedChange.cpp +++ b/stepmania/src/RageSoundReader_SpeedChange.cpp @@ -44,7 +44,7 @@ void RageSoundReader_SpeedChange::Reset() m_fErrorFrames = 0; } -static int FindClosestMatch( const int16_t *pBuffer, int iBufferSize, const int16_t *pCorrelateBuffer, int iCorrelateBufferSize, int iStride ) +static int FindClosestMatch( const float *pBuffer, int iBufferSize, const float *pCorrelateBuffer, int iCorrelateBufferSize, int iStride ) { if( iBufferSize <= iCorrelateBufferSize ) return 0; @@ -55,20 +55,20 @@ static int FindClosestMatch( const int16_t *pBuffer, int iBufferSize, const int1 int iBufferDistanceToSearch = iBufferSize - iCorrelateBufferSize; int iBestOffset = 0; - int iBestScore = 0; + int fBestScore = 0; for( int i = 0; i < iBufferDistanceToSearch; i += iStride ) { - int iScore = 0; - const int16_t *pFrames = pBuffer + i; + float fScore = 0; + const float *pFrames = pBuffer + i; for( int j = 0; j < iCorrelateBufferSize; j += iStride ) { - int iDiff = pFrames[j] - pCorrelateBuffer[j]; - iScore += abs(iDiff); + float fDiff = pFrames[j] - pCorrelateBuffer[j]; + fScore += fabsf(fDiff); } - if( i == 0 || iScore < iBestScore ) + if( i == 0 || fScore < fBestScore ) { - iBestScore = iScore; + fBestScore = fScore; iBestOffset = i; } } @@ -85,11 +85,11 @@ int RageSoundReader_SpeedChange::FillData( int iMaxFrames ) while( iMaxFrames > 0 ) { int iFramesToRead = iMaxFrames - m_iDataBufferAvailFrames; - int iBytesToRead = iFramesToRead * m_Channels.size() * sizeof(int16_t); + int iBytesToRead = iFramesToRead * m_Channels.size() * sizeof(float); if( iBytesToRead <= 0 ) return m_iDataBufferAvailFrames; - int16_t *pTempBuffer = (int16_t *) alloca( iBytesToRead ); + float *pTempBuffer = (float *) alloca( iBytesToRead ); int iGotFrames = m_pSource->Read( pTempBuffer, iFramesToRead ); if( iGotFrames < 0 ) { @@ -105,8 +105,8 @@ int RageSoundReader_SpeedChange::FillData( int iMaxFrames ) if( (int) c.m_DataBuffer.size() < iMaxFrames ) c.m_DataBuffer.resize( iMaxFrames ); - const int16_t *pIn = pTempBuffer + i; - int16_t *pOut = &c.m_DataBuffer[m_iDataBufferAvailFrames]; + const float *pIn = pTempBuffer + i; + float *pOut = &c.m_DataBuffer[m_iDataBufferAvailFrames]; for( int j = 0; j < iGotFrames; ++j ) { *pOut = *pIn; @@ -133,7 +133,7 @@ void RageSoundReader_SpeedChange::EraseData( int iFramesToDelete ) { ChannelInfo &c = m_Channels[i]; if( iFramesToMove ) - memmove( &c.m_DataBuffer[0], &c.m_DataBuffer[iFramesToDelete], iFramesToMove * sizeof(int16_t) ); + memmove( &c.m_DataBuffer[0], &c.m_DataBuffer[iFramesToDelete], iFramesToMove * sizeof(float) ); ASSERT( c.m_iCorrelatedPos >= iFramesToDelete ); c.m_iCorrelatedPos -= iFramesToDelete; } @@ -233,7 +233,7 @@ int RageSoundReader_SpeedChange::GetCursorAvail() const return iCursorAvail; } -int RageSoundReader_SpeedChange::Read( int16_t *pBuf, int iFrames ) +int RageSoundReader_SpeedChange::Read( float *pBuf, int iFrames ) { while( 1 ) { @@ -269,9 +269,9 @@ int RageSoundReader_SpeedChange::Read( int16_t *pBuf, int iFrames ) for( size_t i = 0; i < m_Channels.size(); ++i ) { ChannelInfo &c = m_Channels[i]; - int i1 = c.m_DataBuffer[c.m_iCorrelatedPos+m_iPos]; - int i2 = c.m_DataBuffer[c.m_iLastCorrelatedPos+m_iPos]; - *pBuf++ = int16_t( SCALE( m_iPos, 0, iWindowSizeFrames, i2, i1 ) ); + float i1 = c.m_DataBuffer[c.m_iCorrelatedPos+m_iPos]; + float i2 = c.m_DataBuffer[c.m_iLastCorrelatedPos+m_iPos]; + *pBuf++ = SCALE( m_iPos, 0, iWindowSizeFrames, i2, i1 ); } ++m_iPos; diff --git a/stepmania/src/RageSoundReader_SpeedChange.h b/stepmania/src/RageSoundReader_SpeedChange.h index e17e96b783..82b2817ca9 100644 --- a/stepmania/src/RageSoundReader_SpeedChange.h +++ b/stepmania/src/RageSoundReader_SpeedChange.h @@ -11,7 +11,7 @@ public: RageSoundReader_SpeedChange( RageSoundReader *pSource ); virtual int SetPosition( int iFrame ); - virtual int Read( int16_t *pBuf, int iFrames ); + virtual int Read( float *pBuf, int iFrames ); virtual RageSoundReader_SpeedChange *Copy() const { return new RageSoundReader_SpeedChange(*this); } virtual bool SetProperty( const RString &sProperty, float fValue ); virtual int GetNextSourceFrame() const; @@ -40,7 +40,7 @@ protected: int m_iDataBufferAvailFrames; struct ChannelInfo { - vector m_DataBuffer; + vector m_DataBuffer; int m_iCorrelatedPos; int m_iLastCorrelatedPos; }; diff --git a/stepmania/src/RageSoundReader_ThreadedBuffer.cpp b/stepmania/src/RageSoundReader_ThreadedBuffer.cpp index 5fc6bc3a47..e6e56c4633 100644 --- a/stepmania/src/RageSoundReader_ThreadedBuffer.cpp +++ b/stepmania/src/RageSoundReader_ThreadedBuffer.cpp @@ -32,7 +32,7 @@ RageSoundReader_ThreadedBuffer::RageSoundReader_ThreadedBuffer( RageSoundReader m_iSampleRate = pSource->GetSampleRate(); m_iChannels = pSource->GetNumChannels(); - int iFrameSize = sizeof(int16_t) * this->GetNumChannels(); + int iFrameSize = sizeof(float) * this->GetNumChannels(); m_DataBuffer.reserve( g_iStreamingBufferFrames * iFrameSize, iFrameSize ); m_bEOF = false; @@ -279,7 +279,7 @@ int RageSoundReader_ThreadedBuffer::FillBlock() { /* We own m_pSource, even after unlocking, because m_bFilling is true. */ unsigned iBufSize; - int16_t *pBuf = m_DataBuffer.get_write_pointer( &iBufSize ); + float *pBuf = m_DataBuffer.get_write_pointer( &iBufSize ); ASSERT( (iBufSize % iSamplesPerFrame) == 0 ); iGotFrames = m_pSource->RetriedRead( pBuf, min(g_iReadBlockSizeFrames, iBufSize / iSamplesPerFrame), &iNextSourceFrame, &fRate ); } @@ -306,7 +306,7 @@ int RageSoundReader_ThreadedBuffer::FillBlock() return iGotFrames; } -int RageSoundReader_ThreadedBuffer::Read( int16_t *pBuffer, int iFrames ) +int RageSoundReader_ThreadedBuffer::Read( float *pBuffer, int iFrames ) { if( !m_bEOF ) EnableBuffering(); diff --git a/stepmania/src/RageSoundReader_ThreadedBuffer.h b/stepmania/src/RageSoundReader_ThreadedBuffer.h index e5d8f804e0..2ed75005c7 100644 --- a/stepmania/src/RageSoundReader_ThreadedBuffer.h +++ b/stepmania/src/RageSoundReader_ThreadedBuffer.h @@ -18,7 +18,7 @@ public: RageSoundReader_ThreadedBuffer *Copy() const { return new RageSoundReader_ThreadedBuffer(*this); } virtual int SetPosition( int iFrame ); - virtual int Read( int16_t *pBuffer, int iLength ); + virtual int Read( float *pBuffer, int iLength ); virtual int GetNextSourceFrame() const; virtual int GetLength() const; @@ -46,7 +46,7 @@ private: int m_iSampleRate; int m_iChannels; - CircBuf m_DataBuffer; + CircBuf m_DataBuffer; struct Mapping { diff --git a/stepmania/src/RageSoundReader_Vorbisfile.cpp b/stepmania/src/RageSoundReader_Vorbisfile.cpp index 77ca339d77..8ab2c754bd 100644 --- a/stepmania/src/RageSoundReader_Vorbisfile.cpp +++ b/stepmania/src/RageSoundReader_Vorbisfile.cpp @@ -160,15 +160,15 @@ int RageSoundReader_Vorbisfile::SetPosition( int iFrame ) return 1; } -int RageSoundReader_Vorbisfile::Read( int16_t *buf, int iFrames ) +int RageSoundReader_Vorbisfile::Read( float *buf, int iFrames ) { int frames_read = 0; while( iFrames && !eof ) { - const int bytes_per_frame = sizeof(int16_t)*channels; + const int bytes_per_frame = sizeof(float)*channels; - int ret = 0; + int iFramesRead = 0; { int curofs = (int) ov_pcm_tell(vf); @@ -193,18 +193,20 @@ int RageSoundReader_Vorbisfile::Read( int16_t *buf, int iFrames ) CHECKPOINT_M( ssprintf("p %i,%i: %i frames of silence needed", curofs, read_offset, silence) ); memset( buf, 0, silence ); - ret = silence; + iFramesRead = iSilentFrames; } } - if( ret == 0 ) + if( iFramesRead == 0 ) { int bstream; #if defined(INTEGER_VORBIS) - ret = ov_read( vf, (char *) buf, iFrames * bytes_per_frame, &bstream ); + int ret = ov_read( vf, (char *) buf, iFrames * channels * sizeof(int16_t), &bstream ); #else // float vorbis decoder - ret = ov_read( vf, (char *) buf, iFrames * bytes_per_frame, (BYTE_ORDER == BIG_ENDIAN)?1:0, 2, 1, &bstream ); + float **pcm; + int ret = ov_read_float( vf, &pcm, iFrames, &bstream ); #endif + { vorbis_info *vi = ov_info( vf, -1 ); ASSERT( vi != NULL ); @@ -228,12 +230,43 @@ int RageSoundReader_Vorbisfile::Read( int16_t *buf, int iFrames ) eof = true; continue; } + +#if defined(INTEGER_VORBIS) + if( ret > 0 ) + { + int iSamplesRead = ret / sizeof(int16_t); + iFramesRead = iSamplesRead / channels; + + /* Convert in reverse, so we can do it in-place. */ + const int16_t *pIn = (int16_t *) buf; + float *pOut = (float *) buf; + for( int i = iSamplesRead-1; i >= 0; --i ) + pOut[i] = pIn[i] / 32768.0f; + } +#else + if( ret > 0 ) + { + iFramesRead = ret; + + int iNumChannels = channels; + for( int iChannel = 0; iChannel < iNumChannels; ++iChannel ) + { + const float *pChannelIn = pcm[iChannel]; + float *pChannelOut = &buf[iChannel]; + for( int i = 0; i < iFramesRead; ++i ) + { + *pChannelOut = *pChannelIn; + ++pChannelIn; + pChannelOut += iNumChannels; + } + } + } +#endif } - int iFramesRead = ret / bytes_per_frame; - read_offset += ret / bytes_per_frame; + read_offset += iFramesRead; - buf += ret / sizeof(int16_t); + buf += iFramesRead * channels; frames_read += iFramesRead; iFrames -= iFramesRead; } diff --git a/stepmania/src/RageSoundReader_Vorbisfile.h b/stepmania/src/RageSoundReader_Vorbisfile.h index 7c6c29e5c3..53c689efe9 100644 --- a/stepmania/src/RageSoundReader_Vorbisfile.h +++ b/stepmania/src/RageSoundReader_Vorbisfile.h @@ -16,7 +16,7 @@ public: int GetLength() const; int SetPosition( int iFrame ); - int Read( int16_t *pBuf, int iFrames ); + int Read( float *pBuf, int iFrames ); int GetSampleRate() const; unsigned GetNumChannels() const { return channels; } int GetNextSourceFrame() const; diff --git a/stepmania/src/RageSoundReader_WAV.cpp b/stepmania/src/RageSoundReader_WAV.cpp index aaeeb1a255..936f35aaf4 100644 --- a/stepmania/src/RageSoundReader_WAV.cpp +++ b/stepmania/src/RageSoundReader_WAV.cpp @@ -19,21 +19,31 @@ namespace { /* pBuf contains iSamples 8-bit samples; convert to 16-bit. pBuf must * have enough storage to hold the resulting data. */ - void Convert8bitTo16bit( void *pBuf, int iSamples ) + void Convert8bitToFloat( void *pBuf, int iSamples ) { /* Convert in reverse, so we can do it in-place. */ const uint8_t *pIn = (uint8_t *) pBuf; - int16_t *pOut = (int16_t *) pBuf; + float *pOut = (float *) pBuf; for( int i = iSamples-1; i >= 0; --i ) - pOut[i] = SCALE( pIn[i], 0, 255, -32768, 32767 ); + { + int iSample = pIn[i]; + iSample -= 128; /* 0..255 -> -128..127 */ + pOut[i] = iSample / 128.0f; + } } /* Flip 16-bit samples if necessary. On little-endian systems, this will * optimize out. */ - void Convert16BitFromLittleEndian( int16_t *pBuf, int iSamples ) + void ConvertLittleEndian16BitToFloat( void *pBuf, int iSamples ) { - for( int i = 0; i < iSamples; ++i ) - pBuf[i] = Swap16LE( pBuf[i] ); + /* Convert in reverse, so we can do it in-place. */ + const int16_t *pIn = (int16_t *) pBuf; + float *pOut = (float *) pBuf; + for( int i = iSamples-1; i >= 0; --i ) + { + int16_t iSample = Swap16LE( pIn[i] ); + pOut[i] = iSample / 32768.0f; + } } }; @@ -42,7 +52,7 @@ struct WavReader WavReader( RageFile &f, const RageSoundReader_WAV::WavData &data ): m_File(f), m_WavData(data) { } virtual ~WavReader() { } - virtual int Read( int16_t *pBuf, int iFrames ) = 0; + virtual int Read( float *pBuf, int iFrames ) = 0; virtual int GetLength() const = 0; virtual bool Init() = 0; virtual int SetPosition( int iFrame ) = 0; @@ -72,11 +82,10 @@ struct WavReaderPCM: public WavReader return true; } - int Read( int16_t *buf, int iFrames ) + int Read( float *buf, int iFrames ) { - int len = iFrames * m_WavData.m_iChannels * sizeof(int16_t); - if( m_WavData.m_iBitsPerSample == 8 ) - len /= 2; + int len = iFrames * m_WavData.m_iChannels; + len *= m_WavData.m_iBitsPerSample/8; const int iBytesLeftInDataChunk = m_WavData.m_iDataChunkSize - (m_File.Tell() - m_WavData.m_iDataChunkPos); if( !iBytesLeftInDataChunk ) @@ -84,16 +93,16 @@ struct WavReaderPCM: public WavReader len = min( len, iBytesLeftInDataChunk ); int iGot = m_File.Read( buf, len ); - int iGotSamples = 0; + + int iBytesPerSample = m_WavData.m_iBitsPerSample/8; + int iGotSamples = iGot / iBytesPerSample; switch( m_WavData.m_iBitsPerSample ) { case 8: - Convert8bitTo16bit( buf, iGot ); - iGotSamples = iGot; + Convert8bitToFloat( buf, iGotSamples ); break; case 16: - Convert16BitFromLittleEndian( buf, iGot/2 ); - iGotSamples = iGot / 2; + ConvertLittleEndian16BitToFloat( buf, iGotSamples ); break; } return iGotSamples / m_WavData.m_iChannels; @@ -133,7 +142,7 @@ struct WavReaderADPCM: public WavReader public: vector m_iaCoef1, m_iaCoef2; int16_t m_iFramesPerBlock; - int8_t *m_pBuffer; + float *m_pBuffer; int m_iBufferAvail, m_iBufferUsed; WavReaderADPCM( RageFile &f, const RageSoundReader_WAV::WavData &data ): @@ -170,7 +179,7 @@ public: if( m_sError.size() != 0 ) return false; - m_pBuffer = new int8_t[m_iFramesPerBlock*m_WavData.m_iChannels*sizeof(int16_t)]; + m_pBuffer = new float[m_iFramesPerBlock*m_WavData.m_iChannels]; m_iBufferAvail = m_iBufferUsed = 0; m_File.Seek( m_WavData.m_iDataChunkPos ); @@ -207,7 +216,7 @@ public: if( m_File.Tell() >= m_WavData.m_iDataChunkSize+m_WavData.m_iDataChunkPos || m_File.AtEOF() ) return true; /* past the data chunk */ - int16_t *pBuffer = (int16_t *) m_pBuffer; + float *pBuffer = m_pBuffer; int iCoef1[2], iCoef2[2]; for( int i = 0; i < m_WavData.m_iChannels; ++i ) { @@ -239,9 +248,9 @@ public: } for( int i = 0; i < m_WavData.m_iChannels; ++i ) - pBuffer[m_iBufferAvail++] = iSamp2[i]; + pBuffer[m_iBufferAvail++] = iSamp2[i] / 32768.0f; for( int i = 0; i < m_WavData.m_iChannels; ++i ) - pBuffer[m_iBufferAvail++] = iSamp1[i]; + pBuffer[m_iBufferAvail++] = iSamp1[i] / 32768.0f; int8_t iBuf = 0, iBufSize = 0; @@ -272,7 +281,7 @@ public: int32_t iNewSample = iPredSample + (iDelta[c] * iErrorDelta); iNewSample = clamp( iNewSample, -32768, 32767 ); - pBuffer[m_iBufferAvail++] = (int16_t) iNewSample; + pBuffer[m_iBufferAvail++] = iNewSample / 32768.0f; static const int aAdaptionTable[] = { 768, 614, 512, 409, 307, 230, 230, 230, @@ -290,10 +299,10 @@ public: return true; } - int Read( int16_t *buf, int iFrames ) + int Read( float *buf, int iFrames ) { int iSamplesPerFrame = m_WavData.m_iChannels; - int iBytesPerFrame = iSamplesPerFrame * sizeof(int16_t); + int iBytesPerFrame = iSamplesPerFrame * sizeof(float); int iGotFrames = 0; while( iGotFrames < (int) iFrames ) { @@ -541,7 +550,7 @@ int RageSoundReader_WAV::GetNextSourceFrame() const return m_pImpl->GetNextSourceFrame(); } -int RageSoundReader_WAV::Read( int16_t *pBuf, int iFrames ) +int RageSoundReader_WAV::Read( float *pBuf, int iFrames ) { ASSERT( m_pImpl != NULL ); return m_pImpl->Read( pBuf, iFrames ); diff --git a/stepmania/src/RageSoundReader_WAV.h b/stepmania/src/RageSoundReader_WAV.h index 9b7497c4e4..51b2360c53 100644 --- a/stepmania/src/RageSoundReader_WAV.h +++ b/stepmania/src/RageSoundReader_WAV.h @@ -14,7 +14,7 @@ public: void Close(); int GetLength() const; int SetPosition( int iFrame ); - int Read( int16_t *pBuf, int iFrames ); + int Read( float *pBuf, int iFrames ); int GetSampleRate() const { return m_WavData.m_iSampleRate; } unsigned GetNumChannels() const { return m_WavData.m_iChannels; } int GetNextSourceFrame() const; diff --git a/stepmania/src/RageSoundUtil.cpp b/stepmania/src/RageSoundUtil.cpp index 03abd4a62f..a10c3cdba2 100644 --- a/stepmania/src/RageSoundUtil.cpp +++ b/stepmania/src/RageSoundUtil.cpp @@ -5,17 +5,17 @@ /* Some of these functions assume a channel count: */ static const int channels = 2; -void RageSoundUtil::Attenuate( int16_t *pBuf, int iSamples, float fVolume ) +void RageSoundUtil::Attenuate( float *pBuf, int iSamples, float fVolume ) { while( iSamples-- ) { - *pBuf = int16_t( (*pBuf) * fVolume ); + *pBuf *= fVolume; ++pBuf; } } /* Pan buffer left or right; fPos is -1...+1. Buffer is assumed to be stereo. */ -void RageSoundUtil::Pan( int16_t *buffer, int frames, float fPos ) +void RageSoundUtil::Pan( float *buffer, int frames, float fPos ) { if( fPos == 0 ) return; /* no change */ @@ -40,15 +40,15 @@ void RageSoundUtil::Pan( int16_t *buffer, int frames, float fPos ) ASSERT_M( channels == 2, ssprintf("%i", channels) ); for( int samp = 0; samp < frames; ++samp ) { - int16_t l = int16_t(buffer[0]*fLeftFactors[0] + buffer[1]*fLeftFactors[1]); - int16_t r = int16_t(buffer[0]*fRightFactors[0] + buffer[1]*fRightFactors[1]); + float l = buffer[0]*fLeftFactors[0] + buffer[1]*fLeftFactors[1]; + float r = buffer[0]*fRightFactors[0] + buffer[1]*fRightFactors[1]; buffer[0] = l; buffer[1] = r; buffer += 2; } } -void RageSoundUtil::Fade( int16_t *buffer, int frames, float fStartVolume, float fEndVolume ) +void RageSoundUtil::Fade( float *buffer, int frames, float fStartVolume, float fEndVolume ) { /* If the whole buffer is full volume, skip. */ if( fStartVolume > .9999f && fEndVolume > .9999f ) @@ -61,17 +61,17 @@ void RageSoundUtil::Fade( int16_t *buffer, int frames, float fStartVolume, float fVolPercent = clamp( fVolPercent, 0.f, 1.f ); for(int i = 0; i < channels; ++i) { - *buffer = short(*buffer * fVolPercent); + *buffer *= fVolPercent; buffer++; } } } /* Dupe mono to stereo in-place; do it in reverse, to handle overlap. */ -void RageSoundUtil::ConvertMonoToStereoInPlace( int16_t *data, int iFrames ) +void RageSoundUtil::ConvertMonoToStereoInPlace( float *data, int iFrames ) { - int16_t *input = data; - int16_t *output = input; + float *input = data; + float *output = input; input += iFrames; output += iFrames * 2; while( iFrames-- ) diff --git a/stepmania/src/RageSoundUtil.h b/stepmania/src/RageSoundUtil.h index c49cc387fe..003f40e053 100644 --- a/stepmania/src/RageSoundUtil.h +++ b/stepmania/src/RageSoundUtil.h @@ -5,10 +5,10 @@ namespace RageSoundUtil { - void Attenuate( int16_t *pBuf, int iSamples, float fVolume ); - void Pan( int16_t *pBuffer, int iFrames, float fPos ); - void Fade( int16_t *pBuffer, int iFrames, float fStartVolume, float fEndVolume ); - void ConvertMonoToStereoInPlace( int16_t *pBuffer, int iFrames ); + void Attenuate( float *pBuf, int iSamples, float fVolume ); + void Pan( float *pBuffer, int iFrames, float fPos ); + void Fade( float *pBuffer, int iFrames, float fStartVolume, float fEndVolume ); + void ConvertMonoToStereoInPlace( float *pBuffer, int iFrames ); }; #endif