mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 14:19:46 -06:00
Merge pull request #6621 from lioncash/adpcm
StreamADPCM: Turn the ADPCM decoder into a class
This commit is contained in:
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user