Merge pull request #6621 from lioncash/adpcm

StreamADPCM: Turn the ADPCM decoder into a class
This commit is contained in:
JosJuice
2018-04-09 10:57:32 +02:00
committed by GitHub
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
void DoState(PointerWrap& p); {
void DecodeBlock(s16* pcm, const u8* adpcm); public:
void ResetFilter();
void DoState(PointerWrap& p);
void DecodeBlock(s16* pcm, const u8* adpcm);
private:
s32 m_histl1 = 0;
s32 m_histl2 = 0;
s32 m_histr1 = 0;
s32 m_histr2 = 0;
};
} }