mirror of https://github.com/AxioDL/metaforce.git
Working THP audio and deinterlacing
This commit is contained in:
parent
718bf6151e
commit
9a43c518f9
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
2
hecl
|
@ -1 +1 @@
|
||||||
Subproject commit f1f3bb641d52a584011bfe2113a797833421ba92
|
Subproject commit 0e0e454adec26503b896e3cb2f02195b3516c4a0
|
Loading…
Reference in New Issue