mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 14:51:51 +00:00
Use a MovieAudioTrack for synchronized audio with MvePlayer
This commit is contained in:
parent
573784b37f
commit
bf2e7c210d
1 changed files with 49 additions and 7 deletions
|
@ -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();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue