Browse code

2sf: fix JIT enable, fix sample rate

Adam Higerd authored on 2021/02/11 18:16:28
Showing 1 changed files
... ...
@@ -96,7 +96,7 @@ static const s16 wavedutytbl[8][8] = {
96 96
 
97 97
 static const double ARM7_CLOCK = 33513982;
98 98
 
99
-double DESMUME_SAMPLE_RATE = 48000;
99
+double DESMUME_SAMPLE_RATE = 32728.498;
100 100
 static double samples_per_hline = (DESMUME_SAMPLE_RATE / 59.8261f) / 263.0f;
101 101
 static double sampleLength = DESMUME_SAMPLE_RATE / 32728.498;
102 102
 
Browse code

update for C++17 compliance, update to latest 2sf, add WINE cross-compile makefiles

Adam Higerd authored on 2021/02/11 15:36:17
Showing 1 changed files
... ...
@@ -1,1541 +1,1480 @@
1 1
 /*
2
-	Copyright (C) 2006 yopyop
3
-	Copyright (C) 2006 Theo Berkau
4
-	Copyright (C) 2008-2012 DeSmuME team
2
+   Copyright (C) 2006 yopyop
3
+   Copyright (C) 2006 Theo Berkau
4
+   Copyright (C) 2008-2017 DeSmuME team
5 5
 
6
-	Ideas borrowed from Stephane Dallongeville's SCSP core
6
+   Ideas borrowed from Stephane Dallongeville's SCSP core
7 7
 
8
-	This file is free software: you can redistribute it and/or modify
9
-	it under the terms of the GNU General Public License as published by
10
-	the Free Software Foundation, either version 2 of the License, or
11
-	(at your option) any later version.
8
+   This file is free software: you can redistribute it and/or modify
9
+   it under the terms of the GNU General Public License as published by
10
+   the Free Software Foundation, either version 2 of the License, or
11
+   (at your option) any later version.
12 12
 
13
-	This file is distributed in the hope that it will be useful,
14
-	but WITHOUT ANY WARRANTY; without even the implied warranty of
15
-	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
-	GNU General Public License for more details.
13
+   This file is distributed in the hope that it will be useful,
14
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+   GNU General Public License for more details.
17 17
 
18
-	You should have received a copy of the GNU General Public License
19
-	along with the this software.  If not, see <http://www.gnu.org/licenses/>.
20
-*/
18
+   You should have received a copy of the GNU General Public License
19
+   along with the this software.  If not, see <http://www.gnu.org/licenses/>.
20
+   */
21 21
 
22 22
 #include "XSFCommon.h"
23
+#include "../spu/samplecache.h"
24
+#include "../spu/interpolator.h"
23 25
 
24
-#include <queue>
25
-#include <vector>
26
-#include <cstdlib>
27
-#include <cstring>
26
+#define _USE_MATH_DEFINES
27
+#include <math.h>
28 28
 #ifndef M_PI
29
-static const double M_PI = 3.14159265358979323846;
29
+#define M_PI 3.1415926535897932386
30 30
 #endif
31
+
32
+#include <stdlib.h>
33
+#include <string.h>
34
+#include <queue>
35
+#include <vector>
36
+
31 37
 #include "MMU.h"
32 38
 #include "SPU.h"
33 39
 #include "mem.h"
34 40
 #include "readwrite.h"
35 41
 #include "armcpu.h"
36 42
 #include "NDSSystem.h"
43
+#include "emufile.h"
37 44
 #include "matrix.h"
45
+#include "utils/bits.h"
38 46
 
39
-static inline int16_t read16(uint32_t addr) { return _MMU_read16<ARMCPU_ARM7,MMU_AT_DEBUG>(addr); }
40
-static inline uint8_t read08(uint32_t addr) { return _MMU_read08<ARMCPU_ARM7,MMU_AT_DEBUG>(addr); }
41
-static inline int8_t read_s8(uint32_t addr) { return _MMU_read08<ARMCPU_ARM7,MMU_AT_DEBUG>(addr); }
47
+static inline s16 read16(u32 addr) { return (s16)_MMU_read16<ARMCPU_ARM7,MMU_AT_DEBUG>(addr); }
48
+static inline u8 read08(u32 addr) { return _MMU_read08<ARMCPU_ARM7,MMU_AT_DEBUG>(addr); }
49
+static inline s8 read_s8(u32 addr) { return (s8)_MMU_read08<ARMCPU_ARM7,MMU_AT_DEBUG>(addr); }
42 50
 
43
-static const int K_ADPCM_LOOPING_RECOVERY_INDEX = 99999;
44
-static const int COSINE_INTERPOLATION_RESOLUTION = 8192;
51
+#define K_ADPCM_LOOPING_RECOVERY_INDEX 99999
52
+#define COSINE_INTERPOLATION_RESOLUTION 8192
45 53
 
46
-static auto synchronizer = std::unique_ptr<ISynchronizingAudioBuffer>(metaspu_construct(ESynchMethod_N));
47
-
48
-std::unique_ptr<SPU_struct> SPU_core, SPU_user;
54
+SPU_struct *SPU_core = 0;
49 55
 int SPU_currentCoreNum = SNDCORE_DUMMY;
50 56
 static int volume = 100;
57
+static SampleCache sampleCache;
51 58
 
52 59
 static size_t buffersize = 0;
53
-static ESynchMode synchmode = ESynchMode_DualSynchAsynch;
54
-static ESynchMethod synchmethod = ESynchMethod_N;
60
+static ESynchMode synchmode = ESynchMode_Synchronous;
61
+static ESynchMethod synchmethod = ESynchMethod_0;
62
+static ISynchronizingAudioBuffer* synchronizer = metaspu_construct(synchmethod);
55 63
 
56
-static int SNDCoreId = -1;
57
-static SoundInterface_struct *SNDCore = nullptr;
64
+static int SNDCoreId=-1;
65
+static SoundInterface_struct *SNDCore=NULL;
58 66
 extern SoundInterface_struct *SNDCoreList[];
59 67
 
60 68
 static const int format_shift[] = { 2, 1, 3, 0 };
61
-
62
-static const int8_t indextbl[8] =
63
-{
64
-	-1, -1, -1, -1, 2, 4, 6, 8
65
-};
66
-
67
-static const uint16_t adpcmtbl[89] =
68
-{
69
-	0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x0010,
70
-	0x0011, 0x0013, 0x0015, 0x0017, 0x0019, 0x001C, 0x001F, 0x0022, 0x0025,
71
-	0x0029, 0x002D, 0x0032, 0x0037, 0x003C, 0x0042, 0x0049, 0x0050, 0x0058,
72
-	0x0061, 0x006B, 0x0076, 0x0082, 0x008F, 0x009D, 0x00AD, 0x00BE, 0x00D1,
73
-	0x00E6, 0x00FD, 0x0117, 0x0133, 0x0151, 0x0173, 0x0198, 0x01C1, 0x01EE,
74
-	0x0220, 0x0256, 0x0292, 0x02D4, 0x031C, 0x036C, 0x03C3, 0x0424, 0x048E,
75
-	0x0502, 0x0583, 0x0610, 0x06AB, 0x0756, 0x0812, 0x08E0, 0x09C3, 0x0ABD,
76
-	0x0BD0, 0x0CFF, 0x0E4C, 0x0FBA, 0x114C, 0x1307, 0x14EE, 0x1706, 0x1954,
77
-	0x1BDC, 0x1EA5, 0x21B6, 0x2515, 0x28CA, 0x2CDF, 0x315B, 0x364B, 0x3BB9,
78
-	0x41B2, 0x4844, 0x4F7E, 0x5771, 0x602F, 0x69CE, 0x7462, 0x7FFF
69
+static const u8 volume_shift[] = { 0, 1, 2, 4 };
70
+
71
+static const s8 indextbl[8] = { -1, -1, -1, -1, 2, 4, 6, 8 };
72
+
73
+static const u16 adpcmtbl[89] = {
74
+  0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x0010,
75
+  0x0011, 0x0013, 0x0015, 0x0017, 0x0019, 0x001C, 0x001F, 0x0022, 0x0025,
76
+  0x0029, 0x002D, 0x0032, 0x0037, 0x003C, 0x0042, 0x0049, 0x0050, 0x0058,
77
+  0x0061, 0x006B, 0x0076, 0x0082, 0x008F, 0x009D, 0x00AD, 0x00BE, 0x00D1,
78
+  0x00E6, 0x00FD, 0x0117, 0x0133, 0x0151, 0x0173, 0x0198, 0x01C1, 0x01EE,
79
+  0x0220, 0x0256, 0x0292, 0x02D4, 0x031C, 0x036C, 0x03C3, 0x0424, 0x048E,
80
+  0x0502, 0x0583, 0x0610, 0x06AB, 0x0756, 0x0812, 0x08E0, 0x09C3, 0x0ABD,
81
+  0x0BD0, 0x0CFF, 0x0E4C, 0x0FBA, 0x114C, 0x1307, 0x14EE, 0x1706, 0x1954,
82
+  0x1BDC, 0x1EA5, 0x21B6, 0x2515, 0x28CA, 0x2CDF, 0x315B, 0x364B, 0x3BB9,
83
+  0x41B2, 0x4844, 0x4F7E, 0x5771, 0x602F, 0x69CE, 0x7462, 0x7FFF
79 84
 };
80 85
 
81
-static const int16_t wavedutytbl[8][8] = {
82
-	{ -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, 0x7FFF },
83
-	{ -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, 0x7FFF, 0x7FFF },
84
-	{ -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF },
85
-	{ -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF },
86
-	{ -0x7FFF, -0x7FFF, -0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF },
87
-	{ -0x7FFF, -0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF },
88
-	{ -0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF },
89
-	{ -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF }
86
+static const s16 wavedutytbl[8][8] = {
87
+  { -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, 0x7FFF },
88
+  { -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, 0x7FFF, 0x7FFF },
89
+  { -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF },
90
+  { -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF },
91
+  { -0x7FFF, -0x7FFF, -0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF },
92
+  { -0x7FFF, -0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF },
93
+  { -0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF },
94
+  { -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF }
90 95
 };
91 96
 
92
-static int32_t precalcdifftbl[89][16];
93
-static uint8_t precalcindextbl[89][8];
94
-static double cos_lut[COSINE_INTERPOLATION_RESOLUTION];
95
-
96 97
 static const double ARM7_CLOCK = 33513982;
97 98
 
98
-static const double samples_per_hline = (DESMUME_SAMPLE_RATE / 59.8261f) / 263.0f;
99
+double DESMUME_SAMPLE_RATE = 48000;
100
+static double samples_per_hline = (DESMUME_SAMPLE_RATE / 59.8261f) / 263.0f;
101
+static double sampleLength = DESMUME_SAMPLE_RATE / 32728.498;
102
+
103
+void SetDesmumeSampleRate(double rate) {
104
+  DESMUME_SAMPLE_RATE = rate;
105
+  sampleLength = DESMUME_SAMPLE_RATE / 32728.498;
106
+  samples_per_hline = (DESMUME_SAMPLE_RATE / 59.8261f) / 263.0f;
107
+  for (int i = 0; i < 16; i++) {
108
+    channel_struct *chan = &SPU_core->channels[i];
109
+  }
110
+}
99 111
 
100 112
 static double samples = 0;
101 113
 
102
-template<typename T> static inline T MinMax(T val, T min, T max)
114
+template<typename T>
115
+static FORCEINLINE T MinMax(T val, T min, T max)
103 116
 {
104
-	if (val < min)
105
-		return min;
106
-	else if (val > max)
107
-		return max;
108
-	else
109
-		return val;
117
+  if (val < min)
118
+    return min;
119
+  else if (val > max)
120
+    return max;
121
+
122
+  return val;
110 123
 }
111 124
 
112 125
 //--------------external spu interface---------------
113 126
 
114
-int SPU_ChangeSoundCore(int coreid, int Buffersize)
127
+int SPU_ChangeSoundCore(int coreid, int buffersize)
115 128
 {
116
-	buffersize = Buffersize;
129
+  int i;
117 130
 
118
-	SPU_user.reset();
131
+  ::buffersize = buffersize;
119 132
 
120
-	// Make sure the old core is freed
121
-	if (SNDCore)
122
-		SNDCore->DeInit();
133
+  // Make sure the old core is freed
134
+  if (SNDCore)
135
+    SNDCore->DeInit();
123 136
 
124
-	// So which core do we want?
125
-	if (coreid == SNDCORE_DEFAULT)
126
-		coreid = 0; // Assume we want the first one
137
+  // So which core do we want?
138
+  if (coreid == SNDCORE_DEFAULT)
139
+    coreid = 0; // Assume we want the first one
127 140
 
128
-	SPU_currentCoreNum = coreid;
141
+  SPU_currentCoreNum = coreid;
129 142
 
130
-	// Go through core list and find the id
131
-	for (int i = 0; SNDCoreList[i]; ++i)
132
-		if (SNDCoreList[i]->id == coreid)
133
-		{
134
-			// Set to current core
135
-			SNDCore = SNDCoreList[i];
136
-			break;
137
-		}
143
+  // Go through core list and find the id
144
+  for (i = 0; SNDCoreList[i] != NULL; i++)
145
+  {
146
+    if (SNDCoreList[i]->id == coreid)
147
+    {
148
+      // Set to current core
149
+      SNDCore = SNDCoreList[i];
150
+      break;
151
+    }
152
+  }
138 153
 
139
-	SNDCoreId = coreid;
154
+  SNDCoreId = coreid;
140 155
 
141
-	// If the user picked the dummy core, disable the user spu
142
-	if (SNDCore == &SNDDummy)
143
-		return 0;
156
+  //If the user picked the dummy core, disable the user spu
157
+  if(SNDCore == &SNDDummy)
158
+    return 0;
144 159
 
145
-	// If the core wasnt found in the list for some reason, disable the user spu
146
-	if (!SNDCore)
147
-		return -1;
160
+  //If the core wasnt found in the list for some reason, disable the user spu
161
+  if (SNDCore == NULL)
162
+    return -1;
148 163
 
149
-	// Since it failed, instead of it being fatal, disable the user spu
150
-	if (SNDCore->Init(buffersize * 2) == -1)
151
-	{
152
-		SNDCore = nullptr;
153
-		return -1;
154
-	}
164
+  // Since it failed, instead of it being fatal, disable the user spu
165
+  if (SNDCore->Init(buffersize * 2) == -1)
166
+  {
167
+    SNDCore = 0;
168
+    return -1;
169
+  }
155 170
 
156
-	SNDCore->SetVolume(volume);
171
+  SNDCore->SetVolume(volume);
157 172
 
158
-	SPU_SetSynchMode(synchmode, synchmethod);
173
+  SPU_SetSynchMode(synchmode,synchmethod);
159 174
 
160
-	return 0;
175
+  return 0;
161 176
 }
162 177
 
163
-void SPU_ReInit()
178
+SoundInterface_struct *SPU_SoundCore()
164 179
 {
165
-	SPU_Init(SNDCoreId, buffersize);
180
+  return SNDCore;
166 181
 }
167 182
 
168
-int SPU_Init(int coreid, int Buffersize)
183
+void SPU_ReInit(bool fakeBoot)
169 184
 {
170
-	// Build the cosine interpolation LUT
171
-	int i;
172
-	for (i = 0; i < COSINE_INTERPOLATION_RESOLUTION; ++i)
173
-		cos_lut[i] = (1.0 - std::cos((static_cast<double>(i) / COSINE_INTERPOLATION_RESOLUTION) * M_PI)) * 0.5;
174
-
175
-	SPU_core.reset(new SPU_struct(std::ceil(samples_per_hline)));
176
-	SPU_Reset();
177
-
178
-	int j;
179
-	// create adpcm decode accelerator lookups
180
-	for (i = 0; i < 16; ++i)
181
-		for (j = 0; j < 89; ++j)
182
-		{
183
-			precalcdifftbl[j][i] = ((i & 0x7) * 2 + 1) * adpcmtbl[j] / 8;
184
-			if (i & 0x8)
185
-				precalcdifftbl[j][i] = -precalcdifftbl[j][i];
186
-		}
187
-	for (i = 0; i < 8; ++i)
188
-		for (j = 0; j < 89; ++j)
189
-			precalcindextbl[j][i] = MinMax(j + indextbl[i], 0, 88);
190
-
191
-	return SPU_ChangeSoundCore(coreid, Buffersize);
185
+  SPU_Init(SNDCoreId, buffersize);
186
+
187
+  // Firmware set BIAS to 0x200
188
+  if (fakeBoot)
189
+    SPU_WriteWord(0x04000504, 0x0200);
192 190
 }
193 191
 
194
-void SPU_CloneUser()
192
+int SPU_Init(int coreid, int buffersize)
195 193
 {
196
-	if (SPU_user)
197
-	{
198
-		memcpy(SPU_user->channels, SPU_core->channels, sizeof(SPU_core->channels));
199
-		SPU_user->regs = SPU_core->regs;
200
-	}
194
+  SPU_core = new SPU_struct((int)ceil(samples_per_hline));
195
+  SPU_Reset();
196
+
197
+  SPU_SetSynchMode(synchmode, synchmethod);
198
+
199
+  return SPU_ChangeSoundCore(coreid, buffersize);
200
+}
201
+
202
+void SPU_Pause(int pause)
203
+{
204
+  if (SNDCore == NULL) return;
205
+
206
+  if(pause)
207
+    SNDCore->MuteAudio();
208
+  else
209
+    SNDCore->UnMuteAudio();
201 210
 }
202 211
 
203
-void SPU_SetSynchMode(ESynchMode mode, ESynchMethod method)
212
+void SPU_SetSynchMode(int mode, int method)
204 213
 {
205
-	synchmode = mode;
206
-	if (synchmethod != method)
207
-	{
208
-		synchmethod = method;
209
-		// grr does this need to be locked? spu might need a lock method
210
-		// or maybe not, maybe the platform-specific code that calls this function can deal with it.
211
-		synchronizer.reset(metaspu_construct(synchmethod));
212
-	}
213
-
214
-	SPU_user.reset();
215
-
216
-	if (synchmode == ESynchMode_DualSynchAsynch)
217
-	{
218
-		SPU_user.reset(new SPU_struct(buffersize));
219
-		SPU_CloneUser();
220
-	}
214
+  synchmode = (ESynchMode)mode;
215
+  if(synchmethod != (ESynchMethod)method)
216
+  {
217
+    synchmethod = (ESynchMethod)method;
218
+    delete synchronizer;
219
+    //grr does this need to be locked? spu might need a lock method
220
+    // or maybe not, maybe the platform-specific code that calls this function can deal with it.
221
+    synchronizer = metaspu_construct(synchmethod);
222
+  }
221 223
 }
222 224
 
223
-void SPU_Reset()
225
+void SPU_ClearOutputBuffer()
224 226
 {
225
-	SPU_core->reset();
226
-
227
-	if (SPU_user)
228
-	{
229
-		if (SNDCore)
230
-		{
231
-			SNDCore->DeInit();
232
-			SNDCore->Init(SPU_user->bufsize * 2);
233
-			SNDCore->SetVolume(volume);
234
-		}
235
-		SPU_user->reset();
236
-	}
237
-
238
-	// zero - 09-apr-2010: this concerns me, regarding savestate synch.
239
-	// After 0.9.6, lets experiment with removing it and just properly zapping the spu instead
240
-	// Reset Registers
241
-	for (int i = 0x400; i < 0x51D; ++i)
242
-		T1WriteByte(MMU.ARM7_REG, i, 0);
243
-
244
-	samples = 0;
227
+  if(SNDCore && SNDCore->ClearBuffer)
228
+    SNDCore->ClearBuffer();
229
+}
230
+
231
+void SPU_SetVolume(int volume)
232
+{
233
+  ::volume = volume;
234
+  if (SNDCore)
235
+    SNDCore->SetVolume(volume);
236
+}
237
+
238
+
239
+void SPU_Reset(void)
240
+{
241
+  int i;
242
+
243
+  SPU_core->reset();
244
+
245
+  //zero - 09-apr-2010: this concerns me, regarding savestate synch.
246
+  //After 0.9.6, lets experiment with removing it and just properly zapping the spu instead
247
+  // Reset Registers
248
+  for (i = 0x400; i < 0x51D; i++)
249
+    T1WriteByte(MMU.ARM7_REG, i, 0);
250
+
251
+  samples = 0;
245 252
 }
246 253
 
247 254
 //------------------------------------------
248 255
 
249 256
 void SPU_struct::reset()
250 257
 {
251
-	memset(&this->sndbuf[0], 0, bufsize * 2 * 4);
252
-	memset(&this->outbuf[0], 0, bufsize * 2 * 2);
258
+  memset(sndbuf,0,bufsize*2*4);
259
+  memset(outbuf,0,bufsize*2*2);
253 260
 
254
-	memset(this->channels, 0, sizeof(channel_struct) * 16);
261
+  memset((void *)channels, 0, sizeof(channel_struct) * 16);
255 262
 
256
-	reconstruct(&this->regs);
263
+  reconstruct(&regs);
257 264
 
258
-	for (int i = 0; i < 16; ++i)
259
-		this->channels[i].num = i;
265
+  for(int i = 0; i < 16; i++)
266
+  {
267
+    channels[i].num = i;
268
+  }
260 269
 }
261 270
 
262
-SPU_struct::SPU_struct(int Buffersize) : bufpos(0), buflength(0), sndbuf(new int32_t[Buffersize * 2]), outbuf(new int16_t[Buffersize * 2]), bufsize(Buffersize)
271
+SPU_struct::SPU_struct(int buffersize)
272
+  : bufpos(0)
273
+  , buflength(0)
274
+  , sndbuf(0)
275
+  , outbuf(0)
276
+    , bufsize(buffersize)
263 277
 {
264
-	this->reset();
278
+  sndbuf = new s32[buffersize*2];
279
+  outbuf = new s16[buffersize*2];
280
+  reset();
265 281
 }
266 282
 
267
-void SPU_DeInit()
283
+SPU_struct::~SPU_struct()
268 284
 {
269
-	if (SNDCore)
270
-		SNDCore->DeInit();
271
-	SNDCore = nullptr;
285
+  if(sndbuf) delete[] sndbuf;
286
+  if(outbuf) delete[] outbuf;
287
+}
272 288
 
273
-	SPU_core.reset();
274
-	SPU_user.reset();
289
+void SPU_DeInit(void)
290
+{
291
+  if(SNDCore)
292
+    SNDCore->DeInit();
293
+  SNDCore = 0;
294
+
295
+  delete SPU_core; SPU_core=0;
275 296
 }
276 297
 
277 298
 //////////////////////////////////////////////////////////////////////////////
278 299
 
279 300
 void SPU_struct::ShutUp()
280 301
 {
281
-	for (int i = 0; i < 16; ++i)
282
-		this->channels[i].status = CHANSTAT_STOPPED;
302
+  for(int i=0;i<16;i++)
303
+    channels[i].status = CHANSTAT_STOPPED;
283 304
 }
284 305
 
285
-static inline void adjust_channel_timer(channel_struct *chan)
306
+static FORCEINLINE void adjust_channel_timer(channel_struct *chan)
286 307
 {
287
-	chan->sampinc = (ARM7_CLOCK / (DESMUME_SAMPLE_RATE * 2)) / (0x10000 - chan->timer);
308
+  chan->sampinc = (((double)ARM7_CLOCK) / (DESMUME_SAMPLE_RATE * 2)) / (double)(0x10000 - chan->timer);
288 309
 }
289 310
 
290 311
 void SPU_struct::KeyProbe(int chan_num)
291 312
 {
292
-	channel_struct &thischan = this->channels[chan_num];
293
-	if (thischan.status == CHANSTAT_STOPPED)
294
-	{
295
-		if (thischan.keyon && this->regs.masteren)
296
-			this->KeyOn(chan_num);
297
-	}
298
-	else if (thischan.status == CHANSTAT_PLAY)
299
-	{
300
-		if (!thischan.keyon || !this->regs.masteren)
301
-			this->KeyOff(chan_num);
302
-	}
313
+  channel_struct &thischan = channels[chan_num];
314
+  if(thischan.status == CHANSTAT_STOPPED)
315
+  {
316
+    if(thischan.keyon && regs.masteren)
317
+      KeyOn(chan_num);
318
+  }
319
+  else if(thischan.status == CHANSTAT_PLAY)
320
+  {
321
+    if(!thischan.keyon || !regs.masteren)
322
+      KeyOff(chan_num);
323
+  }
303 324
 }
304 325
 
305 326
 void SPU_struct::KeyOff(int channel)
306 327
 {
307
-	//printf("keyoff%d\n",channel);
308
-	channel_struct &thischan = this->channels[channel];
309
-	thischan.status = CHANSTAT_STOPPED;
328
+  channel_struct &thischan = channels[channel];
329
+  thischan.status = CHANSTAT_STOPPED;
310 330
 }
311 331
 
312 332
 void SPU_struct::KeyOn(int channel)
313 333
 {
314
-	channel_struct &thischan = this->channels[channel];
315
-	thischan.status = CHANSTAT_PLAY;
316
-
317
-	thischan.totlength = thischan.length + thischan.loopstart;
318
-	adjust_channel_timer(&thischan);
319
-
320
-	//printf("keyon %d totlength:%d\n",channel,thischan.totlength);
321
-
322
-	//LOG("Channel %d key on: vol = %d, datashift = %d, hold = %d, pan = %d, waveduty = %d, repeat = %d, format = %d, source address = %07X,"
323
-	//		"timer = %04X, loop start = %04X, length = %06X, MMU.ARM7_REG[0x501] = %02X\n", channel, chan->vol, chan->datashift, chan->hold,
324
-	//		chan->pan, chan->waveduty, chan->repeat, chan->format, chan->addr, chan->timer, chan->loopstart, chan->length, T1ReadByte(MMU.ARM7_REG, 0x501));
325
-
326
-	switch (thischan.format)
327
-	{
328
-		case 0: // 8-bit
329
-			//hischan.loopstart = thischan.loopstart << 2;
330
-			//hischan.length = (thischan.length << 2) + thischan.loopstart;
331
-			thischan.sampcnt = -3;
332
-			break;
333
-		case 1: // 16-bit
334
-			//thischan.loopstart = thischan.loopstart << 1;
335
-			//thischan.length = (thischan.length << 1) + thischan.loopstart;
336
-			thischan.sampcnt = -3;
337
-			break;
338
-		case 2: // ADPCM
339
-			thischan.pcm16b = read16(thischan.addr);
340
-			thischan.pcm16b_last = thischan.pcm16b;
341
-			thischan.index = read08(thischan.addr + 2) & 0x7F;
342
-			thischan.lastsampcnt = 7;
343
-			thischan.sampcnt = -3;
344
-			thischan.loop_index = K_ADPCM_LOOPING_RECOVERY_INDEX;
345
-			//thischan.loopstart = thischan.loopstart << 3;
346
-			//hischan.length = (thischan.length << 3) + thischan.loopstart;
347
-			break;
348
-		case 3: // PSG
349
-			thischan.sampcnt = -1;
350
-			thischan.x = 0x7FFF;
351
-	}
352
-
353
-	thischan.double_totlength_shifted = thischan.totlength << format_shift[thischan.format];
354
-
355
-	if (thischan.format != 3 && fEqual(thischan.double_totlength_shifted, 0.0))
356
-	{
357
-		printf("INFO: Stopping channel %d due to zero length\n", channel);
358
-		thischan.status = CHANSTAT_STOPPED;
359
-	}
334
+  channel_struct &thischan = channels[channel];
335
+  thischan.status = CHANSTAT_PLAY;
336
+
337
+  thischan.totlength = thischan.length + thischan.loopstart;
338
+  adjust_channel_timer(&thischan);
339
+
340
+  switch(thischan.format)
341
+  {
342
+    case 0: // 8-bit
343
+      thischan.sampcnt = -3;
344
+      break;
345
+    case 1: // 16-bit
346
+      thischan.sampcnt = -3;
347
+      break;
348
+    case 2: // ADPCM
349
+      {
350
+        thischan.pcm16b = (s16)read16(thischan.addr);
351
+        thischan.pcm16b_last = thischan.pcm16b;
352
+        thischan.index = read08(thischan.addr + 2) & 0x7F;;
353
+        thischan.lastsampcnt = 7;
354
+        thischan.sampcnt = -3;
355
+        thischan.loop_index = K_ADPCM_LOOPING_RECOVERY_INDEX;
356
+        break;
357
+      }
358
+    case 3: // PSG
359
+      {
360
+        thischan.sampcnt = -1;
361
+        thischan.x = 0x7FFF;
362
+        break;
363
+      }
364
+    default: break;
365
+  }
366
+
367
+  thischan.double_totlength_shifted = (double)(thischan.totlength << format_shift[thischan.format]);
368
+
369
+  if(thischan.format != 3)
370
+  {
371
+    if(thischan.double_totlength_shifted == 0)
372
+    {
373
+      thischan.status = CHANSTAT_STOPPED;
374
+    }
375
+  }
360 376
 }
361 377
 
362 378
 //////////////////////////////////////////////////////////////////////////////
363 379
 
364
-template<typename T> static inline void SETBYTE(uint32_t which, T &oldval, uint8_t newval) { oldval = (oldval & (~(0xFF << (which * 8)))) | (newval << (which * 8)); }
365
-static inline uint8_t GETBYTE(uint32_t which, uint32_t val) { return (val >> (which * 8)) & 0xFF; }
366
-
367
-uint8_t SPU_ReadByte(uint32_t addr)
368
-{
369
-	addr &= 0xFFF;
370
-	return SPU_core->ReadByte(addr);
371
-}
372
-uint16_t SPU_ReadWord(uint32_t addr)
373
-{
374
-	addr &= 0xFFF;
375
-	return SPU_core->ReadWord(addr);
376
-}
377
-uint32_t SPU_ReadLong(uint32_t addr)
378
-{
379
-	addr &= 0xFFF;
380
-	return SPU_core->ReadLong(addr);
381
-}
382
-
383
-uint16_t SPU_struct::ReadWord(uint32_t addr)
380
+u8 SPU_struct::ReadByte(u32 addr)
384 381
 {
385
-	return this->ReadByte(addr) | (this->ReadByte(addr + 1) << 8);
382
+  //individual channel regs
383
+  if ((addr & 0x0F00) == 0x0400)
384
+  {
385
+    u32 chan_num = (addr >> 4) & 0xF;
386
+    const channel_struct& thischan = channels[chan_num];
387
+
388
+    switch (addr & 0xF)
389
+    {
390
+      case 0x0: return thischan.vol;
391
+      case 0x1: return (thischan.volumeDiv | (thischan.hold << 7));
392
+      case 0x2: return thischan.pan;
393
+      case 0x3: return (	thischan.waveduty
394
+                    | (thischan.repeat << 3)
395
+                    | (thischan.format << 5)
396
+                    | ((thischan.status == CHANSTAT_PLAY)?0x80:0)
397
+                    );
398
+      case 0x8: return thischan.timer >> 0;
399
+      case 0x9: return thischan.timer >> 8;
400
+      case 0xA: return thischan.loopstart >> 0;
401
+      case 0xB: return thischan.loopstart >> 8;
402
+    }
403
+    return 0;
404
+  }
405
+
406
+  switch(addr)
407
+  {
408
+    //SOUNDCNT
409
+    case 0x500: return regs.mastervol;
410
+    case 0x501: return (regs.ctl_left
411
+                    | (regs.ctl_right << 2)
412
+                    | (regs.ctl_ch1bypass << 4)
413
+                    | (regs.ctl_ch3bypass << 5)
414
+                    | (regs.masteren << 7)
415
+                    );
416
+
417
+                //SOUNDBIAS
418
+    case 0x504: return regs.soundbias >> 0;
419
+    case 0x505: return regs.soundbias >> 8;
420
+
421
+                //SNDCAP0CNT/SNDCAP1CNT
422
+    case 0x508:
423
+    case 0x509:
424
+                {
425
+                  u32 which = (addr - 0x508);
426
+                  return regs.cap[which].add
427
+                    | (regs.cap[which].source << 1)
428
+                    | (regs.cap[which].oneshot << 2)
429
+                    | (regs.cap[which].bits8 << 3)
430
+                    | (regs.cap[which].runtime.running << 7);
431
+                }
432
+
433
+                //SNDCAP0DAD
434
+    case 0x510: return regs.cap[0].dad >> 0;
435
+    case 0x511: return regs.cap[0].dad >> 8;
436
+    case 0x512: return regs.cap[0].dad >> 16;
437
+    case 0x513: return regs.cap[0].dad >> 24;
438
+
439
+                //SNDCAP0LEN
440
+    case 0x514: return regs.cap[0].len >> 0;
441
+    case 0x515: return regs.cap[0].len >> 8;
442
+
443
+                //SNDCAP1DAD
444
+    case 0x518: return regs.cap[1].dad >> 0;
445
+    case 0x519: return regs.cap[1].dad >> 8;
446
+    case 0x51A: return regs.cap[1].dad >> 16;
447
+    case 0x51B: return regs.cap[1].dad >> 24;
448
+
449
+                //SNDCAP1LEN
450
+    case 0x51C: return regs.cap[1].len >> 0;
451
+    case 0x51D: return regs.cap[1].len >> 8;
452
+  } //switch on address
453
+
454
+  return 0;
386 455
 }
387 456
 
388
-uint32_t SPU_struct::ReadLong(uint32_t addr)
457
+u16 SPU_struct::ReadWord(u32 addr)
389 458
 {
390
-	return this->ReadByte(addr) | (this->ReadByte(addr + 1) << 8) | (this->ReadByte(addr + 2) << 16) | (ReadByte(addr + 3) << 24);
459
+  //individual channel regs
460
+  if ((addr & 0x0F00) == 0x0400)
461
+  {
462
+    u32 chan_num = (addr >> 4) & 0xF;
463
+    const channel_struct& thischan = channels[chan_num];
464
+
465
+    switch (addr & 0xF)
466
+    {
467
+      case 0x0: return	(thischan.vol
468
+                    | (thischan.volumeDiv << 8)
469
+                    | (thischan.hold << 15)
470
+                    );
471
+      case 0x2: return	(thischan.pan
472
+                    | (thischan.waveduty << 8)
473
+                    | (thischan.repeat << 11)
474
+                    | (thischan.format << 13)
475
+                    | ((thischan.status == CHANSTAT_PLAY)?(1 << 15):0)
476
+                    );
477
+      case 0x8: return thischan.timer;
478
+      case 0xA: return thischan.loopstart;
479
+    } //switch on individual channel regs
480
+    return 0;
481
+  }
482
+
483
+  switch(addr)
484
+  {
485
+    //SOUNDCNT
486
+    case 0x500: return	(regs.mastervol
487
+                    | (regs.ctl_left << 8)
488
+                    | (regs.ctl_right << 10)
489
+                    | (regs.ctl_ch1bypass << 12)
490
+                    | (regs.ctl_ch3bypass << 13)
491
+                    | (regs.masteren << 15)
492
+                    );
493
+
494
+                //SOUNDBIAS
495
+    case 0x504: return regs.soundbias;
496
+
497
+                //SNDCAP0CNT/SNDCAP1CNT
498
+    case 0x508:
499
+                {
500
+                  u8 val0 =	regs.cap[0].add
501
+                    | (regs.cap[0].source << 1)
502
+                    | (regs.cap[0].oneshot << 2)
503
+                    | (regs.cap[0].bits8 << 3)
504
+                    | (regs.cap[0].runtime.running << 7);
505
+                  u8 val1 =	regs.cap[1].add
506
+                    | (regs.cap[1].source << 1)
507
+                    | (regs.cap[1].oneshot << 2)
508
+                    | (regs.cap[1].bits8 << 3)
509
+                    | (regs.cap[1].runtime.running << 7);
510
+                  return (u16)(val0 | (val1 << 8));
511
+                }
512
+
513
+                //SNDCAP0DAD
514
+    case 0x510: return regs.cap[0].dad >> 0;
515
+    case 0x512: return regs.cap[0].dad >> 16;
516
+
517
+                //SNDCAP0LEN
518
+    case 0x514: return regs.cap[0].len;
519
+
520
+                //SNDCAP1DAD
521
+    case 0x518: return regs.cap[1].dad >> 0;
522
+    case 0x51A: return regs.cap[1].dad >> 16;
523
+
524
+                //SNDCAP1LEN
525
+    case 0x51C: return regs.cap[1].len;
526
+  } //switch on address
527
+
528
+  return 0;
391 529
 }
392 530
 
393
-uint8_t SPU_struct::ReadByte(uint32_t addr)
531
+u32 SPU_struct::ReadLong(u32 addr)
394 532
 {
395
-	switch (addr)
396
-	{
397
-		// SOUNDCNT
398
-		case 0x500:
399
-			return this->regs.mastervol;
400
-		case 0x501:
401
-			return this->regs.ctl_left | (this->regs.ctl_right << 2) | (this->regs.ctl_ch1bypass << 4) | (this->regs.ctl_ch3bypass << 5) | (this->regs.masteren << 7);
402
-		case 0x502:
403
-		case 0x503:
404
-			return 0;
405
-
406
-		// SOUNDBIAS
407
-		case 0x504:
408
-			return this->regs.soundbias & 0xFF;
409
-		case 0x505:
410
-			return (this->regs.soundbias >> 8) & 0xFF;
411
-		case 0x506:
412
-		case 0x507:
413
-			return 0;
414
-
415
-		// SNDCAP0CNT/SNDCAP1CNT
416
-		case 0x508:
417
-		case 0x509:
418
-		{
419
-			uint32_t which = addr - 0x508;
420
-			return this->regs.cap[which].add | (this->regs.cap[which].source << 1) | (this->regs.cap[which].oneshot << 2) | (this->regs.cap[which].bits8 << 3)
421
-				//| (regs.cap[which].active<<7); //? which is right? need test
422
-				| (this->regs.cap[which].runtime.running << 7);
423
-		}
424
-
425
-		// SNDCAP0DAD
426
-		case 0x510:
427
-			return GETBYTE(0, this->regs.cap[0].dad);
428
-		case 0x511:
429
-			return GETBYTE(1, this->regs.cap[0].dad);
430
-		case 0x512:
431
-			return GETBYTE(2, this->regs.cap[0].dad);
432
-		case 0x513:
433
-			return GETBYTE(3, this->regs.cap[0].dad);
434
-
435
-		// SNDCAP0LEN
436
-		case 0x514:
437
-			return GETBYTE(0, this->regs.cap[0].len);
438
-		case 0x515:
439
-			return GETBYTE(1, this->regs.cap[0].len);
440
-		case 0x516:
441
-		case 0x517:
442
-			return 0; //not used
443
-
444
-		// SNDCAP1DAD
445
-		case 0x518:
446
-			return GETBYTE(0, this->regs.cap[1].dad);
447
-		case 0x519:
448
-			return GETBYTE(1, this->regs.cap[1].dad);
449
-		case 0x51A:
450
-			return GETBYTE(2, this->regs.cap[1].dad);
451
-		case 0x51B:
452
-			return GETBYTE(3, this->regs.cap[1].dad);
453
-
454
-		// SNDCAP1LEN
455
-		case 0x51C:
456
-			return GETBYTE(0, this->regs.cap[1].len);
457
-		case 0x51D:
458
-			return GETBYTE(1, this->regs.cap[1].len);
459
-		case 0x51E:
460
-		case 0x51F:
461
-			return 0; //not used
462
-
463
-		default:
464
-		{
465
-			// individual channel regs
466
-
467
-			uint32_t chan_num = (addr >> 4) & 0xF;
468
-			if (chan_num > 0xF)
469
-				return 0;
470
-			channel_struct &thischan = this->channels[chan_num];
471
-
472
-			switch (addr & 0xF)
473
-			{
474
-				case 0x0:
475
-					return thischan.vol;
476
-				case 0x1:
477
-				{
478
-					uint8_t ret = thischan.datashift;
479
-					if (ret == 4)
480
-						ret = 3;
481
-					ret |= thischan.hold << 7;
482
-					return ret;
483
-				}
484
-				case 0x2:
485
-					return thischan.pan;
486
-				case 0x3:
487
-					return thischan.waveduty | (thischan.repeat << 3) | (thischan.format << 5) | (thischan.status == CHANSTAT_PLAY ? 0x80 : 0);
488
-				case 0x4:
489
-					return 0; //return GETBYTE(0, thischan.addr); //not readable
490
-				case 0x5:
491
-					return 0; //return GETBYTE(1, thischan.addr); //not readable
492
-				case 0x6:
493
-					return 0; //return GETBYTE(2, thischan.addr); //not readable
494
-				case 0x7:
495
-					return 0; //return GETBYTE(3, thischan.addr); //not readable
496
-				case 0x8:
497
-					return GETBYTE(0, thischan.timer);
498
-				case 0x9:
499
-					return GETBYTE(1, thischan.timer);
500
-				case 0xA:
501
-					return GETBYTE(0, thischan.loopstart);
502
-				case 0xB:
503
-					return GETBYTE(1, thischan.loopstart);
504
-				case 0xC:
505
-					return 0; //return GETBYTE(0, thischan.length); //not readable
506
-				case 0xD:
507
-					return 0; //return GETBYTE(1, thischan.length); //not readable
508
-				case 0xE:
509
-					return 0; //return GETBYTE(2, thischan.length); //not readable
510
-				case 0xF:
511
-					return 0; //return GETBYTE(3, thischan.length); //not readable
512
-				default:
513
-					return 0; //impossible
514
-			} // switch on individual channel regs
515
-		} // default case
516
-	} // switch on address
533
+  //individual channel regs
534
+  if ((addr & 0x0F00) == 0x0400)
535
+  {
536
+    u32 chan_num = (addr >> 4) & 0xF;
537
+    channel_struct &thischan=channels[chan_num];
538
+
539
+    switch (addr & 0xF)
540
+    {
541
+      case 0x0: return	(thischan.vol
542
+                    | (thischan.volumeDiv << 8)
543
+                    | (thischan.hold << 15)
544
+                    | (thischan.pan << 16)
545
+                    | (thischan.waveduty << 24)
546
+                    | (thischan.repeat << 27)
547
+                    | (thischan.format << 29)
548
+                    | ((thischan.status == CHANSTAT_PLAY)?(1 << 31):0)
549
+                    );
550
+      case 0x8: return (thischan.timer | (thischan.loopstart << 16));
551
+    } //switch on individual channel regs
552
+    return 0;
553
+  }
554
+
555
+  switch(addr)
556
+  {
557
+    //SOUNDCNT
558
+    case 0x500: return	(regs.mastervol
559
+                    | (regs.ctl_left << 8)
560
+                    | (regs.ctl_right << 10)
561
+                    | (regs.ctl_ch1bypass << 12)
562
+                    | (regs.ctl_ch3bypass << 13)
563
+                    | (regs.masteren << 15)
564
+                    );
565
+
566
+                //SOUNDBIAS
567
+    case 0x504: return (u32)regs.soundbias;
568
+
569
+                //SNDCAP0CNT/SNDCAP1CNT
570
+    case 0x508:
571
+                {
572
+                  u8 val0 =	regs.cap[0].add
573
+                    | (regs.cap[0].source << 1)
574
+                    | (regs.cap[0].oneshot << 2)
575
+                    | (regs.cap[0].bits8 << 3)
576
+                    | (regs.cap[0].runtime.running << 7);
577
+                  u8 val1 =	regs.cap[1].add
578
+                    | (regs.cap[1].source << 1)
579
+                    | (regs.cap[1].oneshot << 2)
580
+                    | (regs.cap[1].bits8 << 3)
581
+                    | (regs.cap[1].runtime.running << 7);
582
+                  return (u32)(val0 | (val1 << 8));
583
+                }
584
+
585
+                //SNDCAP0DAD
586
+    case 0x510: return regs.cap[0].dad;
587
+
588
+                //SNDCAP0LEN
589
+    case 0x514: return (u32)regs.cap[0].len;
590
+
591
+                //SNDCAP1DAD
592
+    case 0x518: return regs.cap[1].dad;
593
+
594
+                //SNDCAP1LEN
595
+    case 0x51C: return (u32)regs.cap[1].len;
596
+  } //switch on address
597
+
598
+  return 0;
517 599
 }
518 600
 
519 601
 SPUFifo::SPUFifo()
520 602
 {
521
-	this->reset();
603
+  reset();
522 604
 }
523 605
 
524 606
 void SPUFifo::reset()
525 607
 {
526
-	this->head = this->tail = this->size = 0;
608
+  head = tail = size = 0;
527 609
 }
528 610
 
529
-void SPUFifo::enqueue(int16_t val)
611
+void SPUFifo::enqueue(s16 val)
530 612
 {
531
-	if (this->size == 16)
532
-		return;
533
-	this->buffer[this->tail] = val;
534
-	++this->tail;
535
-	this->tail &= 15;
536
-	++this->size;
613
+  if(size==16) return;
614
+  buffer[tail] = val;
615
+  tail++;
616
+  tail &= 15;
617
+  size++;
537 618
 }
538 619
 
539
-int16_t SPUFifo::dequeue()
620
+s16 SPUFifo::dequeue()
540 621
 {
541
-	if (!this->size)
542
-		return 0;
543
-	++this->head;
544
-	this->head &= 15;
545
-	int16_t ret = this->buffer[this->head];
546
-	--this->size;
547
-	return ret;
622
+  if(size==0) return 0;
623
+  head++;
624
+  head &= 15;
625
+  s16 ret = buffer[head];
626
+  size--;
627
+  return ret;
548 628
 }
549 629
 
550 630
 void SPU_struct::ProbeCapture(int which)
551 631
 {
552
-	// VERY UNTESTED -- HOW MUCH OF THIS RESETS, AND WHEN?
553
-
554
-	if (!this->regs.cap[which].active)
555
-	{
556
-		this->regs.cap[which].runtime.running = 0;
557
-		return;
558
-	}
559
-
560
-	REGS::CAP &cap = this->regs.cap[which];
561
-	cap.runtime.running = 1;
562
-	cap.runtime.curdad = cap.dad;
563
-	uint32_t len = cap.len;
564
-	if (!len)
565
-		len = 1;
566
-	cap.runtime.maxdad = cap.dad + len * 4;
567
-	cap.runtime.sampcnt = 0;
568
-	cap.runtime.fifo.reset();
632
+  //VERY UNTESTED -- HOW MUCH OF THIS RESETS, AND WHEN?
633
+
634
+  if(!regs.cap[which].active)
635
+  {
636
+    regs.cap[which].runtime.running = 0;
637
+    return;
638
+  }
639
+
640
+  REGS::CAP &cap = regs.cap[which];
641
+  cap.runtime.running = 1;
642
+  cap.runtime.curdad = cap.dad;
643
+  u32 len = cap.len;
644
+  if(len==0) len=1;
645
+  cap.runtime.maxdad = cap.dad + len*4;
646
+  cap.runtime.sampcnt = 0;
647
+  cap.runtime.fifo.reset();
569 648
 }
570 649
 
571
-void SPU_struct::WriteByte(uint32_t addr, uint8_t val)
650
+void SPU_struct::WriteByte(u32 addr, u8 val)
572 651
 {
573
-	switch (addr)
574
-	{
575
-		// SOUNDCNT
576
-		case 0x500:
577
-			this->regs.mastervol = val & 0x7F;
578
-			break;
579
-		case 0x501:
580
-			this->regs.ctl_left = val & 3;
581
-			this->regs.ctl_right = (val >> 2) & 3;
582
-			this->regs.ctl_ch1bypass = (val >> 4) & 1;
583
-			this->regs.ctl_ch3bypass = (val >> 5) & 1;
584
-			this->regs.masteren = (val >> 7) & 1;
585
-			for (int i = 0; i < 16; ++i)
586
-				this->KeyProbe(i);
587
-			break;
588
-		case 0x502:
589
-		case 0x503:
590
-			break; // not used
591
-
592
-		// SOUNDBIAS
593
-		case 0x504:
594
-			SETBYTE(0, this->regs.soundbias, val);
595
-			break;
596
-		case 0x505:
597
-			SETBYTE(1, this->regs.soundbias, val & 3);
598
-			break;
599
-		case 0x506:
600
-		case 0x507:
601
-			break; // these dont answer anyway
602
-
603
-		// SNDCAP0CNT/SNDCAP1CNT
604
-		case 0x508:
605
-		case 0x509:
606
-		{
607
-			uint32_t which = addr - 0x508;
608
-			this->regs.cap[which].add = static_cast<uint8_t>(BIT0(val));
609
-			this->regs.cap[which].source = static_cast<uint8_t>(BIT1(val));
610
-			this->regs.cap[which].oneshot = static_cast<uint8_t>(BIT2(val));
611
-			this->regs.cap[which].bits8 = static_cast<uint8_t>(BIT3(val));
612
-			this->regs.cap[which].active = static_cast<uint8_t>(BIT7(val));
613
-			this->ProbeCapture(which);
614
-			break;
615
-		}
616
-
617
-		// SNDCAP0DAD
618
-		case 0x510:
619
-			SETBYTE(0, this->regs.cap[0].dad, val);
620
-			break;
621
-		case 0x511:
622
-			SETBYTE(1, this->regs.cap[0].dad, val);
623
-			break;
624
-		case 0x512:
625
-			SETBYTE(2, this->regs.cap[0].dad, val);
626
-			break;
627
-		case 0x513:
628
-			SETBYTE(3, this->regs.cap[0].dad, val & 7);
629
-			break;
630
-
631
-		// SNDCAP0LEN
632
-		case 0x514:
633
-			SETBYTE(0, this->regs.cap[0].len, val);
634
-			break;
635
-		case 0x515:
636
-			SETBYTE(1, this->regs.cap[0].len, val);
637
-			break;
638
-		case 0x516:
639
-		case 0x517:
640
-			break; // not used
641
-
642
-		// SNDCAP1DAD
643
-		case 0x518:
644
-			SETBYTE(0, this->regs.cap[1].dad, val);
645
-			break;
646
-		case 0x519:
647
-			SETBYTE(1, this->regs.cap[1].dad, val);
648
-			break;
649
-		case 0x51A:
650
-			SETBYTE(2, this->regs.cap[1].dad, val);
651
-			break;
652
-		case 0x51B:
653
-			SETBYTE(3, this->regs.cap[1].dad, val & 7);
654
-			break;
655
-
656
-		// SNDCAP1LEN
657
-		case 0x51C:
658
-			SETBYTE(0, this->regs.cap[1].len, val);
659
-			break;
660
-		case 0x51D:
661
-			SETBYTE(1, this->regs.cap[1].len, val);
662
-			break;
663
-		case 0x51E:
664
-		case 0x51F:
665
-			break; // not used
666
-
667
-		default:
668
-		{
669
-			// individual channel regs
670
-
671
-			uint32_t chan_num = (addr >> 4) & 0xF;
672
-			if (chan_num>0xF)
673
-				break;
674
-			channel_struct &thischan = this->channels[chan_num];
675
-
676
-			switch (addr & 0xF)
677
-			{
678
-				case 0x0:
679
-					thischan.vol = val & 0x7F;
680
-					break;
681
-				case 0x1:
682
-					thischan.datashift = val & 0x3;
683
-					if (thischan.datashift == 3)
684
-						thischan.datashift = 4;
685
-					thischan.hold = (val >> 7) & 0x1;
686
-					break;
687
-				case 0x2:
688
-					thischan.pan = val & 0x7F;
689
-					break;
690
-				case 0x3:
691
-					thischan.waveduty = val & 0x7;
692
-					thischan.repeat = (val >> 3) & 0x3;
693
-					thischan.format = (val >> 5) & 0x3;
694
-					thischan.keyon = static_cast<uint8_t>(BIT7(val));
695
-					this->KeyProbe(chan_num);
696
-					break;
697
-				case 0x4:
698
-					SETBYTE(0, thischan.addr, val);
699
-					break;
700
-				case 0x5:
701
-					SETBYTE(1, thischan.addr, val);
702
-					break;
703
-				case 0x6:
704
-					SETBYTE(2, thischan.addr, val);
705
-					break;
706
-				case 0x7:
707
-					SETBYTE(3, thischan.addr, val & 0x7);
708
-					break; // only 27 bits of this register are used
709
-				case 0x8:
710
-					SETBYTE(0, thischan.timer, val);
711
-					adjust_channel_timer(&thischan);
712
-					break;
713
-				case 0x9:
714
-					SETBYTE(1, thischan.timer, val);
715
-					adjust_channel_timer(&thischan);
716
-					break;
717
-				case 0xA:
718
-					SETBYTE(0, thischan.loopstart, val);
719
-					break;
720
-				case 0xB:
721
-					SETBYTE(1, thischan.loopstart, val);
722
-					break;
723
-				case 0xC:
724
-					SETBYTE(0, thischan.length, val);
725
-					break;
726
-				case 0xD:
727
-					SETBYTE(1, thischan.length, val);
728
-					break;
729
-				case 0xE:
730
-					SETBYTE(2, thischan.length, val & 0x3F);
731
-					break; // only 22 bits of this register are used
732
-				case 0xF:
733
-					SETBYTE(3, thischan.length, 0);
734
-					break;
735
-			} // switch on individual channel regs
736
-		} // default case
737
-	} // switch on address
652
+  //individual channel regs
653
+  if ((addr & 0x0F00) == 0x0400)
654
+  {
655
+    u8 chan_num = (addr >> 4) & 0xF;
656
+    channel_struct &thischan = channels[chan_num];
657
+
658
+    switch (addr & 0x000F)
659
+    {
660
+      case 0x0: thischan.vol = (val & 0x7F); break;
661
+      case 0x1:
662
+                thischan.volumeDiv = (val & 0x03);
663
+                thischan.hold = (val >> 7) & 0x01;
664
+                break;
665
+      case 0x2: thischan.pan = (val & 0x7F); break;
666
+      case 0x3:
667
+                thischan.waveduty = (val & 0x07);
668
+                thischan.repeat = (val >> 3) & 0x03;
669
+                thischan.format = (val >> 5) & 0x03;
670
+                thischan.keyon = (val >> 7) & 0x01;
671
+                KeyProbe(chan_num);
672
+                break;
673
+      case 0x4: thischan.addr &= 0xFFFFFF00; thischan.addr |= (val & 0xFC); break;
674
+      case 0x5: thischan.addr &= 0xFFFF00FF; thischan.addr |= (val << 8); break;
675
+      case 0x6: thischan.addr &= 0xFF00FFFF; thischan.addr |= (val << 16); break;
676
+      case 0x7: thischan.addr &= 0x00FFFFFF; thischan.addr |= ((val&7) << 24); break; //only 27 bits of this register are used
677
+      case 0x8: thischan.timer &= 0xFF00; thischan.timer |= (val << 0); adjust_channel_timer(&thischan); break;
678
+      case 0x9: thischan.timer &= 0x00FF; thischan.timer |= (val << 8); adjust_channel_timer(&thischan); break;
679
+
680
+      case 0xA: thischan.loopstart &= 0xFF00; thischan.loopstart |= (val << 0); break;
681
+      case 0xB: thischan.loopstart &= 0x00FF; thischan.loopstart |= (val << 8); break;
682
+      case 0xC: thischan.length &= 0xFFFFFF00; thischan.length |= (val << 0); break;
683
+      case 0xD: thischan.length &= 0xFFFF00FF; thischan.length |= (val << 8); break;
684
+      case 0xE: thischan.length &= 0xFF00FFFF; thischan.length |= ((val & 0x3F) << 16); //only 22 bits of this register are used
685
+      case 0xF: break;
686
+
687
+    } //switch on individual channel regs
688
+
689
+    return;
690
+  }
691
+
692
+  switch(addr)
693
+  {
694
+    //SOUNDCNT
695
+    case 0x500: regs.mastervol = (val & 0x7F); break;
696
+    case 0x501:
697
+                regs.ctl_left  = (val >> 0) & 3;
698
+                regs.ctl_right = (val >> 2) & 3;
699
+                regs.ctl_ch1bypass = (val >> 4) & 1;
700
+                regs.ctl_ch3bypass = (val >> 5) & 1;
701
+                regs.masteren = (val >> 7) & 1;
702
+                break;
703
+
704
+                //SOUNDBIAS
705
+    case 0x504: regs.soundbias &= 0xFF00; regs.soundbias |= (val << 0); break;
706
+    case 0x505: regs.soundbias &= 0x00FF; regs.soundbias |= ((val&3) << 8); break;
707
+
708
+                //SNDCAP0CNT/SNDCAP1CNT
709
+    case 0x508:
710
+    case 0x509:
711
+                {
712
+                  u32 which = (addr - 0x508);
713
+                  regs.cap[which].add = BIT0(val);
714
+                  regs.cap[which].source = BIT1(val);
715
+                  regs.cap[which].oneshot = BIT2(val);
716
+                  regs.cap[which].bits8 = BIT3(val);
717
+                  regs.cap[which].active = BIT7(val);
718
+                  ProbeCapture(which);
719
+                  break;
720
+                }
721
+
722
+                //SNDCAP0DAD
723
+    case 0x510: regs.cap[0].dad &= 0xFFFFFF00; regs.cap[0].dad |= (val & 0xFC); break;
724
+    case 0x511: regs.cap[0].dad &= 0xFFFF00FF; regs.cap[0].dad |= (val << 8); break;
725
+    case 0x512: regs.cap[0].dad &= 0xFF00FFFF; regs.cap[0].dad |= (val << 16); break;
726
+    case 0x513: regs.cap[0].dad &= 0x00FFFFFF; regs.cap[0].dad |= ((val&7) << 24); break;
727
+
728
+                //SNDCAP0LEN
729
+    case 0x514: regs.cap[0].len &= 0xFF00; regs.cap[0].len |= (val << 0); break;
730
+    case 0x515: regs.cap[0].len &= 0x00FF; regs.cap[0].len |= (val << 8); break;
731
+
732
+                //SNDCAP1DAD
733
+    case 0x518: regs.cap[1].dad &= 0xFFFFFF00; regs.cap[1].dad |= (val & 0xFC); break;
734
+    case 0x519: regs.cap[1].dad &= 0xFFFF00FF; regs.cap[1].dad |= (val << 8); break;
735
+    case 0x51A: regs.cap[1].dad &= 0xFF00FFFF; regs.cap[1].dad |= (val << 16); break;
736
+    case 0x51B: regs.cap[1].dad &= 0xFF000000; regs.cap[1].dad |= ((val&7) << 24); break;
737
+
738
+                //SNDCAP1LEN
739
+    case 0x51C: regs.cap[1].len &= 0xFF00; regs.cap[1].len |= (val << 0); break;
740
+    case 0x51D: regs.cap[1].len &= 0x00FF; regs.cap[1].len |= (val << 8); break;
741
+  } //switch on address
738 742
 }
739 743
 
740
-void SPU_WriteByte(uint32_t addr, uint8_t val)
744
+void SPU_struct::WriteWord(u32 addr, u16 val)
741 745
 {
742
-	//printf("%08X: chan:%02X reg:%02X val:%02X\n",addr,(addr>>4)&0xF,addr&0xF,val);
743
-	addr &= 0xFFF;
744
-
745
-	SPU_core->WriteByte(addr, val);
746
-	if (SPU_user)
747
-		SPU_user->WriteByte(addr, val);
748
-}
749
-
750
-//////////////////////////////////////////////////////////////////////////////
751
-
752
-void SPU_struct::WriteWord(uint32_t addr, uint16_t val)
753
-{
754
-	this->WriteByte(addr, val & 0xFF);
755
-	this->WriteByte(addr + 1, (val >> 8) & 0xFF);
756
-}
757
-
758
-void SPU_WriteWord(uint32_t addr, uint16_t val)
759
-{
760
-	//printf("%08X: chan:%02X reg:%02X val:%04X\n",addr,(addr>>4)&0xF,addr&0xF,val);
761
-	addr &= 0xFFF;
762
-
763
-	SPU_core->WriteWord(addr, val);
764
-	if (SPU_user)
765
-		SPU_user->WriteWord(addr, val);
766
-}
767
-
768
-//////////////////////////////////////////////////////////////////////////////
769
-
770
-void SPU_struct::WriteLong(uint32_t addr, uint32_t val)
771
-{
772
-	this->WriteByte(addr,val & 0xFF);
773
-	this->WriteByte(addr + 1,(val >> 8) & 0xFF);
774
-	this->WriteByte(addr + 2,(val >> 16) & 0xFF);
775
-	this->WriteByte(addr + 3,(val >> 24) & 0xFF);
746
+  //individual channel regs
747
+  if ((addr & 0x0F00) == 0x0400)
748
+  {
749
+    u32 chan_num = (addr >> 4) & 0xF;
750
+    channel_struct &thischan=channels[chan_num];
751
+
752
+    switch (addr & 0xF)
753
+    {
754
+      case 0x0:
755
+        thischan.vol = (val & 0x7F);
756
+        thischan.volumeDiv = (val >> 8) & 0x3;
757
+        thischan.hold = (val >> 15) & 0x1;
758
+        break;
759
+      case 0x2:
760
+        thischan.pan = (val & 0x7F);
761
+        thischan.waveduty = (val >> 8) & 0x7;
762
+        thischan.repeat = (val >> 11) & 0x3;
763
+        thischan.format = (val >> 13) & 0x3;
764
+        thischan.keyon = (val >> 15) & 0x1;
765
+        KeyProbe(chan_num);
766
+        break;
767
+      case 0x4: thischan.addr &= 0xFFFF0000; thischan.addr |= (val & 0xFFFC); break;
768
+      case 0x6: thischan.addr &= 0x0000FFFF; thischan.addr |= ((val & 0x07FF) << 16); break;
769
+      case 0x8: thischan.timer = val; adjust_channel_timer(&thischan); break;
770
+      case 0xA: thischan.loopstart = val; break;
771
+      case 0xC: thischan.length &= 0xFFFF0000; thischan.length |= (val << 0); break;
772
+      case 0xE: thischan.length &= 0x0000FFFF; thischan.length |= ((val & 0x003F) << 16); break;
773
+    } //switch on individual channel regs
774
+    return;
775
+  }
776
+
777
+  switch (addr)
778
+  {
779
+    //SOUNDCNT
780
+    case 0x500:
781
+      regs.mastervol = (val & 0x7F);
782
+      regs.ctl_left  = (val >> 8) & 0x03;
783
+      regs.ctl_right = (val >> 10) & 0x03;
784
+      regs.ctl_ch1bypass = (val >> 12) & 0x01;
785
+      regs.ctl_ch3bypass = (val >> 13) & 0x01;
786
+      regs.masteren = (val >> 15) & 0x01;
787
+      for(u8 i=0; i<16; i++)
788
+        KeyProbe(i);
789
+      break;
790
+
791
+      //SOUNDBIAS
792
+    case 0x504: regs.soundbias = (val & 0x3FF); break;
793
+
794
+                //SNDCAP0CNT/SNDCAP1CNT
795
+    case 0x508:
796
+                {
797
+                  regs.cap[0].add = BIT0(val);
798
+                  regs.cap[0].source = BIT1(val);
799
+                  regs.cap[0].oneshot = BIT2(val);
800
+                  regs.cap[0].bits8 = BIT3(val);
801
+                  regs.cap[0].active = BIT7(val);
802
+                  ProbeCapture(0);
803
+
804
+                  regs.cap[1].add = BIT8(val);
805
+                  regs.cap[1].source = BIT9(val);
806
+                  regs.cap[1].oneshot = BIT10(val);
807
+                  regs.cap[1].bits8 = BIT11(val);
808
+                  regs.cap[1].active = BIT15(val);
809
+                  ProbeCapture(1);
810
+                  break;
811
+                }
812
+
813
+                //SNDCAP0DAD
814
+    case 0x510: regs.cap[0].dad &= 0xFFFF0000; regs.cap[0].dad |= (val & 0xFFFC); break;
815
+    case 0x512: regs.cap[0].dad &= 0x0000FFFF; regs.cap[0].dad |= ((val & 0x07FF) << 16); break;
816
+
817
+                //SNDCAP0LEN
818
+    case 0x514: regs.cap[0].len = val; break;
819
+
820
+                //SNDCAP1DAD
821
+    case 0x518: regs.cap[1].dad &= 0xFFFF0000; regs.cap[1].dad |= (val & 0xFFFC); break;
822
+    case 0x51A: regs.cap[1].dad &= 0x0000FFFF; regs.cap[1].dad |= ((val & 0x07FF) << 16); break;
823
+
824
+                //SNDCAP1LEN
825
+    case 0x51C: regs.cap[1].len = val; break;
826
+  } //switch on address
776 827
 }
777 828
 
778
-void SPU_WriteLong(uint32_t addr, uint32_t val)
829
+void SPU_struct::WriteLong(u32 addr, u32 val)
779 830
 {
780
-	//printf("%08X: chan:%02X reg:%02X val:%08X\n",addr,(addr>>4)&0xF,addr&0xF,val);
781
-	addr &= 0xFFF;
782
-
783
-	SPU_core->WriteLong(addr, val);
784
-	if (SPU_user)
785
-		SPU_user->WriteLong(addr, val);
831
+  //individual channel regs
832
+  if ((addr & 0x0F00) == 0x0400)
833
+  {
834
+    u32 chan_num = (addr >> 4) & 0xF;
835
+    channel_struct &thischan=channels[chan_num];
836
+
837
+    switch (addr & 0xF)
838
+    {
839
+      case 0x0:
840
+        thischan.vol = val & 0x7F;
841
+        thischan.volumeDiv = (val >> 8) & 0x3;
842
+        thischan.hold = (val >> 15) & 0x1;
843
+        thischan.pan = (val >> 16) & 0x7F;
844
+        thischan.waveduty = (val >> 24) & 0x7;
845
+        thischan.repeat = (val >> 27) & 0x3;
846
+        thischan.format = (val >> 29) & 0x3;
847
+        thischan.keyon = (val >> 31) & 0x1;
848
+        KeyProbe(chan_num);
849
+        break;
850
+
851
+      case 0x4: thischan.addr = (val & 0x07FFFFFC); break;
852
+      case 0x8:
853
+                thischan.timer = (val & 0xFFFF);
854
+                thischan.loopstart = ((val >> 16) & 0xFFFF);
855
+                adjust_channel_timer(&thischan);
856
+                break;
857
+
858
+      case 0xC: thischan.length = (val & 0x003FFFFF); break; //only 22 bits of this register are used
859
+    } //switch on individual channel regs
860
+    return;
861
+  }
862
+
863
+  switch(addr)
864
+  {
865
+    //SOUNDCNT
866
+    case 0x500:
867
+      regs.mastervol = (val & 0x7F);
868
+      regs.ctl_left  = ((val >> 8) & 3);
869
+      regs.ctl_right = ((val>>10) & 3);
870
+      regs.ctl_ch1bypass = ((val >> 12) & 1);
871
+      regs.ctl_ch3bypass = ((val >> 13) & 1);
872
+      regs.masteren = ((val >> 15) & 1);
873
+      for(u8 i=0; i<16; i++)
874
+        KeyProbe(i);
875
+      break;
876
+
877
+      //SOUNDBIAS
878
+    case 0x504: regs.soundbias = (val & 0x3FF);
879
+
880
+                //SNDCAP0CNT/SNDCAP1CNT
881
+    case 0x508:
882
+                regs.cap[0].add = BIT0(val);
883
+                regs.cap[0].source = BIT1(val);
884
+                regs.cap[0].oneshot = BIT2(val);
885
+                regs.cap[0].bits8 = BIT3(val);
886
+                regs.cap[0].active = BIT7(val);
887
+                ProbeCapture(0);
888
+
889
+                regs.cap[1].add = BIT8(val);
890
+                regs.cap[1].source = BIT9(val);
891
+                regs.cap[1].oneshot = BIT10(val);
892
+                regs.cap[1].bits8 = BIT11(val);
893
+                regs.cap[1].active = BIT15(val);
894
+                ProbeCapture(1);
895
+                break;
896
+
897
+                //SNDCAP0DAD
898
+    case 0x510: regs.cap[0].dad = (val & 0x07FFFFFC); break;
899
+
900
+                //SNDCAP0LEN
901
+    case 0x514: regs.cap[0].len = (val & 0xFFFF); break;
902
+
903
+                //SNDCAP1DAD
904
+    case 0x518: regs.cap[1].dad = (val & 0x07FFFFFC); break;
905
+
906
+                //SNDCAP1LEN
907
+    case 0x51C: regs.cap[1].len = (val & 0xFFFF); break;
908
+  } //switch on address
786 909
 }
787 910
 
788 911
 //////////////////////////////////////////////////////////////////////////////
789 912
 
790
-static inline int32_t Interpolate(int32_t a, int32_t b, double ratio, SPUInterpolationMode INTERPOLATE_MODE)
913
+static FORCEINLINE void FetchPSGData(channel_struct *chan, s32 *data)
791 914
 {
792
-	double sampleA = static_cast<double>(a);
793
-	double sampleB = static_cast<double>(b);
794
-	ratio = ratio - u32floor(ratio);
795
-
796
-	switch (INTERPOLATE_MODE)
797
-	{
798
-		case SPUInterpolation_Cosine:
799
-			// Cosine Interpolation Formula:
800
-			// ratio2 = (1 - cos(ratio * M_PI)) / 2
801
-			// sampleI = sampleA * (1 - ratio2) + sampleB * ratio2
802
-			return s32floor((cos_lut[static_cast<unsigned>(ratio * COSINE_INTERPOLATION_RESOLUTION)] * (sampleB - sampleA)) + sampleA);
803
-
804
-		case SPUInterpolation_Linear:
805
-			// Linear Interpolation Formula:
806
-			// sampleI = sampleA * (1 - ratio) + sampleB * ratio
807
-			return s32floor((ratio * (sampleB - sampleA)) + sampleA);
808
-
809
-		default:
810
-			break;
811
-	}
812
-
813
-	return a;
915
+  if (chan->sampcnt < 0)
916
+  {
917
+    *data = 0;
918
+    return;
919
+  }
920
+
921
+  if(chan->num < 8)
922
+  {
923
+    *data = 0;
924
+  }
925
+  else if(chan->num < 14)
926
+  {
927
+    *data = (s32)wavedutytbl[chan->waveduty][(sputrunc(chan->sampcnt)) & 0x7];
928
+  }
929
+  else
930
+  {
931
+    if(chan->lastsampcnt == sputrunc(chan->sampcnt))
932
+    {
933
+      *data = (s32)chan->psgnoise_last;
934
+      return;
935
+    }
936
+
937
+    u32 max = sputrunc(chan->sampcnt);
938
+    for(u32 i = chan->lastsampcnt; i < max; i++)
939
+    {
940
+      if(chan->x & 0x1)
941
+      {
942
+        chan->x = (chan->x >> 1) ^ 0x6000;
943
+        chan->psgnoise_last = -0x7FFF;
944
+      }
945
+      else
946
+      {
947
+        chan->x >>= 1;
948
+        chan->psgnoise_last = 0x7FFF;
949
+      }
950
+    }
951
+
952
+    chan->lastsampcnt = sputrunc(chan->sampcnt);
953
+
954
+    *data = (s32)chan->psgnoise_last;
955
+  }
814 956
 }
815 957
 
816 958
 //////////////////////////////////////////////////////////////////////////////
817 959
 
818
-static inline void Fetch8BitData(const channel_struct *const chan, int32_t *const data, SPUInterpolationMode INTERPOLATE_MODE)
960
+static FORCEINLINE void MixL(SPU_struct* SPU, channel_struct *chan, s32 data)
819 961
 {
820
-	if (chan->sampcnt < 0)
821
-	{
822
-		*data = 0;
823
-		return;
824
-	}
825
-
826
-	uint32_t loc = u32floor(chan->sampcnt);
827
-	if (INTERPOLATE_MODE != SPUInterpolation_None)
828
-	{
829
-		int32_t a = static_cast<int32_t>(read_s8(chan->addr + loc) << 8);
830
-		if (loc < (chan->totlength << 2) - 1)
831
-		{
832
-			int32_t b = static_cast<int32_t>(read_s8(chan->addr + loc + 1) << 8);
833
-			a = Interpolate(a, b, chan->sampcnt, INTERPOLATE_MODE);
834
-		}
835
-		*data = a;
836
-	}
837
-	else
838
-		*data = static_cast<int32_t>(read_s8(chan->addr + loc) << 8);
962
+  data = spumuldiv7(data, chan->vol) >> volume_shift[chan->volumeDiv];
963
+  SPU->sndbuf[SPU->bufpos<<1] += data;
839 964
 }
840 965
 
841
-static inline void Fetch16BitData(const channel_struct *const chan, int32_t *const data, SPUInterpolationMode INTERPOLATE_MODE)
966
+static FORCEINLINE void MixR(SPU_struct* SPU, channel_struct *chan, s32 data)
842 967
 {
843
-	if (chan->sampcnt < 0)
844
-	{
845
-		*data = 0;
846
-		return;
847
-	}
848
-
849
-	if (INTERPOLATE_MODE != SPUInterpolation_None)
850
-	{
851
-		uint32_t loc = u32floor(chan->sampcnt);
852
-
853
-		int32_t a = static_cast<int32_t>(read16(loc * 2 + chan->addr));
854
-		if (loc < (chan->totlength << 1) - 1)
855
-		{
856
-			int32_t b = static_cast<int32_t>(read16(loc * 2 + chan->addr + 2));
857
-			a = Interpolate(a, b, chan->sampcnt, INTERPOLATE_MODE);
858
-		}
859
-		*data = a;
860
-	}
861
-	else
862
-		*data = read16(chan->addr + u32floor(chan->sampcnt) * 2);
968
+  data = spumuldiv7(data, chan->vol) >> volume_shift[chan->volumeDiv];
969
+  SPU->sndbuf[(SPU->bufpos<<1)+1] += data;
863 970
 }
864 971
 
865
-static inline void FetchADPCMData(channel_struct *const chan, int32_t *const data, SPUInterpolationMode INTERPOLATE_MODE)
972
+static FORCEINLINE void MixLR(SPU_struct* SPU, channel_struct *chan, s32 data)
866 973
 {
867
-	if (chan->sampcnt < 8)
868
-	{
869
-		*data = 0;
870
-		return;
871
-	}
872
-
873
-	// No sense decoding, just return the last sample
874
-	if (chan->lastsampcnt != u32floor(chan->sampcnt))
875
-	{
876
-		uint32_t endExclusive = u32floor(chan->sampcnt + 1);
877
-		for (uint32_t i = chan->lastsampcnt + 1; i < endExclusive; ++i)
878
-		{
879
-			uint32_t shift = (i & 1) << 2;
880
-			uint32_t data4bit = static_cast<uint32_t>(read08(chan->addr + (i >> 1))) >> shift;
881
-
882
-			int32_t diff = precalcdifftbl[chan->index][data4bit & 0xF];
883
-			chan->index = precalcindextbl[chan->index][data4bit & 0x7];
884
-
885
-			chan->pcm16b_last = chan->pcm16b;
886
-			chan->pcm16b = MinMax(chan->pcm16b+diff, -0x8000, 0x7FFF);
887
-
888
-			if (i == static_cast<uint32_t>(chan->loopstart << 3))
889
-			{
890
-				if (chan->loop_index != K_ADPCM_LOOPING_RECOVERY_INDEX)
891
-					printf("over-snagging\n");
892
-				chan->loop_pcm16b = chan->pcm16b;
893
-				chan->loop_index = chan->index;
894
-			}
895
-		}
896
-
897
-		chan->lastsampcnt = u32floor(chan->sampcnt);
898
-	}
899
-
900
-	if (INTERPOLATE_MODE != SPUInterpolation_None)
901
-		*data = Interpolate(static_cast<int32_t>(chan->pcm16b_last), static_cast<int32_t>(chan->pcm16b), chan->sampcnt, INTERPOLATE_MODE);
902
-	else
903
-		*data = static_cast<int32_t>(chan->pcm16b);
904
-}
905
-
906
-static inline void FetchPSGData(channel_struct *chan, int32_t *data)
907
-{
908
-	if (chan->sampcnt < 0)
909
-	{
910
-		*data = 0;
911
-		return;
912
-	}
913
-
914
-	if (chan->num < 8)
915
-		*data = 0;
916
-	else if (chan->num < 14)
917
-		*data = static_cast<int32_t>(wavedutytbl[chan->waveduty][u32floor(chan->sampcnt) & 0x7]);
918
-	else
919
-	{
920
-		if (chan->lastsampcnt == u32floor(chan->sampcnt))
921
-		{
922
-			*data = static_cast<int32_t>(chan->psgnoise_last);
923
-			return;
924
-		}
925
-
926
-		uint32_t max = u32floor(chan->sampcnt);
927
-		for (uint32_t i = chan->lastsampcnt; i < max; ++i)
928
-		{
929
-			if (chan->x & 0x1)
930
-			{
931
-				chan->x = (chan->x >> 1) ^ 0x6000;
932
-				chan->psgnoise_last = -0x7FFF;
933
-			}
934
-			else
935
-			{
936
-				chan->x >>= 1;
937
-				chan->psgnoise_last = 0x7FFF;
938
-			}
939
-		}
940
-
941
-		chan->lastsampcnt = u32floor(chan->sampcnt);
942
-
943
-		*data = static_cast<int32_t>(chan->psgnoise_last);
944
-	}
974
+  data = spumuldiv7(data, chan->vol) >> volume_shift[chan->volumeDiv];
975
+  SPU->sndbuf[SPU->bufpos<<1] += spumuldiv7(data, 127 - chan->pan);
976
+  SPU->sndbuf[(SPU->bufpos<<1)+1] += spumuldiv7(data, chan->pan);
945 977
 }
946 978
 
947 979
 //////////////////////////////////////////////////////////////////////////////
948 980
 
949
-static inline void MixL(SPU_struct *SPU, channel_struct *chan, int32_t data)
981
+template<int FORMAT> static FORCEINLINE void TestForLoop(SPU_struct *SPU, channel_struct *chan)
950 982
 {
951
-	data = spumuldiv7(data, chan->vol) >> chan->datashift;
952
-	SPU->sndbuf[SPU->bufpos << 1] += data;
983
+  const int shift = (FORMAT == 0 ? 2 : 1);
984
+
985
+  chan->sampcnt += chan->sampinc;
986
+
987
+  if (chan->sampcnt > chan->double_totlength_shifted)
988
+  {
989
+    // Do we loop? Or are we done?
990
+    if (chan->repeat == 1)
991
+    {
992
+      while (chan->sampcnt > chan->double_totlength_shifted) {
993
+        chan->sampcnt -= chan->double_totlength_shifted - (double)(chan->loopstart << shift);
994
+      }
995
+    }
996
+    else
997
+    {
998
+      SPU->KeyOff(chan->num);
999
+      SPU->bufpos = SPU->buflength;
1000
+    }
1001
+  }
953 1002
 }
954 1003
 
955
-static inline void MixR(SPU_struct *SPU, channel_struct *chan, int32_t data)
1004
+static FORCEINLINE void TestForLoop2(SPU_struct *SPU, channel_struct *chan)
956 1005
 {
957
-	data = spumuldiv7(data, chan->vol) >> chan->datashift;
958
-	SPU->sndbuf[(SPU->bufpos << 1) + 1] += data;
1006
+  // Minimum length (the sum of PNT+LEN) is 4 words (16 bytes),
1007
+  // smaller values (0..3 words) are causing hang-ups
1008
+  // (busy bit remains set infinite, but no sound output occurs).
1009
+  // fix: 7th Dragon (JP) - http://sourceforge.net/p/desmume/bugs/1357/
1010
+  if (chan->totlength < 4) return;
1011
+
1012
+  chan->sampcnt += chan->sampinc;
1013
+
1014
+  if (chan->sampcnt > chan->double_totlength_shifted)
1015
+  {
1016
+    // Do we loop? Or are we done?
1017
+    if (chan->repeat == 1)
1018
+    {
1019
+      double step = (chan->double_totlength_shifted - (double)(chan->loopstart << 3));
1020
+
1021
+      while (chan->sampcnt > chan->double_totlength_shifted) chan->sampcnt -= step;
1022
+
1023
+      if(chan->loop_index == K_ADPCM_LOOPING_RECOVERY_INDEX)
1024
+      {
1025
+        chan->pcm16b = (s16)read16(chan->addr);
1026
+        chan->index = read08(chan->addr+2) & 0x7F;
1027
+        chan->lastsampcnt = 7;
1028
+      }
1029
+      else
1030
+      {
1031
+        chan->pcm16b = chan->loop_pcm16b;
1032
+        chan->index = chan->loop_index;
1033
+        chan->lastsampcnt = (chan->loopstart << 3);
1034
+      }
1035
+    }
1036
+    else
1037
+    {
1038
+      chan->status = CHANSTAT_STOPPED;
1039
+      SPU->KeyOff(chan->num);
1040
+      SPU->bufpos = SPU->buflength;
1041
+    }
1042
+  }
959 1043
 }
960 1044
 
961
-static inline void MixLR(SPU_struct *SPU, channel_struct *chan, int32_t data)
1045
+template<int CHANNELS> FORCEINLINE static void SPU_Mix(SPU_struct* SPU, channel_struct *chan, s32 data)
962 1046
 {
963
-	data = spumuldiv7(data, chan->vol) >> chan->datashift;
964
-	SPU->sndbuf[SPU->bufpos << 1] += spumuldiv7(data, 127 - chan->pan);
965
-	SPU->sndbuf[(SPU->bufpos << 1) + 1] += spumuldiv7(data, chan->pan);
1047
+  switch(CHANNELS)
1048
+  {
1049
+    case 0: MixL(SPU, chan, data); break;
1050
+    case 1: MixLR(SPU, chan, data); break;
1051
+    case 2: MixR(SPU, chan, data); break;
1052
+  }
1053
+  SPU->lastdata = data;
966 1054
 }
967 1055
 
968
-//////////////////////////////////////////////////////////////////////////////
969
-
970
-static inline void TestForLoop(SPU_struct *SPU, channel_struct *chan, int FORMAT)
1056
+//WORK
1057
+  template<int FORMAT, int CHANNELS>
1058
+FORCEINLINE static void ____SPU_ChanUpdate(SPU_struct* const SPU, channel_struct* const chan)
971 1059
 {
972
-	int shift = !FORMAT ? 2 : 1;
973
-
974
-	chan->sampcnt += chan->sampinc;
975
-
976
-	if (chan->sampcnt > chan->double_totlength_shifted)
977
-	{
978
-		// Do we loop? Or are we done?
979
-		if (chan->repeat == 1)
980
-		{
981
-			while (chan->sampcnt > chan->double_totlength_shifted)
982
-				chan->sampcnt -= chan->double_totlength_shifted - static_cast<double>(chan->loopstart << shift);
983
-			//chan->sampcnt = (double)(chan->loopstart << shift);
984
-		}
985
-		else
986
-		{
987
-			SPU->KeyOff(chan->num);
988
-			SPU->bufpos = SPU->buflength;
989
-		}
990
-	}
1060
+  for (; SPU->bufpos < SPU->buflength; SPU->bufpos++)
1061
+  {
1062
+    if(CHANNELS != -1)
1063
+    {
1064
+      s32 data;
1065
+      if (chan->sampcnt < 0) {
1066
+        data = 0;
1067
+      } else if (FORMAT == 3) {
1068
+        FetchPSGData(chan, &data);
1069
+      } else {
1070
+        const SampleData& sample = sampleCache.getSample(chan->addr, chan->loopstart, chan->length, SampleData::Format(FORMAT));
1071
+        data = sample.sampleAt(chan->sampcnt, IInterpolator::allInterpolators[CommonSettings.spuInterpolationMode]);
1072
+      }
1073
+      SPU_Mix<CHANNELS>(SPU, chan, data);
1074
+    }
1075
+
1076
+    switch(FORMAT) {
1077
+      case 0: case 1: TestForLoop<FORMAT>(SPU, chan); break;
1078
+      case 2: TestForLoop2(SPU, chan); break;
1079
+      case 3: chan->sampcnt += chan->sampinc; break;
1080
+    }
1081
+  }
991 1082
 }
992 1083
 
993
-static inline void TestForLoop2(SPU_struct *SPU, channel_struct *chan)
1084
+template<int FORMAT>
1085
+FORCEINLINE static void ___SPU_ChanUpdate(const bool actuallyMix, SPU_struct* const SPU, channel_struct* const chan)
994 1086
 {
995
-	chan->sampcnt += chan->sampinc;
996
-
997
-	if (chan->sampcnt > chan->double_totlength_shifted)
998
-	{
999
-		// Do we loop? Or are we done?
1000
-		if (chan->repeat == 1)
1001
-		{
1002
-			while (chan->sampcnt > chan->double_totlength_shifted)
1003
-				chan->sampcnt -= chan->double_totlength_shifted - static_cast<double>(chan->loopstart << 3);
1004
-
1005
-			if (chan->loop_index == K_ADPCM_LOOPING_RECOVERY_INDEX)
1006
-			{
1007
-				chan->pcm16b = read16(chan->addr);
1008
-				chan->index = read08(chan->addr + 2) & 0x7F;
1009
-				chan->lastsampcnt = 7;
1010
-			}
1011
-			else
1012
-			{
1013
-				chan->pcm16b = chan->loop_pcm16b;
1014
-				chan->index = chan->loop_index;
1015
-				chan->lastsampcnt = chan->loopstart << 3;
1016
-			}
1017
-		}
1018
-		else
1019
-		{
1020
-			chan->status = CHANSTAT_STOPPED;
1021
-			SPU->KeyOff(chan->num);
1022
-			SPU->bufpos = SPU->buflength;
1023
-		}
1024
-	}
1087
+  if(!actuallyMix)
1088
+    ____SPU_ChanUpdate<FORMAT,-1>(SPU,chan);
1089
+  else if (chan->pan == 0)
1090
+    ____SPU_ChanUpdate<FORMAT,0>(SPU,chan);
1091
+  else if (chan->pan == 127)
1092
+    ____SPU_ChanUpdate<FORMAT,2>(SPU,chan);
1093
+  else
1094
+    ____SPU_ChanUpdate<FORMAT,1>(SPU,chan);
1025 1095
 }
1026 1096
 
1027
-static inline void SPU_Mix(SPU_struct *SPU, channel_struct *chan, int32_t data, int CHANNELS)
1097
+FORCEINLINE static void _SPU_ChanUpdate(const bool actuallyMix, SPU_struct* const SPU, channel_struct* const chan)
1028 1098
 {
1029
-	switch (CHANNELS)
1030
-	{
1031
-		case 0:
1032
-			MixL(SPU, chan, data);
1033
-			break;
1034
-		case 1:
1035
-			MixLR(SPU, chan, data);
1036
-			break;
1037
-		case 2:
1038
-			MixR(SPU, chan, data);
1039
-	}
1040
-	SPU->lastdata = data;
1099
+  switch(chan->format)
1100
+  {
1101
+    case 0: ___SPU_ChanUpdate<0>(actuallyMix, SPU, chan); break;
1102
+    case 1: ___SPU_ChanUpdate<1>(actuallyMix, SPU, chan); break;
1103
+    case 2: ___SPU_ChanUpdate<2>(actuallyMix, SPU, chan); break;
1104
+    case 3: ___SPU_ChanUpdate<3>(actuallyMix, SPU, chan); break;
1105
+    default: assert(false);
1106
+  }
1041 1107
 }
1042 1108
 
1043
-// WORK
1044
-static inline void ____SPU_ChanUpdate(SPU_struct *const SPU, channel_struct *const chan, int FORMAT, SPUInterpolationMode INTERPOLATE_MODE, int CHANNELS)
1109
+//ENTERNEW
1110
+static void SPU_MixAudio_Advanced(bool actuallyMix, SPU_struct *SPU, int length)
1045 1111
 {
1046
-	for (; SPU->bufpos < SPU->buflength; ++SPU->bufpos)
1047
-	{
1048
-		if (CHANNELS != -1)
1049
-		{
1050
-			int32_t data = 0;
1051
-			switch (FORMAT)
1052
-			{
1053
-				case 0:
1054
-					Fetch8BitData(chan, &data, INTERPOLATE_MODE);
1055
-					break;
1056
-				case 1:
1057
-					Fetch16BitData(chan, &data, INTERPOLATE_MODE);
1058
-					break;
1059
-				case 2:
1060
-					FetchADPCMData(chan, &data, INTERPOLATE_MODE);
1061
-					break;
1062
-				case 3:
1063
-					FetchPSGData(chan, &data);
1064
-			}
1065
-			SPU_Mix(SPU, chan, data, CHANNELS);
1066
-		}
1067
-
1068
-		switch (FORMAT)
1069
-		{
1070
-			case 0:
1071
-			case 1:
1072
-				TestForLoop(SPU, chan, FORMAT);
1073
-				break;
1074
-			case 2:
1075
-				TestForLoop2(SPU, chan);
1076
-				break;
1077
-			case 3:
1078
-				chan->sampcnt += chan->sampinc;
1079
-		}
1080
-	}
1112
+  //the advanced spu function correctly handles all sound control mixing options, as well as capture
1113
+  //this code is not entirely optimal, as it relies on sort of manhandling the core mixing functions
1114
+  //in order to get the results it needs.
1115
+
1116
+  //THIS IS MAX HACKS!!!!
1117
+  //AND NEEDS TO BE REWRITTEN ALONG WITH THE DEEPEST PARTS OF THE SPU
1118
+  //ONCE WE KNOW THAT IT WORKS
1119
+
1120
+  //BIAS gets ignored since our spu is still not bit perfect,
1121
+  //and it doesnt matter for purposes of capture
1122
+
1123
+  //-----------DEBUG CODE
1124
+  bool skipcap = false;
1125
+  //-----------------
1126
+
1127
+  s32 samp0[2] = {0,0};
1128
+
1129
+  //believe it or not, we are going to do this one sample at a time.
1130
+  //like i said, it is slower.
1131
+  for (int samp = 0; samp < length; samp++)
1132
+  {
1133
+    SPU->sndbuf[0] = 0;
1134
+    SPU->sndbuf[1] = 0;
1135
+    SPU->buflength = 1;
1136
+
1137
+    s32 capmix[2] = {0,0};
1138
+    s32 mix[2] = {0,0};
1139
+    s32 chanout[16];
1140
+    s32 submix[32];
1141
+    static int tsamp = 0;
1142
+    ++tsamp;
1143
+
1144
+    //generate each channel, and helpfully mix it at the same time
1145
+    for (int i = 0; i < 16; i++)
1146
+    {
1147
+      channel_struct *chan = &SPU->channels[i];
1148
+
1149
+      if (chan->status == CHANSTAT_PLAY)
1150
+      {
1151
+        SPU->bufpos = 0;
1152
+
1153
+        bool bypass = false;
1154
+        if (i==1 && SPU->regs.ctl_ch1bypass) bypass=true;
1155
+        if (i==3 && SPU->regs.ctl_ch3bypass) bypass=true;
1156
+
1157
+
1158
+        //output to mixer unless we are bypassed.
1159
+        //dont output to mixer if the user muted us
1160
+        bool outputToMix = true;
1161
+        if (CommonSettings.spu_muteChannels[i]) outputToMix = false;
1162
+        if (bypass) outputToMix = false;
1163
+        bool outputToCap = outputToMix;
1164
+        if (CommonSettings.spu_captureMuted && !bypass) outputToCap = true;
1165
+
1166
+        //channels 1 and 3 should probably always generate their audio
1167
+        //internally at least, just in case they get used by the spu output
1168
+        bool domix = outputToCap || outputToMix || i==1 || i==3;
1169
+
1170
+        //clear the output buffer since this is where _SPU_ChanUpdate wants to accumulate things
1171
+        SPU->sndbuf[0] = SPU->sndbuf[1] = 0;
1172
+
1173
+        //get channel's next output sample.
1174
+        _SPU_ChanUpdate(domix, SPU, chan);
1175
+        chanout[i] = SPU->lastdata >> volume_shift[chan->volumeDiv];
1176
+
1177
+        //save the panned results
1178
+        submix[i*2] = SPU->sndbuf[0];
1179
+        submix[i*2+1] = SPU->sndbuf[1];
1180
+
1181
+        //send sample to our capture mix
1182
+        if (outputToCap)
1183
+        {
1184
+          capmix[0] += submix[i*2];
1185
+          capmix[1] += submix[i*2+1];
1186
+        }
1187
+
1188
+        //send sample to our main mixer
1189
+        if (outputToMix)
1190
+        {
1191
+          mix[0] += submix[i*2];
1192
+          mix[1] += submix[i*2+1];
1193
+        }
1194
+      }
1195
+      else
1196
+      {
1197
+        chanout[i] = 0;
1198
+        submix[i*2] = 0;
1199
+        submix[i*2+1] = 0;
1200
+      }
1201
+    } //foreach channel
1202
+
1203
+    s32 mixout[2] = {mix[0],mix[1]};
1204
+    s32 capmixout[2] = {capmix[0],capmix[1]};
1205
+    s32 sndout[2];
1206
+    s32 capout[2];
1207
+
1208
+    //create SPU output
1209
+    switch (SPU->regs.ctl_left)
1210
+    {
1211
+      case SPU_struct::REGS::LOM_LEFT_MIXER: sndout[0] = mixout[0]; break;
1212
+      case SPU_struct::REGS::LOM_CH1: sndout[0] = submix[1*2+0]; break;
1213
+      case SPU_struct::REGS::LOM_CH3: sndout[0] = submix[3*2+0]; break;
1214
+      case SPU_struct::REGS::LOM_CH1_PLUS_CH3: sndout[0] = submix[1*2+0] + submix[3*2+0]; break;
1215
+    }
1216
+    switch (SPU->regs.ctl_right)
1217
+    {
1218
+      case SPU_struct::REGS::ROM_RIGHT_MIXER: sndout[1] = mixout[1]; break;
1219
+      case SPU_struct::REGS::ROM_CH1: sndout[1] = submix[1*2+1]; break;
1220
+      case SPU_struct::REGS::ROM_CH3: sndout[1] = submix[3*2+1]; break;
1221
+      case SPU_struct::REGS::ROM_CH1_PLUS_CH3: sndout[1] = submix[1*2+1] + submix[3*2+1]; break;
1222
+    }
1223
+
1224
+
1225
+    //generate capture output ("capture bugs" from gbatek are not emulated)
1226
+    if (SPU->regs.cap[0].source == 0)
1227
+      capout[0] = capmixout[0]; //cap0 = L-mix
1228
+    else if (SPU->regs.cap[0].add)
1229
+      capout[0] = chanout[0] + chanout[1]; //cap0 = ch0+ch1
1230
+    else capout[0] = chanout[0]; //cap0 = ch0
1231
+
1232
+    if (SPU->regs.cap[1].source == 0)
1233
+      capout[1] = capmixout[1]; //cap1 = R-mix
1234
+    else if (SPU->regs.cap[1].add)
1235
+      capout[1] = chanout[2] + chanout[3]; //cap1 = ch2+ch3
1236
+    else capout[1] = chanout[2]; //cap1 = ch2
1237
+
1238
+    capout[0] = MinMax(capout[0],-0x8000,0x7FFF);
1239
+    capout[1] = MinMax(capout[1],-0x8000,0x7FFF);
1240
+
1241
+    //write the output sample where it is supposed to go
1242
+    if (samp == 0)
1243
+    {
1244
+      samp0[0] = sndout[0];
1245
+      samp0[1] = sndout[1];
1246
+    }
1247
+    else
1248
+    {
1249
+      SPU->sndbuf[samp*2+0] = sndout[0];
1250
+      SPU->sndbuf[samp*2+1] = sndout[1];
1251
+    }
1252
+
1253
+    for (int capchan = 0; capchan < 2; capchan++)
1254
+    {
1255
+      if (SPU->regs.cap[capchan].runtime.running)
1256
+      {
1257
+        SPU_struct::REGS::CAP& cap = SPU->regs.cap[capchan];
1258
+        u32 last = sputrunc(cap.runtime.sampcnt);
1259
+        cap.runtime.sampcnt += SPU->channels[1+2*capchan].sampinc;
1260
+        u32 curr = sputrunc(cap.runtime.sampcnt);
1261
+        for (u32 j = last; j < curr; j++)
1262
+        {
1263
+          //so, this is a little strange. why go through a fifo?
1264
+          //it seems that some games will set up a reverb effect by capturing
1265
+          //to the nearly same address as playback, but ahead by a couple.
1266
+          //So, playback will always end up being what was captured a couple of samples ago.
1267
+          //This system counts on playback always having read ahead 16 samples.
1268
+          //In that case, playback will end up being what was processed at one entire buffer length ago,
1269
+          //since the 16 samples would have read ahead before they got captured over
1270
+
1271
+          //It's actually the source channels which should have a fifo, but we are
1272
+          //not going to take the hit in speed and complexity. Save it for a future rewrite.
1273
+          //Instead, what we do here is delay the capture by 16 samples to create a similar effect.
1274
+          //Subjectively, it seems to be working.
1275
+
1276
+          //Don't do anything until the fifo is filled, so as to delay it
1277
+          if (cap.runtime.fifo.size < 16)
1278
+          {
1279
+            cap.runtime.fifo.enqueue(capout[capchan]);
1280
+            continue;
1281
+          }
1282
+
1283
+          //(actually capture sample from fifo instead of most recently generated)
1284
+          u32 multiplier;
1285
+          s32 sample = cap.runtime.fifo.dequeue();
1286
+          cap.runtime.fifo.enqueue(capout[capchan]);
1287
+
1288
+          if (cap.bits8)
1289
+          {
1290
+            s8 sample8 = sample >> 8;
1291
+            if (skipcap) _MMU_write08<1,MMU_AT_DMA>(cap.runtime.curdad,0);
1292
+            else _MMU_write08<1,MMU_AT_DMA>(cap.runtime.curdad,sample8);
1293
+            cap.runtime.curdad++;
1294
+            multiplier = 4;
1295
+          }
1296
+          else
1297
+          {
1298
+            s16 sample16 = sample;
1299
+            if (skipcap) _MMU_write16<1,MMU_AT_DMA>(cap.runtime.curdad,0);
1300
+            else _MMU_write16<1,MMU_AT_DMA>(cap.runtime.curdad,sample16);
1301
+            cap.runtime.curdad+=2;
1302
+            multiplier = 2;
1303
+          }
1304
+
1305
+          if (cap.runtime.curdad >= cap.runtime.maxdad)
1306
+          {
1307
+            cap.runtime.curdad = cap.dad;
1308
+            cap.runtime.sampcnt -= cap.len*multiplier;
1309
+          }
1310
+        } //sampinc loop
1311
+      } //if capchan running
1312
+    } //capchan loop
1313
+  } //main sample loop
1314
+
1315
+  SPU->sndbuf[0] = samp0[0];
1316
+  SPU->sndbuf[1] = samp0[1];
1081 1317
 }
1082 1318
 
1083
-static inline void ___SPU_ChanUpdate(bool actuallyMix, SPU_struct *const SPU, channel_struct *const chan, int FORMAT, SPUInterpolationMode INTERPOLATE_MODE)
1084
-{
1085
-	if (!actuallyMix)
1086
-		____SPU_ChanUpdate(SPU, chan, FORMAT, INTERPOLATE_MODE, -1);
1087
-	else if (!chan->pan)
1088
-		____SPU_ChanUpdate(SPU, chan, FORMAT, INTERPOLATE_MODE, 0);
1089
-	else if (chan->pan == 127)
1090
-		____SPU_ChanUpdate(SPU, chan, FORMAT, INTERPOLATE_MODE, 2);
1091
-	else
1092
-		____SPU_ChanUpdate(SPU, chan, FORMAT, INTERPOLATE_MODE, 1);
1093
-}
1094
-
1095
-static inline void __SPU_ChanUpdate(bool actuallyMix, SPU_struct *const SPU, channel_struct *const chan, SPUInterpolationMode INTERPOLATE_MODE)
1096
-{
1097
-	switch (chan->format)
1098
-	{
1099
-		case 0:
1100
-			___SPU_ChanUpdate(actuallyMix, SPU, chan, 0, INTERPOLATE_MODE);
1101
-			break;
1102
-		case 1:
1103
-			___SPU_ChanUpdate(actuallyMix, SPU, chan, 1, INTERPOLATE_MODE);
1104
-			break;
1105
-		case 2:
1106
-			___SPU_ChanUpdate(actuallyMix, SPU, chan, 2, INTERPOLATE_MODE);
1107
-			break;
1108
-		case 3:
1109
-			___SPU_ChanUpdate(actuallyMix, SPU, chan, 3, INTERPOLATE_MODE);
1110
-			break;
1111
-		default:
1112
-			assert(false);
1113
-	}
1114
-}
1115
-
1116
-static inline void _SPU_ChanUpdate(bool actuallyMix, SPU_struct *const SPU, channel_struct *const chan)
1117
-{
1118
-	switch (CommonSettings.spuInterpolationMode)
1119
-	{
1120
-		case SPUInterpolation_None:
1121
-			__SPU_ChanUpdate(actuallyMix, SPU, chan, SPUInterpolation_None);
1122
-			break;
1123
-		case SPUInterpolation_Linear:
1124
-			__SPU_ChanUpdate(actuallyMix, SPU, chan, SPUInterpolation_Linear);
1125
-			break;
1126
-		case SPUInterpolation_Cosine:
1127
-			__SPU_ChanUpdate(actuallyMix, SPU, chan, SPUInterpolation_Cosine);
1128
-			break;
1129
-	}
1130
-}
1131
-
1132
-// ENTERNEW
1133
-static void SPU_MixAudio_Advanced(bool, SPU_struct *SPU, int length)
1134
-{
1135
-	// the advanced spu function correctly handles all sound control mixing options, as well as capture
1136
-	// this code is not entirely optimal, as it relies on sort of manhandling the core mixing functions
1137
-	// in order to get the results it needs.
1138
-
1139
-	// THIS IS MAX HACKS!!!!
1140
-	// AND NEEDS TO BE REWRITTEN ALONG WITH THE DEEPEST PARTS OF THE SPU
1141
-	// ONCE WE KNOW THAT IT WORKS
1142
-
1143
-	// BIAS gets ignored since our spu is still not bit perfect,
1144
-	// and it doesnt matter for purposes of capture
1145
-
1146
-	// -----------DEBUG CODE
1147
-	bool skipcap = false;
1148
-	// -----------------
1149
-
1150
-	int32_t samp0[] = { 0, 0 };
1151
-
1152
-	// believe it or not, we are going to do this one sample at a time.
1153
-	// like i said, it is slower.
1154
-	for (int samp = 0; samp < length; ++samp)
1155
-	{
1156
-		SPU->sndbuf[0] = SPU->sndbuf[1] = 0;
1157
-		SPU->buflength = 1;
1158
-
1159
-		int32_t capmix[] = { 0, 0 }, mix[] = { 0, 0 };
1160
-		int32_t chanout[16];
1161
-		int32_t submix[32];
1162
-
1163
-		// generate each channel, and helpfully mix it at the same time
1164
-		for (int i = 0; i < 16; ++i)
1165
-		{
1166
-			channel_struct *chan = &SPU->channels[i];
1167
-
1168
-			if (chan->status == CHANSTAT_PLAY)
1169
-			{
1170
-				SPU->bufpos = 0;
1171
-
1172
-				bool bypass = false;
1173
-				if (i == 1 && SPU->regs.ctl_ch1bypass)
1174
-					bypass = true;
1175
-				if (i == 3 && SPU->regs.ctl_ch3bypass)
1176
-					bypass = true;
1177
-
1178
-				// output to mixer unless we are bypassed.
1179
-				// dont output to mixer if the user muted us
1180
-				bool outputToMix = true;
1181
-				if (CommonSettings.spu_muteChannels[i])
1182
-					outputToMix = false;
1183
-				if (bypass)
1184
-					outputToMix = false;
1185
-				bool outputToCap = outputToMix;
1186
-				if (CommonSettings.spu_captureMuted && !bypass)
1187
-					outputToCap = true;
1188
-
1189
-				// channels 1 and 3 should probably always generate their audio
1190
-				// internally at least, just in case they get used by the spu output
1191
-				bool domix = outputToCap || outputToMix || i == 1 || i == 3;
1192
-
1193
-				// clear the output buffer since this is where _SPU_ChanUpdate wants to accumulate things
1194
-				SPU->sndbuf[0] = SPU->sndbuf[1] = 0;
1195
-
1196
-				// get channel's next output sample.
1197
-				_SPU_ChanUpdate(domix, SPU, chan);
1198
-				chanout[i] = SPU->lastdata >> chan->datashift;
1199
-
1200
-				// save the panned results
1201
-				submix[i * 2] = SPU->sndbuf[0];
1202
-				submix[i * 2 + 1] = SPU->sndbuf[1];
1203
-
1204
-				// send sample to our capture mix
1205
-				if (outputToCap)
1206
-				{
1207
-					capmix[0] += submix[i * 2];
1208
-					capmix[1] += submix[i * 2 + 1];
1209
-				}
1210
-
1211
-				// send sample to our main mixer
1212
-				if (outputToMix)
1213
-				{
1214
-					mix[0] += submix[i * 2];
1215
-					mix[1] += submix[i * 2 + 1];
1216
-				}
1217
-			}
1218
-			else
1219
-				chanout[i] = submix[i * 2] = submix[i * 2 + 1] = 0;
1220
-		} // foreach channel
1221
-
1222
-		int32_t mixout[] = { mix[0], mix[1] };
1223
-		int32_t capmixout[] = { capmix[0], capmix[1] };
1224
-		int32_t sndout[] = { 0, 0 };
1225
-		int32_t capout[2];
1226
-
1227
-		// create SPU output
1228
-		switch (SPU->regs.ctl_left)
1229
-		{
1230
-			case SPU_struct::REGS::LOM_LEFT_MIXER:
1231
-				sndout[0] = mixout[0];
1232
-				break;
1233
-			case SPU_struct::REGS::LOM_CH1:
1234
-				sndout[0] = submix[2];
1235
-				break;
1236
-			case SPU_struct::REGS::LOM_CH3:
1237
-				sndout[0] = submix[6];
1238
-				break;
1239
-			case SPU_struct::REGS::LOM_CH1_PLUS_CH3:
1240
-				sndout[0] = submix[2] + submix[6];
1241
-		}
1242
-		switch (SPU->regs.ctl_right)
1243
-		{
1244
-			case SPU_struct::REGS::ROM_RIGHT_MIXER:
1245
-				sndout[1] = mixout[1];
1246
-				break;
1247
-			case SPU_struct::REGS::ROM_CH1:
1248
-				sndout[1] = submix[3];
1249
-				break;
1250
-			case SPU_struct::REGS::ROM_CH3:
1251
-				sndout[1] = submix[7];
1252
-				break;
1253
-			case SPU_struct::REGS::ROM_CH1_PLUS_CH3:
1254
-				sndout[1] = submix[3] + submix[7];
1255
-		}
1256
-
1257
-		// generate capture output ("capture bugs" from gbatek are not emulated)
1258
-		if (!SPU->regs.cap[0].source)
1259
-			capout[0] = capmixout[0]; // cap0 = L-mix
1260
-		else if (SPU->regs.cap[0].add)
1261
-			capout[0] = chanout[0] + chanout[1]; // cap0 = ch0+ch1
1262
-		else
1263
-			capout[0] = chanout[0]; // cap0 = ch0
1264
-
1265
-		if (!SPU->regs.cap[1].source)
1266
-			capout[1] = capmixout[1]; // cap1 = R-mix
1267
-		else if (SPU->regs.cap[1].add)
1268
-			capout[1] = chanout[2] + chanout[3]; // cap1 = ch2+ch3
1269
-		else
1270
-			capout[1] = chanout[2]; // cap1 = ch2
1271
-
1272
-		capout[0] = MinMax(capout[0], -0x8000, 0x7FFF);
1273
-		capout[1] = MinMax(capout[1], -0x8000, 0x7FFF);
1274
-
1275
-		// write the output sample where it is supposed to go
1276
-		if (!samp)
1277
-		{
1278
-			samp0[0] = sndout[0];
1279
-			samp0[1] = sndout[1];
1280
-		}
1281
-		else
1282
-		{
1283
-			SPU->sndbuf[samp * 2] = sndout[0];
1284
-			SPU->sndbuf[samp * 2 + 1] = sndout[1];
1285
-		}
1286
-
1287
-		for (int capchan = 0; capchan < 2; ++capchan)
1288
-		{
1289
-			if (SPU->regs.cap[capchan].runtime.running)
1290
-			{
1291
-				SPU_struct::REGS::CAP &cap = SPU->regs.cap[capchan];
1292
-				uint32_t last = u32floor(cap.runtime.sampcnt);
1293
-				cap.runtime.sampcnt += SPU->channels[2 * capchan + 1].sampinc;
1294
-				uint32_t curr = u32floor(cap.runtime.sampcnt);
1295
-				for (uint32_t j = last; j < curr; ++j)
1296
-				{
1297
-					// so, this is a little strange. why go through a fifo?
1298
-					// it seems that some games will set up a reverb effect by capturing
1299
-					// to the nearly same address as playback, but ahead by a couple.
1300
-					// So, playback will always end up being what was captured a couple of samples ago.
1301
-					// This system counts on playback always having read ahead 16 samples.
1302
-					// In that case, playback will end up being what was processed at one entire buffer length ago,
1303
-					// since the 16 samples would have read ahead before they got captured over
1304
-
1305
-					// It's actually the source channels which should have a fifo, but we are
1306
-					// not going to take the hit in speed and complexity. Save it for a future rewrite.
1307
-					// Instead, what we do here is delay the capture by 16 samples to create a similar effect.
1308
-					// Subjectively, it seems to be working.
1309
-
1310
-					// Don't do anything until the fifo is filled, so as to delay it
1311
-					if (cap.runtime.fifo.size < 16)
1312
-					{
1313
-						cap.runtime.fifo.enqueue(static_cast<int16_t>(capout[capchan]));
1314
-						continue;
1315
-					}
1316
-
1317
-					// (actually capture sample from fifo instead of most recently generated)
1318
-					int32_t sample = cap.runtime.fifo.dequeue();
1319
-					cap.runtime.fifo.enqueue(static_cast<int16_t>(capout[capchan]));
1320
-
1321
-					uint32_t multiplier;
1322
-					if (cap.bits8)
1323
-					{
1324
-						int8_t sample8 = static_cast<int8_t>(sample >> 8);
1325
-						if (skipcap)
1326
-							_MMU_write08<1, MMU_AT_DMA>(cap.runtime.curdad, 0);
1327
-						else
1328
-							_MMU_write08<1, MMU_AT_DMA>(cap.runtime.curdad, sample8);
1329
-						++cap.runtime.curdad;
1330
-						multiplier = 4;
1331
-					}
1332
-					else
1333
-					{
1334
-						int16_t sample16 = static_cast<int16_t>(sample);
1335
-						if (skipcap)
1336
-							_MMU_write16<1, MMU_AT_DMA>(cap.runtime.curdad, 0);
1337
-						else
1338
-							_MMU_write16<1, MMU_AT_DMA>(cap.runtime.curdad, sample16);
1339
-						cap.runtime.curdad += 2;
1340
-						multiplier = 2;
1341
-					}
1342
-
1343
-					if (cap.runtime.curdad >= cap.runtime.maxdad)
1344
-					{
1345
-						cap.runtime.curdad = cap.dad;
1346
-						cap.runtime.sampcnt -= cap.len * multiplier;
1347
-					}
1348
-				} // sampinc loop
1349
-			} // if capchan running
1350
-		} // capchan loop
1351
-	} // main sample loop
1352
-
1353
-	SPU->sndbuf[0] = samp0[0];
1354
-	SPU->sndbuf[1] = samp0[1];
1355
-}
1356
-
1357
-// ENTER
1319
+//ENTER
1358 1320
 static void SPU_MixAudio(bool actuallyMix, SPU_struct *SPU, int length)
1359 1321
 {
1360
-	if (actuallyMix)
1361
-	{
1362
-		memset(&SPU->sndbuf[0], 0, length * 4 * 2);
1363
-		memset(&SPU->outbuf[0], 0, length * 2 * 2);
1364
-	}
1365
-
1366
-	// we used to use master enable here, and do nothing if audio is disabled.
1367
-	// now, master enable is emulated better..
1368
-	// but for a speed optimization we will still do it
1369
-	if (!SPU->regs.masteren)
1370
-		return;
1371
-
1372
-	bool advanced = CommonSettings.spu_advanced;
1373
-
1374
-	// branch here so that slow computers don't have to take the advanced (slower) codepath.
1375
-	// it remainds to be seen exactly how much slower it is
1376
-	// if it isnt much slower then we should refactor everything to be simpler, once it is working
1377
-	if (advanced && SPU == SPU_core.get())
1378
-		SPU_MixAudio_Advanced(actuallyMix, SPU, length);
1379
-	else
1380
-	{
1381
-		// non-advanced mode
1382
-		for (int i = 0; i < 16; ++i)
1383
-		{
1384
-			channel_struct *chan = &SPU->channels[i];
1385
-
1386
-			if (chan->status != CHANSTAT_PLAY)
1387
-				continue;
1388
-
1389
-			SPU->bufpos = 0;
1390
-			SPU->buflength = length;
1391
-
1392
-			// Mix audio
1393
-			_SPU_ChanUpdate(!CommonSettings.spu_muteChannels[i] && actuallyMix, SPU, chan);
1394
-		}
1395
-	}
1396
-
1397
-	// we used to bail out if speakers were disabled.
1398
-	// this is technically wrong. sound may still be captured, or something.
1399
-	// in all likelihood, any game doing this probably master disabled the SPU also
1400
-	// so, optimization of this case is probably not necessary.
1401
-	// later, we'll just silence the output
1402
-	bool speakers = T1ReadWord(MMU.ARM7_REG, 0x304) & 0x01;
1403
-
1404
-	uint8_t vol = SPU->regs.mastervol;
1405
-
1406
-	// convert from 32-bit->16-bit
1407
-	if (actuallyMix && speakers)
1408
-		for (int i = 0; i < length * 2; ++i)
1409
-		{
1410
-			// Apply Master Volume
1411
-			SPU->sndbuf[i] = spumuldiv7(SPU->sndbuf[i], vol);
1412
-			int16_t outsample = static_cast<int16_t>(MinMax(SPU->sndbuf[i], -0x8000, 0x7FFF));
1413
-			SPU->outbuf[i] = outsample;
1414
-		}
1322
+  if (actuallyMix)
1323
+  {
1324
+    memset(SPU->sndbuf, 0, length*4*2);
1325
+    memset(SPU->outbuf, 0, length*2*2);
1326
+  }
1327
+
1328
+  SPU_MixAudio_Advanced(actuallyMix, SPU, length);
1329
+
1330
+  //we used to bail out if speakers were disabled.
1331
+  //this is technically wrong. sound may still be captured, or something.
1332
+  //in all likelihood, any game doing this probably master disabled the SPU also
1333
+  //so, optimization of this case is probably not necessary.
1334
+  //later, we'll just silence the output
1335
+  bool speakers = T1ReadWord(MMU.ARM7_REG, 0x304) & 0x01;
1336
+
1337
+  u8 vol = SPU->regs.mastervol;
1338
+
1339
+  // convert from 32-bit->16-bit
1340
+  if (actuallyMix && speakers) {
1341
+    for (int i = 0; i < length*2; i++)
1342
+    {
1343
+      // Apply Master Volume
1344
+      SPU->sndbuf[i] = spumuldiv7(SPU->sndbuf[i], vol);
1345
+      s16 outsample = MinMax(SPU->sndbuf[i],-0x8000,0x7FFF);
1346
+      SPU->outbuf[i] = outsample;
1347
+    }
1348
+  }
1415 1349
 }
1416 1350
 
1417 1351
 //////////////////////////////////////////////////////////////////////////////
1418 1352
 
1419
-// emulates one hline of the cpu core.
1420
-// this will produce a variable number of samples, calculated to keep a 44100hz output
1421
-// in sync with the emulator framerate
1353
+
1354
+//emulates one hline of the cpu core.
1355
+//this will produce a variable number of samples, calculated to keep a 44100hz output
1356
+//in sync with the emulator framerate
1422 1357
 int spu_core_samples = 0;
1423 1358
 void SPU_Emulate_core()
1424 1359
 {
1425
-	bool needToMix = true;
1426
-
1427
-	samples += samples_per_hline;
1428
-	spu_core_samples = static_cast<int>(samples);
1429
-	samples -= spu_core_samples;
1430
-
1431
-	// We don't need to mix audio for Dual Synch/Asynch mode since we do this
1432
-	// later in SPU_Emulate_user(). Disable mixing here to speed up processing.
1433
-	// However, recording still needs to mix the audio, so make sure we're also
1434
-	// not recording before we disable mixing.
1435
-	if (synchmode == ESynchMode_DualSynchAsynch)
1436
-		needToMix = false;
1437
-
1438
-	SPU_MixAudio(needToMix, SPU_core.get(), spu_core_samples);
1439
-
1440
-	if (!SNDCore)
1441
-		return;
1442
-
1443
-	if (SNDCore->FetchSamples)
1444
-		SNDCore->FetchSamples(&SPU_core->outbuf[0], spu_core_samples, synchmode, synchronizer.get());
1445
-	else
1446
-		SPU_DefaultFetchSamples(&SPU_core->outbuf[0], spu_core_samples, synchmode, synchronizer.get());
1360
+  bool needToMix = true;
1361
+  SoundInterface_struct *soundProcessor = SPU_SoundCore();
1362
+
1363
+  samples += samples_per_hline;
1364
+  spu_core_samples = (int)(samples);
1365
+  samples -= spu_core_samples;
1366
+
1367
+  SPU_MixAudio(needToMix, SPU_core, spu_core_samples);
1368
+
1369
+  if (soundProcessor == NULL)
1370
+  {
1371
+    return;
1372
+  }
1373
+
1374
+  if (soundProcessor->FetchSamples != NULL)
1375
+  {
1376
+    soundProcessor->FetchSamples(SPU_core->outbuf, spu_core_samples, synchmode, synchronizer);
1377
+  }
1378
+  else
1379
+  {
1380
+    SPU_DefaultFetchSamples(SPU_core->outbuf, spu_core_samples, synchmode, synchronizer);
1381
+  }
1447 1382
 }
1448 1383
 
1449
-void SPU_Emulate_user(bool /*mix*/)
1384
+void SPU_Emulate_user(bool mix)
1450 1385
 {
1451
-	static std::vector<int16_t> postProcessBuffer;
1452
-	static size_t postProcessBufferSize = 0;
1453
-	size_t processedSampleCount = 0;
1454
-
1455
-	if (!SNDCore)
1456
-		return;
1457
-
1458
-	// Check to see how many free samples are available.
1459
-	// If there are some, fill up the output buffer.
1460
-	size_t freeSampleCount = SNDCore->GetAudioSpace();
1461
-	if (!freeSampleCount)
1462
-		return;
1463
-
1464
-	//printf("mix %i samples\n", audiosize);
1465
-	if (freeSampleCount > buffersize)
1466
-		freeSampleCount = buffersize;
1467
-
1468
-	// If needed, resize the post-process buffer to guarantee that
1469
-	// we can store all the sound data.
1470
-	if (postProcessBufferSize < freeSampleCount * 2 * sizeof(int16_t))
1471
-	{
1472
-		postProcessBufferSize = freeSampleCount * 2 * sizeof(int16_t);
1473
-		postProcessBuffer.resize(postProcessBufferSize);
1474
-	}
1475
-
1476
-	if (SNDCore->PostProcessSamples)
1477
-		processedSampleCount = SNDCore->PostProcessSamples(&postProcessBuffer[0], freeSampleCount, synchmode, synchronizer.get());
1478
-	else
1479
-		processedSampleCount = SPU_DefaultPostProcessSamples(&postProcessBuffer[0], freeSampleCount, synchmode, synchronizer.get());
1480
-
1481
-	SNDCore->UpdateAudio(&postProcessBuffer[0], processedSampleCount);
1386
+  static s16 *postProcessBuffer = NULL;
1387
+  static size_t postProcessBufferSize = 0;
1388
+  size_t freeSampleCount = 0;
1389
+  size_t processedSampleCount = 0;
1390
+  SoundInterface_struct *soundProcessor = SPU_SoundCore();
1391
+
1392
+  if (soundProcessor == NULL)
1393
+  {
1394
+    return;
1395
+  }
1396
+
1397
+  // Check to see how many free samples are available.
1398
+  // If there are some, fill up the output buffer.
1399
+  freeSampleCount = soundProcessor->GetAudioSpace();
1400
+  if (freeSampleCount == 0)
1401
+  {
1402
+    return;
1403
+  }
1404
+
1405
+  if (freeSampleCount > buffersize)
1406
+  {
1407
+    freeSampleCount = buffersize;
1408
+  }
1409
+
1410
+  // If needed, resize the post-process buffer to guarantee that
1411
+  // we can store all the sound data.
1412
+  if (postProcessBufferSize < freeSampleCount * 2 * sizeof(s16))
1413
+  {
1414
+    postProcessBufferSize = freeSampleCount * 2 * sizeof(s16);
1415
+    postProcessBuffer = (s16 *)realloc(postProcessBuffer, postProcessBufferSize);
1416
+  }
1417
+
1418
+  if (soundProcessor->PostProcessSamples != NULL)
1419
+  {
1420
+    processedSampleCount = soundProcessor->PostProcessSamples(postProcessBuffer, freeSampleCount, synchmode, synchronizer);
1421
+  }
1422
+  else
1423
+  {
1424
+    processedSampleCount = SPU_DefaultPostProcessSamples(postProcessBuffer, freeSampleCount, synchmode, synchronizer);
1425
+  }
1426
+
1427
+  soundProcessor->UpdateAudio(postProcessBuffer, processedSampleCount);
1482 1428
 }
1483 1429
 
1484
-void SPU_DefaultFetchSamples(int16_t *sampleBuffer, size_t sampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer)
1430
+void SPU_DefaultFetchSamples(s16 *sampleBuffer, size_t sampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer)
1485 1431
 {
1486
-	if (synchMode == ESynchMode_Synchronous)
1487
-		theSynchronizer->enqueue_samples(sampleBuffer, sampleCount);
1432
+  theSynchronizer->enqueue_samples(sampleBuffer, sampleCount);
1488 1433
 }
1489 1434
 
1490
-size_t SPU_DefaultPostProcessSamples(int16_t *postProcessBuffer, size_t requestedSampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer)
1435
+size_t SPU_DefaultPostProcessSamples(s16 *postProcessBuffer, size_t requestedSampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer)
1491 1436
 {
1492
-	size_t processedSampleCount = 0;
1493
-
1494
-	switch (synchMode)
1495
-	{
1496
-		case ESynchMode_DualSynchAsynch:
1497
-			if (SPU_user)
1498
-			{
1499
-				SPU_MixAudio(true, SPU_user.get(), requestedSampleCount);
1500
-				memcpy(postProcessBuffer, &SPU_user->outbuf[0], requestedSampleCount * 2 * sizeof(int16_t));
1501
-				processedSampleCount = requestedSampleCount;
1502
-			}
1503
-			break;
1504
-
1505
-		case ESynchMode_Synchronous:
1506
-			processedSampleCount = theSynchronizer->output_samples(postProcessBuffer, requestedSampleCount);
1507
-	}
1508
-
1509
-	return processedSampleCount;
1437
+  return theSynchronizer->output_samples(postProcessBuffer, requestedSampleCount);
1510 1438
 }
1511 1439
 
1512 1440
 //////////////////////////////////////////////////////////////////////////////
1513 1441
 // Dummy Sound Interface
1514 1442
 //////////////////////////////////////////////////////////////////////////////
1515 1443
 
1516
-int SNDDummyInit(int) { return 0; }
1444
+int SNDDummyInit(int buffersize);
1445
+void SNDDummyDeInit();
1446
+void SNDDummyUpdateAudio(s16 *buffer, u32 num_samples);
1447
+u32 SNDDummyGetAudioSpace();
1448
+void SNDDummyMuteAudio();
1449
+void SNDDummyUnMuteAudio();
1450
+void SNDDummySetVolume(int volume);
1451
+void SNDDummyClearBuffer();
1452
+void SNDDummyFetchSamples(s16 *sampleBuffer, size_t sampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer);
1453
+size_t SNDDummyPostProcessSamples(s16 *postProcessBuffer, size_t requestedSampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer);
1454
+
1455
+SoundInterface_struct SNDDummy = {
1456
+  SNDCORE_DUMMY,
1457
+  "Dummy Sound Interface",
1458
+  SNDDummyInit,
1459
+  SNDDummyDeInit,
1460
+  SNDDummyUpdateAudio,
1461
+  SNDDummyGetAudioSpace,
1462
+  SNDDummyMuteAudio,
1463
+  SNDDummyUnMuteAudio,
1464
+  SNDDummySetVolume,
1465
+  SNDDummyClearBuffer,
1466
+  SNDDummyFetchSamples,
1467
+  SNDDummyPostProcessSamples
1468
+};
1469
+
1470
+int SNDDummyInit(int buffersize) { return 0; }
1517 1471
 void SNDDummyDeInit() {}
1518
-void SNDDummyUpdateAudio(int16_t *, uint32_t) { }
1519
-uint32_t SNDDummyGetAudioSpace() { return DESMUME_SAMPLE_RATE / 60 + 5; }
1472
+void SNDDummyUpdateAudio(s16 *buffer, u32 num_samples) { }
1473
+u32 SNDDummyGetAudioSpace() { return DESMUME_SAMPLE_RATE/60 + 5; }
1520 1474
 void SNDDummyMuteAudio() {}
1521 1475
 void SNDDummyUnMuteAudio() {}
1522
-void SNDDummySetVolume(int) {}
1476
+void SNDDummySetVolume(int volume) {}
1523 1477
 void SNDDummyClearBuffer() {}
1524
-void SNDDummyFetchSamples(int16_t *, size_t, ESynchMode, ISynchronizingAudioBuffer *) { }
1525
-size_t SNDDummyPostProcessSamples(int16_t *, size_t, ESynchMode, ISynchronizingAudioBuffer *) { return 0; }
1478
+void SNDDummyFetchSamples(s16 *sampleBuffer, size_t sampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer) {}
1479
+size_t SNDDummyPostProcessSamples(s16 *postProcessBuffer, size_t requestedSampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer) { return 0; }
1526 1480
 
1527
-SoundInterface_struct SNDDummy =
1528
-{
1529
-	SNDCORE_DUMMY,
1530
-	"Dummy Sound Interface",
1531
-	SNDDummyInit,
1532
-	SNDDummyDeInit,
1533
-	SNDDummyUpdateAudio,
1534
-	SNDDummyGetAudioSpace,
1535
-	SNDDummyMuteAudio,
1536
-	SNDDummyUnMuteAudio,
1537
-	SNDDummySetVolume,
1538
-	SNDDummyClearBuffer,
1539
-	SNDDummyFetchSamples,
1540
-	SNDDummyPostProcessSamples
1541
-};
Browse code

* Small Makefile changes.

* Removed a couple files that were not being used.
* Cleanups found with clang's -Weverything (and shutting it up about a
lot of things that were ridiculous, as well as ignoring some of the
warnings still coming up).

Naram Qashat authored on 2014/09/25 12:28:21
Showing 1 changed files
... ...
@@ -800,13 +800,11 @@ static inline int32_t Interpolate(int32_t a, int32_t b, double ratio, SPUInterpo
800 800
 			// ratio2 = (1 - cos(ratio * M_PI)) / 2
801 801
 			// sampleI = sampleA * (1 - ratio2) + sampleB * ratio2
802 802
 			return s32floor((cos_lut[static_cast<unsigned>(ratio * COSINE_INTERPOLATION_RESOLUTION)] * (sampleB - sampleA)) + sampleA);
803
-			break;
804 803
 
805 804
 		case SPUInterpolation_Linear:
806 805
 			// Linear Interpolation Formula:
807 806
 			// sampleI = sampleA * (1 - ratio) + sampleB * ratio
808 807
 			return s32floor((ratio * (sampleB - sampleA)) + sampleA);
809
-			break;
810 808
 
811 809
 		default:
812 810
 			break;
... ...
@@ -1128,8 +1126,6 @@ static inline void _SPU_ChanUpdate(bool actuallyMix, SPU_struct *const SPU, chan
1128 1126
 		case SPUInterpolation_Cosine:
1129 1127
 			__SPU_ChanUpdate(actuallyMix, SPU, chan, SPUInterpolation_Cosine);
1130 1128
 			break;
1131
-		default:
1132
-			assert(false);
1133 1129
 	}
1134 1130
 }
1135 1131
 
Browse code

* Fixes for gcc and clang (while they can compile the code, the DLLs made aren't functional, but oh well).

* [2SF] Used more up-to-date asmjit, despite the ugly looking code.

Naram Qashat authored on 2014/09/17 19:51:45
Showing 1 changed files
... ...
@@ -851,7 +851,7 @@ static inline void Fetch16BitData(const channel_struct *const chan, int32_t *con
851 851
 	if (INTERPOLATE_MODE != SPUInterpolation_None)
852 852
 	{
853 853
 		uint32_t loc = u32floor(chan->sampcnt);
854
-		
854
+
855 855
 		int32_t a = static_cast<int32_t>(read16(loc * 2 + chan->addr));
856 856
 		if (loc < (chan->totlength << 1) - 1)
857 857
 		{
... ...
@@ -1450,7 +1450,7 @@ void SPU_Emulate_core()
1450 1450
 		SPU_DefaultFetchSamples(&SPU_core->outbuf[0], spu_core_samples, synchmode, synchronizer.get());
1451 1451
 }
1452 1452
 
1453
-void SPU_Emulate_user(bool mix)
1453
+void SPU_Emulate_user(bool /*mix*/)
1454 1454
 {
1455 1455
 	static std::vector<int16_t> postProcessBuffer;
1456 1456
 	static size_t postProcessBufferSize = 0;
... ...
@@ -1494,7 +1494,7 @@ void SPU_DefaultFetchSamples(int16_t *sampleBuffer, size_t sampleCount, ESynchMo
1494 1494
 size_t SPU_DefaultPostProcessSamples(int16_t *postProcessBuffer, size_t requestedSampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer)
1495 1495
 {
1496 1496
 	size_t processedSampleCount = 0;
1497
-	
1497
+
1498 1498
 	switch (synchMode)
1499 1499
 	{
1500 1500
 		case ESynchMode_DualSynchAsynch:
... ...
@@ -1509,7 +1509,7 @@ size_t SPU_DefaultPostProcessSamples(int16_t *postProcessBuffer, size_t requeste
1509 1509
 		case ESynchMode_Synchronous:
1510 1510
 			processedSampleCount = theSynchronizer->output_samples(postProcessBuffer, requestedSampleCount);
1511 1511
 	}
1512
-	
1512
+
1513 1513
 	return processedSampleCount;
1514 1514
 }
1515 1515
 
... ...
@@ -1525,8 +1525,8 @@ void SNDDummyMuteAudio() {}
1525 1525
 void SNDDummyUnMuteAudio() {}
1526 1526
 void SNDDummySetVolume(int) {}
1527 1527
 void SNDDummyClearBuffer() {}
1528
-void SNDDummyFetchSamples(int16_t *sampleBuffer, size_t sampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer) {}
1529
-size_t SNDDummyPostProcessSamples(int16_t *postProcessBuffer, size_t requestedSampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer) { return 0; }
1528
+void SNDDummyFetchSamples(int16_t *, size_t, ESynchMode, ISynchronizingAudioBuffer *) { }
1529
+size_t SNDDummyPostProcessSamples(int16_t *, size_t, ESynchMode, ISynchronizingAudioBuffer *) { return 0; }
1530 1530
 
1531 1531
 SoundInterface_struct SNDDummy =
1532 1532
 {
Browse code

[2SF] Minor template removal.

Naram Qashat authored on 2014/09/08 13:53:30
Showing 1 changed files
... ...
@@ -787,7 +787,7 @@ void SPU_WriteLong(uint32_t addr, uint32_t val)
787 787
 
788 788
 //////////////////////////////////////////////////////////////////////////////
789 789
 
790
-template<SPUInterpolationMode INTERPOLATE_MODE> static inline int32_t Interpolate(int32_t a, int32_t b, double ratio)
790
+static inline int32_t Interpolate(int32_t a, int32_t b, double ratio, SPUInterpolationMode INTERPOLATE_MODE)
791 791
 {
792 792
 	double sampleA = static_cast<double>(a);
793 793
 	double sampleB = static_cast<double>(b);
... ...
@@ -817,7 +817,7 @@ template<SPUInterpolationMode INTERPOLATE_MODE> static inline int32_t Interpolat
817 817
 
818 818
 //////////////////////////////////////////////////////////////////////////////
819 819
 
820
-template<SPUInterpolationMode INTERPOLATE_MODE> static inline void Fetch8BitData(channel_struct *chan, int32_t *data)
820
+static inline void Fetch8BitData(const channel_struct *const chan, int32_t *const data, SPUInterpolationMode INTERPOLATE_MODE)
821 821
 {
822 822
 	if (chan->sampcnt < 0)
823 823
 	{
... ...
@@ -832,7 +832,7 @@ template<SPUInterpolationMode INTERPOLATE_MODE> static inline void Fetch8BitData
832 832
 		if (loc < (chan->totlength << 2) - 1)
833 833
 		{
834 834
 			int32_t b = static_cast<int32_t>(read_s8(chan->addr + loc + 1) << 8);
835
-			a = Interpolate<INTERPOLATE_MODE>(a, b, chan->sampcnt);
835
+			a = Interpolate(a, b, chan->sampcnt, INTERPOLATE_MODE);
836 836
 		}
837 837
 		*data = a;
838 838
 	}
... ...
@@ -840,7 +840,7 @@ template<SPUInterpolationMode INTERPOLATE_MODE> static inline void Fetch8BitData
840 840
 		*data = static_cast<int32_t>(read_s8(chan->addr + loc) << 8);
841 841
 }
842 842
 
843
-template<SPUInterpolationMode INTERPOLATE_MODE> static inline void Fetch16BitData(const channel_struct * const chan, int32_t *data)
843
+static inline void Fetch16BitData(const channel_struct *const chan, int32_t *const data, SPUInterpolationMode INTERPOLATE_MODE)
844 844
 {
845 845
 	if (chan->sampcnt < 0)
846 846
 	{
... ...
@@ -848,7 +848,7 @@ template<SPUInterpolationMode INTERPOLATE_MODE> static inline void Fetch16BitDat
848 848
 		return;
849 849
 	}
850 850
 
851
-	if(INTERPOLATE_MODE != SPUInterpolation_None)
851
+	if (INTERPOLATE_MODE != SPUInterpolation_None)
852 852
 	{
853 853
 		uint32_t loc = u32floor(chan->sampcnt);
854 854
 		
... ...
@@ -856,7 +856,7 @@ template<SPUInterpolationMode INTERPOLATE_MODE> static inline void Fetch16BitDat
856 856
 		if (loc < (chan->totlength << 1) - 1)
857 857
 		{
858 858
 			int32_t b = static_cast<int32_t>(read16(loc * 2 + chan->addr + 2));
859
-			a = Interpolate<INTERPOLATE_MODE>(a, b, chan->sampcnt);
859
+			a = Interpolate(a, b, chan->sampcnt, INTERPOLATE_MODE);
860 860
 		}
861 861
 		*data = a;
862 862
 	}
... ...
@@ -864,7 +864,7 @@ template<SPUInterpolationMode INTERPOLATE_MODE> static inline void Fetch16BitDat
864 864
 		*data = read16(chan->addr + u32floor(chan->sampcnt) * 2);
865 865
 }
866 866
 
867
-template<SPUInterpolationMode INTERPOLATE_MODE> static inline void FetchADPCMData(channel_struct * const chan, int32_t * const data)
867
+static inline void FetchADPCMData(channel_struct *const chan, int32_t *const data, SPUInterpolationMode INTERPOLATE_MODE)
868 868
 {
869 869
 	if (chan->sampcnt < 8)
870 870
 	{
... ...
@@ -900,7 +900,7 @@ template<SPUInterpolationMode INTERPOLATE_MODE> static inline void FetchADPCMDat
900 900
 	}
901 901
 
902 902
 	if (INTERPOLATE_MODE != SPUInterpolation_None)
903
-		*data = Interpolate<INTERPOLATE_MODE>(static_cast<int32_t>(chan->pcm16b_last), static_cast<int32_t>(chan->pcm16b), chan->sampcnt);
903
+		*data = Interpolate(static_cast<int32_t>(chan->pcm16b_last), static_cast<int32_t>(chan->pcm16b), chan->sampcnt, INTERPOLATE_MODE);
904 904
 	else
905 905
 		*data = static_cast<int32_t>(chan->pcm16b);
906 906
 }
... ...
@@ -969,7 +969,7 @@ static inline void MixLR(SPU_struct *SPU, channel_struct *chan, int32_t data)
969 969
 
970 970
 //////////////////////////////////////////////////////////////////////////////
971 971
 
972
-template<int FORMAT> static inline void TestForLoop(SPU_struct *SPU, channel_struct *chan)
972
+static inline void TestForLoop(SPU_struct *SPU, channel_struct *chan, int FORMAT)
973 973
 {
974 974
 	int shift = !FORMAT ? 2 : 1;
975 975
 
... ...
@@ -1026,7 +1026,7 @@ static inline void TestForLoop2(SPU_struct *SPU, channel_struct *chan)
1026 1026
 	}
1027 1027
 }
1028 1028
 
1029
-template<int CHANNELS> static inline void SPU_Mix(SPU_struct *SPU, channel_struct *chan, int32_t data)
1029
+static inline void SPU_Mix(SPU_struct *SPU, channel_struct *chan, int32_t data, int CHANNELS)
1030 1030
 {
1031 1031
 	switch (CHANNELS)
1032 1032
 	{
... ...
@@ -1043,7 +1043,7 @@ template<int CHANNELS> static inline void SPU_Mix(SPU_struct *SPU, channel_struc
1043 1043
 }
1044 1044
 
1045 1045
 // WORK
1046
-template<int FORMAT, SPUInterpolationMode INTERPOLATE_MODE, int CHANNELS> static inline void ____SPU_ChanUpdate(SPU_struct *const SPU, channel_struct *const chan)
1046
+static inline void ____SPU_ChanUpdate(SPU_struct *const SPU, channel_struct *const chan, int FORMAT, SPUInterpolationMode INTERPOLATE_MODE, int CHANNELS)
1047 1047
 {
1048 1048
 	for (; SPU->bufpos < SPU->buflength; ++SPU->bufpos)
1049 1049
 	{
... ...
@@ -1053,25 +1053,25 @@ template<int FORMAT, SPUInterpolationMode INTERPOLATE_MODE, int CHANNELS> static
1053 1053
 			switch (FORMAT)
1054 1054
 			{
1055 1055
 				case 0:
1056
-					Fetch8BitData<INTERPOLATE_MODE>(chan, &data);
1056
+					Fetch8BitData(chan, &data, INTERPOLATE_MODE);
1057 1057
 					break;
1058 1058
 				case 1:
1059
-					Fetch16BitData<INTERPOLATE_MODE>(chan, &data);
1059
+					Fetch16BitData(chan, &data, INTERPOLATE_MODE);
1060 1060
 					break;
1061 1061
 				case 2:
1062
-					FetchADPCMData<INTERPOLATE_MODE>(chan, &data);
1062
+					FetchADPCMData(chan, &data, INTERPOLATE_MODE);
1063 1063
 					break;
1064 1064
 				case 3:
1065 1065
 					FetchPSGData(chan, &data);
1066 1066
 			}
1067
-			SPU_Mix<CHANNELS>(SPU, chan, data);
1067
+			SPU_Mix(SPU, chan, data, CHANNELS);
1068 1068
 		}
1069 1069
 
1070 1070
 		switch (FORMAT)
1071 1071
 		{
1072 1072
 			case 0:
1073 1073
 			case 1:
1074
-				TestForLoop<FORMAT>(SPU, chan);
1074
+				TestForLoop(SPU, chan, FORMAT);
1075 1075
 				break;
1076 1076
 			case 2:
1077 1077
 				TestForLoop2(SPU, chan);
... ...
@@ -1082,33 +1082,33 @@ template<int FORMAT, SPUInterpolationMode INTERPOLATE_MODE, int CHANNELS> static
1082 1082
 	}
1083 1083
 }
1084 1084
 
1085
-template<int FORMAT, SPUInterpolationMode INTERPOLATE_MODE> static inline void ___SPU_ChanUpdate(bool actuallyMix, SPU_struct *const SPU, channel_struct *const chan)
1085
+static inline void ___SPU_ChanUpdate(bool actuallyMix, SPU_struct *const SPU, channel_struct *const chan, int FORMAT, SPUInterpolationMode INTERPOLATE_MODE)
1086 1086
 {
1087 1087
 	if (!actuallyMix)
1088
-		____SPU_ChanUpdate<FORMAT, INTERPOLATE_MODE, -1>(SPU, chan);
1088
+		____SPU_ChanUpdate(SPU, chan, FORMAT, INTERPOLATE_MODE, -1);
1089 1089
 	else if (!chan->pan)
1090
-		____SPU_ChanUpdate<FORMAT, INTERPOLATE_MODE, 0>(SPU, chan);
1090
+		____SPU_ChanUpdate(SPU, chan, FORMAT, INTERPOLATE_MODE, 0);
1091 1091
 	else if (chan->pan == 127)
1092
-		____SPU_ChanUpdate<FORMAT, INTERPOLATE_MODE, 2>(SPU, chan);
1092
+		____SPU_ChanUpdate(SPU, chan, FORMAT, INTERPOLATE_MODE, 2);
1093 1093
 	else
1094
-		____SPU_ChanUpdate<FORMAT, INTERPOLATE_MODE, 1>(SPU, chan);
1094
+		____SPU_ChanUpdate(SPU, chan, FORMAT, INTERPOLATE_MODE, 1);
1095 1095
 }
1096 1096
 
1097
-template<SPUInterpolationMode INTERPOLATE_MODE> static inline void __SPU_ChanUpdate(bool actuallyMix, SPU_struct *const SPU, channel_struct *const chan)
1097
+static inline void __SPU_ChanUpdate(bool actuallyMix, SPU_struct *const SPU, channel_struct *const chan, SPUInterpolationMode INTERPOLATE_MODE)
1098 1098
 {
1099 1099
 	switch (chan->format)
1100 1100
 	{
1101 1101
 		case 0:
1102
-			___SPU_ChanUpdate<0, INTERPOLATE_MODE>(actuallyMix, SPU, chan);
1102
+			___SPU_ChanUpdate(actuallyMix, SPU, chan, 0, INTERPOLATE_MODE);
1103 1103
 			break;
1104 1104
 		case 1:
1105
-			___SPU_ChanUpdate<1, INTERPOLATE_MODE>(actuallyMix, SPU, chan);
1105
+			___SPU_ChanUpdate(actuallyMix, SPU, chan, 1, INTERPOLATE_MODE);
1106 1106
 			break;
1107 1107
 		case 2:
1108
-			___SPU_ChanUpdate<2, INTERPOLATE_MODE>(actuallyMix, SPU, chan);
1108
+			___SPU_ChanUpdate(actuallyMix, SPU, chan, 2, INTERPOLATE_MODE);
1109 1109
 			break;
1110 1110
 		case 3:
1111
-			___SPU_ChanUpdate<3, INTERPOLATE_MODE>(actuallyMix, SPU, chan);
1111
+			___SPU_ChanUpdate(actuallyMix, SPU, chan, 3, INTERPOLATE_MODE);
1112 1112
 			break;
1113 1113
 		default:
1114 1114
 			assert(false);
... ...
@@ -1120,13 +1120,13 @@ static inline void _SPU_ChanUpdate(bool actuallyMix, SPU_struct *const SPU, chan
1120 1120
 	switch (CommonSettings.spuInterpolationMode)
1121 1121
 	{
1122 1122
 		case SPUInterpolation_None:
1123
-			__SPU_ChanUpdate<SPUInterpolation_None>(actuallyMix, SPU, chan);
1123
+			__SPU_ChanUpdate(actuallyMix, SPU, chan, SPUInterpolation_None);
1124 1124
 			break;
1125 1125
 		case SPUInterpolation_Linear:
1126
-			__SPU_ChanUpdate<SPUInterpolation_Linear>(actuallyMix, SPU, chan);
1126
+			__SPU_ChanUpdate(actuallyMix, SPU, chan, SPUInterpolation_Linear);
1127 1127
 			break;
1128 1128
 		case SPUInterpolation_Cosine:
1129
-			__SPU_ChanUpdate<SPUInterpolation_Cosine>(actuallyMix, SPU, chan);
1129
+			__SPU_ChanUpdate(actuallyMix, SPU, chan, SPUInterpolation_Cosine);
1130 1130
 			break;
1131 1131
 		default:
1132 1132
 			assert(false);
Browse code

Removed a bunch of casts, they seem to be fine without them in most cases.

Naram Qashat authored on 2013/04/18 23:22:54
Showing 1 changed files
... ...
@@ -36,9 +36,9 @@ static const double M_PI = 3.14159265358979323846;
36 36
 #include "NDSSystem.h"
37 37
 #include "matrix.h"
38 38
 
39
-static inline int16_t read16(uint32_t addr) { return static_cast<int16_t>(_MMU_read16<ARMCPU_ARM7,MMU_AT_DEBUG>(addr)); }
39
+static inline int16_t read16(uint32_t addr) { return _MMU_read16<ARMCPU_ARM7,MMU_AT_DEBUG>(addr); }
40 40
 static inline uint8_t read08(uint32_t addr) { return _MMU_read08<ARMCPU_ARM7,MMU_AT_DEBUG>(addr); }
41
-static inline int8_t read_s8(uint32_t addr) { return static_cast<int8_t>(_MMU_read08<ARMCPU_ARM7,MMU_AT_DEBUG>(addr)); }
41
+static inline int8_t read_s8(uint32_t addr) { return _MMU_read08<ARMCPU_ARM7,MMU_AT_DEBUG>(addr); }
42 42
 
43 43
 static const int K_ADPCM_LOOPING_RECOVERY_INDEX = 99999;
44 44
 static const int COSINE_INTERPOLATION_RESOLUTION = 8192;
... ...
@@ -172,7 +172,7 @@ int SPU_Init(int coreid, int Buffersize)
172 172
 	for (i = 0; i < COSINE_INTERPOLATION_RESOLUTION; ++i)
173 173
 		cos_lut[i] = (1.0 - std::cos((static_cast<double>(i) / COSINE_INTERPOLATION_RESOLUTION) * M_PI)) * 0.5;
174 174
 
175
-	SPU_core.reset(new SPU_struct(static_cast<int>(std::ceil(samples_per_hline))));
175
+	SPU_core.reset(new SPU_struct(std::ceil(samples_per_hline)));
176 176
 	SPU_Reset();
177 177
 
178 178
 	int j;
... ...
@@ -350,7 +350,7 @@ void SPU_struct::KeyOn(int channel)
350 350
 			thischan.x = 0x7FFF;
351 351
 	}
352 352
 
353
-	thischan.double_totlength_shifted = static_cast<double>(thischan.totlength << format_shift[thischan.format]);
353
+	thischan.double_totlength_shifted = thischan.totlength << format_shift[thischan.format];
354 354
 
355 355
 	if (thischan.format != 3 && fEqual(thischan.double_totlength_shifted, 0.0))
356 356
 	{
Browse code

Updating in_2sf to use a newish version of DeSmuME, 0.9.9 from SVN. Somewhat cleaned up as well, but not everything because it's a pain in the ass.

Naram Qashat authored on 2013/04/18 17:22:55
Showing 1 changed files
... ...
@@ -26,10 +26,8 @@
26 26
 #include <cstdlib>
27 27
 #include <cstring>
28 28
 #ifndef M_PI
29
-#define M_PI 3.14159265358979323846
29
+static const double M_PI = 3.14159265358979323846;
30 30
 #endif
31
-
32
-//#include "debug.h"
33 31
 #include "MMU.h"
34 32
 #include "SPU.h"
35 33
 #include "mem.h"
... ...
@@ -38,28 +36,27 @@
38 36
 #include "NDSSystem.h"
39 37
 #include "matrix.h"
40 38
 
41
-#include "metaspu/metaspu.h"
39
+static inline int16_t read16(uint32_t addr) { return static_cast<int16_t>(_MMU_read16<ARMCPU_ARM7,MMU_AT_DEBUG>(addr)); }
40
+static inline uint8_t read08(uint32_t addr) { return _MMU_read08<ARMCPU_ARM7,MMU_AT_DEBUG>(addr); }
41
+static inline int8_t read_s8(uint32_t addr) { return static_cast<int8_t>(_MMU_read08<ARMCPU_ARM7,MMU_AT_DEBUG>(addr)); }
42 42
 
43 43
 static const int K_ADPCM_LOOPING_RECOVERY_INDEX = 99999;
44 44
 static const int COSINE_INTERPOLATION_RESOLUTION = 8192;
45 45
 
46
-//static ISynchronizingAudioBuffer* synchronizer = metaspu_construct(ESynchMethod_Z);
47
-static ISynchronizingAudioBuffer* synchronizer = metaspu_construct(ESynchMethod_N);
46
+static auto synchronizer = std::unique_ptr<ISynchronizingAudioBuffer>(metaspu_construct(ESynchMethod_N));
48 47
 
49
-SPU_struct *SPU_core = 0;
50
-SPU_struct *SPU_user = 0;
48
+std::unique_ptr<SPU_struct> SPU_core, SPU_user;
51 49
 int SPU_currentCoreNum = SNDCORE_DUMMY;
52 50
 static int volume = 100;
53 51
 
54
-static int buffersize = 0;
52
+static size_t buffersize = 0;
55 53
 static ESynchMode synchmode = ESynchMode_DualSynchAsynch;
56 54
 static ESynchMethod synchmethod = ESynchMethod_N;
57 55
 
58
-static int SNDCoreId=-1;
59
-static SoundInterface_struct *SNDCore=NULL;
56
+static int SNDCoreId = -1;
57
+static SoundInterface_struct *SNDCore = nullptr;
60 58
 extern SoundInterface_struct *SNDCoreList[];
61 59
 
62
-//const int shift = (FORMAT == 0 ? 2 : 1);
63 60
 static const int format_shift[] = { 2, 1, 3, 0 };
64 61
 
65 62
 static const int8_t indextbl[8] =
... ...
@@ -102,26 +99,23 @@ static const double samples_per_hline = (DESMUME_SAMPLE_RATE / 59.8261f) / 263.0
102 99
 
103 100
 static double samples = 0;
104 101
 
105
-template<typename T>
106
-static inline T MinMax(T val, T min, T max)
102
+template<typename T> static inline T MinMax(T val, T min, T max)
107 103
 {
108 104
 	if (val < min)
109 105
 		return min;
110 106
 	else if (val > max)
111 107
 		return max;
112
-
113
-	return val;
108
+	else
109
+		return val;
114 110
 }
115 111
 
116 112
 //--------------external spu interface---------------
117 113
 
118 114
 int SPU_ChangeSoundCore(int coreid, int Buffersize)
119 115
 {
120
-	int i;
121
-
122 116
 	buffersize = Buffersize;
123 117
 
124
-	delete SPU_user; SPU_user = NULL;
118
+	SPU_user.reset();
125 119
 
126 120
 	// Make sure the old core is freed
127 121
 	if (SNDCore)
... ...
@@ -134,45 +128,38 @@ int SPU_ChangeSoundCore(int coreid, int Buffersize)
134 128
 	SPU_currentCoreNum = coreid;
135 129
 
136 130
 	// Go through core list and find the id
137
-	for (i = 0; SNDCoreList[i] != NULL; i++)
138
-	{
131
+	for (int i = 0; SNDCoreList[i]; ++i)
139 132
 		if (SNDCoreList[i]->id == coreid)
140 133
 		{
141 134
 			// Set to current core
142 135
 			SNDCore = SNDCoreList[i];
143 136
 			break;
144 137
 		}
145
-	}
146 138
 
147 139
 	SNDCoreId = coreid;
148 140
 
149
-	//If the user picked the dummy core, disable the user spu
150
-	if(SNDCore == &SNDDummy)
141
+	// If the user picked the dummy core, disable the user spu
142
+	if (SNDCore == &SNDDummy)
151 143
 		return 0;
152 144
 
153
-	//If the core wasnt found in the list for some reason, disable the user spu
154
-	if (SNDCore == NULL)
145
+	// If the core wasnt found in the list for some reason, disable the user spu
146
+	if (!SNDCore)
155 147
 		return -1;
156 148
 
157 149
 	// Since it failed, instead of it being fatal, disable the user spu
158 150
 	if (SNDCore->Init(buffersize * 2) == -1)
159 151
 	{
160
-		SNDCore = 0;
152
+		SNDCore = nullptr;
161 153
 		return -1;
162 154
 	}
163 155
 
164 156
 	SNDCore->SetVolume(volume);
165 157
 
166
-	SPU_SetSynchMode(synchmode,synchmethod);
158
+	SPU_SetSynchMode(synchmode, synchmethod);
167 159
 
168 160
 	return 0;
169 161
 }
170 162
 
171
-/*SoundInterface_struct *SPU_SoundCore()
172
-{
173
-	return SNDCore;
174
-}*/
175
-
176 163
 void SPU_ReInit()
177 164
 {
178 165
 	SPU_Init(SNDCoreId, buffersize);
... ...
@@ -180,49 +167,35 @@ void SPU_ReInit()
180 167
 
181 168
 int SPU_Init(int coreid, int Buffersize)
182 169
 {
183
-	int i, j;
184
-
185 170
 	// Build the cosine interpolation LUT
186
-	for(i = 0; i < COSINE_INTERPOLATION_RESOLUTION; i++)
187
-		cos_lut[i] = (1.0 - cos(((double)i/(double)COSINE_INTERPOLATION_RESOLUTION) * M_PI)) * 0.5;
171
+	int i;
172
+	for (i = 0; i < COSINE_INTERPOLATION_RESOLUTION; ++i)
173
+		cos_lut[i] = (1.0 - std::cos((static_cast<double>(i) / COSINE_INTERPOLATION_RESOLUTION) * M_PI)) * 0.5;
188 174
 
189
-	SPU_core = new SPU_struct((int)ceil(samples_per_hline));
175
+	SPU_core.reset(new SPU_struct(static_cast<int>(std::ceil(samples_per_hline))));
190 176
 	SPU_Reset();
191 177
 
192
-	//create adpcm decode accelerator lookups
193
-	for(i = 0; i < 16; i++)
194
-	{
195
-		for(j = 0; j < 89; j++)
196
-		{
197
-			precalcdifftbl[j][i] = (((i & 0x7) * 2 + 1) * adpcmtbl[j] / 8);
198
-			if(i & 0x8) precalcdifftbl[j][i] = -precalcdifftbl[j][i];
199
-		}
200
-	}
201
-	for(i = 0; i < 8; i++)
202
-	{
203
-		for(j = 0; j < 89; j++)
178
+	int j;
179
+	// create adpcm decode accelerator lookups
180
+	for (i = 0; i < 16; ++i)
181
+		for (j = 0; j < 89; ++j)
204 182
 		{
205
-			precalcindextbl[j][i] = MinMax((j + indextbl[i]), 0, 88);
183
+			precalcdifftbl[j][i] = ((i & 0x7) * 2 + 1) * adpcmtbl[j] / 8;
184
+			if (i & 0x8)
185
+				precalcdifftbl[j][i] = -precalcdifftbl[j][i];
206 186
 		}
207
-	}
187
+	for (i = 0; i < 8; ++i)
188
+		for (j = 0; j < 89; ++j)
189
+			precalcindextbl[j][i] = MinMax(j + indextbl[i], 0, 88);
208 190
 
209 191
 	return SPU_ChangeSoundCore(coreid, Buffersize);
210 192
 }
211 193
 
212
-/*void SPU_Pause(int pause)
213
-{
214
-	if (SNDCore == NULL) return;
215
-
216
-	if(pause)
217
-		SNDCore->MuteAudio();
218
-	else
219
-		SNDCore->UnMuteAudio();
220
-}*/
221
-
222 194
 void SPU_CloneUser()
223 195
 {
224
-	if(SPU_user) {
225
-		memcpy(SPU_user->channels,SPU_core->channels,sizeof(SPU_core->channels));
196
+	if (SPU_user)
197
+	{
198
+		memcpy(SPU_user->channels, SPU_core->channels, sizeof(SPU_core->channels));
226 199
 		SPU_user->regs = SPU_core->regs;
227 200
 	}
228 201
 }
... ...
@@ -230,59 +203,42 @@ void SPU_CloneUser()
230 203
 void SPU_SetSynchMode(ESynchMode mode, ESynchMethod method)
231 204
 {
232 205
 	synchmode = mode;
233
-	if(synchmethod != method)
206
+	if (synchmethod != method)
234 207
 	{
235 208
 		synchmethod = method;
236
-		delete synchronizer;
237
-		//grr does this need to be locked? spu might need a lock method
238
-		  // or maybe not, maybe the platform-specific code that calls this function can deal with it.
239
-		synchronizer = metaspu_construct(synchmethod);
209
+		// grr does this need to be locked? spu might need a lock method
210
+		// or maybe not, maybe the platform-specific code that calls this function can deal with it.
211
+		synchronizer.reset(metaspu_construct(synchmethod));
240 212
 	}
241 213
 
242
-	delete SPU_user;
243
-	SPU_user = NULL;
214
+	SPU_user.reset();
244 215
 
245
-	if(synchmode == ESynchMode_DualSynchAsynch)
216
+	if (synchmode == ESynchMode_DualSynchAsynch)
246 217
 	{
247
-		SPU_user = new SPU_struct(buffersize);
218
+		SPU_user.reset(new SPU_struct(buffersize));
248 219
 		SPU_CloneUser();
249 220
 	}
250 221
 }
251 222
 
252
-/*void SPU_ClearOutputBuffer()
253
-{
254
-	if(SNDCore && SNDCore->ClearBuffer)
255
-		SNDCore->ClearBuffer();
256
-}*/
257
-
258
-/*void SPU_SetVolume(int vol)
259
-{
260
-	volume = vol;
261
-	if (SNDCore)
262
-		SNDCore->SetVolume(vol);
263
-}*/
264
-
265
-
266 223
 void SPU_Reset()
267 224
 {
268
-	int i;
269
-
270 225
 	SPU_core->reset();
271 226
 
272
-	if(SPU_user) {
273
-		if(SNDCore)
227
+	if (SPU_user)
228
+	{
229
+		if (SNDCore)
274 230
 		{
275 231
 			SNDCore->DeInit();
276
-			SNDCore->Init(SPU_user->bufsize*2);
232
+			SNDCore->Init(SPU_user->bufsize * 2);
277 233
 			SNDCore->SetVolume(volume);
278 234
 		}
279 235
 		SPU_user->reset();
280 236
 	}
281 237
 
282
-	//zero - 09-apr-2010: this concerns me, regarding savestate synch.
283
-	//After 0.9.6, lets experiment with removing it and just properly zapping the spu instead
238
+	// zero - 09-apr-2010: this concerns me, regarding savestate synch.
239
+	// After 0.9.6, lets experiment with removing it and just properly zapping the spu instead
284 240
 	// Reset Registers
285
-	for (i = 0x400; i < 0x51D; i++)
241
+	for (int i = 0x400; i < 0x51D; ++i)
286 242
 		T1WriteByte(MMU.ARM7_REG, i, 0);
287 243
 
288 244
 	samples = 0;
... ...
@@ -292,85 +248,70 @@ void SPU_Reset()
292 248
 
293 249
 void SPU_struct::reset()
294 250
 {
295
-	memset(sndbuf,0,bufsize*2*4);
296
-	memset(outbuf,0,bufsize*2*2);
251
+	memset(&this->sndbuf[0], 0, bufsize * 2 * 4);
252
+	memset(&this->outbuf[0], 0, bufsize * 2 * 2);
297 253
 
298
-	memset((void *)channels, 0, sizeof(channel_struct) * 16);
254
+	memset(this->channels, 0, sizeof(channel_struct) * 16);
299 255
 
300
-	reconstruct(&regs);
256
+	reconstruct(&this->regs);
301 257
 
302
-	for(int i = 0; i < 16; i++)
303
-	{
304
-		channels[i].num = i;
305
-	}
306
-}
307
-
308
-SPU_struct::SPU_struct(int Buffersize)
309
-	: bufpos(0)
310
-	, buflength(0)
311
-	, sndbuf(0)
312
-	, outbuf(0)
313
-	, bufsize(Buffersize)
314
-{
315
-	sndbuf = new int32_t[Buffersize*2];
316
-	outbuf = new int16_t[Buffersize*2];
317
-	reset();
258
+	for (int i = 0; i < 16; ++i)
259
+		this->channels[i].num = i;
318 260
 }
319 261
 
320
-SPU_struct::~SPU_struct()
262
+SPU_struct::SPU_struct(int Buffersize) : bufpos(0), buflength(0), sndbuf(new int32_t[Buffersize * 2]), outbuf(new int16_t[Buffersize * 2]), bufsize(Buffersize)
321 263
 {
322
-	if(sndbuf) delete[] sndbuf;
323
-	if(outbuf) delete[] outbuf;
264
+	this->reset();
324 265
 }
325 266
 
326 267
 void SPU_DeInit()
327 268
 {
328
-	if(SNDCore)
269
+	if (SNDCore)
329 270
 		SNDCore->DeInit();
330
-	SNDCore = 0;
271
+	SNDCore = nullptr;
331 272
 
332
-	delete SPU_core; SPU_core=0;
333
-	delete SPU_user; SPU_user=0;
273
+	SPU_core.reset();
274
+	SPU_user.reset();
334 275
 }
335 276
 
336 277
 //////////////////////////////////////////////////////////////////////////////
337 278
 
338 279
 void SPU_struct::ShutUp()
339 280
 {
340
-	for(int i=0;i<16;i++)
341
-		 channels[i].status = CHANSTAT_STOPPED;
281
+	for (int i = 0; i < 16; ++i)
282
+		this->channels[i].status = CHANSTAT_STOPPED;
342 283
 }
343 284
 
344 285
 static inline void adjust_channel_timer(channel_struct *chan)
345 286
 {
346
-	chan->sampinc = (((double)ARM7_CLOCK) / (DESMUME_SAMPLE_RATE * 2)) / (double)(0x10000 - chan->timer);
287
+	chan->sampinc = (ARM7_CLOCK / (DESMUME_SAMPLE_RATE * 2)) / (0x10000 - chan->timer);
347 288
 }
348 289
 
349 290
 void SPU_struct::KeyProbe(int chan_num)
350 291
 {
351
-	channel_struct &thischan = channels[chan_num];
352
-	if(thischan.status == CHANSTAT_STOPPED)
292
+	channel_struct &thischan = this->channels[chan_num];
293
+	if (thischan.status == CHANSTAT_STOPPED)
353 294
 	{
354
-		if(thischan.keyon && regs.masteren)
355
-			KeyOn(chan_num);
295
+		if (thischan.keyon && this->regs.masteren)
296
+			this->KeyOn(chan_num);
356 297
 	}
357
-	else if(thischan.status == CHANSTAT_PLAY)
298
+	else if (thischan.status == CHANSTAT_PLAY)
358 299
 	{
359
-		if(!thischan.keyon || !regs.masteren)
360
-			KeyOff(chan_num);
300
+		if (!thischan.keyon || !this->regs.masteren)
301
+			this->KeyOff(chan_num);
361 302
 	}
362 303
 }
363 304
 
364 305
 void SPU_struct::KeyOff(int channel)
365 306
 {
366 307
 	//printf("keyoff%d\n",channel);
367
-	channel_struct &thischan = channels[channel];
308
+	channel_struct &thischan = this->channels[channel];
368 309
 	thischan.status = CHANSTAT_STOPPED;
369 310
 }
370 311
 
371 312
 void SPU_struct::KeyOn(int channel)
372 313
 {
373
-	channel_struct &thischan = channels[channel];
314
+	channel_struct &thischan = this->channels[channel];
374 315
 	thischan.status = CHANSTAT_PLAY;
375 316
 
376 317
 	thischan.totlength = thischan.length + thischan.loopstart;
... ...
@@ -378,362 +319,422 @@ void SPU_struct::KeyOn(int channel)
378 319
 
379 320
 	//printf("keyon %d totlength:%d\n",channel,thischan.totlength);
380 321
 
381
-
382 322
 	//LOG("Channel %d key on: vol = %d, datashift = %d, hold = %d, pan = %d, waveduty = %d, repeat = %d, format = %d, source address = %07X,"
383 323
 	//		"timer = %04X, loop start = %04X, length = %06X, MMU.ARM7_REG[0x501] = %02X\n", channel, chan->vol, chan->datashift, chan->hold,
384 324
 	//		chan->pan, chan->waveduty, chan->repeat, chan->format, chan->addr, chan->timer, chan->loopstart, chan->length, T1ReadByte(MMU.ARM7_REG, 0x501));
385 325
 
386
-	switch(thischan.format)
326
+	switch (thischan.format)
387 327
 	{
388
-	case 0: // 8-bit
389
-		thischan.buf8 = (int8_t*)&MMU.MMU_MEM[1][(thischan.addr>>20)&0xFF][(thischan.addr & MMU.MMU_MASK[1][(thischan.addr >> 20) & 0xFF])];
390
-	//	thischan.loopstart = thischan.loopstart << 2;
391
-	//	thischan.length = (thischan.length << 2) + thischan.loopstart;
392
-		thischan.sampcnt = -3;
393
-		break;
394
-	case 1: // 16-bit
395
-		thischan.buf16 = (int16_t *)&MMU.MMU_MEM[1][(thischan.addr>>20)&0xFF][(thischan.addr & MMU.MMU_MASK[1][(thischan.addr >> 20) & 0xFF])];
396
-	//	thischan.loopstart = thischan.loopstart << 1;
397
-	//	thischan.length = (thischan.length << 1) + thischan.loopstart;
398
-		thischan.sampcnt = -3;
399
-		break;
400
-	case 2: // ADPCM
401
-		{
402
-			thischan.buf8 = (int8_t*)&MMU.MMU_MEM[1][(thischan.addr>>20)&0xFF][(thischan.addr & MMU.MMU_MASK[1][(thischan.addr >> 20) & 0xFF])];
403
-			thischan.pcm16b = (int16_t)((thischan.buf8[1] << 8) | thischan.buf8[0]);
328
+		case 0: // 8-bit
329
+			//hischan.loopstart = thischan.loopstart << 2;
330
+			//hischan.length = (thischan.length << 2) + thischan.loopstart;
331
+			thischan.sampcnt = -3;
332
+			break;
333
+		case 1: // 16-bit
334
+			//thischan.loopstart = thischan.loopstart << 1;
335
+			//thischan.length = (thischan.length << 1) + thischan.loopstart;
336
+			thischan.sampcnt = -3;
337
+			break;
338
+		case 2: // ADPCM
339
+			thischan.pcm16b = read16(thischan.addr);
404 340
 			thischan.pcm16b_last = thischan.pcm16b;
405
-			thischan.index = thischan.buf8[2] & 0x7F;
341
+			thischan.index = read08(thischan.addr + 2) & 0x7F;
406 342
 			thischan.lastsampcnt = 7;
407 343
 			thischan.sampcnt = -3;
408 344
 			thischan.loop_index = K_ADPCM_LOOPING_RECOVERY_INDEX;
409
-		//	thischan.loopstart = thischan.loopstart << 3;
410
-		//	thischan.length = (thischan.length << 3) + thischan.loopstart;
345
+			//thischan.loopstart = thischan.loopstart << 3;
346
+			//hischan.length = (thischan.length << 3) + thischan.loopstart;
411 347
 			break;
412
-		}
413
-	case 3: // PSG
414
-		{
348
+		case 3: // PSG
415 349
 			thischan.sampcnt = -1;
416 350
 			thischan.x = 0x7FFF;
417
-			break;
418
-		}
419
-	default: break;
420 351
 	}
421 352
 
422
-	thischan.double_totlength_shifted = (double)(thischan.totlength << format_shift[thischan.format]);
353
+	thischan.double_totlength_shifted = static_cast<double>(thischan.totlength << format_shift[thischan.format]);
423 354
 
424
-	if(thischan.format != 3)
355
+	if (thischan.format != 3 && fEqual(thischan.double_totlength_shifted, 0.0))
425 356
 	{
426
-		if(fEqual(thischan.double_totlength_shifted, 0.0))
427
-		{
428
-			printf("INFO: Stopping channel %d due to zero length\n",channel);
429
-			thischan.status = CHANSTAT_STOPPED;
430
-		}
357
+		printf("INFO: Stopping channel %d due to zero length\n", channel);
358
+		thischan.status = CHANSTAT_STOPPED;
431 359
 	}
432 360
 }
433 361
 
434 362
 //////////////////////////////////////////////////////////////////////////////
435 363
 
436
-//#define SETBYTE(which,oldval,newval) oldval = (oldval & (~(0xFF<<(which*8)))) | ((newval)<<(which*8))
437
-template<typename T> static inline void SETBYTE(uint32_t which, T &oldval, uint8_t newval) { oldval = (oldval & (~(0xFF << (which*8)))) | (newval << (which*8)); }
438
-//#define GETBYTE(which,val) ((val>>(which*8))&0xFF)
364
+template<typename T> static inline void SETBYTE(uint32_t which, T &oldval, uint8_t newval) { oldval = (oldval & (~(0xFF << (which * 8)))) | (newval << (which * 8)); }
439 365
 static inline uint8_t GETBYTE(uint32_t which, uint32_t val) { return (val >> (which * 8)) & 0xFF; }
440 366
 
441
-uint8_t SPU_ReadByte(uint32_t addr) {
367
+uint8_t SPU_ReadByte(uint32_t addr)
368
+{
442 369
 	addr &= 0xFFF;
443 370
 	return SPU_core->ReadByte(addr);
444 371
 }
445
-uint16_t SPU_ReadWord(uint32_t addr) {
372
+uint16_t SPU_ReadWord(uint32_t addr)
373
+{
446 374
 	addr &= 0xFFF;
447 375
 	return SPU_core->ReadWord(addr);
448 376
 }
449
-uint32_t SPU_ReadLong(uint32_t addr) {
377
+uint32_t SPU_ReadLong(uint32_t addr)
378
+{
450 379
 	addr &= 0xFFF;
451 380
 	return SPU_core->ReadLong(addr);
452 381
 }
453 382
 
454 383
 uint16_t SPU_struct::ReadWord(uint32_t addr)
455 384
 {
456
-	return ReadByte(addr)|(ReadByte(addr+1)<<8);
385
+	return this->ReadByte(addr) | (this->ReadByte(addr + 1) << 8);
457 386
 }
458 387
 
459 388
 uint32_t SPU_struct::ReadLong(uint32_t addr)
460 389
 {
461
-	return ReadByte(addr)|(ReadByte(addr+1)<<8)|(ReadByte(addr+2)<<16)|(ReadByte(addr+3)<<24);
390
+	return this->ReadByte(addr) | (this->ReadByte(addr + 1) << 8) | (this->ReadByte(addr + 2) << 16) | (ReadByte(addr + 3) << 24);
462 391
 }
463 392
 
464 393
 uint8_t SPU_struct::ReadByte(uint32_t addr)
465 394
 {
466
-	switch(addr)
395
+	switch (addr)
467 396
 	{
468
-	//SOUNDCNT
469
-	case 0x500: return regs.mastervol;
470
-	case 0x501:
471
-		return (regs.ctl_left)|(regs.ctl_right<<2)|(regs.ctl_ch1bypass<<4)|(regs.ctl_ch3bypass<<5)|(regs.masteren<<7);
472
-	case 0x502: return 0;
473
-	case 0x503: return 0;
474
-
475
-	//SOUNDBIAS
476
-	case 0x504: return regs.soundbias&0xFF;
477
-	case 0x505: return (regs.soundbias>>8)&0xFF;
478
-	case 0x506: return 0;
479
-	case 0x507: return 0;
480
-
481
-	//SNDCAP0CNT/SNDCAP1CNT
482
-	case 0x508:
483
-	case 0x509: {
484
-		uint32_t which = addr-0x508;
485
-		return regs.cap[which].add
486
-			| (regs.cap[which].source<<1)
487
-			| (regs.cap[which].oneshot<<2)
488
-			| (regs.cap[which].bits8<<3)
489
-			//| (regs.cap[which].active<<7); //? which is right? need test
490
-			| (regs.cap[which].runtime.running<<7);
491
-	}
397
+		// SOUNDCNT
398
+		case 0x500:
399
+			return this->regs.mastervol;
400
+		case 0x501:
401
+			return this->regs.ctl_left | (this->regs.ctl_right << 2) | (this->regs.ctl_ch1bypass << 4) | (this->regs.ctl_ch3bypass << 5) | (this->regs.masteren << 7);
402
+		case 0x502:
403
+		case 0x503:
404
+			return 0;
405
+
406
+		// SOUNDBIAS
407
+		case 0x504:
408
+			return this->regs.soundbias & 0xFF;
409
+		case 0x505:
410
+			return (this->regs.soundbias >> 8) & 0xFF;
411
+		case 0x506:
412
+		case 0x507:
413
+			return 0;
414
+
415
+		// SNDCAP0CNT/SNDCAP1CNT
416
+		case 0x508:
417
+		case 0x509:
418
+		{
419
+			uint32_t which = addr - 0x508;
420
+			return this->regs.cap[which].add | (this->regs.cap[which].source << 1) | (this->regs.cap[which].oneshot << 2) | (this->regs.cap[which].bits8 << 3)
421
+				//| (regs.cap[which].active<<7); //? which is right? need test
422
+				| (this->regs.cap[which].runtime.running << 7);
423
+		}
492 424
 
493
-	//SNDCAP0DAD
494
-	case 0x510: return GETBYTE(0,regs.cap[0].dad);
495
-	case 0x511: return GETBYTE(1,regs.cap[0].dad);
496
-	case 0x512: return GETBYTE(2,regs.cap[0].dad);
497
-	case 0x513: return GETBYTE(3,regs.cap[0].dad);
498
-
499
-	//SNDCAP0LEN
500
-	case 0x514: return GETBYTE(0,regs.cap[0].len);
501
-	case 0x515: return GETBYTE(1,regs.cap[0].len);
502
-	case 0x516: return 0; //not used
503
-	case 0x517: return 0; //not used
504
-
505
-	//SNDCAP1DAD
506
-	case 0x518: return GETBYTE(0,regs.cap[1].dad);
507
-	case 0x519: return GETBYTE(1,regs.cap[1].dad);
508
-	case 0x51A: return GETBYTE(2,regs.cap[1].dad);
509
-	case 0x51B: return GETBYTE(3,regs.cap[1].dad);
510
-
511
-	//SNDCAP1LEN
512
-	case 0x51C: return GETBYTE(0,regs.cap[1].len);
513
-	case 0x51D: return GETBYTE(1,regs.cap[1].len);
514
-	case 0x51E: return 0; //not used
515
-	case 0x51F: return 0; //not used
516
-
517
-	default: {
518
-		//individual channel regs
519
-
520
-		uint32_t chan_num = (addr >> 4) & 0xF;
521
-		if(chan_num>0xF) return 0;
522
-		channel_struct &thischan=channels[chan_num];
523
-
524
-		switch(addr & 0xF) {
525
-			case 0x0: return thischan.vol;
526
-			case 0x1: {
527
-				uint8_t ret = thischan.datashift;
528
-				if(ret==4) ret=3;
529
-				ret |= thischan.hold<<7;
530
-				return ret;
531
-			}
532
-			case 0x2: return thischan.pan;
533
-			case 0x3: return thischan.waveduty|(thischan.repeat<<3)|(thischan.format<<5)|((thischan.status == CHANSTAT_PLAY)?0x80:0);
534
-			case 0x4: return 0; //return GETBYTE(0,thischan.addr); //not readable
535
-			case 0x5: return 0; //return GETBYTE(1,thischan.addr); //not readable
536
-			case 0x6: return 0; //return GETBYTE(2,thischan.addr); //not readable
537
-			case 0x7: return 0; //return GETBYTE(3,thischan.addr); //not readable
538
-			case 0x8: return GETBYTE(0,thischan.timer);
539
-			case 0x9: return GETBYTE(1,thischan.timer);
540
-			case 0xA: return GETBYTE(0,thischan.loopstart);
541
-			case 0xB: return GETBYTE(1,thischan.loopstart);
542
-			case 0xC: return 0; //return GETBYTE(0,thischan.length); //not readable
543
-			case 0xD: return 0; //return GETBYTE(1,thischan.length); //not readable
544
-			case 0xE: return 0; //return GETBYTE(2,thischan.length); //not readable
545
-			case 0xF: return 0; //return GETBYTE(3,thischan.length); //not readable
546
-			default: return 0; //impossible
547
-		} //switch on individual channel regs
548
-		} //default case
549
-	} //switch on address
425
+		// SNDCAP0DAD
426
+		case 0x510:
427
+			return GETBYTE(0, this->regs.cap[0].dad);
428
+		case 0x511:
429
+			return GETBYTE(1, this->regs.cap[0].dad);
430
+		case 0x512:
431
+			return GETBYTE(2, this->regs.cap[0].dad);
432
+		case 0x513:
433
+			return GETBYTE(3, this->regs.cap[0].dad);
434
+
435
+		// SNDCAP0LEN
436
+		case 0x514:
437
+			return GETBYTE(0, this->regs.cap[0].len);
438
+		case 0x515:
439
+			return GETBYTE(1, this->regs.cap[0].len);
440
+		case 0x516:
441
+		case 0x517:
442
+			return 0; //not used
443
+
444
+		// SNDCAP1DAD
445
+		case 0x518:
446
+			return GETBYTE(0, this->regs.cap[1].dad);
447
+		case 0x519:
448
+			return GETBYTE(1, this->regs.cap[1].dad);
449
+		case 0x51A:
450
+			return GETBYTE(2, this->regs.cap[1].dad);
451
+		case 0x51B:
452
+			return GETBYTE(3, this->regs.cap[1].dad);
453
+
454
+		// SNDCAP1LEN
455
+		case 0x51C:
456
+			return GETBYTE(0, this->regs.cap[1].len);
457
+		case 0x51D:
458
+			return GETBYTE(1, this->regs.cap[1].len);
459
+		case 0x51E:
460
+		case 0x51F:
461
+			return 0; //not used
462
+
463
+		default:
464
+		{
465
+			// individual channel regs
466
+
467
+			uint32_t chan_num = (addr >> 4) & 0xF;
468
+			if (chan_num > 0xF)
469
+				return 0;
470
+			channel_struct &thischan = this->channels[chan_num];
471
+
472
+			switch (addr & 0xF)
473
+			{
474
+				case 0x0:
475
+					return thischan.vol;
476
+				case 0x1:
477
+				{
478
+					uint8_t ret = thischan.datashift;
479
+					if (ret == 4)
480
+						ret = 3;
481
+					ret |= thischan.hold << 7;
482
+					return ret;
483
+				}
484
+				case 0x2:
485
+					return thischan.pan;
486
+				case 0x3:
487
+					return thischan.waveduty | (thischan.repeat << 3) | (thischan.format << 5) | (thischan.status == CHANSTAT_PLAY ? 0x80 : 0);
488
+				case 0x4:
489
+					return 0; //return GETBYTE(0, thischan.addr); //not readable
490
+				case 0x5:
491
+					return 0; //return GETBYTE(1, thischan.addr); //not readable
492
+				case 0x6:
493
+					return 0; //return GETBYTE(2, thischan.addr); //not readable
494
+				case 0x7:
495
+					return 0; //return GETBYTE(3, thischan.addr); //not readable
496
+				case 0x8:
497
+					return GETBYTE(0, thischan.timer);
498
+				case 0x9:
499
+					return GETBYTE(1, thischan.timer);
500
+				case 0xA:
501
+					return GETBYTE(0, thischan.loopstart);
502
+				case 0xB:
503
+					return GETBYTE(1, thischan.loopstart);
504
+				case 0xC:
505
+					return 0; //return GETBYTE(0, thischan.length); //not readable
506
+				case 0xD:
507
+					return 0; //return GETBYTE(1, thischan.length); //not readable
508
+				case 0xE:
509
+					return 0; //return GETBYTE(2, thischan.length); //not readable
510
+				case 0xF:
511
+					return 0; //return GETBYTE(3, thischan.length); //not readable
512
+				default:
513
+					return 0; //impossible
514
+			} // switch on individual channel regs
515
+		} // default case
516
+	} // switch on address
550 517
 }
551 518
 
552 519
 SPUFifo::SPUFifo()
553 520
 {
554
-	reset();
521
+	this->reset();
555 522
 }
556 523
 
557 524
 void SPUFifo::reset()
558 525
 {
559
-	head = tail = size = 0;
526
+	this->head = this->tail = this->size = 0;
560 527
 }
561 528
 
562 529
 void SPUFifo::enqueue(int16_t val)
563 530
 {
564
-	if(size==16) return;
565
-	buffer[tail] = val;
566
-	tail++;
567
-	tail &= 15;
568
-	size++;
531
+	if (this->size == 16)
532
+		return;
533
+	this->buffer[this->tail] = val;
534
+	++this->tail;
535
+	this->tail &= 15;
536
+	++this->size;
569 537
 }
570 538
 
571 539
 int16_t SPUFifo::dequeue()
572 540
 {
573
-	if(size==0) return 0;
574
-	head++;
575
-	head &= 15;
576
-	int16_t ret = buffer[head];
577
-	size--;
541
+	if (!this->size)
542
+		return 0;
543
+	++this->head;
544
+	this->head &= 15;
545
+	int16_t ret = this->buffer[this->head];
546
+	--this->size;
578 547
 	return ret;
579 548
 }
580 549
 
581
-/*void SPUFifo::save(EMUFILE* fp)
582
-{
583
-	uint32_t version = 1;
584
-	write32le(version,fp);
585
-	write32le(head,fp);
586
-	write32le(tail,fp);
587
-	write32le(size,fp);
588
-	for(int i=0;i<16;i++)
589
-		write16le(buffer[i],fp);
590
-}*/
591
-
592
-bool SPUFifo::load(EMUFILE* fp)
593
-{
594
-	uint32_t version;
595
-	if(read32le(&version,fp) != 1) return false;
596
-	read32le(&head,fp);
597
-	read32le(&tail,fp);
598
-	read32le(&size,fp);
599
-	for(int i=0;i<16;i++)
600
-		read16le(&buffer[i],fp);
601
-	return true;
602
-}
603
-
604 550
 void SPU_struct::ProbeCapture(int which)
605 551
 {
606
-	//VERY UNTESTED -- HOW MUCH OF THIS RESETS, AND WHEN?
552
+	// VERY UNTESTED -- HOW MUCH OF THIS RESETS, AND WHEN?
607 553
 
608
-	if(!regs.cap[which].active)
554
+	if (!this->regs.cap[which].active)
609 555
 	{
610
-		regs.cap[which].runtime.running = 0;
556
+		this->regs.cap[which].runtime.running = 0;
611 557
 		return;
612 558
 	}
613 559
 
614
-	REGS::CAP &cap = regs.cap[which];
560
+	REGS::CAP &cap = this->regs.cap[which];
615 561
 	cap.runtime.running = 1;
616 562
 	cap.runtime.curdad = cap.dad;
617 563
 	uint32_t len = cap.len;
618
-	if(len==0) len=1;
619
-	cap.runtime.maxdad = cap.dad + len*4;
564
+	if (!len)
565
+		len = 1;
566
+	cap.runtime.maxdad = cap.dad + len * 4;
620 567
 	cap.runtime.sampcnt = 0;
621 568
 	cap.runtime.fifo.reset();
622 569
 }
623 570
 
624 571
 void SPU_struct::WriteByte(uint32_t addr, uint8_t val)
625 572
 {
626
-	switch(addr)
573
+	switch (addr)
627 574
 	{
628
-	//SOUNDCNT
629
-	case 0x500:
630
-		regs.mastervol = val&0x7F;
631
-		break;
632
-	case 0x501:
633
-		regs.ctl_left  = (val>>0)&3;
634
-		regs.ctl_right = (val>>2)&3;
635
-		regs.ctl_ch1bypass = (val>>4)&1;
636
-		regs.ctl_ch3bypass = (val>>5)&1;
637
-		regs.masteren = (val>>7)&1;
638
-		for(int i=0;i<16;i++)
639
-			KeyProbe(i);
640
-		break;
641
-	case 0x502: break; //not used
642
-	case 0x503: break; //not used
643
-
644
-	//SOUNDBIAS
645
-	case 0x504: SETBYTE(0,regs.soundbias, val); break;
646
-	case 0x505: SETBYTE(1,regs.soundbias, val&3); break;
647
-	case 0x506: break; //these dont answer anyway
648
-	case 0x507: break; //these dont answer anyway
649
-
650
-	//SNDCAP0CNT/SNDCAP1CNT
651
-	case 0x508:
652
-	case 0x509: {
653
-		uint32_t which = addr-0x508;
654
-		regs.cap[which].add = static_cast<uint8_t>(BIT0(val));
655
-		regs.cap[which].source = static_cast<uint8_t>(BIT1(val));
656
-		regs.cap[which].oneshot = static_cast<uint8_t>(BIT2(val));
657
-		regs.cap[which].bits8 = static_cast<uint8_t>(BIT3(val));
658
-		regs.cap[which].active = static_cast<uint8_t>(BIT7(val));
659
-		ProbeCapture(which);
660
-		break;
661
-	}
662
-
663
-	//SNDCAP0DAD
664
-	case 0x510: SETBYTE(0,regs.cap[0].dad,val); break;
665
-	case 0x511: SETBYTE(1,regs.cap[0].dad,val); break;
666
-	case 0x512: SETBYTE(2,regs.cap[0].dad,val); break;
667
-	case 0x513: SETBYTE(3,regs.cap[0].dad,val&7); break;
575
+		// SOUNDCNT
576
+		case 0x500:
577
+			this->regs.mastervol = val & 0x7F;
578
+			break;
579
+		case 0x501:
580
+			this->regs.ctl_left = val & 3;
581
+			this->regs.ctl_right = (val >> 2) & 3;
582
+			this->regs.ctl_ch1bypass = (val >> 4) & 1;
583
+			this->regs.ctl_ch3bypass = (val >> 5) & 1;
584
+			this->regs.masteren = (val >> 7) & 1;
585
+			for (int i = 0; i < 16; ++i)
586
+				this->KeyProbe(i);
587
+			break;
588
+		case 0x502:
589
+		case 0x503:
590
+			break; // not used
668 591
 
669
-	//SNDCAP0LEN
670
-	case 0x514: SETBYTE(0,regs.cap[0].len,val); break;
671
-	case 0x515: SETBYTE(1,regs.cap[0].len,val); break;
672
-	case 0x516: break; //not used
673
-	case 0x517: break; //not used
592
+		// SOUNDBIAS
593
+		case 0x504:
594
+			SETBYTE(0, this->regs.soundbias, val);
595
+			break;
596
+		case 0x505:
597
+			SETBYTE(1, this->regs.soundbias, val & 3);
598
+			break;
599
+		case 0x506:
600
+		case 0x507:
601
+			break; // these dont answer anyway
674 602
 
675
-	//SNDCAP1DAD
676
-	case 0x518: SETBYTE(0,regs.cap[1].dad,val); break;
677
-	case 0x519: SETBYTE(1,regs.cap[1].dad,val); break;
678
-	case 0x51A: SETBYTE(2,regs.cap[1].dad,val); break;
679
-	case 0x51B: SETBYTE(3,regs.cap[1].dad,val&7); break;
603
+		// SNDCAP0CNT/SNDCAP1CNT
604
+		case 0x508:
605
+		case 0x509:
606
+		{
607
+			uint32_t which = addr - 0x508;
608
+			this->regs.cap[which].add = static_cast<uint8_t>(BIT0(val));
609
+			this->regs.cap[which].source = static_cast<uint8_t>(BIT1(val));
610
+			this->regs.cap[which].oneshot = static_cast<uint8_t>(BIT2(val));
611
+			this->regs.cap[which].bits8 = static_cast<uint8_t>(BIT3(val));
612
+			this->regs.cap[which].active = static_cast<uint8_t>(BIT7(val));
613
+			this->ProbeCapture(which);
614
+			break;
615
+		}
680 616
 
681
-	//SNDCAP1LEN
682
-	case 0x51C: SETBYTE(0,regs.cap[1].len,val); break;
683
-	case 0x51D: SETBYTE(1,regs.cap[1].len,val); break;
684
-	case 0x51E: break; //not used
685
-	case 0x51F: break; //not used
617
+		// SNDCAP0DAD
618
+		case 0x510:
619
+			SETBYTE(0, this->regs.cap[0].dad, val);
620
+			break;
621
+		case 0x511:
622
+			SETBYTE(1, this->regs.cap[0].dad, val);
623
+			break;
624
+		case 0x512:
625
+			SETBYTE(2, this->regs.cap[0].dad, val);
626
+			break;
627
+		case 0x513:
628
+			SETBYTE(3, this->regs.cap[0].dad, val & 7);
629
+			break;
686 630
 
631
+		// SNDCAP0LEN
632
+		case 0x514:
633
+			SETBYTE(0, this->regs.cap[0].len, val);
634
+			break;
635
+		case 0x515:
636
+			SETBYTE(1, this->regs.cap[0].len, val);
637
+			break;
638
+		case 0x516:
639
+		case 0x517:
640
+			break; // not used
687 641
 
642
+		// SNDCAP1DAD
643
+		case 0x518:
644
+			SETBYTE(0, this->regs.cap[1].dad, val);
645
+			break;
646
+		case 0x519:
647
+			SETBYTE(1, this->regs.cap[1].dad, val);
648
+			break;
649
+		case 0x51A:
650
+			SETBYTE(2, this->regs.cap[1].dad, val);
651
+			break;
652
+		case 0x51B:
653
+			SETBYTE(3, this->regs.cap[1].dad, val & 7);
654
+			break;
688 655
 
689
-	default: {
690
-		//individual channel regs
656
+		// SNDCAP1LEN
657
+		case 0x51C:
658
+			SETBYTE(0, this->regs.cap[1].len, val);
659
+			break;
660
+		case 0x51D:
661
+			SETBYTE(1, this->regs.cap[1].len, val);
662
+			break;
663
+		case 0x51E:
664
+		case 0x51F:
665
+			break; // not used
691 666
 
692
-		uint32_t chan_num = (addr >> 4) & 0xF;
693
-		if(chan_num>0xF) break;
694
-		channel_struct &thischan=channels[chan_num];
667
+		default:
668
+		{
669
+			// individual channel regs
695 670
 
696
-		switch(addr & 0xF) {
697
-			case 0x0:
698
-				thischan.vol = val & 0x7F;
671
+			uint32_t chan_num = (addr >> 4) & 0xF;
672
+			if (chan_num>0xF)
699 673
 				break;
700
-			case 0x1:
701
-				thischan.datashift = val & 0x3;
702
-				if (thischan.datashift == 3)
703
-					thischan.datashift = 4;
704
-				thischan.hold = (val >> 7) & 0x1;
705
-				break;
706
-			case 0x2:
707
-				thischan.pan = val & 0x7F;
708
-				break;
709
-			case 0x3:
710
-				thischan.waveduty = val & 0x7;
711
-				thischan.repeat = (val >> 3) & 0x3;
712
-				thischan.format = (val >> 5) & 0x3;
713
-				thischan.keyon = static_cast<uint8_t>(BIT7(val));
714
-				KeyProbe(chan_num);
715
-				break;
716
-			case 0x4: SETBYTE(0,thischan.addr,val); break;
717
-			case 0x5: SETBYTE(1,thischan.addr,val); break;
718
-			case 0x6: SETBYTE(2,thischan.addr,val); break;
719
-			case 0x7: SETBYTE(3,thischan.addr,val&0x7); break; //only 27 bits of this register are used
720
-			case 0x8:
721
-				SETBYTE(0,thischan.timer,val);
722
-				adjust_channel_timer(&thischan);
723
-				break;
724
-			case 0x9:
725
-				SETBYTE(1,thischan.timer,val);
726
-				adjust_channel_timer(&thischan);
727
-				break;
728
-			case 0xA: SETBYTE(0,thischan.loopstart,val); break;
729
-			case 0xB: SETBYTE(1,thischan.loopstart,val); break;
730
-			case 0xC: SETBYTE(0,thischan.length,val); break;
731
-			case 0xD: SETBYTE(1,thischan.length,val); break;
732
-			case 0xE: SETBYTE(2,thischan.length,val & 0x3F); break; //only 22 bits of this register are used
733
-			case 0xF: SETBYTE(3,thischan.length,0); break;
734
-		} //switch on individual channel regs
735
-		} //default case
736
-	} //switch on address
674
+			channel_struct &thischan = this->channels[chan_num];
675
+
676
+			switch (addr & 0xF)
677
+			{
678
+				case 0x0:
679
+					thischan.vol = val & 0x7F;
680
+					break;
681
+				case 0x1:
682
+					thischan.datashift = val & 0x3;
683
+					if (thischan.datashift == 3)
684
+						thischan.datashift = 4;
685
+					thischan.hold = (val >> 7) & 0x1;
686
+					break;
687
+				case 0x2:
688
+					thischan.pan = val & 0x7F;
689
+					break;
690
+				case 0x3:
691
+					thischan.waveduty = val & 0x7;
692
+					thischan.repeat = (val >> 3) & 0x3;
693
+					thischan.format = (val >> 5) & 0x3;
694
+					thischan.keyon = static_cast<uint8_t>(BIT7(val));
695
+					this->KeyProbe(chan_num);
696
+					break;
697
+				case 0x4:
698
+					SETBYTE(0, thischan.addr, val);
699
+					break;
700
+				case 0x5:
701
+					SETBYTE(1, thischan.addr, val);
702
+					break;
703
+				case 0x6:
704
+					SETBYTE(2, thischan.addr, val);
705
+					break;
706
+				case 0x7:
707
+					SETBYTE(3, thischan.addr, val & 0x7);
708
+					break; // only 27 bits of this register are used
709
+				case 0x8:
710
+					SETBYTE(0, thischan.timer, val);
711
+					adjust_channel_timer(&thischan);
712
+					break;
713
+				case 0x9:
714
+					SETBYTE(1, thischan.timer, val);
715
+					adjust_channel_timer(&thischan);
716
+					break;
717
+				case 0xA:
718
+					SETBYTE(0, thischan.loopstart, val);
719
+					break;
720
+				case 0xB:
721
+					SETBYTE(1, thischan.loopstart, val);
722
+					break;
723
+				case 0xC:
724
+					SETBYTE(0, thischan.length, val);
725
+					break;
726
+				case 0xD:
727
+					SETBYTE(1, thischan.length, val);
728
+					break;
729
+				case 0xE:
730
+					SETBYTE(2, thischan.length, val & 0x3F);
731
+					break; // only 22 bits of this register are used
732
+				case 0xF:
733
+					SETBYTE(3, thischan.length, 0);
734
+					break;
735
+			} // switch on individual channel regs
736
+		} // default case
737
+	} // switch on address
737 738
 }
738 739
 
739 740
 void SPU_WriteByte(uint32_t addr, uint8_t val)
... ...
@@ -741,16 +742,17 @@ void SPU_WriteByte(uint32_t addr, uint8_t val)
741 742
 	//printf("%08X: chan:%02X reg:%02X val:%02X\n",addr,(addr>>4)&0xF,addr&0xF,val);
742 743
 	addr &= 0xFFF;
743 744
 
744
-	SPU_core->WriteByte(addr,val);
745
-	if(SPU_user) SPU_user->WriteByte(addr,val);
745
+	SPU_core->WriteByte(addr, val);
746
+	if (SPU_user)
747
+		SPU_user->WriteByte(addr, val);
746 748
 }
747 749
 
748 750
 //////////////////////////////////////////////////////////////////////////////
749 751
 
750 752
 void SPU_struct::WriteWord(uint32_t addr, uint16_t val)
751 753
 {
752
-	WriteByte(addr,val&0xFF);
753
-	WriteByte(addr+1,(val>>8)&0xFF);
754
+	this->WriteByte(addr, val & 0xFF);
755
+	this->WriteByte(addr + 1, (val >> 8) & 0xFF);
754 756
 }
755 757
 
756 758
 void SPU_WriteWord(uint32_t addr, uint16_t val)
... ...
@@ -758,18 +760,19 @@ void SPU_WriteWord(uint32_t addr, uint16_t val)
758 760
 	//printf("%08X: chan:%02X reg:%02X val:%04X\n",addr,(addr>>4)&0xF,addr&0xF,val);
759 761
 	addr &= 0xFFF;
760 762
 
761
-	SPU_core->WriteWord(addr,val);
762
-	if(SPU_user) SPU_user->WriteWord(addr,val);
763
+	SPU_core->WriteWord(addr, val);
764
+	if (SPU_user)
765
+		SPU_user->WriteWord(addr, val);
763 766
 }
764 767
 
765 768
 //////////////////////////////////////////////////////////////////////////////
766 769
 
767 770
 void SPU_struct::WriteLong(uint32_t addr, uint32_t val)
768 771
 {
769
-	WriteByte(addr,val&0xFF);
770
-	WriteByte(addr+1,(val>>8)&0xFF);
771
-	WriteByte(addr+2,(val>>16)&0xFF);
772
-	WriteByte(addr+3,(val>>24)&0xFF);
772
+	this->WriteByte(addr,val & 0xFF);
773
+	this->WriteByte(addr + 1,(val >> 8) & 0xFF);
774
+	this->WriteByte(addr + 2,(val >> 16) & 0xFF);
775
+	this->WriteByte(addr + 3,(val >> 24) & 0xFF);
773 776
 }
774 777
 
775 778
 void SPU_WriteLong(uint32_t addr, uint32_t val)
... ...
@@ -777,16 +780,17 @@ void SPU_WriteLong(uint32_t addr, uint32_t val)
777 780
 	//printf("%08X: chan:%02X reg:%02X val:%08X\n",addr,(addr>>4)&0xF,addr&0xF,val);
778 781
 	addr &= 0xFFF;
779 782
 
780
-	SPU_core->WriteLong(addr,val);
781
-	if(SPU_user) SPU_user->WriteLong(addr,val);
783
+	SPU_core->WriteLong(addr, val);
784
+	if (SPU_user)
785
+		SPU_user->WriteLong(addr, val);
782 786
 }
783 787
 
784 788
 //////////////////////////////////////////////////////////////////////////////
785 789
 
786 790
 template<SPUInterpolationMode INTERPOLATE_MODE> static inline int32_t Interpolate(int32_t a, int32_t b, double ratio)
787 791
 {
788
-	double sampleA = (double)a;
789
-	double sampleB = (double)b;
792
+	double sampleA = static_cast<double>(a);
793
+	double sampleB = static_cast<double>(b);
790 794
 	ratio = ratio - u32floor(ratio);
791 795
 
792 796
 	switch (INTERPOLATE_MODE)
... ...
@@ -795,7 +799,7 @@ template<SPUInterpolationMode INTERPOLATE_MODE> static inline int32_t Interpolat
795 799
 			// Cosine Interpolation Formula:
796 800
 			// ratio2 = (1 - cos(ratio * M_PI)) / 2
797 801
 			// sampleI = sampleA * (1 - ratio2) + sampleB * ratio2
798
-			return s32floor((cos_lut[(unsigned int)(ratio * (double)COSINE_INTERPOLATION_RESOLUTION)] * (sampleB - sampleA)) + sampleA);
802
+			return s32floor((cos_lut[static_cast<unsigned>(ratio * COSINE_INTERPOLATION_RESOLUTION)] * (sampleB - sampleA)) + sampleA);
799 803
 			break;
800 804
 
801 805
 		case SPUInterpolation_Linear:
... ...
@@ -822,17 +826,18 @@ template<SPUInterpolationMode INTERPOLATE_MODE> static inline void Fetch8BitData
822 826
 	}
823 827
 
824 828
 	uint32_t loc = u32floor(chan->sampcnt);
825
-	if(INTERPOLATE_MODE != SPUInterpolation_None)
829
+	if (INTERPOLATE_MODE != SPUInterpolation_None)
826 830
 	{
827
-		int32_t a = (int32_t)(chan->buf8[loc] << 8);
828
-		if(loc < (chan->totlength << 2) - 1) {
829
-			int32_t b = (int32_t)(chan->buf8[loc + 1] << 8);
831
+		int32_t a = static_cast<int32_t>(read_s8(chan->addr + loc) << 8);
832
+		if (loc < (chan->totlength << 2) - 1)
833
+		{
834
+			int32_t b = static_cast<int32_t>(read_s8(chan->addr + loc + 1) << 8);
830 835
 			a = Interpolate<INTERPOLATE_MODE>(a, b, chan->sampcnt);
831 836
 		}
832 837
 		*data = a;
833 838
 	}
834 839
 	else
835
-		*data = (int32_t)chan->buf8[loc] << 8;
840
+		*data = static_cast<int32_t>(read_s8(chan->addr + loc) << 8);
836 841
 }
837 842
 
838 843
 template<SPUInterpolationMode INTERPOLATE_MODE> static inline void Fetch16BitData(const channel_struct * const chan, int32_t *data)
... ...
@@ -846,16 +851,17 @@ template<SPUInterpolationMode INTERPOLATE_MODE> static inline void Fetch16BitDat
846 851
 	if(INTERPOLATE_MODE != SPUInterpolation_None)
847 852
 	{
848 853
 		uint32_t loc = u32floor(chan->sampcnt);
849
-		int32_t a = (int32_t)chan->buf16[loc], b;
850
-		if(loc < (chan->totlength << 1) - 1)
854
+		
855
+		int32_t a = static_cast<int32_t>(read16(loc * 2 + chan->addr));
856
+		if (loc < (chan->totlength << 1) - 1)
851 857
 		{
852
-			b = (int32_t)chan->buf16[loc + 1];
858
+			int32_t b = static_cast<int32_t>(read16(loc * 2 + chan->addr + 2));
853 859
 			a = Interpolate<INTERPOLATE_MODE>(a, b, chan->sampcnt);
854 860
 		}
855 861
 		*data = a;
856 862
 	}
857 863
 	else
858
-		*data = (int32_t)chan->buf16[u32floor(chan->sampcnt)];
864
+		*data = read16(chan->addr + u32floor(chan->sampcnt) * 2);
859 865
 }
860 866
 
861 867
 template<SPUInterpolationMode INTERPOLATE_MODE> static inline void FetchADPCMData(channel_struct * const chan, int32_t * const data)
... ...
@@ -867,34 +873,36 @@ template<SPUInterpolationMode INTERPOLATE_MODE> static inline void FetchADPCMDat
867 873
 	}
868 874
 
869 875
 	// No sense decoding, just return the last sample
870
-	if (chan->lastsampcnt != u32floor(chan->sampcnt)){
871
-
872
-	    const uint32_t endExclusive = u32floor(chan->sampcnt+1);
873
-	    for (uint32_t i = chan->lastsampcnt+1; i < endExclusive; i++)
874
-	    {
875
-	    	const uint32_t shift = (i&1)<<2;
876
-	    	const uint32_t data4bit = (((uint32_t)chan->buf8[i >> 1]) >> shift);
876
+	if (chan->lastsampcnt != u32floor(chan->sampcnt))
877
+	{
878
+		uint32_t endExclusive = u32floor(chan->sampcnt + 1);
879
+		for (uint32_t i = chan->lastsampcnt + 1; i < endExclusive; ++i)
880
+		{
881
+			uint32_t shift = (i & 1) << 2;
882
+			uint32_t data4bit = static_cast<uint32_t>(read08(chan->addr + (i >> 1))) >> shift;
877 883
 
878
-	    	const int32_t diff = precalcdifftbl[chan->index][data4bit & 0xF];
879
-	    	chan->index = precalcindextbl[chan->index][data4bit & 0x7];
884
+			int32_t diff = precalcdifftbl[chan->index][data4bit & 0xF];
885
+			chan->index = precalcindextbl[chan->index][data4bit & 0x7];
880 886
 
881
-	    	chan->pcm16b_last = chan->pcm16b;
882
-	    	chan->pcm16b = static_cast<int16_t>(MinMax<int32_t>(chan->pcm16b+diff, -0x8000, 0x7FFF));
887
+			chan->pcm16b_last = chan->pcm16b;
888
+			chan->pcm16b = MinMax(chan->pcm16b+diff, -0x8000, 0x7FFF);
883 889
 
884
-			if(i == static_cast<uint32_t>(chan->loopstart<<3)) {
885
-				if(chan->loop_index != K_ADPCM_LOOPING_RECOVERY_INDEX) printf("over-snagging\n");
890
+			if (i == static_cast<uint32_t>(chan->loopstart << 3))
891
+			{
892
+				if (chan->loop_index != K_ADPCM_LOOPING_RECOVERY_INDEX)
893
+					printf("over-snagging\n");
886 894
 				chan->loop_pcm16b = chan->pcm16b;
887 895
 				chan->loop_index = chan->index;
888 896
 			}
889
-	    }
897
+		}
890 898
 
891
-	    chan->lastsampcnt = u32floor(chan->sampcnt);
892
-    }
899
+		chan->lastsampcnt = u32floor(chan->sampcnt);
900
+	}
893 901
 
894
-	if(INTERPOLATE_MODE != SPUInterpolation_None)
895
-		*data = Interpolate<INTERPOLATE_MODE>((int32_t)chan->pcm16b_last,(int32_t)chan->pcm16b,chan->sampcnt);
902
+	if (INTERPOLATE_MODE != SPUInterpolation_None)
903
+		*data = Interpolate<INTERPOLATE_MODE>(static_cast<int32_t>(chan->pcm16b_last), static_cast<int32_t>(chan->pcm16b), chan->sampcnt);
896 904
 	else
897
-		*data = (int32_t)chan->pcm16b;
905
+		*data = static_cast<int32_t>(chan->pcm16b);
898 906
 }
899 907
 
900 908
 static inline void FetchPSGData(channel_struct *chan, int32_t *data)
... ...
@@ -905,26 +913,22 @@ static inline void FetchPSGData(channel_struct *chan, int32_t *data)
905 913
 		return;
906 914
 	}
907 915
 
908
-	if(chan->num < 8)
909
-	{
916
+	if (chan->num < 8)
910 917
 		*data = 0;
911
-	}
912
-	else if(chan->num < 14)
913
-	{
914
-		*data = (int32_t)wavedutytbl[chan->waveduty][(u32floor(chan->sampcnt)) & 0x7];
915
-	}
918
+	else if (chan->num < 14)
919
+		*data = static_cast<int32_t>(wavedutytbl[chan->waveduty][u32floor(chan->sampcnt) & 0x7]);
916 920
 	else
917 921
 	{
918
-		if(chan->lastsampcnt == u32floor(chan->sampcnt))
922
+		if (chan->lastsampcnt == u32floor(chan->sampcnt))
919 923
 		{
920
-			*data = (int32_t)chan->psgnoise_last;
924
+			*data = static_cast<int32_t>(chan->psgnoise_last);
921 925
 			return;
922 926
 		}
923 927
 
924 928
 		uint32_t max = u32floor(chan->sampcnt);
925
-		for(uint32_t i = chan->lastsampcnt; i < max; i++)
929
+		for (uint32_t i = chan->lastsampcnt; i < max; ++i)
926 930
 		{
927
-			if(chan->x & 0x1)
931
+			if (chan->x & 0x1)
928 932
 			{
929 933
 				chan->x = (chan->x >> 1) ^ 0x6000;
930 934
 				chan->psgnoise_last = -0x7FFF;
... ...
@@ -938,36 +942,36 @@ static inline void FetchPSGData(channel_struct *chan, int32_t *data)
938 942
 
939 943
 		chan->lastsampcnt = u32floor(chan->sampcnt);
940 944
 
941
-		*data = (int32_t)chan->psgnoise_last;
945
+		*data = static_cast<int32_t>(chan->psgnoise_last);
942 946
 	}
943 947
 }
944 948
 
945 949
 //////////////////////////////////////////////////////////////////////////////
946 950
 
947
-static inline void MixL(SPU_struct* SPU, channel_struct *chan, int32_t data)
951
+static inline void MixL(SPU_struct *SPU, channel_struct *chan, int32_t data)
948 952
 {
949 953
 	data = spumuldiv7(data, chan->vol) >> chan->datashift;
950
-	SPU->sndbuf[SPU->bufpos<<1] += data;
954
+	SPU->sndbuf[SPU->bufpos << 1] += data;
951 955
 }
952 956
 
953
-static inline void MixR(SPU_struct* SPU, channel_struct *chan, int32_t data)
957
+static inline void MixR(SPU_struct *SPU, channel_struct *chan, int32_t data)
954 958
 {
955 959
 	data = spumuldiv7(data, chan->vol) >> chan->datashift;
956
-	SPU->sndbuf[(SPU->bufpos<<1)+1] += data;
960
+	SPU->sndbuf[(SPU->bufpos << 1) + 1] += data;
957 961
 }
958 962
 
959
-static inline void MixLR(SPU_struct* SPU, channel_struct *chan, int32_t data)
963
+static inline void MixLR(SPU_struct *SPU, channel_struct *chan, int32_t data)
960 964
 {
961 965
 	data = spumuldiv7(data, chan->vol) >> chan->datashift;
962
-	SPU->sndbuf[SPU->bufpos<<1] += spumuldiv7(data, 127 - chan->pan);
963
-	SPU->sndbuf[(SPU->bufpos<<1)+1] += spumuldiv7(data, chan->pan);
966
+	SPU->sndbuf[SPU->bufpos << 1] += spumuldiv7(data, 127 - chan->pan);
967
+	SPU->sndbuf[(SPU->bufpos << 1) + 1] += spumuldiv7(data, chan->pan);
964 968
 }
965 969
 
966 970
 //////////////////////////////////////////////////////////////////////////////
967 971
 
968 972
 template<int FORMAT> static inline void TestForLoop(SPU_struct *SPU, channel_struct *chan)
969 973
 {
970
-	const int shift = (FORMAT == 0 ? 2 : 1);
974
+	int shift = !FORMAT ? 2 : 1;
971 975
 
972 976
 	chan->sampcnt += chan->sampinc;
973 977
 
... ...
@@ -977,7 +981,7 @@ template<int FORMAT> static inline void TestForLoop(SPU_struct *SPU, channel_str
977 981
 		if (chan->repeat == 1)
978 982
 		{
979 983
 			while (chan->sampcnt > chan->double_totlength_shifted)
980
-				chan->sampcnt -= chan->double_totlength_shifted - (double)(chan->loopstart << shift);
984
+				chan->sampcnt -= chan->double_totlength_shifted - static_cast<double>(chan->loopstart << shift);
981 985
 			//chan->sampcnt = (double)(chan->loopstart << shift);
982 986
 		}
983 987
 		else
... ...
@@ -998,19 +1002,19 @@ static inline void TestForLoop2(SPU_struct *SPU, channel_struct *chan)
998 1002
 		if (chan->repeat == 1)
999 1003
 		{
1000 1004
 			while (chan->sampcnt > chan->double_totlength_shifted)
1001
-				chan->sampcnt -= chan->double_totlength_shifted - (double)(chan->loopstart << 3);
1005
+				chan->sampcnt -= chan->double_totlength_shifted - static_cast<double>(chan->loopstart << 3);
1002 1006
 
1003
-			if(chan->loop_index == K_ADPCM_LOOPING_RECOVERY_INDEX)
1007
+			if (chan->loop_index == K_ADPCM_LOOPING_RECOVERY_INDEX)
1004 1008
 			{
1005
-				chan->pcm16b = (int16_t)((chan->buf8[1] << 8) | chan->buf8[0]);
1006
-				chan->index = chan->buf8[2] & 0x7F;
1009
+				chan->pcm16b = read16(chan->addr);
1010
+				chan->index = read08(chan->addr + 2) & 0x7F;
1007 1011
 				chan->lastsampcnt = 7;
1008 1012
 			}
1009 1013
 			else
1010 1014
 			{
1011 1015
 				chan->pcm16b = chan->loop_pcm16b;
1012 1016
 				chan->index = chan->loop_index;
1013
-				chan->lastsampcnt = (chan->loopstart << 3);
1017
+				chan->lastsampcnt = chan->loopstart << 3;
1014 1018
 			}
1015 1019
 		}
1016 1020
 		else
... ...
@@ -1022,116 +1026,146 @@ static inline void TestForLoop2(SPU_struct *SPU, channel_struct *chan)
1022 1026
 	}
1023 1027
 }
1024 1028
 
1025
-template<int CHANNELS> inline static void SPU_Mix(SPU_struct* SPU, channel_struct *chan, int32_t data)
1029
+template<int CHANNELS> static inline void SPU_Mix(SPU_struct *SPU, channel_struct *chan, int32_t data)
1026 1030
 {
1027
-	switch(CHANNELS)
1031
+	switch (CHANNELS)
1028 1032
 	{
1029
-		case 0: MixL(SPU, chan, data); break;
1030
-		case 1: MixLR(SPU, chan, data); break;
1031
-		case 2: MixR(SPU, chan, data); break;
1033
+		case 0:
1034
+			MixL(SPU, chan, data);
1035
+			break;
1036
+		case 1:
1037
+			MixLR(SPU, chan, data);
1038
+			break;
1039
+		case 2:
1040
+			MixR(SPU, chan, data);
1032 1041
 	}
1033 1042
 	SPU->lastdata = data;
1034 1043
 }
1035 1044
 
1036
-//WORK
1037
-template<int FORMAT, SPUInterpolationMode INTERPOLATE_MODE, int CHANNELS>
1038
-	inline static void ____SPU_ChanUpdate(SPU_struct* const SPU, channel_struct* const chan)
1045
+// WORK
1046
+template<int FORMAT, SPUInterpolationMode INTERPOLATE_MODE, int CHANNELS> static inline void ____SPU_ChanUpdate(SPU_struct *const SPU, channel_struct *const chan)
1039 1047
 {
1040
-	for (; SPU->bufpos < SPU->buflength; SPU->bufpos++)
1048
+	for (; SPU->bufpos < SPU->buflength; ++SPU->bufpos)
1041 1049
 	{
1042
-		if(CHANNELS != -1)
1050
+		if (CHANNELS != -1)
1043 1051
 		{
1044 1052
 			int32_t data = 0;
1045
-			switch(FORMAT)
1053
+			switch (FORMAT)
1046 1054
 			{
1047
-				case 0: Fetch8BitData<INTERPOLATE_MODE>(chan, &data); break;
1048
-				case 1: Fetch16BitData<INTERPOLATE_MODE>(chan, &data); break;
1049
-				case 2: FetchADPCMData<INTERPOLATE_MODE>(chan, &data); break;
1050
-				case 3: FetchPSGData(chan, &data); break;
1055
+				case 0:
1056
+					Fetch8BitData<INTERPOLATE_MODE>(chan, &data);
1057
+					break;
1058
+				case 1:
1059
+					Fetch16BitData<INTERPOLATE_MODE>(chan, &data);
1060
+					break;
1061
+				case 2:
1062
+					FetchADPCMData<INTERPOLATE_MODE>(chan, &data);
1063
+					break;
1064
+				case 3:
1065
+					FetchPSGData(chan, &data);
1051 1066
 			}
1052 1067
 			SPU_Mix<CHANNELS>(SPU, chan, data);
1053 1068
 		}
1054 1069
 
1055
-		switch(FORMAT) {
1056
-			case 0: case 1: TestForLoop<FORMAT>(SPU, chan); break;
1057
-			case 2: TestForLoop2(SPU, chan); break;
1058
-			case 3: chan->sampcnt += chan->sampinc; break;
1070
+		switch (FORMAT)
1071
+		{
1072
+			case 0:
1073
+			case 1:
1074
+				TestForLoop<FORMAT>(SPU, chan);
1075
+				break;
1076
+			case 2:
1077
+				TestForLoop2(SPU, chan);
1078
+				break;
1079
+			case 3:
1080
+				chan->sampcnt += chan->sampinc;
1059 1081
 		}
1060 1082
 	}
1061 1083
 }
1062 1084
 
1063
-template<int FORMAT, SPUInterpolationMode INTERPOLATE_MODE>
1064
-	inline static void ___SPU_ChanUpdate(const bool actuallyMix, SPU_struct* const SPU, channel_struct* const chan)
1085
+template<int FORMAT, SPUInterpolationMode INTERPOLATE_MODE> static inline void ___SPU_ChanUpdate(bool actuallyMix, SPU_struct *const SPU, channel_struct *const chan)
1065 1086
 {
1066
-	if(!actuallyMix)
1067
-		____SPU_ChanUpdate<FORMAT,INTERPOLATE_MODE,-1>(SPU,chan);
1068
-	else if (chan->pan == 0)
1069
-		____SPU_ChanUpdate<FORMAT,INTERPOLATE_MODE,0>(SPU,chan);
1087
+	if (!actuallyMix)
1088
+		____SPU_ChanUpdate<FORMAT, INTERPOLATE_MODE, -1>(SPU, chan);
1089
+	else if (!chan->pan)
1090
+		____SPU_ChanUpdate<FORMAT, INTERPOLATE_MODE, 0>(SPU, chan);
1070 1091
 	else if (chan->pan == 127)
1071
-		____SPU_ChanUpdate<FORMAT,INTERPOLATE_MODE,2>(SPU,chan);
1092
+		____SPU_ChanUpdate<FORMAT, INTERPOLATE_MODE, 2>(SPU, chan);
1072 1093
 	else
1073
-		____SPU_ChanUpdate<FORMAT,INTERPOLATE_MODE,1>(SPU,chan);
1094
+		____SPU_ChanUpdate<FORMAT, INTERPOLATE_MODE, 1>(SPU, chan);
1074 1095
 }
1075 1096
 
1076
-template<SPUInterpolationMode INTERPOLATE_MODE>
1077
-	inline static void __SPU_ChanUpdate(const bool actuallyMix, SPU_struct* const SPU, channel_struct* const chan)
1097
+template<SPUInterpolationMode INTERPOLATE_MODE> static inline void __SPU_ChanUpdate(bool actuallyMix, SPU_struct *const SPU, channel_struct *const chan)
1078 1098
 {
1079
-	switch(chan->format)
1099
+	switch (chan->format)
1080 1100
 	{
1081
-		case 0: ___SPU_ChanUpdate<0,INTERPOLATE_MODE>(actuallyMix, SPU, chan); break;
1082
-		case 1: ___SPU_ChanUpdate<1,INTERPOLATE_MODE>(actuallyMix, SPU, chan); break;
1083
-		case 2: ___SPU_ChanUpdate<2,INTERPOLATE_MODE>(actuallyMix, SPU, chan); break;
1084
-		case 3: ___SPU_ChanUpdate<3,INTERPOLATE_MODE>(actuallyMix, SPU, chan); break;
1085
-		default: assert(false);
1101
+		case 0:
1102
+			___SPU_ChanUpdate<0, INTERPOLATE_MODE>(actuallyMix, SPU, chan);
1103
+			break;
1104
+		case 1:
1105
+			___SPU_ChanUpdate<1, INTERPOLATE_MODE>(actuallyMix, SPU, chan);
1106
+			break;
1107
+		case 2:
1108
+			___SPU_ChanUpdate<2, INTERPOLATE_MODE>(actuallyMix, SPU, chan);
1109
+			break;
1110
+		case 3:
1111
+			___SPU_ChanUpdate<3, INTERPOLATE_MODE>(actuallyMix, SPU, chan);
1112
+			break;
1113
+		default:
1114
+			assert(false);
1086 1115
 	}
1087 1116
 }
1088 1117
 
1089
-inline static void _SPU_ChanUpdate(const bool actuallyMix, SPU_struct* const SPU, channel_struct* const chan)
1118
+static inline void _SPU_ChanUpdate(bool actuallyMix, SPU_struct *const SPU, channel_struct *const chan)
1090 1119
 {
1091
-	switch(CommonSettings.spuInterpolationMode)
1120
+	switch (CommonSettings.spuInterpolationMode)
1092 1121
 	{
1093
-	case SPUInterpolation_None: __SPU_ChanUpdate<SPUInterpolation_None>(actuallyMix, SPU, chan); break;
1094
-	case SPUInterpolation_Linear: __SPU_ChanUpdate<SPUInterpolation_Linear>(actuallyMix, SPU, chan); break;
1095
-	case SPUInterpolation_Cosine: __SPU_ChanUpdate<SPUInterpolation_Cosine>(actuallyMix, SPU, chan); break;
1096
-	default: assert(false);
1122
+		case SPUInterpolation_None:
1123
+			__SPU_ChanUpdate<SPUInterpolation_None>(actuallyMix, SPU, chan);
1124
+			break;
1125
+		case SPUInterpolation_Linear:
1126
+			__SPU_ChanUpdate<SPUInterpolation_Linear>(actuallyMix, SPU, chan);
1127
+			break;
1128
+		case SPUInterpolation_Cosine:
1129
+			__SPU_ChanUpdate<SPUInterpolation_Cosine>(actuallyMix, SPU, chan);
1130
+			break;
1131
+		default:
1132
+			assert(false);
1097 1133
 	}
1098 1134
 }
1099 1135
 
1100
-//ENTERNEW
1136
+// ENTERNEW
1101 1137
 static void SPU_MixAudio_Advanced(bool, SPU_struct *SPU, int length)
1102 1138
 {
1103
-	//the advanced spu function correctly handles all sound control mixing options, as well as capture
1104
-	//this code is not entirely optimal, as it relies on sort of manhandling the core mixing functions
1105
-	//in order to get the results it needs.
1139
+	// the advanced spu function correctly handles all sound control mixing options, as well as capture
1140
+	// this code is not entirely optimal, as it relies on sort of manhandling the core mixing functions
1141
+	// in order to get the results it needs.
1106 1142
 
1107
-	//THIS IS MAX HACKS!!!!
1108
-	//AND NEEDS TO BE REWRITTEN ALONG WITH THE DEEPEST PARTS OF THE SPU
1109
-	//ONCE WE KNOW THAT IT WORKS
1143
+	// THIS IS MAX HACKS!!!!
1144
+	// AND NEEDS TO BE REWRITTEN ALONG WITH THE DEEPEST PARTS OF THE SPU
1145
+	// ONCE WE KNOW THAT IT WORKS
1110 1146
 
1111
-	//BIAS gets ignored since our spu is still not bit perfect,
1112
-	//and it doesnt matter for purposes of capture
1147
+	// BIAS gets ignored since our spu is still not bit perfect,
1148
+	// and it doesnt matter for purposes of capture
1113 1149
 
1114
-	//-----------DEBUG CODE
1150
+	// -----------DEBUG CODE
1115 1151
 	bool skipcap = false;
1116
-	//-----------------
1152
+	// -----------------
1117 1153
 
1118
-	int32_t samp0[2] = {0,0};
1154
+	int32_t samp0[] = { 0, 0 };
1119 1155
 
1120
-	//believe it or not, we are going to do this one sample at a time.
1121
-	//like i said, it is slower.
1122
-	for(int samp=0;samp<length;samp++)
1156
+	// believe it or not, we are going to do this one sample at a time.
1157
+	// like i said, it is slower.
1158
+	for (int samp = 0; samp < length; ++samp)
1123 1159
 	{
1124
-		SPU->sndbuf[0] = 0;
1125
-		SPU->sndbuf[1] = 0;
1160
+		SPU->sndbuf[0] = SPU->sndbuf[1] = 0;
1126 1161
 		SPU->buflength = 1;
1127 1162
 
1128
-		int32_t capmix[2] = {0,0};
1129
-		int32_t mix[2] = {0,0};
1163
+		int32_t capmix[] = { 0, 0 }, mix[] = { 0, 0 };
1130 1164
 		int32_t chanout[16];
1131 1165
 		int32_t submix[32];
1132 1166
 
1133
-		//generate each channel, and helpfully mix it at the same time
1134
-		for(int i=0;i<16;i++)
1167
+		// generate each channel, and helpfully mix it at the same time
1168
+		for (int i = 0; i < 16; ++i)
1135 1169
 		{
1136 1170
 			channel_struct *chan = &SPU->channels[i];
1137 1171
 
... ...
@@ -1140,201 +1174,216 @@ static void SPU_MixAudio_Advanced(bool, SPU_struct *SPU, int length)
1140 1174
 				SPU->bufpos = 0;
1141 1175
 
1142 1176
 				bool bypass = false;
1143
-				if(i==1 && SPU->regs.ctl_ch1bypass) bypass=true;
1144
-				if(i==3 && SPU->regs.ctl_ch3bypass) bypass=true;
1145
-
1177
+				if (i == 1 && SPU->regs.ctl_ch1bypass)
1178
+					bypass = true;
1179
+				if (i == 3 && SPU->regs.ctl_ch3bypass)
1180
+					bypass = true;
1146 1181
 
1147
-				//output to mixer unless we are bypassed.
1148
-				//dont output to mixer if the user muted us
1182
+				// output to mixer unless we are bypassed.
1183
+				// dont output to mixer if the user muted us
1149 1184
 				bool outputToMix = true;
1150
-				if(CommonSettings.spu_muteChannels[i]) outputToMix = false;
1151
-				if(bypass) outputToMix = false;
1185
+				if (CommonSettings.spu_muteChannels[i])
1186
+					outputToMix = false;
1187
+				if (bypass)
1188
+					outputToMix = false;
1152 1189
 				bool outputToCap = outputToMix;
1153
-				if(CommonSettings.spu_captureMuted && !bypass) outputToCap = true;
1190
+				if (CommonSettings.spu_captureMuted && !bypass)
1191
+					outputToCap = true;
1154 1192
 
1155
-				//channels 1 and 3 should probably always generate their audio
1156
-				//internally at least, just in case they get used by the spu output
1157
-				bool domix = outputToCap || outputToMix || i==1 || i==3;
1193
+				// channels 1 and 3 should probably always generate their audio
1194
+				// internally at least, just in case they get used by the spu output
1195
+				bool domix = outputToCap || outputToMix || i == 1 || i == 3;
1158 1196
 
1159
-				//clear the output buffer since this is where _SPU_ChanUpdate wants to accumulate things
1197
+				// clear the output buffer since this is where _SPU_ChanUpdate wants to accumulate things
1160 1198
 				SPU->sndbuf[0] = SPU->sndbuf[1] = 0;
1161 1199
 
1162
-				//get channel's next output sample.
1200
+				// get channel's next output sample.
1163 1201
 				_SPU_ChanUpdate(domix, SPU, chan);
1164 1202
 				chanout[i] = SPU->lastdata >> chan->datashift;
1165 1203
 
1166
-				//save the panned results
1167
-				submix[i*2] = SPU->sndbuf[0];
1168
-				submix[i*2+1] = SPU->sndbuf[1];
1204
+				// save the panned results
1205
+				submix[i * 2] = SPU->sndbuf[0];
1206
+				submix[i * 2 + 1] = SPU->sndbuf[1];
1169 1207
 
1170
-				//send sample to our capture mix
1171
-				if(outputToCap)
1208
+				// send sample to our capture mix
1209
+				if (outputToCap)
1172 1210
 				{
1173
-					capmix[0] += submix[i*2];
1174
-					capmix[1] += submix[i*2+1];
1211
+					capmix[0] += submix[i * 2];
1212
+					capmix[1] += submix[i * 2 + 1];
1175 1213
 				}
1176 1214
 
1177
-				//send sample to our main mixer
1178
-				if(outputToMix)
1215
+				// send sample to our main mixer
1216
+				if (outputToMix)
1179 1217
 				{
1180
-					mix[0] += submix[i*2];
1181
-					mix[1] += submix[i*2+1];
1218
+					mix[0] += submix[i * 2];
1219
+					mix[1] += submix[i * 2 + 1];
1182 1220
 				}
1183 1221
 			}
1184 1222
 			else
1185
-			{
1186
-				chanout[i] = 0;
1187
-				submix[i*2] = 0;
1188
-				submix[i*2+1] = 0;
1189
-			}
1190
-		} //foreach channel
1223
+				chanout[i] = submix[i * 2] = submix[i * 2 + 1] = 0;
1224
+		} // foreach channel
1191 1225
 
1192
-		int32_t mixout[2] = {mix[0],mix[1]};
1193
-		int32_t capmixout[2] = {capmix[0],capmix[1]};
1194
-		int32_t sndout[2] = {0,0};
1226
+		int32_t mixout[] = { mix[0], mix[1] };
1227
+		int32_t capmixout[] = { capmix[0], capmix[1] };
1228
+		int32_t sndout[] = { 0, 0 };
1195 1229
 		int32_t capout[2];
1196 1230
 
1197
-		//create SPU output
1198
-		switch(SPU->regs.ctl_left)
1231
+		// create SPU output
1232
+		switch (SPU->regs.ctl_left)
1199 1233
 		{
1200
-		case SPU_struct::REGS::LOM_LEFT_MIXER: sndout[0] = mixout[0]; break;
1201
-		case SPU_struct::REGS::LOM_CH1: sndout[0] = submix[1*2+0]; break;
1202
-		case SPU_struct::REGS::LOM_CH3: sndout[0] = submix[3*2+0]; break;
1203
-		case SPU_struct::REGS::LOM_CH1_PLUS_CH3: sndout[0] = submix[1*2+0] + submix[3*2+0]; break;
1234
+			case SPU_struct::REGS::LOM_LEFT_MIXER:
1235
+				sndout[0] = mixout[0];
1236
+				break;
1237
+			case SPU_struct::REGS::LOM_CH1:
1238
+				sndout[0] = submix[2];
1239
+				break;
1240
+			case SPU_struct::REGS::LOM_CH3:
1241
+				sndout[0] = submix[6];
1242
+				break;
1243
+			case SPU_struct::REGS::LOM_CH1_PLUS_CH3:
1244
+				sndout[0] = submix[2] + submix[6];
1204 1245
 		}
1205
-		switch(SPU->regs.ctl_right)
1246
+		switch (SPU->regs.ctl_right)
1206 1247
 		{
1207
-		case SPU_struct::REGS::ROM_RIGHT_MIXER: sndout[1] = mixout[1]; break;
1208
-		case SPU_struct::REGS::ROM_CH1: sndout[1] = submix[1*2+1]; break;
1209
-		case SPU_struct::REGS::ROM_CH3: sndout[1] = submix[3*2+1]; break;
1210
-		case SPU_struct::REGS::ROM_CH1_PLUS_CH3: sndout[1] = submix[1*2+1] + submix[3*2+1]; break;
1248
+			case SPU_struct::REGS::ROM_RIGHT_MIXER:
1249
+				sndout[1] = mixout[1];
1250
+				break;
1251
+			case SPU_struct::REGS::ROM_CH1:
1252
+				sndout[1] = submix[3];
1253
+				break;
1254
+			case SPU_struct::REGS::ROM_CH3:
1255
+				sndout[1] = submix[7];
1256
+				break;
1257
+			case SPU_struct::REGS::ROM_CH1_PLUS_CH3:
1258
+				sndout[1] = submix[3] + submix[7];
1211 1259
 		}
1212 1260
 
1261
+		// generate capture output ("capture bugs" from gbatek are not emulated)
1262
+		if (!SPU->regs.cap[0].source)
1263
+			capout[0] = capmixout[0]; // cap0 = L-mix
1264
+		else if (SPU->regs.cap[0].add)
1265
+			capout[0] = chanout[0] + chanout[1]; // cap0 = ch0+ch1
1266
+		else
1267
+			capout[0] = chanout[0]; // cap0 = ch0
1213 1268
 
1214
-		//generate capture output ("capture bugs" from gbatek are not emulated)
1215
-		if(SPU->regs.cap[0].source==0)
1216
-			capout[0] = capmixout[0]; //cap0 = L-mix
1217
-		else if(SPU->regs.cap[0].add)
1218
-			capout[0] = chanout[0] + chanout[1]; //cap0 = ch0+ch1
1219
-		else capout[0] = chanout[0]; //cap0 = ch0
1220
-
1221
-		if(SPU->regs.cap[1].source==0)
1222
-			capout[1] = capmixout[1]; //cap1 = R-mix
1223
-		else if(SPU->regs.cap[1].add)
1224
-			capout[1] = chanout[2] + chanout[3]; //cap1 = ch2+ch3
1225
-		else capout[1] = chanout[2]; //cap1 = ch2
1269
+		if (!SPU->regs.cap[1].source)
1270
+			capout[1] = capmixout[1]; // cap1 = R-mix
1271
+		else if (SPU->regs.cap[1].add)
1272
+			capout[1] = chanout[2] + chanout[3]; // cap1 = ch2+ch3
1273
+		else
1274
+			capout[1] = chanout[2]; // cap1 = ch2
1226 1275
 
1227
-		capout[0] = MinMax<int32_t>(capout[0],-0x8000,0x7FFF);
1228
-		capout[1] = MinMax<int32_t>(capout[1],-0x8000,0x7FFF);
1276
+		capout[0] = MinMax(capout[0], -0x8000, 0x7FFF);
1277
+		capout[1] = MinMax(capout[1], -0x8000, 0x7FFF);
1229 1278
 
1230
-		//write the output sample where it is supposed to go
1231
-		if(samp==0)
1279
+		// write the output sample where it is supposed to go
1280
+		if (!samp)
1232 1281
 		{
1233 1282
 			samp0[0] = sndout[0];
1234 1283
 			samp0[1] = sndout[1];
1235 1284
 		}
1236 1285
 		else
1237 1286
 		{
1238
-			SPU->sndbuf[samp*2+0] = sndout[0];
1239
-			SPU->sndbuf[samp*2+1] = sndout[1];
1287
+			SPU->sndbuf[samp * 2] = sndout[0];
1288
+			SPU->sndbuf[samp * 2 + 1] = sndout[1];
1240 1289
 		}
1241 1290
 
1242
-		for(int capchan=0;capchan<2;capchan++)
1291
+		for (int capchan = 0; capchan < 2; ++capchan)
1243 1292
 		{
1244
-			if(SPU->regs.cap[capchan].runtime.running)
1293
+			if (SPU->regs.cap[capchan].runtime.running)
1245 1294
 			{
1246
-				SPU_struct::REGS::CAP& cap = SPU->regs.cap[capchan];
1295
+				SPU_struct::REGS::CAP &cap = SPU->regs.cap[capchan];
1247 1296
 				uint32_t last = u32floor(cap.runtime.sampcnt);
1248
-				cap.runtime.sampcnt += SPU->channels[1+2*capchan].sampinc;
1297
+				cap.runtime.sampcnt += SPU->channels[2 * capchan + 1].sampinc;
1249 1298
 				uint32_t curr = u32floor(cap.runtime.sampcnt);
1250
-				for(uint32_t j=last;j<curr;j++)
1299
+				for (uint32_t j = last; j < curr; ++j)
1251 1300
 				{
1252
-					//so, this is a little strange. why go through a fifo?
1253
-					//it seems that some games will set up a reverb effect by capturing
1254
-					//to the nearly same address as playback, but ahead by a couple.
1255
-					//So, playback will always end up being what was captured a couple of samples ago.
1256
-					//This system counts on playback always having read ahead 16 samples.
1257
-					//In that case, playback will end up being what was processed at one entire buffer length ago,
1258
-					//since the 16 samples would have read ahead before they got captured over
1259
-
1260
-					//It's actually the source channels which should have a fifo, but we are
1261
-					//not going to take the hit in speed and complexity. Save it for a future rewrite.
1262
-					//Instead, what we do here is delay the capture by 16 samples to create a similar effect.
1263
-					//Subjectively, it seems to be working.
1264
-
1265
-					//Don't do anything until the fifo is filled, so as to delay it
1266
-					if(cap.runtime.fifo.size<16)
1301
+					// so, this is a little strange. why go through a fifo?
1302
+					// it seems that some games will set up a reverb effect by capturing
1303
+					// to the nearly same address as playback, but ahead by a couple.
1304
+					// So, playback will always end up being what was captured a couple of samples ago.
1305
+					// This system counts on playback always having read ahead 16 samples.
1306
+					// In that case, playback will end up being what was processed at one entire buffer length ago,
1307
+					// since the 16 samples would have read ahead before they got captured over
1308
+
1309
+					// It's actually the source channels which should have a fifo, but we are
1310
+					// not going to take the hit in speed and complexity. Save it for a future rewrite.
1311
+					// Instead, what we do here is delay the capture by 16 samples to create a similar effect.
1312
+					// Subjectively, it seems to be working.
1313
+
1314
+					// Don't do anything until the fifo is filled, so as to delay it
1315
+					if (cap.runtime.fifo.size < 16)
1267 1316
 					{
1268 1317
 						cap.runtime.fifo.enqueue(static_cast<int16_t>(capout[capchan]));
1269 1318
 						continue;
1270 1319
 					}
1271 1320
 
1272
-					//(actually capture sample from fifo instead of most recently generated)
1273
-					uint32_t multiplier;
1321
+					// (actually capture sample from fifo instead of most recently generated)
1274 1322
 					int32_t sample = cap.runtime.fifo.dequeue();
1275 1323
 					cap.runtime.fifo.enqueue(static_cast<int16_t>(capout[capchan]));
1276 1324
 
1277
-					//static FILE* fp = NULL;
1278
-					//if(!fp) fp = fopen("d:\\capout.raw","wb");
1279
-					//fwrite(&sample,2,1,fp);
1280
-
1281
-					if(cap.bits8)
1325
+					uint32_t multiplier;
1326
+					if (cap.bits8)
1282 1327
 					{
1283
-						int8_t sample8 = static_cast<int8_t>(sample>>8);
1284
-						if(skipcap) _MMU_write08<1,MMU_AT_DMA>(cap.runtime.curdad,0);
1285
-						else _MMU_write08<1,MMU_AT_DMA>(cap.runtime.curdad,sample8);
1286
-						cap.runtime.curdad++;
1328
+						int8_t sample8 = static_cast<int8_t>(sample >> 8);
1329
+						if (skipcap)
1330
+							_MMU_write08<1, MMU_AT_DMA>(cap.runtime.curdad, 0);
1331
+						else
1332
+							_MMU_write08<1, MMU_AT_DMA>(cap.runtime.curdad, sample8);
1333
+						++cap.runtime.curdad;
1287 1334
 						multiplier = 4;
1288 1335
 					}
1289 1336
 					else
1290 1337
 					{
1291 1338
 						int16_t sample16 = static_cast<int16_t>(sample);
1292
-						if(skipcap) _MMU_write16<1,MMU_AT_DMA>(cap.runtime.curdad,0);
1293
-						else _MMU_write16<1,MMU_AT_DMA>(cap.runtime.curdad,sample16);
1294
-						cap.runtime.curdad+=2;
1339
+						if (skipcap)
1340
+							_MMU_write16<1, MMU_AT_DMA>(cap.runtime.curdad, 0);
1341
+						else
1342
+							_MMU_write16<1, MMU_AT_DMA>(cap.runtime.curdad, sample16);
1343
+						cap.runtime.curdad += 2;
1295 1344
 						multiplier = 2;
1296 1345
 					}
1297 1346
 
1298
-					if(cap.runtime.curdad>=cap.runtime.maxdad) {
1347
+					if (cap.runtime.curdad >= cap.runtime.maxdad)
1348
+					{
1299 1349
 						cap.runtime.curdad = cap.dad;
1300
-						cap.runtime.sampcnt -= cap.len*multiplier;
1350
+						cap.runtime.sampcnt -= cap.len * multiplier;
1301 1351
 					}
1302
-				} //sampinc loop
1303
-			} //if capchan running
1304
-		} //capchan loop
1305
-	} //main sample loop
1352
+				} // sampinc loop
1353
+			} // if capchan running
1354
+		} // capchan loop
1355
+	} // main sample loop
1306 1356
 
1307 1357
 	SPU->sndbuf[0] = samp0[0];
1308 1358
 	SPU->sndbuf[1] = samp0[1];
1309 1359
 }
1310 1360
 
1311
-//ENTER
1361
+// ENTER
1312 1362
 static void SPU_MixAudio(bool actuallyMix, SPU_struct *SPU, int length)
1313 1363
 {
1314
-	if(actuallyMix)
1364
+	if (actuallyMix)
1315 1365
 	{
1316
-		memset(SPU->sndbuf, 0, length*4*2);
1317
-		memset(SPU->outbuf, 0, length*2*2);
1366
+		memset(&SPU->sndbuf[0], 0, length * 4 * 2);
1367
+		memset(&SPU->outbuf[0], 0, length * 2 * 2);
1318 1368
 	}
1319 1369
 
1320
-	//we used to use master enable here, and do nothing if audio is disabled.
1321
-	//now, master enable is emulated better..
1322
-	//but for a speed optimization we will still do it
1323
-	if(!SPU->regs.masteren) return;
1370
+	// we used to use master enable here, and do nothing if audio is disabled.
1371
+	// now, master enable is emulated better..
1372
+	// but for a speed optimization we will still do it
1373
+	if (!SPU->regs.masteren)
1374
+		return;
1324 1375
 
1325
-	bool advanced = CommonSettings.spu_advanced ;
1376
+	bool advanced = CommonSettings.spu_advanced;
1326 1377
 
1327
-	//branch here so that slow computers don't have to take the advanced (slower) codepath.
1328
-	//it remainds to be seen exactly how much slower it is
1329
-	//if it isnt much slower then we should refactor everything to be simpler, once it is working
1330
-	if(advanced && SPU == SPU_core)
1331
-	{
1378
+	// branch here so that slow computers don't have to take the advanced (slower) codepath.
1379
+	// it remainds to be seen exactly how much slower it is
1380
+	// if it isnt much slower then we should refactor everything to be simpler, once it is working
1381
+	if (advanced && SPU == SPU_core.get())
1332 1382
 		SPU_MixAudio_Advanced(actuallyMix, SPU, length);
1333
-	}
1334 1383
 	else
1335 1384
 	{
1336
-		//non-advanced mode
1337
-		for(int i=0;i<16;i++)
1385
+		// non-advanced mode
1386
+		for (int i = 0; i < 16; ++i)
1338 1387
 		{
1339 1388
 			channel_struct *chan = &SPU->channels[i];
1340 1389
 
... ...
@@ -1349,83 +1398,119 @@ static void SPU_MixAudio(bool actuallyMix, SPU_struct *SPU, int length)
1349 1398
 		}
1350 1399
 	}
1351 1400
 
1352
-	//we used to bail out if speakers were disabled.
1353
-	//this is technically wrong. sound may still be captured, or something.
1354
-	//in all likelihood, any game doing this probably master disabled the SPU also
1355
-	//so, optimization of this case is probably not necessary.
1356
-	//later, we'll just silence the output
1401
+	// we used to bail out if speakers were disabled.
1402
+	// this is technically wrong. sound may still be captured, or something.
1403
+	// in all likelihood, any game doing this probably master disabled the SPU also
1404
+	// so, optimization of this case is probably not necessary.
1405
+	// later, we'll just silence the output
1357 1406
 	bool speakers = T1ReadWord(MMU.ARM7_REG, 0x304) & 0x01;
1358 1407
 
1359 1408
 	uint8_t vol = SPU->regs.mastervol;
1360 1409
 
1361 1410
 	// convert from 32-bit->16-bit
1362
-	if(actuallyMix && speakers)
1363
-		for (int i = 0; i < length*2; i++)
1411
+	if (actuallyMix && speakers)
1412
+		for (int i = 0; i < length * 2; ++i)
1364 1413
 		{
1365 1414
 			// Apply Master Volume
1366 1415
 			SPU->sndbuf[i] = spumuldiv7(SPU->sndbuf[i], vol);
1367
-			int16_t outsample = static_cast<int16_t>(MinMax<int32_t>(SPU->sndbuf[i],-0x8000,0x7FFF));
1416
+			int16_t outsample = static_cast<int16_t>(MinMax(SPU->sndbuf[i], -0x8000, 0x7FFF));
1368 1417
 			SPU->outbuf[i] = outsample;
1369 1418
 		}
1370
-
1371
-
1372 1419
 }
1373 1420
 
1374 1421
 //////////////////////////////////////////////////////////////////////////////
1375 1422
 
1376
-
1377
-//emulates one hline of the cpu core.
1378
-//this will produce a variable number of samples, calculated to keep a 44100hz output
1379
-//in sync with the emulator framerate
1423
+// emulates one hline of the cpu core.
1424
+// this will produce a variable number of samples, calculated to keep a 44100hz output
1425
+// in sync with the emulator framerate
1380 1426
 int spu_core_samples = 0;
1381 1427
 void SPU_Emulate_core()
1382 1428
 {
1429
+	bool needToMix = true;
1430
+
1383 1431
 	samples += samples_per_hline;
1384
-	spu_core_samples = (int)(samples);
1432
+	spu_core_samples = static_cast<int>(samples);
1385 1433
 	samples -= spu_core_samples;
1386 1434
 
1387
-	bool synchronize = (synchmode == ESynchMode_Synchronous);
1388
-	bool mix = /*driver->AVI_IsRecording() || driver->WAV_IsRecording() ||*/ synchronize;
1435
+	// We don't need to mix audio for Dual Synch/Asynch mode since we do this
1436
+	// later in SPU_Emulate_user(). Disable mixing here to speed up processing.
1437
+	// However, recording still needs to mix the audio, so make sure we're also
1438
+	// not recording before we disable mixing.
1439
+	if (synchmode == ESynchMode_DualSynchAsynch)
1440
+		needToMix = false;
1441
+
1442
+	SPU_MixAudio(needToMix, SPU_core.get(), spu_core_samples);
1389 1443
 
1390
-	SPU_MixAudio(mix,SPU_core,spu_core_samples);
1391
-	if(synchronize && SPU_currentCoreNum != SNDCORE_DUMMY)
1392
-		synchronizer->enqueue_samples(SPU_core->outbuf, spu_core_samples);
1444
+	if (!SNDCore)
1445
+		return;
1446
+
1447
+	if (SNDCore->FetchSamples)
1448
+		SNDCore->FetchSamples(&SPU_core->outbuf[0], spu_core_samples, synchmode, synchronizer.get());
1449
+	else
1450
+		SPU_DefaultFetchSamples(&SPU_core->outbuf[0], spu_core_samples, synchmode, synchronizer.get());
1393 1451
 }
1394 1452
 
1395 1453
 void SPU_Emulate_user(bool mix)
1396 1454
 {
1397
-	uint32_t audiosize;
1455
+	static std::vector<int16_t> postProcessBuffer;
1456
+	static size_t postProcessBufferSize = 0;
1457
+	size_t processedSampleCount = 0;
1458
+
1459
+	if (!SNDCore)
1460
+		return;
1461
+
1462
+	// Check to see how many free samples are available.
1463
+	// If there are some, fill up the output buffer.
1464
+	size_t freeSampleCount = SNDCore->GetAudioSpace();
1465
+	if (!freeSampleCount)
1466
+		return;
1398 1467
 
1399
-	// Check to see how much free space there is
1400
-	// If there is some, fill up the buffer
1401
-	if(!SNDCore) return;
1402
-	audiosize = SNDCore->GetAudioSpace();
1468
+	//printf("mix %i samples\n", audiosize);
1469
+	if (freeSampleCount > buffersize)
1470
+		freeSampleCount = buffersize;
1403 1471
 
1404
-	if (audiosize > 0)
1472
+	// If needed, resize the post-process buffer to guarantee that
1473
+	// we can store all the sound data.
1474
+	if (postProcessBufferSize < freeSampleCount * 2 * sizeof(int16_t))
1405 1475
 	{
1406
-		//printf("mix %i samples\n", audiosize);
1407
-		if (audiosize > (uint32_t)buffersize)
1408
-			audiosize = buffersize;
1476
+		postProcessBufferSize = freeSampleCount * 2 * sizeof(int16_t);
1477
+		postProcessBuffer.resize(postProcessBufferSize);
1478
+	}
1409 1479
 
1410
-		int16_t* outbuf;
1411
-		int samplesOutput;
1412
-		if(synchmode == ESynchMode_Synchronous)
1413
-		{
1414
-			static std::vector<int16_t> tempbuf;
1415
-			if(tempbuf.size() < audiosize*2) tempbuf.resize(audiosize*2);
1416
-			outbuf = &tempbuf[0];
1417
-			samplesOutput = synchronizer->output_samples(outbuf, audiosize);
1418
-		}
1419
-		else if(SPU_user)
1420
-		{
1421
-			outbuf = SPU_user->outbuf;
1422
-			samplesOutput = (SPU_MixAudio(mix,SPU_user,audiosize), audiosize);
1423
-		}
1424
-		else return;
1480
+	if (SNDCore->PostProcessSamples)
1481
+		processedSampleCount = SNDCore->PostProcessSamples(&postProcessBuffer[0], freeSampleCount, synchmode, synchronizer.get());
1482
+	else
1483
+		processedSampleCount = SPU_DefaultPostProcessSamples(&postProcessBuffer[0], freeSampleCount, synchmode, synchronizer.get());
1484
+
1485
+	SNDCore->UpdateAudio(&postProcessBuffer[0], processedSampleCount);
1486
+}
1425 1487
 
1426
-		SNDCore->UpdateAudio(outbuf, samplesOutput);
1427
-		//WAV_WavSoundUpdate(SPU_user->outbuf, samplesOutput, WAVMODE_USER);
1488
+void SPU_DefaultFetchSamples(int16_t *sampleBuffer, size_t sampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer)
1489
+{
1490
+	if (synchMode == ESynchMode_Synchronous)
1491
+		theSynchronizer->enqueue_samples(sampleBuffer, sampleCount);
1492
+}
1493
+
1494
+size_t SPU_DefaultPostProcessSamples(int16_t *postProcessBuffer, size_t requestedSampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer)
1495
+{
1496
+	size_t processedSampleCount = 0;
1497
+	
1498
+	switch (synchMode)
1499
+	{
1500
+		case ESynchMode_DualSynchAsynch:
1501
+			if (SPU_user)
1502
+			{
1503
+				SPU_MixAudio(true, SPU_user.get(), requestedSampleCount);
1504
+				memcpy(postProcessBuffer, &SPU_user->outbuf[0], requestedSampleCount * 2 * sizeof(int16_t));
1505
+				processedSampleCount = requestedSampleCount;
1506
+			}
1507
+			break;
1508
+
1509
+		case ESynchMode_Synchronous:
1510
+			processedSampleCount = theSynchronizer->output_samples(postProcessBuffer, requestedSampleCount);
1428 1511
 	}
1512
+	
1513
+	return processedSampleCount;
1429 1514
 }
1430 1515
 
1431 1516
 //////////////////////////////////////////////////////////////////////////////
... ...
@@ -1435,12 +1520,16 @@ void SPU_Emulate_user(bool mix)
1435 1520
 int SNDDummyInit(int) { return 0; }
1436 1521
 void SNDDummyDeInit() {}
1437 1522
 void SNDDummyUpdateAudio(int16_t *, uint32_t) { }
1438
-uint32_t SNDDummyGetAudioSpace() { return DESMUME_SAMPLE_RATE/60 + 5; }
1523
+uint32_t SNDDummyGetAudioSpace() { return DESMUME_SAMPLE_RATE / 60 + 5; }
1439 1524
 void SNDDummyMuteAudio() {}
1440 1525
 void SNDDummyUnMuteAudio() {}
1441 1526
 void SNDDummySetVolume(int) {}
1527
+void SNDDummyClearBuffer() {}
1528
+void SNDDummyFetchSamples(int16_t *sampleBuffer, size_t sampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer) {}
1529
+size_t SNDDummyPostProcessSamples(int16_t *postProcessBuffer, size_t requestedSampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer) { return 0; }
1442 1530
 
1443
-SoundInterface_struct SNDDummy = {
1531
+SoundInterface_struct SNDDummy =
1532
+{
1444 1533
 	SNDCORE_DUMMY,
1445 1534
 	"Dummy Sound Interface",
1446 1535
 	SNDDummyInit,
... ...
@@ -1450,308 +1539,7 @@ SoundInterface_struct SNDDummy = {
1450 1539
 	SNDDummyMuteAudio,
1451 1540
 	SNDDummyUnMuteAudio,
1452 1541
 	SNDDummySetVolume,
1453
-	NULL
1542
+	SNDDummyClearBuffer,
1543
+	SNDDummyFetchSamples,
1544
+	SNDDummyPostProcessSamples
1454 1545
 };
1455
-
1456
-//---------wav writer------------
1457
-
1458
-/*typedef struct {
1459
-	char id[4];
1460
-	uint32_t size;
1461
-} chunk_struct;
1462
-
1463
-typedef struct {
1464
-	chunk_struct riff;
1465
-	char rifftype[4];
1466
-} waveheader_struct;
1467
-
1468
-typedef struct {
1469
-	chunk_struct chunk;
1470
-	uint16_t compress;
1471
-	uint16_t numchan;
1472
-	uint32_t rate;
1473
-	uint32_t bytespersec;
1474
-	uint16_t blockalign;
1475
-	uint16_t bitspersample;
1476
-} fmt_struct;
1477
-
1478
-WavWriter::WavWriter()
1479
-: spufp(NULL)
1480
-{
1481
-}
1482
-bool WavWriter::open(const std::string & fname)
1483
-{
1484
-	waveheader_struct waveheader;
1485
-	fmt_struct fmt;
1486
-	chunk_struct data;
1487
-	size_t elems_written = 0;
1488
-
1489
-	if ((spufp = fopen(fname.c_str(), "wb")) == NULL)
1490
-		return false;
1491
-
1492
-	// Do wave header
1493
-	memcpy(waveheader.riff.id, "RIFF", 4);
1494
-	waveheader.riff.size = 0; // we'll fix this after the file is closed
1495
-	memcpy(waveheader.rifftype, "WAVE", 4);
1496
-	elems_written += fwrite((void *)&waveheader, 1, sizeof(waveheader_struct), spufp);
1497
-
1498
-	// fmt chunk
1499
-	memcpy(fmt.chunk.id, "fmt ", 4);
1500
-	fmt.chunk.size = 16; // we'll fix this at the end
1501
-	fmt.compress = 1; // PCM
1502
-	fmt.numchan = 2; // Stereo
1503
-	fmt.rate = DESMUME_SAMPLE_RATE;
1504
-	fmt.bitspersample = 16;
1505
-	fmt.blockalign = fmt.bitspersample / 8 * fmt.numchan;
1506
-	fmt.bytespersec = fmt.rate * fmt.blockalign;
1507
-	elems_written += fwrite((void *)&fmt, 1, sizeof(fmt_struct), spufp);
1508
-
1509
-	// data chunk
1510
-	memcpy(data.id, "data", 4);
1511
-	data.size = 0; // we'll fix this at the end
1512
-	elems_written += fwrite((void *)&data, 1, sizeof(chunk_struct), spufp);
1513
-
1514
-	return true;
1515
-}
1516
-
1517
-void WavWriter::close()
1518
-{
1519
-	if(!spufp) return;
1520
-	size_t elems_written = 0;
1521
-	long length = ftell(spufp);
1522
-
1523
-	// Let's fix the riff chunk size and the data chunk size
1524
-	fseek(spufp, sizeof(waveheader_struct)-0x8, SEEK_SET);
1525
-	length -= 0x8;
1526
-	elems_written += fwrite((void *)&length, 1, 4, spufp);
1527
-
1528
-	fseek(spufp, sizeof(waveheader_struct)+sizeof(fmt_struct)+0x4, SEEK_SET);
1529
-	length -= sizeof(waveheader_struct)+sizeof(fmt_struct);
1530
-	elems_written += fwrite((void *)&length, 1, 4, spufp);
1531
-	fclose(spufp);
1532
-	spufp = NULL;
1533
-}
1534
-
1535
-void WavWriter::update(void* soundData, int numSamples)
1536
-{
1537
-	if(!spufp) return;
1538
-	//TODO - big endian for the int16_t samples??*/
1539
-	/*size_t elems_written = *//*fwrite(soundData, numSamples*2, 2, spufp);
1540
-}
1541
-
1542
-bool WavWriter::isRecording() const
1543
-{
1544
-	return spufp != NULL;
1545
-}*/
1546
-
1547
-
1548
-//static WavWriter wavWriter;
1549
-
1550
-/*void WAV_End()
1551
-{
1552
-	wavWriter.close();
1553
-}*/
1554
-
1555
-/*bool WAV_Begin(const char* fname, WAVMode mode)
1556
-{
1557
-	WAV_End();
1558
-
1559
-	if(!wavWriter.open(fname))
1560
-		return false;
1561
-
1562
-	if(mode == WAVMODE_ANY)
1563
-		mode = WAVMODE_CORE;
1564
-	wavWriter.mode = mode;
1565
-
1566
-	driver->USR_InfoMessage("WAV recording started.");
1567
-
1568
-	return true;
1569
-}*/
1570
-
1571
-/*bool WAV_IsRecording(WAVMode mode)
1572
-{
1573
-	if(wavWriter.mode == mode || mode == WAVMODE_ANY)
1574
-		return wavWriter.isRecording();
1575
-	return false;
1576
-}*/
1577
-
1578
-/*void WAV_WavSoundUpdate(void* soundData, int numSamples, WAVMode mode)
1579
-{
1580
-	if(wavWriter.mode == mode || mode == WAVMODE_ANY)
1581
-		wavWriter.update(soundData, numSamples);
1582
-}*/
1583
-
1584
-
1585
-
1586
-//////////////////////////////////////////////////////////////////////////////
1587
-
1588
-/*void spu_savestate(EMUFILE* os)
1589
-{
1590
-	//version
1591
-	write32le(6,os);
1592
-
1593
-	SPU_struct *spu = SPU_core;
1594
-
1595
-	for(int j=0;j<16;j++) {
1596
-		channel_struct &chan = spu->channels[j];
1597
-		write32le(chan.num,os);
1598
-		write8le(chan.vol,os);
1599
-		write8le(chan.datashift,os);
1600
-		write8le(chan.hold,os);
1601
-		write8le(chan.pan,os);
1602
-		write8le(chan.waveduty,os);
1603
-		write8le(chan.repeat,os);
1604
-		write8le(chan.format,os);
1605
-		write8le(chan.status,os);
1606
-		write32le(chan.addr,os);
1607
-		write16le(chan.timer,os);
1608
-		write16le(chan.loopstart,os);
1609
-		write32le(chan.length,os);
1610
-		write64le(double_to_u64(chan.sampcnt),os);
1611
-		write64le(double_to_u64(chan.sampinc),os);
1612
-		write32le(chan.lastsampcnt,os);
1613
-		write16le(chan.pcm16b,os);
1614
-		write16le(chan.pcm16b_last,os);
1615
-		write32le(chan.index,os);
1616
-		write16le(chan.x,os);
1617
-		write16le(chan.psgnoise_last,os);
1618
-		write8le(chan.keyon,os);
1619
-	}
1620
-
1621
-	write64le(double_to_u64(samples),os);
1622
-
1623
-	write8le(spu->regs.mastervol,os);
1624
-	write8le(spu->regs.ctl_left,os);
1625
-	write8le(spu->regs.ctl_right,os);
1626
-	write8le(spu->regs.ctl_ch1bypass,os);
1627
-	write8le(spu->regs.ctl_ch3bypass,os);
1628
-	write8le(spu->regs.masteren,os);
1629
-	write16le(spu->regs.soundbias,os);
1630
-
1631
-	for(int i=0;i<2;i++)
1632
-	{
1633
-		write8le(spu->regs.cap[i].add,os);
1634
-		write8le(spu->regs.cap[i].source,os);
1635
-		write8le(spu->regs.cap[i].oneshot,os);
1636
-		write8le(spu->regs.cap[i].bits8,os);
1637
-		write8le(spu->regs.cap[i].active,os);
1638
-		write32le(spu->regs.cap[i].dad,os);
1639
-		write16le(spu->regs.cap[i].len,os);
1640
-		write8le(spu->regs.cap[i].runtime.running,os);
1641
-		write32le(spu->regs.cap[i].runtime.curdad,os);
1642
-		write32le(spu->regs.cap[i].runtime.maxdad,os);
1643
-		write_double_le(spu->regs.cap[i].runtime.sampcnt,os);
1644
-	}
1645
-
1646
-	for(int i=0;i<2;i++)
1647
-		spu->regs.cap[i].runtime.fifo.save(os);
1648
-}*/
1649
-
1650
-bool spu_loadstate(EMUFILE* is, int)
1651
-{
1652
-	uint64_t temp64;
1653
-
1654
-	//read version
1655
-	uint32_t version;
1656
-	if(read32le(&version,is) != 1) return false;
1657
-
1658
-	SPU_struct *spu = SPU_core;
1659
-	reconstruct(&SPU_core->regs);
1660
-
1661
-	for(int j=0;j<16;j++) {
1662
-		channel_struct &chan = spu->channels[j];
1663
-		read32le(&chan.num,is);
1664
-		read8le(&chan.vol,is);
1665
-		read8le(&chan.datashift,is);
1666
-		read8le(&chan.hold,is);
1667
-		read8le(&chan.pan,is);
1668
-		read8le(&chan.waveduty,is);
1669
-		read8le(&chan.repeat,is);
1670
-		read8le(&chan.format,is);
1671
-		read8le(&chan.status,is);
1672
-		read32le(&chan.addr,is);
1673
-		read16le(&chan.timer,is);
1674
-		read16le(&chan.loopstart,is);
1675
-		read32le(&chan.length,is);
1676
-		chan.totlength = chan.length + chan.loopstart;
1677
-		chan.double_totlength_shifted = (double)(chan.totlength << format_shift[chan.format]);
1678
-		//printf("%f\n",chan.double_totlength_shifted);
1679
-		if(version >= 2)
1680
-		{
1681
-			read64le(&temp64,is); chan.sampcnt = u64_to_double(temp64);
1682
-			read64le(&temp64,is); chan.sampinc = u64_to_double(temp64);
1683
-		}
1684
-		else
1685
-		{
1686
-			read32le((uint32_t*)&chan.sampcnt,is);
1687
-			read32le((uint32_t*)&chan.sampinc,is);
1688
-		}
1689
-		read32le(&chan.lastsampcnt,is);
1690
-		read16le(&chan.pcm16b,is);
1691
-		read16le(&chan.pcm16b_last,is);
1692
-		read32le(&chan.index,is);
1693
-		read16le(&chan.x,is);
1694
-		read16le(&chan.psgnoise_last,is);
1695
-
1696
-		if(version>=4)
1697
-			read8le(&chan.keyon,is);
1698
-
1699
-		//hopefully trigger a recovery of the adpcm looping system
1700
-		chan.loop_index = K_ADPCM_LOOPING_RECOVERY_INDEX;
1701
-
1702
-		//fixup the pointers which we had are supposed to keep cached
1703
-		chan.buf8 = (int8_t*)&MMU.MMU_MEM[1][(chan.addr>>20)&0xFF][(chan.addr & MMU.MMU_MASK[1][(chan.addr >> 20) & 0xFF])];
1704
-		chan.buf16 = (int16_t*)chan.buf8;
1705
-	}
1706
-
1707
-	if(version>=2) {
1708
-		read64le(&temp64,is); samples = u64_to_double(temp64);
1709
-	}
1710
-
1711
-	if(version>=4)
1712
-	{
1713
-		read8le(&spu->regs.mastervol,is);
1714
-		read8le(&spu->regs.ctl_left,is);
1715
-		read8le(&spu->regs.ctl_right,is);
1716
-		read8le(&spu->regs.ctl_ch1bypass,is);
1717
-		read8le(&spu->regs.ctl_ch3bypass,is);
1718
-		read8le(&spu->regs.masteren,is);
1719
-		read16le(&spu->regs.soundbias,is);
1720
-	}
1721
-
1722
-	if(version>=5)
1723
-	{
1724
-		for(int i=0;i<2;i++)
1725
-		{
1726
-			read8le(&spu->regs.cap[i].add,is);
1727
-			read8le(&spu->regs.cap[i].source,is);
1728
-			read8le(&spu->regs.cap[i].oneshot,is);
1729
-			read8le(&spu->regs.cap[i].bits8,is);
1730
-			read8le(&spu->regs.cap[i].active,is);
1731
-			read32le(&spu->regs.cap[i].dad,is);
1732
-			read16le(&spu->regs.cap[i].len,is);
1733
-			read8le(&spu->regs.cap[i].runtime.running,is);
1734
-			read32le(&spu->regs.cap[i].runtime.curdad,is);
1735
-			read32le(&spu->regs.cap[i].runtime.maxdad,is);
1736
-			read_double_le(&spu->regs.cap[i].runtime.sampcnt,is);
1737
-		}
1738
-	}
1739
-
1740
-	if(version>=6)
1741
-		for(int i=0;i<2;i++) spu->regs.cap[i].runtime.fifo.load(is);
1742
-	else
1743
-		for(int i=0;i<2;i++) spu->regs.cap[i].runtime.fifo.reset();
1744
-
1745
-	//older versions didnt store a mastervol;
1746
-	//we must reload this or else games will start silent
1747
-	if(version<4)
1748
-	{
1749
-		spu->regs.mastervol = T1ReadByte(MMU.ARM7_REG, 0x500) & 0x7F;
1750
-		spu->regs.masteren = static_cast<uint8_t>(BIT15(T1ReadWord(MMU.ARM7_REG, 0x500)));
1751
-	}
1752
-
1753
-	//copy the core spu (the more accurate) to the user spu
1754
-	SPU_CloneUser();
1755
-
1756
-	return true;
1757
-}
Browse code

Cleanup of some warnings, updating modification dates, using nullptr instead of NULL in some cases.

Naram Qashat authored on 2013/03/30 16:17:42
Showing 1 changed files
... ...
@@ -1041,7 +1041,7 @@ template<int FORMAT, SPUInterpolationMode INTERPOLATE_MODE, int CHANNELS>
1041 1041
 	{
1042 1042
 		if(CHANNELS != -1)
1043 1043
 		{
1044
-			int32_t data;
1044
+			int32_t data = 0;
1045 1045
 			switch(FORMAT)
1046 1046
 			{
1047 1047
 				case 0: Fetch8BitData<INTERPOLATE_MODE>(chan, &data); break;
Browse code

Import actual code.

Naram Qashat authored on 2013/03/26 02:41:19
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,1757 @@
1
+/*
2
+	Copyright (C) 2006 yopyop
3
+	Copyright (C) 2006 Theo Berkau
4
+	Copyright (C) 2008-2012 DeSmuME team
5
+
6
+	Ideas borrowed from Stephane Dallongeville's SCSP core
7
+
8
+	This file is free software: you can redistribute it and/or modify
9
+	it under the terms of the GNU General Public License as published by
10
+	the Free Software Foundation, either version 2 of the License, or
11
+	(at your option) any later version.
12
+
13
+	This file is distributed in the hope that it will be useful,
14
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+	GNU General Public License for more details.
17
+
18
+	You should have received a copy of the GNU General Public License
19
+	along with the this software.  If not, see <http://www.gnu.org/licenses/>.
20
+*/
21
+
22
+#include "XSFCommon.h"
23
+
24
+#include <queue>
25
+#include <vector>
26
+#include <cstdlib>
27
+#include <cstring>
28
+#ifndef M_PI
29
+#define M_PI 3.14159265358979323846
30
+#endif
31
+
32
+//#include "debug.h"
33
+#include "MMU.h"
34
+#include "SPU.h"
35
+#include "mem.h"
36
+#include "readwrite.h"
37
+#include "armcpu.h"
38
+#include "NDSSystem.h"
39
+#include "matrix.h"
40
+
41
+#include "metaspu/metaspu.h"
42
+
43
+static const int K_ADPCM_LOOPING_RECOVERY_INDEX = 99999;
44
+static const int COSINE_INTERPOLATION_RESOLUTION = 8192;
45
+
46
+//static ISynchronizingAudioBuffer* synchronizer = metaspu_construct(ESynchMethod_Z);
47
+static ISynchronizingAudioBuffer* synchronizer = metaspu_construct(ESynchMethod_N);
48
+
49
+SPU_struct *SPU_core = 0;
50
+SPU_struct *SPU_user = 0;
51
+int SPU_currentCoreNum = SNDCORE_DUMMY;
52
+static int volume = 100;
53
+
54
+static int buffersize = 0;
55
+static ESynchMode synchmode = ESynchMode_DualSynchAsynch;
56
+static ESynchMethod synchmethod = ESynchMethod_N;
57
+
58
+static int SNDCoreId=-1;
59
+static SoundInterface_struct *SNDCore=NULL;
60
+extern SoundInterface_struct *SNDCoreList[];
61
+
62
+//const int shift = (FORMAT == 0 ? 2 : 1);
63
+static const int format_shift[] = { 2, 1, 3, 0 };
64
+
65
+static const int8_t indextbl[8] =
66
+{
67
+	-1, -1, -1, -1, 2, 4, 6, 8
68
+};
69
+
70
+static const uint16_t adpcmtbl[89] =
71
+{
72
+	0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x0010,
73
+	0x0011, 0x0013, 0x0015, 0x0017, 0x0019, 0x001C, 0x001F, 0x0022, 0x0025,
74
+	0x0029, 0x002D, 0x0032, 0x0037, 0x003C, 0x0042, 0x0049, 0x0050, 0x0058,
75
+	0x0061, 0x006B, 0x0076, 0x0082, 0x008F, 0x009D, 0x00AD, 0x00BE, 0x00D1,
76
+	0x00E6, 0x00FD, 0x0117, 0x0133, 0x0151, 0x0173, 0x0198, 0x01C1, 0x01EE,
77
+	0x0220, 0x0256, 0x0292, 0x02D4, 0x031C, 0x036C, 0x03C3, 0x0424, 0x048E,
78
+	0x0502, 0x0583, 0x0610, 0x06AB, 0x0756, 0x0812, 0x08E0, 0x09C3, 0x0ABD,
79
+	0x0BD0, 0x0CFF, 0x0E4C, 0x0FBA, 0x114C, 0x1307, 0x14EE, 0x1706, 0x1954,
80
+	0x1BDC, 0x1EA5, 0x21B6, 0x2515, 0x28CA, 0x2CDF, 0x315B, 0x364B, 0x3BB9,
81
+	0x41B2, 0x4844, 0x4F7E, 0x5771, 0x602F, 0x69CE, 0x7462, 0x7FFF
82
+};
83
+
84
+static const int16_t wavedutytbl[8][8] = {
85
+	{ -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, 0x7FFF },
86
+	{ -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, 0x7FFF, 0x7FFF },
87
+	{ -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF },
88
+	{ -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF },
89
+	{ -0x7FFF, -0x7FFF, -0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF },
90
+	{ -0x7FFF, -0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF },
91
+	{ -0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF },
92
+	{ -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF }
93
+};
94
+
95
+static int32_t precalcdifftbl[89][16];
96
+static uint8_t precalcindextbl[89][8];
97
+static double cos_lut[COSINE_INTERPOLATION_RESOLUTION];
98
+
99
+static const double ARM7_CLOCK = 33513982;
100
+
101
+static const double samples_per_hline = (DESMUME_SAMPLE_RATE / 59.8261f) / 263.0f;
102
+
103
+static double samples = 0;
104
+
105
+template<typename T>
106
+static inline T MinMax(T val, T min, T max)
107
+{
108
+	if (val < min)
109
+		return min;
110
+	else if (val > max)
111
+		return max;
112
+
113
+	return val;
114
+}
115
+
116
+//--------------external spu interface---------------
117
+
118
+int SPU_ChangeSoundCore(int coreid, int Buffersize)
119
+{
120
+	int i;
121
+
122
+	buffersize = Buffersize;
123
+
124
+	delete SPU_user; SPU_user = NULL;
125
+
126
+	// Make sure the old core is freed
127
+	if (SNDCore)
128
+		SNDCore->DeInit();
129
+
130
+	// So which core do we want?
131
+	if (coreid == SNDCORE_DEFAULT)
132
+		coreid = 0; // Assume we want the first one
133
+
134
+	SPU_currentCoreNum = coreid;
135
+
136
+	// Go through core list and find the id
137
+	for (i = 0; SNDCoreList[i] != NULL; i++)
138
+	{
139
+		if (SNDCoreList[i]->id == coreid)
140
+		{
141
+			// Set to current core
142
+			SNDCore = SNDCoreList[i];
143
+			break;
144
+		}
145
+	}
146
+
147
+	SNDCoreId = coreid;
148
+
149
+	//If the user picked the dummy core, disable the user spu
150
+	if(SNDCore == &SNDDummy)
151
+		return 0;
152
+
153
+	//If the core wasnt found in the list for some reason, disable the user spu
154
+	if (SNDCore == NULL)
155
+		return -1;
156
+
157
+	// Since it failed, instead of it being fatal, disable the user spu
158
+	if (SNDCore->Init(buffersize * 2) == -1)
159
+	{
160
+		SNDCore = 0;
161
+		return -1;
162
+	}
163
+
164
+	SNDCore->SetVolume(volume);
165
+
166
+	SPU_SetSynchMode(synchmode,synchmethod);
167
+
168
+	return 0;
169
+}
170
+
171
+/*SoundInterface_struct *SPU_SoundCore()
172
+{
173
+	return SNDCore;
174
+}*/
175
+
176
+void SPU_ReInit()
177
+{
178
+	SPU_Init(SNDCoreId, buffersize);
179
+}
180
+
181
+int SPU_Init(int coreid, int Buffersize)
182
+{
183
+	int i, j;
184
+
185
+	// Build the cosine interpolation LUT
186
+	for(i = 0; i < COSINE_INTERPOLATION_RESOLUTION; i++)
187
+		cos_lut[i] = (1.0 - cos(((double)i/(double)COSINE_INTERPOLATION_RESOLUTION) * M_PI)) * 0.5;
188
+
189
+	SPU_core = new SPU_struct((int)ceil(samples_per_hline));
190
+	SPU_Reset();
191
+
192
+	//create adpcm decode accelerator lookups
193
+	for(i = 0; i < 16; i++)
194
+	{
195
+		for(j = 0; j < 89; j++)
196
+		{
197
+			precalcdifftbl[j][i] = (((i & 0x7) * 2 + 1) * adpcmtbl[j] / 8);
198
+			if(i & 0x8) precalcdifftbl[j][i] = -precalcdifftbl[j][i];
199
+		}
200
+	}
201
+	for(i = 0; i < 8; i++)
202
+	{
203
+		for(j = 0; j < 89; j++)
204
+		{
205
+			precalcindextbl[j][i] = MinMax((j + indextbl[i]), 0, 88);
206
+		}
207
+	}
208
+
209
+	return SPU_ChangeSoundCore(coreid, Buffersize);
210
+}
211
+
212
+/*void SPU_Pause(int pause)
213
+{
214
+	if (SNDCore == NULL) return;
215
+
216
+	if(pause)
217
+		SNDCore->MuteAudio();
218
+	else
219
+		SNDCore->UnMuteAudio();
220
+}*/
221
+
222
+void SPU_CloneUser()
223
+{
224
+	if(SPU_user) {
225
+		memcpy(SPU_user->channels,SPU_core->channels,sizeof(SPU_core->channels));
226
+		SPU_user->regs = SPU_core->regs;
227
+	}
228
+}
229
+
230
+void SPU_SetSynchMode(ESynchMode mode, ESynchMethod method)
231
+{
232
+	synchmode = mode;
233
+	if(synchmethod != method)
234
+	{
235
+		synchmethod = method;
236
+		delete synchronizer;
237
+		//grr does this need to be locked? spu might need a lock method
238
+		  // or maybe not, maybe the platform-specific code that calls this function can deal with it.
239
+		synchronizer = metaspu_construct(synchmethod);
240
+	}
241
+
242
+	delete SPU_user;
243
+	SPU_user = NULL;
244
+
245
+	if(synchmode == ESynchMode_DualSynchAsynch)
246
+	{
247
+		SPU_user = new SPU_struct(buffersize);
248
+		SPU_CloneUser();
249
+	}
250
+}
251
+
252
+/*void SPU_ClearOutputBuffer()
253
+{
254
+	if(SNDCore && SNDCore->ClearBuffer)
255
+		SNDCore->ClearBuffer();
256
+}*/
257
+
258
+/*void SPU_SetVolume(int vol)
259
+{
260
+	volume = vol;
261
+	if (SNDCore)
262
+		SNDCore->SetVolume(vol);
263
+}*/
264
+
265
+
266
+void SPU_Reset()
267
+{
268
+	int i;
269
+
270
+	SPU_core->reset();
271
+
272
+	if(SPU_user) {
273
+		if(SNDCore)
274
+		{
275
+			SNDCore->DeInit();
276
+			SNDCore->Init(SPU_user->bufsize*2);
277
+			SNDCore->SetVolume(volume);
278
+		}
279
+		SPU_user->reset();
280
+	}
281
+
282
+	//zero - 09-apr-2010: this concerns me, regarding savestate synch.
283
+	//After 0.9.6, lets experiment with removing it and just properly zapping the spu instead
284
+	// Reset Registers
285
+	for (i = 0x400; i < 0x51D; i++)
286
+		T1WriteByte(MMU.ARM7_REG, i, 0);
287
+
288
+	samples = 0;
289
+}
290
+
291
+//------------------------------------------
292
+
293
+void SPU_struct::reset()
294
+{
295
+	memset(sndbuf,0,bufsize*2*4);
296
+	memset(outbuf,0,bufsize*2*2);
297
+
298
+	memset((void *)channels, 0, sizeof(channel_struct) * 16);
299
+
300
+	reconstruct(&regs);
301
+
302
+	for(int i = 0; i < 16; i++)
303
+	{
304
+		channels[i].num = i;
305
+	}
306
+}
307
+
308
+SPU_struct::SPU_struct(int Buffersize)
309
+	: bufpos(0)
310
+	, buflength(0)
311
+	, sndbuf(0)
312
+	, outbuf(0)
313
+	, bufsize(Buffersize)
314
+{
315
+	sndbuf = new int32_t[Buffersize*2];
316
+	outbuf = new int16_t[Buffersize*2];
317
+	reset();
318
+}
319
+
320
+SPU_struct::~SPU_struct()
321
+{
322
+	if(sndbuf) delete[] sndbuf;
323
+	if(outbuf) delete[] outbuf;
324
+}
325
+
326
+void SPU_DeInit()
327
+{
328
+	if(SNDCore)
329
+		SNDCore->DeInit();
330
+	SNDCore = 0;
331
+
332
+	delete SPU_core; SPU_core=0;
333
+	delete SPU_user; SPU_user=0;
334
+}
335
+
336
+//////////////////////////////////////////////////////////////////////////////
337
+
338
+void SPU_struct::ShutUp()
339
+{
340
+	for(int i=0;i<16;i++)
341
+		 channels[i].status = CHANSTAT_STOPPED;
342
+}
343
+
344
+static inline void adjust_channel_timer(channel_struct *chan)
345
+{
346
+	chan->sampinc = (((double)ARM7_CLOCK) / (DESMUME_SAMPLE_RATE * 2)) / (double)(0x10000 - chan->timer);
347
+}
348
+
349
+void SPU_struct::KeyProbe(int chan_num)
350
+{
351
+	channel_struct &thischan = channels[chan_num];
352
+	if(thischan.status == CHANSTAT_STOPPED)
353
+	{
354
+		if(thischan.keyon && regs.masteren)
355
+			KeyOn(chan_num);
356
+	}
357
+	else if(thischan.status == CHANSTAT_PLAY)
358
+	{
359
+		if(!thischan.keyon || !regs.masteren)
360
+			KeyOff(chan_num);
361
+	}
362
+}
363
+
364
+void SPU_struct::KeyOff(int channel)
365
+{
366
+	//printf("keyoff%d\n",channel);
367
+	channel_struct &thischan = channels[channel];
368
+	thischan.status = CHANSTAT_STOPPED;
369
+}
370
+
371
+void SPU_struct::KeyOn(int channel)
372
+{
373
+	channel_struct &thischan = channels[channel];
374
+	thischan.status = CHANSTAT_PLAY;
375
+
376
+	thischan.totlength = thischan.length + thischan.loopstart;
377
+	adjust_channel_timer(&thischan);
378
+
379
+	//printf("keyon %d totlength:%d\n",channel,thischan.totlength);
380
+
381
+
382
+	//LOG("Channel %d key on: vol = %d, datashift = %d, hold = %d, pan = %d, waveduty = %d, repeat = %d, format = %d, source address = %07X,"
383
+	//		"timer = %04X, loop start = %04X, length = %06X, MMU.ARM7_REG[0x501] = %02X\n", channel, chan->vol, chan->datashift, chan->hold,
384
+	//		chan->pan, chan->waveduty, chan->repeat, chan->format, chan->addr, chan->timer, chan->loopstart, chan->length, T1ReadByte(MMU.ARM7_REG, 0x501));
385
+
386
+	switch(thischan.format)
387
+	{
388
+	case 0: // 8-bit
389
+		thischan.buf8 = (int8_t*)&MMU.MMU_MEM[1][(thischan.addr>>20)&0xFF][(thischan.addr & MMU.MMU_MASK[1][(thischan.addr >> 20) & 0xFF])];
390
+	//	thischan.loopstart = thischan.loopstart << 2;
391
+	//	thischan.length = (thischan.length << 2) + thischan.loopstart;
392
+		thischan.sampcnt = -3;
393
+		break;
394
+	case 1: // 16-bit
395
+		thischan.buf16 = (int16_t *)&MMU.MMU_MEM[1][(thischan.addr>>20)&0xFF][(thischan.addr & MMU.MMU_MASK[1][(thischan.addr >> 20) & 0xFF])];
396
+	//	thischan.loopstart = thischan.loopstart << 1;
397
+	//	thischan.length = (thischan.length << 1) + thischan.loopstart;
398
+		thischan.sampcnt = -3;
399
+		break;
400
+	case 2: // ADPCM
401
+		{
402
+			thischan.buf8 = (int8_t*)&MMU.MMU_MEM[1][(thischan.addr>>20)&0xFF][(thischan.addr & MMU.MMU_MASK[1][(thischan.addr >> 20) & 0xFF])];
403
+			thischan.pcm16b = (int16_t)((thischan.buf8[1] << 8) | thischan.buf8[0]);
404
+			thischan.pcm16b_last = thischan.pcm16b;
405
+			thischan.index = thischan.buf8[2] & 0x7F;
406
+			thischan.lastsampcnt = 7;
407
+			thischan.sampcnt = -3;
408
+			thischan.loop_index = K_ADPCM_LOOPING_RECOVERY_INDEX;
409
+		//	thischan.loopstart = thischan.loopstart << 3;
410
+		//	thischan.length = (thischan.length << 3) + thischan.loopstart;
411
+			break;
412
+		}
413
+	case 3: // PSG
414
+		{
415
+			thischan.sampcnt = -1;
416
+			thischan.x = 0x7FFF;
417
+			break;
418
+		}
419
+	default: break;
420
+	}
421
+
422
+	thischan.double_totlength_shifted = (double)(thischan.totlength << format_shift[thischan.format]);
423
+
424
+	if(thischan.format != 3)
425
+	{
426
+		if(fEqual(thischan.double_totlength_shifted, 0.0))
427
+		{
428
+			printf("INFO: Stopping channel %d due to zero length\n",channel);
429
+			thischan.status = CHANSTAT_STOPPED;
430
+		}
431
+	}
432
+}
433
+
434
+//////////////////////////////////////////////////////////////////////////////
435
+
436
+//#define SETBYTE(which,oldval,newval) oldval = (oldval & (~(0xFF<<(which*8)))) | ((newval)<<(which*8))
437
+template<typename T> static inline void SETBYTE(uint32_t which, T &oldval, uint8_t newval) { oldval = (oldval & (~(0xFF << (which*8)))) | (newval << (which*8)); }
438
+//#define GETBYTE(which,val) ((val>>(which*8))&0xFF)
439
+static inline uint8_t GETBYTE(uint32_t which, uint32_t val) { return (val >> (which * 8)) & 0xFF; }
440
+
441
+uint8_t SPU_ReadByte(uint32_t addr) {
442
+	addr &= 0xFFF;
443
+	return SPU_core->ReadByte(addr);
444
+}
445
+uint16_t SPU_ReadWord(uint32_t addr) {
446
+	addr &= 0xFFF;
447
+	return SPU_core->ReadWord(addr);
448
+}
449
+uint32_t SPU_ReadLong(uint32_t addr) {
450
+	addr &= 0xFFF;
451
+	return SPU_core->ReadLong(addr);
452
+}
453
+
454
+uint16_t SPU_struct::ReadWord(uint32_t addr)
455
+{
456
+	return ReadByte(addr)|(ReadByte(addr+1)<<8);
457
+}
458
+
459
+uint32_t SPU_struct::ReadLong(uint32_t addr)
460
+{
461
+	return ReadByte(addr)|(ReadByte(addr+1)<<8)|(ReadByte(addr+2)<<16)|(ReadByte(addr+3)<<24);
462
+}
463
+
464
+uint8_t SPU_struct::ReadByte(uint32_t addr)
465
+{
466
+	switch(addr)
467
+	{
468
+	//SOUNDCNT
469
+	case 0x500: return regs.mastervol;
470
+	case 0x501:
471
+		return (regs.ctl_left)|(regs.ctl_right<<2)|(regs.ctl_ch1bypass<<4)|(regs.ctl_ch3bypass<<5)|(regs.masteren<<7);
472
+	case 0x502: return 0;
473
+	case 0x503: return 0;
474
+
475
+	//SOUNDBIAS
476
+	case 0x504: return regs.soundbias&0xFF;
477
+	case 0x505: return (regs.soundbias>>8)&0xFF;
478
+	case 0x506: return 0;
479
+	case 0x507: return 0;
480
+
481
+	//SNDCAP0CNT/SNDCAP1CNT
482
+	case 0x508:
483
+	case 0x509: {
484
+		uint32_t which = addr-0x508;
485
+		return regs.cap[which].add
486
+			| (regs.cap[which].source<<1)
487
+			| (regs.cap[which].oneshot<<2)
488
+			| (regs.cap[which].bits8<<3)
489
+			//| (regs.cap[which].active<<7); //? which is right? need test
490
+			| (regs.cap[which].runtime.running<<7);
491
+	}
492
+
493
+	//SNDCAP0DAD
494
+	case 0x510: return GETBYTE(0,regs.cap[0].dad);
495
+	case 0x511: return GETBYTE(1,regs.cap[0].dad);
496
+	case 0x512: return GETBYTE(2,regs.cap[0].dad);
497
+	case 0x513: return GETBYTE(3,regs.cap[0].dad);
498
+
499
+	//SNDCAP0LEN
500
+	case 0x514: return GETBYTE(0,regs.cap[0].len);
501
+	case 0x515: return GETBYTE(1,regs.cap[0].len);
502
+	case 0x516: return 0; //not used
503
+	case 0x517: return 0; //not used
504
+
505
+	//SNDCAP1DAD
506
+	case 0x518: return GETBYTE(0,regs.cap[1].dad);
507
+	case 0x519: return GETBYTE(1,regs.cap[1].dad);
508
+	case 0x51A: return GETBYTE(2,regs.cap[1].dad);
509
+	case 0x51B: return GETBYTE(3,regs.cap[1].dad);
510
+
511
+	//SNDCAP1LEN
512
+	case 0x51C: return GETBYTE(0,regs.cap[1].len);
513
+	case 0x51D: return GETBYTE(1,regs.cap[1].len);
514
+	case 0x51E: return 0; //not used
515
+	case 0x51F: return 0; //not used
516
+
517
+	default: {
518
+		//individual channel regs
519
+
520
+		uint32_t chan_num = (addr >> 4) & 0xF;
521
+		if(chan_num>0xF) return 0;
522
+		channel_struct &thischan=channels[chan_num];
523
+
524
+		switch(addr & 0xF) {
525
+			case 0x0: return thischan.vol;
526
+			case 0x1: {
527
+				uint8_t ret = thischan.datashift;
528
+				if(ret==4) ret=3;
529
+				ret |= thischan.hold<<7;
530
+				return ret;
531
+			}
532
+			case 0x2: return thischan.pan;
533
+			case 0x3: return thischan.waveduty|(thischan.repeat<<3)|(thischan.format<<5)|((thischan.status == CHANSTAT_PLAY)?0x80:0);
534
+			case 0x4: return 0; //return GETBYTE(0,thischan.addr); //not readable
535
+			case 0x5: return 0; //return GETBYTE(1,thischan.addr); //not readable
536
+			case 0x6: return 0; //return GETBYTE(2,thischan.addr); //not readable
537
+			case 0x7: return 0; //return GETBYTE(3,thischan.addr); //not readable
538
+			case 0x8: return GETBYTE(0,thischan.timer);
539
+			case 0x9: return GETBYTE(1,thischan.timer);
540
+			case 0xA: return GETBYTE(0,thischan.loopstart);
541
+			case 0xB: return GETBYTE(1,thischan.loopstart);
542
+			case 0xC: return 0; //return GETBYTE(0,thischan.length); //not readable
543
+			case 0xD: return 0; //return GETBYTE(1,thischan.length); //not readable
544
+			case 0xE: return 0; //return GETBYTE(2,thischan.length); //not readable
545
+			case 0xF: return 0; //return GETBYTE(3,thischan.length); //not readable
546
+			default: return 0; //impossible
547
+		} //switch on individual channel regs
548
+		} //default case
549
+	} //switch on address
550
+}
551
+
552
+SPUFifo::SPUFifo()
553
+{
554
+	reset();
555
+}
556
+
557
+void SPUFifo::reset()
558
+{
559
+	head = tail = size = 0;
560
+}
561
+
562
+void SPUFifo::enqueue(int16_t val)
563
+{
564
+	if(size==16) return;
565
+	buffer[tail] = val;
566
+	tail++;
567
+	tail &= 15;
568
+	size++;
569
+}
570
+
571
+int16_t SPUFifo::dequeue()
572
+{
573
+	if(size==0) return 0;
574
+	head++;
575
+	head &= 15;
576
+	int16_t ret = buffer[head];
577
+	size--;
578
+	return ret;
579
+}
580
+
581
+/*void SPUFifo::save(EMUFILE* fp)
582
+{
583
+	uint32_t version = 1;
584
+	write32le(version,fp);
585
+	write32le(head,fp);
586
+	write32le(tail,fp);
587
+	write32le(size,fp);
588
+	for(int i=0;i<16;i++)
589
+		write16le(buffer[i],fp);
590
+}*/
591
+
592
+bool SPUFifo::load(EMUFILE* fp)
593
+{
594
+	uint32_t version;
595
+	if(read32le(&version,fp) != 1) return false;
596
+	read32le(&head,fp);
597
+	read32le(&tail,fp);
598
+	read32le(&size,fp);
599
+	for(int i=0;i<16;i++)
600
+		read16le(&buffer[i],fp);
601
+	return true;
602
+}
603
+
604
+void SPU_struct::ProbeCapture(int which)
605
+{
606
+	//VERY UNTESTED -- HOW MUCH OF THIS RESETS, AND WHEN?
607
+
608
+	if(!regs.cap[which].active)
609
+	{
610
+		regs.cap[which].runtime.running = 0;
611
+		return;
612
+	}
613
+
614
+	REGS::CAP &cap = regs.cap[which];
615
+	cap.runtime.running = 1;
616
+	cap.runtime.curdad = cap.dad;
617
+	uint32_t len = cap.len;
618
+	if(len==0) len=1;
619
+	cap.runtime.maxdad = cap.dad + len*4;
620
+	cap.runtime.sampcnt = 0;
621
+	cap.runtime.fifo.reset();
622
+}
623
+
624
+void SPU_struct::WriteByte(uint32_t addr, uint8_t val)
625
+{
626
+	switch(addr)
627
+	{
628
+	//SOUNDCNT
629
+	case 0x500:
630
+		regs.mastervol = val&0x7F;
631
+		break;
632
+	case 0x501:
633
+		regs.ctl_left  = (val>>0)&3;
634
+		regs.ctl_right = (val>>2)&3;
635
+		regs.ctl_ch1bypass = (val>>4)&1;
636
+		regs.ctl_ch3bypass = (val>>5)&1;
637
+		regs.masteren = (val>>7)&1;
638
+		for(int i=0;i<16;i++)
639
+			KeyProbe(i);
640
+		break;
641
+	case 0x502: break; //not used
642
+	case 0x503: break; //not used
643
+
644
+	//SOUNDBIAS
645
+	case 0x504: SETBYTE(0,regs.soundbias, val); break;
646
+	case 0x505: SETBYTE(1,regs.soundbias, val&3); break;
647
+	case 0x506: break; //these dont answer anyway
648
+	case 0x507: break; //these dont answer anyway
649
+
650
+	//SNDCAP0CNT/SNDCAP1CNT
651
+	case 0x508:
652
+	case 0x509: {
653
+		uint32_t which = addr-0x508;
654
+		regs.cap[which].add = static_cast<uint8_t>(BIT0(val));
655
+		regs.cap[which].source = static_cast<uint8_t>(BIT1(val));
656
+		regs.cap[which].oneshot = static_cast<uint8_t>(BIT2(val));
657
+		regs.cap[which].bits8 = static_cast<uint8_t>(BIT3(val));
658
+		regs.cap[which].active = static_cast<uint8_t>(BIT7(val));
659
+		ProbeCapture(which);
660
+		break;
661
+	}
662
+
663
+	//SNDCAP0DAD
664
+	case 0x510: SETBYTE(0,regs.cap[0].dad,val); break;
665
+	case 0x511: SETBYTE(1,regs.cap[0].dad,val); break;
666
+	case 0x512: SETBYTE(2,regs.cap[0].dad,val); break;
667
+	case 0x513: SETBYTE(3,regs.cap[0].dad,val&7); break;
668
+
669
+	//SNDCAP0LEN
670
+	case 0x514: SETBYTE(0,regs.cap[0].len,val); break;
671
+	case 0x515: SETBYTE(1,regs.cap[0].len,val); break;
672
+	case 0x516: break; //not used
673
+	case 0x517: break; //not used
674
+
675
+	//SNDCAP1DAD
676
+	case 0x518: SETBYTE(0,regs.cap[1].dad,val); break;
677
+	case 0x519: SETBYTE(1,regs.cap[1].dad,val); break;
678
+	case 0x51A: SETBYTE(2,regs.cap[1].dad,val); break;
679
+	case 0x51B: SETBYTE(3,regs.cap[1].dad,val&7); break;
680
+
681
+	//SNDCAP1LEN
682
+	case 0x51C: SETBYTE(0,regs.cap[1].len,val); break;
683
+	case 0x51D: SETBYTE(1,regs.cap[1].len,val); break;
684
+	case 0x51E: break; //not used
685
+	case 0x51F: break; //not used
686
+
687
+
688
+
689
+	default: {
690
+		//individual channel regs
691
+
692
+		uint32_t chan_num = (addr >> 4) & 0xF;
693
+		if(chan_num>0xF) break;
694
+		channel_struct &thischan=channels[chan_num];
695
+
696
+		switch(addr & 0xF) {
697
+			case 0x0:
698
+				thischan.vol = val & 0x7F;
699
+				break;
700
+			case 0x1:
701
+				thischan.datashift = val & 0x3;
702
+				if (thischan.datashift == 3)
703
+					thischan.datashift = 4;
704
+				thischan.hold = (val >> 7) & 0x1;
705
+				break;
706
+			case 0x2:
707
+				thischan.pan = val & 0x7F;
708
+				break;
709
+			case 0x3:
710
+				thischan.waveduty = val & 0x7;
711
+				thischan.repeat = (val >> 3) & 0x3;
712
+				thischan.format = (val >> 5) & 0x3;
713
+				thischan.keyon = static_cast<uint8_t>(BIT7(val));
714
+				KeyProbe(chan_num);
715
+				break;
716
+			case 0x4: SETBYTE(0,thischan.addr,val); break;
717
+			case 0x5: SETBYTE(1,thischan.addr,val); break;
718
+			case 0x6: SETBYTE(2,thischan.addr,val); break;
719
+			case 0x7: SETBYTE(3,thischan.addr,val&0x7); break; //only 27 bits of this register are used
720
+			case 0x8:
721
+				SETBYTE(0,thischan.timer,val);
722
+				adjust_channel_timer(&thischan);
723
+				break;
724
+			case 0x9:
725
+				SETBYTE(1,thischan.timer,val);
726
+				adjust_channel_timer(&thischan);
727
+				break;
728
+			case 0xA: SETBYTE(0,thischan.loopstart,val); break;
729
+			case 0xB: SETBYTE(1,thischan.loopstart,val); break;
730
+			case 0xC: SETBYTE(0,thischan.length,val); break;
731
+			case 0xD: SETBYTE(1,thischan.length,val); break;
732
+			case 0xE: SETBYTE(2,thischan.length,val & 0x3F); break; //only 22 bits of this register are used
733
+			case 0xF: SETBYTE(3,thischan.length,0); break;
734
+		} //switch on individual channel regs
735
+		} //default case
736
+	} //switch on address
737
+}
738
+
739
+void SPU_WriteByte(uint32_t addr, uint8_t val)
740
+{
741
+	//printf("%08X: chan:%02X reg:%02X val:%02X\n",addr,(addr>>4)&0xF,addr&0xF,val);
742
+	addr &= 0xFFF;
743
+
744
+	SPU_core->WriteByte(addr,val);
745
+	if(SPU_user) SPU_user->WriteByte(addr,val);
746
+}
747
+
748
+//////////////////////////////////////////////////////////////////////////////
749
+
750
+void SPU_struct::WriteWord(uint32_t addr, uint16_t val)
751
+{
752
+	WriteByte(addr,val&0xFF);
753
+	WriteByte(addr+1,(val>>8)&0xFF);
754
+}
755
+
756
+void SPU_WriteWord(uint32_t addr, uint16_t val)
757
+{
758
+	//printf("%08X: chan:%02X reg:%02X val:%04X\n",addr,(addr>>4)&0xF,addr&0xF,val);
759
+	addr &= 0xFFF;
760
+
761
+	SPU_core->WriteWord(addr,val);
762
+	if(SPU_user) SPU_user->WriteWord(addr,val);
763
+}
764
+
765
+//////////////////////////////////////////////////////////////////////////////
766
+
767
+void SPU_struct::WriteLong(uint32_t addr, uint32_t val)
768
+{
769
+	WriteByte(addr,val&0xFF);
770
+	WriteByte(addr+1,(val>>8)&0xFF);
771
+	WriteByte(addr+2,(val>>16)&0xFF);
772
+	WriteByte(addr+3,(val>>24)&0xFF);
773
+}
774
+
775
+void SPU_WriteLong(uint32_t addr, uint32_t val)
776
+{
777
+	//printf("%08X: chan:%02X reg:%02X val:%08X\n",addr,(addr>>4)&0xF,addr&0xF,val);
778
+	addr &= 0xFFF;
779
+
780
+	SPU_core->WriteLong(addr,val);
781
+	if(SPU_user) SPU_user->WriteLong(addr,val);
782
+}
783
+
784
+//////////////////////////////////////////////////////////////////////////////
785
+
786
+template<SPUInterpolationMode INTERPOLATE_MODE> static inline int32_t Interpolate(int32_t a, int32_t b, double ratio)
787
+{
788
+	double sampleA = (double)a;
789
+	double sampleB = (double)b;
790
+	ratio = ratio - u32floor(ratio);
791
+
792
+	switch (INTERPOLATE_MODE)
793
+	{
794
+		case SPUInterpolation_Cosine:
795
+			// Cosine Interpolation Formula:
796
+			// ratio2 = (1 - cos(ratio * M_PI)) / 2
797
+			// sampleI = sampleA * (1 - ratio2) + sampleB * ratio2
798
+			return s32floor((cos_lut[(unsigned int)(ratio * (double)COSINE_INTERPOLATION_RESOLUTION)] * (sampleB - sampleA)) + sampleA);
799
+			break;
800
+
801
+		case SPUInterpolation_Linear:
802
+			// Linear Interpolation Formula:
803
+			// sampleI = sampleA * (1 - ratio) + sampleB * ratio
804
+			return s32floor((ratio * (sampleB - sampleA)) + sampleA);
805
+			break;
806
+
807
+		default:
808
+			break;
809
+	}
810
+
811
+	return a;
812
+}
813
+
814
+//////////////////////////////////////////////////////////////////////////////
815
+
816
+template<SPUInterpolationMode INTERPOLATE_MODE> static inline void Fetch8BitData(channel_struct *chan, int32_t *data)
817
+{
818
+	if (chan->sampcnt < 0)
819
+	{
820
+		*data = 0;
821
+		return;
822
+	}
823
+
824
+	uint32_t loc = u32floor(chan->sampcnt);
825
+	if(INTERPOLATE_MODE != SPUInterpolation_None)
826
+	{
827
+		int32_t a = (int32_t)(chan->buf8[loc] << 8);
828
+		if(loc < (chan->totlength << 2) - 1) {
829
+			int32_t b = (int32_t)(chan->buf8[loc + 1] << 8);
830
+			a = Interpolate<INTERPOLATE_MODE>(a, b, chan->sampcnt);
831
+		}
832
+		*data = a;
833
+	}
834
+	else
835
+		*data = (int32_t)chan->buf8[loc] << 8;
836
+}
837
+
838
+template<SPUInterpolationMode INTERPOLATE_MODE> static inline void Fetch16BitData(const channel_struct * const chan, int32_t *data)
839
+{
840
+	if (chan->sampcnt < 0)
841
+	{
842
+		*data = 0;
843
+		return;
844
+	}
845
+
846
+	if(INTERPOLATE_MODE != SPUInterpolation_None)
847
+	{
848
+		uint32_t loc = u32floor(chan->sampcnt);
849
+		int32_t a = (int32_t)chan->buf16[loc], b;
850
+		if(loc < (chan->totlength << 1) - 1)
851
+		{
852
+			b = (int32_t)chan->buf16[loc + 1];
853
+			a = Interpolate<INTERPOLATE_MODE>(a, b, chan->sampcnt);
854
+		}
855
+		*data = a;
856
+	}
857
+	else
858
+		*data = (int32_t)chan->buf16[u32floor(chan->sampcnt)];
859
+}
860
+
861
+template<SPUInterpolationMode INTERPOLATE_MODE> static inline void FetchADPCMData(channel_struct * const chan, int32_t * const data)
862
+{
863
+	if (chan->sampcnt < 8)
864
+	{
865
+		*data = 0;
866
+		return;
867
+	}
868
+
869
+	// No sense decoding, just return the last sample
870
+	if (chan->lastsampcnt != u32floor(chan->sampcnt)){
871
+
872
+	    const uint32_t endExclusive = u32floor(chan->sampcnt+1);
873
+	    for (uint32_t i = chan->lastsampcnt+1; i < endExclusive; i++)
874
+	    {
875
+	    	const uint32_t shift = (i&1)<<2;
876
+	    	const uint32_t data4bit = (((uint32_t)chan->buf8[i >> 1]) >> shift);
877
+
878
+	    	const int32_t diff = precalcdifftbl[chan->index][data4bit & 0xF];
879
+	    	chan->index = precalcindextbl[chan->index][data4bit & 0x7];
880
+
881
+	    	chan->pcm16b_last = chan->pcm16b;
882
+	    	chan->pcm16b = static_cast<int16_t>(MinMax<int32_t>(chan->pcm16b+diff, -0x8000, 0x7FFF));
883
+
884
+			if(i == static_cast<uint32_t>(chan->loopstart<<3)) {
885
+				if(chan->loop_index != K_ADPCM_LOOPING_RECOVERY_INDEX) printf("over-snagging\n");
886
+				chan->loop_pcm16b = chan->pcm16b;
887
+				chan->loop_index = chan->index;
888
+			}
889
+	    }
890
+
891
+	    chan->lastsampcnt = u32floor(chan->sampcnt);
892
+    }
893
+
894
+	if(INTERPOLATE_MODE != SPUInterpolation_None)
895
+		*data = Interpolate<INTERPOLATE_MODE>((int32_t)chan->pcm16b_last,(int32_t)chan->pcm16b,chan->sampcnt);
896
+	else
897
+		*data = (int32_t)chan->pcm16b;
898
+}
899
+
900
+static inline void FetchPSGData(channel_struct *chan, int32_t *data)
901
+{
902
+	if (chan->sampcnt < 0)
903
+	{
904
+		*data = 0;
905
+		return;
906
+	}
907
+
908
+	if(chan->num < 8)
909
+	{
910
+		*data = 0;
911
+	}
912
+	else if(chan->num < 14)
913
+	{
914
+		*data = (int32_t)wavedutytbl[chan->waveduty][(u32floor(chan->sampcnt)) & 0x7];
915
+	}
916
+	else
917
+	{
918
+		if(chan->lastsampcnt == u32floor(chan->sampcnt))
919
+		{
920
+			*data = (int32_t)chan->psgnoise_last;
921
+			return;
922
+		}
923
+
924
+		uint32_t max = u32floor(chan->sampcnt);
925
+		for(uint32_t i = chan->lastsampcnt; i < max; i++)
926
+		{
927
+			if(chan->x & 0x1)
928
+			{
929
+				chan->x = (chan->x >> 1) ^ 0x6000;
930
+				chan->psgnoise_last = -0x7FFF;
931
+			}
932
+			else
933
+			{
934
+				chan->x >>= 1;
935
+				chan->psgnoise_last = 0x7FFF;
936
+			}
937
+		}
938
+
939
+		chan->lastsampcnt = u32floor(chan->sampcnt);
940
+
941
+		*data = (int32_t)chan->psgnoise_last;
942
+	}
943
+}
944
+
945
+//////////////////////////////////////////////////////////////////////////////
946
+
947
+static inline void MixL(SPU_struct* SPU, channel_struct *chan, int32_t data)
948
+{
949
+	data = spumuldiv7(data, chan->vol) >> chan->datashift;
950
+	SPU->sndbuf[SPU->bufpos<<1] += data;
951
+}
952
+
953
+static inline void MixR(SPU_struct* SPU, channel_struct *chan, int32_t data)
954
+{
955
+	data = spumuldiv7(data, chan->vol) >> chan->datashift;
956
+	SPU->sndbuf[(SPU->bufpos<<1)+1] += data;
957
+}
958
+
959
+static inline void MixLR(SPU_struct* SPU, channel_struct *chan, int32_t data)
960
+{
961
+	data = spumuldiv7(data, chan->vol) >> chan->datashift;
962
+	SPU->sndbuf[SPU->bufpos<<1] += spumuldiv7(data, 127 - chan->pan);
963
+	SPU->sndbuf[(SPU->bufpos<<1)+1] += spumuldiv7(data, chan->pan);
964
+}
965
+
966
+//////////////////////////////////////////////////////////////////////////////
967
+
968
+template<int FORMAT> static inline void TestForLoop(SPU_struct *SPU, channel_struct *chan)
969
+{
970
+	const int shift = (FORMAT == 0 ? 2 : 1);
971
+
972
+	chan->sampcnt += chan->sampinc;
973
+
974
+	if (chan->sampcnt > chan->double_totlength_shifted)
975
+	{
976
+		// Do we loop? Or are we done?
977
+		if (chan->repeat == 1)
978
+		{
979
+			while (chan->sampcnt > chan->double_totlength_shifted)
980
+				chan->sampcnt -= chan->double_totlength_shifted - (double)(chan->loopstart << shift);
981
+			//chan->sampcnt = (double)(chan->loopstart << shift);
982
+		}
983
+		else
984
+		{
985
+			SPU->KeyOff(chan->num);
986
+			SPU->bufpos = SPU->buflength;
987
+		}
988
+	}
989
+}
990
+
991
+static inline void TestForLoop2(SPU_struct *SPU, channel_struct *chan)
992
+{
993
+	chan->sampcnt += chan->sampinc;
994
+
995
+	if (chan->sampcnt > chan->double_totlength_shifted)
996
+	{
997
+		// Do we loop? Or are we done?
998
+		if (chan->repeat == 1)
999
+		{
1000
+			while (chan->sampcnt > chan->double_totlength_shifted)
1001
+				chan->sampcnt -= chan->double_totlength_shifted - (double)(chan->loopstart << 3);
1002
+
1003
+			if(chan->loop_index == K_ADPCM_LOOPING_RECOVERY_INDEX)
1004
+			{
1005
+				chan->pcm16b = (int16_t)((chan->buf8[1] << 8) | chan->buf8[0]);
1006
+				chan->index = chan->buf8[2] & 0x7F;
1007
+				chan->lastsampcnt = 7;
1008
+			}
1009
+			else
1010
+			{
1011
+				chan->pcm16b = chan->loop_pcm16b;
1012
+				chan->index = chan->loop_index;
1013
+				chan->lastsampcnt = (chan->loopstart << 3);
1014
+			}
1015
+		}
1016
+		else
1017
+		{
1018
+			chan->status = CHANSTAT_STOPPED;
1019
+			SPU->KeyOff(chan->num);
1020
+			SPU->bufpos = SPU->buflength;
1021
+		}
1022
+	}
1023
+}
1024
+
1025
+template<int CHANNELS> inline static void SPU_Mix(SPU_struct* SPU, channel_struct *chan, int32_t data)
1026
+{
1027
+	switch(CHANNELS)
1028
+	{
1029
+		case 0: MixL(SPU, chan, data); break;
1030
+		case 1: MixLR(SPU, chan, data); break;
1031
+		case 2: MixR(SPU, chan, data); break;
1032
+	}
1033
+	SPU->lastdata = data;
1034
+}
1035
+
1036
+//WORK
1037
+template<int FORMAT, SPUInterpolationMode INTERPOLATE_MODE, int CHANNELS>
1038
+	inline static void ____SPU_ChanUpdate(SPU_struct* const SPU, channel_struct* const chan)
1039
+{
1040
+	for (; SPU->bufpos < SPU->buflength; SPU->bufpos++)
1041
+	{
1042
+		if(CHANNELS != -1)
1043
+		{
1044
+			int32_t data;
1045
+			switch(FORMAT)
1046
+			{
1047
+				case 0: Fetch8BitData<INTERPOLATE_MODE>(chan, &data); break;
1048
+				case 1: Fetch16BitData<INTERPOLATE_MODE>(chan, &data); break;
1049
+				case 2: FetchADPCMData<INTERPOLATE_MODE>(chan, &data); break;
1050
+				case 3: FetchPSGData(chan, &data); break;
1051
+			}
1052
+			SPU_Mix<CHANNELS>(SPU, chan, data);
1053
+		}
1054
+
1055
+		switch(FORMAT) {
1056
+			case 0: case 1: TestForLoop<FORMAT>(SPU, chan); break;
1057
+			case 2: TestForLoop2(SPU, chan); break;
1058
+			case 3: chan->sampcnt += chan->sampinc; break;
1059
+		}
1060
+	}
1061
+}
1062
+
1063
+template<int FORMAT, SPUInterpolationMode INTERPOLATE_MODE>
1064
+	inline static void ___SPU_ChanUpdate(const bool actuallyMix, SPU_struct* const SPU, channel_struct* const chan)
1065
+{
1066
+	if(!actuallyMix)
1067
+		____SPU_ChanUpdate<FORMAT,INTERPOLATE_MODE,-1>(SPU,chan);
1068
+	else if (chan->pan == 0)
1069
+		____SPU_ChanUpdate<FORMAT,INTERPOLATE_MODE,0>(SPU,chan);
1070
+	else if (chan->pan == 127)
1071
+		____SPU_ChanUpdate<FORMAT,INTERPOLATE_MODE,2>(SPU,chan);
1072
+	else
1073
+		____SPU_ChanUpdate<FORMAT,INTERPOLATE_MODE,1>(SPU,chan);
1074
+}
1075
+
1076
+template<SPUInterpolationMode INTERPOLATE_MODE>
1077
+	inline static void __SPU_ChanUpdate(const bool actuallyMix, SPU_struct* const SPU, channel_struct* const chan)
1078
+{
1079
+	switch(chan->format)
1080
+	{
1081
+		case 0: ___SPU_ChanUpdate<0,INTERPOLATE_MODE>(actuallyMix, SPU, chan); break;
1082
+		case 1: ___SPU_ChanUpdate<1,INTERPOLATE_MODE>(actuallyMix, SPU, chan); break;
1083
+		case 2: ___SPU_ChanUpdate<2,INTERPOLATE_MODE>(actuallyMix, SPU, chan); break;
1084
+		case 3: ___SPU_ChanUpdate<3,INTERPOLATE_MODE>(actuallyMix, SPU, chan); break;
1085
+		default: assert(false);
1086
+	}
1087
+}
1088
+
1089
+inline static void _SPU_ChanUpdate(const bool actuallyMix, SPU_struct* const SPU, channel_struct* const chan)
1090
+{
1091
+	switch(CommonSettings.spuInterpolationMode)
1092
+	{
1093
+	case SPUInterpolation_None: __SPU_ChanUpdate<SPUInterpolation_None>(actuallyMix, SPU, chan); break;
1094
+	case SPUInterpolation_Linear: __SPU_ChanUpdate<SPUInterpolation_Linear>(actuallyMix, SPU, chan); break;
1095
+	case SPUInterpolation_Cosine: __SPU_ChanUpdate<SPUInterpolation_Cosine>(actuallyMix, SPU, chan); break;
1096
+	default: assert(false);
1097
+	}
1098
+}
1099
+
1100
+//ENTERNEW
1101
+static void SPU_MixAudio_Advanced(bool, SPU_struct *SPU, int length)
1102
+{
1103
+	//the advanced spu function correctly handles all sound control mixing options, as well as capture
1104
+	//this code is not entirely optimal, as it relies on sort of manhandling the core mixing functions
1105
+	//in order to get the results it needs.
1106
+
1107
+	//THIS IS MAX HACKS!!!!
1108
+	//AND NEEDS TO BE REWRITTEN ALONG WITH THE DEEPEST PARTS OF THE SPU
1109
+	//ONCE WE KNOW THAT IT WORKS
1110
+
1111
+	//BIAS gets ignored since our spu is still not bit perfect,
1112
+	//and it doesnt matter for purposes of capture
1113
+
1114
+	//-----------DEBUG CODE
1115
+	bool skipcap = false;
1116
+	//-----------------
1117
+
1118
+	int32_t samp0[2] = {0,0};
1119
+
1120
+	//believe it or not, we are going to do this one sample at a time.
1121
+	//like i said, it is slower.
1122
+	for(int samp=0;samp<length;samp++)
1123
+	{
1124
+		SPU->sndbuf[0] = 0;
1125
+		SPU->sndbuf[1] = 0;
1126
+		SPU->buflength = 1;
1127
+
1128
+		int32_t capmix[2] = {0,0};
1129
+		int32_t mix[2] = {0,0};
1130
+		int32_t chanout[16];
1131
+		int32_t submix[32];
1132
+
1133
+		//generate each channel, and helpfully mix it at the same time
1134
+		for(int i=0;i<16;i++)
1135
+		{
1136
+			channel_struct *chan = &SPU->channels[i];
1137
+
1138
+			if (chan->status == CHANSTAT_PLAY)
1139
+			{
1140
+				SPU->bufpos = 0;
1141
+
1142
+				bool bypass = false;
1143
+				if(i==1 && SPU->regs.ctl_ch1bypass) bypass=true;
1144
+				if(i==3 && SPU->regs.ctl_ch3bypass) bypass=true;
1145
+
1146
+
1147
+				//output to mixer unless we are bypassed.
1148
+				//dont output to mixer if the user muted us
1149
+				bool outputToMix = true;
1150
+				if(CommonSettings.spu_muteChannels[i]) outputToMix = false;
1151
+				if(bypass) outputToMix = false;
1152
+				bool outputToCap = outputToMix;
1153
+				if(CommonSettings.spu_captureMuted && !bypass) outputToCap = true;
1154
+
1155
+				//channels 1 and 3 should probably always generate their audio
1156
+				//internally at least, just in case they get used by the spu output
1157
+				bool domix = outputToCap || outputToMix || i==1 || i==3;
1158
+
1159
+				//clear the output buffer since this is where _SPU_ChanUpdate wants to accumulate things
1160
+				SPU->sndbuf[0] = SPU->sndbuf[1] = 0;
1161
+
1162
+				//get channel's next output sample.
1163
+				_SPU_ChanUpdate(domix, SPU, chan);
1164
+				chanout[i] = SPU->lastdata >> chan->datashift;
1165
+
1166
+				//save the panned results
1167
+				submix[i*2] = SPU->sndbuf[0];
1168
+				submix[i*2+1] = SPU->sndbuf[1];
1169
+
1170
+				//send sample to our capture mix
1171
+				if(outputToCap)
1172
+				{
1173
+					capmix[0] += submix[i*2];
1174
+					capmix[1] += submix[i*2+1];
1175
+				}
1176
+
1177
+				//send sample to our main mixer
1178
+				if(outputToMix)
1179
+				{
1180
+					mix[0] += submix[i*2];
1181
+					mix[1] += submix[i*2+1];
1182
+				}
1183
+			}
1184
+			else
1185
+			{
1186
+				chanout[i] = 0;
1187
+				submix[i*2] = 0;
1188
+				submix[i*2+1] = 0;
1189
+			}
1190
+		} //foreach channel
1191
+
1192
+		int32_t mixout[2] = {mix[0],mix[1]};
1193
+		int32_t capmixout[2] = {capmix[0],capmix[1]};
1194
+		int32_t sndout[2] = {0,0};
1195
+		int32_t capout[2];
1196
+
1197
+		//create SPU output
1198
+		switch(SPU->regs.ctl_left)
1199
+		{
1200
+		case SPU_struct::REGS::LOM_LEFT_MIXER: sndout[0] = mixout[0]; break;
1201
+		case SPU_struct::REGS::LOM_CH1: sndout[0] = submix[1*2+0]; break;
1202
+		case SPU_struct::REGS::LOM_CH3: sndout[0] = submix[3*2+0]; break;
1203
+		case SPU_struct::REGS::LOM_CH1_PLUS_CH3: sndout[0] = submix[1*2+0] + submix[3*2+0]; break;
1204
+		}
1205
+		switch(SPU->regs.ctl_right)
1206
+		{
1207
+		case SPU_struct::REGS::ROM_RIGHT_MIXER: sndout[1] = mixout[1]; break;
1208
+		case SPU_struct::REGS::ROM_CH1: sndout[1] = submix[1*2+1]; break;
1209
+		case SPU_struct::REGS::ROM_CH3: sndout[1] = submix[3*2+1]; break;
1210
+		case SPU_struct::REGS::ROM_CH1_PLUS_CH3: sndout[1] = submix[1*2+1] + submix[3*2+1]; break;
1211
+		}
1212
+
1213
+
1214
+		//generate capture output ("capture bugs" from gbatek are not emulated)
1215
+		if(SPU->regs.cap[0].source==0)
1216
+			capout[0] = capmixout[0]; //cap0 = L-mix
1217
+		else if(SPU->regs.cap[0].add)
1218
+			capout[0] = chanout[0] + chanout[1]; //cap0 = ch0+ch1
1219
+		else capout[0] = chanout[0]; //cap0 = ch0
1220
+
1221
+		if(SPU->regs.cap[1].source==0)
1222
+			capout[1] = capmixout[1]; //cap1 = R-mix
1223
+		else if(SPU->regs.cap[1].add)
1224
+			capout[1] = chanout[2] + chanout[3]; //cap1 = ch2+ch3
1225
+		else capout[1] = chanout[2]; //cap1 = ch2
1226
+
1227
+		capout[0] = MinMax<int32_t>(capout[0],-0x8000,0x7FFF);
1228
+		capout[1] = MinMax<int32_t>(capout[1],-0x8000,0x7FFF);
1229
+
1230
+		//write the output sample where it is supposed to go
1231
+		if(samp==0)
1232
+		{
1233
+			samp0[0] = sndout[0];
1234
+			samp0[1] = sndout[1];
1235
+		}
1236
+		else
1237
+		{
1238
+			SPU->sndbuf[samp*2+0] = sndout[0];
1239
+			SPU->sndbuf[samp*2+1] = sndout[1];
1240
+		}
1241
+
1242
+		for(int capchan=0;capchan<2;capchan++)
1243
+		{
1244
+			if(SPU->regs.cap[capchan].runtime.running)
1245
+			{
1246
+				SPU_struct::REGS::CAP& cap = SPU->regs.cap[capchan];
1247
+				uint32_t last = u32floor(cap.runtime.sampcnt);
1248
+				cap.runtime.sampcnt += SPU->channels[1+2*capchan].sampinc;
1249
+				uint32_t curr = u32floor(cap.runtime.sampcnt);
1250
+				for(uint32_t j=last;j<curr;j++)
1251
+				{
1252
+					//so, this is a little strange. why go through a fifo?
1253
+					//it seems that some games will set up a reverb effect by capturing
1254
+					//to the nearly same address as playback, but ahead by a couple.
1255
+					//So, playback will always end up being what was captured a couple of samples ago.
1256
+					//This system counts on playback always having read ahead 16 samples.
1257
+					//In that case, playback will end up being what was processed at one entire buffer length ago,
1258
+					//since the 16 samples would have read ahead before they got captured over
1259
+
1260
+					//It's actually the source channels which should have a fifo, but we are
1261
+					//not going to take the hit in speed and complexity. Save it for a future rewrite.
1262
+					//Instead, what we do here is delay the capture by 16 samples to create a similar effect.
1263
+					//Subjectively, it seems to be working.
1264
+
1265
+					//Don't do anything until the fifo is filled, so as to delay it
1266
+					if(cap.runtime.fifo.size<16)
1267
+					{
1268
+						cap.runtime.fifo.enqueue(static_cast<int16_t>(capout[capchan]));
1269
+						continue;
1270
+					}
1271
+
1272
+					//(actually capture sample from fifo instead of most recently generated)
1273
+					uint32_t multiplier;
1274
+					int32_t sample = cap.runtime.fifo.dequeue();
1275
+					cap.runtime.fifo.enqueue(static_cast<int16_t>(capout[capchan]));
1276
+
1277
+					//static FILE* fp = NULL;
1278
+					//if(!fp) fp = fopen("d:\\capout.raw","wb");
1279
+					//fwrite(&sample,2,1,fp);
1280
+
1281
+					if(cap.bits8)
1282
+					{
1283
+						int8_t sample8 = static_cast<int8_t>(sample>>8);
1284
+						if(skipcap) _MMU_write08<1,MMU_AT_DMA>(cap.runtime.curdad,0);
1285
+						else _MMU_write08<1,MMU_AT_DMA>(cap.runtime.curdad,sample8);
1286
+						cap.runtime.curdad++;
1287
+						multiplier = 4;
1288
+					}
1289
+					else
1290
+					{
1291
+						int16_t sample16 = static_cast<int16_t>(sample);
1292
+						if(skipcap) _MMU_write16<1,MMU_AT_DMA>(cap.runtime.curdad,0);
1293
+						else _MMU_write16<1,MMU_AT_DMA>(cap.runtime.curdad,sample16);
1294
+						cap.runtime.curdad+=2;
1295
+						multiplier = 2;
1296
+					}
1297
+
1298
+					if(cap.runtime.curdad>=cap.runtime.maxdad) {
1299
+						cap.runtime.curdad = cap.dad;
1300
+						cap.runtime.sampcnt -= cap.len*multiplier;
1301
+					}
1302
+				} //sampinc loop
1303
+			} //if capchan running
1304
+		} //capchan loop
1305
+	} //main sample loop
1306
+
1307
+	SPU->sndbuf[0] = samp0[0];
1308
+	SPU->sndbuf[1] = samp0[1];
1309
+}
1310
+
1311
+//ENTER
1312
+static void SPU_MixAudio(bool actuallyMix, SPU_struct *SPU, int length)
1313
+{
1314
+	if(actuallyMix)
1315
+	{
1316
+		memset(SPU->sndbuf, 0, length*4*2);
1317
+		memset(SPU->outbuf, 0, length*2*2);
1318
+	}
1319
+
1320
+	//we used to use master enable here, and do nothing if audio is disabled.
1321
+	//now, master enable is emulated better..
1322
+	//but for a speed optimization we will still do it
1323
+	if(!SPU->regs.masteren) return;
1324
+
1325
+	bool advanced = CommonSettings.spu_advanced ;
1326
+
1327
+	//branch here so that slow computers don't have to take the advanced (slower) codepath.
1328
+	//it remainds to be seen exactly how much slower it is
1329
+	//if it isnt much slower then we should refactor everything to be simpler, once it is working
1330
+	if(advanced && SPU == SPU_core)
1331
+	{
1332
+		SPU_MixAudio_Advanced(actuallyMix, SPU, length);
1333
+	}
1334
+	else
1335
+	{
1336
+		//non-advanced mode
1337
+		for(int i=0;i<16;i++)
1338
+		{
1339
+			channel_struct *chan = &SPU->channels[i];
1340
+
1341
+			if (chan->status != CHANSTAT_PLAY)
1342
+				continue;
1343
+
1344
+			SPU->bufpos = 0;
1345
+			SPU->buflength = length;
1346
+
1347
+			// Mix audio
1348
+			_SPU_ChanUpdate(!CommonSettings.spu_muteChannels[i] && actuallyMix, SPU, chan);
1349
+		}
1350
+	}
1351
+
1352
+	//we used to bail out if speakers were disabled.
1353
+	//this is technically wrong. sound may still be captured, or something.
1354
+	//in all likelihood, any game doing this probably master disabled the SPU also
1355
+	//so, optimization of this case is probably not necessary.
1356
+	//later, we'll just silence the output
1357
+	bool speakers = T1ReadWord(MMU.ARM7_REG, 0x304) & 0x01;
1358
+
1359
+	uint8_t vol = SPU->regs.mastervol;
1360
+
1361
+	// convert from 32-bit->16-bit
1362
+	if(actuallyMix && speakers)
1363
+		for (int i = 0; i < length*2; i++)
1364
+		{
1365
+			// Apply Master Volume
1366
+			SPU->sndbuf[i] = spumuldiv7(SPU->sndbuf[i], vol);
1367
+			int16_t outsample = static_cast<int16_t>(MinMax<int32_t>(SPU->sndbuf[i],-0x8000,0x7FFF));
1368
+			SPU->outbuf[i] = outsample;
1369
+		}
1370
+
1371
+
1372
+}
1373
+
1374
+//////////////////////////////////////////////////////////////////////////////
1375
+
1376
+
1377
+//emulates one hline of the cpu core.
1378
+//this will produce a variable number of samples, calculated to keep a 44100hz output
1379
+//in sync with the emulator framerate
1380
+int spu_core_samples = 0;
1381
+void SPU_Emulate_core()
1382
+{
1383
+	samples += samples_per_hline;
1384
+	spu_core_samples = (int)(samples);
1385
+	samples -= spu_core_samples;
1386
+
1387
+	bool synchronize = (synchmode == ESynchMode_Synchronous);
1388
+	bool mix = /*driver->AVI_IsRecording() || driver->WAV_IsRecording() ||*/ synchronize;
1389
+
1390
+	SPU_MixAudio(mix,SPU_core,spu_core_samples);
1391
+	if(synchronize && SPU_currentCoreNum != SNDCORE_DUMMY)
1392
+		synchronizer->enqueue_samples(SPU_core->outbuf, spu_core_samples);
1393
+}
1394
+
1395
+void SPU_Emulate_user(bool mix)
1396
+{
1397
+	uint32_t audiosize;
1398
+
1399
+	// Check to see how much free space there is
1400
+	// If there is some, fill up the buffer
1401
+	if(!SNDCore) return;
1402
+	audiosize = SNDCore->GetAudioSpace();
1403
+
1404
+	if (audiosize > 0)
1405
+	{
1406
+		//printf("mix %i samples\n", audiosize);
1407
+		if (audiosize > (uint32_t)buffersize)
1408
+			audiosize = buffersize;
1409
+
1410
+		int16_t* outbuf;
1411
+		int samplesOutput;
1412
+		if(synchmode == ESynchMode_Synchronous)
1413
+		{
1414
+			static std::vector<int16_t> tempbuf;
1415
+			if(tempbuf.size() < audiosize*2) tempbuf.resize(audiosize*2);
1416
+			outbuf = &tempbuf[0];
1417
+			samplesOutput = synchronizer->output_samples(outbuf, audiosize);
1418
+		}
1419
+		else if(SPU_user)
1420
+		{
1421
+			outbuf = SPU_user->outbuf;
1422
+			samplesOutput = (SPU_MixAudio(mix,SPU_user,audiosize), audiosize);
1423
+		}
1424
+		else return;
1425
+
1426
+		SNDCore->UpdateAudio(outbuf, samplesOutput);
1427
+		//WAV_WavSoundUpdate(SPU_user->outbuf, samplesOutput, WAVMODE_USER);
1428
+	}
1429
+}
1430
+
1431
+//////////////////////////////////////////////////////////////////////////////
1432
+// Dummy Sound Interface
1433
+//////////////////////////////////////////////////////////////////////////////
1434
+
1435
+int SNDDummyInit(int) { return 0; }
1436
+void SNDDummyDeInit() {}
1437
+void SNDDummyUpdateAudio(int16_t *, uint32_t) { }
1438
+uint32_t SNDDummyGetAudioSpace() { return DESMUME_SAMPLE_RATE/60 + 5; }
1439
+void SNDDummyMuteAudio() {}
1440
+void SNDDummyUnMuteAudio() {}
1441
+void SNDDummySetVolume(int) {}
1442
+
1443
+SoundInterface_struct SNDDummy = {
1444
+	SNDCORE_DUMMY,
1445
+	"Dummy Sound Interface",
1446
+	SNDDummyInit,
1447
+	SNDDummyDeInit,
1448
+	SNDDummyUpdateAudio,
1449
+	SNDDummyGetAudioSpace,
1450
+	SNDDummyMuteAudio,
1451
+	SNDDummyUnMuteAudio,
1452
+	SNDDummySetVolume,
1453
+	NULL
1454
+};
1455
+
1456
+//---------wav writer------------
1457
+
1458
+/*typedef struct {
1459
+	char id[4];
1460
+	uint32_t size;
1461
+} chunk_struct;
1462
+
1463
+typedef struct {
1464
+	chunk_struct riff;
1465
+	char rifftype[4];
1466
+} waveheader_struct;
1467
+
1468
+typedef struct {
1469
+	chunk_struct chunk;
1470
+	uint16_t compress;
1471
+	uint16_t numchan;
1472
+	uint32_t rate;
1473
+	uint32_t bytespersec;
1474
+	uint16_t blockalign;
1475
+	uint16_t bitspersample;
1476
+} fmt_struct;
1477
+
1478
+WavWriter::WavWriter()
1479
+: spufp(NULL)
1480
+{
1481
+}
1482
+bool WavWriter::open(const std::string & fname)
1483
+{
1484
+	waveheader_struct waveheader;
1485
+	fmt_struct fmt;
1486
+	chunk_struct data;
1487
+	size_t elems_written = 0;
1488
+
1489
+	if ((spufp = fopen(fname.c_str(), "wb")) == NULL)
1490
+		return false;
1491
+
1492
+	// Do wave header
1493
+	memcpy(waveheader.riff.id, "RIFF", 4);
1494
+	waveheader.riff.size = 0; // we'll fix this after the file is closed
1495
+	memcpy(waveheader.rifftype, "WAVE", 4);
1496
+	elems_written += fwrite((void *)&waveheader, 1, sizeof(waveheader_struct), spufp);
1497
+
1498
+	// fmt chunk
1499
+	memcpy(fmt.chunk.id, "fmt ", 4);
1500
+	fmt.chunk.size = 16; // we'll fix this at the end
1501
+	fmt.compress = 1; // PCM
1502
+	fmt.numchan = 2; // Stereo
1503
+	fmt.rate = DESMUME_SAMPLE_RATE;
1504
+	fmt.bitspersample = 16;
1505
+	fmt.blockalign = fmt.bitspersample / 8 * fmt.numchan;
1506
+	fmt.bytespersec = fmt.rate * fmt.blockalign;
1507
+	elems_written += fwrite((void *)&fmt, 1, sizeof(fmt_struct), spufp);
1508
+
1509
+	// data chunk
1510
+	memcpy(data.id, "data", 4);
1511
+	data.size = 0; // we'll fix this at the end
1512
+	elems_written += fwrite((void *)&data, 1, sizeof(chunk_struct), spufp);
1513
+
1514
+	return true;
1515
+}
1516
+
1517
+void WavWriter::close()
1518
+{
1519
+	if(!spufp) return;
1520
+	size_t elems_written = 0;
1521
+	long length = ftell(spufp);
1522
+
1523
+	// Let's fix the riff chunk size and the data chunk size
1524
+	fseek(spufp, sizeof(waveheader_struct)-0x8, SEEK_SET);
1525
+	length -= 0x8;
1526
+	elems_written += fwrite((void *)&length, 1, 4, spufp);
1527
+
1528
+	fseek(spufp, sizeof(waveheader_struct)+sizeof(fmt_struct)+0x4, SEEK_SET);
1529
+	length -= sizeof(waveheader_struct)+sizeof(fmt_struct);
1530
+	elems_written += fwrite((void *)&length, 1, 4, spufp);
1531
+	fclose(spufp);
1532
+	spufp = NULL;
1533
+}
1534
+
1535
+void WavWriter::update(void* soundData, int numSamples)
1536
+{
1537
+	if(!spufp) return;
1538
+	//TODO - big endian for the int16_t samples??*/
1539
+	/*size_t elems_written = *//*fwrite(soundData, numSamples*2, 2, spufp);
1540
+}
1541
+
1542
+bool WavWriter::isRecording() const
1543
+{
1544
+	return spufp != NULL;
1545
+}*/
1546
+
1547
+
1548
+//static WavWriter wavWriter;
1549
+
1550
+/*void WAV_End()
1551
+{
1552
+	wavWriter.close();
1553
+}*/
1554
+
1555
+/*bool WAV_Begin(const char* fname, WAVMode mode)
1556
+{
1557
+	WAV_End();
1558
+
1559
+	if(!wavWriter.open(fname))
1560
+		return false;
1561
+
1562
+	if(mode == WAVMODE_ANY)
1563
+		mode = WAVMODE_CORE;
1564
+	wavWriter.mode = mode;
1565
+
1566
+	driver->USR_InfoMessage("WAV recording started.");
1567
+
1568
+	return true;
1569
+}*/
1570
+
1571
+/*bool WAV_IsRecording(WAVMode mode)
1572
+{
1573
+	if(wavWriter.mode == mode || mode == WAVMODE_ANY)
1574
+		return wavWriter.isRecording();
1575
+	return false;
1576
+}*/
1577
+
1578
+/*void WAV_WavSoundUpdate(void* soundData, int numSamples, WAVMode mode)
1579
+{
1580
+	if(wavWriter.mode == mode || mode == WAVMODE_ANY)
1581
+		wavWriter.update(soundData, numSamples);
1582
+}*/
1583
+
1584
+
1585
+
1586
+//////////////////////////////////////////////////////////////////////////////
1587
+
1588
+/*void spu_savestate(EMUFILE* os)
1589
+{
1590
+	//version
1591
+	write32le(6,os);
1592
+
1593
+	SPU_struct *spu = SPU_core;
1594
+
1595
+	for(int j=0;j<16;j++) {
1596
+		channel_struct &chan = spu->channels[j];
1597
+		write32le(chan.num,os);
1598
+		write8le(chan.vol,os);
1599
+		write8le(chan.datashift,os);
1600
+		write8le(chan.hold,os);
1601
+		write8le(chan.pan,os);
1602
+		write8le(chan.waveduty,os);
1603
+		write8le(chan.repeat,os);
1604
+		write8le(chan.format,os);
1605
+		write8le(chan.status,os);
1606
+		write32le(chan.addr,os);
1607
+		write16le(chan.timer,os);
1608
+		write16le(chan.loopstart,os);
1609
+		write32le(chan.length,os);
1610
+		write64le(double_to_u64(chan.sampcnt),os);
1611
+		write64le(double_to_u64(chan.sampinc),os);
1612
+		write32le(chan.lastsampcnt,os);
1613
+		write16le(chan.pcm16b,os);
1614
+		write16le(chan.pcm16b_last,os);
1615
+		write32le(chan.index,os);
1616
+		write16le(chan.x,os);
1617
+		write16le(chan.psgnoise_last,os);
1618
+		write8le(chan.keyon,os);
1619
+	}
1620
+
1621
+	write64le(double_to_u64(samples),os);
1622
+
1623
+	write8le(spu->regs.mastervol,os);
1624
+	write8le(spu->regs.ctl_left,os);
1625
+	write8le(spu->regs.ctl_right,os);
1626
+	write8le(spu->regs.ctl_ch1bypass,os);
1627
+	write8le(spu->regs.ctl_ch3bypass,os);
1628
+	write8le(spu->regs.masteren,os);
1629
+	write16le(spu->regs.soundbias,os);
1630
+
1631
+	for(int i=0;i<2;i++)
1632
+	{
1633
+		write8le(spu->regs.cap[i].add,os);
1634
+		write8le(spu->regs.cap[i].source,os);
1635
+		write8le(spu->regs.cap[i].oneshot,os);
1636
+		write8le(spu->regs.cap[i].bits8,os);
1637
+		write8le(spu->regs.cap[i].active,os);
1638
+		write32le(spu->regs.cap[i].dad,os);
1639
+		write16le(spu->regs.cap[i].len,os);
1640
+		write8le(spu->regs.cap[i].runtime.running,os);
1641
+		write32le(spu->regs.cap[i].runtime.curdad,os);
1642
+		write32le(spu->regs.cap[i].runtime.maxdad,os);
1643
+		write_double_le(spu->regs.cap[i].runtime.sampcnt,os);
1644
+	}
1645
+
1646
+	for(int i=0;i<2;i++)
1647
+		spu->regs.cap[i].runtime.fifo.save(os);
1648
+}*/
1649
+
1650
+bool spu_loadstate(EMUFILE* is, int)
1651
+{
1652
+	uint64_t temp64;
1653
+
1654
+	//read version
1655
+	uint32_t version;
1656
+	if(read32le(&version,is) != 1) return false;
1657
+
1658
+	SPU_struct *spu = SPU_core;
1659
+	reconstruct(&SPU_core->regs);
1660
+
1661
+	for(int j=0;j<16;j++) {
1662
+		channel_struct &chan = spu->channels[j];
1663
+		read32le(&chan.num,is);
1664
+		read8le(&chan.vol,is);
1665
+		read8le(&chan.datashift,is);
1666
+		read8le(&chan.hold,is);
1667
+		read8le(&chan.pan,is);
1668
+		read8le(&chan.waveduty,is);
1669
+		read8le(&chan.repeat,is);
1670
+		read8le(&chan.format,is);
1671
+		read8le(&chan.status,is);
1672
+		read32le(&chan.addr,is);
1673
+		read16le(&chan.timer,is);
1674
+		read16le(&chan.loopstart,is);
1675
+		read32le(&chan.length,is);
1676
+		chan.totlength = chan.length + chan.loopstart;
1677
+		chan.double_totlength_shifted = (double)(chan.totlength << format_shift[chan.format]);
1678
+		//printf("%f\n",chan.double_totlength_shifted);
1679
+		if(version >= 2)
1680
+		{
1681
+			read64le(&temp64,is); chan.sampcnt = u64_to_double(temp64);
1682
+			read64le(&temp64,is); chan.sampinc = u64_to_double(temp64);
1683
+		}
1684
+		else
1685
+		{
1686
+			read32le((uint32_t*)&chan.sampcnt,is);
1687
+			read32le((uint32_t*)&chan.sampinc,is);
1688
+		}
1689
+		read32le(&chan.lastsampcnt,is);
1690
+		read16le(&chan.pcm16b,is);
1691
+		read16le(&chan.pcm16b_last,is);
1692
+		read32le(&chan.index,is);
1693
+		read16le(&chan.x,is);
1694
+		read16le(&chan.psgnoise_last,is);
1695
+
1696
+		if(version>=4)
1697
+			read8le(&chan.keyon,is);
1698
+
1699
+		//hopefully trigger a recovery of the adpcm looping system
1700
+		chan.loop_index = K_ADPCM_LOOPING_RECOVERY_INDEX;
1701
+
1702
+		//fixup the pointers which we had are supposed to keep cached
1703
+		chan.buf8 = (int8_t*)&MMU.MMU_MEM[1][(chan.addr>>20)&0xFF][(chan.addr & MMU.MMU_MASK[1][(chan.addr >> 20) & 0xFF])];
1704
+		chan.buf16 = (int16_t*)chan.buf8;
1705
+	}
1706
+
1707
+	if(version>=2) {
1708
+		read64le(&temp64,is); samples = u64_to_double(temp64);
1709
+	}
1710
+
1711
+	if(version>=4)
1712
+	{
1713
+		read8le(&spu->regs.mastervol,is);
1714
+		read8le(&spu->regs.ctl_left,is);
1715
+		read8le(&spu->regs.ctl_right,is);
1716
+		read8le(&spu->regs.ctl_ch1bypass,is);
1717
+		read8le(&spu->regs.ctl_ch3bypass,is);
1718
+		read8le(&spu->regs.masteren,is);
1719
+		read16le(&spu->regs.soundbias,is);
1720
+	}
1721
+
1722
+	if(version>=5)
1723
+	{
1724
+		for(int i=0;i<2;i++)
1725
+		{
1726
+			read8le(&spu->regs.cap[i].add,is);
1727
+			read8le(&spu->regs.cap[i].source,is);
1728
+			read8le(&spu->regs.cap[i].oneshot,is);
1729
+			read8le(&spu->regs.cap[i].bits8,is);
1730
+			read8le(&spu->regs.cap[i].active,is);
1731
+			read32le(&spu->regs.cap[i].dad,is);
1732
+			read16le(&spu->regs.cap[i].len,is);
1733
+			read8le(&spu->regs.cap[i].runtime.running,is);
1734
+			read32le(&spu->regs.cap[i].runtime.curdad,is);
1735
+			read32le(&spu->regs.cap[i].runtime.maxdad,is);
1736
+			read_double_le(&spu->regs.cap[i].runtime.sampcnt,is);
1737
+		}
1738
+	}
1739
+
1740
+	if(version>=6)
1741
+		for(int i=0;i<2;i++) spu->regs.cap[i].runtime.fifo.load(is);
1742
+	else
1743
+		for(int i=0;i<2;i++) spu->regs.cap[i].runtime.fifo.reset();
1744
+
1745
+	//older versions didnt store a mastervol;
1746
+	//we must reload this or else games will start silent
1747
+	if(version<4)
1748
+	{
1749
+		spu->regs.mastervol = T1ReadByte(MMU.ARM7_REG, 0x500) & 0x7F;
1750
+		spu->regs.masteren = static_cast<uint8_t>(BIT15(T1ReadWord(MMU.ARM7_REG, 0x500)));
1751
+	}
1752
+
1753
+	//copy the core spu (the more accurate) to the user spu
1754
+	SPU_CloneUser();
1755
+
1756
+	return true;
1757
+}