From 81996b890bf33c8bd4d2ece52466e1293e063c84 Mon Sep 17 00:00:00 2001 From: hrydgard Date: Sat, 21 Mar 2009 17:19:46 +0000 Subject: [PATCH] Switch DTK ADPCM decoder to the one by hcs/destop, since it sounds quite a bit better. Affects Ikaruga, Crazy Taxi and maybe some more GC games. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2715 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Core/Src/HW/StreamADPCM.H | 21 +---- Source/Core/Core/Src/HW/StreamADPCM.cpp | 103 +++++++++++---------- Source/Core/DolphinWX/Src/AboutDolphin.cpp | 2 +- 3 files changed, 57 insertions(+), 69 deletions(-) diff --git a/Source/Core/Core/Src/HW/StreamADPCM.H b/Source/Core/Core/Src/HW/StreamADPCM.H index d6d62ae8e5..5b4bed7537 100644 --- a/Source/Core/Core/Src/HW/StreamADPCM.H +++ b/Source/Core/Core/Src/HW/StreamADPCM.H @@ -1,32 +1,15 @@ -/********************************************************************* - - Nintendo GameCube ADPCM Decoder Core Class - Original Author: Shinji Chiba - Modified to fit Dolphin code style by ector - - History: Mar.19 2001 - Create. - -*********************************************************************/ +// Adapted from in_cube by hcs & destop #ifndef _STREAMADPCM_H #define _STREAMADPCM_H #include "Common.h" -class PointerWrap; - -#define ONE_BLOCK_SIZE 32 -#define SAMPLES_PER_BLOCK 28 -#define MONO 1 -#define STEREO 2 class NGCADPCM { public: static void InitFilter(); - static void DecodeBlock( short*pcm, u8 *adpcm); -private: - static float iir1[STEREO], iir2[STEREO]; - static short DecodeSample(int, int, int); + static void DecodeBlock(short *pcm, const u8 *adpcm); }; #endif diff --git a/Source/Core/Core/Src/HW/StreamADPCM.cpp b/Source/Core/Core/Src/HW/StreamADPCM.cpp index 99e1a2e958..b5f0c1f0cd 100644 --- a/Source/Core/Core/Src/HW/StreamADPCM.cpp +++ b/Source/Core/Core/Src/HW/StreamADPCM.cpp @@ -1,61 +1,66 @@ -/********************************************************************* - - Nintendo GameCube ADPCM Decoder Core Class - Author: Shinji Chiba - -*********************************************************************/ +// Adapted from in_cube by hcs & destop #include "StreamADPCM.H" -// STATE_TO_SAVE -float NGCADPCM::iir1[STEREO], - NGCADPCM::iir2[STEREO]; +#define ONE_BLOCK_SIZE 32 +#define SAMPLES_PER_BLOCK 28 + +// STATE_TO_SAVE (not saved yet!) +static int histl1; +static int histl2; +static int histr1; +static int histr2; + +short ADPDecodeSample(int bits, int q, int *hist1p, int *hist2p) { + int hist, cur; + const int hist1 = *hist1p; + const int hist2 = *hist2p; + + switch (q >> 4) + { + case 0: + hist = 0; + break; + case 1: + hist = (hist1 * 0x3c); + break; + case 2: + hist = (hist1 * 0x73) - (hist2 * 0x34); + break; + case 3: + hist = (hist1 * 0x62) - (hist2 * 0x37); + break; + } + hist = (hist + 0x20) >> 6; + if (hist > 0x1fffff) hist = 0x1fffff; + if (hist < -0x200000) hist = -0x200000; + + cur = (((short)(bits << 12) >> (q & 0xf)) << 6) + hist; + + *hist2p = *hist1p; + *hist1p = cur; + + cur >>= 6; + + if (cur < -0x8000) return -0x8000; + if (cur > 0x7fff) return 0x7fff; + + return (short)cur; +} void NGCADPCM::InitFilter() { - iir1[0] = iir1[1] = - iir2[0] = iir2[1] = 0.0f; + histl1 = 0; + histl2 = 0; + histr1 = 0; + histr2 = 0; } -short NGCADPCM::DecodeSample( int bits, int q, int ch ) +void NGCADPCM::DecodeBlock(short *pcm, const u8 *adpcm) { - static const float coef[4] = { 0.86f, 1.8f, 0.82f, 1.53f }; - float iir_filter; - - iir_filter = (float) ((short) (bits << 12) >> (q & 0xf)); - switch (q >> 4) + for (int i = 0; i < SAMPLES_PER_BLOCK; i++) { - case 1: - iir_filter += (iir1[ch] * coef[0]); - break; - case 2: - iir_filter += (iir1[ch] * coef[1] - iir2[ch] * coef[2]); - break; - case 3: - iir_filter += (iir1[ch] * coef[3] - iir2[ch] * coef[0]); - } - - iir2[ch] = iir1[ch]; - if ( iir_filter <= -32768.5f ) - { - iir1[ch] = -32767.5f; - return -32767; - } - else if ( iir_filter >= 32767.5f ) - { - iir1[ch] = 32767.5f; - return 32767; - } - return (short) ((iir1[ch] = iir_filter) * 0.5f); -} - -void NGCADPCM::DecodeBlock( short *pcm, u8* adpcm) -{ - int ch = 1; - int i; - for( i = 0; i < SAMPLES_PER_BLOCK; i++ ) - { - pcm[i * STEREO] = DecodeSample( adpcm[i + (ONE_BLOCK_SIZE - SAMPLES_PER_BLOCK)] & 0xf, adpcm[0], 0 ); - pcm[i * STEREO + MONO] = DecodeSample( adpcm[i + (ONE_BLOCK_SIZE - SAMPLES_PER_BLOCK)] >> 4, adpcm[ch], ch ); + pcm[i * 2] = ADPDecodeSample(adpcm[i + (ONE_BLOCK_SIZE - SAMPLES_PER_BLOCK)] & 0xf, adpcm[0], &histl1, &histl2); + pcm[i * 2 + 1] = ADPDecodeSample(adpcm[i + (ONE_BLOCK_SIZE - SAMPLES_PER_BLOCK)] >> 4, adpcm[1], &histr1, &histr2); } } diff --git a/Source/Core/DolphinWX/Src/AboutDolphin.cpp b/Source/Core/DolphinWX/Src/AboutDolphin.cpp index 51a9a5f0c5..6f9b0e7f48 100644 --- a/Source/Core/DolphinWX/Src/AboutDolphin.cpp +++ b/Source/Core/DolphinWX/Src/AboutDolphin.cpp @@ -52,7 +52,7 @@ void AboutDolphin::CreateGUIControls() "Special thanks to Bushing, Costis, CrowTRobo, Marcan, Segher, Titanik, or9 and Hotquik for their reverse engineering and docs/demos.\n\n" "Big thanks to Gilles Mouchard whose Microlib PPC emulator gave our development a kickstart.\n\n" "Thanks to Frank Wille for his PowerPC disassembler, which or9 and we modified to include Gekko specifics.\n\n" - "Thanks to Shinji Chiba for his GC ADPCM decoder.\n\n" + "Thanks to hcs/destop for their GC ADPCM decoder.\n\n" "We are not affiliated with Nintendo in any way.\n" "Gamecube and Wii are trademarks of Nintendo.\n" "The emulator is for educational purposes only and should not be used to play games you do not legally own.\n\n";