changed sound API
This commit is contained in:
+69
-49
@@ -75,6 +75,7 @@ RageSound::RageSound()
|
|||||||
initialized = true;
|
initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
original = this;
|
||||||
stream.Sample = NULL;
|
stream.Sample = NULL;
|
||||||
position = 0;
|
position = 0;
|
||||||
playing = false;
|
playing = false;
|
||||||
@@ -91,6 +92,11 @@ RageSound::RageSound()
|
|||||||
|
|
||||||
RageSound::~RageSound()
|
RageSound::~RageSound()
|
||||||
{
|
{
|
||||||
|
/* If we're a "master" sound (not a copy), tell RageSoundManager to
|
||||||
|
* stop mixing us and everything that's copied from us. */
|
||||||
|
if(original == this)
|
||||||
|
SOUNDMAN->StopPlayingSound(*this);
|
||||||
|
|
||||||
Unload();
|
Unload();
|
||||||
|
|
||||||
/* Unregister ourselves. */
|
/* Unregister ourselves. */
|
||||||
@@ -104,6 +110,7 @@ RageSound::RageSound(const RageSound &cpy)
|
|||||||
|
|
||||||
stream.Sample = NULL;
|
stream.Sample = NULL;
|
||||||
|
|
||||||
|
original = cpy.original;
|
||||||
full_buf = cpy.full_buf;
|
full_buf = cpy.full_buf;
|
||||||
big = cpy.big;
|
big = cpy.big;
|
||||||
m_sFilePath = cpy.m_sFilePath;
|
m_sFilePath = cpy.m_sFilePath;
|
||||||
@@ -131,7 +138,7 @@ RageSound::RageSound(const RageSound &cpy)
|
|||||||
void RageSound::Unload()
|
void RageSound::Unload()
|
||||||
{
|
{
|
||||||
if(IsPlaying())
|
if(IsPlaying())
|
||||||
Stop();
|
StopPlaying();
|
||||||
|
|
||||||
Sound_FreeSample(stream.Sample);
|
Sound_FreeSample(stream.Sample);
|
||||||
stream.Sample = NULL;
|
stream.Sample = NULL;
|
||||||
@@ -146,6 +153,9 @@ void RageSound::Load(CString sSoundFilePath, bool cache)
|
|||||||
{
|
{
|
||||||
LOG->Trace( "RageSound::LoadSound( '%s' )", sSoundFilePath.GetString() );
|
LOG->Trace( "RageSound::LoadSound( '%s' )", sSoundFilePath.GetString() );
|
||||||
|
|
||||||
|
/* Don't load over copies. */
|
||||||
|
// ASSERT(original == this);
|
||||||
|
|
||||||
Unload();
|
Unload();
|
||||||
|
|
||||||
m_sFilePath = sSoundFilePath;
|
m_sFilePath = sSoundFilePath;
|
||||||
@@ -231,22 +241,9 @@ void RageSound::SetLengthSeconds(float secs)
|
|||||||
m_LengthSamples = int(secs*samplerate);
|
m_LengthSamples = int(secs*samplerate);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Start playing from the current position. If the sound is already
|
|
||||||
* playing, Stop is called. */
|
|
||||||
void RageSound::Play()
|
|
||||||
{
|
|
||||||
LockMut(SOUNDMAN->lock);
|
|
||||||
|
|
||||||
if(playing) Stop();
|
|
||||||
playing = true;
|
|
||||||
|
|
||||||
// Tell the sound manager to start mixing us
|
|
||||||
SOUNDMAN->StartMixing(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RageSound::Update(float delta)
|
void RageSound::Update(float delta)
|
||||||
{
|
{
|
||||||
if(playing && big)
|
if(playing && big && delta)
|
||||||
stream.FillBuf(int(delta * samplerate * samplesize));
|
stream.FillBuf(int(delta * samplerate * samplesize));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -299,10 +296,6 @@ int RageSound::GetPCM(char *buffer, int size, int sampleno)
|
|||||||
{
|
{
|
||||||
LockMut(SOUNDMAN->lock);
|
LockMut(SOUNDMAN->lock);
|
||||||
|
|
||||||
/* If the sound is paused, just fill the buffer with silence.
|
|
||||||
* Hmm. Pausing is annoying, since we'll get startup latency if
|
|
||||||
* we keep our buffer playing; we should stop the stream completely
|
|
||||||
* when we pause ... */
|
|
||||||
ASSERT(playing);
|
ASSERT(playing);
|
||||||
|
|
||||||
int bytes_stored = 0;
|
int bytes_stored = 0;
|
||||||
@@ -391,7 +384,7 @@ int RageSound::GetPCM(char *buffer, int size, int sampleno)
|
|||||||
if(Loop && m_LengthSamples != 0)
|
if(Loop && m_LengthSamples != 0)
|
||||||
{
|
{
|
||||||
/* Rewind and start over. */
|
/* Rewind and start over. */
|
||||||
SetPositionSeconds(float(m_StartSample) / samplerate);
|
SetPositionSamples(m_StartSample);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(AutoStop)
|
if(AutoStop)
|
||||||
@@ -446,36 +439,39 @@ int RageSound::GetPCM(char *buffer, int size, int sampleno)
|
|||||||
return bytes_stored;
|
return bytes_stored;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* After we finish via the GetPCM return value, this is called by
|
/* Start playing from the current position. If the sound is already
|
||||||
* RageSoundManager once the sound is actually flushed, which means
|
* playing, Stop is called. */
|
||||||
* we're *really* stopped. */
|
void RageSound::StartPlaying()
|
||||||
void RageSound::SoundStopped()
|
|
||||||
{
|
{
|
||||||
LOG->Trace("stop completed");
|
LockMut(SOUNDMAN->lock);
|
||||||
Stop();
|
|
||||||
|
ASSERT(!playing);
|
||||||
|
|
||||||
|
// Tell the sound manager to start mixing us
|
||||||
|
playing = true;
|
||||||
|
SOUNDMAN->StartMixing(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RageSound::Pause()
|
void RageSound::StopPlaying()
|
||||||
{
|
{
|
||||||
if(!playing) return;
|
/* Tell the sound manager to stop mixing this sound. */
|
||||||
|
|
||||||
// Tell the sound manager to stop mixing this sound.
|
|
||||||
SOUNDMAN->StopMixing(this);
|
SOUNDMAN->StopMixing(this);
|
||||||
|
|
||||||
playing = false;
|
playing = false;
|
||||||
|
|
||||||
|
pos_map.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
RageSound *RageSound::Play()
|
||||||
|
{
|
||||||
|
return SOUNDMAN->PlaySound(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RageSound::Stop()
|
void RageSound::Stop()
|
||||||
{
|
{
|
||||||
/* Tell the sound manager to stop mixing this sound. */
|
SOUNDMAN->StopPlayingSound(*this);
|
||||||
SOUNDMAN->StopMixing(this);
|
|
||||||
|
|
||||||
SetPositionSeconds(float(m_StartSample)/samplerate);
|
|
||||||
|
|
||||||
playing = false;
|
|
||||||
pos_map.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float RageSound::GetLengthSeconds()
|
float RageSound::GetLengthSeconds()
|
||||||
{
|
{
|
||||||
if(big) {
|
if(big) {
|
||||||
@@ -564,23 +560,43 @@ float RageSound::GetPositionSeconds() const
|
|||||||
|
|
||||||
void RageSound::SetPositionSeconds( float fSeconds )
|
void RageSound::SetPositionSeconds( float fSeconds )
|
||||||
{
|
{
|
||||||
|
SetPositionSamples( fSeconds == -1? -1: int(fSeconds * samplerate) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void RageSound::SetPositionSamples( int samples )
|
||||||
|
{
|
||||||
|
if(samples == -1)
|
||||||
|
samples = m_StartSample;
|
||||||
|
|
||||||
/* This can take a while. Only lock the sound buffer if we're actually playing. */
|
/* This can take a while. Only lock the sound buffer if we're actually playing. */
|
||||||
SOUNDMAN->lock.Lock();
|
SOUNDMAN->lock.Lock();
|
||||||
if(!playing)
|
|
||||||
SOUNDMAN->lock.Unlock();
|
|
||||||
|
|
||||||
position = int(fSeconds * samplerate);
|
if(!playing)
|
||||||
if( fSeconds < 0 )
|
{
|
||||||
fSeconds = 0;
|
SOUNDMAN->lock.Unlock();
|
||||||
|
/* If we're already there, don't do anything. */
|
||||||
|
if(position == samples)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
position = samples;
|
||||||
|
if( samples < 0 )
|
||||||
|
samples = 0;
|
||||||
|
|
||||||
if(big) {
|
if(big) {
|
||||||
ASSERT(stream.Sample);
|
ASSERT(stream.Sample);
|
||||||
if(fSeconds == 0)
|
int ms = int(float(samples) * 1000.f / samplerate);
|
||||||
|
|
||||||
|
if(ms == 0)
|
||||||
Sound_Rewind(stream.Sample);
|
Sound_Rewind(stream.Sample);
|
||||||
else if(AccurateSync)
|
else if(AccurateSync)
|
||||||
Sound_AccurateSeek(stream.Sample, int(fSeconds * 1000));
|
Sound_AccurateSeek(stream.Sample, ms);
|
||||||
else
|
else
|
||||||
Sound_FastSeek(stream.Sample, int(fSeconds * 1000));
|
{
|
||||||
|
RageTimer tm;
|
||||||
|
Sound_FastSeek(stream.Sample, ms);
|
||||||
|
LOG->Trace("%f", tm.GetDeltaTime());
|
||||||
|
}
|
||||||
stream.buf.clear();
|
stream.buf.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -603,11 +619,15 @@ void RageSound::LoadAndPlayIfNotAlready( CString sSoundFilePath )
|
|||||||
return; // do nothing
|
return; // do nothing
|
||||||
|
|
||||||
Load( sSoundFilePath );
|
Load( sSoundFilePath );
|
||||||
SetPositionSeconds(0);
|
if(IsPlaying())
|
||||||
SetStartSeconds(0);
|
StopPlaying();
|
||||||
|
|
||||||
|
/* Use defaults: the beginning, the whole file. */
|
||||||
|
SetStartSeconds();
|
||||||
SetLengthSeconds();
|
SetLengthSeconds();
|
||||||
|
SetPositionSamples();
|
||||||
SetLooping();
|
SetLooping();
|
||||||
Play();
|
StartPlaying();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CircBuf::reserve(unsigned n)
|
void CircBuf::reserve(unsigned n)
|
||||||
|
|||||||
@@ -26,6 +26,10 @@ public:
|
|||||||
|
|
||||||
class RageSound
|
class RageSound
|
||||||
{
|
{
|
||||||
|
/* If we were copied from another RageSound, this will point to it; otherwise
|
||||||
|
* this is ourself. */
|
||||||
|
RageSound *original;
|
||||||
|
|
||||||
/* These are only used when big == true: */
|
/* These are only used when big == true: */
|
||||||
struct stream_t {
|
struct stream_t {
|
||||||
Sound_Sample *Sample;
|
Sound_Sample *Sample;
|
||||||
@@ -79,11 +83,15 @@ class RageSound
|
|||||||
* stopped, and PlayCopy can't be used.) Default is true. Ignored when looping. */
|
* stopped, and PlayCopy can't be used.) Default is true. Ignored when looping. */
|
||||||
bool AutoStop;
|
bool AutoStop;
|
||||||
|
|
||||||
|
void SetPositionSamples( int samples = -1 );
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RageSound();
|
RageSound();
|
||||||
~RageSound();
|
~RageSound();
|
||||||
RageSound(const RageSound &cpy);
|
RageSound(const RageSound &cpy);
|
||||||
|
|
||||||
|
/* Used by RageSoundManager: */
|
||||||
|
RageSound *GetOriginal() { return original; }
|
||||||
|
|
||||||
/* 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.
|
||||||
@@ -92,10 +100,6 @@ public:
|
|||||||
* can still be called (the sound is still playing). */
|
* can still be called (the sound is still playing). */
|
||||||
int GetPCM(char *buffer, int size, int sampleno);
|
int GetPCM(char *buffer, int size, int sampleno);
|
||||||
|
|
||||||
/* Called by the sound driver when a sound has actually finished stopping
|
|
||||||
* normally. Not called when Stop() is called to stop the sound prematurely. */
|
|
||||||
void SoundStopped();
|
|
||||||
|
|
||||||
void Update(float delta);
|
void Update(float delta);
|
||||||
|
|
||||||
/* User API from here on: */
|
/* User API from here on: */
|
||||||
@@ -110,18 +114,22 @@ public:
|
|||||||
void Unload();
|
void Unload();
|
||||||
|
|
||||||
/* If enabled, then the sound will automatically stop when it reaches
|
/* If enabled, then the sound will automatically stop when it reaches
|
||||||
* the end; otherwise it'll feed silence until Stop() is called. */
|
* the end; otherwise it'll feed silence until stopped manually. */
|
||||||
void SetAutoStop(bool yes=true) { AutoStop=yes; }
|
void SetAutoStop(bool yes=true) { AutoStop=yes; }
|
||||||
bool GetAutoStop() const { return AutoStop; }
|
bool GetAutoStop() const { return AutoStop; }
|
||||||
|
|
||||||
void SetStartSeconds(float secs = 0); /* default = beginning */
|
void SetStartSeconds(float secs = 0); /* default = beginning */
|
||||||
void SetLengthSeconds(float secs = -1); /* default = no length limit */
|
void SetLengthSeconds(float secs = -1); /* default = no length limit */
|
||||||
void Play();
|
void StartPlaying();
|
||||||
void Pause();
|
// void Pause();
|
||||||
|
void StopPlaying();
|
||||||
|
|
||||||
|
RageSound *Play();
|
||||||
void Stop();
|
void Stop();
|
||||||
|
|
||||||
float GetLengthSeconds();
|
float GetLengthSeconds();
|
||||||
float GetPositionSeconds() const;
|
float GetPositionSeconds() const;
|
||||||
void SetPositionSeconds( float fSeconds );
|
void SetPositionSeconds( float fSeconds = -1);
|
||||||
void SetAccurateSync(bool yes=true) { AccurateSync = yes; }
|
void SetAccurateSync(bool yes=true) { AccurateSync = yes; }
|
||||||
void SetPlaybackRate( float fScale );
|
void SetPlaybackRate( float fScale );
|
||||||
float GetPlaybackRate() const { return speed; }
|
float GetPlaybackRate() const { return speed; }
|
||||||
|
|||||||
@@ -32,11 +32,14 @@ RageSoundManager::~RageSoundManager()
|
|||||||
|
|
||||||
void RageSoundManager::StartMixing(RageSound *snd)
|
void RageSoundManager::StartMixing(RageSound *snd)
|
||||||
{
|
{
|
||||||
|
playing_sounds.insert(snd);
|
||||||
driver->StartMixing(snd);
|
driver->StartMixing(snd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RageSoundManager::StopMixing(RageSound *snd)
|
void RageSoundManager::StopMixing(RageSound *snd)
|
||||||
{
|
{
|
||||||
|
playing_sounds.erase(snd);
|
||||||
|
|
||||||
driver->StopMixing(snd);
|
driver->StopMixing(snd);
|
||||||
|
|
||||||
/* The sound is finished, and should be deleted if it's in owned_sounds.
|
/* The sound is finished, and should be deleted if it's in owned_sounds.
|
||||||
@@ -103,7 +106,7 @@ void RageSoundManager::Update(float delta)
|
|||||||
|
|
||||||
int got = s->GetPCM(buf, bytes, now);
|
int got = s->GetPCM(buf, bytes, now);
|
||||||
if(got < bytes)
|
if(got < bytes)
|
||||||
s->SoundStopped();
|
s->StopPlaying();
|
||||||
|
|
||||||
j = next;
|
j = next;
|
||||||
}
|
}
|
||||||
@@ -127,38 +130,50 @@ float RageSoundManager::GetPlayLatency() const
|
|||||||
return driver->GetPlayLatency();
|
return driver->GetPlayLatency();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RageSoundManager::PlayCopy( const RageSound &snd )
|
RageSound *RageSoundManager::PlaySound(RageSound &snd)
|
||||||
{
|
{
|
||||||
/* Make a copy of the sound and play it; this detaches the sound
|
RageSound *sound_to_play;
|
||||||
* from the screen. This has a few effects:
|
if(!snd.IsPlaying())
|
||||||
*
|
sound_to_play = &snd;
|
||||||
* 1. If this is called more than once, it actually plays a new
|
else
|
||||||
* copy of the sound, rather than rewinding the currently-playing
|
{
|
||||||
* one. (This is important for keyed games.)
|
sound_to_play = new RageSound(snd);
|
||||||
*
|
|
||||||
* 2. If the screen closes, the sound plays to completion.
|
|
||||||
*
|
|
||||||
* I'm not sure if copying will become a performance problem. As a
|
|
||||||
* flag, we could play snd instead of a copy if snd isn't actually
|
|
||||||
* playing. This would keep property 1 and lose 2, which would be
|
|
||||||
* fine for keyed games. Copying a streamed sound reopens the sound;
|
|
||||||
* copying a prebuffered sound makes a new copy of the buffer (unless
|
|
||||||
* std::basic_string happens to be refcounted). That's not too bad,
|
|
||||||
* but we might do five of these in the same frame ...
|
|
||||||
*/
|
|
||||||
|
|
||||||
RageSound *newsnd = new RageSound(snd);
|
|
||||||
|
|
||||||
/* PlayCopy's sounds must always stop on their own. */
|
|
||||||
newsnd->SetLooping(false);
|
|
||||||
newsnd->SetAutoStop(true);
|
|
||||||
|
|
||||||
/* We're responsible for freeing it. */
|
/* We're responsible for freeing it. */
|
||||||
owned_sounds.insert(newsnd);
|
owned_sounds.insert(sound_to_play);
|
||||||
|
|
||||||
newsnd->Play();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Move to the start position.
|
||||||
|
sound_to_play->SetPositionSeconds();
|
||||||
|
sound_to_play->StartPlaying();
|
||||||
|
|
||||||
|
return sound_to_play;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RageSoundManager::StopPlayingSound(RageSound &snd)
|
||||||
|
{
|
||||||
|
/* Stop playing all playing sounds derived from the same parent as snd. */
|
||||||
|
vector<RageSound *> snds;
|
||||||
|
GetCopies(snd, snds);
|
||||||
|
for(vector<RageSound *>::iterator i = snds.begin(); i != snds.end(); i++)
|
||||||
|
{
|
||||||
|
if((*i)->IsPlaying())
|
||||||
|
(*i)->StopPlaying();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RageSoundManager::GetCopies(RageSound &snd, vector<RageSound *> &snds)
|
||||||
|
{
|
||||||
|
RageSound *parent = snd.GetOriginal();
|
||||||
|
|
||||||
|
snds.clear();
|
||||||
|
for(set<RageSound *>::iterator i = playing_sounds.begin();
|
||||||
|
i != playing_sounds.end(); i++)
|
||||||
|
if((*i)->GetOriginal() == parent)
|
||||||
|
snds.push_back(*i);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void RageSoundManager::PlayOnce( CString sPath )
|
void RageSoundManager::PlayOnce( CString sPath )
|
||||||
{
|
{
|
||||||
/* We want this to start quickly, so don't try to prebuffer it. */
|
/* We want this to start quickly, so don't try to prebuffer it. */
|
||||||
@@ -189,7 +204,7 @@ void RageSoundManager::PlayOnceFromDir( CString sDir )
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
int index = rand() % arraySoundFiles.size();
|
int index = rand() % arraySoundFiles.size();
|
||||||
PlayOnce( sDir + arraySoundFiles[index] );
|
SOUNDMAN->PlayOnce( sDir + arraySoundFiles[index] );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Standalone helpers: */
|
/* Standalone helpers: */
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ class RageSoundManager
|
|||||||
/* Set of sounds that are finished and should be deleted. */
|
/* Set of sounds that are finished and should be deleted. */
|
||||||
set<RageSound *> sounds_to_delete;
|
set<RageSound *> sounds_to_delete;
|
||||||
|
|
||||||
|
set<RageSound *> playing_sounds;
|
||||||
|
|
||||||
struct FakeSound {
|
struct FakeSound {
|
||||||
float begin;
|
float begin;
|
||||||
int samples_read;
|
int samples_read;
|
||||||
@@ -43,10 +45,11 @@ public:
|
|||||||
float GetPlayLatency() const;
|
float GetPlayLatency() const;
|
||||||
|
|
||||||
void PlayOnce( CString sPath );
|
void PlayOnce( CString sPath );
|
||||||
void PlayOnceFromDir( CString sDir );
|
static void PlayOnceFromDir( CString sDir );
|
||||||
void PlayCopy( const RageSound &snd );
|
|
||||||
|
|
||||||
|
|
||||||
|
RageSound *PlaySound(RageSound &snd);
|
||||||
|
void StopPlayingSound(RageSound &snd);
|
||||||
|
void GetCopies(RageSound &snd, vector<RageSound *> &snds);
|
||||||
/* A list of all sounds that currently exist. RageSound adds and removes
|
/* A list of all sounds that currently exist. RageSound adds and removes
|
||||||
* itself to this. */
|
* itself to this. */
|
||||||
set<RageSound *> all_sounds;
|
set<RageSound *> all_sounds;
|
||||||
|
|||||||
@@ -1005,7 +1005,8 @@ void ScreenGameplay::Input( const DeviceInput& DeviceI, const InputEventType typ
|
|||||||
* of the song while we tween out, which looks really strange.
|
* of the song while we tween out, which looks really strange.
|
||||||
* -glenn
|
* -glenn
|
||||||
*/
|
*/
|
||||||
m_soundMusic.Pause();
|
/* but with the new sound code, Stop leaves the position alone -glenn (XXX remove this comment) */
|
||||||
|
m_soundMusic.Stop();
|
||||||
|
|
||||||
this->ClearMessageQueue();
|
this->ClearMessageQueue();
|
||||||
m_Fade.CloseWipingLeft( SM_SaveChangedBeforeGoingBack );
|
m_Fade.CloseWipingLeft( SM_SaveChangedBeforeGoingBack );
|
||||||
@@ -1414,7 +1415,7 @@ void ScreenGameplay::HandleScreenMessage( const ScreenMessage SM )
|
|||||||
|
|
||||||
case SM_BeginFailed:
|
case SM_BeginFailed:
|
||||||
m_DancingState = STATE_OUTRO;
|
m_DancingState = STATE_OUTRO;
|
||||||
m_soundMusic.Pause();
|
m_soundMusic.Stop();
|
||||||
m_StarWipe.SetTransitionTime( 1.5f );
|
m_StarWipe.SetTransitionTime( 1.5f );
|
||||||
m_StarWipe.CloseWipingRight( SM_None );
|
m_StarWipe.CloseWipingRight( SM_None );
|
||||||
int p;
|
int p;
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
ScreenSandbox::ScreenSandbox()
|
ScreenSandbox::ScreenSandbox()
|
||||||
{
|
{
|
||||||
|
MUSIC->Stop();
|
||||||
// m_quad.StretchTo( RectI(SCREEN_LEFT, SCREEN_TOP, SCREEN_RIGHT, SCREEN_BOTTOM) );
|
// m_quad.StretchTo( RectI(SCREEN_LEFT, SCREEN_TOP, SCREEN_RIGHT, SCREEN_BOTTOM) );
|
||||||
// m_quad.SetDiffuse( RageColor(1,1,1,1) );
|
// m_quad.SetDiffuse( RageColor(1,1,1,1) );
|
||||||
// this->AddChild( &m_quad );
|
// this->AddChild( &m_quad );
|
||||||
@@ -52,8 +53,7 @@ ScreenSandbox::ScreenSandbox()
|
|||||||
"p Play\n"
|
"p Play\n"
|
||||||
"s Stop\n"
|
"s Stop\n"
|
||||||
"l Toggle looping\n"
|
"l Toggle looping\n"
|
||||||
"a Toggle autostop\n"
|
"a Toggle autostop\n");
|
||||||
"f Fire sound in the background");
|
|
||||||
|
|
||||||
for(int i = 0; i < nsounds; ++i)
|
for(int i = 0; i < nsounds; ++i)
|
||||||
{
|
{
|
||||||
@@ -65,14 +65,21 @@ ScreenSandbox::ScreenSandbox()
|
|||||||
s[0].txt.SetXY(150, 100);
|
s[0].txt.SetXY(150, 100);
|
||||||
s[1].txt.SetXY(450, 100);
|
s[1].txt.SetXY(450, 100);
|
||||||
s[2].txt.SetXY(150, 250);
|
s[2].txt.SetXY(150, 250);
|
||||||
s[3].txt.SetXY(450, 250);
|
// s[3].txt.SetXY(450, 250);
|
||||||
s[4].txt.SetXY(150, 400);
|
// s[4].txt.SetXY(150, 400);
|
||||||
|
|
||||||
s[0].s.Load("Themes/default/Sounds/_common menu music.ogg");
|
s[0].s.Load("Themes/default/Sounds/_common menu music.ogg");
|
||||||
s[1].s.Load("Themes/default/Sounds/music scroll music.ogg");
|
s[1].s.Load("Themes/default/Sounds/music scroll music.ogg");
|
||||||
s[2].s.Load("Themes/default/Sounds/evaluation extra stage.mp3");
|
s[2].s.Load("Themes/default/Sounds/evaluation extra stage.mp3");
|
||||||
s[3].s.Load("Themes/default/Sounds/gameplay oni die.mp3");
|
// s[3].s.Load("Themes/default/Sounds/gameplay oni die.mp3");
|
||||||
s[4].s.Load("Themes/default/Sounds/gameplay toasty.mp3");
|
// s[4].s.Load("Themes/default/Sounds/gameplay toasty.mp3");
|
||||||
|
|
||||||
|
/*s[0].s.SetPositionSeconds(3);
|
||||||
|
s[0].s.SetStartSeconds(3);
|
||||||
|
s[0].s.SetLengthSeconds(1);
|
||||||
|
s[0].s.SetAutoStop(false);
|
||||||
|
s[0].s.Play();
|
||||||
|
*/
|
||||||
selected = 0;
|
selected = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,19 +91,30 @@ void ScreenSandbox::UpdateText(int n)
|
|||||||
unsigned x = fn.find_last_of("/\\");
|
unsigned x = fn.find_last_of("/\\");
|
||||||
if(x != fn.npos) fn.erase(0, x+1);
|
if(x != fn.npos) fn.erase(0, x+1);
|
||||||
|
|
||||||
|
vector<RageSound *> snds;
|
||||||
|
SOUNDMAN->GetCopies(s[n].s, snds);
|
||||||
|
|
||||||
|
CString pos;
|
||||||
|
for(unsigned p = 0; p < snds.size(); ++p)
|
||||||
|
{
|
||||||
|
if(p) pos += ", ";
|
||||||
|
pos += ssprintf("%.3f", snds[p]->GetPositionSeconds());
|
||||||
|
}
|
||||||
|
|
||||||
s[n].txt.SetText(ssprintf(
|
s[n].txt.SetText(ssprintf(
|
||||||
"%i: %s\n"
|
"%i: %s\n"
|
||||||
"%s\n"
|
"%s\n"
|
||||||
"%s\n"
|
"%s\n"
|
||||||
"%s\n"
|
"%s\n"
|
||||||
"%.3f of %.3f\n"
|
"(%s) of %.3f\n"
|
||||||
"%s\n"
|
"%s\n"
|
||||||
"%s",
|
"%s",
|
||||||
n+1, fn.GetString(),
|
n+1, fn.GetString(),
|
||||||
s[n].s.IsPlaying()? "Playing":"Stopped",
|
s[n].s.IsPlaying()? "Playing":"Stopped",
|
||||||
s[n].s.GetLooping()? "Looping": "Not looping",
|
s[n].s.GetLooping()? "Looping": "Not looping",
|
||||||
s[n].s.GetAutoStop()? "Stop when finished": "Continue until stopped",
|
s[n].s.GetAutoStop()? "Stop when finished": "Continue until stopped",
|
||||||
s[n].s.GetPositionSeconds(), s[n].s.GetLengthSeconds(),
|
pos.size()? pos.GetString(): "none playing",
|
||||||
|
s[n].s.GetLengthSeconds(),
|
||||||
s[n].s.IsStreaming()? "Streaming":"Preloaded",
|
s[n].s.IsStreaming()? "Streaming":"Preloaded",
|
||||||
selected == n? "^^^^^^":""
|
selected == n? "^^^^^^":""
|
||||||
));
|
));
|
||||||
@@ -135,9 +153,6 @@ void ScreenSandbox::Input( const DeviceInput& DeviceI, const InputEventType type
|
|||||||
case 'a':
|
case 'a':
|
||||||
s[selected].s.SetAutoStop(!s[selected].s.GetAutoStop());
|
s[selected].s.SetAutoStop(!s[selected].s.GetAutoStop());
|
||||||
break;
|
break;
|
||||||
case 'f':
|
|
||||||
SOUNDMAN->PlayCopy(s[selected].s);
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* case SDLK_LEFT:
|
/* case SDLK_LEFT:
|
||||||
obj.SetX(obj.GetX() - 10);
|
obj.SetX(obj.GetX() - 10);
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
#include "RageSound.h"
|
#include "RageSound.h"
|
||||||
#include "Sample3dObject.h"
|
#include "Sample3dObject.h"
|
||||||
|
|
||||||
const int nsounds = 5;
|
const int nsounds = 3;
|
||||||
|
|
||||||
class ScreenSandbox : public Screen
|
class ScreenSandbox : public Screen
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -24,8 +24,7 @@ protected:
|
|||||||
|
|
||||||
/* When a sound is finished playing (GetPCM returns less than requested) and
|
/* When a sound is finished playing (GetPCM returns less than requested) and
|
||||||
* the sound has been completely flushed (so GetPosition is no longer meaningful),
|
* the sound has been completely flushed (so GetPosition is no longer meaningful),
|
||||||
* call RageSound::SoundStopped(). Do *not* call this when StopMixing is
|
* call RageSound::StopPlaying(). Do *not* call it when StopMixing is called. */
|
||||||
* called. */
|
|
||||||
|
|
||||||
/* Optional, if needed: */
|
/* Optional, if needed: */
|
||||||
virtual void Update(float delta) { }
|
virtual void Update(float delta) { }
|
||||||
|
|||||||
@@ -75,12 +75,13 @@ void RageSound_DSound::Update(float delta)
|
|||||||
{
|
{
|
||||||
if(str[i]->state != str[i]->STOPPING) continue;
|
if(str[i]->state != str[i]->STOPPING) continue;
|
||||||
|
|
||||||
if(str[i]->str_ds->GetPosition() < str[i]->flush_pos)
|
int ps = str[i]->str_ds->GetPosition();
|
||||||
|
if(ps < str[i]->flush_pos)
|
||||||
continue; /* stopping but still flushing */
|
continue; /* stopping but still flushing */
|
||||||
|
|
||||||
/* The sound has stopped and flushed all of its buffers. */
|
/* The sound has stopped and flushed all of its buffers. */
|
||||||
if(str[i]->snd != NULL)
|
if(str[i]->snd != NULL)
|
||||||
str[i]->snd->SoundStopped();
|
str[i]->snd->StopPlaying();
|
||||||
str[i]->snd = NULL;
|
str[i]->snd = NULL;
|
||||||
|
|
||||||
str[i]->str_ds->Stop();
|
str[i]->str_ds->Stop();
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ void RageSound_DSound_Software::Update(float delta)
|
|||||||
continue; /* stopping but still flushing */
|
continue; /* stopping but still flushing */
|
||||||
|
|
||||||
/* This sound is done. */
|
/* This sound is done. */
|
||||||
snds[i]->snd->SoundStopped();
|
snds[i]->snd->StopPlaying();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ void RageSound_WaveOut::Update(float delta)
|
|||||||
continue; /* stopping but still flushing */
|
continue; /* stopping but still flushing */
|
||||||
|
|
||||||
/* This sound is done. */
|
/* This sound is done. */
|
||||||
snds[i]->snd->SoundStopped();
|
snds[i]->snd->StopPlaying();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user