1 /* Mednafen - Multi-system Emulator 2 * 3 * This program is free software; you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License as published by 5 * the Free Software Foundation; either version 2 of the License, or 6 * (at your option) any later version. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program; if not, write to the Free Software 15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 */ 17 18 #ifndef __MDFN_OKIADPCM_H 19 #define __MDFN_OKIADPCM_H 20 21 // PC-FX ADPCM decoder not finished! 22 23 typedef enum 24 { 25 OKIADPCM_MSM5205 = 0, 26 OKIADPCM_MSM5218 = 1, 27 OKIADPCM_COUNT 28 } OKIADPCM_Chip; 29 30 extern const int OKIADPCM_StepSizes[49]; 31 extern const int OKIADPCM_StepIndexDeltas[16]; 32 extern const int32 OKIADPCM_DeltaTable[49][16]; 33 34 template <OKIADPCM_Chip CHIP_TYPE> 35 class OKIADPCM_Decoder 36 { 37 public: 38 OKIADPCM_Decoder()39 OKIADPCM_Decoder() 40 { 41 CurSample = 0x0800; 42 43 StepSizeIndex = 0; 44 } ~OKIADPCM_Decoder()45 ~OKIADPCM_Decoder() 46 { 47 48 } 49 GetSample(void)50 INLINE uint16 GetSample(void) 51 { 52 return(CurSample); 53 } 54 SetSample(uint16 new_sample)55 INLINE void SetSample(uint16 new_sample) 56 { 57 CurSample = new_sample; 58 } 59 GetSSI(void)60 INLINE uint8 GetSSI(void) 61 { 62 return(StepSizeIndex); 63 } 64 SetSSI(uint8 new_ssi)65 INLINE void SetSSI(uint8 new_ssi) 66 { 67 StepSizeIndex = new_ssi; 68 } 69 70 // DecodeDelta returns the coded delta for the given nibble and (previous) predictor. 71 // It will not wrap nor saturate the returned value, and CurSample is not updated. DecodeDelta(const uint8 nibble)72 INLINE int32 DecodeDelta(const uint8 nibble) 73 { 74 int32 ret = OKIADPCM_DeltaTable[StepSizeIndex][nibble]; 75 76 StepSizeIndex += OKIADPCM_StepIndexDeltas[nibble]; 77 78 if(StepSizeIndex < 0) 79 StepSizeIndex = 0; 80 81 if(StepSizeIndex > 48) 82 StepSizeIndex = 48; 83 84 return(ret); 85 } 86 87 // This function will return the full 12-bits, it's up to the caller to 88 // truncate as necessary(MSM5205 only has a 10-bit D/A, MSM5218 has a 12-bit D/A) Decode(const uint8 nibble)89 INLINE uint16 Decode(const uint8 nibble) 90 { 91 CurSample += DecodeDelta(nibble); 92 93 if(CHIP_TYPE == OKIADPCM_MSM5205) 94 { 95 CurSample &= 0xFFF; 96 } 97 else if(CHIP_TYPE == OKIADPCM_MSM5218) 98 { 99 if(CurSample > 0xFFF) 100 CurSample = 0xFFF; 101 if(CurSample < 0) 102 CurSample = 0; 103 } 104 return(CurSample); 105 } 106 107 private: 108 int32 CurSample; 109 int32 StepSizeIndex; 110 }; 111 #endif 112