Browse code

Various changes:

* Use enum class instead of enum (except for the enums for the resource IDs, not really necessary there).
* For NCSF specifically, included a function to convert an enum class to its underlying integral type (as this is needed for use with the std::bitset class).
* Cleanup headers so all the ones needed in a file are explicitly included even if they may possibly be included in another header.
* Used forward declarations in a few spots.
* Explicitly namespaced all (u)int*_t uses (this might seem like overkill, but it helps me see when the standard types are being used with a simple search for std::).
* Made sure it all builds with MinGW-w64 as well (both gcc and clang).
* Removed some std::move from DialogBuilder.cpp based on clang's warnings for that.
* Replaced use of std::copy_n on strings in DialogBuilder.cpp with my CopyToString functions that use wcscpy.
* Replaced CHAR_MIN/CHAR_MAX in eqstr.h and ltstr.h with std::numeric_limits<char>::min/max().

Naram Qashat authored on 2021/03/21 03:16:45
Showing 1 changed files
... ...
@@ -5,10 +5,13 @@
5 5
  * Partially based on the vio*sf framework
6 6
  */
7 7
 
8
-#include <cstring>
9
-#include "XSFPlayer.h"
10
-#include "XSFConfig.h"
8
+#include <algorithm>
9
+#include <limits>
10
+#include <vector>
11
+#include <cstdint>
11 12
 #include "XSFCommon.h"
13
+#include "XSFConfig.h"
14
+#include "XSFPlayer.h"
12 15
 
13 16
 extern XSFConfig *xSFConfig;
14 17
 
... ...
@@ -50,26 +53,26 @@ XSFPlayer &XSFPlayer::operator=(const XSFPlayer &xSFPlayer)
50 53
 	return *this;
51 54
 }
52 55
 
53
-bool XSFPlayer::FillBuffer(std::vector<uint8_t> &buf, unsigned &samplesWritten)
56
+bool XSFPlayer::FillBuffer(std::vector<std::uint8_t> &buf, unsigned &samplesWritten)
54 57
 {
55 58
 	bool endFlag = false;
56 59
 	unsigned detectSilence = xSFConfig->GetDetectSilenceSec();
57 60
 	unsigned pos = 0, bufsize = buf.size() >> 2;
58
-	auto trueBuffer = std::vector<uint8_t>(bufsize << (this->uses32BitSamplesClampedTo16Bit ? 3 : 2));
59
-	auto longBuffer = std::vector<uint8_t>(bufsize << 3);
60
-	auto bufLong = reinterpret_cast<int32_t *>(&longBuffer[0]);
61
+	auto trueBuffer = std::vector<std::uint8_t>(bufsize << (this->uses32BitSamplesClampedTo16Bit ? 3 : 2));
62
+	auto longBuffer = std::vector<std::uint8_t>(bufsize << 3);
63
+	auto bufLong = reinterpret_cast<std::int32_t *>(&longBuffer[0]);
61 64
 	while (pos < bufsize)
62 65
 	{
63 66
 		unsigned remain = bufsize - pos, offset = pos;
64 67
 		this->GenerateSamples(trueBuffer, pos << (this->uses32BitSamplesClampedTo16Bit ? 2 : 1), remain);
65 68
 		if (this->uses32BitSamplesClampedTo16Bit)
66 69
 		{
67
-			auto trueBufLong = reinterpret_cast<int32_t *>(&trueBuffer[0]);
70
+			auto trueBufLong = reinterpret_cast<std::int32_t *>(&trueBuffer[0]);
68 71
 			std::copy_n(&trueBufLong[0], bufsize << 1, &bufLong[0]);
69 72
 		}
70 73
 		else
71 74
 		{
72
-			auto trueBufShort = reinterpret_cast<int16_t *>(&trueBuffer[0]);
75
+			auto trueBufShort = reinterpret_cast<std::int16_t *>(&trueBuffer[0]);
73 76
 			std::copy_n(&trueBufShort[0], bufsize << 1, &bufLong[0]);
74 77
 		}
75 78
 		if (detectSilence || skipSilenceOnStartSec)
... ...
@@ -77,7 +80,7 @@ bool XSFPlayer::FillBuffer(std::vector<uint8_t> &buf, unsigned &samplesWritten)
77 80
 			unsigned skipOffset = 0;
78 81
 			for (unsigned ofs = 0; ofs < remain; ++ofs)
79 82
 			{
80
-				uint32_t sampleL = bufLong[2 * (offset + ofs)], sampleR = bufLong[2 * (offset + ofs) + 1];
83
+				std::uint32_t sampleL = bufLong[2 * (offset + ofs)], sampleR = bufLong[2 * (offset + ofs) + 1];
81 84
 				bool silence = (sampleL + CHECK_SILENCE_BIAS + CHECK_SILENCE_LEVEL) - this->prevSampleL <= CHECK_SILENCE_LEVEL * 2 &&
82 85
 					(sampleR + CHECK_SILENCE_BIAS + CHECK_SILENCE_LEVEL) - this->prevSampleR <= CHECK_SILENCE_LEVEL * 2;
83 86
 
... ...
@@ -114,7 +117,7 @@ bool XSFPlayer::FillBuffer(std::vector<uint8_t> &buf, unsigned &samplesWritten)
114 117
 			{
115 118
 				if (skipOffset)
116 119
 				{
117
-					auto tmpBuf = std::vector<int32_t>((bufsize - skipOffset) << 1);
120
+					auto tmpBuf = std::vector<std::int32_t>((bufsize - skipOffset) << 1);
118 121
 					std::copy(&bufLong[(offset + skipOffset) << 1], &bufLong[bufsize << 1], &tmpBuf[0]);
119 122
 					std::copy_n(&tmpBuf[0], (bufsize - skipOffset) << 1, &bufLong[offset << 1]);
120 123
 					pos += skipOffset;
... ...
@@ -129,12 +132,12 @@ bool XSFPlayer::FillBuffer(std::vector<uint8_t> &buf, unsigned &samplesWritten)
129 132
 		{
130 133
 			if (this->uses32BitSamplesClampedTo16Bit)
131 134
 			{
132
-				auto trueBufLong = reinterpret_cast<int32_t *>(&trueBuffer[0]);
135
+				auto trueBufLong = reinterpret_cast<std::int32_t *>(&trueBuffer[0]);
133 136
 				std::copy_n(&bufLong[0], bufsize << 1, &trueBufLong[0]);
134 137
 			}
135 138
 			else
136 139
 			{
137
-				auto trueBufShort = reinterpret_cast<int16_t *>(&trueBuffer[0]);
140
+				auto trueBufShort = reinterpret_cast<std::int16_t *>(&trueBuffer[0]);
138 141
 				std::copy_n(&bufLong[0], bufsize << 1, &trueBufShort[0]);
139 142
 			}
140 143
 		}
... ...
@@ -164,29 +167,29 @@ bool XSFPlayer::FillBuffer(std::vector<uint8_t> &buf, unsigned &samplesWritten)
164 167
 			double s1 = bufLong[2 * ofs] * scale, s2 = bufLong[2 * ofs + 1] * scale;
165 168
 			if (!this->uses32BitSamplesClampedTo16Bit)
166 169
 			{
167
-				clamp(s1, std::numeric_limits<int16_t>::min(), std::numeric_limits<int16_t>::max());
168
-				clamp(s2, std::numeric_limits<int16_t>::min(), std::numeric_limits<int16_t>::max());
170
+				clamp(s1, std::numeric_limits<std::int16_t>::min(), std::numeric_limits<std::int16_t>::max());
171
+				clamp(s2, std::numeric_limits<std::int16_t>::min(), std::numeric_limits<std::int16_t>::max());
169 172
 			}
170
-			bufLong[2 * ofs] = static_cast<int32_t>(s1);
171
-			bufLong[2 * ofs + 1] = static_cast<int32_t>(s2);
173
+			bufLong[2 * ofs] = static_cast<std::int32_t>(s1);
174
+			bufLong[2 * ofs + 1] = static_cast<std::int32_t>(s2);
172 175
 		}
173 176
 	}
174 177
 
175 178
 	if (this->uses32BitSamplesClampedTo16Bit)
176 179
 	{
177
-		auto bufShort = reinterpret_cast<int16_t *>(&buf[0]);
180
+		auto bufShort = reinterpret_cast<std::int16_t *>(&buf[0]);
178 181
 		for (unsigned ofs = 0; ofs < bufsize; ++ofs)
179 182
 		{
180
-			int32_t s1 = bufLong[2 * ofs], s2 = bufLong[2 * ofs + 1];
181
-			clamp(s1, std::numeric_limits<int16_t>::min(), std::numeric_limits<int16_t>::max());
182
-			clamp(s2, std::numeric_limits<int16_t>::min(), std::numeric_limits<int16_t>::max());
183
-			bufShort[2 * ofs] = static_cast<int16_t>(s1);
184
-			bufShort[2 * ofs + 1] = static_cast<int16_t>(s2);
183
+			std::int32_t s1 = bufLong[2 * ofs], s2 = bufLong[2 * ofs + 1];
184
+			clamp(s1, std::numeric_limits<std::int16_t>::min(), std::numeric_limits<std::int16_t>::max());
185
+			clamp(s2, std::numeric_limits<std::int16_t>::min(), std::numeric_limits<std::int16_t>::max());
186
+			bufShort[2 * ofs] = static_cast<std::int16_t>(s1);
187
+			bufShort[2 * ofs + 1] = static_cast<std::int16_t>(s2);
185 188
 		}
186 189
 	}
187 190
 	else
188 191
 	{
189
-		auto trueBufShort = reinterpret_cast<int16_t *>(&trueBuffer[0]);
192
+		auto trueBufShort = reinterpret_cast<std::int16_t *>(&trueBuffer[0]);
190 193
 		std::copy_n(&bufLong[0], bufsize << 1, &trueBufShort[0]);
191 194
 		std::copy(&trueBuffer[0], &trueBuffer[bufsize << 2], &buf[0]);
192 195
 	}
... ...
@@ -194,12 +197,12 @@ bool XSFPlayer::FillBuffer(std::vector<uint8_t> &buf, unsigned &samplesWritten)
194 197
 	/* Fading */
195 198
 	if (!xSFConfig->GetPlayInfinitely() && this->fadeSample && this->currentSample + bufsize >= this->lengthSample)
196 199
 	{
197
-		auto bufShort = reinterpret_cast<int16_t *>(&buf[0]);
200
+		auto bufShort = reinterpret_cast<std::int16_t *>(&buf[0]);
198 201
 		for (unsigned ofs = 0; ofs < bufsize; ++ofs)
199 202
 		{
200 203
 			if (this->currentSample + ofs >= this->lengthSample && this->currentSample + ofs < this->lengthSample + this->fadeSample)
201 204
 			{
202
-				int scale = static_cast<uint64_t>(this->lengthSample + this->fadeSample - (this->currentSample + ofs)) * 0x10000 / this->fadeSample;
205
+				int scale = static_cast<std::uint64_t>(this->lengthSample + this->fadeSample - (this->currentSample + ofs)) * 0x10000 / this->fadeSample;
203 206
 				bufShort[2 * ofs] = (bufShort[2 * ofs] * scale) >> 16;
204 207
 				bufShort[2 * ofs + 1] = (bufShort[2 * ofs + 1] * scale) >> 16;
205 208
 			}
... ...
@@ -217,8 +220,8 @@ bool XSFPlayer::Load()
217 220
 {
218 221
 	this->lengthInMS = this->xSF->GetLengthMS(xSFConfig->GetDefaultLength());
219 222
 	this->fadeInMS = this->xSF->GetFadeMS(xSFConfig->GetDefaultFade());
220
-	this->lengthSample = static_cast<uint64_t>(this->lengthInMS) * this->sampleRate / 1000;
221
-	this->fadeSample = static_cast<uint64_t>(this->fadeInMS) * this->sampleRate / 1000;
223
+	this->lengthSample = static_cast<std::uint64_t>(this->lengthInMS) * this->sampleRate / 1000;
224
+	this->fadeSample = static_cast<std::uint64_t>(this->fadeInMS) * this->sampleRate / 1000;
222 225
 	this->volume = this->xSF->GetVolume(xSFConfig->GetVolumeType(), xSFConfig->GetPeakType());
223 226
 	return true;
224 227
 }
... ...
@@ -233,9 +236,9 @@ void XSFPlayer::SeekTop()
233 236
 #ifdef WINAMP_PLUGIN
234 237
 static inline DWORD TicksDiff(DWORD prev, DWORD cur) { return cur >= prev ? cur - prev : 0xFFFFFFFF - prev + cur; }
235 238
 
236
-int XSFPlayer::Seek(unsigned seekPosition, volatile int *killswitch, std::vector<uint8_t> &buf, Out_Module *outMod)
239
+int XSFPlayer::Seek(unsigned seekPosition, volatile int *killswitch, std::vector<std::uint8_t> &buf, Out_Module *outMod)
237 240
 {
238
-	unsigned bufsize = buf.size() >> 2, seekSample = static_cast<uint64_t>(seekPosition) * this->sampleRate / 1000;
241
+	unsigned bufsize = buf.size() >> 2, seekSample = static_cast<std::uint64_t>(seekPosition) * this->sampleRate / 1000;
239 242
 	DWORD prevTick = outMod ? GetTickCount() : 0;
240 243
 	if (seekSample < this->currentSample)
241 244
 	{
... ...
@@ -253,7 +256,7 @@ int XSFPlayer::Seek(unsigned seekPosition, volatile int *killswitch, std::vector
253 256
 			if (TicksDiff(prevTick, curTick) >= 500)
254 257
 			{
255 258
 				prevTick = curTick;
256
-				unsigned cur = static_cast<uint64_t>(this->currentSample) * 1000 / this->sampleRate;
259
+				unsigned cur = static_cast<std::uint64_t>(this->currentSample) * 1000 / this->sampleRate;
257 260
 				outMod->Flush(cur);
258 261
 			}
259 262
 		}
Browse code

Remove last modification date from files.

(I never remember to update these and besides, GitHub history can show when they were last modified.)

Naram Qashat authored on 2021/03/19 10:58:12
Showing 1 changed files
... ...
@@ -1,7 +1,6 @@
1 1
 /*
2 2
  * xSF - Core Player
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2014-09-24
5 4
  *
6 5
  * Partially based on the vio*sf framework
7 6
  */
Browse code

Lots of changes in regards to strings, as follows:

* Removed my custom String class, as well as removed the really old
Unicode ConvertUTF, the UTF Converter, and the UTF Encode/Decode
functions.
* Replaced the above with using standard C++ std::wstring_convert and
std::codecvt_utf8.
* Added headers adapted from llvm's libc++ project for allowing the
above C++ classes to exist with GCC and Clang when libc++ isn't being
used.
* Used std::string over std::wstring whenever possible.
* Added header adapted from llvm's libc++ project to create special
versions of the ifstream and ofstream classes that would utilize _wfopen
on non-MSVC Windows compilers, so those compilers could access files on
Windows that use characters outside the current codepage.
* Removed the -static-libgcc and -static-libstdc++ flags from the
Makefile for non-MSVC builds. The generated DLLs will require extra DLLs
from either Cygwin or MinGW (whichever is used to compile), I've only
tested with MinGW and for some reason they crash Winamp on exit, I have
no idea why.

Naram Qashat authored on 2014/09/24 13:58:55
Showing 1 changed files
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * xSF - Core Player
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2014-09-08
4
+ * Last modification on 2014-09-24
5 5
  *
6 6
  * Partially based on the vio*sf framework
7 7
  */
Browse code

Use std::copy_n/std::fill_n instead of std::copy/std::fill where possible.

Naram Qashat authored on 2014/09/08 16:52:49
Showing 1 changed files
... ...
@@ -66,12 +66,12 @@ bool XSFPlayer::FillBuffer(std::vector<uint8_t> &buf, unsigned &samplesWritten)
66 66
 		if (this->uses32BitSamplesClampedTo16Bit)
67 67
 		{
68 68
 			auto trueBufLong = reinterpret_cast<int32_t *>(&trueBuffer[0]);
69
-			std::copy(&trueBufLong[0], &trueBufLong[bufsize << 1], &bufLong[0]);
69
+			std::copy_n(&trueBufLong[0], bufsize << 1, &bufLong[0]);
70 70
 		}
71 71
 		else
72 72
 		{
73 73
 			auto trueBufShort = reinterpret_cast<int16_t *>(&trueBuffer[0]);
74
-			std::copy(&trueBufShort[0], &trueBufShort[bufsize << 1], &bufLong[0]);
74
+			std::copy_n(&trueBufShort[0], bufsize << 1, &bufLong[0]);
75 75
 		}
76 76
 		if (detectSilence || skipSilenceOnStartSec)
77 77
 		{
... ...
@@ -117,7 +117,7 @@ bool XSFPlayer::FillBuffer(std::vector<uint8_t> &buf, unsigned &samplesWritten)
117 117
 				{
118 118
 					auto tmpBuf = std::vector<int32_t>((bufsize - skipOffset) << 1);
119 119
 					std::copy(&bufLong[(offset + skipOffset) << 1], &bufLong[bufsize << 1], &tmpBuf[0]);
120
-					std::copy(&tmpBuf[0], &tmpBuf[(bufsize - skipOffset) << 1], &bufLong[offset << 1]);
120
+					std::copy_n(&tmpBuf[0], (bufsize - skipOffset) << 1, &bufLong[offset << 1]);
121 121
 					pos += skipOffset;
122 122
 				}
123 123
 				else
... ...
@@ -131,12 +131,12 @@ bool XSFPlayer::FillBuffer(std::vector<uint8_t> &buf, unsigned &samplesWritten)
131 131
 			if (this->uses32BitSamplesClampedTo16Bit)
132 132
 			{
133 133
 				auto trueBufLong = reinterpret_cast<int32_t *>(&trueBuffer[0]);
134
-				std::copy(&bufLong[0], &bufLong[bufsize << 1], &trueBufLong[0]);
134
+				std::copy_n(&bufLong[0], bufsize << 1, &trueBufLong[0]);
135 135
 			}
136 136
 			else
137 137
 			{
138 138
 				auto trueBufShort = reinterpret_cast<int16_t *>(&trueBuffer[0]);
139
-				std::copy(&bufLong[0], &bufLong[bufsize << 1], &trueBufShort[0]);
139
+				std::copy_n(&bufLong[0], bufsize << 1, &trueBufShort[0]);
140 140
 			}
141 141
 		}
142 142
 	}
... ...
@@ -188,7 +188,7 @@ bool XSFPlayer::FillBuffer(std::vector<uint8_t> &buf, unsigned &samplesWritten)
188 188
 	else
189 189
 	{
190 190
 		auto trueBufShort = reinterpret_cast<int16_t *>(&trueBuffer[0]);
191
-		std::copy(&bufLong[0], &bufLong[bufsize << 1], &trueBufShort[0]);
191
+		std::copy_n(&bufLong[0], bufsize << 1, &trueBufShort[0]);
192 192
 		std::copy(&trueBuffer[0], &trueBuffer[bufsize << 2], &buf[0]);
193 193
 	}
194 194
 
Browse code

Minor cleanups in the framework.

Naram Qashat authored on 2014/09/08 15:06:52
Showing 1 changed files
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * xSF - Core Player
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2013-05-07
4
+ * Last modification on 2014-09-08
5 5
  *
6 6
  * Partially based on the vio*sf framework
7 7
  */
... ...
@@ -56,25 +56,21 @@ bool XSFPlayer::FillBuffer(std::vector<uint8_t> &buf, unsigned &samplesWritten)
56 56
 	bool endFlag = false;
57 57
 	unsigned detectSilence = xSFConfig->GetDetectSilenceSec();
58 58
 	unsigned pos = 0, bufsize = buf.size() >> 2;
59
-	std::vector<uint8_t> trueBuffer;
60
-	if (this->uses32BitSamplesClampedTo16Bit)
61
-		trueBuffer.resize(bufsize << 3);
62
-	else
63
-		trueBuffer.resize(bufsize << 2);
59
+	auto trueBuffer = std::vector<uint8_t>(bufsize << (this->uses32BitSamplesClampedTo16Bit ? 3 : 2));
64 60
 	auto longBuffer = std::vector<uint8_t>(bufsize << 3);
65
-	int32_t *bufLong = reinterpret_cast<int32_t *>(&longBuffer[0]);
61
+	auto bufLong = reinterpret_cast<int32_t *>(&longBuffer[0]);
66 62
 	while (pos < bufsize)
67 63
 	{
68 64
 		unsigned remain = bufsize - pos, offset = pos;
69 65
 		this->GenerateSamples(trueBuffer, pos << (this->uses32BitSamplesClampedTo16Bit ? 2 : 1), remain);
70 66
 		if (this->uses32BitSamplesClampedTo16Bit)
71 67
 		{
72
-			int32_t *trueBufLong = reinterpret_cast<int32_t *>(&trueBuffer[0]);
68
+			auto trueBufLong = reinterpret_cast<int32_t *>(&trueBuffer[0]);
73 69
 			std::copy(&trueBufLong[0], &trueBufLong[bufsize << 1], &bufLong[0]);
74 70
 		}
75 71
 		else
76 72
 		{
77
-			int16_t *trueBufShort = reinterpret_cast<int16_t *>(&trueBuffer[0]);
73
+			auto trueBufShort = reinterpret_cast<int16_t *>(&trueBuffer[0]);
78 74
 			std::copy(&trueBufShort[0], &trueBufShort[bufsize << 1], &bufLong[0]);
79 75
 		}
80 76
 		if (detectSilence || skipSilenceOnStartSec)
... ...
@@ -134,12 +130,12 @@ bool XSFPlayer::FillBuffer(std::vector<uint8_t> &buf, unsigned &samplesWritten)
134 130
 		{
135 131
 			if (this->uses32BitSamplesClampedTo16Bit)
136 132
 			{
137
-				int32_t *trueBufLong = reinterpret_cast<int32_t *>(&trueBuffer[0]);
133
+				auto trueBufLong = reinterpret_cast<int32_t *>(&trueBuffer[0]);
138 134
 				std::copy(&bufLong[0], &bufLong[bufsize << 1], &trueBufLong[0]);
139 135
 			}
140 136
 			else
141 137
 			{
142
-				int16_t *trueBufShort = reinterpret_cast<int16_t *>(&trueBuffer[0]);
138
+				auto trueBufShort = reinterpret_cast<int16_t *>(&trueBuffer[0]);
143 139
 				std::copy(&bufLong[0], &bufLong[bufsize << 1], &trueBufShort[0]);
144 140
 			}
145 141
 		}
... ...
@@ -179,7 +175,7 @@ bool XSFPlayer::FillBuffer(std::vector<uint8_t> &buf, unsigned &samplesWritten)
179 175
 
180 176
 	if (this->uses32BitSamplesClampedTo16Bit)
181 177
 	{
182
-		int16_t *bufShort = reinterpret_cast<int16_t *>(&buf[0]);
178
+		auto bufShort = reinterpret_cast<int16_t *>(&buf[0]);
183 179
 		for (unsigned ofs = 0; ofs < bufsize; ++ofs)
184 180
 		{
185 181
 			int32_t s1 = bufLong[2 * ofs], s2 = bufLong[2 * ofs + 1];
... ...
@@ -191,7 +187,7 @@ bool XSFPlayer::FillBuffer(std::vector<uint8_t> &buf, unsigned &samplesWritten)
191 187
 	}
192 188
 	else
193 189
 	{
194
-		int16_t *trueBufShort = reinterpret_cast<int16_t *>(&trueBuffer[0]);
190
+		auto trueBufShort = reinterpret_cast<int16_t *>(&trueBuffer[0]);
195 191
 		std::copy(&bufLong[0], &bufLong[bufsize << 1], &trueBufShort[0]);
196 192
 		std::copy(&trueBuffer[0], &trueBuffer[bufsize << 2], &buf[0]);
197 193
 	}
... ...
@@ -199,7 +195,7 @@ bool XSFPlayer::FillBuffer(std::vector<uint8_t> &buf, unsigned &samplesWritten)
199 195
 	/* Fading */
200 196
 	if (!xSFConfig->GetPlayInfinitely() && this->fadeSample && this->currentSample + bufsize >= this->lengthSample)
201 197
 	{
202
-		int16_t *bufShort = reinterpret_cast<int16_t *>(&buf[0]);
198
+		auto bufShort = reinterpret_cast<int16_t *>(&buf[0]);
203 199
 		for (unsigned ofs = 0; ofs < bufsize; ++ofs)
204 200
 		{
205 201
 			if (this->currentSample + ofs >= this->lengthSample && this->currentSample + ofs < this->lengthSample + this->fadeSample)
Browse code

* Replaced Lanczos window with Hann window for the windowed sinc function in the NCSF plugin. * Added a ring buffer specifically designed for working with SWAVs to replace the one provided by kode54, still have to give him thanks for the original though. * Fixed clipping issue caused by invalid clamping values. * Minor fix to using the min()/max() functions of numeric_limits because Winamp's out.h includes windows.h without my specific wrapper to redefine things.

Naram Qashat authored on 2013/05/07 05:42:46
Showing 1 changed files
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * xSF - Core Player
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2013-04-26
4
+ * Last modification on 2013-05-07
5 5
  *
6 6
  * Partially based on the vio*sf framework
7 7
  */
... ...
@@ -169,8 +169,8 @@ bool XSFPlayer::FillBuffer(std::vector<uint8_t> &buf, unsigned &samplesWritten)
169 169
 			double s1 = bufLong[2 * ofs] * scale, s2 = bufLong[2 * ofs + 1] * scale;
170 170
 			if (!this->uses32BitSamplesClampedTo16Bit)
171 171
 			{
172
-				clamp(s1, -0x7FFF, 0x8000);
173
-				clamp(s2, -0x7FFF, 0x8000);
172
+				clamp(s1, std::numeric_limits<int16_t>::min(), std::numeric_limits<int16_t>::max());
173
+				clamp(s2, std::numeric_limits<int16_t>::min(), std::numeric_limits<int16_t>::max());
174 174
 			}
175 175
 			bufLong[2 * ofs] = static_cast<int32_t>(s1);
176 176
 			bufLong[2 * ofs + 1] = static_cast<int32_t>(s2);
... ...
@@ -183,8 +183,8 @@ bool XSFPlayer::FillBuffer(std::vector<uint8_t> &buf, unsigned &samplesWritten)
183 183
 		for (unsigned ofs = 0; ofs < bufsize; ++ofs)
184 184
 		{
185 185
 			int32_t s1 = bufLong[2 * ofs], s2 = bufLong[2 * ofs + 1];
186
-			clamp(s1, -0x7FFF, 0x8000);
187
-			clamp(s2, -0x7FFF, 0x8000);
186
+			clamp(s1, std::numeric_limits<int16_t>::min(), std::numeric_limits<int16_t>::max());
187
+			clamp(s2, std::numeric_limits<int16_t>::min(), std::numeric_limits<int16_t>::max());
188 188
 			bufShort[2 * ofs] = static_cast<int16_t>(s1);
189 189
 			bufShort[2 * ofs + 1] = static_cast<int16_t>(s2);
190 190
 		}
Browse code

Fixed up the Lanczos interpolation in NCSF (thanks to kode54), also allowed the NCSF plugin to use 32-bit samples in it's GenerateSamples function.

Naram Qashat authored on 2013/04/26 00:54:28
Showing 1 changed files
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * xSF - Core Player
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2013-04-23
4
+ * Last modification on 2013-04-26
5 5
  *
6 6
  * Partially based on the vio*sf framework
7 7
  */
... ...
@@ -14,13 +14,14 @@
14 14
 extern XSFConfig *xSFConfig;
15 15
 
16 16
 XSFPlayer::XSFPlayer() : xSF(), sampleRate(0), detectedSilenceSample(0), detectedSilenceSec(0), skipSilenceOnStartSec(5), lengthSample(0), fadeSample(0), currentSample(0),
17
-	prevSampleL(CHECK_SILENCE_BIAS), prevSampleR(CHECK_SILENCE_BIAS), lengthInMS(-1), fadeInMS(-1), volume(1.0), ignoreVolume(false)
17
+	prevSampleL(CHECK_SILENCE_BIAS), prevSampleR(CHECK_SILENCE_BIAS), lengthInMS(-1), fadeInMS(-1), volume(1.0), ignoreVolume(false), uses32BitSamplesClampedTo16Bit(false)
18 18
 {
19 19
 }
20 20
 
21 21
 XSFPlayer::XSFPlayer(const XSFPlayer &xSFPlayer) : xSF(new XSFFile()), sampleRate(xSFPlayer.sampleRate), detectedSilenceSample(xSFPlayer.detectedSilenceSample), detectedSilenceSec(xSFPlayer.detectedSilenceSec),
22 22
 	skipSilenceOnStartSec(xSFPlayer.skipSilenceOnStartSec), lengthSample(xSFPlayer.lengthSample), fadeSample(xSFPlayer.fadeSample), currentSample(xSFPlayer.currentSample), prevSampleL(xSFPlayer.prevSampleL),
23
-	prevSampleR(xSFPlayer.prevSampleR), lengthInMS(xSFPlayer.lengthInMS), fadeInMS(xSFPlayer.fadeInMS), volume(xSFPlayer.volume), ignoreVolume(xSFPlayer.ignoreVolume)
23
+	prevSampleR(xSFPlayer.prevSampleR), lengthInMS(xSFPlayer.lengthInMS), fadeInMS(xSFPlayer.fadeInMS), volume(xSFPlayer.volume), ignoreVolume(xSFPlayer.ignoreVolume),
24
+	uses32BitSamplesClampedTo16Bit(xSFPlayer.uses32BitSamplesClampedTo16Bit)
24 25
 {
25 26
 	*this->xSF = *xSFPlayer.xSF;
26 27
 }
... ...
@@ -45,6 +46,7 @@ XSFPlayer &XSFPlayer::operator=(const XSFPlayer &xSFPlayer)
45 46
 		this->fadeInMS = xSFPlayer.fadeInMS;
46 47
 		this->volume = xSFPlayer.volume;
47 48
 		this->ignoreVolume = xSFPlayer.ignoreVolume;
49
+		this->uses32BitSamplesClampedTo16Bit = xSFPlayer.uses32BitSamplesClampedTo16Bit;
48 50
 	}
49 51
 	return *this;
50 52
 }
... ...
@@ -54,17 +56,33 @@ bool XSFPlayer::FillBuffer(std::vector<uint8_t> &buf, unsigned &samplesWritten)
54 56
 	bool endFlag = false;
55 57
 	unsigned detectSilence = xSFConfig->GetDetectSilenceSec();
56 58
 	unsigned pos = 0, bufsize = buf.size() >> 2;
59
+	std::vector<uint8_t> trueBuffer;
60
+	if (this->uses32BitSamplesClampedTo16Bit)
61
+		trueBuffer.resize(bufsize << 3);
62
+	else
63
+		trueBuffer.resize(bufsize << 2);
64
+	auto longBuffer = std::vector<uint8_t>(bufsize << 3);
65
+	int32_t *bufLong = reinterpret_cast<int32_t *>(&longBuffer[0]);
57 66
 	while (pos < bufsize)
58 67
 	{
59 68
 		unsigned remain = bufsize - pos, offset = pos;
60
-		this->GenerateSamples(buf, pos << 1, remain);
69
+		this->GenerateSamples(trueBuffer, pos << (this->uses32BitSamplesClampedTo16Bit ? 2 : 1), remain);
70
+		if (this->uses32BitSamplesClampedTo16Bit)
71
+		{
72
+			int32_t *trueBufLong = reinterpret_cast<int32_t *>(&trueBuffer[0]);
73
+			std::copy(&trueBufLong[0], &trueBufLong[bufsize << 1], &bufLong[0]);
74
+		}
75
+		else
76
+		{
77
+			int16_t *trueBufShort = reinterpret_cast<int16_t *>(&trueBuffer[0]);
78
+			std::copy(&trueBufShort[0], &trueBufShort[bufsize << 1], &bufLong[0]);
79
+		}
61 80
 		if (detectSilence || skipSilenceOnStartSec)
62 81
 		{
63 82
 			unsigned skipOffset = 0;
64 83
 			for (unsigned ofs = 0; ofs < remain; ++ofs)
65 84
 			{
66
-				short *bufShort = reinterpret_cast<short *>(&buf[0]);
67
-				unsigned long sampleL = bufShort[2 * (offset + ofs)], sampleR = bufShort[2 * (offset + ofs) + 1];
85
+				uint32_t sampleL = bufLong[2 * (offset + ofs)], sampleR = bufLong[2 * (offset + ofs) + 1];
68 86
 				bool silence = (sampleL + CHECK_SILENCE_BIAS + CHECK_SILENCE_LEVEL) - this->prevSampleL <= CHECK_SILENCE_LEVEL * 2 &&
69 87
 					(sampleR + CHECK_SILENCE_BIAS + CHECK_SILENCE_LEVEL) - this->prevSampleR <= CHECK_SILENCE_LEVEL * 2;
70 88
 
... ...
@@ -101,9 +119,9 @@ bool XSFPlayer::FillBuffer(std::vector<uint8_t> &buf, unsigned &samplesWritten)
101 119
 			{
102 120
 				if (skipOffset)
103 121
 				{
104
-					auto tmpBuf = std::vector<uint8_t>(2 * skipOffset);
105
-					memcpy(&tmpBuf[0], &buf[offset + 2 * skipOffset], 2 * skipOffset);
106
-					memcpy(&buf[offset], &tmpBuf[0], 2 * skipOffset);
122
+					auto tmpBuf = std::vector<int32_t>((bufsize - skipOffset) << 1);
123
+					std::copy(&bufLong[(offset + skipOffset) << 1], &bufLong[bufsize << 1], &tmpBuf[0]);
124
+					std::copy(&tmpBuf[0], &tmpBuf[(bufsize - skipOffset) << 1], &bufLong[offset << 1]);
107 125
 					pos += skipOffset;
108 126
 				}
109 127
 				else
... ...
@@ -112,6 +130,19 @@ bool XSFPlayer::FillBuffer(std::vector<uint8_t> &buf, unsigned &samplesWritten)
112 130
 		}
113 131
 		else
114 132
 			pos += remain;
133
+		if (pos < bufsize)
134
+		{
135
+			if (this->uses32BitSamplesClampedTo16Bit)
136
+			{
137
+				int32_t *trueBufLong = reinterpret_cast<int32_t *>(&trueBuffer[0]);
138
+				std::copy(&bufLong[0], &bufLong[bufsize << 1], &trueBufLong[0]);
139
+			}
140
+			else
141
+			{
142
+				int16_t *trueBufShort = reinterpret_cast<int16_t *>(&trueBuffer[0]);
143
+				std::copy(&bufLong[0], &bufLong[bufsize << 1], &trueBufShort[0]);
144
+			}
145
+		}
115 146
 	}
116 147
 
117 148
 	/* Detect end of song */
... ...
@@ -133,27 +164,42 @@ bool XSFPlayer::FillBuffer(std::vector<uint8_t> &buf, unsigned &samplesWritten)
133 164
 	if (!this->ignoreVolume && (!fEqual(this->volume, 1.0) || !fEqual(xSFConfig->GetVolume(), 1.0)))
134 165
 	{
135 166
 		double scale = this->volume * xSFConfig->GetVolume();
136
-		short *bufShort = reinterpret_cast<short *>(&buf[0]);
137 167
 		for (unsigned ofs = 0; ofs < bufsize; ++ofs)
138 168
 		{
139
-			double s1 = bufShort[2 * ofs] * scale, s2 = bufShort[2 * ofs + 1] * scale;
140
-			if (s1 > 0x7FFF)
141
-				s1 = 0x7FFF;
142
-			else if (s1 < -0x8000)
143
-				s1 = -0x8000;
144
-			if (s2 > 0x7FFF)
145
-				s2 = 0x7FFF;
146
-			else if (s2 < -0x8000)
147
-				s2 = -0x8000;
148
-			bufShort[2 * ofs] = static_cast<short>(s1);
149
-			bufShort[2 * ofs + 1] = static_cast<short>(s2);
169
+			double s1 = bufLong[2 * ofs] * scale, s2 = bufLong[2 * ofs + 1] * scale;
170
+			if (!this->uses32BitSamplesClampedTo16Bit)
171
+			{
172
+				clamp(s1, -0x7FFF, 0x8000);
173
+				clamp(s2, -0x7FFF, 0x8000);
174
+			}
175
+			bufLong[2 * ofs] = static_cast<int32_t>(s1);
176
+			bufLong[2 * ofs + 1] = static_cast<int32_t>(s2);
177
+		}
178
+	}
179
+
180
+	if (this->uses32BitSamplesClampedTo16Bit)
181
+	{
182
+		int16_t *bufShort = reinterpret_cast<int16_t *>(&buf[0]);
183
+		for (unsigned ofs = 0; ofs < bufsize; ++ofs)
184
+		{
185
+			int32_t s1 = bufLong[2 * ofs], s2 = bufLong[2 * ofs + 1];
186
+			clamp(s1, -0x7FFF, 0x8000);
187
+			clamp(s2, -0x7FFF, 0x8000);
188
+			bufShort[2 * ofs] = static_cast<int16_t>(s1);
189
+			bufShort[2 * ofs + 1] = static_cast<int16_t>(s2);
150 190
 		}
151 191
 	}
192
+	else
193
+	{
194
+		int16_t *trueBufShort = reinterpret_cast<int16_t *>(&trueBuffer[0]);
195
+		std::copy(&bufLong[0], &bufLong[bufsize << 1], &trueBufShort[0]);
196
+		std::copy(&trueBuffer[0], &trueBuffer[bufsize << 2], &buf[0]);
197
+	}
152 198
 
153 199
 	/* Fading */
154 200
 	if (!xSFConfig->GetPlayInfinitely() && this->fadeSample && this->currentSample + bufsize >= this->lengthSample)
155 201
 	{
156
-		short *bufShort = reinterpret_cast<short *>(&buf[0]);
202
+		int16_t *bufShort = reinterpret_cast<int16_t *>(&buf[0]);
157 203
 		for (unsigned ofs = 0; ofs < bufsize; ++ofs)
158 204
 		{
159 205
 			if (this->currentSample + ofs >= this->lengthSample && this->currentSample + ofs < this->lengthSample + this->fadeSample)
Browse code

Added Lanczos interpolation to the NCSF plugin, and cleaned up a bit of the other code, as well as removing pstdint.h since it's no longer needed.

Naram Qashat authored on 2013/04/23 20:29:21
Showing 1 changed files
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * xSF - Core Player
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2013-03-30
4
+ * Last modification on 2013-04-23
5 5
  *
6 6
  * Partially based on the vio*sf framework
7 7
  */
... ...
@@ -13,8 +13,8 @@
13 13
 
14 14
 extern XSFConfig *xSFConfig;
15 15
 
16
-XSFPlayer::XSFPlayer() : xSF(nullptr), sampleRate(0), detectedSilenceSample(0), detectedSilenceSec(0), skipSilenceOnStartSec(5), lengthSample(0), fadeSample(0), currentSample(0),
17
-	prevSampleL(XSFPlayer::CHECK_SILENCE_BIAS), prevSampleR(XSFPlayer::CHECK_SILENCE_BIAS), lengthInMS(-1), fadeInMS(-1), volume(1.0), ignoreVolume(false)
16
+XSFPlayer::XSFPlayer() : xSF(), sampleRate(0), detectedSilenceSample(0), detectedSilenceSec(0), skipSilenceOnStartSec(5), lengthSample(0), fadeSample(0), currentSample(0),
17
+	prevSampleL(CHECK_SILENCE_BIAS), prevSampleR(CHECK_SILENCE_BIAS), lengthInMS(-1), fadeInMS(-1), volume(1.0), ignoreVolume(false)
18 18
 {
19 19
 }
20 20
 
... ...
@@ -30,7 +30,7 @@ XSFPlayer &XSFPlayer::operator=(const XSFPlayer &xSFPlayer)
30 30
 	if (this != &xSFPlayer)
31 31
 	{
32 32
 		if (!this->xSF)
33
-			this->xSF = new XSFFile();
33
+			this->xSF.reset(new XSFFile());
34 34
 		*this->xSF = *xSFPlayer.xSF;
35 35
 		this->sampleRate = xSFPlayer.sampleRate;
36 36
 		this->detectedSilenceSample = xSFPlayer.detectedSilenceSample;
... ...
@@ -65,8 +65,8 @@ bool XSFPlayer::FillBuffer(std::vector<uint8_t> &buf, unsigned &samplesWritten)
65 65
 			{
66 66
 				short *bufShort = reinterpret_cast<short *>(&buf[0]);
67 67
 				unsigned long sampleL = bufShort[2 * (offset + ofs)], sampleR = bufShort[2 * (offset + ofs) + 1];
68
-				bool silence = (sampleL + XSFPlayer::CHECK_SILENCE_BIAS + XSFPlayer::CHECK_SILENCE_LEVEL) - this->prevSampleL <= XSFPlayer::CHECK_SILENCE_LEVEL * 2 &&
69
-					(sampleR + XSFPlayer::CHECK_SILENCE_BIAS + XSFPlayer::CHECK_SILENCE_LEVEL) - this->prevSampleR <= XSFPlayer::CHECK_SILENCE_LEVEL * 2;
68
+				bool silence = (sampleL + CHECK_SILENCE_BIAS + CHECK_SILENCE_LEVEL) - this->prevSampleL <= CHECK_SILENCE_LEVEL * 2 &&
69
+					(sampleR + CHECK_SILENCE_BIAS + CHECK_SILENCE_LEVEL) - this->prevSampleR <= CHECK_SILENCE_LEVEL * 2;
70 70
 
71 71
 				if (silence)
72 72
 				{
... ...
@@ -93,15 +93,15 @@ bool XSFPlayer::FillBuffer(std::vector<uint8_t> &buf, unsigned &samplesWritten)
93 93
 					}
94 94
 				}
95 95
 
96
-				prevSampleL = sampleL + XSFPlayer::CHECK_SILENCE_BIAS;
97
-				prevSampleR = sampleR + XSFPlayer::CHECK_SILENCE_BIAS;
96
+				prevSampleL = sampleL + CHECK_SILENCE_BIAS;
97
+				prevSampleR = sampleR + CHECK_SILENCE_BIAS;
98 98
 			}
99 99
 
100 100
 			if (!this->skipSilenceOnStartSec)
101 101
 			{
102 102
 				if (skipOffset)
103 103
 				{
104
-					std::vector<uint8_t> tmpBuf = std::vector<uint8_t>(2 * skipOffset);
104
+					auto tmpBuf = std::vector<uint8_t>(2 * skipOffset);
105 105
 					memcpy(&tmpBuf[0], &buf[offset + 2 * skipOffset], 2 * skipOffset);
106 106
 					memcpy(&buf[offset], &tmpBuf[0], 2 * skipOffset);
107 107
 					pos += skipOffset;
... ...
@@ -186,11 +186,10 @@ void XSFPlayer::SeekTop()
186 186
 {
187 187
 	this->skipSilenceOnStartSec = xSFConfig->GetSkipSilenceOnStartSec();
188 188
 	this->currentSample = this->detectedSilenceSec = this->detectedSilenceSample = 0;
189
-	this->prevSampleL = this->prevSampleR = XSFPlayer::CHECK_SILENCE_BIAS;
189
+	this->prevSampleL = this->prevSampleR = CHECK_SILENCE_BIAS;
190 190
 }
191 191
 
192 192
 #ifdef WINAMP_PLUGIN
193
-
194 193
 static inline DWORD TicksDiff(DWORD prev, DWORD cur) { return cur >= prev ? cur - prev : 0xFFFFFFFF - prev + cur; }
195 194
 
196 195
 int XSFPlayer::Seek(unsigned seekPosition, volatile int *killswitch, std::vector<uint8_t> &buf, Out_Module *outMod)
... ...
@@ -229,5 +228,4 @@ int XSFPlayer::Seek(unsigned seekPosition, volatile int *killswitch, std::vector
229 228
 		outMod->Flush(seekPosition);
230 229
 	return 0;
231 230
 }
232
-
233 231
 #endif
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
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * xSF - Core Player
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2013-03-21
4
+ * Last modification on 2013-03-30
5 5
  *
6 6
  * Partially based on the vio*sf framework
7 7
  */
... ...
@@ -13,7 +13,7 @@
13 13
 
14 14
 extern XSFConfig *xSFConfig;
15 15
 
16
-XSFPlayer::XSFPlayer() : xSF(NULL), sampleRate(0), detectedSilenceSample(0), detectedSilenceSec(0), skipSilenceOnStartSec(5), lengthSample(0), fadeSample(0), currentSample(0),
16
+XSFPlayer::XSFPlayer() : xSF(nullptr), sampleRate(0), detectedSilenceSample(0), detectedSilenceSec(0), skipSilenceOnStartSec(5), lengthSample(0), fadeSample(0), currentSample(0),
17 17
 	prevSampleL(XSFPlayer::CHECK_SILENCE_BIAS), prevSampleR(XSFPlayer::CHECK_SILENCE_BIAS), lengthInMS(-1), fadeInMS(-1), volume(1.0), ignoreVolume(false)
18 18
 {
19 19
 }
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,233 @@
1
+/*
2
+ * xSF - Core Player
3
+ * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
+ * Last modification on 2013-03-21
5
+ *
6
+ * Partially based on the vio*sf framework
7
+ */
8
+
9
+#include <cstring>
10
+#include "XSFPlayer.h"
11
+#include "XSFConfig.h"
12
+#include "XSFCommon.h"
13
+
14
+extern XSFConfig *xSFConfig;
15
+
16
+XSFPlayer::XSFPlayer() : xSF(NULL), sampleRate(0), detectedSilenceSample(0), detectedSilenceSec(0), skipSilenceOnStartSec(5), lengthSample(0), fadeSample(0), currentSample(0),
17
+	prevSampleL(XSFPlayer::CHECK_SILENCE_BIAS), prevSampleR(XSFPlayer::CHECK_SILENCE_BIAS), lengthInMS(-1), fadeInMS(-1), volume(1.0), ignoreVolume(false)
18
+{
19
+}
20
+
21
+XSFPlayer::XSFPlayer(const XSFPlayer &xSFPlayer) : xSF(new XSFFile()), sampleRate(xSFPlayer.sampleRate), detectedSilenceSample(xSFPlayer.detectedSilenceSample), detectedSilenceSec(xSFPlayer.detectedSilenceSec),
22
+	skipSilenceOnStartSec(xSFPlayer.skipSilenceOnStartSec), lengthSample(xSFPlayer.lengthSample), fadeSample(xSFPlayer.fadeSample), currentSample(xSFPlayer.currentSample), prevSampleL(xSFPlayer.prevSampleL),
23
+	prevSampleR(xSFPlayer.prevSampleR), lengthInMS(xSFPlayer.lengthInMS), fadeInMS(xSFPlayer.fadeInMS), volume(xSFPlayer.volume), ignoreVolume(xSFPlayer.ignoreVolume)
24
+{
25
+	*this->xSF = *xSFPlayer.xSF;
26
+}
27
+
28
+XSFPlayer &XSFPlayer::operator=(const XSFPlayer &xSFPlayer)
29
+{
30
+	if (this != &xSFPlayer)
31
+	{
32
+		if (!this->xSF)
33
+			this->xSF = new XSFFile();
34
+		*this->xSF = *xSFPlayer.xSF;
35
+		this->sampleRate = xSFPlayer.sampleRate;
36
+		this->detectedSilenceSample = xSFPlayer.detectedSilenceSample;
37
+		this->detectedSilenceSec = xSFPlayer.detectedSilenceSec;
38
+		this->skipSilenceOnStartSec = xSFPlayer.skipSilenceOnStartSec;
39
+		this->lengthSample = xSFPlayer.lengthSample;
40
+		this->fadeSample = xSFPlayer.fadeSample;
41
+		this->currentSample = xSFPlayer.currentSample;
42
+		this->prevSampleL = xSFPlayer.prevSampleL;
43
+		this->prevSampleR = xSFPlayer.prevSampleR;
44
+		this->lengthInMS = xSFPlayer.lengthInMS;
45
+		this->fadeInMS = xSFPlayer.fadeInMS;
46
+		this->volume = xSFPlayer.volume;
47
+		this->ignoreVolume = xSFPlayer.ignoreVolume;
48
+	}
49
+	return *this;
50
+}
51
+
52
+bool XSFPlayer::FillBuffer(std::vector<uint8_t> &buf, unsigned &samplesWritten)
53
+{
54
+	bool endFlag = false;
55
+	unsigned detectSilence = xSFConfig->GetDetectSilenceSec();
56
+	unsigned pos = 0, bufsize = buf.size() >> 2;
57
+	while (pos < bufsize)
58
+	{
59
+		unsigned remain = bufsize - pos, offset = pos;
60
+		this->GenerateSamples(buf, pos << 1, remain);
61
+		if (detectSilence || skipSilenceOnStartSec)
62
+		{
63
+			unsigned skipOffset = 0;
64
+			for (unsigned ofs = 0; ofs < remain; ++ofs)
65
+			{
66
+				short *bufShort = reinterpret_cast<short *>(&buf[0]);
67
+				unsigned long sampleL = bufShort[2 * (offset + ofs)], sampleR = bufShort[2 * (offset + ofs) + 1];
68
+				bool silence = (sampleL + XSFPlayer::CHECK_SILENCE_BIAS + XSFPlayer::CHECK_SILENCE_LEVEL) - this->prevSampleL <= XSFPlayer::CHECK_SILENCE_LEVEL * 2 &&
69
+					(sampleR + XSFPlayer::CHECK_SILENCE_BIAS + XSFPlayer::CHECK_SILENCE_LEVEL) - this->prevSampleR <= XSFPlayer::CHECK_SILENCE_LEVEL * 2;
70
+
71
+				if (silence)
72
+				{
73
+					if (++this->detectedSilenceSample >= this->sampleRate)
74
+					{
75
+						this->detectedSilenceSample -= this->sampleRate;
76
+						++this->detectedSilenceSec;
77
+						if (this->skipSilenceOnStartSec && this->detectedSilenceSec >= this->skipSilenceOnStartSec)
78
+						{
79
+							this->skipSilenceOnStartSec = this->detectedSilenceSec = 0;
80
+							if (ofs)
81
+								skipOffset = ofs;
82
+						}
83
+					}
84
+				}
85
+				else
86
+				{
87
+					this->detectedSilenceSample = this->detectedSilenceSec = 0;
88
+					if (this->skipSilenceOnStartSec)
89
+					{
90
+						this->skipSilenceOnStartSec = 0;
91
+						if (ofs)
92
+							skipOffset = ofs;
93
+					}
94
+				}
95
+
96
+				prevSampleL = sampleL + XSFPlayer::CHECK_SILENCE_BIAS;
97
+				prevSampleR = sampleR + XSFPlayer::CHECK_SILENCE_BIAS;
98
+			}
99
+
100
+			if (!this->skipSilenceOnStartSec)
101
+			{
102
+				if (skipOffset)
103
+				{
104
+					std::vector<uint8_t> tmpBuf = std::vector<uint8_t>(2 * skipOffset);
105
+					memcpy(&tmpBuf[0], &buf[offset + 2 * skipOffset], 2 * skipOffset);
106
+					memcpy(&buf[offset], &tmpBuf[0], 2 * skipOffset);
107
+					pos += skipOffset;
108
+				}
109
+				else
110
+					pos += remain;
111
+			}
112
+		}
113
+		else
114
+			pos += remain;
115
+	}
116
+
117
+	/* Detect end of song */
118
+	if (!xSFConfig->GetPlayInfinitely())
119
+	{
120
+		if (this->currentSample >= this->lengthSample + this->fadeSample)
121
+		{
122
+			samplesWritten = 0;
123
+			return true;
124
+		}
125
+		if (this->currentSample + bufsize >= this->lengthSample + this->fadeSample)
126
+		{
127
+			bufsize = this->lengthSample + this->fadeSample - this->currentSample;
128
+			endFlag = true;
129
+		}
130
+	}
131
+
132
+	/* Volume */
133
+	if (!this->ignoreVolume && (!fEqual(this->volume, 1.0) || !fEqual(xSFConfig->GetVolume(), 1.0)))
134
+	{
135
+		double scale = this->volume * xSFConfig->GetVolume();
136
+		short *bufShort = reinterpret_cast<short *>(&buf[0]);
137
+		for (unsigned ofs = 0; ofs < bufsize; ++ofs)
138
+		{
139
+			double s1 = bufShort[2 * ofs] * scale, s2 = bufShort[2 * ofs + 1] * scale;
140
+			if (s1 > 0x7FFF)
141
+				s1 = 0x7FFF;
142
+			else if (s1 < -0x8000)
143
+				s1 = -0x8000;
144
+			if (s2 > 0x7FFF)
145
+				s2 = 0x7FFF;
146
+			else if (s2 < -0x8000)
147
+				s2 = -0x8000;
148
+			bufShort[2 * ofs] = static_cast<short>(s1);
149
+			bufShort[2 * ofs + 1] = static_cast<short>(s2);
150
+		}
151
+	}
152
+
153
+	/* Fading */
154
+	if (!xSFConfig->GetPlayInfinitely() && this->fadeSample && this->currentSample + bufsize >= this->lengthSample)
155
+	{
156
+		short *bufShort = reinterpret_cast<short *>(&buf[0]);
157
+		for (unsigned ofs = 0; ofs < bufsize; ++ofs)
158
+		{
159
+			if (this->currentSample + ofs >= this->lengthSample && this->currentSample + ofs < this->lengthSample + this->fadeSample)
160
+			{
161
+				int scale = static_cast<uint64_t>(this->lengthSample + this->fadeSample - (this->currentSample + ofs)) * 0x10000 / this->fadeSample;
162
+				bufShort[2 * ofs] = (bufShort[2 * ofs] * scale) >> 16;
163
+				bufShort[2 * ofs + 1] = (bufShort[2 * ofs + 1] * scale) >> 16;
164
+			}
165
+			else if (this->currentSample + ofs >= this->lengthSample + this->fadeSample)
166
+				bufShort[2 * ofs] = bufShort[2 * ofs + 1] = 0;
167
+		}
168
+	}
169
+
170
+	this->currentSample += bufsize;
171
+	samplesWritten = bufsize;
172
+	return endFlag;
173
+}
174
+
175
+bool XSFPlayer::Load()
176
+{
177
+	this->lengthInMS = this->xSF->GetLengthMS(xSFConfig->GetDefaultLength());
178
+	this->fadeInMS = this->xSF->GetFadeMS(xSFConfig->GetDefaultFade());
179
+	this->lengthSample = static_cast<uint64_t>(this->lengthInMS) * this->sampleRate / 1000;
180
+	this->fadeSample = static_cast<uint64_t>(this->fadeInMS) * this->sampleRate / 1000;
181
+	this->volume = this->xSF->GetVolume(xSFConfig->GetVolumeType(), xSFConfig->GetPeakType());
182
+	return true;
183
+}
184
+
185
+void XSFPlayer::SeekTop()
186
+{
187
+	this->skipSilenceOnStartSec = xSFConfig->GetSkipSilenceOnStartSec();
188
+	this->currentSample = this->detectedSilenceSec = this->detectedSilenceSample = 0;
189
+	this->prevSampleL = this->prevSampleR = XSFPlayer::CHECK_SILENCE_BIAS;
190
+}
191
+
192
+#ifdef WINAMP_PLUGIN
193
+
194
+static inline DWORD TicksDiff(DWORD prev, DWORD cur) { return cur >= prev ? cur - prev : 0xFFFFFFFF - prev + cur; }
195
+
196
+int XSFPlayer::Seek(unsigned seekPosition, volatile int *killswitch, std::vector<uint8_t> &buf, Out_Module *outMod)
197
+{
198
+	unsigned bufsize = buf.size() >> 2, seekSample = static_cast<uint64_t>(seekPosition) * this->sampleRate / 1000;
199
+	DWORD prevTick = outMod ? GetTickCount() : 0;
200
+	if (seekSample < this->currentSample)
201
+	{
202
+		this->Terminate();
203
+		this->Load();
204
+		this->SeekTop();
205
+	}
206
+	while (seekSample - this->currentSample > bufsize)
207
+	{
208
+		if (killswitch && *killswitch)
209
+			return 1;
210
+		if (outMod)
211
+		{
212
+			DWORD curTick = GetTickCount();
213
+			if (TicksDiff(prevTick, curTick) >= 500)
214
+			{
215
+				prevTick = curTick;
216
+				unsigned cur = static_cast<uint64_t>(this->currentSample) * 1000 / this->sampleRate;
217
+				outMod->Flush(cur);
218
+			}
219
+		}
220
+		this->GenerateSamples(buf, 0, bufsize);
221
+		this->currentSample += bufsize;
222
+	}
223
+	if (seekSample - this->currentSample > 0)
224
+	{
225
+		this->GenerateSamples(buf, 0, seekSample - this->currentSample);
226
+		this->currentSample = seekSample;
227
+	}
228
+	if (outMod)
229
+		outMod->Flush(seekPosition);
230
+	return 0;
231
+}
232
+
233
+#endif