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
... ...
@@ -14,9 +14,13 @@
14 14
 
15 15
 #include <algorithm>
16 16
 #include <bitset>
17
+#include <cstddef>
17 18
 #include <cstdint>
18
-#include "SWAV.h"
19
-#include "Track.h"
19
+#include "common.h"
20
+#include "consts.h"
21
+
22
+struct SWAV;
23
+struct Track;
20 24
 
21 25
 /*
22 26
  * This structure is meant to be similar to what is stored in the actual
... ...
@@ -27,41 +31,41 @@
27 31
 struct NDSSoundRegister
28 32
 {
29 33
 	// Control Register
30
-	uint8_t volumeMul;
31
-	uint8_t volumeDiv;
32
-	uint8_t panning;
33
-	uint8_t waveDuty;
34
-	uint8_t repeatMode;
35
-	uint8_t format;
34
+	std::uint8_t volumeMul;
35
+	std::uint8_t volumeDiv;
36
+	std::uint8_t panning;
37
+	std::uint8_t waveDuty;
38
+	std::uint8_t repeatMode;
39
+	std::uint8_t format;
36 40
 	bool enable;
37 41
 
38 42
 	// Data Source Register
39 43
 	const SWAV *source;
40 44
 
41 45
 	// Timer Register
42
-	uint16_t timer;
46
+	std::uint16_t timer;
43 47
 
44 48
 	// PSG Handling, not a DS register
45
-	uint16_t psgX;
46
-	int16_t psgLast;
47
-	uint32_t psgLastCount;
49
+	std::uint16_t psgX;
50
+	std::int16_t psgLast;
51
+	std::uint32_t psgLastCount;
48 52
 
49 53
 	// The following are taken from DeSmuME
50 54
 	double samplePosition;
51 55
 	double sampleIncrease;
52 56
 
53 57
 	// Loopstart Register
54
-	uint32_t loopStart;
58
+	std::uint32_t loopStart;
55 59
 
56 60
 	// Length Register
57
-	uint32_t length;
61
+	std::uint32_t length;
58 62
 
59
-	uint32_t totalLength;
63
+	std::uint32_t totalLength;
60 64
 
61 65
 	NDSSoundRegister();
62 66
 
63 67
 	void ClearControlRegister();
64
-	void SetControlRegister(uint32_t reg);
68
+	void SetControlRegister(std::uint32_t reg);
65 69
 };
66 70
 
67 71
 /*
... ...
@@ -72,10 +76,10 @@ struct NDSSoundRegister
72 76
  */
73 77
 struct TempSndReg
74 78
 {
75
-	uint32_t CR;
79
+	std::uint32_t CR;
76 80
 	const SWAV *SOURCE;
77
-	uint16_t TIMER;
78
-	uint32_t REPEAT_POINT, LENGTH;
81
+	std::uint16_t TIMER;
82
+	std::uint32_t REPEAT_POINT, LENGTH;
79 83
 
80 84
 	TempSndReg();
81 85
 };
... ...
@@ -95,10 +99,10 @@ struct Player;
95 99
  * accessing the SWAVs samples and also doesn't use 0s before the
96 100
  * start of the SWAV or use 0s after the end of a non-looping SWAV.
97 101
  */
98
-template<size_t N> struct RingBuffer
102
+template<std::size_t N> struct RingBuffer
99 103
 {
100
-	int16_t buffer[N * 2];
101
-	size_t bufferPos, getPos;
104
+	std::int16_t buffer[N * 2];
105
+	std::size_t bufferPos, getPos;
102 106
 
103 107
 	RingBuffer() : bufferPos(N / 2), getPos(N / 2)
104 108
 	{
... ...
@@ -109,7 +113,7 @@ template<size_t N> struct RingBuffer
109 113
 		std::fill_n(&this->buffer[0], N * 2, 0);
110 114
 		this->bufferPos = this->getPos = N / 2;
111 115
 	}
112
-	void PushSample(int16_t sample)
116
+	void PushSample(std::int16_t sample)
113 117
 	{
114 118
 		this->buffer[this->bufferPos] = sample;
115 119
 		if (this->bufferPos >= N)
... ...
@@ -120,23 +124,23 @@ template<size_t N> struct RingBuffer
120 124
 		if (this->bufferPos >= N * 3 / 2)
121 125
 			this->bufferPos -= N;
122 126
 	}
123
-	void PushSamples(const int16_t *samples, size_t size)
127
+	void PushSamples(const std::int16_t *samples, std::size_t size)
124 128
 	{
125 129
 		if (this->bufferPos + size > N * 3 / 2)
126 130
 		{
127
-			size_t free = N * 3 / 2 - this->bufferPos;
131
+			std::size_t free = N * 3 / 2 - this->bufferPos;
128 132
 			std::copy_n(&samples[0], free, &this->buffer[this->bufferPos]);
129 133
 			std::copy(&samples[free], &samples[size], &this->buffer[N / 2]);
130 134
 		}
131 135
 		else
132 136
 			std::copy_n(&samples[0], size, &this->buffer[this->bufferPos]);
133
-		size_t rightFree = this->bufferPos < N ? N - this->bufferPos : 0;
137
+		std::size_t rightFree = this->bufferPos < N ? N - this->bufferPos : 0;
134 138
 		if (rightFree < size)
135 139
 		{
136 140
 			if (!rightFree)
137 141
 			{
138
-				size_t leftStart = this->bufferPos - N;
139
-				size_t leftSize = std::min(N / 2 - leftStart, size);
142
+				std::size_t leftStart = this->bufferPos - N;
143
+				std::size_t leftSize = std::min(N / 2 - leftStart, size);
140 144
 				std::copy_n(&samples[0], leftSize, &this->buffer[leftStart]);
141 145
 				if (leftSize < size)
142 146
 					std::copy(&samples[leftSize], &samples[size], &this->buffer[N * 3 / 2]);
... ...
@@ -153,7 +157,7 @@ template<size_t N> struct RingBuffer
153 157
 		if (this->bufferPos >= N * 3 / 2)
154 158
 			this->bufferPos -= N;
155 159
 	}
156
-	const int16_t *GetBuffer() const
160
+	const std::int16_t *GetBuffer() const
157 161
 	{
158 162
 		return &this->buffer[this->getPos];
159 163
 	}
... ...
@@ -167,35 +171,35 @@ template<size_t N> struct RingBuffer
167 171
 
168 172
 struct Channel
169 173
 {
170
-	int8_t chnId;
174
+	std::int8_t chnId;
171 175
 
172 176
 	TempSndReg tempReg;
173
-	uint8_t state;
174
-	int8_t trackId; // -1 = none
175
-	uint8_t prio;
177
+	ChannelState state;
178
+	std::int8_t trackId; // -1 = none
179
+	std::uint8_t prio;
176 180
 	bool manualSweep;
177 181
 
178
-	std::bitset<CF_BITS> flags;
179
-	int8_t pan; // -64 .. 63
180
-	int16_t extAmpl;
182
+	std::bitset<ToIntegral(ChannelFlag::Bits)> flags;
183
+	std::int8_t pan; // -64 .. 63
184
+	std::int16_t extAmpl;
181 185
 
182
-	int16_t velocity;
183
-	int8_t extPan;
184
-	uint8_t key;
186
+	std::int16_t velocity;
187
+	std::int8_t extPan;
188
+	std::uint8_t key;
185 189
 
186 190
 	int ampl; // 7 fractionary bits
187 191
 	int extTune; // in 64ths of a semitone
188 192
 
189
-	uint8_t orgKey;
193
+	std::uint8_t orgKey;
190 194
 
191
-	uint8_t modType, modSpeed, modDepth, modRange;
192
-	uint16_t modDelay, modDelayCnt, modCounter;
195
+	std::uint8_t modType, modSpeed, modDepth, modRange;
196
+	std::uint16_t modDelay, modDelayCnt, modCounter;
193 197
 
194
-	uint32_t sweepLen, sweepCnt;
195
-	int16_t sweepPitch;
198
+	std::uint32_t sweepLen, sweepCnt;
199
+	std::int16_t sweepPitch;
196 200
 
197
-	uint8_t attackLvl, sustainLvl;
198
-	uint16_t decayRate, releaseRate;
201
+	std::uint8_t attackLvl, sustainLvl;
202
+	std::uint16_t decayRate, releaseRate;
199 203
 
200 204
 	/*
201 205
 	 * These were originally global variables in FeOS Sound System, but
... ...
@@ -203,7 +207,7 @@ struct Channel
203 207
 	 * into this class.
204 208
 	 */
205 209
 	int noteLength;
206
-	uint16_t vol;
210
+	std::uint16_t vol;
207 211
 
208 212
 	const Player *ply;
209 213
 	NDSSoundRegister reg;
... ...
@@ -234,7 +238,7 @@ struct Channel
234 238
 	void Kill();
235 239
 	void UpdateTrack();
236 240
 	void Update();
237
-	int32_t Interpolate();
238
-	int32_t GenerateSample();
241
+	std::int32_t Interpolate();
242
+	std::int32_t GenerateSample();
239 243
 	void IncrementSample();
240 244
 };
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
  * SSEQ Player - Channel structures
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2014-10-27
5 4
  *
6 5
  * Adapted from source code of FeOS Sound System
7 6
  * By fincs
Browse code

Various updates:

* Fix build with Visual Studio, updating projects to Visual Studio 2019 (as that is what I have installed).
* Changed C++ language standard to C++ 17.
* Add files for in_2sf's spu from Coda's recent commit.
* Add files for zlib now that it is being included as a submodule (removes the need for the zlib DLL as well).
* Remove common.props (due to the aforementioned zlib inclusion as well as the winamp headers also being in the project now).
* Minor NCSF file in the SSEQ player, the check for when to process tracks should've been >=, not >.

Naram Qashat authored on 2021/03/15 22:34:25
Showing 1 changed files
... ...
@@ -21,7 +21,7 @@
21 21
 
22 22
 /*
23 23
  * This structure is meant to be similar to what is stored in the actual
24
- * Nintendo DS's sound registers.  Items that were not being used by this
24
+ * Nintendo DS's sound registers. Items that were not being used by this
25 25
  * player have been removed, and items which help the simulated registers
26 26
  * have been added.
27 27
  */
... ...
@@ -67,7 +67,7 @@ struct NDSSoundRegister
67 67
 
68 68
 /*
69 69
  * From FeOS Sound System, this is temporary storage of what will go into
70
- * the Nintendo DS sound registers.  It is kept separate as the original code
70
+ * the Nintendo DS sound registers. It is kept separate as the original code
71 71
  * from FeOS Sound System utilized this to hold data prior to passing it into
72 72
  * the DS's registers.
73 73
  */
... ...
@@ -88,7 +88,7 @@ struct Player;
88 88
  * data, duplicated. The way it is duplicated is done as follows:
89 89
  * the samples are stored in the center of the buffer, and on both
90 90
  * sides is half of the data, the first half being after the data
91
- * and the second half before before the data. This in essense
91
+ * and the second half begin before the data. This in essence
92 92
  * mirrors the data while allowing a pointer to always be retrieved
93 93
  * and no extra copies of the buffer are created. Part of the idea
94 94
  * for this came from kode54's original buffer implementation, but
Browse code

[NCSF] Applied sinc modification from kode54:

Sinc mode should not scale the window, just the sinc pulse.

Naram Qashat authored on 2014/10/27 04:15:11
Showing 1 changed files
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * SSEQ Player - Channel structures
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2014-09-17
4
+ * Last modification on 2014-10-27
5 5
  *
6 6
  * Adapted from source code of FeOS Sound System
7 7
  * By fincs
... ...
@@ -220,6 +220,7 @@ struct Channel
220 220
 	static const unsigned SINC_WIDTH = 8;
221 221
 	static const unsigned SINC_SAMPLES = SINC_RESOLUTION * SINC_WIDTH;
222 222
 	static double sinc_lut[SINC_SAMPLES + 1];
223
+	static double window_lut[SINC_SAMPLES + 1];
223 224
 
224 225
 	RingBuffer<SINC_WIDTH * 2> ringBuffer;
225 226
 
Browse code

[NCSF] Very minor cleanups.

Naram Qashat authored on 2014/10/24 19:58:46
Showing 1 changed files
... ...
@@ -210,7 +210,7 @@ struct Channel
210 210
 	NDSSoundRegister reg;
211 211
 
212 212
 	/*
213
-	 * Lookup tables for the cosine and Lanczos Sinc interpolations, to
213
+	 * Lookup tables for the Sinc interpolation, to
214 214
 	 * avoid the need to call the sin/cos functions all the time.
215 215
 	 * These are static as they will not change between channels or runs
216 216
 	 * of the program.
Browse code

[NCSF] Interpolation changes:

* Removed Cosine, 4-Point B-Spline, 6-Point B-Spline, and 6-point
Osculating.
* Added 4-Point Legrange and 6-Point Legrange.
* Changed wording of the Sinc interpolation to mention that it is
16-point.

Naram Qashat authored on 2014/09/28 00:07:18
Showing 1 changed files
... ...
@@ -216,11 +216,9 @@ struct Channel
216 216
 	 * of the program.
217 217
 	 */
218 218
 	static bool initializedLUTs;
219
-	static const unsigned COSINE_RESOLUTION = 8192;
220 219
 	static const unsigned SINC_RESOLUTION = 8192;
221 220
 	static const unsigned SINC_WIDTH = 8;
222 221
 	static const unsigned SINC_SAMPLES = SINC_RESOLUTION * SINC_WIDTH;
223
-	static double cosine_lut[COSINE_RESOLUTION];
224 222
 	static double sinc_lut[SINC_SAMPLES + 1];
225 223
 
226 224
 	RingBuffer<SINC_WIDTH * 2> ringBuffer;
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
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * SSEQ Player - Channel structures
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2014-09-08
4
+ * Last modification on 2014-09-17
5 5
  *
6 6
  * Adapted from source code of FeOS Sound System
7 7
  * By fincs
... ...
@@ -13,6 +13,7 @@
13 13
 
14 14
 #pragma once
15 15
 
16
+#include <algorithm>
16 17
 #include <bitset>
17 18
 #include <cstdint>
18 19
 #include "SWAV.h"
... ...
@@ -153,7 +154,7 @@ template<size_t N> struct RingBuffer
153 154
 		if (this->bufferPos >= N * 3 / 2)
154 155
 			this->bufferPos -= N;
155 156
 	}
156
-	const int16_t *const GetBuffer() const
157
+	const int16_t *GetBuffer() const
157 158
 	{
158 159
 		return &this->buffer[this->getPos];
159 160
 	}
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
... ...
@@ -102,11 +102,11 @@ template<size_t N> struct RingBuffer
102 102
 
103 103
 	RingBuffer() : bufferPos(N / 2), getPos(N / 2)
104 104
 	{
105
-		std::fill(&this->buffer[0], &this->buffer[N * 2], 0);
105
+		std::fill_n(&this->buffer[0], N * 2, 0);
106 106
 	}
107 107
 	void Clear()
108 108
 	{
109
-		std::fill(&this->buffer[0], &this->buffer[N * 2], 0);
109
+		std::fill_n(&this->buffer[0], N * 2, 0);
110 110
 		this->bufferPos = this->getPos = N / 2;
111 111
 	}
112 112
 	void PushSample(int16_t sample)
... ...
@@ -125,11 +125,11 @@ template<size_t N> struct RingBuffer
125 125
 		if (this->bufferPos + size > N * 3 / 2)
126 126
 		{
127 127
 			size_t free = N * 3 / 2 - this->bufferPos;
128
-			std::copy(&samples[0], &samples[free], &this->buffer[this->bufferPos]);
128
+			std::copy_n(&samples[0], free, &this->buffer[this->bufferPos]);
129 129
 			std::copy(&samples[free], &samples[size], &this->buffer[N / 2]);
130 130
 		}
131 131
 		else
132
-			std::copy(&samples[0], &samples[size], &this->buffer[this->bufferPos]);
132
+			std::copy_n(&samples[0], size, &this->buffer[this->bufferPos]);
133 133
 		size_t rightFree = this->bufferPos < N ? N - this->bufferPos : 0;
134 134
 		if (rightFree < size)
135 135
 		{
... ...
@@ -137,18 +137,18 @@ template<size_t N> struct RingBuffer
137 137
 			{
138 138
 				size_t leftStart = this->bufferPos - N;
139 139
 				size_t leftSize = std::min(N / 2 - leftStart, size);
140
-				std::copy(&samples[0], &samples[leftSize], &this->buffer[leftStart]);
140
+				std::copy_n(&samples[0], leftSize, &this->buffer[leftStart]);
141 141
 				if (leftSize < size)
142 142
 					std::copy(&samples[leftSize], &samples[size], &this->buffer[N * 3 / 2]);
143 143
 			}
144 144
 			else
145 145
 			{
146
-				std::copy(&samples[0], &samples[rightFree], &this->buffer[this->bufferPos + N]);
146
+				std::copy_n(&samples[0], rightFree, &this->buffer[this->bufferPos + N]);
147 147
 				std::copy(&samples[rightFree], &samples[size], &this->buffer[0]);
148 148
 			}
149 149
 		}
150 150
 		else
151
-			std::copy(&samples[0], &samples[size], &this->buffer[this->bufferPos + N]);
151
+			std::copy_n(&samples[0], size, &this->buffer[this->bufferPos + N]);
152 152
 		this->bufferPos += size;
153 153
 		if (this->bufferPos >= N * 3 / 2)
154 154
 			this->bufferPos -= N;
Browse code

Use #pragma once instead of include guards.

Naram Qashat authored on 2014/09/08 14:47:36
Showing 1 changed files
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * SSEQ Player - Channel structures
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
  * Adapted from source code of FeOS Sound System
7 7
  * By fincs
... ...
@@ -11,8 +11,7 @@
11 11
  * http://desmume.org/
12 12
  */
13 13
 
14
-#ifndef SSEQPLAYER_CHANNEL_H
15
-#define SSEQPLAYER_CHANNEL_H
14
+#pragma once
16 15
 
17 16
 #include <bitset>
18 17
 #include <cstdint>
... ...
@@ -240,5 +239,3 @@ struct Channel
240 239
 	int32_t GenerateSample();
241 240
 	void IncrementSample();
242 241
 };
243
-
244
-#endif
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
  * SSEQ Player - Channel structures
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
  * Adapted from source code of FeOS Sound System
7 7
  * By fincs
... ...
@@ -83,6 +83,89 @@ struct TempSndReg
83 83
 
84 84
 struct Player;
85 85
 
86
+/*
87
+ * This creates a ring buffer, which will store N samples of SWAV
88
+ * data, duplicated. The way it is duplicated is done as follows:
89
+ * the samples are stored in the center of the buffer, and on both
90
+ * sides is half of the data, the first half being after the data
91
+ * and the second half before before the data. This in essense
92
+ * mirrors the data while allowing a pointer to always be retrieved
93
+ * and no extra copies of the buffer are created. Part of the idea
94
+ * for this came from kode54's original buffer implementation, but
95
+ * this has been designed to make sure that there are no delays in
96
+ * accessing the SWAVs samples and also doesn't use 0s before the
97
+ * start of the SWAV or use 0s after the end of a non-looping SWAV.
98
+ */
99
+template<size_t N> struct RingBuffer
100
+{
101
+	int16_t buffer[N * 2];
102
+	size_t bufferPos, getPos;
103
+
104
+	RingBuffer() : bufferPos(N / 2), getPos(N / 2)
105
+	{
106
+		std::fill(&this->buffer[0], &this->buffer[N * 2], 0);
107
+	}
108
+	void Clear()
109
+	{
110
+		std::fill(&this->buffer[0], &this->buffer[N * 2], 0);
111
+		this->bufferPos = this->getPos = N / 2;
112
+	}
113
+	void PushSample(int16_t sample)
114
+	{
115
+		this->buffer[this->bufferPos] = sample;
116
+		if (this->bufferPos >= N)
117
+			this->buffer[this->bufferPos - N] = sample;
118
+		else
119
+			this->buffer[this->bufferPos + N] = sample;
120
+		++this->bufferPos;
121
+		if (this->bufferPos >= N * 3 / 2)
122
+			this->bufferPos -= N;
123
+	}
124
+	void PushSamples(const int16_t *samples, size_t size)
125
+	{
126
+		if (this->bufferPos + size > N * 3 / 2)
127
+		{
128
+			size_t free = N * 3 / 2 - this->bufferPos;
129
+			std::copy(&samples[0], &samples[free], &this->buffer[this->bufferPos]);
130
+			std::copy(&samples[free], &samples[size], &this->buffer[N / 2]);
131
+		}
132
+		else
133
+			std::copy(&samples[0], &samples[size], &this->buffer[this->bufferPos]);
134
+		size_t rightFree = this->bufferPos < N ? N - this->bufferPos : 0;
135
+		if (rightFree < size)
136
+		{
137
+			if (!rightFree)
138
+			{
139
+				size_t leftStart = this->bufferPos - N;
140
+				size_t leftSize = std::min(N / 2 - leftStart, size);
141
+				std::copy(&samples[0], &samples[leftSize], &this->buffer[leftStart]);
142
+				if (leftSize < size)
143
+					std::copy(&samples[leftSize], &samples[size], &this->buffer[N * 3 / 2]);
144
+			}
145
+			else
146
+			{
147
+				std::copy(&samples[0], &samples[rightFree], &this->buffer[this->bufferPos + N]);
148
+				std::copy(&samples[rightFree], &samples[size], &this->buffer[0]);
149
+			}
150
+		}
151
+		else
152
+			std::copy(&samples[0], &samples[size], &this->buffer[this->bufferPos + N]);
153
+		this->bufferPos += size;
154
+		if (this->bufferPos >= N * 3 / 2)
155
+			this->bufferPos -= N;
156
+	}
157
+	const int16_t *const GetBuffer() const
158
+	{
159
+		return &this->buffer[this->getPos];
160
+	}
161
+	void NextSample()
162
+	{
163
+		++this->getPos;
164
+		if (this->getPos >= N * 3 / 2)
165
+			this->getPos -= N;
166
+	}
167
+};
168
+
86 169
 struct Channel
87 170
 {
88 171
 	int8_t chnId;
... ...
@@ -126,14 +209,6 @@ struct Channel
126 209
 	const Player *ply;
127 210
 	NDSSoundRegister reg;
128 211
 
129
-	/*
130
-	 * Interpolation history buffer, which contains the maximum number of
131
-	 * samples required for any given interpolation mode. Doubled to
132
-	 * simplify the case of wrapping. Thanks to kode54 for providing this.
133
-	 */
134
-	uint32_t sampleHistoryPtr;
135
-	int16_t sampleHistory[64];
136
-
137 212
 	/*
138 213
 	 * Lookup tables for the cosine and Lanczos Sinc interpolations, to
139 214
 	 * avoid the need to call the sin/cos functions all the time.
... ...
@@ -142,11 +217,13 @@ struct Channel
142 217
 	 */
143 218
 	static bool initializedLUTs;
144 219
 	static const unsigned COSINE_RESOLUTION = 8192;
145
-	static const unsigned LANCZOS_RESOLUTION = 8192;
146
-	static const unsigned LANCZOS_WIDTH = 8;
147
-	static const unsigned LANCZOS_SAMPLES = LANCZOS_RESOLUTION * LANCZOS_WIDTH;
220
+	static const unsigned SINC_RESOLUTION = 8192;
221
+	static const unsigned SINC_WIDTH = 8;
222
+	static const unsigned SINC_SAMPLES = SINC_RESOLUTION * SINC_WIDTH;
148 223
 	static double cosine_lut[COSINE_RESOLUTION];
149
-	static double lanczos_lut[LANCZOS_SAMPLES + 1];
224
+	static double sinc_lut[SINC_SAMPLES + 1];
225
+
226
+	RingBuffer<SINC_WIDTH * 2> ringBuffer;
150 227
 
151 228
 	Channel();
152 229
 
... ...
@@ -162,7 +239,6 @@ struct Channel
162 239
 	int32_t Interpolate();
163 240
 	int32_t GenerateSample();
164 241
 	void IncrementSample();
165
-	void clearHistory();
166 242
 };
167 243
 
168 244
 #endif
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
  * SSEQ Player - Channel structures
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
  * Adapted from source code of FeOS Sound System
7 7
  * By fincs
... ...
@@ -132,7 +132,7 @@ struct Channel
132 132
 	 * simplify the case of wrapping. Thanks to kode54 for providing this.
133 133
 	 */
134 134
 	uint32_t sampleHistoryPtr;
135
-	int16_t sampleHistory[16];
135
+	int16_t sampleHistory[64];
136 136
 
137 137
 	/*
138 138
 	 * Lookup tables for the cosine and Lanczos Sinc interpolations, to
... ...
@@ -143,10 +143,10 @@ struct Channel
143 143
 	static bool initializedLUTs;
144 144
 	static const unsigned COSINE_RESOLUTION = 8192;
145 145
 	static const unsigned LANCZOS_RESOLUTION = 8192;
146
-	static const unsigned LANCZOS_WIDTH = 3;
146
+	static const unsigned LANCZOS_WIDTH = 8;
147 147
 	static const unsigned LANCZOS_SAMPLES = LANCZOS_RESOLUTION * LANCZOS_WIDTH;
148 148
 	static double cosine_lut[COSINE_RESOLUTION];
149
-	static double lanczos_lut[LANCZOS_SAMPLES];
149
+	static double lanczos_lut[LANCZOS_SAMPLES + 1];
150 150
 
151 151
 	Channel();
152 152
 
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
  * SSEQ Player - Channel structures
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2013-04-18
4
+ * Last modification on 2013-04-23
5 5
  *
6 6
  * Adapted from source code of FeOS Sound System
7 7
  * By fincs
... ...
@@ -15,10 +15,9 @@
15 15
 #define SSEQPLAYER_CHANNEL_H
16 16
 
17 17
 #include <bitset>
18
-#include <tuple>
18
+#include <cstdint>
19 19
 #include "SWAV.h"
20 20
 #include "Track.h"
21
-#include "pstdint.h"
22 21
 
23 22
 /*
24 23
  * This structure is meant to be similar to what is stored in the actual
... ...
@@ -135,6 +134,20 @@ struct Channel
135 134
 	uint32_t sampleHistoryPtr;
136 135
 	int16_t sampleHistory[16];
137 136
 
137
+	/*
138
+	 * Lookup tables for the cosine and Lanczos Sinc interpolations, to
139
+	 * avoid the need to call the sin/cos functions all the time.
140
+	 * These are static as they will not change between channels or runs
141
+	 * of the program.
142
+	 */
143
+	static bool initializedLUTs;
144
+	static const unsigned COSINE_RESOLUTION = 8192;
145
+	static const unsigned LANCZOS_RESOLUTION = 8192;
146
+	static const unsigned LANCZOS_WIDTH = 3;
147
+	static const unsigned LANCZOS_SAMPLES = LANCZOS_RESOLUTION * LANCZOS_WIDTH;
148
+	static double cosine_lut[COSINE_RESOLUTION];
149
+	static double lanczos_lut[LANCZOS_SAMPLES];
150
+
138 151
 	Channel();
139 152
 
140 153
 	void UpdateVol(const Track &trk);
Browse code

Implemented circular interpolation buffer to fix interpolation, thanks to kode54 for the code.

Naram Qashat authored on 2013/04/18 20:43:31
Showing 1 changed files
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * SSEQ Player - Channel structures
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2013-04-02
4
+ * Last modification on 2013-04-18
5 5
  *
6 6
  * Adapted from source code of FeOS Sound System
7 7
  * By fincs
... ...
@@ -127,6 +127,14 @@ struct Channel
127 127
 	const Player *ply;
128 128
 	NDSSoundRegister reg;
129 129
 
130
+	/*
131
+	 * Interpolation history buffer, which contains the maximum number of
132
+	 * samples required for any given interpolation mode. Doubled to
133
+	 * simplify the case of wrapping. Thanks to kode54 for providing this.
134
+	 */
135
+	uint32_t sampleHistoryPtr;
136
+	int16_t sampleHistory[16];
137
+
130 138
 	Channel();
131 139
 
132 140
 	void UpdateVol(const Track &trk);
... ...
@@ -141,6 +149,7 @@ struct Channel
141 149
 	int32_t Interpolate();
142 150
 	int32_t GenerateSample();
143 151
 	void IncrementSample();
152
+	void clearHistory();
144 153
 };
145 154
 
146 155
 #endif
Browse code

Utilize SSEQ's volume from it's INFO section, plus some minor optimizations.

Naram Qashat authored on 2013/04/07 16:39:00
Showing 1 changed files
... ...
@@ -58,6 +58,8 @@ struct NDSSoundRegister
58 58
 	// Length Register
59 59
 	uint32_t length;
60 60
 
61
+	uint32_t totalLength;
62
+
61 63
 	NDSSoundRegister();
62 64
 
63 65
 	void ClearControlRegister();
Browse code

Added new interpolation methods, added version number in plugin description.

Naram Qashat authored on 2013/04/02 22:40:32
Showing 1 changed files
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * SSEQ Player - Channel structures
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2013-03-21
4
+ * Last modification on 2013-04-02
5 5
  *
6 6
  * Adapted from source code of FeOS Sound System
7 7
  * By fincs
... ...
@@ -15,6 +15,7 @@
15 15
 #define SSEQPLAYER_CHANNEL_H
16 16
 
17 17
 #include <bitset>
18
+#include <tuple>
18 19
 #include "SWAV.h"
19 20
 #include "Track.h"
20 21
 #include "pstdint.h"
... ...
@@ -135,7 +136,7 @@ struct Channel
135 136
 	void Kill();
136 137
 	void UpdateTrack();
137 138
 	void Update();
138
-	int32_t Interpolate(int32_t a, int32_t b, double ratio);
139
+	int32_t Interpolate();
139 140
 	int32_t GenerateSample();
140 141
 	void IncrementSample();
141 142
 };
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,143 @@
1
+/*
2
+ * SSEQ Player - Channel structures
3
+ * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
+ * Last modification on 2013-03-21
5
+ *
6
+ * Adapted from source code of FeOS Sound System
7
+ * By fincs
8
+ * https://github.com/fincs/FSS
9
+ *
10
+ * Some code/concepts from DeSmuME
11
+ * http://desmume.org/
12
+ */
13
+
14
+#ifndef SSEQPLAYER_CHANNEL_H
15
+#define SSEQPLAYER_CHANNEL_H
16
+
17
+#include <bitset>
18
+#include "SWAV.h"
19
+#include "Track.h"
20
+#include "pstdint.h"
21
+
22
+/*
23
+ * This structure is meant to be similar to what is stored in the actual
24
+ * Nintendo DS's sound registers.  Items that were not being used by this
25
+ * player have been removed, and items which help the simulated registers
26
+ * have been added.
27
+ */
28
+struct NDSSoundRegister
29
+{
30
+	// Control Register
31
+	uint8_t volumeMul;
32
+	uint8_t volumeDiv;
33
+	uint8_t panning;
34
+	uint8_t waveDuty;
35
+	uint8_t repeatMode;
36
+	uint8_t format;
37
+	bool enable;
38
+
39
+	// Data Source Register
40
+	const SWAV *source;
41
+
42
+	// Timer Register
43
+	uint16_t timer;
44
+
45
+	// PSG Handling, not a DS register
46
+	uint16_t psgX;
47
+	int16_t psgLast;
48
+	uint32_t psgLastCount;
49
+
50
+	// The following are taken from DeSmuME
51
+	double samplePosition;
52
+	double sampleIncrease;
53
+
54
+	// Loopstart Register
55
+	uint32_t loopStart;
56
+
57
+	// Length Register
58
+	uint32_t length;
59
+
60
+	NDSSoundRegister();
61
+
62
+	void ClearControlRegister();
63
+	void SetControlRegister(uint32_t reg);
64
+};
65
+
66
+/*
67
+ * From FeOS Sound System, this is temporary storage of what will go into
68
+ * the Nintendo DS sound registers.  It is kept separate as the original code
69
+ * from FeOS Sound System utilized this to hold data prior to passing it into
70
+ * the DS's registers.
71
+ */
72
+struct TempSndReg
73
+{
74
+	uint32_t CR;
75
+	const SWAV *SOURCE;
76
+	uint16_t TIMER;
77
+	uint32_t REPEAT_POINT, LENGTH;
78
+
79
+	TempSndReg();
80
+};
81
+
82
+struct Player;
83
+
84
+struct Channel
85
+{
86
+	int8_t chnId;
87
+
88
+	TempSndReg tempReg;
89
+	uint8_t state;
90
+	int8_t trackId; // -1 = none
91
+	uint8_t prio;
92
+	bool manualSweep;
93
+
94
+	std::bitset<CF_BITS> flags;
95
+	int8_t pan; // -64 .. 63
96
+	int16_t extAmpl;
97
+
98
+	int16_t velocity;
99
+	int8_t extPan;
100
+	uint8_t key;
101
+
102
+	int ampl; // 7 fractionary bits
103
+	int extTune; // in 64ths of a semitone
104
+
105
+	uint8_t orgKey;
106
+
107
+	uint8_t modType, modSpeed, modDepth, modRange;
108
+	uint16_t modDelay, modDelayCnt, modCounter;
109
+
110
+	uint32_t sweepLen, sweepCnt;
111
+	int16_t sweepPitch;
112
+
113
+	uint8_t attackLvl, sustainLvl;
114
+	uint16_t decayRate, releaseRate;
115
+
116
+	/*
117
+	 * These were originally global variables in FeOS Sound System, but
118
+	 * since they were linked to a certain channel anyways, I moved them
119
+	 * into this class.
120
+	 */
121
+	int noteLength;
122
+	uint16_t vol;
123
+
124
+	const Player *ply;
125
+	NDSSoundRegister reg;
126
+
127
+	Channel();
128
+
129
+	void UpdateVol(const Track &trk);
130
+	void UpdatePan(const Track &trk);
131
+	void UpdateTune(const Track &trk);
132
+	void UpdateMod(const Track &trk);
133
+	void UpdatePorta(const Track &trk);
134
+	void Release();
135
+	void Kill();
136
+	void UpdateTrack();
137
+	void Update();
138
+	int32_t Interpolate(int32_t a, int32_t b, double ratio);
139
+	int32_t GenerateSample();
140
+	void IncrementSample();
141
+};
142
+
143
+#endif