1 #include <cassert>
2 #include <cstring>
3 #include <cmath>
4 #include <climits>
5 #include "string_format.h"
6 #include "../Log.h"
7 #include "../states/RegisterStateFile.h"
8 #include "Iop_SpuBase.h"
9
10 using namespace Iop;
11
12 #define INIT_SAMPLE_RATE (44100)
13 #define TIME_SCALE (0x1000)
14 #define LOG_NAME ("iop_spubase")
15
16 #define INVALID_ADDRESS (~0U)
17
18 #define STATE_PATH_FORMAT ("iop_spu/spu_%d.xml")
19 #define STATE_REGS_CTRL ("CTRL")
20 #define STATE_REGS_IRQADDR ("IRQADDR")
21 #define STATE_REGS_TRANSFERADDR ("TRANSFERADDR")
22 #define STATE_REGS_TRANSFERMODE ("TRANSFERMODE")
23 #define STATE_REGS_CORE0OUTPUTOFFSET ("CORE0OUTPUTOFFSET")
24 #define STATE_REGS_CHANNELON ("CHANNELON")
25 #define STATE_REGS_CHANNELREVERB ("CHANNELREVERB")
26 #define STATE_REGS_REVERBWORKADDRSTART ("REVERBWORKADDRSTART")
27 #define STATE_REGS_REVERBWORKADDREND ("REVERBWORKADDREND")
28 #define STATE_REGS_REVERBCURRADDR ("REVERBCURRADDR")
29 #define STATE_REGS_REVERB_FORMAT ("REVERB%d")
30
31 #define STATE_CHANNEL_REGS_PREFIX ("CHANNEL%02d_")
32 #define STATE_CHANNEL_REGS_VOLUMELEFT ("VOLUMELEFT")
33 #define STATE_CHANNEL_REGS_VOLUMERIGHT ("VOLUMERIGHT")
34 #define STATE_CHANNEL_REGS_VOLUMELEFTABS ("VOLUMELEFTABS")
35 #define STATE_CHANNEL_REGS_VOLUMERIGHTABS ("VOLUMERIGHTABS")
36 #define STATE_CHANNEL_REGS_STATUS ("STATUS")
37 #define STATE_CHANNEL_REGS_PITCH ("PITCH")
38 #define STATE_CHANNEL_REGS_ADSRLEVEL ("ADSRLEVEL")
39 #define STATE_CHANNEL_REGS_ADSRRATE ("ADSRRATE")
40 #define STATE_CHANNEL_REGS_ADSRVOLUME ("ADSRVOLUME")
41 #define STATE_CHANNEL_REGS_ADDRESS ("ADDRESS")
42 #define STATE_CHANNEL_REGS_REPEAT ("REPEAT")
43 #define STATE_CHANNEL_REGS_CURRENT ("CURRENT")
44
45 #define STATE_SAMPLEREADER_REGS_SRCSAMPLEIDX ("SrcSampleIdx")
46 #define STATE_SAMPLEREADER_REGS_SRCSAMPLINGRATE ("SrcSamplingRate")
47 #define STATE_SAMPLEREADER_REGS_NEXTSAMPLEADDR ("NextSampleAddr")
48 #define STATE_SAMPLEREADER_REGS_REPEATADDR ("RepeatAddr")
49 #define STATE_SAMPLEREADER_REGS_IRQADDR ("IrqAddr")
50 #define STATE_SAMPLEREADER_REGS_PITCH ("Pitch")
51 #define STATE_SAMPLEREADER_REGS_S1 ("S1")
52 #define STATE_SAMPLEREADER_REGS_S2 ("S2")
53 #define STATE_SAMPLEREADER_REGS_DONE ("Done")
54 #define STATE_SAMPLEREADER_REGS_NEXTVALID ("NextValid")
55 #define STATE_SAMPLEREADER_REGS_ENDFLAG ("EndFlag")
56 #define STATE_SAMPLEREADER_REGS_IRQPENDING ("IrqPending")
57 #define STATE_SAMPLEREADER_REGS_DIDCHANGEREPEAT ("DidChangeRepeat")
58 #define STATE_SAMPLEREADER_REGS_BUFFER_FORMAT ("%sBuffer%d")
59
60 bool CSpuBase::g_reverbParamIsAddress[REVERB_PARAM_COUNT] =
61 {
62 true,
63 true,
64 false,
65 false,
66 false,
67 false,
68 false,
69 false,
70 false,
71 false,
72 true,
73 true,
74 true,
75 true,
76 true,
77 true,
78 true,
79 true,
80 true,
81 true,
82 true,
83 true,
84 true,
85 true,
86 true,
87 true,
88 true,
89 true,
90 true,
91 true,
92 false,
93 false};
94
95 const uint32 CSpuBase::g_linearIncreaseSweepDeltas[0x80] =
96 {
97 0x3A0CC55E, 0x305FF9CE, 0x2976D61E, 0x203FFBDE, 0x1D0662AF, 0x182FFCE7, 0x1359971F, 0x101FFDEF,
98 0x0DD2475F, 0x0C17FE73, 0x0A0233AF, 0x080FFEF7, 0x07144A05, 0x060BFF39, 0x050119D7, 0x03F9DC6C,
99 0x037F3A27, 0x02FE04E5, 0x026B32E3, 0x01EF5BE9, 0x01B514DD, 0x018712AA, 0x01430F6B, 0x0100385E,
100 0x00E129C7, 0x00BE85CF, 0x00A187B5, 0x00801C2F, 0x007094E3, 0x00607F9E, 0x004FE588, 0x003DEB7D,
101 0x00392824, 0x00318930, 0x00271B77, 0x00204E57, 0x001B851B, 0x0017F80F, 0x00141506, 0x0010272B,
102 0x000E0504, 0x000BFC07, 0x000A0A83, 0x0007FD5A, 0x0006C140, 0x00063126, 0x0004F41E, 0x0003E925,
103 0x000389CC, 0x0002F8DF, 0x00027A0F, 0x0002021A, 0x0001C4E6, 0x00017C6F, 0x00014267, 0x0001010D,
104 0x0000DFC9, 0x0000C023, 0x00009E83, 0x00007ECF, 0x00006FE4, 0x00005F1B, 0x00004F41, 0x00003F67,
105 0x000037F2, 0x00002F8D, 0x000027A0, 0x0000203D, 0x00001BF9, 0x00001814, 0x00001405, 0x00000FD9,
106 0x00000D96, 0x00000BE3, 0x00000A02, 0x000007EC, 0x0000070B, 0x000005F1, 0x00000501, 0x000003F6,
107 0x00000385, 0x00000304, 0x00000280, 0x00000200, 0x000001BE, 0x0000017F, 0x00000140, 0x00000100,
108 0x000000DF, 0x000000BF, 0x000000A0, 0x00000080, 0x0000006F, 0x0000005F, 0x00000050, 0x00000040,
109 0x00000037, 0x0000002F, 0x00000028, 0x00000020, 0x0000001B, 0x00000017, 0x00000014, 0x00000010,
110 0x0000000D, 0x0000000B, 0x0000000A, 0x00000008, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
111 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
112 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000};
113
114 const uint32 CSpuBase::g_linearDecreaseSweepDeltas[0x80] =
115 {
116 0x488FF6B5, 0x3A0CC55E, 0x305FF9CE, 0x2976D61E, 0x203FFBDE, 0x1D0662AF, 0x182FFCE7, 0x1359971F,
117 0x101FFDEF, 0x0DD2475F, 0x0C17FE73, 0x0A0233AF, 0x080FFEF7, 0x07144A05, 0x060BFF39, 0x050119D7,
118 0x03F9DC6C, 0x037F3A27, 0x02FE04E5, 0x026B32E3, 0x01EF5BE9, 0x01B514DD, 0x018712AA, 0x01430F6B,
119 0x0100385E, 0x00E129C7, 0x00BE85CF, 0x00A187B5, 0x00801C2F, 0x007094E3, 0x00607F9E, 0x004FE588,
120 0x003DEB7D, 0x00392824, 0x00318930, 0x00271B77, 0x00204E57, 0x001B851B, 0x0017F80F, 0x00141506,
121 0x0010272B, 0x000E0504, 0x000BFC07, 0x000A0A83, 0x0007FD5A, 0x0006C140, 0x00063126, 0x0004F41E,
122 0x0003E925, 0x000389CC, 0x0002F8DF, 0x00027A0F, 0x0002021A, 0x0001C4E6, 0x00017C6F, 0x00014267,
123 0x0001010D, 0x0000DFC9, 0x0000C023, 0x00009E83, 0x00007ECF, 0x00006FE4, 0x00005F1B, 0x00004F41,
124 0x00003F67, 0x000037F2, 0x00002F8D, 0x000027A0, 0x0000203D, 0x00001BF9, 0x00001814, 0x00001405,
125 0x00000FD9, 0x00000D96, 0x00000BE3, 0x00000A02, 0x000007EC, 0x0000070B, 0x000005F1, 0x00000501,
126 0x000003F6, 0x00000385, 0x00000304, 0x00000280, 0x00000200, 0x000001BE, 0x0000017F, 0x00000140,
127 0x00000100, 0x000000DF, 0x000000BF, 0x000000A0, 0x00000080, 0x0000006F, 0x0000005F, 0x00000050,
128 0x00000040, 0x00000037, 0x0000002F, 0x00000028, 0x00000020, 0x0000001B, 0x00000017, 0x00000014,
129 0x00000010, 0x0000000D, 0x0000000B, 0x0000000A, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
130 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
131 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000};
132
CSpuBase(uint8 * ram,uint32 ramSize,unsigned int spuNumber)133 CSpuBase::CSpuBase(uint8* ram, uint32 ramSize, unsigned int spuNumber)
134 : m_ram(ram)
135 , m_ramSize(ramSize)
136 , m_spuNumber(spuNumber)
137 , m_reverbEnabled(true)
138 {
139 Reset();
140
141 //Init log table for ADSR
142 memset(m_adsrLogTable, 0, sizeof(m_adsrLogTable));
143
144 uint32 value = 3;
145 uint32 columnIncrement = 1;
146 uint32 column = 0;
147
148 for(unsigned int i = 32; i < 160; i++)
149 {
150 if(value < 0x3FFFFFFF)
151 {
152 value += columnIncrement;
153 column++;
154 if(column == 5)
155 {
156 column = 1;
157 columnIncrement *= 2;
158 }
159 }
160 else
161 {
162 value = 0x3FFFFFFF;
163 }
164 m_adsrLogTable[i] = value;
165 }
166 }
167
Reset()168 void CSpuBase::Reset()
169 {
170 m_ctrl = 0;
171
172 m_volumeAdjust = 1.0f;
173
174 m_channelOn.f = 0;
175 m_channelReverb.f = 0;
176 m_reverbTicks = 0;
177 m_irqAddr = INVALID_ADDRESS;
178 m_irqPending = false;
179 m_transferMode = 0;
180 m_transferAddr = 0;
181
182 m_core0OutputOffset = 0;
183
184 m_reverbCurrAddr = 0;
185 m_reverbWorkAddrStart = 0;
186 m_reverbWorkAddrEnd = 0x80000;
187 m_baseSamplingRate = 44100;
188
189 memset(m_channel, 0, sizeof(m_channel));
190 memset(m_reverb, 0, sizeof(m_reverb));
191
192 for(unsigned int i = 0; i < MAX_CHANNEL; i++)
193 {
194 m_reader[i].Reset();
195 m_reader[i].SetMemory(m_ram, m_ramSize);
196 }
197
198 m_blockReader.Reset();
199 m_soundInputDataAddr = (m_spuNumber == 0) ? SOUND_INPUT_DATA_CORE0_BASE : SOUND_INPUT_DATA_CORE1_BASE;
200 m_blockWritePtr = 0;
201 }
202
LoadState(Framework::CZipArchiveReader & archive)203 void CSpuBase::LoadState(Framework::CZipArchiveReader& archive)
204 {
205 auto path = string_format(STATE_PATH_FORMAT, m_spuNumber);
206
207 auto registerFile = CRegisterStateFile(*archive.BeginReadFile(path.c_str()));
208 m_ctrl = registerFile.GetRegister32(STATE_REGS_CTRL);
209 m_irqAddr = registerFile.GetRegister32(STATE_REGS_IRQADDR);
210 m_transferMode = registerFile.GetRegister32(STATE_REGS_TRANSFERMODE);
211 m_transferAddr = registerFile.GetRegister32(STATE_REGS_TRANSFERADDR);
212 m_core0OutputOffset = registerFile.GetRegister32(STATE_REGS_CORE0OUTPUTOFFSET);
213 m_channelOn.f = registerFile.GetRegister32(STATE_REGS_CHANNELON);
214 m_channelReverb.f = registerFile.GetRegister32(STATE_REGS_CHANNELREVERB);
215 m_reverbWorkAddrStart = registerFile.GetRegister32(STATE_REGS_REVERBWORKADDRSTART);
216 m_reverbWorkAddrEnd = registerFile.GetRegister32(STATE_REGS_REVERBWORKADDREND);
217 m_reverbCurrAddr = registerFile.GetRegister32(STATE_REGS_REVERBCURRADDR);
218
219 static const uint32 reverbRegisterCount = sizeof(m_reverb) / sizeof(uint128);
220 for(uint32 i = 0; i < reverbRegisterCount; i++)
221 {
222 auto reverbRegisterName = string_format(STATE_REGS_REVERB_FORMAT, i);
223 reinterpret_cast<uint128*>(m_reverb)[i] = registerFile.GetRegister128(reverbRegisterName.c_str());
224 }
225
226 for(unsigned int i = 0; i < MAX_CHANNEL; i++)
227 {
228 auto& channel = m_channel[i];
229 auto& reader = m_reader[i];
230 auto channelPrefix = string_format(STATE_CHANNEL_REGS_PREFIX, i);
231 channel.volumeLeft <<= registerFile.GetRegister32((channelPrefix + STATE_CHANNEL_REGS_VOLUMELEFT).c_str());
232 channel.volumeRight <<= registerFile.GetRegister32((channelPrefix + STATE_CHANNEL_REGS_VOLUMERIGHT).c_str());
233 channel.volumeLeftAbs = registerFile.GetRegister32((channelPrefix + STATE_CHANNEL_REGS_VOLUMELEFTABS).c_str());
234 channel.volumeRightAbs = registerFile.GetRegister32((channelPrefix + STATE_CHANNEL_REGS_VOLUMERIGHTABS).c_str());
235 channel.status = registerFile.GetRegister32((channelPrefix + STATE_CHANNEL_REGS_STATUS).c_str());
236 channel.pitch = registerFile.GetRegister32((channelPrefix + STATE_CHANNEL_REGS_PITCH).c_str());
237 channel.adsrLevel <<= registerFile.GetRegister32((channelPrefix + STATE_CHANNEL_REGS_ADSRLEVEL).c_str());
238 channel.adsrRate <<= registerFile.GetRegister32((channelPrefix + STATE_CHANNEL_REGS_ADSRRATE).c_str());
239 channel.adsrVolume = registerFile.GetRegister32((channelPrefix + STATE_CHANNEL_REGS_ADSRVOLUME).c_str());
240 channel.address = registerFile.GetRegister32((channelPrefix + STATE_CHANNEL_REGS_ADDRESS).c_str());
241 channel.repeat = registerFile.GetRegister32((channelPrefix + STATE_CHANNEL_REGS_REPEAT).c_str());
242 channel.current = registerFile.GetRegister32((channelPrefix + STATE_CHANNEL_REGS_CURRENT).c_str());
243 reader.LoadState(registerFile, channelPrefix);
244 }
245 }
246
SaveState(Framework::CZipArchiveWriter & archive)247 void CSpuBase::SaveState(Framework::CZipArchiveWriter& archive)
248 {
249 auto path = string_format(STATE_PATH_FORMAT, m_spuNumber);
250
251 auto registerFile = new CRegisterStateFile(path.c_str());
252 registerFile->SetRegister32(STATE_REGS_CTRL, m_ctrl);
253 registerFile->SetRegister32(STATE_REGS_IRQADDR, m_irqAddr);
254 registerFile->SetRegister32(STATE_REGS_TRANSFERMODE, m_transferMode);
255 registerFile->SetRegister32(STATE_REGS_TRANSFERADDR, m_transferAddr);
256 registerFile->SetRegister32(STATE_REGS_CORE0OUTPUTOFFSET, m_core0OutputOffset);
257 registerFile->SetRegister32(STATE_REGS_CHANNELON, m_channelOn.f);
258 registerFile->SetRegister32(STATE_REGS_CHANNELREVERB, m_channelReverb.f);
259 registerFile->SetRegister32(STATE_REGS_REVERBWORKADDRSTART, m_reverbWorkAddrStart);
260 registerFile->SetRegister32(STATE_REGS_REVERBWORKADDREND, m_reverbWorkAddrEnd);
261 registerFile->SetRegister32(STATE_REGS_REVERBCURRADDR, m_reverbCurrAddr);
262
263 static const uint32 reverbRegisterCount = sizeof(m_reverb) / sizeof(uint128);
264 for(uint32 i = 0; i < reverbRegisterCount; i++)
265 {
266 auto reverbRegisterName = string_format(STATE_REGS_REVERB_FORMAT, i);
267 registerFile->SetRegister128(reverbRegisterName.c_str(), reinterpret_cast<const uint128*>(m_reverb)[i]);
268 }
269
270 for(unsigned int i = 0; i < MAX_CHANNEL; i++)
271 {
272 const auto& channel = m_channel[i];
273 const auto& reader = m_reader[i];
274 auto channelPrefix = string_format(STATE_CHANNEL_REGS_PREFIX, i);
275 registerFile->SetRegister32((channelPrefix + STATE_CHANNEL_REGS_VOLUMELEFT).c_str(), channel.volumeLeft);
276 registerFile->SetRegister32((channelPrefix + STATE_CHANNEL_REGS_VOLUMERIGHT).c_str(), channel.volumeRight);
277 registerFile->SetRegister32((channelPrefix + STATE_CHANNEL_REGS_VOLUMELEFTABS).c_str(), channel.volumeLeftAbs);
278 registerFile->SetRegister32((channelPrefix + STATE_CHANNEL_REGS_VOLUMERIGHTABS).c_str(), channel.volumeRightAbs);
279 registerFile->SetRegister32((channelPrefix + STATE_CHANNEL_REGS_STATUS).c_str(), channel.status);
280 registerFile->SetRegister32((channelPrefix + STATE_CHANNEL_REGS_PITCH).c_str(), channel.pitch);
281 registerFile->SetRegister32((channelPrefix + STATE_CHANNEL_REGS_ADSRLEVEL).c_str(), channel.adsrLevel);
282 registerFile->SetRegister32((channelPrefix + STATE_CHANNEL_REGS_ADSRRATE).c_str(), channel.adsrRate);
283 registerFile->SetRegister32((channelPrefix + STATE_CHANNEL_REGS_ADSRVOLUME).c_str(), channel.adsrVolume);
284 registerFile->SetRegister32((channelPrefix + STATE_CHANNEL_REGS_ADDRESS).c_str(), channel.address);
285 registerFile->SetRegister32((channelPrefix + STATE_CHANNEL_REGS_REPEAT).c_str(), channel.repeat);
286 registerFile->SetRegister32((channelPrefix + STATE_CHANNEL_REGS_CURRENT).c_str(), channel.current);
287 reader.SaveState(registerFile, channelPrefix);
288 }
289
290 archive.InsertFile(registerFile);
291 }
292
IsEnabled() const293 bool CSpuBase::IsEnabled() const
294 {
295 return (m_ctrl & 0x8000) != 0;
296 }
297
SetVolumeAdjust(float volumeAdjust)298 void CSpuBase::SetVolumeAdjust(float volumeAdjust)
299 {
300 m_volumeAdjust = volumeAdjust;
301 }
302
SetReverbEnabled(bool enabled)303 void CSpuBase::SetReverbEnabled(bool enabled)
304 {
305 m_reverbEnabled = enabled;
306 }
307
GetControl() const308 uint16 CSpuBase::GetControl() const
309 {
310 return m_ctrl;
311 }
312
SetControl(uint16 value)313 void CSpuBase::SetControl(uint16 value)
314 {
315 m_ctrl = value;
316 if((m_ctrl & CONTROL_IRQ) == 0)
317 {
318 ClearIrqPending();
319 }
320 }
321
SetBaseSamplingRate(uint32 samplingRate)322 void CSpuBase::SetBaseSamplingRate(uint32 samplingRate)
323 {
324 m_baseSamplingRate = samplingRate;
325 }
326
GetIrqPending() const327 bool CSpuBase::GetIrqPending() const
328 {
329 return m_irqPending;
330 }
331
ClearIrqPending()332 void CSpuBase::ClearIrqPending()
333 {
334 m_irqPending = false;
335 }
336
GetIrqAddress() const337 uint32 CSpuBase::GetIrqAddress() const
338 {
339 return m_irqAddr;
340 }
341
SetIrqAddress(uint32 value)342 void CSpuBase::SetIrqAddress(uint32 value)
343 {
344 m_irqAddr = value & (m_ramSize - 1);
345 }
346
GetTransferMode() const347 uint16 CSpuBase::GetTransferMode() const
348 {
349 return m_transferMode;
350 }
351
SetTransferMode(uint16 transferMode)352 void CSpuBase::SetTransferMode(uint16 transferMode)
353 {
354 m_transferMode = transferMode;
355 }
356
GetTransferAddress() const357 uint32 CSpuBase::GetTransferAddress() const
358 {
359 return m_transferAddr;
360 }
361
SetTransferAddress(uint32 value)362 void CSpuBase::SetTransferAddress(uint32 value)
363 {
364 m_transferAddr = value & (m_ramSize - 1);
365 }
366
GetChannelOn() const367 UNION32_16 CSpuBase::GetChannelOn() const
368 {
369 return m_channelOn;
370 }
371
SetChannelOnLo(uint16 value)372 void CSpuBase::SetChannelOnLo(uint16 value)
373 {
374 m_channelOn.h0 = value;
375 }
376
SetChannelOnHi(uint16 value)377 void CSpuBase::SetChannelOnHi(uint16 value)
378 {
379 m_channelOn.h1 = value;
380 }
381
GetChannelReverb() const382 UNION32_16 CSpuBase::GetChannelReverb() const
383 {
384 return m_channelReverb;
385 }
386
SetChannelReverbLo(uint16 value)387 void CSpuBase::SetChannelReverbLo(uint16 value)
388 {
389 m_channelReverb.h0 = value;
390 }
391
SetChannelReverbHi(uint16 value)392 void CSpuBase::SetChannelReverbHi(uint16 value)
393 {
394 m_channelReverb.h1 = value;
395 }
396
GetReverbParam(unsigned int param) const397 uint32 CSpuBase::GetReverbParam(unsigned int param) const
398 {
399 assert(param < REVERB_PARAM_COUNT);
400 return m_reverb[param];
401 }
402
SetReverbParam(unsigned int param,uint32 value)403 void CSpuBase::SetReverbParam(unsigned int param, uint32 value)
404 {
405 assert(param < REVERB_PARAM_COUNT);
406 m_reverb[param] = value;
407 }
408
GetEndFlags() const409 UNION32_16 CSpuBase::GetEndFlags() const
410 {
411 UNION32_16 result(0);
412 for(unsigned int i = 0; i < MAX_CHANNEL; i++)
413 {
414 if(m_reader[i].GetEndFlag())
415 {
416 result.f |= (1 << i);
417 }
418 }
419 return result;
420 }
421
ClearEndFlags()422 void CSpuBase::ClearEndFlags()
423 {
424 for(unsigned int i = 0; i < MAX_CHANNEL; i++)
425 {
426 m_reader[i].ClearEndFlag();
427 }
428 }
429
GetChannel(unsigned int channelNumber)430 CSpuBase::CHANNEL& CSpuBase::GetChannel(unsigned int channelNumber)
431 {
432 assert(channelNumber < MAX_CHANNEL);
433 return m_channel[channelNumber];
434 }
435
SendKeyOn(uint32 channels)436 void CSpuBase::SendKeyOn(uint32 channels)
437 {
438 for(unsigned int i = 0; i < MAX_CHANNEL; i++)
439 {
440 CHANNEL& channel = m_channel[i];
441 if(channels & (1 << i))
442 {
443 channel.status = KEY_ON;
444 }
445 }
446 }
447
SendKeyOff(uint32 channels)448 void CSpuBase::SendKeyOff(uint32 channels)
449 {
450 for(unsigned int i = 0; i < MAX_CHANNEL; i++)
451 {
452 CHANNEL& channel = m_channel[i];
453 if(channels & (1 << i))
454 {
455 if(channel.status == STOPPED) continue;
456 if(channel.status == KEY_ON)
457 {
458 channel.status = STOPPED;
459 //Update channel registers since we are doing KEY_ON -> STOPPED transition
460 auto& reader = m_reader[i];
461 reader.SetParamsNoRead(channel.address, channel.repeat);
462 reader.ClearEndFlag();
463 channel.current = reader.GetCurrent();
464 }
465 else
466 {
467 channel.status = RELEASE;
468 }
469 }
470 }
471 }
472
GetReverbWorkAddressStart() const473 uint32 CSpuBase::GetReverbWorkAddressStart() const
474 {
475 return m_reverbWorkAddrStart;
476 }
477
SetReverbWorkAddressStart(uint32 address)478 void CSpuBase::SetReverbWorkAddressStart(uint32 address)
479 {
480 assert(address <= m_ramSize);
481 m_reverbWorkAddrStart = address;
482 m_reverbCurrAddr = address;
483 }
484
GetReverbWorkAddressEnd() const485 uint32 CSpuBase::GetReverbWorkAddressEnd() const
486 {
487 return m_reverbWorkAddrEnd - 1;
488 }
489
SetReverbWorkAddressEnd(uint32 address)490 void CSpuBase::SetReverbWorkAddressEnd(uint32 address)
491 {
492 assert((address & 0xFFFF) == 0xFFFF);
493 assert(address <= m_ramSize);
494 m_reverbWorkAddrEnd = address + 1;
495 }
496
SetReverbCurrentAddress(uint32 address)497 void CSpuBase::SetReverbCurrentAddress(uint32 address)
498 {
499 m_reverbCurrAddr = address;
500 }
501
ReceiveDma(uint8 * buffer,uint32 blockSize,uint32 blockAmount)502 uint32 CSpuBase::ReceiveDma(uint8* buffer, uint32 blockSize, uint32 blockAmount)
503 {
504 #ifdef _DEBUG
505 CLog::GetInstance().Print(LOG_NAME, "Receiving DMA transfer to 0x%08X. Size = 0x%08X bytes.\r\n",
506 m_transferAddr, blockSize * blockAmount);
507 #endif
508 if(m_transferMode == TRANSFER_MODE_VOICE)
509 {
510 if((m_ctrl & CONTROL_DMA) == CONTROL_DMA_STOP)
511 {
512 //Genso Suikoden 5 uses this
513 return 0;
514 }
515 if((m_ctrl & CONTROL_DMA) == CONTROL_DMA_READ)
516 {
517 //- DMA reads need to be throttled to allow FFX IopSoundDriver to properly synchronize itself
518 blockAmount = std::min<uint32>(blockAmount, 0x10);
519 return blockAmount;
520 }
521 //- Tsugunai needs voice transfers to be throttled because it starts a DMA transfer
522 // and then writes data that is necessary to the transfer callback in memory
523 //- Some PSF sets (FF4, Xenogears, Xenosaga 2) are sensitive to aggressive throttling (doesn't like 0x10)
524 blockAmount = std::min<uint32>(blockAmount, 0x100);
525 assert((m_ctrl & CONTROL_DMA) == CONTROL_DMA_WRITE);
526 unsigned int blocksTransfered = 0;
527 for(unsigned int i = 0; i < blockAmount; i++)
528 {
529 uint32 copySize = std::min<uint32>(m_ramSize - m_transferAddr, blockSize);
530 memcpy(m_ram + m_transferAddr, buffer, copySize);
531 m_transferAddr += blockSize;
532 m_transferAddr &= m_ramSize - 1;
533 buffer += blockSize;
534 blocksTransfered++;
535 }
536 return blocksTransfered;
537 }
538 else if(
539 (m_transferMode == TRANSFER_MODE_BLOCK_CORE0IN) ||
540 (m_transferMode == TRANSFER_MODE_BLOCK_CORE1IN))
541 {
542 assert(m_transferAddr == 0);
543 assert((m_spuNumber == 0) || !(m_transferMode == TRANSFER_MODE_BLOCK_CORE0IN));
544 assert((m_spuNumber == 1) || !(m_transferMode == TRANSFER_MODE_BLOCK_CORE1IN));
545 assert(m_blockWritePtr <= SOUND_INPUT_DATA_SIZE);
546
547 uint32 availableBytes = SOUND_INPUT_DATA_SIZE - m_blockWritePtr;
548 uint32 availableBlocks = availableBytes / blockSize;
549 blockAmount = std::min(blockAmount, availableBlocks);
550
551 uint32 dstAddr = m_soundInputDataAddr + m_blockWritePtr;
552 memcpy(m_ram + dstAddr, buffer, blockAmount * blockSize);
553 m_blockWritePtr += blockAmount * blockSize;
554
555 return blockAmount;
556 }
557 else
558 {
559 return 1;
560 }
561 }
562
WriteWord(uint16 value)563 void CSpuBase::WriteWord(uint16 value)
564 {
565 assert((m_transferAddr + 1) < m_ramSize);
566 *reinterpret_cast<uint16*>(&m_ram[m_transferAddr]) = value;
567 m_transferAddr += 2;
568 }
569
ComputeChannelVolume(const CHANNEL_VOLUME & volume,int32 currentVolume)570 int32 CSpuBase::ComputeChannelVolume(const CHANNEL_VOLUME& volume, int32 currentVolume)
571 {
572 int32 volumeLevel = 0;
573 if(!volume.mode.mode)
574 {
575 if(volume.volume.phase)
576 {
577 volumeLevel = 0x3FFF - volume.volume.volume;
578 }
579 else
580 {
581 volumeLevel = volume.volume.volume;
582 }
583 volumeLevel <<= 17;
584 }
585 else
586 {
587 assert(volume.sweep.phase == 0);
588 assert(volume.sweep.slope == 0);
589 if(volume.sweep.decrease)
590 {
591 uint32 sweepDelta = g_linearDecreaseSweepDeltas[volume.sweep.volume];
592 volumeLevel = currentVolume - sweepDelta;
593 }
594 else
595 {
596 uint32 sweepDelta = g_linearIncreaseSweepDeltas[volume.sweep.volume];
597 volumeLevel = currentVolume + sweepDelta;
598 }
599 volumeLevel = std::max<int32>(volumeLevel, 0x00000000);
600 volumeLevel = std::min<int32>(volumeLevel, 0x7FFFFFFF);
601 }
602 return volumeLevel;
603 }
604
MixSamples(int32 inputSample,int32 volumeLevel,int16 * output)605 void CSpuBase::MixSamples(int32 inputSample, int32 volumeLevel, int16* output)
606 {
607 inputSample = (inputSample * volumeLevel) / 0x7FFF;
608 int32 resultSample = inputSample + static_cast<int32>(*output);
609 resultSample = std::max<int32>(resultSample, SHRT_MIN);
610 resultSample = std::min<int32>(resultSample, SHRT_MAX);
611 *output = static_cast<int16>(resultSample);
612 }
613
Render(int16 * samples,unsigned int sampleCount,unsigned int sampleRate)614 void CSpuBase::Render(int16* samples, unsigned int sampleCount, unsigned int sampleRate)
615 {
616 bool updateReverb = m_reverbEnabled && (m_ctrl & CONTROL_REVERB) && (m_reverbWorkAddrStart < m_reverbWorkAddrEnd);
617 bool checkIrqs = (m_ctrl & CONTROL_IRQ) && (m_irqAddr != INVALID_ADDRESS);
618
619 assert((sampleCount & 0x01) == 0);
620 //ticks are 44100Hz ticks
621 unsigned int ticks = sampleCount / 2;
622 memset(samples, 0, sizeof(int16) * sampleCount);
623
624 for(unsigned int j = 0; j < ticks; j++)
625 {
626 int16 reverbSample[2] = {0, 0};
627 //Update channels
628 for(unsigned int i = 0; i < 24; i++)
629 {
630 auto& channel(m_channel[i]);
631 if((channel.status == STOPPED) && !checkIrqs) continue;
632 auto& reader(m_reader[i]);
633 reader.SetIrqAddress(m_irqAddr);
634 if(channel.status == KEY_ON)
635 {
636 reader.SetParamsRead(channel.address, channel.repeat);
637 reader.ClearEndFlag();
638 channel.status = ATTACK;
639 channel.adsrVolume = 0;
640 }
641 else
642 {
643 if(reader.IsDone())
644 {
645 channel.status = STOPPED;
646 channel.adsrVolume = 0;
647 reader.ClearIsDone();
648 //No point in continuing if we don't need to check interrupts
649 if(!checkIrqs) continue;
650 }
651 if(reader.DidChangeRepeat())
652 {
653 channel.repeat = reader.GetRepeat();
654 reader.ClearDidChangeRepeat();
655 }
656 //Update repeat in case it has been changed externally (needed for FFX)
657 reader.SetRepeat(channel.repeat);
658 }
659
660 int16 readSample = 0;
661 reader.SetPitch(m_baseSamplingRate, channel.pitch);
662 reader.GetSamples(&readSample, 1, sampleRate);
663 channel.current = reader.GetCurrent();
664
665 if(checkIrqs && reader.GetIrqPending())
666 {
667 m_irqPending = true;
668 }
669
670 reader.ClearIrqPending();
671
672 //Mix samples
673 UpdateAdsr(channel);
674 int32 inputSample = static_cast<int32>(readSample);
675 //Mix adsrVolume
676 {
677 inputSample = (inputSample * static_cast<int32>(channel.adsrVolume >> 16)) / static_cast<int32>(MAX_ADSR_VOLUME >> 16);
678 }
679
680 channel.volumeLeftAbs = ComputeChannelVolume(channel.volumeLeft, channel.volumeLeftAbs);
681 channel.volumeRightAbs = ComputeChannelVolume(channel.volumeRight, channel.volumeRightAbs);
682
683 int32 adjustedLeftVolume = std::min<int32>(0x7FFF, static_cast<int32>(static_cast<float>(channel.volumeLeftAbs >> 16) * m_volumeAdjust));
684 int32 adjustedRightVolume = std::min<int32>(0x7FFF, static_cast<int32>(static_cast<float>(channel.volumeRightAbs >> 16) * m_volumeAdjust));
685 MixSamples(inputSample, adjustedLeftVolume, samples + 0);
686 MixSamples(inputSample, adjustedRightVolume, samples + 1);
687 //Mix in reverb if enabled for this channel
688 if(updateReverb && (m_channelReverb.f & (1 << i)))
689 {
690 MixSamples(inputSample, adjustedLeftVolume, reverbSample + 0);
691 MixSamples(inputSample, adjustedRightVolume, reverbSample + 1);
692 }
693 }
694
695 if(!m_blockReader.CanReadSamples() && (m_blockWritePtr == SOUND_INPUT_DATA_SIZE))
696 {
697 //We're ready to consume some data
698 m_blockReader.FillBlock(m_ram + m_soundInputDataAddr);
699 m_blockWritePtr = 0;
700 }
701
702 if(m_blockReader.CanReadSamples())
703 {
704 int16 sampleL = 0;
705 int16 sampleR = 0;
706 m_blockReader.GetSamples(sampleL, sampleR, sampleRate);
707
708 MixSamples(sampleL, 0x3FFF, samples + 0);
709 MixSamples(sampleR, 0x3FFF, samples + 1);
710 }
711
712 //Simulate SPU CORE0 writing its output in RAM and check for potential interrupts
713 if(m_spuNumber == 0)
714 {
715 if(m_irqAddr == (CORE0_OUTPUT_LEFT + m_core0OutputOffset))
716 {
717 m_irqPending = true;
718 }
719 else if(m_irqAddr == (CORE0_OUTPUT_RIGHT + m_core0OutputOffset))
720 {
721 m_irqPending = true;
722 }
723 m_core0OutputOffset += 2;
724 m_core0OutputOffset &= (CORE0_OUTPUT_SIZE - 1);
725 }
726
727 //Update reverb
728 if(updateReverb)
729 {
730 //Feed samples to FIR filter
731 if(m_reverbTicks & 1)
732 {
733 //IIR_INPUT_A0 = buffer[IIR_SRC_A0] * IIR_COEF + INPUT_SAMPLE_L * IN_COEF_L;
734 //IIR_INPUT_A1 = buffer[IIR_SRC_A1] * IIR_COEF + INPUT_SAMPLE_R * IN_COEF_R;
735 //IIR_INPUT_B0 = buffer[IIR_SRC_B0] * IIR_COEF + INPUT_SAMPLE_L * IN_COEF_L;
736 //IIR_INPUT_B1 = buffer[IIR_SRC_B1] * IIR_COEF + INPUT_SAMPLE_R * IN_COEF_R;
737
738 float input_sample_l = static_cast<float>(reverbSample[0]) * 0.5f;
739 float input_sample_r = static_cast<float>(reverbSample[1]) * 0.5f;
740
741 float irr_coef = GetReverbCoef(IIR_COEF);
742 float in_coef_l = GetReverbCoef(IN_COEF_L);
743 float in_coef_r = GetReverbCoef(IN_COEF_R);
744
745 float iir_input_a0 = GetReverbSample(GetReverbOffset(ACC_SRC_A0)) * irr_coef + input_sample_l * in_coef_l;
746 float iir_input_a1 = GetReverbSample(GetReverbOffset(ACC_SRC_A1)) * irr_coef + input_sample_r * in_coef_r;
747 float iir_input_b0 = GetReverbSample(GetReverbOffset(ACC_SRC_B0)) * irr_coef + input_sample_l * in_coef_l;
748 float iir_input_b1 = GetReverbSample(GetReverbOffset(ACC_SRC_B1)) * irr_coef + input_sample_r * in_coef_r;
749
750 //IIR_A0 = IIR_INPUT_A0 * IIR_ALPHA + buffer[IIR_DEST_A0] * (1.0 - IIR_ALPHA);
751 //IIR_A1 = IIR_INPUT_A1 * IIR_ALPHA + buffer[IIR_DEST_A1] * (1.0 - IIR_ALPHA);
752 //IIR_B0 = IIR_INPUT_B0 * IIR_ALPHA + buffer[IIR_DEST_B0] * (1.0 - IIR_ALPHA);
753 //IIR_B1 = IIR_INPUT_B1 * IIR_ALPHA + buffer[IIR_DEST_B1] * (1.0 - IIR_ALPHA);
754
755 float iir_alpha = GetReverbCoef(IIR_ALPHA);
756
757 float iir_a0 = iir_input_a0 * iir_alpha + GetReverbSample(GetReverbOffset(IIR_DEST_A0)) * (1.0f - iir_alpha);
758 float iir_a1 = iir_input_a1 * iir_alpha + GetReverbSample(GetReverbOffset(IIR_DEST_A1)) * (1.0f - iir_alpha);
759 float iir_b0 = iir_input_b0 * iir_alpha + GetReverbSample(GetReverbOffset(IIR_DEST_B0)) * (1.0f - iir_alpha);
760 float iir_b1 = iir_input_b1 * iir_alpha + GetReverbSample(GetReverbOffset(IIR_DEST_B1)) * (1.0f - iir_alpha);
761
762 //buffer[IIR_DEST_A0 + 1sample] = IIR_A0;
763 //buffer[IIR_DEST_A1 + 1sample] = IIR_A1;
764 //buffer[IIR_DEST_B0 + 1sample] = IIR_B0;
765 //buffer[IIR_DEST_B1 + 1sample] = IIR_B1;
766
767 SetReverbSample(GetReverbOffset(IIR_DEST_A0) + 2, iir_a0);
768 SetReverbSample(GetReverbOffset(IIR_DEST_A1) + 2, iir_a1);
769 SetReverbSample(GetReverbOffset(IIR_DEST_B0) + 2, iir_b0);
770 SetReverbSample(GetReverbOffset(IIR_DEST_B1) + 2, iir_b1);
771
772 //ACC0 = buffer[ACC_SRC_A0] * ACC_COEF_A +
773 // buffer[ACC_SRC_B0] * ACC_COEF_B +
774 // buffer[ACC_SRC_C0] * ACC_COEF_C +
775 // buffer[ACC_SRC_D0] * ACC_COEF_D;
776 //ACC1 = buffer[ACC_SRC_A1] * ACC_COEF_A +
777 // buffer[ACC_SRC_B1] * ACC_COEF_B +
778 // buffer[ACC_SRC_C1] * ACC_COEF_C +
779 // buffer[ACC_SRC_D1] * ACC_COEF_D;
780
781 float acc_coef_a = GetReverbCoef(ACC_COEF_A);
782 float acc_coef_b = GetReverbCoef(ACC_COEF_B);
783 float acc_coef_c = GetReverbCoef(ACC_COEF_C);
784 float acc_coef_d = GetReverbCoef(ACC_COEF_D);
785
786 float acc0 =
787 GetReverbSample(GetReverbOffset(ACC_SRC_A0)) * acc_coef_a +
788 GetReverbSample(GetReverbOffset(ACC_SRC_B0)) * acc_coef_b +
789 GetReverbSample(GetReverbOffset(ACC_SRC_C0)) * acc_coef_c +
790 GetReverbSample(GetReverbOffset(ACC_SRC_D0)) * acc_coef_d;
791
792 float acc1 =
793 GetReverbSample(GetReverbOffset(ACC_SRC_A1)) * acc_coef_a +
794 GetReverbSample(GetReverbOffset(ACC_SRC_B1)) * acc_coef_b +
795 GetReverbSample(GetReverbOffset(ACC_SRC_C1)) * acc_coef_c +
796 GetReverbSample(GetReverbOffset(ACC_SRC_D1)) * acc_coef_d;
797
798 //FB_A0 = buffer[MIX_DEST_A0 - FB_SRC_A];
799 //FB_A1 = buffer[MIX_DEST_A1 - FB_SRC_A];
800 //FB_B0 = buffer[MIX_DEST_B0 - FB_SRC_B];
801 //FB_B1 = buffer[MIX_DEST_B1 - FB_SRC_B];
802
803 float fb_a0 = GetReverbSample(GetReverbOffset(MIX_DEST_A0) - GetReverbOffset(FB_SRC_A));
804 float fb_a1 = GetReverbSample(GetReverbOffset(MIX_DEST_A1) - GetReverbOffset(FB_SRC_A));
805 float fb_b0 = GetReverbSample(GetReverbOffset(MIX_DEST_B0) - GetReverbOffset(FB_SRC_B));
806 float fb_b1 = GetReverbSample(GetReverbOffset(MIX_DEST_B1) - GetReverbOffset(FB_SRC_B));
807
808 //buffer[MIX_DEST_A0] = ACC0 - FB_A0 * FB_ALPHA;
809 //buffer[MIX_DEST_A1] = ACC1 - FB_A1 * FB_ALPHA;
810 //buffer[MIX_DEST_B0] = (FB_ALPHA * ACC0) - FB_A0 * (FB_ALPHA^0x8000) - FB_B0 * FB_X;
811 //buffer[MIX_DEST_B1] = (FB_ALPHA * ACC1) - FB_A1 * (FB_ALPHA^0x8000) - FB_B1 * FB_X;
812
813 float fb_alpha = GetReverbCoef(FB_ALPHA);
814 float fb_x = GetReverbCoef(FB_X);
815
816 SetReverbSample(GetReverbOffset(MIX_DEST_A0), acc0 - fb_a0 * fb_alpha);
817 SetReverbSample(GetReverbOffset(MIX_DEST_A1), acc1 - fb_a1 * fb_alpha);
818 SetReverbSample(GetReverbOffset(MIX_DEST_B0), (fb_alpha * acc0) - fb_a0 * -fb_alpha - fb_b0 * fb_x);
819 SetReverbSample(GetReverbOffset(MIX_DEST_B1), (fb_alpha * acc1) - fb_a1 * -fb_alpha - fb_b1 * fb_x);
820
821 m_reverbCurrAddr += 2;
822 if(m_reverbCurrAddr >= m_reverbWorkAddrEnd)
823 {
824 m_reverbCurrAddr = m_reverbWorkAddrStart;
825 }
826 }
827
828 if(m_reverbWorkAddrStart != 0)
829 {
830 float sampleL = 0.333f * (GetReverbSample(GetReverbOffset(MIX_DEST_A0)) + GetReverbSample(GetReverbOffset(MIX_DEST_B0)));
831 float sampleR = 0.333f * (GetReverbSample(GetReverbOffset(MIX_DEST_A1)) + GetReverbSample(GetReverbOffset(MIX_DEST_B1)));
832
833 {
834 int16* output = samples + 0;
835 int32 resultSample = static_cast<int32>(sampleL) + static_cast<int32>(*output);
836 resultSample = std::max<int32>(resultSample, SHRT_MIN);
837 resultSample = std::min<int32>(resultSample, SHRT_MAX);
838 *output = static_cast<int16>(resultSample);
839 }
840
841 {
842 int16* output = samples + 1;
843 int32 resultSample = static_cast<int32>(sampleR) + static_cast<int32>(*output);
844 resultSample = std::max<int32>(resultSample, SHRT_MIN);
845 resultSample = std::min<int32>(resultSample, SHRT_MAX);
846 *output = static_cast<int16>(resultSample);
847 }
848 }
849
850 m_reverbTicks++;
851 }
852 samples += 2;
853 }
854 }
855
GetAdsrDelta(unsigned int index) const856 uint32 CSpuBase::GetAdsrDelta(unsigned int index) const
857 {
858 return m_adsrLogTable[index + 32];
859 }
860
GetReverbSample(uint32 address) const861 float CSpuBase::GetReverbSample(uint32 address) const
862 {
863 uint32 absoluteAddress = m_reverbCurrAddr + address;
864 while(absoluteAddress >= m_reverbWorkAddrEnd)
865 {
866 absoluteAddress -= m_reverbWorkAddrEnd;
867 absoluteAddress += m_reverbWorkAddrStart;
868 }
869 return static_cast<float>(*reinterpret_cast<int16*>(m_ram + absoluteAddress));
870 }
871
SetReverbSample(uint32 address,float value)872 void CSpuBase::SetReverbSample(uint32 address, float value)
873 {
874 uint32 absoluteAddress = m_reverbCurrAddr + address;
875 while(absoluteAddress >= m_reverbWorkAddrEnd)
876 {
877 absoluteAddress -= m_reverbWorkAddrEnd;
878 absoluteAddress += m_reverbWorkAddrStart;
879 }
880 value = std::max<float>(value, SHRT_MIN);
881 value = std::min<float>(value, SHRT_MAX);
882 int16 intValue = static_cast<int16>(value);
883 *reinterpret_cast<int16*>(m_ram + absoluteAddress) = intValue;
884 }
885
GetReverbOffset(unsigned int registerId) const886 uint32 CSpuBase::GetReverbOffset(unsigned int registerId) const
887 {
888 return m_reverb[registerId];
889 }
890
GetReverbCoef(unsigned int registerId) const891 float CSpuBase::GetReverbCoef(unsigned int registerId) const
892 {
893 int16 value = static_cast<int16>(m_reverb[registerId]);
894 return static_cast<float>(value) / static_cast<float>(0x8000);
895 }
896
UpdateAdsr(CHANNEL & channel)897 void CSpuBase::UpdateAdsr(CHANNEL& channel)
898 {
899 static const unsigned int logIndex[8] = {0, 4, 6, 8, 9, 10, 11, 12};
900 int32 currentAdsrLevel = channel.adsrVolume;
901 if(channel.status == ATTACK)
902 {
903 if(channel.adsrLevel.attackMode == 0)
904 {
905 //Linear mode
906 currentAdsrLevel += GetAdsrDelta((channel.adsrLevel.attackRate ^ 0x7F) - 0x10);
907 }
908 else
909 {
910 if(currentAdsrLevel < 0x60000000)
911 {
912 currentAdsrLevel += GetAdsrDelta((channel.adsrLevel.attackRate ^ 0x7F) - 0x10);
913 }
914 else
915 {
916 currentAdsrLevel += GetAdsrDelta((channel.adsrLevel.attackRate ^ 0x7F) - 0x18);
917 }
918 }
919 //Terminasion condition
920 if(currentAdsrLevel < 0)
921 {
922 currentAdsrLevel = MAX_ADSR_VOLUME;
923 channel.status = DECAY;
924 }
925 }
926 else if(channel.status == DECAY)
927 {
928 unsigned int decayType = (static_cast<uint32>(currentAdsrLevel) >> 28) & 0x7;
929 currentAdsrLevel -= GetAdsrDelta((4 * (channel.adsrLevel.decayRate ^ 0x1F)) - 0x18 + logIndex[decayType]);
930 //Terminasion condition
931 if(static_cast<unsigned int>((currentAdsrLevel >> 27) & 0xF) <= channel.adsrLevel.sustainLevel)
932 {
933 channel.status = SUSTAIN;
934 }
935 }
936 else if(channel.status == SUSTAIN)
937 {
938 if(channel.adsrRate.sustainDirection == 0)
939 {
940 //Increment
941 if(channel.adsrRate.sustainMode == 0)
942 {
943 currentAdsrLevel += GetAdsrDelta((channel.adsrRate.sustainRate ^ 0x7F) - 0x10);
944 }
945 else
946 {
947 if(currentAdsrLevel < 0x60000000)
948 {
949 currentAdsrLevel += GetAdsrDelta((channel.adsrRate.sustainRate ^ 0x7F) - 0x10);
950 }
951 else
952 {
953 currentAdsrLevel += GetAdsrDelta((channel.adsrRate.sustainRate ^ 0x7F) - 0x18);
954 }
955 }
956
957 if(currentAdsrLevel < 0)
958 {
959 currentAdsrLevel = MAX_ADSR_VOLUME;
960 }
961 }
962 else
963 {
964 //Decrement
965 if(channel.adsrRate.sustainMode == 0)
966 {
967 //Linear
968 currentAdsrLevel -= GetAdsrDelta((channel.adsrRate.sustainRate ^ 0x7F) - 0x0F);
969 }
970 else
971 {
972 unsigned int sustainType = (static_cast<uint32>(currentAdsrLevel) >> 28) & 0x7;
973 currentAdsrLevel -= GetAdsrDelta((channel.adsrRate.sustainRate ^ 0x7F) - 0x1B + logIndex[sustainType]);
974 }
975
976 if(currentAdsrLevel < 0)
977 {
978 currentAdsrLevel = 0;
979 }
980 }
981 }
982 else if(channel.status == RELEASE)
983 {
984 if(channel.adsrRate.releaseMode == 0)
985 {
986 //Linear
987 currentAdsrLevel -= GetAdsrDelta((4 * (channel.adsrRate.releaseRate ^ 0x1F)) - 0x0C);
988 }
989 else
990 {
991 unsigned int releaseType = (static_cast<uint32>(currentAdsrLevel) >> 28) & 0x7;
992 currentAdsrLevel -= GetAdsrDelta((4 * (channel.adsrRate.releaseRate ^ 0x1F)) - 0x18 + logIndex[releaseType]);
993 }
994
995 if(currentAdsrLevel < 0)
996 {
997 currentAdsrLevel = 0;
998 channel.status = STOPPED;
999 }
1000 }
1001 channel.adsrVolume = static_cast<uint32>(currentAdsrLevel);
1002 }
1003
1004 ///////////////////////////////////////////////////////
1005 // CSampleReader
1006 ///////////////////////////////////////////////////////
1007
CSampleReader()1008 CSpuBase::CSampleReader::CSampleReader()
1009 {
1010 Reset();
1011 }
1012
Reset()1013 void CSpuBase::CSampleReader::Reset()
1014 {
1015 m_nextSampleAddr = 0;
1016 m_repeatAddr = 0;
1017 m_irqAddr = INVALID_ADDRESS;
1018 memset(m_buffer, 0, sizeof(m_buffer));
1019 m_pitch = 0;
1020 m_srcSampleIdx = 0;
1021 m_srcSamplingRate = 0;
1022 m_s1 = 0;
1023 m_s2 = 0;
1024 m_done = false;
1025 m_didChangeRepeat = false;
1026 m_nextValid = false;
1027 m_endFlag = false;
1028 m_irqPending = false;
1029 }
1030
SetMemory(uint8 * ram,uint32 ramSize)1031 void CSpuBase::CSampleReader::SetMemory(uint8* ram, uint32 ramSize)
1032 {
1033 m_ram = ram;
1034 m_ramSize = ramSize;
1035 assert((ramSize & (ramSize - 1)) == 0);
1036 }
1037
LoadState(const CRegisterStateFile & registerFile,const std::string & channelPrefix)1038 void CSpuBase::CSampleReader::LoadState(const CRegisterStateFile& registerFile, const std::string& channelPrefix)
1039 {
1040 m_srcSampleIdx = registerFile.GetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_SRCSAMPLEIDX).c_str());
1041 m_srcSamplingRate = registerFile.GetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_SRCSAMPLINGRATE).c_str());
1042 m_nextSampleAddr = registerFile.GetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_NEXTSAMPLEADDR).c_str());
1043 m_repeatAddr = registerFile.GetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_REPEATADDR).c_str());
1044 m_irqAddr = registerFile.GetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_IRQADDR).c_str());
1045 m_pitch = registerFile.GetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_PITCH).c_str());
1046 m_s1 = registerFile.GetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_S1).c_str());
1047 m_s2 = registerFile.GetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_S2).c_str());
1048 m_done = registerFile.GetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_DONE).c_str()) != 0;
1049 m_nextValid = registerFile.GetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_NEXTVALID).c_str()) != 0;
1050 m_endFlag = registerFile.GetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_ENDFLAG).c_str()) != 0;
1051 m_irqPending = registerFile.GetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_IRQPENDING).c_str()) != 0;
1052 m_didChangeRepeat = registerFile.GetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_DIDCHANGEREPEAT).c_str()) != 0;
1053
1054 static const uint32 bufferRegisterCount = sizeof(m_buffer) / sizeof(uint128);
1055 for(uint32 i = 0; i < bufferRegisterCount; i++)
1056 {
1057 auto bufferRegisterName = string_format(STATE_SAMPLEREADER_REGS_BUFFER_FORMAT, channelPrefix.c_str(), i);
1058 reinterpret_cast<uint128*>(m_buffer)[i] = registerFile.GetRegister128(bufferRegisterName.c_str());
1059 }
1060 }
1061
SaveState(CRegisterStateFile * registerFile,const std::string & channelPrefix) const1062 void CSpuBase::CSampleReader::SaveState(CRegisterStateFile* registerFile, const std::string& channelPrefix) const
1063 {
1064 registerFile->SetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_SRCSAMPLEIDX).c_str(), m_srcSampleIdx);
1065 registerFile->SetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_SRCSAMPLINGRATE).c_str(), m_srcSamplingRate);
1066 registerFile->SetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_NEXTSAMPLEADDR).c_str(), m_nextSampleAddr);
1067 registerFile->SetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_REPEATADDR).c_str(), m_repeatAddr);
1068 registerFile->SetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_IRQADDR).c_str(), m_irqAddr);
1069 registerFile->SetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_PITCH).c_str(), m_pitch);
1070 registerFile->SetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_S1).c_str(), m_s1);
1071 registerFile->SetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_S2).c_str(), m_s2);
1072 registerFile->SetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_DONE).c_str(), m_done);
1073 registerFile->SetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_NEXTVALID).c_str(), m_nextValid);
1074 registerFile->SetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_ENDFLAG).c_str(), m_endFlag);
1075 registerFile->SetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_IRQPENDING).c_str(), m_irqPending);
1076 registerFile->SetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_DIDCHANGEREPEAT).c_str(), m_didChangeRepeat);
1077
1078 static const uint32 bufferRegisterCount = sizeof(m_buffer) / sizeof(uint128);
1079 for(uint32 i = 0; i < bufferRegisterCount; i++)
1080 {
1081 auto bufferRegisterName = string_format(STATE_SAMPLEREADER_REGS_BUFFER_FORMAT, channelPrefix.c_str(), i);
1082 registerFile->SetRegister128(bufferRegisterName.c_str(), reinterpret_cast<const uint128*>(m_buffer)[i]);
1083 }
1084 }
1085
SetParams(uint32 address,uint32 repeat)1086 void CSpuBase::CSampleReader::SetParams(uint32 address, uint32 repeat)
1087 {
1088 m_srcSampleIdx = 0;
1089 m_nextSampleAddr = address;
1090 m_repeatAddr = repeat;
1091 m_s1 = 0;
1092 m_s2 = 0;
1093 m_nextValid = false;
1094 m_done = false;
1095 m_didChangeRepeat = false;
1096 }
1097
SetParamsRead(uint32 address,uint32 repeat)1098 void CSpuBase::CSampleReader::SetParamsRead(uint32 address, uint32 repeat)
1099 {
1100 SetParams(address, repeat);
1101 AdvanceBuffer();
1102 }
1103
SetParamsNoRead(uint32 address,uint32 repeat)1104 void CSpuBase::CSampleReader::SetParamsNoRead(uint32 address, uint32 repeat)
1105 {
1106 SetParams(address, repeat);
1107 memset(m_buffer, 0, sizeof(m_buffer));
1108 }
1109
SetPitch(uint32 baseSamplingRate,uint16 pitch)1110 void CSpuBase::CSampleReader::SetPitch(uint32 baseSamplingRate, uint16 pitch)
1111 {
1112 m_srcSamplingRate = baseSamplingRate * pitch / 4096;
1113 }
1114
GetSamples(int16 * samples,unsigned int sampleCount,unsigned int dstSamplingRate)1115 void CSpuBase::CSampleReader::GetSamples(int16* samples, unsigned int sampleCount, unsigned int dstSamplingRate)
1116 {
1117 for(unsigned int i = 0; i < sampleCount; i++)
1118 {
1119 samples[i] = GetSample(dstSamplingRate);
1120 }
1121 }
1122
GetSample(unsigned int dstSamplingRate)1123 int16 CSpuBase::CSampleReader::GetSample(unsigned int dstSamplingRate)
1124 {
1125 uint32 srcSampleIdx = m_srcSampleIdx / TIME_SCALE;
1126 int32 srcSampleAlpha = m_srcSampleIdx % TIME_SCALE;
1127 int32 currentSample = m_buffer[srcSampleIdx];
1128 int32 nextSample = m_buffer[srcSampleIdx + 1];
1129 int32 resultSample = (currentSample * (TIME_SCALE - srcSampleAlpha) / TIME_SCALE) +
1130 (nextSample * srcSampleAlpha / TIME_SCALE);
1131 m_srcSampleIdx += (m_srcSamplingRate * TIME_SCALE) / dstSamplingRate;
1132 if(srcSampleIdx >= BUFFER_SAMPLES)
1133 {
1134 m_srcSampleIdx -= BUFFER_SAMPLES * TIME_SCALE;
1135 AdvanceBuffer();
1136 }
1137 return static_cast<int16>(resultSample);
1138 }
1139
AdvanceBuffer()1140 void CSpuBase::CSampleReader::AdvanceBuffer()
1141 {
1142 if(m_nextValid)
1143 {
1144 memmove(m_buffer, m_buffer + BUFFER_SAMPLES, sizeof(int16) * BUFFER_SAMPLES);
1145 UnpackSamples(m_buffer + BUFFER_SAMPLES);
1146 }
1147 else
1148 {
1149 UnpackSamples(m_buffer);
1150 UnpackSamples(m_buffer + BUFFER_SAMPLES);
1151 m_nextValid = true;
1152 }
1153 }
1154
UnpackSamples(int16 * dst)1155 void CSpuBase::CSampleReader::UnpackSamples(int16* dst)
1156 {
1157 int32 workBuffer[BUFFER_SAMPLES];
1158
1159 uint8* nextSample = m_ram + m_nextSampleAddr;
1160
1161 if(m_nextSampleAddr == m_irqAddr)
1162 {
1163 m_irqPending = true;
1164 }
1165
1166 //Read header
1167 uint8 shiftFactor = nextSample[0] & 0xF;
1168 uint8 predictNumber = nextSample[0] >> 4;
1169 uint8 flags = nextSample[1];
1170 assert(predictNumber < 5);
1171
1172 //Get intermediate values
1173 {
1174 unsigned int workBufferPtr = 0;
1175 for(unsigned int i = 2; i < 16; i++)
1176 {
1177 uint8 sampleByte = nextSample[i];
1178 int16 firstSample = ((sampleByte & 0x0F) << 12);
1179 int16 secondSample = ((sampleByte & 0xF0) << 8);
1180 firstSample >>= shiftFactor;
1181 secondSample >>= shiftFactor;
1182 workBuffer[workBufferPtr++] = firstSample;
1183 workBuffer[workBufferPtr++] = secondSample;
1184 }
1185 }
1186
1187 //Generate PCM samples
1188 {
1189 // clang-format off
1190 //Table is 16 entries long to prevent reading indeterminate
1191 //values if predictNumber is greater or equal to 5.
1192 //According to some sources, entries at 5 and beyond contain 0 on real hardware
1193 static const int32 predictorTable[16][2] =
1194 {
1195 {0, 0},
1196 {60, 0},
1197 {115, -52},
1198 {98, -55},
1199 {122, -60},
1200 };
1201 // clang-format on
1202
1203 for(unsigned int i = 0; i < BUFFER_SAMPLES; i++)
1204 {
1205 int32 currentValue = workBuffer[i] * 64;
1206 currentValue += (m_s1 * predictorTable[predictNumber][0]) / 64;
1207 currentValue += (m_s2 * predictorTable[predictNumber][1]) / 64;
1208 m_s2 = m_s1;
1209 m_s1 = currentValue;
1210 int32 result = (currentValue + 32) / 64;
1211 result = std::max<int32>(result, SHRT_MIN);
1212 result = std::min<int32>(result, SHRT_MAX);
1213 dst[i] = static_cast<int16>(result);
1214 }
1215 }
1216
1217 if(flags & 0x04)
1218 {
1219 m_repeatAddr = m_nextSampleAddr;
1220 m_didChangeRepeat = true;
1221 }
1222
1223 m_nextSampleAddr += 0x10;
1224 assert(m_nextSampleAddr < m_ramSize);
1225 m_nextSampleAddr &= (m_ramSize - 1);
1226
1227 if(flags & 0x01)
1228 {
1229 m_endFlag = true;
1230 m_nextSampleAddr = m_repeatAddr;
1231
1232 //If flags is in { 0x01, 0x05, 0x07 }, mute channel (Xenogears requires that)
1233 if(flags != 0x03)
1234 {
1235 m_done = true;
1236 }
1237 }
1238 }
1239
GetRepeat() const1240 uint32 CSpuBase::CSampleReader::GetRepeat() const
1241 {
1242 return m_repeatAddr;
1243 }
1244
SetRepeat(uint32 repeatAddr)1245 void CSpuBase::CSampleReader::SetRepeat(uint32 repeatAddr)
1246 {
1247 m_repeatAddr = repeatAddr;
1248 }
1249
GetCurrent() const1250 uint32 CSpuBase::CSampleReader::GetCurrent() const
1251 {
1252 return m_nextSampleAddr;
1253 }
1254
SetIrqAddress(uint32 irqAddr)1255 void CSpuBase::CSampleReader::SetIrqAddress(uint32 irqAddr)
1256 {
1257 m_irqAddr = irqAddr;
1258 }
1259
IsDone() const1260 bool CSpuBase::CSampleReader::IsDone() const
1261 {
1262 return m_done;
1263 }
1264
ClearIsDone()1265 void CSpuBase::CSampleReader::ClearIsDone()
1266 {
1267 m_done = false;
1268 }
1269
GetEndFlag() const1270 bool CSpuBase::CSampleReader::GetEndFlag() const
1271 {
1272 return m_endFlag;
1273 }
1274
ClearEndFlag()1275 void CSpuBase::CSampleReader::ClearEndFlag()
1276 {
1277 m_endFlag = false;
1278 }
1279
GetIrqPending() const1280 bool CSpuBase::CSampleReader::GetIrqPending() const
1281 {
1282 return m_irqPending;
1283 }
1284
ClearIrqPending()1285 void CSpuBase::CSampleReader::ClearIrqPending()
1286 {
1287 m_irqPending = false;
1288 }
1289
DidChangeRepeat() const1290 bool CSpuBase::CSampleReader::DidChangeRepeat() const
1291 {
1292 return m_didChangeRepeat;
1293 }
1294
ClearDidChangeRepeat()1295 void CSpuBase::CSampleReader::ClearDidChangeRepeat()
1296 {
1297 m_didChangeRepeat = false;
1298 }
1299
1300 ///////////////////////////////////////////////////////
1301 // CBlockSampleReader
1302 ///////////////////////////////////////////////////////
1303
Reset()1304 void CSpuBase::CBlockSampleReader::Reset()
1305 {
1306 m_srcSampleIdx = SOUND_INPUT_DATA_SAMPLES * TIME_SCALE;
1307 }
1308
CanReadSamples() const1309 bool CSpuBase::CBlockSampleReader::CanReadSamples() const
1310 {
1311 uint32 sampleIdx = (m_srcSampleIdx / TIME_SCALE);
1312 return (sampleIdx < SOUND_INPUT_DATA_SAMPLES);
1313 }
1314
FillBlock(const uint8 * block)1315 void CSpuBase::CBlockSampleReader::FillBlock(const uint8* block)
1316 {
1317 memcpy(m_blockBuffer, block, SOUND_INPUT_DATA_SIZE);
1318 m_srcSampleIdx = 0;
1319 }
1320
GetSamples(int16 & sampleL,int16 & sampleR,unsigned int dstSamplingRate)1321 void CSpuBase::CBlockSampleReader::GetSamples(int16& sampleL, int16& sampleR, unsigned int dstSamplingRate)
1322 {
1323 uint32 srcSampleIdx = m_srcSampleIdx / TIME_SCALE;
1324 int32 srcSampleAlpha = m_srcSampleIdx % TIME_SCALE;
1325 assert(srcSampleIdx < SOUND_INPUT_DATA_SAMPLES);
1326
1327 auto inputSamples = reinterpret_cast<const int16*>(m_blockBuffer);
1328 sampleL = inputSamples[0x000 + srcSampleIdx];
1329 sampleR = inputSamples[0x100 + srcSampleIdx];
1330
1331 m_srcSampleIdx += (SRC_SAMPLING_RATE * TIME_SCALE) / dstSamplingRate;
1332 }
1333