StreamADPCM: Turn the ADPCM decoder into a class

Migrates the state to be instance-based as opposed to being a flat
namespace. This keeps behavior localized to its own instantiable unit
(and forces uses of the class to also be localized, lest they cart around
an instance all over the place).
This commit is contained in:
Lioncash 2018-04-09 03:39:34 -04:00
parent 7bc1063d2a
commit 1b3dae918a
3 changed files with 32 additions and 26 deletions

View File

@ -207,6 +207,8 @@ static UDICR s_DICR;
static UDIIMMBUF s_DIIMMBUF; static UDIIMMBUF s_DIIMMBUF;
static UDICFG s_DICFG; static UDICFG s_DICFG;
static StreamADPCM::ADPCMDecoder s_adpcm_decoder;
// DTK // DTK
static bool s_stream = false; static bool s_stream = false;
static bool s_stop_at_track_end = false; static bool s_stop_at_track_end = false;
@ -286,7 +288,7 @@ void DoState(PointerWrap& p)
DVDThread::DoState(p); DVDThread::DoState(p);
StreamADPCM::DoState(p); s_adpcm_decoder.DoState(p);
} }
static size_t ProcessDTKSamples(std::vector<s16>* temp_pcm, const std::vector<u8>& audio_data) static size_t ProcessDTKSamples(std::vector<s16>* temp_pcm, const std::vector<u8>& audio_data)
@ -295,7 +297,7 @@ static size_t ProcessDTKSamples(std::vector<s16>* temp_pcm, const std::vector<u8
size_t bytes_processed = 0; size_t bytes_processed = 0;
while (samples_processed < temp_pcm->size() / 2 && bytes_processed < audio_data.size()) while (samples_processed < temp_pcm->size() / 2 && bytes_processed < audio_data.size())
{ {
StreamADPCM::DecodeBlock(&(*temp_pcm)[samples_processed * 2], &audio_data[bytes_processed]); s_adpcm_decoder.DecodeBlock(&(*temp_pcm)[samples_processed * 2], &audio_data[bytes_processed]);
for (size_t i = 0; i < StreamADPCM::SAMPLES_PER_BLOCK * 2; ++i) for (size_t i = 0; i < StreamADPCM::SAMPLES_PER_BLOCK * 2; ++i)
{ {
// TODO: Fix the mixer so it can accept non-byte-swapped samples. // TODO: Fix the mixer so it can accept non-byte-swapped samples.
@ -331,7 +333,7 @@ static u32 AdvanceDTK(u32 maximum_samples, u32* samples_to_process)
break; break;
} }
StreamADPCM::InitFilter(); s_adpcm_decoder.ResetFilter();
} }
s_audio_position += StreamADPCM::ONE_BLOCK_SIZE; s_audio_position += StreamADPCM::ONE_BLOCK_SIZE;
@ -933,7 +935,7 @@ void ExecuteCommand(u32 command_0, u32 command_1, u32 command_2, u32 output_addr
s_current_start = s_next_start; s_current_start = s_next_start;
s_current_length = s_next_length; s_current_length = s_next_length;
s_audio_position = s_current_start; s_audio_position = s_current_start;
StreamADPCM::InitFilter(); s_adpcm_decoder.ResetFilter();
s_stream = true; s_stream = true;
} }
} }

View File

@ -12,12 +12,6 @@
namespace StreamADPCM namespace StreamADPCM
{ {
// STATE_TO_SAVE
static s32 histl1;
static s32 histl2;
static s32 histr1;
static s32 histr2;
static s16 ADPDecodeSample(s32 bits, s32 q, s32& hist1, s32& hist2) static s16 ADPDecodeSample(s32 bits, s32 q, s32& hist1, s32& hist2)
{ {
s32 hist = 0; s32 hist = 0;
@ -49,30 +43,30 @@ static s16 ADPDecodeSample(s32 bits, s32 q, s32& hist1, s32& hist2)
return (s16)cur; return (s16)cur;
} }
void InitFilter() void ADPCMDecoder::ResetFilter()
{ {
histl1 = 0; m_histl1 = 0;
histl2 = 0; m_histl2 = 0;
histr1 = 0; m_histr1 = 0;
histr2 = 0; m_histr2 = 0;
} }
void DoState(PointerWrap& p) void ADPCMDecoder::DoState(PointerWrap& p)
{ {
p.Do(histl1); p.Do(m_histl1);
p.Do(histl2); p.Do(m_histl2);
p.Do(histr1); p.Do(m_histr1);
p.Do(histr2); p.Do(m_histr2);
} }
void DecodeBlock(s16* pcm, const u8* adpcm) void ADPCMDecoder::DecodeBlock(s16* pcm, const u8* adpcm)
{ {
for (int i = 0; i < SAMPLES_PER_BLOCK; i++) for (int i = 0; i < SAMPLES_PER_BLOCK; i++)
{ {
pcm[i * 2] = ADPDecodeSample(adpcm[i + (ONE_BLOCK_SIZE - SAMPLES_PER_BLOCK)] & 0xf, adpcm[0], pcm[i * 2] = ADPDecodeSample(adpcm[i + (ONE_BLOCK_SIZE - SAMPLES_PER_BLOCK)] & 0xf, adpcm[0],
histl1, histl2); m_histl1, m_histl2);
pcm[i * 2 + 1] = ADPDecodeSample(adpcm[i + (ONE_BLOCK_SIZE - SAMPLES_PER_BLOCK)] >> 4, adpcm[1], pcm[i * 2 + 1] = ADPDecodeSample(adpcm[i + (ONE_BLOCK_SIZE - SAMPLES_PER_BLOCK)] >> 4, adpcm[1],
histr1, histr2); m_histr1, m_histr2);
} }
} }
} }

View File

@ -18,7 +18,17 @@ enum
SAMPLES_PER_BLOCK = 28 SAMPLES_PER_BLOCK = 28
}; };
void InitFilter(); class ADPCMDecoder
{
public:
void ResetFilter();
void DoState(PointerWrap& p); void DoState(PointerWrap& p);
void DecodeBlock(s16* pcm, const u8* adpcm); void DecodeBlock(s16* pcm, const u8* adpcm);
private:
s32 m_histl1 = 0;
s32 m_histl2 = 0;
s32 m_histr1 = 0;
s32 m_histr2 = 0;
};
} }