fixes, etc.
This commit is contained in:
+73
-57
@@ -74,8 +74,11 @@ RageSound::RageSound()
|
|||||||
position = 0;
|
position = 0;
|
||||||
playing = false;
|
playing = false;
|
||||||
Loop = false;
|
Loop = false;
|
||||||
|
AutoStop = true;
|
||||||
speed = 1.0f;
|
speed = 1.0f;
|
||||||
stream.buf.reserve(internal_buffer_size);
|
stream.buf.reserve(internal_buffer_size);
|
||||||
|
m_StartSeconds = 0;
|
||||||
|
m_LengthSeconds = -1;
|
||||||
|
|
||||||
/* Register ourselves, so we receive Update()s. */
|
/* Register ourselves, so we receive Update()s. */
|
||||||
SOUNDMAN->all_sounds.insert(this);
|
SOUNDMAN->all_sounds.insert(this);
|
||||||
@@ -100,6 +103,7 @@ RageSound::RageSound(const RageSound &cpy)
|
|||||||
Loop = false;
|
Loop = false;
|
||||||
speed = 1.0f;
|
speed = 1.0f;
|
||||||
stream.buf.reserve(internal_buffer_size);
|
stream.buf.reserve(internal_buffer_size);
|
||||||
|
AutoStop = cpy.AutoStop;
|
||||||
|
|
||||||
/* Copy some of it; don't copy the playing state. */
|
/* Copy some of it; don't copy the playing state. */
|
||||||
big = cpy.big;
|
big = cpy.big;
|
||||||
@@ -205,22 +209,26 @@ void RageSound::Load(CString sSoundFilePath, bool cache)
|
|||||||
position = 0;
|
position = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RageSound::Play( bool bLoop, float fStartSeconds, float fLengthSeconds )
|
void RageSound::SetStartSeconds( float secs )
|
||||||
|
{
|
||||||
|
m_StartSeconds = secs;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RageSound::SetLengthSeconds(float secs)
|
||||||
|
{
|
||||||
|
m_LengthSeconds = secs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Start playing from m_StartSeconds. TODO: a way to start playing
|
||||||
|
* from the current pos (unpause) */
|
||||||
|
void RageSound::Play()
|
||||||
{
|
{
|
||||||
LockMutex L(SOUNDMAN->lock);
|
LockMutex L(SOUNDMAN->lock);
|
||||||
|
|
||||||
if(playing) Stop();
|
if(playing) Stop();
|
||||||
playing = true;
|
playing = true;
|
||||||
|
|
||||||
Loop = bLoop;
|
|
||||||
|
|
||||||
if(fStartSeconds != -1000)
|
|
||||||
{
|
|
||||||
m_StartSeconds = fStartSeconds;
|
|
||||||
SetPositionSeconds(m_StartSeconds);
|
SetPositionSeconds(m_StartSeconds);
|
||||||
} else m_StartSeconds = 0;
|
|
||||||
|
|
||||||
m_LengthSeconds = fLengthSeconds;
|
|
||||||
|
|
||||||
// Tell the sound manager to start mixing us
|
// Tell the sound manager to start mixing us
|
||||||
SOUNDMAN->StartMixing(this);
|
SOUNDMAN->StartMixing(this);
|
||||||
@@ -325,50 +333,8 @@ int RageSound::GetPCM(char *buffer, int size, int sampleno)
|
|||||||
memcpy(buffer, full_buf.data()+byte_pos, got);
|
memcpy(buffer, full_buf.data()+byte_pos, got);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(got) {
|
if(!got)
|
||||||
/* Save this sampleno/position map. */
|
|
||||||
pos_map[3].push_back(pos_map_t(sampleno, position, got/samplesize));
|
|
||||||
|
|
||||||
int got_samples = got / samplesize; /* bytes -> samples */
|
|
||||||
|
|
||||||
/* This block goes from position to position+got_samples. */
|
|
||||||
const float FADE_TIME = 1.5f;
|
|
||||||
|
|
||||||
/* XXX: Loop shouldn't set fading; add a Fade_Time member?
|
|
||||||
*
|
|
||||||
* We want to fade when there's FADE_TIME seconds left, but if
|
|
||||||
* m_LengthSeconds is -1, we don't know the length we're playing.
|
|
||||||
* (m_LengthSeconds is the length to play, not the length of the
|
|
||||||
* source.) If we don't know the length, don't fade. */
|
|
||||||
if(Loop) {
|
|
||||||
Sint16 *p = (Sint16 *) buffer;
|
|
||||||
int this_position = position;
|
|
||||||
|
|
||||||
for(int samp = 0; samp < got_samples; ++samp)
|
|
||||||
{
|
{
|
||||||
float fSecsUntilSilent = (m_StartSeconds + m_LengthSeconds) - float(this_position)/samplerate;
|
|
||||||
float fVolPercent = fSecsUntilSilent / FADE_TIME;
|
|
||||||
|
|
||||||
fVolPercent = clamp(fVolPercent, 0.f, 1.f);
|
|
||||||
for(int i = 0; i < channels; ++i) {
|
|
||||||
*p = short(*p * fVolPercent);
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
this_position++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bytes_stored += got;
|
|
||||||
position += got_samples;
|
|
||||||
size -= got;
|
|
||||||
buffer += got;
|
|
||||||
sampleno += got_samples;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we've filled the buffer, we're done. */
|
|
||||||
if(!size) break;
|
|
||||||
|
|
||||||
/* We need more data. Find out if we've hit EOF. */
|
/* We need more data. Find out if we've hit EOF. */
|
||||||
bool HitEOF = true;
|
bool HitEOF = true;
|
||||||
if(big) {
|
if(big) {
|
||||||
@@ -392,11 +358,59 @@ int RageSound::GetPCM(char *buffer, int size, int sampleno)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* We're at EOF. If we're not looping, just stop. */
|
/* We're at EOF. If we're not looping, just stop. */
|
||||||
if(!Loop)
|
if(Loop)
|
||||||
break;
|
{
|
||||||
|
|
||||||
/* Rewind and start over. */
|
/* Rewind and start over. */
|
||||||
SetPositionSeconds(m_StartSeconds);
|
SetPositionSeconds(m_StartSeconds);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(AutoStop)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* We're out of data, but we're not going to stop, so fill in the
|
||||||
|
* rest with silence. */
|
||||||
|
memset(buffer, 0, size);
|
||||||
|
got = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Save this sampleno/position map. */
|
||||||
|
pos_map[3].push_back(pos_map_t(sampleno, position, got/samplesize));
|
||||||
|
|
||||||
|
int got_samples = got / samplesize; /* bytes -> samples */
|
||||||
|
|
||||||
|
/* This block goes from position to position+got_samples. */
|
||||||
|
const float FADE_TIME = 1.5f;
|
||||||
|
|
||||||
|
/* XXX: Loop shouldn't set fading; add a Fade_Time member?
|
||||||
|
*
|
||||||
|
* We want to fade when there's FADE_TIME seconds left, but if
|
||||||
|
* m_LengthSeconds is -1, we don't know the length we're playing.
|
||||||
|
* (m_LengthSeconds is the length to play, not the length of the
|
||||||
|
* source.) If we don't know the length, don't fade. */
|
||||||
|
if(Loop && m_LengthSeconds != -1) {
|
||||||
|
Sint16 *p = (Sint16 *) buffer;
|
||||||
|
int this_position = position;
|
||||||
|
|
||||||
|
for(int samp = 0; samp < got_samples; ++samp)
|
||||||
|
{
|
||||||
|
float fSecsUntilSilent = (m_StartSeconds + m_LengthSeconds) - float(this_position)/samplerate;
|
||||||
|
float fVolPercent = fSecsUntilSilent / FADE_TIME;
|
||||||
|
|
||||||
|
fVolPercent = clamp(fVolPercent, 0.f, 1.f);
|
||||||
|
for(int i = 0; i < channels; ++i) {
|
||||||
|
*p = short(*p * fVolPercent);
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
this_position++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bytes_stored += got;
|
||||||
|
position += got_samples;
|
||||||
|
size -= got;
|
||||||
|
buffer += got;
|
||||||
|
sampleno += got_samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
return bytes_stored;
|
return bytes_stored;
|
||||||
@@ -460,7 +474,7 @@ float RageSound::GetLengthSeconds()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float RageSound::GetPositionSeconds()
|
float RageSound::GetPositionSeconds() const
|
||||||
{
|
{
|
||||||
LockMutex L(SOUNDMAN->lock);
|
LockMutex L(SOUNDMAN->lock);
|
||||||
|
|
||||||
@@ -556,6 +570,7 @@ void RageSound::SetPlaybackRate( float fScale )
|
|||||||
speed = fScale;
|
speed = fScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This is used to start music. It probably belongs in RageSoundManager. */
|
||||||
void RageSound::LoadAndPlayIfNotAlready( CString sSoundFilePath )
|
void RageSound::LoadAndPlayIfNotAlready( CString sSoundFilePath )
|
||||||
{
|
{
|
||||||
SOUNDMAN->lock.Lock();
|
SOUNDMAN->lock.Lock();
|
||||||
@@ -564,7 +579,8 @@ void RageSound::LoadAndPlayIfNotAlready( CString sSoundFilePath )
|
|||||||
SOUNDMAN->lock.Unlock();
|
SOUNDMAN->lock.Unlock();
|
||||||
|
|
||||||
Load( sSoundFilePath );
|
Load( sSoundFilePath );
|
||||||
Play( true );
|
SetLooping();
|
||||||
|
Play();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CircBuf::reserve(unsigned n)
|
void CircBuf::reserve(unsigned n)
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ class RageSound
|
|||||||
CString m_sFilePath;
|
CString m_sFilePath;
|
||||||
// float m_Rate;
|
// float m_Rate;
|
||||||
|
|
||||||
/* If looping, the range to loop: */
|
/* The amount of data to play (or loop): */
|
||||||
float m_StartSeconds, m_LengthSeconds;
|
float m_StartSeconds, m_LengthSeconds;
|
||||||
bool Loop;
|
bool Loop;
|
||||||
|
|
||||||
@@ -68,6 +68,13 @@ class RageSound
|
|||||||
|
|
||||||
float speed;
|
float speed;
|
||||||
|
|
||||||
|
/* If true, the sound will stop when it reaches the end; otherwise it'll
|
||||||
|
* continue to move forward, feeding silence, which is useful to continue
|
||||||
|
* timing longer than the actual sound. (However, if this is false, the
|
||||||
|
* sound will never stop on its own unless destructed; it must be explitly
|
||||||
|
* stopped, and PlayCopy can't be used.) Default is true. Ignored when looping. */
|
||||||
|
bool AutoStop;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RageSound();
|
RageSound();
|
||||||
~RageSound();
|
~RageSound();
|
||||||
@@ -82,16 +89,22 @@ public:
|
|||||||
void LoadAndPlayIfNotAlready( CString sSoundFilePath );
|
void LoadAndPlayIfNotAlready( CString sSoundFilePath );
|
||||||
void Unload();
|
void Unload();
|
||||||
|
|
||||||
void Play( bool bLoop = false, float fStartSeconds = -1000, float fLengthSeconds = -1 );
|
void SetAutoStop(bool yes=true) { AutoStop=yes; }
|
||||||
|
bool GetAutoStop() const { return AutoStop; }
|
||||||
|
void SetStartSeconds(float secs = 0); /* default = beginning */
|
||||||
|
void SetLengthSeconds(float secs = -1); /* default = no length limit */
|
||||||
|
void Play();
|
||||||
void Pause();
|
void Pause();
|
||||||
void Stop();
|
void Stop();
|
||||||
float GetLengthSeconds();
|
float GetLengthSeconds();
|
||||||
float GetPositionSeconds();
|
float GetPositionSeconds() const;
|
||||||
void SetPositionSeconds( float fSeconds );
|
void SetPositionSeconds( float fSeconds );
|
||||||
void SetPlaybackRate( float fScale );
|
void SetPlaybackRate( float fScale );
|
||||||
float GetPlaybackRate() const { return speed; }
|
float GetPlaybackRate() const { return speed; }
|
||||||
bool IsPlaying() const { return playing; }
|
bool IsPlaying() const { return playing; }
|
||||||
CString GetLoadedFilePath() const { return m_sFilePath; };
|
CString GetLoadedFilePath() const { return m_sFilePath; }
|
||||||
|
void SetLooping(bool yes=true) { Loop=yes; }
|
||||||
|
bool GetLooping() const { return Loop; }
|
||||||
|
|
||||||
/* Called only by the sound drivers: */
|
/* Called only by the sound drivers: */
|
||||||
/* This function should return the number of bytes actually put into buffer.
|
/* This function should return the number of bytes actually put into buffer.
|
||||||
|
|||||||
Reference in New Issue
Block a user