mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 14:51:51 +00:00
Play the VPX "soundtrack" as a SoundStream
This commit is contained in:
parent
94b249172a
commit
c808aad595
4 changed files with 59 additions and 8 deletions
|
@ -117,10 +117,11 @@ int MusicEnabled() // int return is for scripting
|
||||||
static std::unique_ptr<SoundStream> musicStream;
|
static std::unique_ptr<SoundStream> musicStream;
|
||||||
static TArray<SoundStream*> customStreams;
|
static TArray<SoundStream*> customStreams;
|
||||||
|
|
||||||
SoundStream *S_CreateCustomStream(size_t size, int samplerate, int numchannels, StreamCallback cb, void *userdata)
|
SoundStream *S_CreateCustomStream(size_t size, int samplerate, int numchannels, MusicCustomStreamType sampletype, StreamCallback cb, void *userdata)
|
||||||
{
|
{
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
if (numchannels < 2) flags |= SoundStream::Mono;
|
if (numchannels < 2) flags |= SoundStream::Mono;
|
||||||
|
if (sampletype == MusicSamplesFloat) flags |= SoundStream::Float;
|
||||||
auto stream = GSnd->CreateStream(cb, int(size), flags, samplerate, userdata);
|
auto stream = GSnd->CreateStream(cb, int(size), flags, samplerate, userdata);
|
||||||
if (stream)
|
if (stream)
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,9 +11,13 @@ class FileReader;
|
||||||
class SoundStream;
|
class SoundStream;
|
||||||
|
|
||||||
|
|
||||||
|
enum MusicCustomStreamType : bool {
|
||||||
|
MusicSamples16bit,
|
||||||
|
MusicSamplesFloat
|
||||||
|
};
|
||||||
int MusicEnabled();
|
int MusicEnabled();
|
||||||
typedef bool(*StreamCallback)(SoundStream* stream, void* buff, int len, void* userdata);
|
typedef bool(*StreamCallback)(SoundStream* stream, void* buff, int len, void* userdata);
|
||||||
SoundStream *S_CreateCustomStream(size_t size, int samplerate, int numchannels, StreamCallback cb, void *userdata);
|
SoundStream *S_CreateCustomStream(size_t size, int samplerate, int numchannels, MusicCustomStreamType sampletype, StreamCallback cb, void *userdata);
|
||||||
void S_StopCustomStream(SoundStream* stream);
|
void S_StopCustomStream(SoundStream* stream);
|
||||||
void S_PauseAllCustomStreams(bool on);
|
void S_PauseAllCustomStreams(bool on);
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,8 @@
|
||||||
#include "filesystem.h"
|
#include "filesystem.h"
|
||||||
#include "vm.h"
|
#include "vm.h"
|
||||||
#include "printf.h"
|
#include "printf.h"
|
||||||
|
#include <zmusic.h>
|
||||||
|
#include "filereadermusicinterface.h"
|
||||||
|
|
||||||
class MoviePlayer
|
class MoviePlayer
|
||||||
{
|
{
|
||||||
|
@ -221,6 +223,9 @@ class VpxPlayer : public MoviePlayer
|
||||||
AnimTextures animtex;
|
AnimTextures animtex;
|
||||||
const TArray<int> animSnd;
|
const TArray<int> animSnd;
|
||||||
|
|
||||||
|
ZMusic_MusicStream MusicStream = nullptr;
|
||||||
|
SoundStream *AudioStream = nullptr;
|
||||||
|
|
||||||
unsigned width, height;
|
unsigned width, height;
|
||||||
TArray<uint8_t> Pic;
|
TArray<uint8_t> Pic;
|
||||||
TArray<uint8_t> readBuf;
|
TArray<uint8_t> readBuf;
|
||||||
|
@ -240,6 +245,12 @@ class VpxPlayer : public MoviePlayer
|
||||||
public:
|
public:
|
||||||
int soundtrack = -1;
|
int soundtrack = -1;
|
||||||
|
|
||||||
|
bool StreamCallback(SoundStream*, void *buff, int len)
|
||||||
|
{
|
||||||
|
return ZMusic_FillStream(MusicStream, buff, len);
|
||||||
|
}
|
||||||
|
static bool StreamCallbackC(SoundStream *stream, void *buff, int len, void *userdata)
|
||||||
|
{ return static_cast<VpxPlayer*>(userdata)->StreamCallback(stream, buff, len); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool isvalid() { return !failed; }
|
bool isvalid() { return !failed; }
|
||||||
|
@ -405,9 +416,36 @@ public:
|
||||||
|
|
||||||
void Start() override
|
void Start() override
|
||||||
{
|
{
|
||||||
if (soundtrack > 0)
|
if (soundtrack >= 0 && !AudioStream)
|
||||||
{
|
{
|
||||||
S_ChangeMusic(fileSystem.GetFileFullName(soundtrack, false), 0, false);
|
S_StopMusic(true);
|
||||||
|
FileReader reader = fileSystem.OpenFileReader(soundtrack);
|
||||||
|
if (reader.isOpen())
|
||||||
|
{
|
||||||
|
MusicStream = ZMusic_OpenSong(GetMusicReader(reader), MDEV_DEFAULT, nullptr);
|
||||||
|
}
|
||||||
|
if (MusicStream)
|
||||||
|
{
|
||||||
|
SoundStreamInfo info{};
|
||||||
|
ZMusic_GetStreamInfo(MusicStream, &info);
|
||||||
|
// if mBufferSize == 0, the music stream is played externally (e.g.
|
||||||
|
// Windows' MIDI synth), which we can't keep synced. Play anyway?
|
||||||
|
if (info.mBufferSize > 0 && ZMusic_Start(MusicStream, 0, false))
|
||||||
|
{
|
||||||
|
AudioStream = S_CreateCustomStream(6000, info.mSampleRate, abs(info.mNumChannels),
|
||||||
|
(info.mNumChannels < 0) ? MusicSamples16bit : MusicSamplesFloat,
|
||||||
|
&StreamCallbackC, this);
|
||||||
|
}
|
||||||
|
if (!AudioStream)
|
||||||
|
{
|
||||||
|
ZMusic_Close(MusicStream);
|
||||||
|
MusicStream = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (AudioStream)
|
||||||
|
{
|
||||||
|
AudioStream->SetPaused(false);
|
||||||
}
|
}
|
||||||
animtex.SetSize(AnimTexture::YUV, width, height);
|
animtex.SetSize(AnimTexture::YUV, width, height);
|
||||||
}
|
}
|
||||||
|
@ -461,9 +499,12 @@ public:
|
||||||
return !stop;
|
return !stop;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Stop()
|
void Stop() override
|
||||||
{
|
{
|
||||||
S_StopMusic(true);
|
if (AudioStream)
|
||||||
|
{
|
||||||
|
AudioStream->SetPaused(true);
|
||||||
|
}
|
||||||
bool nostopsound = (flags & NOSOUNDCUTOFF);
|
bool nostopsound = (flags & NOSOUNDCUTOFF);
|
||||||
if (!nostopsound) soundEngine->StopAllChannels();
|
if (!nostopsound) soundEngine->StopAllChannels();
|
||||||
}
|
}
|
||||||
|
@ -472,6 +513,11 @@ public:
|
||||||
{
|
{
|
||||||
vpx_codec_destroy(&codec);
|
vpx_codec_destroy(&codec);
|
||||||
animtex.Clean();
|
animtex.Clean();
|
||||||
|
if(AudioStream)
|
||||||
|
{
|
||||||
|
S_StopCustomStream(AudioStream);
|
||||||
|
ZMusic_Close(MusicStream);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FTextureID GetTexture() override
|
FTextureID GetTexture() override
|
||||||
|
@ -618,7 +664,7 @@ public:
|
||||||
if (adata.inf.bitsPerSample == 8) copy8bitSamples(read);
|
if (adata.inf.bitsPerSample == 8) copy8bitSamples(read);
|
||||||
else copy16bitSamples(read);
|
else copy16bitSamples(read);
|
||||||
if (!stream && read) // the sound may not start in the first frame, but the stream cannot start without any sound data present.
|
if (!stream && read) // the sound may not start in the first frame, but the stream cannot start without any sound data present.
|
||||||
stream = S_CreateCustomStream(6000, adata.inf.sampleRate, adata.inf.nChannels, StreamCallbackFunc, this);
|
stream = S_CreateCustomStream(6000, adata.inf.sampleRate, adata.inf.nChannels, MusicSamples16bit, StreamCallbackFunc, this);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -291,7 +291,7 @@ bool InterplayDecoder::RunFrame(uint64_t clock)
|
||||||
if (!bAudioStarted)
|
if (!bAudioStarted)
|
||||||
{
|
{
|
||||||
// start audio playback
|
// start audio playback
|
||||||
stream = S_CreateCustomStream(6000, audio.nSampleRate, audio.nChannels, StreamCallbackFunc, this);
|
stream = S_CreateCustomStream(6000, audio.nSampleRate, audio.nChannels, MusicSamples16bit, StreamCallbackFunc, this);
|
||||||
bAudioStarted = true;
|
bAudioStarted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue