1 #pragma once 2 3 #include "Types.h" 4 #include "BasicUnion.h" 5 #include "Convertible.h" 6 #include "zip/ZipArchiveWriter.h" 7 #include "zip/ZipArchiveReader.h" 8 9 class CRegisterStateFile; 10 11 namespace Iop 12 { 13 class CSpuBase 14 { 15 public: 16 struct ADSR_LEVEL : public convertible<uint16> 17 { 18 unsigned int sustainLevel : 4; 19 unsigned int decayRate : 4; 20 unsigned int attackRate : 7; 21 unsigned int attackMode : 1; 22 }; 23 static_assert(sizeof(ADSR_LEVEL) >= sizeof(uint16), "Size of ADSR_LEVEL struct must be at least 2 bytes."); 24 25 struct ADSR_RATE : public convertible<uint16> 26 { 27 unsigned int releaseRate : 5; 28 unsigned int releaseMode : 1; 29 unsigned int sustainRate : 7; 30 unsigned int reserved0 : 1; 31 unsigned int sustainDirection : 1; 32 unsigned int sustainMode : 1; 33 }; 34 static_assert(sizeof(ADSR_RATE) >= sizeof(uint16), "Size of ADSR_RATE struct must be at least 2 bytes."); 35 36 struct CHANNEL_VOLUME : public convertible<uint16> 37 { 38 union { 39 struct 40 { 41 unsigned int unused0 : 15; 42 unsigned int mode : 1; 43 } mode; 44 struct 45 { 46 unsigned int volume : 14; 47 unsigned int phase : 1; 48 unsigned int mode : 1; 49 } volume; 50 struct 51 { 52 unsigned int volume : 7; 53 unsigned int unused0 : 5; 54 unsigned int phase : 1; 55 unsigned int decrease : 1; 56 unsigned int slope : 1; 57 unsigned int mode : 1; 58 } sweep; 59 }; 60 }; 61 static_assert(sizeof(CHANNEL_VOLUME) >= sizeof(uint16), "Size of CHANNEL_VOLUME struct must be at least 2 bytes."); 62 63 enum 64 { 65 MAX_CHANNEL = 24 66 }; 67 68 enum 69 { 70 REVERB_PARAM_COUNT = 32 71 }; 72 73 enum CONTROL 74 { 75 CONTROL_REVERB = 0x80, 76 CONTROL_IRQ = 0x40, 77 78 CONTROL_DMA = 0x30, 79 CONTROL_DMA_STOP = 0x00, 80 CONTROL_DMA_IO = 0x10, 81 CONTROL_DMA_WRITE = 0x20, 82 CONTROL_DMA_READ = 0x30, 83 }; 84 85 enum TRANSFER_MODE 86 { 87 TRANSFER_MODE_VOICE = 0, 88 TRANSFER_MODE_BLOCK_CORE0IN = 1, 89 TRANSFER_MODE_BLOCK_CORE1IN = 2, 90 TRANSFER_MODE_BLOCK_READ = 4 91 }; 92 93 enum 94 { 95 FB_SRC_A = 0, 96 FB_SRC_B, 97 IIR_ALPHA, 98 ACC_COEF_A, 99 ACC_COEF_B, 100 ACC_COEF_C, 101 ACC_COEF_D, 102 IIR_COEF, 103 FB_ALPHA, 104 FB_X, 105 IIR_DEST_A0, 106 IIR_DEST_A1, 107 ACC_SRC_A0, 108 ACC_SRC_A1, 109 ACC_SRC_B0, 110 ACC_SRC_B1, 111 IIR_SRC_A0, 112 IIR_SRC_A1, 113 IIR_DEST_B0, 114 IIR_DEST_B1, 115 ACC_SRC_C0, 116 ACC_SRC_C1, 117 ACC_SRC_D0, 118 ACC_SRC_D1, 119 IIR_SRC_B1, 120 IIR_SRC_B0, 121 MIX_DEST_A0, 122 MIX_DEST_A1, 123 MIX_DEST_B0, 124 MIX_DEST_B1, 125 IN_COEF_L, 126 IN_COEF_R, 127 REVERB_REG_COUNT, 128 }; 129 130 enum CHANNEL_STATUS 131 { 132 STOPPED = 0, 133 KEY_ON = 1, 134 ATTACK, 135 DECAY, 136 SUSTAIN, 137 RELEASE, 138 }; 139 140 struct CHANNEL 141 { 142 CHANNEL_VOLUME volumeLeft; 143 CHANNEL_VOLUME volumeRight; 144 int32 volumeLeftAbs; 145 int32 volumeRightAbs; 146 uint16 pitch; 147 uint32 address; 148 ADSR_LEVEL adsrLevel; 149 ADSR_RATE adsrRate; 150 uint32 adsrVolume; 151 uint32 repeat; 152 uint16 status; 153 uint32 current; 154 }; 155 156 CSpuBase(uint8*, uint32, unsigned int); 157 virtual ~CSpuBase() = default; 158 159 void Reset(); 160 161 void LoadState(Framework::CZipArchiveReader&); 162 void SaveState(Framework::CZipArchiveWriter&); 163 164 bool IsEnabled() const; 165 166 void SetVolumeAdjust(float); 167 void SetReverbEnabled(bool); 168 169 void SetBaseSamplingRate(uint32); 170 171 bool GetIrqPending() const; 172 void ClearIrqPending(); 173 174 uint32 GetIrqAddress() const; 175 void SetIrqAddress(uint32); 176 177 uint16 GetTransferMode() const; 178 void SetTransferMode(uint16); 179 180 uint32 GetTransferAddress() const; 181 void SetTransferAddress(uint32); 182 183 uint16 GetControl() const; 184 void SetControl(uint16); 185 186 uint32 GetReverbParam(unsigned int) const; 187 void SetReverbParam(unsigned int, uint32); 188 189 uint32 GetReverbWorkAddressStart() const; 190 void SetReverbWorkAddressStart(uint32); 191 192 uint32 GetReverbWorkAddressEnd() const; 193 void SetReverbWorkAddressEnd(uint32); 194 195 void SetReverbCurrentAddress(uint32); 196 197 UNION32_16 GetChannelOn() const; 198 void SetChannelOn(uint16, uint16); 199 void SetChannelOnLo(uint16); 200 void SetChannelOnHi(uint16); 201 202 UNION32_16 GetChannelReverb() const; 203 void SetChannelReverbLo(uint16); 204 void SetChannelReverbHi(uint16); 205 206 CHANNEL& GetChannel(unsigned int); 207 208 void SendKeyOn(uint32); 209 void SendKeyOff(uint32); 210 211 UNION32_16 GetEndFlags() const; 212 void ClearEndFlags(); 213 214 void WriteWord(uint16); 215 216 uint32 ReceiveDma(uint8*, uint32, uint32); 217 218 void Render(int16*, unsigned int, unsigned int); 219 220 static bool g_reverbParamIsAddress[REVERB_PARAM_COUNT]; 221 222 private: 223 enum 224 { 225 CORE0_OUTPUT_LEFT = 0x800, 226 CORE0_OUTPUT_RIGHT = 0xA00, 227 CORE0_OUTPUT_SIZE = 0x200, 228 SOUND_INPUT_DATA_CORE0_BASE = 0x2000, 229 SOUND_INPUT_DATA_CORE1_BASE = 0x2400, 230 SOUND_INPUT_DATA_SIZE = 0x400, 231 SOUND_INPUT_DATA_SAMPLES = (SOUND_INPUT_DATA_SIZE / 4), 232 }; 233 234 class CSampleReader 235 { 236 public: 237 CSampleReader(); 238 virtual ~CSampleReader() = default; 239 240 void Reset(); 241 void SetMemory(uint8*, uint32); 242 243 void LoadState(const CRegisterStateFile&, const std::string&); 244 void SaveState(CRegisterStateFile*, const std::string&) const; 245 246 void SetParamsRead(uint32, uint32); 247 void SetParamsNoRead(uint32, uint32); 248 void SetPitch(uint32, uint16); 249 void GetSamples(int16*, unsigned int, unsigned int); 250 uint32 GetRepeat() const; 251 void SetRepeat(uint32); 252 uint32 GetCurrent() const; 253 void SetIrqAddress(uint32); 254 bool IsDone() const; 255 void ClearIsDone(); 256 bool GetEndFlag() const; 257 void ClearEndFlag(); 258 bool GetIrqPending() const; 259 void ClearIrqPending(); 260 261 bool DidChangeRepeat() const; 262 void ClearDidChangeRepeat(); 263 264 private: 265 enum 266 { 267 BUFFER_SAMPLES = 28, 268 }; 269 270 void SetParams(uint32, uint32); 271 void UnpackSamples(int16*); 272 void AdvanceBuffer(); 273 int16 GetSample(unsigned int); 274 275 uint8* m_ram = nullptr; 276 uint32 m_ramSize = 0; 277 278 uint32 m_srcSampleIdx; 279 unsigned int m_srcSamplingRate; 280 uint32 m_nextSampleAddr = 0; 281 uint32 m_repeatAddr = 0; 282 uint32 m_irqAddr = 0; 283 int16 m_buffer[BUFFER_SAMPLES * 2]; 284 uint16 m_pitch; 285 int32 m_s1; 286 int32 m_s2; 287 bool m_done; 288 bool m_nextValid; 289 bool m_endFlag; 290 bool m_irqPending = false; 291 bool m_didChangeRepeat; 292 293 static_assert((sizeof(decltype(m_buffer)) % 16) == 0, "sizeof(m_buffer) must be a multiple of 16 (needed for saved state)."); 294 }; 295 296 class CBlockSampleReader 297 { 298 public: 299 void Reset(); 300 bool CanReadSamples() const; 301 302 void FillBlock(const uint8*); 303 void GetSamples(int16&, int16&, unsigned int); 304 305 private: 306 enum 307 { 308 SRC_SAMPLING_RATE = 48000, 309 }; 310 311 uint32 m_srcSampleIdx = 0; 312 uint8 m_blockBuffer[SOUND_INPUT_DATA_SIZE]; 313 }; 314 315 enum 316 { 317 MAX_ADSR_VOLUME = 0x7FFFFFFF, 318 }; 319 320 void UpdateAdsr(CHANNEL&); 321 uint32 GetAdsrDelta(unsigned int) const; 322 float GetReverbSample(uint32) const; 323 void SetReverbSample(uint32, float); 324 uint32 GetReverbOffset(unsigned int) const; 325 float GetReverbCoef(unsigned int) const; 326 327 static void MixSamples(int32, int32, int16*); 328 int32 ComputeChannelVolume(const CHANNEL_VOLUME&, int32); 329 330 static const uint32 g_linearIncreaseSweepDeltas[0x80]; 331 static const uint32 g_linearDecreaseSweepDeltas[0x80]; 332 333 uint8* m_ram; 334 uint32 m_ramSize; 335 unsigned int m_spuNumber; 336 uint32 m_baseSamplingRate; 337 338 uint32 m_irqAddr = 0; 339 bool m_irqPending = false; 340 uint16 m_transferMode; 341 uint32 m_transferAddr; 342 uint32 m_core0OutputOffset; 343 UNION32_16 m_channelOn; 344 UNION32_16 m_channelReverb; 345 uint32 m_reverbWorkAddrStart; 346 uint32 m_reverbWorkAddrEnd; 347 uint32 m_reverbCurrAddr; 348 uint16 m_ctrl; 349 int m_reverbTicks; 350 uint32 m_reverb[REVERB_REG_COUNT]; 351 CHANNEL m_channel[MAX_CHANNEL]; 352 CSampleReader m_reader[MAX_CHANNEL]; 353 uint32 m_adsrLogTable[160]; 354 bool m_reverbEnabled; 355 float m_volumeAdjust; 356 357 CBlockSampleReader m_blockReader; 358 uint32 m_soundInputDataAddr = 0; 359 uint32 m_blockWritePtr = 0; 360 361 static_assert((sizeof(decltype(m_reverb)) % 16) == 0, "sizeof(m_reverb) must be a multiple of 16 (needed for saved state)."); 362 }; 363 } 364