Working THP audio and deinterlacing

This commit is contained in:
Jack Andersen 2016-03-07 21:10:52 -10:00
parent 718bf6151e
commit 9a43c518f9
7 changed files with 115 additions and 24 deletions

View File

@ -30,7 +30,8 @@ void ViewManager::BuildTestPART(urde::IObjectStore& objStore)
m_lineRenderer.reset(new urde::CLineRenderer(urde::CLineRenderer::EPrimitiveMode::LineStrip, 4, nullptr, true)); m_lineRenderer.reset(new urde::CLineRenderer(urde::CLineRenderer::EPrimitiveMode::LineStrip, 4, nullptr, true));
*/ */
m_particleView.reset(new ParticleView(*this, m_viewResources, *m_rootView)); m_particleView.reset(new ParticleView(*this, m_viewResources, *m_rootView));
m_moviePlayer.reset(new CMoviePlayer("Video/00_first_start.thp", -1.f, true, false)); m_moviePlayer.reset(new CMoviePlayer("Video/SpecialEnding.thp", -1.f, true, true));
m_videoVoice->start();
//m_rootView->accessContentViews().clear(); //m_rootView->accessContentViews().clear();
m_rootView->accessContentViews().push_back(m_particleView.get()); m_rootView->accessContentViews().push_back(m_particleView.get());
@ -147,7 +148,7 @@ void ViewManager::DismissSplash()
ViewManager::ViewManager(hecl::Runtime::FileStoreManager& fileMgr, hecl::CVarManager& cvarMgr) ViewManager::ViewManager(hecl::Runtime::FileStoreManager& fileMgr, hecl::CVarManager& cvarMgr)
: m_fileStoreManager(fileMgr), m_cvarManager(cvarMgr), m_projManager(*this), : m_fileStoreManager(fileMgr), m_cvarManager(cvarMgr), m_projManager(*this),
m_fontCache(fileMgr), m_translator(urde::SystemLocaleOrEnglish()), m_fontCache(fileMgr), m_translator(urde::SystemLocaleOrEnglish()), m_voiceCallback(*this),
m_recentProjectsPath(hecl::SysFormat(_S("%s/recent_projects.txt"), fileMgr.getStoreRoot().c_str())), m_recentProjectsPath(hecl::SysFormat(_S("%s/recent_projects.txt"), fileMgr.getStoreRoot().c_str())),
m_recentFilesPath(hecl::SysFormat(_S("%s/recent_files.txt"), fileMgr.getStoreRoot().c_str())) m_recentFilesPath(hecl::SysFormat(_S("%s/recent_files.txt"), fileMgr.getStoreRoot().c_str()))
{ {
@ -238,6 +239,11 @@ void ViewManager::init(boo::IApplication* app)
m_mainWindow->setWaitCursor(false); m_mainWindow->setWaitCursor(false);
m_voiceAllocator = boo::NewAudioVoiceAllocator();
boo::AudioChannelSet audioSet = m_voiceAllocator->getAvailableSet();
m_stereoMatrix.setAudioChannelSet(audioSet);
m_stereoMatrix.setDefaultMatrixCoefficients();
m_videoVoice = m_voiceAllocator->allocateNewVoice(audioSet, 32000, &m_voiceCallback);
CGraphics::InitializeBoo(gf, m_mainWindow->getCommandQueue(), root->renderTex()); CGraphics::InitializeBoo(gf, m_mainWindow->getCommandQueue(), root->renderTex());
CElementGen::Initialize(); CElementGen::Initialize();
CMoviePlayer::Initialize(); CMoviePlayer::Initialize();
@ -286,6 +292,7 @@ bool ViewManager::proc()
m_rootView->draw(gfxQ); m_rootView->draw(gfxQ);
CGraphics::EndScene(); CGraphics::EndScene();
gfxQ->execute(); gfxQ->execute();
m_voiceAllocator->pumpVoices();
m_mainWindow->waitForRetrace(); m_mainWindow->waitForRetrace();
return true; return true;
@ -293,6 +300,7 @@ bool ViewManager::proc()
void ViewManager::stop() void ViewManager::stop()
{ {
m_videoVoice.reset();
CElementGen::Shutdown(); CElementGen::Shutdown();
CMoviePlayer::Shutdown(); CMoviePlayer::Shutdown();
CLineRenderer::Shutdown(); CLineRenderer::Shutdown();

View File

@ -1,7 +1,9 @@
#ifndef URDE_VIEW_MANAGER_HPP #ifndef URDE_VIEW_MANAGER_HPP
#define URDE_VIEW_MANAGER_HPP #define URDE_VIEW_MANAGER_HPP
#include <hecl/CVarManager.hpp> #include "hecl/CVarManager.hpp"
#include "boo/audiodev/IAudioVoiceAllocator.hpp"
#include "boo/audiodev/AudioMatrix.hpp"
#include "ProjectManager.hpp" #include "ProjectManager.hpp"
#include "Space.hpp" #include "Space.hpp"
@ -49,6 +51,23 @@ class ViewManager : public specter::IViewManager
std::unique_ptr<urde::CElementGen> m_partGen; std::unique_ptr<urde::CElementGen> m_partGen;
std::unique_ptr<urde::CLineRenderer> m_lineRenderer; std::unique_ptr<urde::CLineRenderer> m_lineRenderer;
std::unique_ptr<urde::CMoviePlayer> m_moviePlayer; std::unique_ptr<urde::CMoviePlayer> m_moviePlayer;
std::unique_ptr<boo::IAudioVoiceAllocator> m_voiceAllocator;
std::unique_ptr<boo::IAudioVoice> m_videoVoice;
boo::AudioMatrixStereo m_stereoMatrix;
struct AudioVoiceCallback : boo::IAudioVoiceCallback
{
ViewManager& m_vm;
std::vector<s16> m_stereoBuf;
void needsNextBuffer(boo::IAudioVoice& voice, size_t frames)
{
m_stereoBuf.clear();
m_stereoBuf.resize(frames * 2);
if (m_vm.m_moviePlayer)
m_vm.m_moviePlayer->MixAudio(m_stereoBuf.data(), nullptr, frames);
m_vm.m_stereoMatrix.bufferStereoSampleData(voice, m_stereoBuf.data(), frames);
}
AudioVoiceCallback(ViewManager& vm) : m_vm(vm) {}
} m_voiceCallback;
hecl::SystemString m_recentProjectsPath; hecl::SystemString m_recentProjectsPath;
std::vector<hecl::SystemString> m_recentProjects; std::vector<hecl::SystemString> m_recentProjects;

View File

@ -2,13 +2,6 @@
static const int NibbleToInt[16] = {0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1}; static const int NibbleToInt[16] = {0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1};
static inline short SampClamp(int val)
{
if (val < -32768) val = -32768;
if (val > 32767) val = 32767;
return val;
}
void DSPDecompressFrame(int16_t* out, const uint8_t* in, void DSPDecompressFrame(int16_t* out, const uint8_t* in,
const int16_t coefs[8][2], int16_t* prev1, int16_t* prev2, const int16_t coefs[8][2], int16_t* prev1, int16_t* prev2,
unsigned lastSample) unsigned lastSample)
@ -29,7 +22,7 @@ void DSPDecompressFrame(int16_t* out, const uint8_t* in,
factor1 * *prev1 + factor1 * *prev1 +
factor2 * *prev2; factor2 * *prev2;
sampleData >>= 11; sampleData >>= 11;
sampleData = SampClamp(sampleData); sampleData = DSPSampClamp(sampleData);
out[s] = sampleData; out[s] = sampleData;
*prev2 = *prev1; *prev2 = *prev1;
*prev1 = sampleData; *prev1 = sampleData;
@ -56,7 +49,7 @@ void DSPDecompressFrameStereoStride(int16_t* out, const uint8_t* in,
factor1 * *prev1 + factor1 * *prev1 +
factor2 * *prev2; factor2 * *prev2;
sampleData >>= 11; sampleData >>= 11;
sampleData = SampClamp(sampleData); sampleData = DSPSampClamp(sampleData);
out[s*2] = sampleData; out[s*2] = sampleData;
*prev2 = *prev1; *prev2 = *prev1;
*prev1 = sampleData; *prev1 = sampleData;
@ -83,7 +76,7 @@ void DSPDecompressFrameStereoDupe(int16_t* out, const uint8_t* in,
factor1 * *prev1 + factor1 * *prev1 +
factor2 * *prev2; factor2 * *prev2;
sampleData >>= 11; sampleData >>= 11;
sampleData = SampClamp(sampleData); sampleData = DSPSampClamp(sampleData);
out[s*2] = sampleData; out[s*2] = sampleData;
out[s*2+1] = sampleData; out[s*2+1] = sampleData;
*prev2 = *prev1; *prev2 = *prev1;

View File

@ -7,6 +7,13 @@ extern "C" {
#include <stdint.h> #include <stdint.h>
static inline short DSPSampClamp(int val)
{
if (val < -32768) val = -32768;
if (val > 32767) val = 32767;
return val;
}
void DSPDecompressFrame(int16_t* out, const uint8_t* in, void DSPDecompressFrame(int16_t* out, const uint8_t* in,
const int16_t coefs[8][2], int16_t* prev1, int16_t* prev2, const int16_t coefs[8][2], int16_t* prev1, int16_t* prev2,
unsigned lastSample); unsigned lastSample);

View File

@ -462,10 +462,70 @@ void CMoviePlayer::SetStaticAudioVolume(int vol)
void CMoviePlayer::SetStaticAudio(const void* data, u32 length, u32 loopStart, u32 loopEnd) void CMoviePlayer::SetStaticAudio(const void* data, u32 length, u32 loopStart, u32 loopEnd)
{ {
} }
void CMoviePlayer::MixAudio(short* out, const short* in, u32 length)
void CMoviePlayer::MixAudio(s16* out, const s16* in, u32 samples)
{ {
if (xd4_audioSlot == -1)
{
if (in)
memcpy(out, in, samples * 4);
else
memset(out, 0, samples * 4);
return;
}
while (samples)
{
CTHPTextureSet* tex = &x80_textures[xd4_audioSlot];
u32 thisSamples = std::min(tex->audioSamples - tex->playedSamples, samples);
if (!thisSamples)
{
++xd4_audioSlot;
if (xd4_audioSlot >= x80_textures.size())
xd4_audioSlot = 0;
tex = &x80_textures[xd4_audioSlot];
thisSamples = std::min(tex->audioSamples - tex->playedSamples, samples);
}
if (thisSamples)
{
if (in)
{
for (u32 i=0 ; i<thisSamples ; ++i)
{
out[0] = DSPSampClamp(in[0] +
s16(s32(tex->audioBuf.get()[(i+tex->playedSamples)*2]) * 0x50F4 / 0x8000));
out[1] = DSPSampClamp(in[1] +
s16(s32(tex->audioBuf.get()[(i+tex->playedSamples)*2+1]) * 0x50F4 / 0x8000));
out += 2;
in += 2;
}
}
else
{
for (u32 i=0 ; i<thisSamples ; ++i)
{
out[0] = DSPSampClamp(
s16(s32(tex->audioBuf.get()[(i+tex->playedSamples)*2]) * 0x50F4 / 0x8000));
out[1] = DSPSampClamp(
s16(s32(tex->audioBuf.get()[(i+tex->playedSamples)*2+1]) * 0x50F4 / 0x8000));
out += 2;
}
}
tex->playedSamples += thisSamples;
samples -= thisSamples;
}
else
{
if (in)
memcpy(out, in, samples * 4);
else
memset(out, 0, samples * 4);
return;
}
}
} }
void CMoviePlayer::MixStaticAudio(short* out, const short* in, u32 length)
void CMoviePlayer::MixStaticAudio(short* out, const short* in, u32 samples)
{ {
} }
void CMoviePlayer::StaticMyAudioCallback() void CMoviePlayer::StaticMyAudioCallback()
@ -489,7 +549,7 @@ void CMoviePlayer::Rewind()
xc8_curFrame = 0; xc8_curFrame = 0;
xcc_decodedTexSlot = 0; xcc_decodedTexSlot = 0;
xd0_drawTexSlot = -1; xd0_drawTexSlot = -1;
xd4_ = -1; xd4_audioSlot = -1;
xd8_decodedTexCount = 0; xd8_decodedTexCount = 0;
xdc_frameRem = 0.f; xdc_frameRem = 0.f;
xe8_curSeconds = 0.f; xe8_curSeconds = 0.f;
@ -510,7 +570,8 @@ void CMoviePlayer::DrawFrame()
if (xd0_drawTexSlot == -1) if (xd0_drawTexSlot == -1)
return; return;
CTHPTextureSet& tex = x80_textures[xd0_drawTexSlot]; CTHPTextureSet& tex = x80_textures[xd0_drawTexSlot];
CGraphics::g_BooMainCommandQueue->setShaderDataBinding(tex.binding[m_deinterlace ? xf4_26_fieldFlip : 0]); CGraphics::g_BooMainCommandQueue->setShaderDataBinding
(tex.binding[m_deinterlace ? (xfc_fieldIndex != 0) : 0]);
CGraphics::g_BooMainCommandQueue->draw(0, 4); CGraphics::g_BooMainCommandQueue->draw(0, 4);
if (!xfc_fieldIndex && CGraphics::g_LastFrameUsedAbove) if (!xfc_fieldIndex && CGraphics::g_LastFrameUsedAbove)
xf4_26_fieldFlip = true; xf4_26_fieldFlip = true;
@ -593,8 +654,8 @@ void CMoviePlayer::Update(float dt)
++xd0_drawTexSlot; ++xd0_drawTexSlot;
if (xd0_drawTexSlot >= x80_textures.size()) if (xd0_drawTexSlot >= x80_textures.size())
xd0_drawTexSlot = 0; xd0_drawTexSlot = 0;
if (xd4_ == -1) if (xd4_audioSlot == -1)
xd4_ = 0; xd4_audioSlot = 0;
--xd8_decodedTexCount; --xd8_decodedTexCount;
++xc8_curFrame; ++xc8_curFrame;
if (xc8_curFrame == x28_thpHead.numFrames && xf4_24_loop) if (xc8_curFrame == x28_thpHead.numFrames && xf4_24_loop)
@ -668,7 +729,8 @@ void CMoviePlayer::DecodeFromRead(const void* data)
break; break;
} }
case THPComponents::Type::Audio: case THPComponents::Type::Audio:
THPAudioDecode(tex.audioBuf.get(), (u8*)inptr, x74_audioInfo.numChannels == 2); tex.audioSamples = THPAudioDecode(tex.audioBuf.get(), (u8*)inptr, x74_audioInfo.numChannels == 2);
tex.playedSamples = 0;
inptr += frameHeader.audioSize; inptr += frameHeader.audioSize;
break; break;
default: break; default: break;

View File

@ -86,6 +86,8 @@ private:
boo::ITextureD* Y[2] = {}; boo::ITextureD* Y[2] = {};
boo::ITextureD* U = nullptr; boo::ITextureD* U = nullptr;
boo::ITextureD* V = nullptr; boo::ITextureD* V = nullptr;
u32 playedSamples = 0;
u32 audioSamples = 0;
std::unique_ptr<s16[]> audioBuf; std::unique_ptr<s16[]> audioBuf;
boo::IShaderDataBinding* binding[2] = {}; boo::IShaderDataBinding* binding[2] = {};
}; };
@ -103,7 +105,7 @@ private:
u32 xc8_curFrame = 0; u32 xc8_curFrame = 0;
u32 xcc_decodedTexSlot = 0; u32 xcc_decodedTexSlot = 0;
u32 xd0_drawTexSlot = -1; u32 xd0_drawTexSlot = -1;
u32 xd4_ = -1; u32 xd4_audioSlot = -1;
s32 xd8_decodedTexCount = 0; s32 xd8_decodedTexCount = 0;
float xdc_frameRem = 0.f; float xdc_frameRem = 0.f;
EPlayMode xe0_playMode = EPlayMode::Playing; EPlayMode xe0_playMode = EPlayMode::Playing;
@ -142,8 +144,8 @@ public:
static void DisableStaticAudio(); static void DisableStaticAudio();
static void SetStaticAudioVolume(int vol); static void SetStaticAudioVolume(int vol);
static void SetStaticAudio(const void* data, u32 length, u32 loopStart, u32 loopEnd); static void SetStaticAudio(const void* data, u32 length, u32 loopStart, u32 loopEnd);
void MixAudio(short* out, const short* in, u32 length); void MixAudio(s16* out, const s16* in, u32 samples);
static void MixStaticAudio(short* out, const short* in, u32 length); static void MixStaticAudio(short* out, const short* in, u32 samples);
static void StaticMyAudioCallback(); static void StaticMyAudioCallback();
void Rewind(); void Rewind();

2
hecl

@ -1 +1 @@
Subproject commit f1f3bb641d52a584011bfe2113a797833421ba92 Subproject commit 0e0e454adec26503b896e3cb2f02195b3516c4a0