start_time

This commit is contained in:
Glenn Maynard
2004-01-12 03:57:11 +00:00
parent d5eded488a
commit 071ec73a04
3 changed files with 35 additions and 5 deletions
@@ -66,25 +66,52 @@ bool RageSound_ALSA9::stream::GetData(bool init)
static Sint16 *buf = NULL;
if ( !buf )
buf = new Sint16[max_writeahead*samples_per_frame];
char *cbuf = (char*) buf;
unsigned len = frames_to_fill*bytes_per_frame;
const int play_pos = pcm->GetPlayPos();
const int cur_play_pos = pcm->GetPosition();
int len = frames_to_fill*bytes_per_frame;
/* It might be INACTIVE, when we're prebuffering. We just don't want to
* fill anything in STOPPING; in that case, we just clear the audio buffer. */
if( state != STOPPING )
{
const unsigned got = snd->GetPCM( (char *) buf, len, pcm->GetPlayPos() );
int bytes_read = 0;
int bytes_left = len;
if( got < len )
/* Does the sound have a start time? */
if( !start_time.IsZero() )
{
/* If the sound is supposed to start at a time past this buffer, insert silence. */
const int iFramesUntilThisBuffer = play_pos - cur_play_pos;
const float fSecondsBeforeStart = -start_time.Ago();
const int iFramesBeforeStart = int(fSecondsBeforeStart * pcm->GetSampleRate());
const int iSilentFramesInThisBuffer = iFramesBeforeStart-iFramesUntilThisBuffer;
const int iSilentBytesInThisBuffer = clamp( iSilentFramesInThisBuffer * bytes_per_frame, 0, bytes_left );
memset( cbuf+bytes_read, 0, iSilentBytesInThisBuffer );
bytes_read += iSilentBytesInThisBuffer;
bytes_left -= iSilentBytesInThisBuffer;
if( !iSilentBytesInThisBuffer )
start_time.SetZero();
}
int got = snd->GetPCM( cbuf+bytes_read, len-bytes_read, play_pos + (bytes_read/bytes_per_frame) );
bytes_read += got;
bytes_left -= got;
if( bytes_left > 0 )
{
/* Fill the remainder of the buffer with silence. */
memset( buf+got, 0, len-got );
memset( cbuf+bytes_read, 0, bytes_left );
/* STOPPING tells the mixer thread to release the stream once str->flush_bufs
* buffers have been flushed. */
state = STOPPING;
/* Flush two buffers worth of data. */
flush_pos = pcm->GetPlayPos();
flush_pos = pcm->GetPlayPos() + (bytes_read / bytes_per_frame);
}
} else {
/* Silence the buffer. */
@@ -121,6 +148,7 @@ void RageSound_ALSA9::StartMixing(RageSound *snd)
/* Give the stream to the playing sound and remove it from the pool. */
stream_pool[i]->snd = snd;
stream_pool[i]->pcm->SetSampleRate( snd->GetSampleRate() );
stream_pool[i]->start_time = snd->GetStartTime();
/* Pre-buffer the stream. */
stream_pool[i]->GetData(true);
@@ -18,6 +18,7 @@ private:
/* Sound object that's playing on this stream, or NULL if this
* channel is available: */
RageSound *snd;
RageTimer start_time;
enum {
INACTIVE,
@@ -13,6 +13,7 @@ private:
struct sound
{
RageSound *snd;
RageTimer start_time;
bool stopping;
int flush_pos; /* state == STOPPING only */
sound() { snd = NULL; stopping=false; }