Browse code

Replace the Sound View dialog with a wxWidgets-based one.

* Removes the one that was orignally based entirely on the DeSmuME one, while still looking most the same but cleaner.
* To accommodate this, I needed to rework how wxWidgets was initialized so the configuration dialog boxes could also work alongside this.
* Needed to add a custom wxApp to handle the above.
* This also means that the configuration dialog no longer needs the plugin's HINSTANCE passed along.
* Had to not disable wxGauge or wxToogleButton for the Sound View dialog.
* Also remove the now-unneeded enums in the XSFConfig*.cpp files.
* Sound View is still done in a thread so its event loop can run independently from the rest of the plugin.
* XSFConfig_NCSF doesn't need to be the one to start the Sound View dialog now.

Naram Qashat authored on 2021/04/10 15:19:43
Showing 1 changed files
... ...
@@ -18,19 +18,35 @@
18 18
 #include <vector>
19 19
 #include <cstddef>
20 20
 #include <cstdint>
21
+#ifdef __GNUC__
22
+# pragma GCC diagnostic push
23
+# pragma GCC diagnostic ignored "-Wold-style-cast"
24
+#elif defined(__clang__)
25
+# pragma clang diagnostic push
26
+# pragma clang diagnostic ignored "-Wold-style-cast"
27
+#endif
28
+#include <wx/app.h>
29
+#ifdef __GNUC__
30
+# pragma GCC diagnostic pop
31
+#elif defined(__clang__)
32
+# pragma clang diagnostic pop
33
+#endif
21 34
 #include <zlib.h>
35
+#include "SSEQPlayer/common.h"
36
+#include "SSEQPlayer/consts.h"
37
+#include "SSEQPlayer/Player.h"
38
+#include "SSEQPlayer/SDAT.h"
39
+#include "XSFApp.h"
40
+#include "XSFApp_NCSF.h"
22 41
 #include "XSFCommon.h"
23 42
 #include "XSFConfig_NCSF.h"
24 43
 #include "XSFPlayer_NCSF.h"
25
-#include "SSEQPlayer/SDAT.h"
26
-#include "SSEQPlayer/Player.h"
27
-#include "SSEQPlayer/common.h"
28
-#include "SSEQPlayer/consts.h"
29 44
 
30 45
 const char *XSFPlayer::WinampDescription = "NCSF Decoder";
31 46
 const char *XSFPlayer::WinampExts = "ncsf;minincsf\0DS Nitro Composer Sound Format files (*.ncsf;*.minincsf)\0";
32 47
 
33 48
 extern std::unique_ptr<XSFConfig> xSFConfig;
49
+extern std::unique_ptr<XSFApp> xSFApp;
34 50
 
35 51
 XSFPlayer *XSFPlayer::Create(const std::filesystem::path &path)
36 52
 {
... ...
@@ -105,23 +121,10 @@ XSFPlayer_NCSF::XSFPlayer_NCSF(const std::filesystem::path &path) : XSFPlayer(),
105 121
 }
106 122
 
107 123
 static std::unique_ptr<std::thread> soundViewThreadHandle;
108
-static std::atomic_bool killSoundViewThread;
109 124
 
110 125
 static void soundViewThread(XSFPlayer_NCSF *player)
111 126
 {
112
-	auto xSFConfig_NCSF = static_cast<XSFConfig_NCSF *>(xSFConfig.get());
113
-	xSFConfig_NCSF->CallSoundView(player, xSFConfig->GetHInstance(), nullptr);
114
-	MSG msg;
115
-	while (!killSoundViewThread)
116
-	{
117
-		xSFConfig_NCSF->RefreshSoundView();
118
-		if (PeekMessageW(&msg, nullptr, 0, 0, PM_REMOVE))
119
-		{
120
-			TranslateMessage(&msg);
121
-			DispatchMessageW(&msg);
122
-		}
123
-	}
124
-	xSFConfig_NCSF->CloseSoundView();
127
+	static_cast<XSFApp_NCSF *>(xSFApp.get())->CreateSoundView(static_cast<XSFConfig_NCSF *>(xSFConfig.get()), player);
125 128
 }
126 129
 
127 130
 XSFPlayer_NCSF::~XSFPlayer_NCSF()
... ...
@@ -135,10 +138,7 @@ bool XSFPlayer_NCSF::Load()
135 138
 		return false;
136 139
 
137 140
 	if (this->useSoundViewDialog)
138
-	{
139
-		killSoundViewThread = false;
140 141
 		soundViewThreadHandle.reset(new std::thread(soundViewThread, this));
141
-	}
142 142
 
143 143
 	PseudoFile file;
144 144
 	file.data = &this->sdatData;
... ...
@@ -210,9 +210,12 @@ void XSFPlayer_NCSF::Terminate()
210 210
 {
211 211
 	this->player.Stop(true);
212 212
 
213
-	killSoundViewThread = true;
214
-	soundViewThreadHandle->join();
215
-	soundViewThreadHandle.reset();
213
+	if (soundViewThreadHandle)
214
+	{
215
+		static_cast<XSFApp_NCSF *>(xSFApp.get())->DestroySoundView();
216
+		soundViewThreadHandle->join();
217
+		soundViewThreadHandle.reset();
218
+	}
216 219
 }
217 220
 
218 221
 void XSFPlayer_NCSF::SetUseSoundViewDialog(bool newUseSoundViewDialog)
Browse code

Move muldiv7 to SSEQPlayer's common.h.

(Basically I was using the same function in 2 files and why do that when I could make it a common thing.)

Naram Qashat authored on 2021/04/07 23:52:06
Showing 1 changed files
... ...
@@ -156,11 +156,6 @@ bool XSFPlayer_NCSF::Load()
156 156
 	return XSFPlayer::Load();
157 157
 }
158 158
 
159
-static inline std::int32_t muldiv7(std::int32_t val, std::uint8_t mul)
160
-{
161
-	return mul == 127 ? val : ((val * mul) >> 7);
162
-}
163
-
164 159
 void XSFPlayer_NCSF::GenerateSamples(std::vector<std::uint8_t> &buf, unsigned offset, unsigned samples)
165 160
 {
166 161
 	unsigned long mute = this->mutes.to_ulong();
Browse code

Use std::thread in place of the Windows API CreateThread.

Naram Qashat authored on 2021/04/07 21:52:53
Showing 1 changed files
... ...
@@ -9,10 +9,12 @@
9 9
  */
10 10
 
11 11
 #include <algorithm>
12
+#include <atomic>
12 13
 #include <bitset>
13 14
 #include <filesystem>
14 15
 #include <memory>
15 16
 #include <string>
17
+#include <thread>
16 18
 #include <vector>
17 19
 #include <cstddef>
18 20
 #include <cstdint>
... ...
@@ -102,13 +104,13 @@ XSFPlayer_NCSF::XSFPlayer_NCSF(const std::filesystem::path &path) : XSFPlayer(),
102 104
 	this->xSF.reset(new XSFFile(path, 8, 12));
103 105
 }
104 106
 
105
-static HANDLE soundViewThreadHandle = INVALID_HANDLE_VALUE;
106
-static bool killSoundViewThread;
107
+static std::unique_ptr<std::thread> soundViewThreadHandle;
108
+static std::atomic_bool killSoundViewThread;
107 109
 
108
-static DWORD WINAPI soundViewThread(void *b)
110
+static void soundViewThread(XSFPlayer_NCSF *player)
109 111
 {
110 112
 	auto xSFConfig_NCSF = static_cast<XSFConfig_NCSF *>(xSFConfig.get());
111
-	xSFConfig_NCSF->CallSoundView(static_cast<XSFPlayer_NCSF *>(b), xSFConfig->GetHInstance(), nullptr);
113
+	xSFConfig_NCSF->CallSoundView(player, xSFConfig->GetHInstance(), nullptr);
112 114
 	MSG msg;
113 115
 	while (!killSoundViewThread)
114 116
 	{
... ...
@@ -120,7 +122,6 @@ static DWORD WINAPI soundViewThread(void *b)
120 122
 		}
121 123
 	}
122 124
 	xSFConfig_NCSF->CloseSoundView();
123
-	return 0;
124 125
 }
125 126
 
126 127
 XSFPlayer_NCSF::~XSFPlayer_NCSF()
... ...
@@ -136,7 +137,7 @@ bool XSFPlayer_NCSF::Load()
136 137
 	if (this->useSoundViewDialog)
137 138
 	{
138 139
 		killSoundViewThread = false;
139
-		soundViewThreadHandle = CreateThread(nullptr, 0, soundViewThread, this, 0, nullptr);
140
+		soundViewThreadHandle.reset(new std::thread(soundViewThread, this));
140 141
 	}
141 142
 
142 143
 	PseudoFile file;
... ...
@@ -214,17 +215,9 @@ void XSFPlayer_NCSF::Terminate()
214 215
 {
215 216
 	this->player.Stop(true);
216 217
 
217
-	if (soundViewThreadHandle != INVALID_HANDLE_VALUE)
218
-	{
219
-		killSoundViewThread = true;
220
-		if (WaitForSingleObject(soundViewThreadHandle, 2000) == WAIT_TIMEOUT)
221
-		{
222
-			TerminateThread(soundViewThreadHandle, 0);
223
-			static_cast<XSFConfig_NCSF *>(xSFConfig.get())->CloseSoundView();
224
-		}
225
-		CloseHandle(soundViewThreadHandle);
226
-		soundViewThreadHandle = INVALID_HANDLE_VALUE;
227
-	}
218
+	killSoundViewThread = true;
219
+	soundViewThreadHandle->join();
220
+	soundViewThreadHandle.reset();
228 221
 }
229 222
 
230 223
 void XSFPlayer_NCSF::SetUseSoundViewDialog(bool newUseSoundViewDialog)
Browse code

Fix compile issues because of the earlier std::unique_ptr change in in_xsf.cpp.

Naram Qashat authored on 2021/04/07 00:29:13
Showing 1 changed files
... ...
@@ -28,7 +28,7 @@
28 28
 const char *XSFPlayer::WinampDescription = "NCSF Decoder";
29 29
 const char *XSFPlayer::WinampExts = "ncsf;minincsf\0DS Nitro Composer Sound Format files (*.ncsf;*.minincsf)\0";
30 30
 
31
-extern XSFConfig *xSFConfig;
31
+extern std::unique_ptr<XSFConfig> xSFConfig;
32 32
 
33 33
 XSFPlayer *XSFPlayer::Create(const std::filesystem::path &path)
34 34
 {
... ...
@@ -107,7 +107,7 @@ static bool killSoundViewThread;
107 107
 
108 108
 static DWORD WINAPI soundViewThread(void *b)
109 109
 {
110
-	auto xSFConfig_NCSF = static_cast<XSFConfig_NCSF *>(xSFConfig);
110
+	auto xSFConfig_NCSF = static_cast<XSFConfig_NCSF *>(xSFConfig.get());
111 111
 	xSFConfig_NCSF->CallSoundView(static_cast<XSFPlayer_NCSF *>(b), xSFConfig->GetHInstance(), nullptr);
112 112
 	MSG msg;
113 113
 	while (!killSoundViewThread)
... ...
@@ -220,7 +220,7 @@ void XSFPlayer_NCSF::Terminate()
220 220
 		if (WaitForSingleObject(soundViewThreadHandle, 2000) == WAIT_TIMEOUT)
221 221
 		{
222 222
 			TerminateThread(soundViewThreadHandle, 0);
223
-			static_cast<XSFConfig_NCSF *>(xSFConfig)->CloseSoundView();
223
+			static_cast<XSFConfig_NCSF *>(xSFConfig.get())->CloseSoundView();
224 224
 		}
225 225
 		CloseHandle(soundViewThreadHandle);
226 226
 		soundViewThreadHandle = INVALID_HANDLE_VALUE;
Browse code

Make the NCSF Sound View dialog always available.

(Before it was only available under Debug builds.)

Naram Qashat authored on 2021/04/06 22:29:00
Showing 1 changed files
... ...
@@ -96,16 +96,12 @@ bool XSFPlayer_NCSF::LoadNCSF()
96 96
 	return this->RecursiveLoadNCSF(this->xSF.get(), 1);
97 97
 }
98 98
 
99
-XSFPlayer_NCSF::XSFPlayer_NCSF(const std::filesystem::path &path) : XSFPlayer(), sseq(0), sdatData(), sdat(), player(), secondsPerSample(0), secondsIntoPlayback(0), secondsUntilNextClock(0), mutes()
100
-#ifndef NDEBUG
101
-	, useSoundViewDialog(false)
102
-#endif
99
+XSFPlayer_NCSF::XSFPlayer_NCSF(const std::filesystem::path &path) : XSFPlayer(), sseq(0), sdatData(), sdat(), player(), secondsPerSample(0), secondsIntoPlayback(0), secondsUntilNextClock(0), mutes(), useSoundViewDialog(false)
103 100
 {
104 101
 	this->uses32BitSamplesClampedTo16Bit = true;
105 102
 	this->xSF.reset(new XSFFile(path, 8, 12));
106 103
 }
107 104
 
108
-#ifndef NDEBUG
109 105
 static HANDLE soundViewThreadHandle = INVALID_HANDLE_VALUE;
110 106
 static bool killSoundViewThread;
111 107
 
... ...
@@ -126,7 +122,6 @@ static DWORD WINAPI soundViewThread(void *b)
126 122
 	xSFConfig_NCSF->CloseSoundView();
127 123
 	return 0;
128 124
 }
129
-#endif
130 125
 
131 126
 XSFPlayer_NCSF::~XSFPlayer_NCSF()
132 127
 {
... ...
@@ -138,13 +133,11 @@ bool XSFPlayer_NCSF::Load()
138 133
 	if (!this->LoadNCSF())
139 134
 		return false;
140 135
 
141
-#ifndef NDEBUG
142 136
 	if (this->useSoundViewDialog)
143 137
 	{
144 138
 		killSoundViewThread = false;
145 139
 		soundViewThreadHandle = CreateThread(nullptr, 0, soundViewThread, this, 0, nullptr);
146 140
 	}
147
-#endif
148 141
 
149 142
 	PseudoFile file;
150 143
 	file.data = &this->sdatData;
... ...
@@ -221,7 +214,6 @@ void XSFPlayer_NCSF::Terminate()
221 214
 {
222 215
 	this->player.Stop(true);
223 216
 
224
-#ifndef NDEBUG
225 217
 	if (soundViewThreadHandle != INVALID_HANDLE_VALUE)
226 218
 	{
227 219
 		killSoundViewThread = true;
... ...
@@ -233,15 +225,12 @@ void XSFPlayer_NCSF::Terminate()
233 225
 		CloseHandle(soundViewThreadHandle);
234 226
 		soundViewThreadHandle = INVALID_HANDLE_VALUE;
235 227
 	}
236
-#endif
237 228
 }
238 229
 
239
-#ifndef NDEBUG
240 230
 void XSFPlayer_NCSF::SetUseSoundViewDialog(bool newUseSoundViewDialog)
241 231
 {
242 232
 	this->useSoundViewDialog = newUseSoundViewDialog;
243 233
 }
244
-#endif
245 234
 
246 235
 void XSFPlayer_NCSF::SetInterpolation(unsigned interpolation)
247 236
 {
... ...
@@ -253,9 +242,7 @@ void XSFPlayer_NCSF::SetMutes(const std::bitset<16> &newMutes)
253 242
 	this->mutes = newMutes;
254 243
 }
255 244
 
256
-#ifndef NDEBUG
257 245
 const Channel &XSFPlayer_NCSF::GetChannel(std::size_t chanNum) const
258 246
 {
259 247
 	return this->player.channels[chanNum];
260 248
 }
261
-#endif
Browse code

Use std::unique_ptr in in_xsf.cpp.

Also move the code of the NCSF Player's destructor to Terminate() and call Terminate() in the destructor.

Naram Qashat authored on 2021/04/06 20:45:29
Showing 1 changed files
... ...
@@ -130,19 +130,7 @@ static DWORD WINAPI soundViewThread(void *b)
130 130
 
131 131
 XSFPlayer_NCSF::~XSFPlayer_NCSF()
132 132
 {
133
-#ifndef NDEBUG
134
-	if (soundViewThreadHandle != INVALID_HANDLE_VALUE)
135
-	{
136
-		killSoundViewThread = true;
137
-		if (WaitForSingleObject(soundViewThreadHandle, 2000) == WAIT_TIMEOUT)
138
-		{
139
-			TerminateThread(soundViewThreadHandle, 0);
140
-			static_cast<XSFConfig_NCSF *>(xSFConfig)->CloseSoundView();
141
-		}
142
-		CloseHandle(soundViewThreadHandle);
143
-		soundViewThreadHandle = INVALID_HANDLE_VALUE;
144
-	}
145
-#endif
133
+	this->Terminate();
146 134
 }
147 135
 
148 136
 bool XSFPlayer_NCSF::Load()
... ...
@@ -232,6 +220,20 @@ void XSFPlayer_NCSF::GenerateSamples(std::vector<std::uint8_t> &buf, unsigned of
232 220
 void XSFPlayer_NCSF::Terminate()
233 221
 {
234 222
 	this->player.Stop(true);
223
+
224
+#ifndef NDEBUG
225
+	if (soundViewThreadHandle != INVALID_HANDLE_VALUE)
226
+	{
227
+		killSoundViewThread = true;
228
+		if (WaitForSingleObject(soundViewThreadHandle, 2000) == WAIT_TIMEOUT)
229
+		{
230
+			TerminateThread(soundViewThreadHandle, 0);
231
+			static_cast<XSFConfig_NCSF *>(xSFConfig)->CloseSoundView();
232
+		}
233
+		CloseHandle(soundViewThreadHandle);
234
+		soundViewThreadHandle = INVALID_HANDLE_VALUE;
235
+	}
236
+#endif
235 237
 }
236 238
 
237 239
 #ifndef NDEBUG
Browse code

Use std::filesystem::path for reading/writing files.

Also remove fstream_wfopen.h as it is no longer needed.
Also make XSFFile not store the string of the path but store the path as std::filesystem::path.

Naram Qashat authored on 2021/04/05 00:20:56
Showing 1 changed files
... ...
@@ -30,18 +30,11 @@ const char *XSFPlayer::WinampExts = "ncsf;minincsf\0DS Nitro Composer Sound Form
30 30
 
31 31
 extern XSFConfig *xSFConfig;
32 32
 
33
-XSFPlayer *XSFPlayer::Create(const std::string &fn)
33
+XSFPlayer *XSFPlayer::Create(const std::filesystem::path &path)
34 34
 {
35
-	return new XSFPlayer_NCSF(fn);
35
+	return new XSFPlayer_NCSF(path);
36 36
 }
37 37
 
38
-#ifdef _WIN32
39
-XSFPlayer *XSFPlayer::Create(const std::wstring &fn)
40
-{
41
-	return new XSFPlayer_NCSF(fn);
42
-}
43
-#endif
44
-
45 38
 void XSFPlayer_NCSF::MapNCSFSection(const std::vector<std::uint8_t> &section)
46 39
 {
47 40
 	std::uint32_t size = Get32BitsLE(&section[8]), finalSize = size;
... ...
@@ -72,11 +65,7 @@ bool XSFPlayer_NCSF::RecursiveLoadNCSF(XSFFile *xSFToLoad, int level)
72 65
 {
73 66
 	if (level <= 10 && xSFToLoad->GetTagExists("_lib"))
74 67
 	{
75
-#ifdef _WIN32
76
-		auto libxSF = std::make_unique<XSFFile>((std::filesystem::path(xSFToLoad->GetFilename()).parent_path() / xSFToLoad->GetTagValue("_lib")).wstring(), 8, 12);
77
-#else
78
-		auto libxSF = std::make_unique<XSFFile>((std::filesystem::path(xSFToLoad->GetFilename()).parent_path() / xSFToLoad->GetTagValue("_lib")).string(), 8, 12);
79
-#endif
68
+		auto libxSF = std::make_unique<XSFFile>(xSFToLoad->GetFilepath().parent_path() / xSFToLoad->GetTagValue("_lib"), 8, 12);
80 69
 		if (!this->RecursiveLoadNCSF(libxSF.get(), level + 1))
81 70
 			return false;
82 71
 	}
... ...
@@ -93,11 +82,7 @@ bool XSFPlayer_NCSF::RecursiveLoadNCSF(XSFFile *xSFToLoad, int level)
93 82
 		if (xSFToLoad->GetTagExists(libTag))
94 83
 		{
95 84
 			found = true;
96
-#ifdef _WIN32
97
-			auto libxSF = std::make_unique<XSFFile>((std::filesystem::path(xSFToLoad->GetFilename()).parent_path() / xSFToLoad->GetTagValue(libTag)).wstring(), 8, 12);
98
-#else
99
-			auto libxSF = std::make_unique<XSFFile>((std::filesystem::path(xSFToLoad->GetFilename()).parent_path() / xSFToLoad->GetTagValue(libTag)).string(), 8, 12);
100
-#endif
85
+			auto libxSF = std::make_unique<XSFFile>(xSFToLoad->GetFilepath().parent_path() / xSFToLoad->GetTagValue(libTag), 8, 12);
101 86
 			if (!this->RecursiveLoadNCSF(libxSF.get(), level + 1))
102 87
 				return false;
103 88
 		}
... ...
@@ -111,25 +96,14 @@ bool XSFPlayer_NCSF::LoadNCSF()
111 96
 	return this->RecursiveLoadNCSF(this->xSF.get(), 1);
112 97
 }
113 98
 
114
-XSFPlayer_NCSF::XSFPlayer_NCSF(const std::string &filename) : XSFPlayer(), sseq(0), sdatData(), sdat(), player(), secondsPerSample(0), secondsIntoPlayback(0), secondsUntilNextClock(0), mutes()
115
-#ifndef NDEBUG
116
-	, useSoundViewDialog(false)
117
-#endif
118
-{
119
-	this->uses32BitSamplesClampedTo16Bit = true;
120
-	this->xSF.reset(new XSFFile(filename, 8, 12));
121
-}
122
-
123
-#ifdef _WIN32
124
-XSFPlayer_NCSF::XSFPlayer_NCSF(const std::wstring &filename) : XSFPlayer(), sseq(0), sdatData(), sdat(), player(), secondsPerSample(0), secondsIntoPlayback(0), secondsUntilNextClock(0), mutes()
99
+XSFPlayer_NCSF::XSFPlayer_NCSF(const std::filesystem::path &path) : XSFPlayer(), sseq(0), sdatData(), sdat(), player(), secondsPerSample(0), secondsIntoPlayback(0), secondsUntilNextClock(0), mutes()
125 100
 #ifndef NDEBUG
126 101
 	, useSoundViewDialog(false)
127 102
 #endif
128 103
 {
129 104
 	this->uses32BitSamplesClampedTo16Bit = true;
130
-	this->xSF.reset(new XSFFile(filename, 8, 12));
105
+	this->xSF.reset(new XSFFile(path, 8, 12));
131 106
 }
132
-#endif
133 107
 
134 108
 #ifndef NDEBUG
135 109
 static HANDLE soundViewThreadHandle = INVALID_HANDLE_VALUE;
Browse code

Add wxWidgets-based configuration dialog boxes.

* Removes the configuration dialog boxes that used my DialogBuilder.
* Move default configuration values to be inlined within the headers.
* Moved 2SF's and GSF's XSFConfig classes to their own headers to accommodate the new wxWidgets dialog boxes.
* Make it so NCSF's SoundView dialog can be toggled on or off from the configuration dialog box.

Naram Qashat authored on 2021/04/04 12:46:14
Showing 1 changed files
... ...
@@ -112,6 +112,9 @@ bool XSFPlayer_NCSF::LoadNCSF()
112 112
 }
113 113
 
114 114
 XSFPlayer_NCSF::XSFPlayer_NCSF(const std::string &filename) : XSFPlayer(), sseq(0), sdatData(), sdat(), player(), secondsPerSample(0), secondsIntoPlayback(0), secondsUntilNextClock(0), mutes()
115
+#ifndef NDEBUG
116
+	, useSoundViewDialog(false)
117
+#endif
115 118
 {
116 119
 	this->uses32BitSamplesClampedTo16Bit = true;
117 120
 	this->xSF.reset(new XSFFile(filename, 8, 12));
... ...
@@ -119,6 +122,9 @@ XSFPlayer_NCSF::XSFPlayer_NCSF(const std::string &filename) : XSFPlayer(), sseq(
119 122
 
120 123
 #ifdef _WIN32
121 124
 XSFPlayer_NCSF::XSFPlayer_NCSF(const std::wstring &filename) : XSFPlayer(), sseq(0), sdatData(), sdat(), player(), secondsPerSample(0), secondsIntoPlayback(0), secondsUntilNextClock(0), mutes()
125
+#ifndef NDEBUG
126
+	, useSoundViewDialog(false)
127
+#endif
122 128
 {
123 129
 	this->uses32BitSamplesClampedTo16Bit = true;
124 130
 	this->xSF.reset(new XSFFile(filename, 8, 12));
... ...
@@ -151,14 +157,17 @@ static DWORD WINAPI soundViewThread(void *b)
151 157
 XSFPlayer_NCSF::~XSFPlayer_NCSF()
152 158
 {
153 159
 #ifndef NDEBUG
154
-	killSoundViewThread = true;
155
-	if (WaitForSingleObject(soundViewThreadHandle, 2000) == WAIT_TIMEOUT)
160
+	if (soundViewThreadHandle != INVALID_HANDLE_VALUE)
156 161
 	{
157
-		TerminateThread(soundViewThreadHandle, 0);
158
-		static_cast<XSFConfig_NCSF *>(xSFConfig)->CloseSoundView();
162
+		killSoundViewThread = true;
163
+		if (WaitForSingleObject(soundViewThreadHandle, 2000) == WAIT_TIMEOUT)
164
+		{
165
+			TerminateThread(soundViewThreadHandle, 0);
166
+			static_cast<XSFConfig_NCSF *>(xSFConfig)->CloseSoundView();
167
+		}
168
+		CloseHandle(soundViewThreadHandle);
169
+		soundViewThreadHandle = INVALID_HANDLE_VALUE;
159 170
 	}
160
-	CloseHandle(soundViewThreadHandle);
161
-	soundViewThreadHandle = INVALID_HANDLE_VALUE;
162 171
 #endif
163 172
 }
164 173
 
... ...
@@ -168,8 +177,11 @@ bool XSFPlayer_NCSF::Load()
168 177
 		return false;
169 178
 
170 179
 #ifndef NDEBUG
171
-	killSoundViewThread = false;
172
-	soundViewThreadHandle = CreateThread(nullptr, 0, soundViewThread, this, 0, nullptr);
180
+	if (this->useSoundViewDialog)
181
+	{
182
+		killSoundViewThread = false;
183
+		soundViewThreadHandle = CreateThread(nullptr, 0, soundViewThread, this, 0, nullptr);
184
+	}
173 185
 #endif
174 186
 
175 187
 	PseudoFile file;
... ...
@@ -248,6 +260,13 @@ void XSFPlayer_NCSF::Terminate()
248 260
 	this->player.Stop(true);
249 261
 }
250 262
 
263
+#ifndef NDEBUG
264
+void XSFPlayer_NCSF::SetUseSoundViewDialog(bool newUseSoundViewDialog)
265
+{
266
+	this->useSoundViewDialog = newUseSoundViewDialog;
267
+}
268
+#endif
269
+
251 270
 void XSFPlayer_NCSF::SetInterpolation(unsigned interpolation)
252 271
 {
253 272
 	this->player.interpolation = static_cast<Interpolation>(interpolation);
Browse code

Replace #ifdef _DEBUG with #ifndef NDEBUG

Naram Qashat authored on 2021/04/03 11:24:08
Showing 1 changed files
... ...
@@ -125,7 +125,7 @@ XSFPlayer_NCSF::XSFPlayer_NCSF(const std::wstring &filename) : XSFPlayer(), sseq
125 125
 }
126 126
 #endif
127 127
 
128
-#ifdef _DEBUG
128
+#ifndef NDEBUG
129 129
 static HANDLE soundViewThreadHandle = INVALID_HANDLE_VALUE;
130 130
 static bool killSoundViewThread;
131 131
 
... ...
@@ -150,7 +150,7 @@ static DWORD WINAPI soundViewThread(void *b)
150 150
 
151 151
 XSFPlayer_NCSF::~XSFPlayer_NCSF()
152 152
 {
153
-#ifdef _DEBUG
153
+#ifndef NDEBUG
154 154
 	killSoundViewThread = true;
155 155
 	if (WaitForSingleObject(soundViewThreadHandle, 2000) == WAIT_TIMEOUT)
156 156
 	{
... ...
@@ -167,7 +167,7 @@ bool XSFPlayer_NCSF::Load()
167 167
 	if (!this->LoadNCSF())
168 168
 		return false;
169 169
 
170
-#ifdef _DEBUG
170
+#ifndef NDEBUG
171 171
 	killSoundViewThread = false;
172 172
 	soundViewThreadHandle = CreateThread(nullptr, 0, soundViewThread, this, 0, nullptr);
173 173
 #endif
... ...
@@ -258,7 +258,7 @@ void XSFPlayer_NCSF::SetMutes(const std::bitset<16> &newMutes)
258 258
 	this->mutes = newMutes;
259 259
 }
260 260
 
261
-#ifdef _DEBUG
261
+#ifndef NDEBUG
262 262
 const Channel &XSFPlayer_NCSF::GetChannel(std::size_t chanNum) const
263 263
 {
264 264
 	return this->player.channels[chanNum];
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
... ...
@@ -8,17 +8,22 @@
8 8
  * https://github.com/fincs/FSS
9 9
  */
10 10
 
11
+#include <algorithm>
12
+#include <bitset>
11 13
 #include <filesystem>
12 14
 #include <memory>
13
-#include <cstdlib>
14
-#include <ctime>
15
+#include <string>
16
+#include <vector>
17
+#include <cstddef>
18
+#include <cstdint>
15 19
 #include <zlib.h>
16
-#include "convert.h"
17
-#include "XSFPlayer_NCSF.h"
18
-#include "XSFConfig_NCSF.h"
19 20
 #include "XSFCommon.h"
21
+#include "XSFConfig_NCSF.h"
22
+#include "XSFPlayer_NCSF.h"
20 23
 #include "SSEQPlayer/SDAT.h"
21 24
 #include "SSEQPlayer/Player.h"
25
+#include "SSEQPlayer/common.h"
26
+#include "SSEQPlayer/consts.h"
22 27
 
23 28
 const char *XSFPlayer::WinampDescription = "NCSF Decoder";
24 29
 const char *XSFPlayer::WinampExts = "ncsf;minincsf\0DS Nitro Composer Sound Format files (*.ncsf;*.minincsf)\0";
... ...
@@ -37,9 +42,9 @@ XSFPlayer *XSFPlayer::Create(const std::wstring &fn)
37 42
 }
38 43
 #endif
39 44
 
40
-void XSFPlayer_NCSF::MapNCSFSection(const std::vector<uint8_t> &section)
45
+void XSFPlayer_NCSF::MapNCSFSection(const std::vector<std::uint8_t> &section)
41 46
 {
42
-	uint32_t size = Get32BitsLE(&section[8]), finalSize = size;
47
+	std::uint32_t size = Get32BitsLE(&section[8]), finalSize = size;
43 48
 	if (this->sdatData.empty())
44 49
 		this->sdatData.resize(finalSize, 0);
45 50
 	else if (this->sdatData.size() < size)
... ...
@@ -183,12 +188,12 @@ bool XSFPlayer_NCSF::Load()
183 188
 	return XSFPlayer::Load();
184 189
 }
185 190
 
186
-static inline int32_t muldiv7(int32_t val, uint8_t mul)
191
+static inline std::int32_t muldiv7(std::int32_t val, std::uint8_t mul)
187 192
 {
188 193
 	return mul == 127 ? val : ((val * mul) >> 7);
189 194
 }
190 195
 
191
-void XSFPlayer_NCSF::GenerateSamples(std::vector<uint8_t> &buf, unsigned offset, unsigned samples)
196
+void XSFPlayer_NCSF::GenerateSamples(std::vector<std::uint8_t> &buf, unsigned offset, unsigned samples)
192 197
 {
193 198
 	unsigned long mute = this->mutes.to_ulong();
194 199
 
... ...
@@ -196,22 +201,22 @@ void XSFPlayer_NCSF::GenerateSamples(std::vector<uint8_t> &buf, unsigned offset,
196 201
 	{
197 202
 		this->secondsIntoPlayback += this->secondsPerSample;
198 203
 
199
-		int32_t leftChannel = 0, rightChannel = 0;
204
+		std::int32_t leftChannel = 0, rightChannel = 0;
200 205
 
201 206
 		// I need to advance the sound channels here
202 207
 		for (int i = 0; i < 16; ++i)
203 208
 		{
204 209
 			Channel &chn = this->player.channels[i];
205 210
 
206
-			if (chn.state > CS_NONE)
211
+			if (chn.state > ChannelState::None)
207 212
 			{
208
-				int32_t sample = chn.GenerateSample();
213
+				std::int32_t sample = chn.GenerateSample();
209 214
 				chn.IncrementSample();
210 215
 
211 216
 				if (mute & BIT(i))
212 217
 					continue;
213 218
 
214
-				uint8_t datashift = chn.reg.volumeDiv;
219
+				std::uint8_t datashift = chn.reg.volumeDiv;
215 220
 				if (datashift == 3)
216 221
 					datashift = 4;
217 222
 				sample = muldiv7(sample, chn.reg.volumeMul) >> datashift;
... ...
@@ -254,7 +259,7 @@ void XSFPlayer_NCSF::SetMutes(const std::bitset<16> &newMutes)
254 259
 }
255 260
 
256 261
 #ifdef _DEBUG
257
-const Channel &XSFPlayer_NCSF::GetChannel(size_t chanNum) const
262
+const Channel &XSFPlayer_NCSF::GetChannel(std::size_t chanNum) const
258 263
 {
259 264
 	return this->player.channels[chanNum];
260 265
 }
Browse code

Correct a few warnings Visual Studio was complaining about.

Naram Qashat authored on 2021/03/20 20:40:21
Showing 1 changed files
... ...
@@ -106,14 +106,14 @@ bool XSFPlayer_NCSF::LoadNCSF()
106 106
 	return this->RecursiveLoadNCSF(this->xSF.get(), 1);
107 107
 }
108 108
 
109
-XSFPlayer_NCSF::XSFPlayer_NCSF(const std::string &filename) : XSFPlayer()
109
+XSFPlayer_NCSF::XSFPlayer_NCSF(const std::string &filename) : XSFPlayer(), sseq(0), sdatData(), sdat(), player(), secondsPerSample(0), secondsIntoPlayback(0), secondsUntilNextClock(0), mutes()
110 110
 {
111 111
 	this->uses32BitSamplesClampedTo16Bit = true;
112 112
 	this->xSF.reset(new XSFFile(filename, 8, 12));
113 113
 }
114 114
 
115 115
 #ifdef _WIN32
116
-XSFPlayer_NCSF::XSFPlayer_NCSF(const std::wstring &filename) : XSFPlayer()
116
+XSFPlayer_NCSF::XSFPlayer_NCSF(const std::wstring &filename) : XSFPlayer(), sseq(0), sdatData(), sdat(), player(), secondsPerSample(0), secondsIntoPlayback(0), secondsUntilNextClock(0), mutes()
117 117
 {
118 118
 	this->uses32BitSamplesClampedTo16Bit = true;
119 119
 	this->xSF.reset(new XSFFile(filename, 8, 12));
Browse code

Use C++17 std::filesystem functions instead of my own.

Naram Qashat authored on 2021/03/20 20:05:50
Showing 1 changed files
... ...
@@ -8,6 +8,7 @@
8 8
  * https://github.com/fincs/FSS
9 9
  */
10 10
 
11
+#include <filesystem>
11 12
 #include <memory>
12 13
 #include <cstdlib>
13 14
 #include <ctime>
... ...
@@ -67,9 +68,9 @@ bool XSFPlayer_NCSF::RecursiveLoadNCSF(XSFFile *xSFToLoad, int level)
67 68
 	if (level <= 10 && xSFToLoad->GetTagExists("_lib"))
68 69
 	{
69 70
 #ifdef _WIN32
70
-		auto libxSF = std::make_unique<XSFFile>(ConvertFuncs::StringToWString(ExtractDirectoryFromPath(xSFToLoad->GetFilename()) + xSFToLoad->GetTagValue("_lib")), 8, 12);
71
+		auto libxSF = std::make_unique<XSFFile>((std::filesystem::path(xSFToLoad->GetFilename()).parent_path() / xSFToLoad->GetTagValue("_lib")).wstring(), 8, 12);
71 72
 #else
72
-		auto libxSF = std::make_unique<XSFFile>(ExtractDirectoryFromPath(xSFToLoad->GetFilename()) + xSFToLoad->GetTagValue("_lib"), 8, 12);
73
+		auto libxSF = std::make_unique<XSFFile>((std::filesystem::path(xSFToLoad->GetFilename()).parent_path() / xSFToLoad->GetTagValue("_lib")).string(), 8, 12);
73 74
 #endif
74 75
 		if (!this->RecursiveLoadNCSF(libxSF.get(), level + 1))
75 76
 			return false;
... ...
@@ -88,9 +89,9 @@ bool XSFPlayer_NCSF::RecursiveLoadNCSF(XSFFile *xSFToLoad, int level)
88 89
 		{
89 90
 			found = true;
90 91
 #ifdef _WIN32
91
-			auto libxSF = std::make_unique<XSFFile>(ConvertFuncs::StringToWString(ExtractDirectoryFromPath(xSFToLoad->GetFilename()) + xSFToLoad->GetTagValue(libTag)), 8, 12);
92
+			auto libxSF = std::make_unique<XSFFile>((std::filesystem::path(xSFToLoad->GetFilename()).parent_path() / xSFToLoad->GetTagValue(libTag)).wstring(), 8, 12);
92 93
 #else
93
-			auto libxSF = std::make_unique<XSFFile>(ExtractDirectoryFromPath(xSFToLoad->GetFilename()) + xSFToLoad->GetTagValue(libTag), 8, 12);
94
+			auto libxSF = std::make_unique<XSFFile>((std::filesystem::path(xSFToLoad->GetFilename()).parent_path() / xSFToLoad->GetTagValue(libTag)).string(), 8, 12);
94 95
 #endif
95 96
 			if (!this->RecursiveLoadNCSF(libxSF.get(), level + 1))
96 97
 				return false;
Browse code

Replace std::rand with RNG based on actual DS RNG.

(This also means the playback of songs with randomness in them will be deterministic now.)

Naram Qashat authored on 2021/03/20 18:46:24
Showing 1 changed files
... ...
@@ -166,8 +166,6 @@ bool XSFPlayer_NCSF::Load()
166 166
 	soundViewThreadHandle = CreateThread(nullptr, 0, soundViewThread, this, 0, nullptr);
167 167
 #endif
168 168
 
169
-	std::srand(static_cast<unsigned>(std::time(nullptr)));
170
-
171 169
 	PseudoFile file;
172 170
 	file.data = &this->sdatData;
173 171
 	this->sdat.reset(new SDAT(file, this->sseq));
Browse code

Use std::make_unique where possible.

Naram Qashat authored on 2021/03/20 04:37:08
Showing 1 changed files
... ...
@@ -67,9 +67,9 @@ bool XSFPlayer_NCSF::RecursiveLoadNCSF(XSFFile *xSFToLoad, int level)
67 67
 	if (level <= 10 && xSFToLoad->GetTagExists("_lib"))
68 68
 	{
69 69
 #ifdef _WIN32
70
-		auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ConvertFuncs::StringToWString(ExtractDirectoryFromPath(xSFToLoad->GetFilename()) + xSFToLoad->GetTagValue("_lib")), 8, 12));
70
+		auto libxSF = std::make_unique<XSFFile>(ConvertFuncs::StringToWString(ExtractDirectoryFromPath(xSFToLoad->GetFilename()) + xSFToLoad->GetTagValue("_lib")), 8, 12);
71 71
 #else
72
-		auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename()) + xSFToLoad->GetTagValue("_lib"), 8, 12));
72
+		auto libxSF = std::make_unique<XSFFile>(ExtractDirectoryFromPath(xSFToLoad->GetFilename()) + xSFToLoad->GetTagValue("_lib"), 8, 12);
73 73
 #endif
74 74
 		if (!this->RecursiveLoadNCSF(libxSF.get(), level + 1))
75 75
 			return false;
... ...
@@ -88,9 +88,9 @@ bool XSFPlayer_NCSF::RecursiveLoadNCSF(XSFFile *xSFToLoad, int level)
88 88
 		{
89 89
 			found = true;
90 90
 #ifdef _WIN32
91
-			auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ConvertFuncs::StringToWString(ExtractDirectoryFromPath(xSFToLoad->GetFilename()) + xSFToLoad->GetTagValue(libTag)), 8, 12));
91
+			auto libxSF = std::make_unique<XSFFile>(ConvertFuncs::StringToWString(ExtractDirectoryFromPath(xSFToLoad->GetFilename()) + xSFToLoad->GetTagValue(libTag)), 8, 12);
92 92
 #else
93
-			auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename()) + xSFToLoad->GetTagValue(libTag), 8, 12));
93
+			auto libxSF = std::make_unique<XSFFile>(ExtractDirectoryFromPath(xSFToLoad->GetFilename()) + xSFToLoad->GetTagValue(libTag), 8, 12);
94 94
 #endif
95 95
 			if (!this->RecursiveLoadNCSF(libxSF.get(), level + 1))
96 96
 				return false;
Browse code

Replace memcpy/memset with std::copy_n/std::fill_n.

Naram Qashat authored on 2021/03/19 16:25:21
Showing 1 changed files
... ...
@@ -43,7 +43,7 @@ void XSFPlayer_NCSF::MapNCSFSection(const std::vector<uint8_t> &section)
43 43
 		this->sdatData.resize(finalSize, 0);
44 44
 	else if (this->sdatData.size() < size)
45 45
 		this->sdatData.resize(finalSize);
46
-	memcpy(&this->sdatData[0], &section[0], size);
46
+	std::copy_n(&section[0], size, &this->sdatData[0]);
47 47
 }
48 48
 
49 49
 bool XSFPlayer_NCSF::MapNCSF(XSFFile *xSFToLoad)
Browse code

Some conversion replacements:

* Replace the (w)stringify functions with the standard std::to_(w)string functions.
* Replace convertTo with versions that use type_traits to determine which standard string conversion function to call, as well as handle enums specically.

Naram Qashat authored on 2021/03/19 11:57:21
Showing 1 changed files
... ...
@@ -83,7 +83,7 @@ bool XSFPlayer_NCSF::RecursiveLoadNCSF(XSFFile *xSFToLoad, int level)
83 83
 	do
84 84
 	{
85 85
 		found = false;
86
-		std::string libTag = "_lib" + stringify(n++);
86
+		std::string libTag = "_lib" + std::to_string(n++);
87 87
 		if (xSFToLoad->GetTagExists(libTag))
88 88
 		{
89 89
 			found = true;
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 - NCSF Player
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2014-10-25
5 4
  *
6 5
  * Partially based on the vio*sf framework
7 6
  *
Browse code

[NCSF] Utilize the PLAYER blocks in the SDAT if they exist.

Backwards compatibility is kept by treating the lack of PLAYER info as
if all channels are able to be allocated.

Naram Qashat authored on 2014/10/25 23:12:53
Showing 1 changed files
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * xSF - NCSF Player
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2014-10-18
4
+ * Last modification on 2014-10-25
5 5
  *
6 6
  * Partially based on the vio*sf framework
7 7
  *
... ...
@@ -173,6 +173,7 @@ bool XSFPlayer_NCSF::Load()
173 173
 	file.data = &this->sdatData;
174 174
 	this->sdat.reset(new SDAT(file, this->sseq));
175 175
 	auto *sseqToPlay = this->sdat->sseq.get();
176
+	this->player.allowedChannels = std::bitset<16>(this->sdat->player.channelMask);
176 177
 	this->player.sseqVol = Cnv_Scale(sseqToPlay->info.vol);
177 178
 	this->player.sampleRate = this->sampleRate;
178 179
 	this->player.Setup(sseqToPlay);
Browse code

[NCSF] Correctly handle the SSEQ volume from the INFO block.

Naram Qashat authored on 2014/10/18 04:20:53
Showing 1 changed files
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * xSF - NCSF Player
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2014-10-13
4
+ * Last modification on 2014-10-18
5 5
  *
6 6
  * Partially based on the vio*sf framework
7 7
  *
... ...
@@ -173,10 +173,9 @@ bool XSFPlayer_NCSF::Load()
173 173
 	file.data = &this->sdatData;
174 174
 	this->sdat.reset(new SDAT(file, this->sseq));
175 175
 	auto *sseqToPlay = this->sdat->sseq.get();
176
-	this->sseqVol = sseqToPlay->info.vol;
176
+	this->player.sseqVol = Cnv_Scale(sseqToPlay->info.vol);
177 177
 	this->player.sampleRate = this->sampleRate;
178 178
 	this->player.Setup(sseqToPlay);
179
-	//this->player.masterVol = sseqToPlay->info.vol;
180 179
 	this->player.Timer();
181 180
 	this->secondsPerSample = 1.0 / this->sampleRate;
182 181
 	this->secondsIntoPlayback = 0;
... ...
@@ -223,12 +222,6 @@ void XSFPlayer_NCSF::GenerateSamples(std::vector<uint8_t> &buf, unsigned offset,
223 222
 			}
224 223
 		}
225 224
 
226
-		leftChannel = muldiv7(leftChannel, 127 - this->player.masterVol);
227
-		rightChannel = muldiv7(rightChannel, 127 - this->player.masterVol);
228
-
229
-		//leftChannel = muldiv7(leftChannel, this->sseqVol);
230
-		//rightChannel = muldiv7(rightChannel, this->sseqVol);
231
-
232 225
 		buf[offset++] = leftChannel & 0xFF;
233 226
 		buf[offset++] = (leftChannel >> 8) & 0xFF;
234 227
 		buf[offset++] = (leftChannel >> 16) & 0xFF;
Browse code

[NCSF] Implemented the random, variable, and conditional commands. Also fixed loop counter.

Naram Qashat authored on 2014/10/13 18:00:29
Showing 1 changed files
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * xSF - NCSF Player
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2014-10-05
4
+ * Last modification on 2014-10-13
5 5
  *
6 6
  * Partially based on the vio*sf framework
7 7
  *
... ...
@@ -10,6 +10,8 @@
10 10
  */
11 11
 
12 12
 #include <memory>
13
+#include <cstdlib>
14
+#include <ctime>
13 15
 #include <zlib.h>
14 16
 #include "convert.h"
15 17
 #include "XSFPlayer_NCSF.h"
... ...
@@ -165,6 +167,8 @@ bool XSFPlayer_NCSF::Load()
165 167
 	soundViewThreadHandle = CreateThread(nullptr, 0, soundViewThread, this, 0, nullptr);
166 168
 #endif
167 169
 
170
+	std::srand(static_cast<unsigned>(std::time(nullptr)));
171
+
168 172
 	PseudoFile file;
169 173
 	file.data = &this->sdatData;
170 174
 	this->sdat.reset(new SDAT(file, this->sseq));
Browse code

Reverted the sound changes back to the original FSS code, but with the fix to clamp the total volume.

Also commented out the code that uses the SSEQ's volume, it seems as if
the DS doesn't use it so I probably shouldn't be using it either.

Naram Qashat authored on 2014/10/07 17:45:05
Showing 1 changed files
... ...
@@ -222,8 +222,8 @@ void XSFPlayer_NCSF::GenerateSamples(std::vector<uint8_t> &buf, unsigned offset,
222 222
 		leftChannel = muldiv7(leftChannel, 127 - this->player.masterVol);
223 223
 		rightChannel = muldiv7(rightChannel, 127 - this->player.masterVol);
224 224
 
225
-		leftChannel = muldiv7(leftChannel, this->sseqVol);
226
-		rightChannel = muldiv7(rightChannel, this->sseqVol);
225
+		//leftChannel = muldiv7(leftChannel, this->sseqVol);
226
+		//rightChannel = muldiv7(rightChannel, this->sseqVol);
227 227
 
228 228
 		buf[offset++] = leftChannel & 0xFF;
229 229
 		buf[offset++] = (leftChannel >> 8) & 0xFF;
Browse code

[NCSF] Fix volume issues with a little help from the Nintendo DS SDK.

Also added a clone of DeSmuME's Sound View that is only build during a
debug build, which helped to identify the above issues.

Naram Qashat authored on 2014/10/05 20:00:09
Showing 1 changed files
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * xSF - NCSF Player
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2014-09-24
4
+ * Last modification on 2014-10-05
5 5
  *
6 6
  * Partially based on the vio*sf framework
7 7
  *
... ...
@@ -13,6 +13,7 @@
13 13
 #include <zlib.h>
14 14
 #include "convert.h"
15 15
 #include "XSFPlayer_NCSF.h"
16
+#include "XSFConfig_NCSF.h"
16 17
 #include "XSFCommon.h"
17 18
 #include "SSEQPlayer/SDAT.h"
18 19
 #include "SSEQPlayer/Player.h"
... ...
@@ -20,6 +21,8 @@
20 21
 const char *XSFPlayer::WinampDescription = "NCSF Decoder";
21 22
 const char *XSFPlayer::WinampExts = "ncsf;minincsf\0DS Nitro Composer Sound Format files (*.ncsf;*.minincsf)\0";
22 23
 
24
+extern XSFConfig *xSFConfig;
25
+
23 26
 XSFPlayer *XSFPlayer::Create(const std::string &fn)
24 27
 {
25 28
 	return new XSFPlayer_NCSF(fn);
... ...
@@ -115,11 +118,53 @@ XSFPlayer_NCSF::XSFPlayer_NCSF(const std::wstring &filename) : XSFPlayer()
115 118
 }
116 119
 #endif
117 120
 
121
+#ifdef _DEBUG
122
+static HANDLE soundViewThreadHandle = INVALID_HANDLE_VALUE;
123
+static bool killSoundViewThread;
124
+
125
+static DWORD WINAPI soundViewThread(void *b)
126
+{
127
+	auto xSFConfig_NCSF = static_cast<XSFConfig_NCSF *>(xSFConfig);
128
+	xSFConfig_NCSF->CallSoundView(static_cast<XSFPlayer_NCSF *>(b), xSFConfig->GetHInstance(), nullptr);
129
+	MSG msg;
130
+	while (!killSoundViewThread)
131
+	{
132
+		xSFConfig_NCSF->RefreshSoundView();
133
+		if (PeekMessageW(&msg, nullptr, 0, 0, PM_REMOVE))
134
+		{
135
+			TranslateMessage(&msg);
136
+			DispatchMessageW(&msg);
137
+		}
138
+	}
139
+	xSFConfig_NCSF->CloseSoundView();
140
+	return 0;
141
+}
142
+#endif
143
+
144
+XSFPlayer_NCSF::~XSFPlayer_NCSF()
145
+{
146
+#ifdef _DEBUG
147
+	killSoundViewThread = true;
148
+	if (WaitForSingleObject(soundViewThreadHandle, 2000) == WAIT_TIMEOUT)
149
+	{
150
+		TerminateThread(soundViewThreadHandle, 0);
151
+		static_cast<XSFConfig_NCSF *>(xSFConfig)->CloseSoundView();
152
+	}
153
+	CloseHandle(soundViewThreadHandle);
154
+	soundViewThreadHandle = INVALID_HANDLE_VALUE;
155
+#endif
156
+}
157
+
118 158
 bool XSFPlayer_NCSF::Load()
119 159
 {
120 160
 	if (!this->LoadNCSF())
121 161
 		return false;
122 162
 
163
+#ifdef _DEBUG
164
+	killSoundViewThread = false;
165
+	soundViewThreadHandle = CreateThread(nullptr, 0, soundViewThread, this, 0, nullptr);
166
+#endif
167
+
123 168
 	PseudoFile file;
124 169
 	file.data = &this->sdatData;
125 170
 	this->sdat.reset(new SDAT(file, this->sseq));
... ...
@@ -211,3 +256,10 @@ void XSFPlayer_NCSF::SetMutes(const std::bitset<16> &newMutes)
211 256
 {
212 257
 	this->mutes = newMutes;
213 258
 }
259
+
260
+#ifdef _DEBUG
261
+const Channel &XSFPlayer_NCSF::GetChannel(size_t chanNum) const
262
+{
263
+	return this->player.channels[chanNum];
264
+}
265
+#endif
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 - NCSF Player
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2014-09-17
4
+ * Last modification on 2014-09-24
5 5
  *
6 6
  * Partially based on the vio*sf framework
7 7
  *
... ...
@@ -25,7 +25,7 @@ XSFPlayer *XSFPlayer::Create(const std::string &fn)
25 25
 	return new XSFPlayer_NCSF(fn);
26 26
 }
27 27
 
28
-#ifdef _MSC_VER
28
+#ifdef _WIN32
29 29
 XSFPlayer *XSFPlayer::Create(const std::wstring &fn)
30 30
 {
31 31
 	return new XSFPlayer_NCSF(fn);
... ...
@@ -62,10 +62,10 @@ bool XSFPlayer_NCSF::RecursiveLoadNCSF(XSFFile *xSFToLoad, int level)
62 62
 {
63 63
 	if (level <= 10 && xSFToLoad->GetTagExists("_lib"))
64 64
 	{
65
-#ifdef _MSC_VER
66
-		auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename().GetWStr()) + xSFToLoad->GetTagValue("_lib").GetWStr(), 8, 12));
65
+#ifdef _WIN32
66
+		auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ConvertFuncs::StringToWString(ExtractDirectoryFromPath(xSFToLoad->GetFilename()) + xSFToLoad->GetTagValue("_lib")), 8, 12));
67 67
 #else
68
-		auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename().GetAnsi()) + xSFToLoad->GetTagValue("_lib").GetAnsi(), 8, 12));
68
+		auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename()) + xSFToLoad->GetTagValue("_lib"), 8, 12));
69 69
 #endif
70 70
 		if (!this->RecursiveLoadNCSF(libxSF.get(), level + 1))
71 71
 			return false;
... ...
@@ -83,10 +83,10 @@ bool XSFPlayer_NCSF::RecursiveLoadNCSF(XSFFile *xSFToLoad, int level)
83 83
 		if (xSFToLoad->GetTagExists(libTag))
84 84
 		{
85 85
 			found = true;
86
-#ifdef _MSC_VER
87
-			auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename().GetWStr()) + xSFToLoad->GetTagValue(libTag).GetWStr(), 8, 12));
86
+#ifdef _WIN32
87
+			auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ConvertFuncs::StringToWString(ExtractDirectoryFromPath(xSFToLoad->GetFilename()) + xSFToLoad->GetTagValue(libTag)), 8, 12));
88 88
 #else
89
-			auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename().GetAnsi()) + xSFToLoad->GetTagValue(libTag).GetAnsi(), 8, 12));
89
+			auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename()) + xSFToLoad->GetTagValue(libTag), 8, 12));
90 90
 #endif
91 91
 			if (!this->RecursiveLoadNCSF(libxSF.get(), level + 1))
92 92
 				return false;
... ...
@@ -107,7 +107,7 @@ XSFPlayer_NCSF::XSFPlayer_NCSF(const std::string &filename) : XSFPlayer()
107 107
 	this->xSF.reset(new XSFFile(filename, 8, 12));
108 108
 }
109 109
 
110
-#ifdef _MSC_VER
110
+#ifdef _WIN32
111 111
 XSFPlayer_NCSF::XSFPlayer_NCSF(const std::wstring &filename) : XSFPlayer()
112 112
 {
113 113
 	this->uses32BitSamplesClampedTo16Bit = true;
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
  * xSF - NCSF Player
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2013-04-26
4
+ * Last modification on 2014-09-17
5 5
  *
6 6
  * Partially based on the vio*sf framework
7 7
  *
... ...
@@ -25,10 +25,12 @@ XSFPlayer *XSFPlayer::Create(const std::string &fn)
25 25
 	return new XSFPlayer_NCSF(fn);
26 26
 }
27 27
 
28
+#ifdef _MSC_VER
28 29
 XSFPlayer *XSFPlayer::Create(const std::wstring &fn)
29 30
 {
30 31
 	return new XSFPlayer_NCSF(fn);
31 32
 }
33
+#endif
32 34
 
33 35
 void XSFPlayer_NCSF::MapNCSFSection(const std::vector<uint8_t> &section)
34 36
 {
... ...
@@ -60,7 +62,7 @@ bool XSFPlayer_NCSF::RecursiveLoadNCSF(XSFFile *xSFToLoad, int level)
60 62
 {
61 63
 	if (level <= 10 && xSFToLoad->GetTagExists("_lib"))
62 64
 	{
63
-#ifdef _WIN32
65
+#ifdef _MSC_VER
64 66
 		auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename().GetWStr()) + xSFToLoad->GetTagValue("_lib").GetWStr(), 8, 12));
65 67
 #else
66 68
 		auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename().GetAnsi()) + xSFToLoad->GetTagValue("_lib").GetAnsi(), 8, 12));
... ...
@@ -81,7 +83,7 @@ bool XSFPlayer_NCSF::RecursiveLoadNCSF(XSFFile *xSFToLoad, int level)
81 83
 		if (xSFToLoad->GetTagExists(libTag))
82 84
 		{
83 85
 			found = true;
84
-#ifdef _WIN32
86
+#ifdef _MSC_VER
85 87
 			auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename().GetWStr()) + xSFToLoad->GetTagValue(libTag).GetWStr(), 8, 12));
86 88
 #else
87 89
 			auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename().GetAnsi()) + xSFToLoad->GetTagValue(libTag).GetAnsi(), 8, 12));
... ...
@@ -105,11 +107,13 @@ XSFPlayer_NCSF::XSFPlayer_NCSF(const std::string &filename) : XSFPlayer()
105 107
 	this->xSF.reset(new XSFFile(filename, 8, 12));
106 108
 }
107 109
 
110
+#ifdef _MSC_VER
108 111
 XSFPlayer_NCSF::XSFPlayer_NCSF(const std::wstring &filename) : XSFPlayer()
109 112
 {
110 113
 	this->uses32BitSamplesClampedTo16Bit = true;
111 114
 	this->xSF.reset(new XSFFile(filename, 8, 12));
112 115
 }
116
+#endif
113 117
 
114 118
 bool XSFPlayer_NCSF::Load()
115 119
 {
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 - NCSF 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
  *
... ...
@@ -101,11 +101,13 @@ bool XSFPlayer_NCSF::LoadNCSF()
101 101
 
102 102
 XSFPlayer_NCSF::XSFPlayer_NCSF(const std::string &filename) : XSFPlayer()
103 103
 {
104
+	this->uses32BitSamplesClampedTo16Bit = true;
104 105
 	this->xSF.reset(new XSFFile(filename, 8, 12));
105 106
 }
106 107
 
107 108
 XSFPlayer_NCSF::XSFPlayer_NCSF(const std::wstring &filename) : XSFPlayer()
108 109
 {
110
+	this->uses32BitSamplesClampedTo16Bit = true;
109 111
 	this->xSF.reset(new XSFFile(filename, 8, 12));
110 112
 }
111 113
 
... ...
@@ -130,14 +132,6 @@ bool XSFPlayer_NCSF::Load()
130 132
 	return XSFPlayer::Load();
131 133
 }
132 134
 
133
-template<typename T1, typename T2> static inline void clamp(T1 &valueToClamp, const T2 &minValue, const T2 &maxValue)
134
-{
135
-	if (valueToClamp < minValue)
136
-		valueToClamp = minValue;
137
-	else if (valueToClamp > maxValue)
138
-		valueToClamp = maxValue;
139
-}
140
-
141 135
 static inline int32_t muldiv7(int32_t val, uint8_t mul)
142 136
 {
143 137
 	return mul == 127 ? val : ((val * mul) >> 7);
... ...
@@ -182,13 +176,14 @@ void XSFPlayer_NCSF::GenerateSamples(std::vector<uint8_t> &buf, unsigned offset,
182 176
 		leftChannel = muldiv7(leftChannel, this->sseqVol);
183 177
 		rightChannel = muldiv7(rightChannel, this->sseqVol);
184 178
 
185
-		clamp(leftChannel, -0x8000, 0x7FFF);
186
-		clamp(rightChannel, -0x8000, 0x7FFF);
187
-
188 179
 		buf[offset++] = leftChannel & 0xFF;
189 180
 		buf[offset++] = (leftChannel >> 8) & 0xFF;
181
+		buf[offset++] = (leftChannel >> 16) & 0xFF;
182
+		buf[offset++] = (leftChannel >> 24) & 0xFF;
190 183
 		buf[offset++] = rightChannel & 0xFF;
191 184
 		buf[offset++] = (rightChannel >> 8) & 0xFF;
185
+		buf[offset++] = (rightChannel >> 16) & 0xFF;
186
+		buf[offset++] = (rightChannel >> 24) & 0xFF;
192 187
 
193 188
 		if (this->secondsIntoPlayback > this->secondsUntilNextClock)
194 189
 		{
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 - NCSF Player
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2013-04-01
4
+ * Last modification on 2013-04-23
5 5
  *
6 6
  * Partially based on the vio*sf framework
7 7
  *
... ...
@@ -96,17 +96,17 @@ bool XSFPlayer_NCSF::RecursiveLoadNCSF(XSFFile *xSFToLoad, int level)
96 96
 
97 97
 bool XSFPlayer_NCSF::LoadNCSF()
98 98
 {
99
-	return this->RecursiveLoadNCSF(this->xSF, 1);
99
+	return this->RecursiveLoadNCSF(this->xSF.get(), 1);
100 100
 }
101 101
 
102 102
 XSFPlayer_NCSF::XSFPlayer_NCSF(const std::string &filename) : XSFPlayer()
103 103
 {
104
-	this->xSF = new XSFFile(filename, 8, 12);
104
+	this->xSF.reset(new XSFFile(filename, 8, 12));
105 105
 }
106 106
 
107 107
 XSFPlayer_NCSF::XSFPlayer_NCSF(const std::wstring &filename) : XSFPlayer()
108 108
 {
109
-	this->xSF = new XSFFile(filename, 8, 12);
109
+	this->xSF.reset(new XSFFile(filename, 8, 12));
110 110
 }
111 111
 
112 112
 bool XSFPlayer_NCSF::Load()
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
... ...
@@ -118,9 +118,10 @@ bool XSFPlayer_NCSF::Load()
118 118
 	file.data = &this->sdatData;
119 119
 	this->sdat.reset(new SDAT(file, this->sseq));
120 120
 	auto *sseqToPlay = this->sdat->sseq.get();
121
+	this->sseqVol = sseqToPlay->info.vol;
121 122
 	this->player.sampleRate = this->sampleRate;
122 123
 	this->player.Setup(sseqToPlay);
123
-	//this->player.masterVol = sseq->info.vol;
124
+	//this->player.masterVol = sseqToPlay->info.vol;
124 125
 	this->player.Timer();
125 126
 	this->secondsPerSample = 1.0 / this->sampleRate;
126 127
 	this->secondsIntoPlayback = 0;
... ...
@@ -178,6 +179,9 @@ void XSFPlayer_NCSF::GenerateSamples(std::vector<uint8_t> &buf, unsigned offset,
178 179
 		leftChannel = muldiv7(leftChannel, 127 - this->player.masterVol);
179 180
 		rightChannel = muldiv7(rightChannel, 127 - this->player.masterVol);
180 181
 
182
+		leftChannel = muldiv7(leftChannel, this->sseqVol);
183
+		rightChannel = muldiv7(rightChannel, this->sseqVol);
184
+
181 185
 		clamp(leftChannel, -0x8000, 0x7FFF);
182 186
 		clamp(rightChannel, -0x8000, 0x7FFF);
183 187
 
Browse code

Corrected issue with terminating the SSEQ player by actually making it stop properly.

Naram Qashat authored on 2013/04/02 03:03:26
Showing 1 changed files
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * xSF - NCSF Player
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2013-03-30
4
+ * Last modification on 2013-04-01
5 5
  *
6 6
  * Partially based on the vio*sf framework
7 7
  *
... ...
@@ -194,6 +194,11 @@ void XSFPlayer_NCSF::GenerateSamples(std::vector<uint8_t> &buf, unsigned offset,
194 194
 	}
195 195
 }
196 196
 
197
+void XSFPlayer_NCSF::Terminate()
198
+{
199
+	this->player.Stop(true);
200
+}
201
+
197 202
 void XSFPlayer_NCSF::SetInterpolation(unsigned interpolation)
198 203
 {
199 204
 	this->player.interpolation = static_cast<Interpolation>(interpolation);
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 - NCSF Player
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2013-03-25
4
+ * Last modification on 2013-03-30
5 5
  *
6 6
  * Partially based on the vio*sf framework
7 7
  *
Browse code

Utilized more C++11 constructs. Also attempted to fix issue with the Info Box not wanting to come up anymore if the file doesn't exist.

Naram Qashat authored on 2013/03/30 07:36:38
Showing 1 changed files
... ...
@@ -61,9 +61,9 @@ bool XSFPlayer_NCSF::RecursiveLoadNCSF(XSFFile *xSFToLoad, int level)
61 61
 	if (level <= 10 && xSFToLoad->GetTagExists("_lib"))
62 62
 	{
63 63
 #ifdef _WIN32
64
-		auto libxSF = std::auto_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename().GetWStr()) + xSFToLoad->GetTagValue("_lib").GetWStr(), 8, 12));
64
+		auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename().GetWStr()) + xSFToLoad->GetTagValue("_lib").GetWStr(), 8, 12));
65 65
 #else
66
-		auto libxSF = std::auto_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename().GetAnsi()) + xSFToLoad->GetTagValue("_lib").GetAnsi(), 8, 12));
66
+		auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename().GetAnsi()) + xSFToLoad->GetTagValue("_lib").GetAnsi(), 8, 12));
67 67
 #endif
68 68
 		if (!this->RecursiveLoadNCSF(libxSF.get(), level + 1))
69 69
 			return false;
... ...
@@ -82,9 +82,9 @@ bool XSFPlayer_NCSF::RecursiveLoadNCSF(XSFFile *xSFToLoad, int level)
82 82
 		{
83 83
 			found = true;
84 84
 #ifdef _WIN32
85
-			auto libxSF = std::auto_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename().GetWStr()) + xSFToLoad->GetTagValue(libTag).GetWStr(), 8, 12));
85
+			auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename().GetWStr()) + xSFToLoad->GetTagValue(libTag).GetWStr(), 8, 12));
86 86
 #else
87
-			auto libxSF = std::auto_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename().GetAnsi()) + xSFToLoad->GetTagValue(libTag).GetAnsi(), 8, 12));
87
+			auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename().GetAnsi()) + xSFToLoad->GetTagValue(libTag).GetAnsi(), 8, 12));
88 88
 #endif
89 89
 			if (!this->RecursiveLoadNCSF(libxSF.get(), level + 1))
90 90
 				return false;
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,205 @@
1
+/*
2
+ * xSF - NCSF Player
3
+ * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
+ * Last modification on 2013-03-25
5
+ *
6
+ * Partially based on the vio*sf framework
7
+ *
8
+ * Utilizes a modified FeOS Sound System for playback
9
+ * https://github.com/fincs/FSS
10
+ */
11
+
12
+#include <memory>
13
+#include <zlib.h>
14
+#include "convert.h"
15
+#include "XSFPlayer_NCSF.h"
16
+#include "XSFCommon.h"
17
+#include "SSEQPlayer/SDAT.h"
18
+#include "SSEQPlayer/Player.h"
19
+
20
+const char *XSFPlayer::WinampDescription = "NCSF Decoder";
21
+const char *XSFPlayer::WinampExts = "ncsf;minincsf\0DS Nitro Composer Sound Format files (*.ncsf;*.minincsf)\0";
22
+
23
+XSFPlayer *XSFPlayer::Create(const std::string &fn)
24
+{
25
+	return new XSFPlayer_NCSF(fn);
26
+}
27
+
28
+XSFPlayer *XSFPlayer::Create(const std::wstring &fn)
29
+{
30
+	return new XSFPlayer_NCSF(fn);
31
+}
32
+
33
+void XSFPlayer_NCSF::MapNCSFSection(const std::vector<uint8_t> &section)
34
+{
35
+	uint32_t size = Get32BitsLE(&section[8]), finalSize = size;
36
+	if (this->sdatData.empty())
37
+		this->sdatData.resize(finalSize, 0);
38
+	else if (this->sdatData.size() < size)
39
+		this->sdatData.resize(finalSize);
40
+	memcpy(&this->sdatData[0], &section[0], size);
41
+}
42
+
43
+bool XSFPlayer_NCSF::MapNCSF(XSFFile *xSFToLoad)
44
+{
45
+	if (!xSFToLoad->IsValidType(0x25))
46
+		return false;
47
+
48
+	auto &reservedSection = xSFToLoad->GetReservedSection(), &programSection = xSFToLoad->GetProgramSection();
49
+
50
+	if (!reservedSection.empty())
51
+		this->sseq = Get32BitsLE(&reservedSection[0]);
52
+
53
+	if (!programSection.empty())
54
+		this->MapNCSFSection(programSection);
55
+
56
+	return true;
57
+}
58
+
59
+bool XSFPlayer_NCSF::RecursiveLoadNCSF(XSFFile *xSFToLoad, int level)
60
+{
61
+	if (level <= 10 && xSFToLoad->GetTagExists("_lib"))
62
+	{
63
+#ifdef _WIN32
64
+		auto libxSF = std::auto_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename().GetWStr()) + xSFToLoad->GetTagValue("_lib").GetWStr(), 8, 12));
65
+#else
66
+		auto libxSF = std::auto_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename().GetAnsi()) + xSFToLoad->GetTagValue("_lib").GetAnsi(), 8, 12));
67
+#endif
68
+		if (!this->RecursiveLoadNCSF(libxSF.get(), level + 1))
69
+			return false;
70
+	}
71
+
72
+	if (!this->MapNCSF(xSFToLoad))
73
+		return false;
74
+
75
+	unsigned n = 2;
76
+	bool found;
77
+	do
78
+	{
79
+		found = false;
80
+		std::string libTag = "_lib" + stringify(n++);
81
+		if (xSFToLoad->GetTagExists(libTag))
82
+		{
83
+			found = true;
84
+#ifdef _WIN32
85
+			auto libxSF = std::auto_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename().GetWStr()) + xSFToLoad->GetTagValue(libTag).GetWStr(), 8, 12));
86
+#else
87
+			auto libxSF = std::auto_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename().GetAnsi()) + xSFToLoad->GetTagValue(libTag).GetAnsi(), 8, 12));
88
+#endif
89
+			if (!this->RecursiveLoadNCSF(libxSF.get(), level + 1))
90
+				return false;
91
+		}
92
+	} while (found);
93
+
94
+	return true;
95
+}
96
+
97
+bool XSFPlayer_NCSF::LoadNCSF()
98
+{
99
+	return this->RecursiveLoadNCSF(this->xSF, 1);
100
+}
101
+
102
+XSFPlayer_NCSF::XSFPlayer_NCSF(const std::string &filename) : XSFPlayer()
103
+{
104
+	this->xSF = new XSFFile(filename, 8, 12);
105
+}
106
+
107
+XSFPlayer_NCSF::XSFPlayer_NCSF(const std::wstring &filename) : XSFPlayer()
108
+{
109
+	this->xSF = new XSFFile(filename, 8, 12);
110
+}
111
+
112
+bool XSFPlayer_NCSF::Load()
113
+{
114
+	if (!this->LoadNCSF())
115
+		return false;
116
+
117
+	PseudoFile file;
118
+	file.data = &this->sdatData;
119
+	this->sdat.reset(new SDAT(file, this->sseq));
120
+	auto *sseqToPlay = this->sdat->sseq.get();
121
+	this->player.sampleRate = this->sampleRate;
122
+	this->player.Setup(sseqToPlay);
123
+	//this->player.masterVol = sseq->info.vol;
124
+	this->player.Timer();
125
+	this->secondsPerSample = 1.0 / this->sampleRate;
126
+	this->secondsIntoPlayback = 0;
127
+	this->secondsUntilNextClock = SecondsPerClockCycle;
128
+
129
+	return XSFPlayer::Load();
130
+}
131
+
132
+template<typename T1, typename T2> static inline void clamp(T1 &valueToClamp, const T2 &minValue, const T2 &maxValue)
133
+{
134
+	if (valueToClamp < minValue)
135
+		valueToClamp = minValue;
136
+	else if (valueToClamp > maxValue)
137
+		valueToClamp = maxValue;
138
+}
139
+
140
+static inline int32_t muldiv7(int32_t val, uint8_t mul)
141
+{
142
+	return mul == 127 ? val : ((val * mul) >> 7);
143
+}
144
+
145
+void XSFPlayer_NCSF::GenerateSamples(std::vector<uint8_t> &buf, unsigned offset, unsigned samples)
146
+{
147
+	unsigned long mute = this->mutes.to_ulong();
148
+
149
+	for (unsigned smpl = 0; smpl < samples; ++smpl)
150
+	{
151
+		this->secondsIntoPlayback += this->secondsPerSample;
152
+
153
+		int32_t leftChannel = 0, rightChannel = 0;
154
+
155
+		// I need to advance the sound channels here
156
+		for (int i = 0; i < 16; ++i)
157
+		{
158
+			Channel &chn = this->player.channels[i];
159
+
160
+			if (chn.state > CS_NONE)
161
+			{
162
+				int32_t sample = chn.GenerateSample();
163
+				chn.IncrementSample();
164
+
165
+				if (mute & BIT(i))
166
+					continue;
167
+
168
+				uint8_t datashift = chn.reg.volumeDiv;
169
+				if (datashift == 3)
170
+					datashift = 4;
171
+				sample = muldiv7(sample, chn.reg.volumeMul) >> datashift;
172
+
173
+				leftChannel += muldiv7(sample, 127 - chn.reg.panning);
174
+				rightChannel += muldiv7(sample, chn.reg.panning);
175
+			}
176
+		}
177
+
178
+		leftChannel = muldiv7(leftChannel, 127 - this->player.masterVol);
179
+		rightChannel = muldiv7(rightChannel, 127 - this->player.masterVol);
180
+
181
+		clamp(leftChannel, -0x8000, 0x7FFF);
182
+		clamp(rightChannel, -0x8000, 0x7FFF);
183
+
184
+		buf[offset++] = leftChannel & 0xFF;
185
+		buf[offset++] = (leftChannel >> 8) & 0xFF;
186
+		buf[offset++] = rightChannel & 0xFF;
187
+		buf[offset++] = (rightChannel >> 8) & 0xFF;
188
+
189
+		if (this->secondsIntoPlayback > this->secondsUntilNextClock)
190
+		{
191
+			this->player.Timer();
192
+			this->secondsUntilNextClock += SecondsPerClockCycle;
193
+		}
194
+	}
195
+}
196
+
197
+void XSFPlayer_NCSF::SetInterpolation(unsigned interpolation)
198
+{
199
+	this->player.interpolation = static_cast<Interpolation>(interpolation);
200
+}
201
+
202
+void XSFPlayer_NCSF::SetMutes(const std::bitset<16> &newMutes)
203
+{
204
+	this->mutes = newMutes;
205
+}