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 1
deleted file mode 100644
... ...
@@ -1,315 +0,0 @@
1
-/* SPU2-X, A plugin for Emulating the Sound Processing Unit of the Playstation 2
2
-* Developed and maintained by the Pcsx2 Development Team.
3
-*
4
-* Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz]
5
-*
6
-* SPU2-X is free software: you can redistribute it and/or modify it under the terms
7
-* of the GNU Lesser General Public License as published by the Free Software Found-
8
-* ation, either version 3 of the License, or (at your option) any later version.
9
-*
10
-* SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
11
-* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12
-* PURPOSE.  See the GNU Lesser General Public License for more details.
13
-*
14
-* You should have received a copy of the GNU Lesser General Public License
15
-* along with SPU2-X.  If not, see <http://www.gnu.org/licenses/>.
16
-*/
17
-
18
-#include "XSFCommon.h"
19
-
20
-#include "../types.h"
21
-#include "SoundTouch/SoundTouch.h"
22
-#include "SndOut.h"
23
-
24
-static std::unique_ptr<soundtouch::SoundTouch> pSoundTouch;
25
-static int ts_stats_stretchblocks = 0;
26
-static int ts_stats_normalblocks = 0;
27
-static int ts_stats_logcounter = 0;
28
-
29
-// data prediction amount, used to "commit" data that hasn't
30
-// finished timestretch processing.
31
-int32_t SndBuffer::m_predictData;
32
-
33
-// records last buffer status (fill %, range -100 to 100, with 0 being 50% full)
34
-float SndBuffer::lastPct;
35
-float SndBuffer::lastEmergencyAdj;
36
-
37
-float SndBuffer::cTempo = 1;
38
-float SndBuffer::eTempo = 1;
39
-int SndBuffer::freezeTempo = 0;
40
-
41
-void SndBuffer::PredictDataWrite(int samples)
42
-{
43
-	m_predictData += samples;
44
-}
45
-
46
-// Calculate the buffer status percentage.
47
-// Returns range from -1.0 to 1.0
48
-//    1.0 = buffer overflow!
49
-//    0.0 = buffer nominal (50% full)
50
-//   -1.0 = buffer underflow!
51
-float SndBuffer::GetStatusPct()
52
-{
53
-	// Get the buffer status of the output driver too, so that we can
54
-	// obtain a more accurate overall buffer status.
55
-
56
-	int drvempty = 0;
57
-	//int drvempty = mods[OutputModule]->GetEmptySampleCount(); // / 2;
58
-	//TODO
59
-
60
-	//ConLog( "Data %d >>> driver: %d   predict: %d\n", data, drvempty, predictData );
61
-
62
-	float result = static_cast<float>(m_data + m_predictData - drvempty) - (m_size / 2);
63
-	result /= m_size / 2;
64
-	return result;
65
-}
66
-
67
-void SndBuffer::UpdateTempoChange()
68
-{
69
-	if (--freezeTempo > 0)
70
-		return;
71
-
72
-	float statusPct = GetStatusPct();
73
-	float pctChange = statusPct - lastPct;
74
-
75
-	float tempoChange;
76
-	float emergencyAdj = 0;
77
-	float newcee = cTempo; // workspace var. for cTempo
78
-
79
-	// IMPORTANT!
80
-	// If you plan to tweak these values, make sure you're using a release build
81
-	// OUTSIDE THE DEBUGGER to test it!  The Visual Studio debugger can really cause
82
-	// erratic behavior in the audio buffers, and makes the timestretcher seem a
83
-	// lot more inconsistent than it really is.
84
-
85
-	// We have two factors.
86
-	//   * Distance from nominal buffer status (50% full)
87
-	//   * The change from previous update to this update.
88
-
89
-	// Prediction based on the buffer change:
90
-	// (linear seems to work better here)
91
-
92
-	tempoChange = pctChange * 0.75f;
93
-
94
-	if (statusPct * tempoChange < 0.0f)
95
-		// only apply tempo change if it is in synch with the buffer status.
96
-		// In other words, if the buffer is high (over 0%), and is decreasing,
97
-		// ignore it.  It'll just muck things up.
98
-
99
-		tempoChange = 0;
100
-
101
-	// Sudden spikes in framerate can cause the nominal buffer status
102
-	// to go critical, in which case we have to enact an emergency
103
-	// stretch. The following cubic formulas do that.  Values near
104
-	// the extremeites give much larger results than those near 0.
105
-	// And the value is added only this time, and does not accumulate.
106
-	// (otherwise a large value like this would cause problems down the road)
107
-
108
-	// Constants:
109
-	// Weight - weights the statusPct's "emergency" consideration.
110
-	//   higher values here will make the buffer perform more drastic
111
-	//   compensations at the outer edges of the buffer (at -75 or +75%
112
-	//   or beyond, for example).
113
-
114
-	// Range - scales the adjustment to the given range (more or less).
115
-	//   The actual range is dependent on the weight used, so if you increase
116
-	//   Weight you'll usually want to decrease Range somewhat to compensate.
117
-
118
-	// Prediction based on the buffer fill status:
119
-
120
-	float statusWeight = 2.99f;
121
-	float statusRange = 0.068f;
122
-
123
-	// "non-emergency" deadzone:  In this area stretching will be strongly discouraged.
124
-	// Note: due tot he nature of timestretch latency, it's always a wee bit harder to
125
-	// cope with low fps (underruns) than it is high fps (overruns).  So to help out a
126
-	// little, the low-end portions of this check are less forgiving than the high-sides.
127
-
128
-	if (cTempo < 0.965f || cTempo > 1.060f || pctChange < -0.38f || pctChange > 0.54f || statusPct < -0.32f || statusPct > 0.39f || eTempo < 0.89f || eTempo > 1.19f)
129
-		emergencyAdj = std::pow(statusPct * statusWeight, 3.0f) * statusRange;
130
-
131
-	// Smooth things out by factoring our previous adjustment into this one.
132
-	// It helps make the system 'feel' a little smarter by  giving it at least
133
-	// one packet worth of history to help work off of:
134
-
135
-	emergencyAdj = (emergencyAdj * 0.75f) + (lastEmergencyAdj * 0.25f);
136
-
137
-	lastEmergencyAdj = emergencyAdj;
138
-	lastPct = statusPct;
139
-
140
-	// Accumulate a fraction of the tempo change into the tempo itself.
141
-	// This helps the system run "smarter" to games that run consistently
142
-	// fast or slow by altering the base tempo to something closer to the
143
-	// game's active speed.  In tests most games normalize within 2 seconds
144
-	// at 100ms latency, which is pretty good (larger buffers normalize even
145
-	// quicker).
146
-
147
-	newcee += newcee * (tempoChange + emergencyAdj) * 0.03f;
148
-
149
-	// Apply tempoChange as a scale of cTempo.  That way the effect is proportional
150
-	// to the current tempo.  (otherwise tempos rate of change at the extremes would
151
-	// be too drastic)
152
-
153
-	float newTempo = newcee + (emergencyAdj * cTempo);
154
-
155
-	// ... and as a final optimization, only stretch if the new tempo is outside
156
-	// a nominal threshold.  Keep this threshold check small, because it could
157
-	// cause some serious side effects otherwise. (enlarging the cTempo check above
158
-	// is usually better/safer)
159
-	if (newTempo < 0.970f || newTempo > 1.045f)
160
-	{
161
-		cTempo = newcee;
162
-
163
-		if (newTempo < 0.10f)
164
-			newTempo = 0.10f;
165
-		else if (newTempo > 10.0f)
166
-			newTempo = 10.0f;
167
-
168
-		if (cTempo < 0.15f)
169
-			cTempo = 0.15f;
170
-		else if (cTempo > 7.5f)
171
-			cTempo = 7.5f;
172
-
173
-		pSoundTouch->setTempo(eTempo = newTempo);
174
-		++ts_stats_stretchblocks;
175
-
176
-		/*ConLog(" * SPU2: [Nominal %d%%] [Emergency: %d%%] (baseTempo: %d%% ) (newTempo: %d%%) (buffer: %d%%)\n",
177
-			//(relation < 0.0) ? "Normalize" : "",
178
-			(int)(tempoChange * 100.0 * 0.03),
179
-			(int)(emergencyAdj * 100.0),
180
-			(int)(cTempo * 100.0),
181
-			(int)(newTempo * 100.0),
182
-			(int)(statusPct * 100.0)
183
-		);*/
184
-	}
185
-	else
186
-	{
187
-		// Nominal operation -- turn off stretching.
188
-		// note: eTempo 'slides' toward 1.0 for smoother audio and better
189
-		// protection against spikes.
190
-		if (!fEqual(cTempo, 1.0f))
191
-		{
192
-			cTempo = 1.0f;
193
-			eTempo = (1.0f + eTempo) * 0.5f;
194
-			pSoundTouch->setTempo(eTempo);
195
-		}
196
-		else
197
-		{
198
-			if (!fEqual(eTempo, cTempo))
199
-				pSoundTouch->setTempo(eTempo = cTempo);
200
-			++ts_stats_normalblocks;
201
-		}
202
-	}
203
-}
204
-
205
-void SndBuffer::timeStretchUnderrun()
206
-{
207
-	// timeStretcher failed it's job.  We need to slow down the audio some.
208
-
209
-	cTempo -= cTempo * 0.12f;
210
-	eTempo -= eTempo * 0.30f;
211
-	if (eTempo < 0.1f)
212
-		eTempo = 0.1f;
213
-	pSoundTouch->setTempo(eTempo);
214
-}
215
-
216
-int32_t SndBuffer::timeStretchOverrun()
217
-{
218
-	// If we overran it means the timestretcher failed.  We need to speed
219
-	// up audio playback.
220
-	cTempo += cTempo * 0.12f;
221
-	eTempo += eTempo * 0.40f;
222
-	if (eTempo > 7.5f)
223
-		eTempo = 7.5f;
224
-	pSoundTouch->setTempo(eTempo);
225
-
226
-	// Throw out just a little bit (two packets worth) to help
227
-	// give the TS some room to work:
228
-
229
-	return SndOutPacketSize * 2;
230
-}
231
-
232
-static void CvtPacketToFloat(StereoOut32 *srcdest)
233
-{
234
-	StereoOutFloat *dest = reinterpret_cast<StereoOutFloat *>(srcdest);
235
-	const StereoOut32 *src = srcdest;
236
-	for (int i = 0; i < SndOutPacketSize; ++i, ++dest, ++src)
237
-		*dest = static_cast<StereoOutFloat>(*src);
238
-}
239
-
240
-// Parameter note: Size should always be a multiple of 128, thanks!
241
-static void CvtPacketToInt(StereoOut32 *srcdest, uint32_t size)
242
-{
243
-	//jASSUME( (size & 127) == 0 );
244
-
245
-	const StereoOutFloat *src = reinterpret_cast<StereoOutFloat *>(srcdest);
246
-	StereoOut32 *dest = srcdest;
247
-
248
-	for (uint32_t i = 0; i < size; ++i, ++dest, ++src)
249
-		*dest = static_cast<StereoOut32>(*src);
250
-}
251
-
252
-void SndBuffer::timeStretchWrite()
253
-{
254
-	bool progress = false;
255
-
256
-	// data prediction helps keep the tempo adjustments more accurate.
257
-	// The timestretcher returns packets in belated "clump" form.
258
-	// Meaning that most of the time we'll get nothing back, and then
259
-	// suddenly we'll get several chunks back at once.  Thus we use
260
-	// data prediction to make the timestretcher more responsive.
261
-
262
-	PredictDataWrite(SndOutPacketSize / eTempo);
263
-	CvtPacketToFloat(sndTempBuffer.get());
264
-
265
-	pSoundTouch->putSamples(reinterpret_cast<float *>(sndTempBuffer.get()), SndOutPacketSize);
266
-
267
-	int tempProgress;
268
-	while (tempProgress = pSoundTouch->receiveSamples(reinterpret_cast<float *>(sndTempBuffer.get()), SndOutPacketSize), !!tempProgress)
269
-	{
270
-		// Hint: It's assumed that pSoundTouch will return chunks of 128 bytes (it always does as
271
-		// long as the SSE optimizations are enabled), which means we can do our own SSE opts here.
272
-
273
-		CvtPacketToInt(sndTempBuffer.get(), tempProgress);
274
-		_WriteSamples(sndTempBuffer.get(), tempProgress);
275
-		progress = true;
276
-	}
277
-
278
-	UpdateTempoChange();
279
-
280
-	//TODO
281
-	//if( MsgOverruns() )
282
-	{
283
-		if(progress)
284
-		{
285
-			if (++ts_stats_logcounter > 300)
286
-			{
287
-				ts_stats_logcounter = 0;
288
-				printf(" * SPU2 > Timestretch Stats > %d%% of packets stretched.\n", (ts_stats_stretchblocks * 100) / (ts_stats_normalblocks + ts_stats_stretchblocks));
289
-				ts_stats_normalblocks = ts_stats_stretchblocks = 0;
290
-			}
291
-		}
292
-	}
293
-}
294
-
295
-void SndBuffer::soundtouchInit()
296
-{
297
-	pSoundTouch.reset(new soundtouch::SoundTouch());
298
-	pSoundTouch->setSampleRate(SampleRate);
299
-	pSoundTouch->setChannels(2);
300
-
301
-	pSoundTouch->setSetting(soundtouch::SETTING_USE_QUICKSEEK, 0);
302
-	pSoundTouch->setSetting(soundtouch::SETTING_USE_AA_FILTER, 0);
303
-
304
-	pSoundTouch->setTempo(1);
305
-
306
-	// some timestretch management vars:
307
-
308
-	cTempo = eTempo = 1.0;
309
-	lastPct = lastEmergencyAdj = 0;
310
-
311
-	// just freeze tempo changes for a while at startup.
312
-	// the driver buffers are bogus anyway.
313
-	freezeTempo = 16;
314
-	m_predictData = 0;
315
-}
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
... ...
@@ -259,7 +259,7 @@ void SndBuffer::timeStretchWrite()
259 259
 	// suddenly we'll get several chunks back at once.  Thus we use
260 260
 	// data prediction to make the timestretcher more responsive.
261 261
 
262
-	PredictDataWrite(static_cast<int>(SndOutPacketSize / eTempo));
262
+	PredictDataWrite(SndOutPacketSize / eTempo);
263 263
 	CvtPacketToFloat(sndTempBuffer.get());
264 264
 
265 265
 	pSoundTouch->putSamples(reinterpret_cast<float *>(sndTempBuffer.get()), SndOutPacketSize);
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
... ...
@@ -17,15 +17,11 @@
17 17
 
18 18
 #include "XSFCommon.h"
19 19
 
20
-//#include "Global.h"
21 20
 #include "../types.h"
22 21
 #include "SoundTouch/SoundTouch.h"
23 22
 #include "SndOut.h"
24
-//#include "SoundTouch/WavFile.h"
25 23
 
26
-#include "SoundTouch/Dialogs.h"
27
-
28
-static soundtouch::SoundTouch* pSoundTouch = NULL;
24
+static std::unique_ptr<soundtouch::SoundTouch> pSoundTouch;
29 25
 static int ts_stats_stretchblocks = 0;
30 26
 static int ts_stats_normalblocks = 0;
31 27
 static int ts_stats_logcounter = 0;
... ...
@@ -42,7 +38,7 @@ float SndBuffer::cTempo = 1;
42 38
 float SndBuffer::eTempo = 1;
43 39
 int SndBuffer::freezeTempo = 0;
44 40
 
45
-void SndBuffer::PredictDataWrite( int samples )
41
+void SndBuffer::PredictDataWrite(int samples)
46 42
 {
47 43
 	m_predictData += samples;
48 44
 }
... ...
@@ -63,24 +59,22 @@ float SndBuffer::GetStatusPct()
63 59
 
64 60
 	//ConLog( "Data %d >>> driver: %d   predict: %d\n", data, drvempty, predictData );
65 61
 
66
-	float result = (float)(m_data + m_predictData - drvempty) - (m_size/2);
67
-	result /= (m_size/2);
62
+	float result = static_cast<float>(m_data + m_predictData - drvempty) - (m_size / 2);
63
+	result /= m_size / 2;
68 64
 	return result;
69 65
 }
70 66
 
71 67
 void SndBuffer::UpdateTempoChange()
72 68
 {
73
-	if( --freezeTempo > 0 )
74
-	{
69
+	if (--freezeTempo > 0)
75 70
 		return;
76
-	}
77 71
 
78 72
 	float statusPct = GetStatusPct();
79 73
 	float pctChange = statusPct - lastPct;
80 74
 
81 75
 	float tempoChange;
82 76
 	float emergencyAdj = 0;
83
-	float newcee = cTempo;		// workspace var. for cTempo
77
+	float newcee = cTempo; // workspace var. for cTempo
84 78
 
85 79
 	// IMPORTANT!
86 80
 	// If you plan to tweak these values, make sure you're using a release build
... ...
@@ -97,14 +91,12 @@ void SndBuffer::UpdateTempoChange()
97 91
 
98 92
 	tempoChange = pctChange * 0.75f;
99 93
 
100
-	if( statusPct * tempoChange < 0.0f )
101
-	{
94
+	if (statusPct * tempoChange < 0.0f)
102 95
 		// only apply tempo change if it is in synch with the buffer status.
103 96
 		// In other words, if the buffer is high (over 0%), and is decreasing,
104 97
 		// ignore it.  It'll just muck things up.
105 98
 
106 99
 		tempoChange = 0;
107
-	}
108 100
 
109 101
 	// Sudden spikes in framerate can cause the nominal buffer status
110 102
 	// to go critical, in which case we have to enact an emergency
... ...
@@ -125,27 +117,22 @@ void SndBuffer::UpdateTempoChange()
125 117
 
126 118
 	// Prediction based on the buffer fill status:
127 119
 
128
-	const float statusWeight = 2.99f;
129
-	const float statusRange = 0.068f;
120
+	float statusWeight = 2.99f;
121
+	float statusRange = 0.068f;
130 122
 
131 123
 	// "non-emergency" deadzone:  In this area stretching will be strongly discouraged.
132 124
 	// Note: due tot he nature of timestretch latency, it's always a wee bit harder to
133 125
 	// cope with low fps (underruns) than it is high fps (overruns).  So to help out a
134 126
 	// little, the low-end portions of this check are less forgiving than the high-sides.
135 127
 
136
-	if( cTempo < 0.965f || cTempo > 1.060f ||
137
-		pctChange < -0.38f || pctChange > 0.54f ||
138
-		statusPct < -0.32f || statusPct > 0.39f ||
139
-		eTempo < 0.89f || eTempo > 1.19f )
140
-	{
141
-		emergencyAdj = ( pow( statusPct*statusWeight, 3.0f ) * statusRange);
142
-	}
128
+	if (cTempo < 0.965f || cTempo > 1.060f || pctChange < -0.38f || pctChange > 0.54f || statusPct < -0.32f || statusPct > 0.39f || eTempo < 0.89f || eTempo > 1.19f)
129
+		emergencyAdj = std::pow(statusPct * statusWeight, 3.0f) * statusRange;
143 130
 
144 131
 	// Smooth things out by factoring our previous adjustment into this one.
145 132
 	// It helps make the system 'feel' a little smarter by  giving it at least
146 133
 	// one packet worth of history to help work off of:
147 134
 
148
-	emergencyAdj = (emergencyAdj * 0.75f) + (lastEmergencyAdj * 0.25f );
135
+	emergencyAdj = (emergencyAdj * 0.75f) + (lastEmergencyAdj * 0.25f);
149 136
 
150 137
 	lastEmergencyAdj = emergencyAdj;
151 138
 	lastPct = statusPct;
... ...
@@ -157,30 +144,34 @@ void SndBuffer::UpdateTempoChange()
157 144
 	// at 100ms latency, which is pretty good (larger buffers normalize even
158 145
 	// quicker).
159 146
 
160
-	newcee += newcee * (tempoChange+emergencyAdj) * 0.03f;
147
+	newcee += newcee * (tempoChange + emergencyAdj) * 0.03f;
161 148
 
162 149
 	// Apply tempoChange as a scale of cTempo.  That way the effect is proportional
163 150
 	// to the current tempo.  (otherwise tempos rate of change at the extremes would
164 151
 	// be too drastic)
165 152
 
166
-	float newTempo = newcee + ( emergencyAdj * cTempo );
153
+	float newTempo = newcee + (emergencyAdj * cTempo);
167 154
 
168 155
 	// ... and as a final optimization, only stretch if the new tempo is outside
169 156
 	// a nominal threshold.  Keep this threshold check small, because it could
170 157
 	// cause some serious side effects otherwise. (enlarging the cTempo check above
171 158
 	// is usually better/safer)
172
-	if( newTempo < 0.970f || newTempo > 1.045f )
159
+	if (newTempo < 0.970f || newTempo > 1.045f)
173 160
 	{
174
-		cTempo = (float)newcee;
161
+		cTempo = newcee;
175 162
 
176
-		if( newTempo < 0.10f ) newTempo = 0.10f;
177
-		else if( newTempo > 10.0f ) newTempo = 10.0f;
163
+		if (newTempo < 0.10f)
164
+			newTempo = 0.10f;
165
+		else if (newTempo > 10.0f)
166
+			newTempo = 10.0f;
178 167
 
179
-		if( cTempo < 0.15f ) cTempo = 0.15f;
180
-		else if( cTempo > 7.5f ) cTempo = 7.5f;
168
+		if (cTempo < 0.15f)
169
+			cTempo = 0.15f;
170
+		else if (cTempo > 7.5f)
171
+			cTempo = 7.5f;
181 172
 
182
-		pSoundTouch->setTempo( eTempo = (float)newTempo );
183
-		ts_stats_stretchblocks++;
173
+		pSoundTouch->setTempo(eTempo = newTempo);
174
+		++ts_stats_stretchblocks;
184 175
 
185 176
 		/*ConLog(" * SPU2: [Nominal %d%%] [Emergency: %d%%] (baseTempo: %d%% ) (newTempo: %d%%) (buffer: %d%%)\n",
186 177
 			//(relation < 0.0) ? "Normalize" : "",
... ...
@@ -199,14 +190,14 @@ void SndBuffer::UpdateTempoChange()
199 190
 		if (!fEqual(cTempo, 1.0f))
200 191
 		{
201 192
 			cTempo = 1.0f;
202
-			eTempo = ( 1.0f + eTempo ) * 0.5f;
203
-			pSoundTouch->setTempo( eTempo );
193
+			eTempo = (1.0f + eTempo) * 0.5f;
194
+			pSoundTouch->setTempo(eTempo);
204 195
 		}
205 196
 		else
206 197
 		{
207 198
 			if (!fEqual(eTempo, cTempo))
208
-				pSoundTouch->setTempo( eTempo=cTempo );
209
-			ts_stats_normalblocks++;
199
+				pSoundTouch->setTempo(eTempo = cTempo);
200
+			++ts_stats_normalblocks;
210 201
 		}
211 202
 	}
212 203
 }
... ...
@@ -215,10 +206,11 @@ void SndBuffer::timeStretchUnderrun()
215 206
 {
216 207
 	// timeStretcher failed it's job.  We need to slow down the audio some.
217 208
 
218
-	cTempo -= (cTempo * 0.12f);
219
-	eTempo -= (eTempo * 0.30f);
220
-	if( eTempo < 0.1f ) eTempo = 0.1f;
221
-	pSoundTouch->setTempo( eTempo );
209
+	cTempo -= cTempo * 0.12f;
210
+	eTempo -= eTempo * 0.30f;
211
+	if (eTempo < 0.1f)
212
+		eTempo = 0.1f;
213
+	pSoundTouch->setTempo(eTempo);
222 214
 }
223 215
 
224 216
 int32_t SndBuffer::timeStretchOverrun()
... ...
@@ -227,33 +219,34 @@ int32_t SndBuffer::timeStretchOverrun()
227 219
 	// up audio playback.
228 220
 	cTempo += cTempo * 0.12f;
229 221
 	eTempo += eTempo * 0.40f;
230
-	if( eTempo > 7.5f ) eTempo = 7.5f;
231
-	pSoundTouch->setTempo( eTempo );
222
+	if (eTempo > 7.5f)
223
+		eTempo = 7.5f;
224
+	pSoundTouch->setTempo(eTempo);
232 225
 
233 226
 	// Throw out just a little bit (two packets worth) to help
234 227
 	// give the TS some room to work:
235 228
 
236
-	return SndOutPacketSize*2;
229
+	return SndOutPacketSize * 2;
237 230
 }
238 231
 
239
-static void CvtPacketToFloat( StereoOut32* srcdest )
232
+static void CvtPacketToFloat(StereoOut32 *srcdest)
240 233
 {
241
-	StereoOutFloat* dest = (StereoOutFloat*)srcdest;
242
-	const StereoOut32* src = (StereoOut32*)srcdest;
243
-	for( int i=0; i<SndOutPacketSize; ++i, ++dest, ++src )
244
-		*dest = (StereoOutFloat)*src;
234
+	StereoOutFloat *dest = reinterpret_cast<StereoOutFloat *>(srcdest);
235
+	const StereoOut32 *src = srcdest;
236
+	for (int i = 0; i < SndOutPacketSize; ++i, ++dest, ++src)
237
+		*dest = static_cast<StereoOutFloat>(*src);
245 238
 }
246 239
 
247 240
 // Parameter note: Size should always be a multiple of 128, thanks!
248
-static void CvtPacketToInt( StereoOut32* srcdest, uint32_t size )
241
+static void CvtPacketToInt(StereoOut32 *srcdest, uint32_t size)
249 242
 {
250 243
 	//jASSUME( (size & 127) == 0 );
251 244
 
252
-	const StereoOutFloat* src = (StereoOutFloat*)srcdest;
253
-	StereoOut32* dest = srcdest;
245
+	const StereoOutFloat *src = reinterpret_cast<StereoOutFloat *>(srcdest);
246
+	StereoOut32 *dest = srcdest;
254 247
 
255
-	for( uint32_t i=0; i<size; ++i, ++dest, ++src )
256
-		*dest = (StereoOut32)*src;
248
+	for (uint32_t i = 0; i < size; ++i, ++dest, ++src)
249
+		*dest = static_cast<StereoOut32>(*src);
257 250
 }
258 251
 
259 252
 void SndBuffer::timeStretchWrite()
... ...
@@ -266,20 +259,19 @@ void SndBuffer::timeStretchWrite()
266 259
 	// suddenly we'll get several chunks back at once.  Thus we use
267 260
 	// data prediction to make the timestretcher more responsive.
268 261
 
269
-	PredictDataWrite( (int)( SndOutPacketSize / eTempo ) );
270
-	CvtPacketToFloat( sndTempBuffer );
262
+	PredictDataWrite(static_cast<int>(SndOutPacketSize / eTempo));
263
+	CvtPacketToFloat(sndTempBuffer.get());
271 264
 
272
-	pSoundTouch->putSamples( (float*)sndTempBuffer, SndOutPacketSize );
265
+	pSoundTouch->putSamples(reinterpret_cast<float *>(sndTempBuffer.get()), SndOutPacketSize);
273 266
 
274 267
 	int tempProgress;
275
-	while( tempProgress = pSoundTouch->receiveSamples( (float*)sndTempBuffer, SndOutPacketSize),
276
-		tempProgress != 0 )
268
+	while (tempProgress = pSoundTouch->receiveSamples(reinterpret_cast<float *>(sndTempBuffer.get()), SndOutPacketSize), !!tempProgress)
277 269
 	{
278 270
 		// Hint: It's assumed that pSoundTouch will return chunks of 128 bytes (it always does as
279 271
 		// long as the SSE optimizations are enabled), which means we can do our own SSE opts here.
280 272
 
281
-		CvtPacketToInt( sndTempBuffer, tempProgress );
282
-		_WriteSamples( sndTempBuffer, tempProgress );
273
+		CvtPacketToInt(sndTempBuffer.get(), tempProgress);
274
+		_WriteSamples(sndTempBuffer.get(), tempProgress);
283 275
 		progress = true;
284 276
 	}
285 277
 
... ...
@@ -288,15 +280,13 @@ void SndBuffer::timeStretchWrite()
288 280
 	//TODO
289 281
 	//if( MsgOverruns() )
290 282
 	{
291
-		if( progress )
283
+		if(progress)
292 284
 		{
293
-			if( ++ts_stats_logcounter > 300 )
285
+			if (++ts_stats_logcounter > 300)
294 286
 			{
295 287
 				ts_stats_logcounter = 0;
296
-				printf( " * SPU2 > Timestretch Stats > %d%% of packets stretched.\n",
297
-					( ts_stats_stretchblocks * 100 ) / ( ts_stats_normalblocks + ts_stats_stretchblocks ) );
298
-				ts_stats_normalblocks = 0;
299
-				ts_stats_stretchblocks = 0;
288
+				printf(" * SPU2 > Timestretch Stats > %d%% of packets stretched.\n", (ts_stats_stretchblocks * 100) / (ts_stats_normalblocks + ts_stats_stretchblocks));
289
+				ts_stats_normalblocks = ts_stats_stretchblocks = 0;
300 290
 			}
301 291
 		}
302 292
 	}
... ...
@@ -304,49 +294,22 @@ void SndBuffer::timeStretchWrite()
304 294
 
305 295
 void SndBuffer::soundtouchInit()
306 296
 {
307
-	pSoundTouch = new soundtouch::SoundTouch();
297
+	pSoundTouch.reset(new soundtouch::SoundTouch());
308 298
 	pSoundTouch->setSampleRate(SampleRate);
309 299
 	pSoundTouch->setChannels(2);
310 300
 
311
-	pSoundTouch->setSetting( soundtouch::SETTING_USE_QUICKSEEK, 0 );
312
-	pSoundTouch->setSetting( soundtouch::SETTING_USE_AA_FILTER, 0 );
313
-
314
-	SoundtouchCfg::ApplySettings( *pSoundTouch );
301
+	pSoundTouch->setSetting(soundtouch::SETTING_USE_QUICKSEEK, 0);
302
+	pSoundTouch->setSetting(soundtouch::SETTING_USE_AA_FILTER, 0);
315 303
 
316 304
 	pSoundTouch->setTempo(1);
317 305
 
318 306
 	// some timestretch management vars:
319 307
 
320
-	cTempo = 1.0;
321
-	eTempo = 1.0;
322
-	lastPct = 0;
323
-	lastEmergencyAdj = 0;
308
+	cTempo = eTempo = 1.0;
309
+	lastPct = lastEmergencyAdj = 0;
324 310
 
325 311
 	// just freeze tempo changes for a while at startup.
326 312
 	// the driver buffers are bogus anyway.
327 313
 	freezeTempo = 16;
328 314
 	m_predictData = 0;
329 315
 }
330
-
331
-// reset timestretch management vars, and delay updates a bit:
332
-void SndBuffer::soundtouchClearContents()
333
-{
334
-	if( pSoundTouch == NULL ) return;
335
-
336
-	pSoundTouch->clear();
337
-	pSoundTouch->setTempo(1);
338
-
339
-	cTempo = 1.0;
340
-	eTempo = 1.0;
341
-	lastPct = 0;
342
-	lastEmergencyAdj = 0;
343
-
344
-	freezeTempo = 16;
345
-	m_predictData = 0;
346
-}
347
-
348
-void SndBuffer::soundtouchCleanup()
349
-{
350
-	//safe_delete( pSoundTouch );
351
-	delete pSoundTouch;
352
-}
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
... ...
@@ -18,7 +18,7 @@
18 18
 #include "XSFCommon.h"
19 19
 
20 20
 //#include "Global.h"
21
-#include "types.h"
21
+#include "../types.h"
22 22
 #include "SoundTouch/SoundTouch.h"
23 23
 #include "SndOut.h"
24 24
 //#include "SoundTouch/WavFile.h"
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,352 @@
1
+/* SPU2-X, A plugin for Emulating the Sound Processing Unit of the Playstation 2
2
+* Developed and maintained by the Pcsx2 Development Team.
3
+*
4
+* Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz]
5
+*
6
+* SPU2-X is free software: you can redistribute it and/or modify it under the terms
7
+* of the GNU Lesser General Public License as published by the Free Software Found-
8
+* ation, either version 3 of the License, or (at your option) any later version.
9
+*
10
+* SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
11
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12
+* PURPOSE.  See the GNU Lesser General Public License for more details.
13
+*
14
+* You should have received a copy of the GNU Lesser General Public License
15
+* along with SPU2-X.  If not, see <http://www.gnu.org/licenses/>.
16
+*/
17
+
18
+#include "XSFCommon.h"
19
+
20
+//#include "Global.h"
21
+#include "types.h"
22
+#include "SoundTouch/SoundTouch.h"
23
+#include "SndOut.h"
24
+//#include "SoundTouch/WavFile.h"
25
+
26
+#include "SoundTouch/Dialogs.h"
27
+
28
+static soundtouch::SoundTouch* pSoundTouch = NULL;
29
+static int ts_stats_stretchblocks = 0;
30
+static int ts_stats_normalblocks = 0;
31
+static int ts_stats_logcounter = 0;
32
+
33
+// data prediction amount, used to "commit" data that hasn't
34
+// finished timestretch processing.
35
+int32_t SndBuffer::m_predictData;
36
+
37
+// records last buffer status (fill %, range -100 to 100, with 0 being 50% full)
38
+float SndBuffer::lastPct;
39
+float SndBuffer::lastEmergencyAdj;
40
+
41
+float SndBuffer::cTempo = 1;
42
+float SndBuffer::eTempo = 1;
43
+int SndBuffer::freezeTempo = 0;
44
+
45
+void SndBuffer::PredictDataWrite( int samples )
46
+{
47
+	m_predictData += samples;
48
+}
49
+
50
+// Calculate the buffer status percentage.
51
+// Returns range from -1.0 to 1.0
52
+//    1.0 = buffer overflow!
53
+//    0.0 = buffer nominal (50% full)
54
+//   -1.0 = buffer underflow!
55
+float SndBuffer::GetStatusPct()
56
+{
57
+	// Get the buffer status of the output driver too, so that we can
58
+	// obtain a more accurate overall buffer status.
59
+
60
+	int drvempty = 0;
61
+	//int drvempty = mods[OutputModule]->GetEmptySampleCount(); // / 2;
62
+	//TODO
63
+
64
+	//ConLog( "Data %d >>> driver: %d   predict: %d\n", data, drvempty, predictData );
65
+
66
+	float result = (float)(m_data + m_predictData - drvempty) - (m_size/2);
67
+	result /= (m_size/2);
68
+	return result;
69
+}
70
+
71
+void SndBuffer::UpdateTempoChange()
72
+{
73
+	if( --freezeTempo > 0 )
74
+	{
75
+		return;
76
+	}
77
+
78
+	float statusPct = GetStatusPct();
79
+	float pctChange = statusPct - lastPct;
80
+
81
+	float tempoChange;
82
+	float emergencyAdj = 0;
83
+	float newcee = cTempo;		// workspace var. for cTempo
84
+
85
+	// IMPORTANT!
86
+	// If you plan to tweak these values, make sure you're using a release build
87
+	// OUTSIDE THE DEBUGGER to test it!  The Visual Studio debugger can really cause
88
+	// erratic behavior in the audio buffers, and makes the timestretcher seem a
89
+	// lot more inconsistent than it really is.
90
+
91
+	// We have two factors.
92
+	//   * Distance from nominal buffer status (50% full)
93
+	//   * The change from previous update to this update.
94
+
95
+	// Prediction based on the buffer change:
96
+	// (linear seems to work better here)
97
+
98
+	tempoChange = pctChange * 0.75f;
99
+
100
+	if( statusPct * tempoChange < 0.0f )
101
+	{
102
+		// only apply tempo change if it is in synch with the buffer status.
103
+		// In other words, if the buffer is high (over 0%), and is decreasing,
104
+		// ignore it.  It'll just muck things up.
105
+
106
+		tempoChange = 0;
107
+	}
108
+
109
+	// Sudden spikes in framerate can cause the nominal buffer status
110
+	// to go critical, in which case we have to enact an emergency
111
+	// stretch. The following cubic formulas do that.  Values near
112
+	// the extremeites give much larger results than those near 0.
113
+	// And the value is added only this time, and does not accumulate.
114
+	// (otherwise a large value like this would cause problems down the road)
115
+
116
+	// Constants:
117
+	// Weight - weights the statusPct's "emergency" consideration.
118
+	//   higher values here will make the buffer perform more drastic
119
+	//   compensations at the outer edges of the buffer (at -75 or +75%
120
+	//   or beyond, for example).
121
+
122
+	// Range - scales the adjustment to the given range (more or less).
123
+	//   The actual range is dependent on the weight used, so if you increase
124
+	//   Weight you'll usually want to decrease Range somewhat to compensate.
125
+
126
+	// Prediction based on the buffer fill status:
127
+
128
+	const float statusWeight = 2.99f;
129
+	const float statusRange = 0.068f;
130
+
131
+	// "non-emergency" deadzone:  In this area stretching will be strongly discouraged.
132
+	// Note: due tot he nature of timestretch latency, it's always a wee bit harder to
133
+	// cope with low fps (underruns) than it is high fps (overruns).  So to help out a
134
+	// little, the low-end portions of this check are less forgiving than the high-sides.
135
+
136
+	if( cTempo < 0.965f || cTempo > 1.060f ||
137
+		pctChange < -0.38f || pctChange > 0.54f ||
138
+		statusPct < -0.32f || statusPct > 0.39f ||
139
+		eTempo < 0.89f || eTempo > 1.19f )
140
+	{
141
+		emergencyAdj = ( pow( statusPct*statusWeight, 3.0f ) * statusRange);
142
+	}
143
+
144
+	// Smooth things out by factoring our previous adjustment into this one.
145
+	// It helps make the system 'feel' a little smarter by  giving it at least
146
+	// one packet worth of history to help work off of:
147
+
148
+	emergencyAdj = (emergencyAdj * 0.75f) + (lastEmergencyAdj * 0.25f );
149
+
150
+	lastEmergencyAdj = emergencyAdj;
151
+	lastPct = statusPct;
152
+
153
+	// Accumulate a fraction of the tempo change into the tempo itself.
154
+	// This helps the system run "smarter" to games that run consistently
155
+	// fast or slow by altering the base tempo to something closer to the
156
+	// game's active speed.  In tests most games normalize within 2 seconds
157
+	// at 100ms latency, which is pretty good (larger buffers normalize even
158
+	// quicker).
159
+
160
+	newcee += newcee * (tempoChange+emergencyAdj) * 0.03f;
161
+
162
+	// Apply tempoChange as a scale of cTempo.  That way the effect is proportional
163
+	// to the current tempo.  (otherwise tempos rate of change at the extremes would
164
+	// be too drastic)
165
+
166
+	float newTempo = newcee + ( emergencyAdj * cTempo );
167
+
168
+	// ... and as a final optimization, only stretch if the new tempo is outside
169
+	// a nominal threshold.  Keep this threshold check small, because it could
170
+	// cause some serious side effects otherwise. (enlarging the cTempo check above
171
+	// is usually better/safer)
172
+	if( newTempo < 0.970f || newTempo > 1.045f )
173
+	{
174
+		cTempo = (float)newcee;
175
+
176
+		if( newTempo < 0.10f ) newTempo = 0.10f;
177
+		else if( newTempo > 10.0f ) newTempo = 10.0f;
178
+
179
+		if( cTempo < 0.15f ) cTempo = 0.15f;
180
+		else if( cTempo > 7.5f ) cTempo = 7.5f;
181
+
182
+		pSoundTouch->setTempo( eTempo = (float)newTempo );
183
+		ts_stats_stretchblocks++;
184
+
185
+		/*ConLog(" * SPU2: [Nominal %d%%] [Emergency: %d%%] (baseTempo: %d%% ) (newTempo: %d%%) (buffer: %d%%)\n",
186
+			//(relation < 0.0) ? "Normalize" : "",
187
+			(int)(tempoChange * 100.0 * 0.03),
188
+			(int)(emergencyAdj * 100.0),
189
+			(int)(cTempo * 100.0),
190
+			(int)(newTempo * 100.0),
191
+			(int)(statusPct * 100.0)
192
+		);*/
193
+	}
194
+	else
195
+	{
196
+		// Nominal operation -- turn off stretching.
197
+		// note: eTempo 'slides' toward 1.0 for smoother audio and better
198
+		// protection against spikes.
199
+		if (!fEqual(cTempo, 1.0f))
200
+		{
201
+			cTempo = 1.0f;
202
+			eTempo = ( 1.0f + eTempo ) * 0.5f;
203
+			pSoundTouch->setTempo( eTempo );
204
+		}
205
+		else
206
+		{
207
+			if (!fEqual(eTempo, cTempo))
208
+				pSoundTouch->setTempo( eTempo=cTempo );
209
+			ts_stats_normalblocks++;
210
+		}
211
+	}
212
+}
213
+
214
+void SndBuffer::timeStretchUnderrun()
215
+{
216
+	// timeStretcher failed it's job.  We need to slow down the audio some.
217
+
218
+	cTempo -= (cTempo * 0.12f);
219
+	eTempo -= (eTempo * 0.30f);
220
+	if( eTempo < 0.1f ) eTempo = 0.1f;
221
+	pSoundTouch->setTempo( eTempo );
222
+}
223
+
224
+int32_t SndBuffer::timeStretchOverrun()
225
+{
226
+	// If we overran it means the timestretcher failed.  We need to speed
227
+	// up audio playback.
228
+	cTempo += cTempo * 0.12f;
229
+	eTempo += eTempo * 0.40f;
230
+	if( eTempo > 7.5f ) eTempo = 7.5f;
231
+	pSoundTouch->setTempo( eTempo );
232
+
233
+	// Throw out just a little bit (two packets worth) to help
234
+	// give the TS some room to work:
235
+
236
+	return SndOutPacketSize*2;
237
+}
238
+
239
+static void CvtPacketToFloat( StereoOut32* srcdest )
240
+{
241
+	StereoOutFloat* dest = (StereoOutFloat*)srcdest;
242
+	const StereoOut32* src = (StereoOut32*)srcdest;
243
+	for( int i=0; i<SndOutPacketSize; ++i, ++dest, ++src )
244
+		*dest = (StereoOutFloat)*src;
245
+}
246
+
247
+// Parameter note: Size should always be a multiple of 128, thanks!
248
+static void CvtPacketToInt( StereoOut32* srcdest, uint32_t size )
249
+{
250
+	//jASSUME( (size & 127) == 0 );
251
+
252
+	const StereoOutFloat* src = (StereoOutFloat*)srcdest;
253
+	StereoOut32* dest = srcdest;
254
+
255
+	for( uint32_t i=0; i<size; ++i, ++dest, ++src )
256
+		*dest = (StereoOut32)*src;
257
+}
258
+
259
+void SndBuffer::timeStretchWrite()
260
+{
261
+	bool progress = false;
262
+
263
+	// data prediction helps keep the tempo adjustments more accurate.
264
+	// The timestretcher returns packets in belated "clump" form.
265
+	// Meaning that most of the time we'll get nothing back, and then
266
+	// suddenly we'll get several chunks back at once.  Thus we use
267
+	// data prediction to make the timestretcher more responsive.
268
+
269
+	PredictDataWrite( (int)( SndOutPacketSize / eTempo ) );
270
+	CvtPacketToFloat( sndTempBuffer );
271
+
272
+	pSoundTouch->putSamples( (float*)sndTempBuffer, SndOutPacketSize );
273
+
274
+	int tempProgress;
275
+	while( tempProgress = pSoundTouch->receiveSamples( (float*)sndTempBuffer, SndOutPacketSize),
276
+		tempProgress != 0 )
277
+	{
278
+		// Hint: It's assumed that pSoundTouch will return chunks of 128 bytes (it always does as
279
+		// long as the SSE optimizations are enabled), which means we can do our own SSE opts here.
280
+
281
+		CvtPacketToInt( sndTempBuffer, tempProgress );
282
+		_WriteSamples( sndTempBuffer, tempProgress );
283
+		progress = true;
284
+	}
285
+
286
+	UpdateTempoChange();
287
+
288
+	//TODO
289
+	//if( MsgOverruns() )
290
+	{
291
+		if( progress )
292
+		{
293
+			if( ++ts_stats_logcounter > 300 )
294
+			{
295
+				ts_stats_logcounter = 0;
296
+				printf( " * SPU2 > Timestretch Stats > %d%% of packets stretched.\n",
297
+					( ts_stats_stretchblocks * 100 ) / ( ts_stats_normalblocks + ts_stats_stretchblocks ) );
298
+				ts_stats_normalblocks = 0;
299
+				ts_stats_stretchblocks = 0;
300
+			}
301
+		}
302
+	}
303
+}
304
+
305
+void SndBuffer::soundtouchInit()
306
+{
307
+	pSoundTouch = new soundtouch::SoundTouch();
308
+	pSoundTouch->setSampleRate(SampleRate);
309
+	pSoundTouch->setChannels(2);
310
+
311
+	pSoundTouch->setSetting( soundtouch::SETTING_USE_QUICKSEEK, 0 );
312
+	pSoundTouch->setSetting( soundtouch::SETTING_USE_AA_FILTER, 0 );
313
+
314
+	SoundtouchCfg::ApplySettings( *pSoundTouch );
315
+
316
+	pSoundTouch->setTempo(1);
317
+
318
+	// some timestretch management vars:
319
+
320
+	cTempo = 1.0;
321
+	eTempo = 1.0;
322
+	lastPct = 0;
323
+	lastEmergencyAdj = 0;
324
+
325
+	// just freeze tempo changes for a while at startup.
326
+	// the driver buffers are bogus anyway.
327
+	freezeTempo = 16;
328
+	m_predictData = 0;
329
+}
330
+
331
+// reset timestretch management vars, and delay updates a bit:
332
+void SndBuffer::soundtouchClearContents()
333
+{
334
+	if( pSoundTouch == NULL ) return;
335
+
336
+	pSoundTouch->clear();
337
+	pSoundTouch->setTempo(1);
338
+
339
+	cTempo = 1.0;
340
+	eTempo = 1.0;
341
+	lastPct = 0;
342
+	lastEmergencyAdj = 0;
343
+
344
+	freezeTempo = 16;
345
+	m_predictData = 0;
346
+}
347
+
348
+void SndBuffer::soundtouchCleanup()
349
+{
350
+	//safe_delete( pSoundTouch );
351
+	delete pSoundTouch;
352
+}