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

--- a/src/in_ncsf/SSEQPlayer/Channel.cpp
+++ b/src/in_ncsf/SSEQPlayer/Channel.cpp
@@ -18,7 +18,7 @@
 #include "common.h"
 
 NDSSoundRegister::NDSSoundRegister() : volumeMul(0), volumeDiv(0), panning(0), waveDuty(0), repeatMode(0), format(0), enable(false),
-	source(nullptr), timer(0), psgX(0), psgLast(0), psgLastCount(0), samplePosition(0), sampleIncrease(0), loopStart(0), length(0)
+	source(nullptr), timer(0), psgX(0), psgLast(0), psgLastCount(0), samplePosition(0), sampleIncrease(0), loopStart(0), length(0), totalLength(0)
 {
 }
 
@@ -418,6 +418,7 @@
 			this->reg.source = this->tempReg.SOURCE;
 			this->reg.loopStart = this->tempReg.REPEAT_POINT;
 			this->reg.length = this->tempReg.LENGTH;
+			this->reg.totalLength = this->reg.loopStart + this->reg.length;
 			this->ampl = AMPL_THRESHOLD;
 			this->state = CS_ATTACK;
 			// Fall down
@@ -587,7 +588,7 @@
 	uint32_t loc = static_cast<uint32_t>(this->reg.samplePosition);
 	const auto &data = &this->reg.source->data[loc];
 	int32_t a = data[0], b;
-	if (loc + 1 < this->reg.loopStart + this->reg.length)
+	if (loc + 1 < this->reg.totalLength)
 		b = data[1];
 	else
 	{
@@ -603,7 +604,7 @@
 	if (this->ply->interpolation == INTERPOLATION_BSPLINE || this->ply->interpolation == INTERPOLATION_HERMITE || this->ply->interpolation == INTERPOLATION_OPTIMAL)
 	{
 		int32_t c, z;
-		if (loc + 2 < this->reg.loopStart + this->reg.length)
+		if (loc + 2 < this->reg.totalLength)
 			c = data[2];
 		else
 		{
@@ -619,7 +620,7 @@
 			z = data[-1];
 		else
 		{
-			if (loc + 1 < this->reg.loopStart + this->reg.length)
+			if (loc + 1 < this->reg.totalLength)
 			{
 				int32_t ap1 = data[1];
 				z = 2 * a - ap1;
@@ -639,7 +640,7 @@
 			c3 = 0.5 * (a - b) + 1 / 6.0 * (c - z);
 			return static_cast<int32_t>(((c3 * ratio + c2) * ratio + c1) * ratio + c0);
 		}
-		if (this->ply->interpolation == INTERPOLATION_HERMITE)
+		else if (this->ply->interpolation == INTERPOLATION_HERMITE)
 		{
 			c0 = a;
 			c1 = 0.5 * (b - z);
@@ -717,11 +718,11 @@
 void Channel::IncrementSample()
 {
 	this->reg.samplePosition += this->reg.sampleIncrease;
-	if (this->reg.format != 3 && this->reg.samplePosition >= (this->reg.loopStart + this->reg.length))
+	if (this->reg.format != 3 && this->reg.samplePosition >= this->reg.totalLength)
 	{
 		if (this->reg.repeatMode == 1)
 		{
-			while (this->reg.samplePosition >= (this->reg.loopStart + this->reg.length))
+			while (this->reg.samplePosition >= this->reg.totalLength)
 				this->reg.samplePosition -= this->reg.length;
 		}
 		else

--- a/src/in_ncsf/SSEQPlayer/Channel.h
+++ b/src/in_ncsf/SSEQPlayer/Channel.h
@@ -57,6 +57,8 @@
 
 	// Length Register
 	uint32_t length;
+
+	uint32_t totalLength;
 
 	NDSSoundRegister();
 

--- a/src/in_ncsf/SSEQPlayer/INFOEntry.cpp
+++ b/src/in_ncsf/SSEQPlayer/INFOEntry.cpp
@@ -9,7 +9,7 @@
 
 #include "INFOEntry.h"
 
-INFOEntrySEQ::INFOEntrySEQ() : fileID(0), bank(0)
+INFOEntrySEQ::INFOEntrySEQ() : fileID(0), bank(0), vol(0)
 {
 }
 
@@ -18,7 +18,9 @@
 	this->fileID = file.ReadLE<uint16_t>();
 	file.ReadLE<uint16_t>(); // unknown
 	this->bank = file.ReadLE<uint16_t>();
-	file.ReadLE<uint8_t>(); // vol
+	this->vol = file.ReadLE<uint8_t>();
+	if (!this->vol)
+		this->vol = 0x7F; // Prevents nothing for volume
 	file.ReadLE<uint8_t>(); // cpr
 	file.ReadLE<uint8_t>(); // ppr
 	file.ReadLE<uint8_t>(); // ply

--- a/src/in_ncsf/SSEQPlayer/INFOEntry.h
+++ b/src/in_ncsf/SSEQPlayer/INFOEntry.h
@@ -25,6 +25,7 @@
 {
 	uint16_t fileID;
 	uint16_t bank;
+	uint8_t vol;
 
 	INFOEntrySEQ();
 

--- a/src/in_ncsf/XSFPlayer_NCSF.cpp
+++ b/src/in_ncsf/XSFPlayer_NCSF.cpp
@@ -118,9 +118,10 @@
 	file.data = &this->sdatData;
 	this->sdat.reset(new SDAT(file, this->sseq));
 	auto *sseqToPlay = this->sdat->sseq.get();
+	this->sseqVol = sseqToPlay->info.vol;
 	this->player.sampleRate = this->sampleRate;
 	this->player.Setup(sseqToPlay);
-	//this->player.masterVol = sseq->info.vol;
+	//this->player.masterVol = sseqToPlay->info.vol;
 	this->player.Timer();
 	this->secondsPerSample = 1.0 / this->sampleRate;
 	this->secondsIntoPlayback = 0;
@@ -177,6 +178,9 @@
 
 		leftChannel = muldiv7(leftChannel, 127 - this->player.masterVol);
 		rightChannel = muldiv7(rightChannel, 127 - this->player.masterVol);
+
+		leftChannel = muldiv7(leftChannel, this->sseqVol);
+		rightChannel = muldiv7(rightChannel, this->sseqVol);
 
 		clamp(leftChannel, -0x8000, 0x7FFF);
 		clamp(rightChannel, -0x8000, 0x7FFF);

--- a/src/in_ncsf/XSFPlayer_NCSF.h
+++ b/src/in_ncsf/XSFPlayer_NCSF.h
@@ -24,6 +24,7 @@
 	std::vector<uint8_t> sdatData;
 	std::unique_ptr<SDAT> sdat;
 	Player player;
+	uint8_t sseqVol;
 	double secondsPerSample, secondsIntoPlayback, secondsUntilNextClock;
 	std::bitset<16> mutes;