mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-03-10 11:11: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
|
class MvePlayer : public MoviePlayer
|
||||||
{
|
{
|
||||||
InterplayDecoder decoder;
|
InterplayDecoder decoder;
|
||||||
SoundStream* stream = nullptr;
|
MovieAudioTrack audioTrack;
|
||||||
bool failed = false;
|
bool failed = false;
|
||||||
|
|
||||||
bool StreamCallback(SoundStream *stream, void *buff, int len)
|
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);
|
return decoder.FillSamples(buff, len);
|
||||||
}
|
}
|
||||||
static bool StreamCallbackC(SoundStream *stream, void *buff, int len, void *userdata)
|
static bool StreamCallbackC(SoundStream *stream, void *buff, int len, void *userdata)
|
||||||
|
@ -288,15 +332,15 @@ public:
|
||||||
{
|
{
|
||||||
if (failed) return false;
|
if (failed) return false;
|
||||||
|
|
||||||
|
audioTrack.SetClock(clock);
|
||||||
bool playon = decoder.RunFrame(clock);
|
bool playon = decoder.RunFrame(clock);
|
||||||
if (playon)
|
if (playon)
|
||||||
{
|
{
|
||||||
if (!stream && decoder.HasAudio())
|
if (!audioTrack.GetAudioStream() && decoder.HasAudio())
|
||||||
{
|
{
|
||||||
S_StopMusic(true);
|
S_StopMusic(true);
|
||||||
// start audio playback
|
// start audio playback
|
||||||
stream = S_CreateCustomStream(6000, decoder.GetSampleRate(), decoder.NumChannels(), MusicSamples16bit, StreamCallbackC, this);
|
if (!audioTrack.Start(decoder.GetSampleRate(), decoder.NumChannels(), MusicSamples16bit, StreamCallbackC, this))
|
||||||
if (!stream)
|
|
||||||
decoder.DisableAudio();
|
decoder.DisableAudio();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -306,9 +350,7 @@ public:
|
||||||
|
|
||||||
~MvePlayer()
|
~MvePlayer()
|
||||||
{
|
{
|
||||||
if (stream)
|
audioTrack.Finish();
|
||||||
S_StopCustomStream(stream);
|
|
||||||
stream = nullptr;
|
|
||||||
|
|
||||||
decoder.Close();
|
decoder.Close();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue