mirror of
https://github.com/ZDoom/raze-gles.git
synced 2025-01-28 18:00:40 +00:00
- added sound playback to the Smacker video player.
Thanks to Blood's weird setup and the resulting lack of sound support in NBlood's player I never realized that this is a fully featured movie format that actually has sound support. Now the soundtrack will play if present.
This commit is contained in:
parent
1a21e73cd9
commit
570897005c
1 changed files with 80 additions and 2 deletions
|
@ -486,13 +486,27 @@ public:
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
struct AudioData
|
||||||
|
{
|
||||||
|
int hFx;
|
||||||
|
SmackerAudioInfo inf;
|
||||||
|
|
||||||
|
int16_t samples[6000 * 20]; // must be a multiple of the stream buffer size and larger than the initial chunk of audio
|
||||||
|
|
||||||
|
int nWrite;
|
||||||
|
int nRead;
|
||||||
|
};
|
||||||
|
|
||||||
class DSmkPlayer : public DScreenJob
|
class DSmkPlayer : public DScreenJob
|
||||||
{
|
{
|
||||||
SmackerHandle hSMK{};
|
SmackerHandle hSMK{};
|
||||||
|
int numAudioTracks;
|
||||||
|
AudioData adata;
|
||||||
uint32_t nWidth, nHeight;
|
uint32_t nWidth, nHeight;
|
||||||
uint8_t palette[768];
|
uint8_t palette[768];
|
||||||
AnimTextures animtex;
|
AnimTextures animtex;
|
||||||
TArray<uint8_t> pFrame;
|
TArray<uint8_t> pFrame;
|
||||||
|
TArray<uint8_t> audioBuffer;
|
||||||
int nFrameRate;
|
int nFrameRate;
|
||||||
int nFrames;
|
int nFrames;
|
||||||
bool fullscreenScale;
|
bool fullscreenScale;
|
||||||
|
@ -500,10 +514,40 @@ class DSmkPlayer : public DScreenJob
|
||||||
int nFrame = 0;
|
int nFrame = 0;
|
||||||
const AnimSound* animSnd;
|
const AnimSound* animSnd;
|
||||||
FString filename;
|
FString filename;
|
||||||
|
SoundStream* stream = nullptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool isvalid() { return hSMK.isValid; }
|
bool isvalid() { return hSMK.isValid; }
|
||||||
|
|
||||||
|
static bool StreamCallbackFunc(SoundStream* stream, void* buff, int len, void* userdata)
|
||||||
|
{
|
||||||
|
DSmkPlayer* pId = (DSmkPlayer*)userdata;
|
||||||
|
memcpy(buff, &pId->adata.samples[pId->adata.nRead], len);
|
||||||
|
pId->adata.nRead += len / 2;
|
||||||
|
if (pId->adata.nRead >= countof(pId->adata.samples)) pId->adata.nRead = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void copy8bitSamples(unsigned count)
|
||||||
|
{
|
||||||
|
for (unsigned i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
adata.samples[adata.nWrite] = (audioBuffer[i] - 128) << 8;
|
||||||
|
if (++adata.nWrite >= countof(adata.samples)) adata.nWrite = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void copy16bitSamples(unsigned count)
|
||||||
|
{
|
||||||
|
auto ptr = (uint16_t*)audioBuffer.Data();
|
||||||
|
for (unsigned i = 0; i < count/2; i++)
|
||||||
|
{
|
||||||
|
adata.samples[adata.nWrite] = *ptr++;
|
||||||
|
if (++adata.nWrite >= countof(adata.samples)) adata.nWrite = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
DSmkPlayer(const char *fn, const AnimSound* ans, bool fixedviewport)
|
DSmkPlayer(const char *fn, const AnimSound* ans, bool fixedviewport)
|
||||||
{
|
{
|
||||||
hSMK = Smacker_Open(fn);
|
hSMK = Smacker_Open(fn);
|
||||||
|
@ -518,7 +562,30 @@ public:
|
||||||
nFrames = Smacker_GetNumFrames(hSMK);
|
nFrames = Smacker_GetNumFrames(hSMK);
|
||||||
Smacker_GetPalette(hSMK, palette);
|
Smacker_GetPalette(hSMK, palette);
|
||||||
fullscreenScale = (!fixedviewport || (nWidth <= 320 && nHeight <= 200) || nWidth >= 640 || nHeight >= 480);
|
fullscreenScale = (!fixedviewport || (nWidth <= 320 && nHeight <= 200) || nWidth >= 640 || nHeight >= 480);
|
||||||
animSnd = ans;
|
|
||||||
|
bool hassound = false;
|
||||||
|
numAudioTracks = Smacker_GetNumAudioTracks(hSMK);
|
||||||
|
if (numAudioTracks)
|
||||||
|
{
|
||||||
|
adata.nWrite = 0;
|
||||||
|
adata.nRead = 0;
|
||||||
|
adata.inf = Smacker_GetAudioTrackDetails(hSMK, 0);
|
||||||
|
if (adata.inf.idealBufferSize > 0)
|
||||||
|
{
|
||||||
|
audioBuffer.Resize(adata.inf.idealBufferSize);
|
||||||
|
auto read = Smacker_GetAudioData(hSMK, 0, (int16_t*)audioBuffer.Data());
|
||||||
|
if (adata.inf.bitsPerSample == 8) copy8bitSamples(read);
|
||||||
|
else copy16bitSamples(read);
|
||||||
|
animSnd = nullptr;
|
||||||
|
hassound = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!hassound)
|
||||||
|
{
|
||||||
|
adata.inf = {};
|
||||||
|
animSnd = ans;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
@ -541,6 +608,16 @@ public:
|
||||||
Smacker_GetPalette(hSMK, palette);
|
Smacker_GetPalette(hSMK, palette);
|
||||||
Smacker_GetFrame(hSMK, pFrame.Data());
|
Smacker_GetFrame(hSMK, pFrame.Data());
|
||||||
animtex.SetFrame(palette, pFrame.Data());
|
animtex.SetFrame(palette, pFrame.Data());
|
||||||
|
if (numAudioTracks)
|
||||||
|
{
|
||||||
|
auto read = Smacker_GetAudioData(hSMK, 0, (int16_t*)audioBuffer.Data());
|
||||||
|
if (adata.inf.bitsPerSample == 8) copy8bitSamples(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.
|
||||||
|
stream = S_CreateCustomStream(6000, adata.inf.sampleRate, adata.inf.nChannels, StreamCallbackFunc, this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if (fullscreenScale)
|
if (fullscreenScale)
|
||||||
{
|
{
|
||||||
|
@ -554,7 +631,7 @@ public:
|
||||||
{
|
{
|
||||||
nFrame++;
|
nFrame++;
|
||||||
Smacker_GetNextFrame(hSMK);
|
Smacker_GetNextFrame(hSMK);
|
||||||
for (int i = 0; animSnd[i].framenum >= 0; i++)
|
if (animSnd) for (int i = 0; animSnd[i].framenum >= 0; i++)
|
||||||
{
|
{
|
||||||
if (animSnd[i].framenum == nFrame)
|
if (animSnd[i].framenum == nFrame)
|
||||||
{
|
{
|
||||||
|
@ -573,6 +650,7 @@ public:
|
||||||
void OnDestroy() override
|
void OnDestroy() override
|
||||||
{
|
{
|
||||||
Smacker_Close(hSMK);
|
Smacker_Close(hSMK);
|
||||||
|
if (stream) S_StopCustomStream(stream);
|
||||||
soundEngine->StopAllChannels();
|
soundEngine->StopAllChannels();
|
||||||
animtex.Clean();
|
animtex.Clean();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue