Use a MovieAudioTrack for synchronized audio with MvePlayer

This commit is contained in:
Chris Robinson 2022-10-06 11:19:10 -07:00 committed by Christoph Oelckers
parent 573784b37f
commit bf2e7c210d
1 changed files with 49 additions and 7 deletions

View File

@ -260,11 +260,55 @@ public:
class MvePlayer : public MoviePlayer
{
InterplayDecoder decoder;
SoundStream* stream = nullptr;
MovieAudioTrack audioTrack;
bool failed = false;
bool StreamCallback(SoundStream *stream, void *buff, int len)
{
const double delay = audioTrack.GetClockDiff(stream);
const int samplerate = audioTrack.GetSampleRate();
const int framesize = audioTrack.GetFrameSize();
if(delay > 0.0)
{
// If diff > 0, skip samples. Don't skip more than a full update at once.
int skip = std::min(int(delay*samplerate)*framesize, len);
if(!decoder.FillSamples(buff, len))
return false;
// Offset the measured audio position to account for the skipped samples.
audioTrack.AdjustOffset(skip/framesize);
if(skip == len)
return decoder.FillSamples(buff, len);
memmove(buff, (char*)buff+skip, len-skip);
if(!decoder.FillSamples((char*)buff+len-skip, skip))
memset((char*)buff+len-skip, 0, skip);
return true;
}
if(delay < 0.0)
{
// If diff < 0, duplicate samples. Don't duplicate a full update (we need at
// least one new sample frame to duplicate).
int dup = std::min(int(-delay*samplerate)*framesize, len-framesize);
if(!decoder.FillSamples((char*)buff+dup, len-dup))
return false;
if(framesize == 1)
memset(buff, ((char*)buff)[dup], dup);
else
{
for(int i=0;i < dup;++i)
((char*)buff)[i] = ((char*)buff+dup)[i%framesize];
}
// Offset the measured audio position to account for the duplicated samples.
audioTrack.AdjustOffset(-dup/framesize);
return true;
}
return decoder.FillSamples(buff, len);
}
static bool StreamCallbackC(SoundStream *stream, void *buff, int len, void *userdata)
@ -288,15 +332,15 @@ public:
{
if (failed) return false;
audioTrack.SetClock(clock);
bool playon = decoder.RunFrame(clock);
if (playon)
{
if (!stream && decoder.HasAudio())
if (!audioTrack.GetAudioStream() && decoder.HasAudio())
{
S_StopMusic(true);
// start audio playback
stream = S_CreateCustomStream(6000, decoder.GetSampleRate(), decoder.NumChannels(), MusicSamples16bit, StreamCallbackC, this);
if (!stream)
if (!audioTrack.Start(decoder.GetSampleRate(), decoder.NumChannels(), MusicSamples16bit, StreamCallbackC, this))
decoder.DisableAudio();
}
}
@ -306,9 +350,7 @@ public:
~MvePlayer()
{
if (stream)
S_StopCustomStream(stream);
stream = nullptr;
audioTrack.Finish();
decoder.Close();
}