| ... | ... |
@@ -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 |
| ... | ... |
@@ -44,7 +44,7 @@ TempSndReg::TempSndReg() : CR(0), SOURCE(nullptr), TIMER(0), REPEAT_POINT(0), LE |
| 44 | 44 |
|
| 45 | 45 |
bool Channel::initializedLUTs = false; |
| 46 | 46 |
double Channel::cosine_lut[Channel::COSINE_RESOLUTION]; |
| 47 |
-double Channel::lanczos_lut[Channel::LANCZOS_SAMPLES + 1]; |
|
| 47 |
+double Channel::sinc_lut[Channel::SINC_SAMPLES + 1]; |
|
| 48 | 48 |
|
| 49 | 49 |
#ifndef M_PI |
| 50 | 50 |
static const double M_PI = 3.14159265358979323846; |
| ... | ... |
@@ -57,16 +57,16 @@ static inline double sinc(double x) |
| 57 | 57 |
|
| 58 | 58 |
Channel::Channel() : chnId(-1), tempReg(), state(CS_NONE), trackId(-1), prio(0), manualSweep(false), flags(), pan(0), extAmpl(0), velocity(0), extPan(0), |
| 59 | 59 |
key(0), ampl(0), extTune(0), orgKey(0), modType(0), modSpeed(0), modDepth(0), modRange(0), modDelay(0), modDelayCnt(0), modCounter(0), |
| 60 |
- sweepLen(0), sweepCnt(0), sweepPitch(0), attackLvl(0), sustainLvl(0x7F), decayRate(0), releaseRate(0xFFFF), noteLength(-1), vol(0), ply(nullptr), reg() |
|
| 60 |
+ sweepLen(0), sweepCnt(0), sweepPitch(0), attackLvl(0), sustainLvl(0x7F), decayRate(0), releaseRate(0xFFFF), noteLength(-1), vol(0), ply(nullptr), reg(), |
|
| 61 |
+ ringBuffer() |
|
| 61 | 62 |
{
|
| 62 |
- this->clearHistory(); |
|
| 63 | 63 |
if (!this->initializedLUTs) |
| 64 | 64 |
{
|
| 65 | 65 |
for (unsigned i = 0; i < COSINE_RESOLUTION; ++i) |
| 66 | 66 |
this->cosine_lut[i] = (1.0 - std::cos((static_cast<double>(i) / COSINE_RESOLUTION) * M_PI)) * 0.5; |
| 67 |
- double dx = static_cast<double>(LANCZOS_WIDTH) / LANCZOS_SAMPLES, x = 0.0; |
|
| 68 |
- for (unsigned i = 0; i <= LANCZOS_SAMPLES; ++i, x += dx) |
|
| 69 |
- this->lanczos_lut[i] = std::abs(x) < LANCZOS_WIDTH ? sinc(x) * sinc(x / LANCZOS_WIDTH) : 0.0; |
|
| 67 |
+ double dx = static_cast<double>(SINC_WIDTH) / SINC_SAMPLES, x = 0.0; |
|
| 68 |
+ for (unsigned i = 0; i <= SINC_SAMPLES; ++i, x += dx) |
|
| 69 |
+ this->sinc_lut[i] = std::abs(x) < SINC_WIDTH ? sinc(x) * (0.5 * (1.0 + std::cos((M_PI * x) / SINC_WIDTH))) : 0.0; |
|
| 70 | 70 |
this->initializedLUTs = true; |
| 71 | 71 |
} |
| 72 | 72 |
} |
| ... | ... |
@@ -144,7 +144,6 @@ void Channel::Kill() |
| 144 | 144 |
this->reg.ClearControlRegister(); |
| 145 | 145 |
this->vol = 0; |
| 146 | 146 |
this->noteLength = -1; |
| 147 |
- this->clearHistory(); |
|
| 148 | 147 |
} |
| 149 | 148 |
|
| 150 | 149 |
static inline int getModFlag(int type) |
| ... | ... |
@@ -604,22 +603,22 @@ int32_t Channel::Interpolate() |
| 604 | 603 |
double ratio = this->reg.samplePosition; |
| 605 | 604 |
ratio -= static_cast<int32_t>(ratio); |
| 606 | 605 |
|
| 607 |
- const auto &data = &this->sampleHistory[this->sampleHistoryPtr + 16]; |
|
| 606 |
+ const auto &data = this->ringBuffer.GetBuffer(); |
|
| 608 | 607 |
|
| 609 |
- if (this->ply->interpolation == INTERPOLATION_LANCZOS) |
|
| 608 |
+ if (this->ply->interpolation == INTERPOLATION_SINC) |
|
| 610 | 609 |
{
|
| 611 |
- double kernel[LANCZOS_WIDTH * 2], kernel_sum = 0.0; |
|
| 612 |
- int i = LANCZOS_WIDTH, shift = static_cast<int>(std::floor(ratio * LANCZOS_RESOLUTION)); |
|
| 613 |
- int step = this->reg.sampleIncrease > 1.0 ? static_cast<int>(LANCZOS_RESOLUTION / this->reg.sampleIncrease) : LANCZOS_RESOLUTION; |
|
| 614 |
- int shift_adj = shift * step / LANCZOS_RESOLUTION; |
|
| 615 |
- for (; i >= -static_cast<int>(LANCZOS_WIDTH - 1); --i) |
|
| 610 |
+ double kernel[SINC_WIDTH * 2], kernel_sum = 0.0; |
|
| 611 |
+ int i = SINC_WIDTH, shift = static_cast<int>(std::floor(ratio * SINC_RESOLUTION)); |
|
| 612 |
+ int step = this->reg.sampleIncrease > 1.0 ? static_cast<int>(SINC_RESOLUTION / this->reg.sampleIncrease) : SINC_RESOLUTION; |
|
| 613 |
+ int shift_adj = shift * step / SINC_RESOLUTION; |
|
| 614 |
+ for (; i >= -static_cast<int>(SINC_WIDTH - 1); --i) |
|
| 616 | 615 |
{
|
| 617 | 616 |
int pos = i * step; |
| 618 |
- kernel_sum += kernel[i + LANCZOS_WIDTH - 1] = this->lanczos_lut[std::abs(shift_adj - pos)]; |
|
| 617 |
+ kernel_sum += kernel[i + SINC_WIDTH - 1] = this->sinc_lut[std::abs(shift_adj - pos)]; |
|
| 619 | 618 |
} |
| 620 | 619 |
double sum = 0.0; |
| 621 |
- for (i = 0; i < static_cast<int>(LANCZOS_WIDTH * 2); ++i) |
|
| 622 |
- sum += data[i - static_cast<int>(LANCZOS_WIDTH) + 1] * kernel[i]; |
|
| 620 |
+ for (i = 0; i < static_cast<int>(SINC_WIDTH * 2); ++i) |
|
| 621 |
+ sum += data[i - static_cast<int>(SINC_WIDTH) + 1] * kernel[i]; |
|
| 623 | 622 |
return static_cast<int32_t>(sum / kernel_sum); |
| 624 | 623 |
} |
| 625 | 624 |
else if (this->ply->interpolation > INTERPOLATION_COSINE) |
| ... | ... |
@@ -721,22 +720,59 @@ void Channel::IncrementSample() |
| 721 | 720 |
{
|
| 722 | 721 |
double samplePosition = this->reg.samplePosition + this->reg.sampleIncrease; |
| 723 | 722 |
|
| 724 |
- if (this->reg.format != 3 && this->reg.samplePosition >= 0) |
|
| 723 |
+ if (this->reg.format != 3) |
|
| 725 | 724 |
{
|
| 726 |
- uint32_t loc = static_cast<uint32_t>(this->reg.samplePosition); |
|
| 727 |
- uint32_t newloc = static_cast<uint32_t>(samplePosition); |
|
| 725 |
+ if (this->reg.samplePosition < 0 && samplePosition >= 0) |
|
| 726 |
+ {
|
|
| 727 |
+ this->ringBuffer.Clear(); |
|
| 728 |
+ this->ringBuffer.bufferPos += SINC_WIDTH + 1; |
|
| 729 |
+ auto preData = std::vector<int16_t>(SINC_WIDTH + 1, this->reg.source->dataptr[0]); |
|
| 730 |
+ this->ringBuffer.PushSamples(&preData[0], SINC_WIDTH + 1); |
|
| 731 |
+ if (this->reg.totalLength < SINC_WIDTH + 1) |
|
| 732 |
+ {
|
|
| 733 |
+ this->ringBuffer.PushSamples(&this->reg.source->dataptr[0], this->reg.totalLength); |
|
| 734 |
+ if (this->reg.repeatMode == 1) |
|
| 735 |
+ {
|
|
| 736 |
+ size_t samplesLeft = SINC_WIDTH + 1 - this->reg.totalLength; |
|
| 737 |
+ while (samplesLeft) |
|
| 738 |
+ {
|
|
| 739 |
+ size_t samplesToPush = std::min(samplesLeft, this->reg.length); |
|
| 740 |
+ this->ringBuffer.PushSamples(&this->reg.source->dataptr[this->reg.loopStart], samplesToPush); |
|
| 741 |
+ samplesLeft -= samplesToPush; |
|
| 742 |
+ } |
|
| 743 |
+ } |
|
| 744 |
+ } |
|
| 745 |
+ else |
|
| 746 |
+ this->ringBuffer.PushSamples(&this->reg.source->dataptr[0], SINC_WIDTH + 1); |
|
| 747 |
+ } |
|
| 748 |
+ if (this->reg.samplePosition >= 0) |
|
| 749 |
+ {
|
|
| 750 |
+ uint32_t loc = static_cast<uint32_t>(this->reg.samplePosition) + SINC_WIDTH + 1; |
|
| 751 |
+ uint32_t newloc = static_cast<uint32_t>(samplePosition) + SINC_WIDTH + 1; |
|
| 728 | 752 |
|
| 729 |
- if (newloc >= this->reg.totalLength) |
|
| 730 |
- newloc -= this->reg.length; |
|
| 753 |
+ if (this->reg.repeatMode == 1) |
|
| 754 |
+ {
|
|
| 755 |
+ if (loc >= this->reg.totalLength) |
|
| 756 |
+ loc -= this->reg.length; |
|
| 757 |
+ if (newloc >= this->reg.totalLength) |
|
| 758 |
+ newloc -= this->reg.length; |
|
| 759 |
+ } |
|
| 731 | 760 |
|
| 732 |
- while (loc != newloc) |
|
| 733 |
- {
|
|
| 734 |
- this->sampleHistory[this->sampleHistoryPtr] = this->sampleHistory[this->sampleHistoryPtr + 32] = this->reg.source->dataptr[loc++]; |
|
| 761 |
+ while (loc != newloc) |
|
| 762 |
+ {
|
|
| 763 |
+ this->ringBuffer.NextSample(); |
|
| 735 | 764 |
|
| 736 |
- this->sampleHistoryPtr = (this->sampleHistoryPtr + 1) & 31; |
|
| 765 |
+ if (loc < this->reg.totalLength) |
|
| 766 |
+ this->ringBuffer.PushSample(this->reg.source->dataptr[loc++]); |
|
| 767 |
+ else |
|
| 768 |
+ {
|
|
| 769 |
+ ++loc; |
|
| 770 |
+ this->ringBuffer.PushSample(this->reg.source->dataptr[this->reg.totalLength - 1]); |
|
| 771 |
+ } |
|
| 737 | 772 |
|
| 738 |
- if (loc >= this->reg.totalLength) |
|
| 739 |
- loc -= this->reg.length; |
|
| 773 |
+ if (this->reg.repeatMode == 1 && loc >= this->reg.totalLength) |
|
| 774 |
+ loc -= this->reg.length; |
|
| 775 |
+ } |
|
| 740 | 776 |
} |
| 741 | 777 |
} |
| 742 | 778 |
|
| ... | ... |
@@ -753,9 +789,3 @@ void Channel::IncrementSample() |
| 753 | 789 |
this->Kill(); |
| 754 | 790 |
} |
| 755 | 791 |
} |
| 756 |
- |
|
| 757 |
-void Channel::clearHistory() |
|
| 758 |
-{
|
|
| 759 |
- this->sampleHistoryPtr = 0; |
|
| 760 |
- memset(this->sampleHistory, 0, sizeof(this->sampleHistory)); |
|
| 761 |
-} |
| ... | ... |
@@ -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 |
| ... | ... |
@@ -1,7 +1,7 @@ |
| 1 | 1 |
/* |
| 2 | 2 |
* SSEQ Player - Player structure |
| 3 | 3 |
* By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com] |
| 4 |
- * Last modification on 2013-04-18 |
|
| 4 |
+ * Last modification on 2013-05-07 |
|
| 5 | 5 |
* |
| 6 | 6 |
* Adapted from source code of FeOS Sound System |
| 7 | 7 |
* By fincs |
| ... | ... |
@@ -120,7 +120,6 @@ int Player::ChannelAlloc(int type, int priority) |
| 120 | 120 |
this->channels[curChnNo].ply = this; |
| 121 | 121 |
this->channels[curChnNo].noteLength = -1; |
| 122 | 122 |
this->channels[curChnNo].vol = 0; |
| 123 |
- this->channels[curChnNo].clearHistory(); |
|
| 124 | 123 |
return curChnNo; |
| 125 | 124 |
} |
| 126 | 125 |
|
| ... | ... |
@@ -1,7 +1,7 @@ |
| 1 | 1 |
/* |
| 2 | 2 |
* SSEQ Player - Constants/Macros |
| 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 |
| ... | ... |
@@ -59,7 +59,7 @@ enum Interpolation |
| 59 | 59 |
INTERPOLATION_4POINTBSPLINE, |
| 60 | 60 |
INTERPOLATION_6POINTOSCULATING, |
| 61 | 61 |
INTERPOLATION_6POINTBSPLINE, |
| 62 |
- INTERPOLATION_LANCZOS |
|
| 62 |
+ INTERPOLATION_SINC |
|
| 63 | 63 |
}; |
| 64 | 64 |
|
| 65 | 65 |
#endif |
| ... | ... |
@@ -1,7 +1,7 @@ |
| 1 | 1 |
/* |
| 2 | 2 |
* xSF - NCSF configuration |
| 3 | 3 |
* By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com] |
| 4 |
- * Last modification on 2013-04-26 |
|
| 4 |
+ * Last modification on 2013-05-07 |
|
| 5 | 5 |
* |
| 6 | 6 |
* Partially based on the vio*sf framework |
| 7 | 7 |
*/ |
| ... | ... |
@@ -42,7 +42,7 @@ public: |
| 42 | 42 |
|
| 43 | 43 |
unsigned XSFConfig::initSampleRate = 44100; |
| 44 | 44 |
std::wstring XSFConfig::commonName = L"NCSF Decoder"; |
| 45 |
-std::wstring XSFConfig::versionNumber = L"1.7.1"; |
|
| 45 |
+std::wstring XSFConfig::versionNumber = L"1.8"; |
|
| 46 | 46 |
unsigned XSFConfig_NCSF::initInterpolation = 5; |
| 47 | 47 |
std::wstring XSFConfig_NCSF::initMutes = L"0000000000000000"; |
| 48 | 48 |
|
| ... | ... |
@@ -101,7 +101,7 @@ INT_PTR CALLBACK XSFConfig_NCSF::ConfigDialogProc(HWND hwndDlg, UINT uMsg, WPARA |
| 101 | 101 |
SendMessageW(GetDlgItem(hwndDlg, idInterpolation), CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(L"4-point, 3rd-order B-spline")); |
| 102 | 102 |
SendMessageW(GetDlgItem(hwndDlg, idInterpolation), CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(L"6-point, 5th-order Osculating")); |
| 103 | 103 |
SendMessageW(GetDlgItem(hwndDlg, idInterpolation), CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(L"6-point, 5th-order B-spline")); |
| 104 |
- SendMessageW(GetDlgItem(hwndDlg, idInterpolation), CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(L"Lanczos (Sinc)")); |
|
| 104 |
+ SendMessageW(GetDlgItem(hwndDlg, idInterpolation), CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(L"Sinc (Hann Window)")); |
|
| 105 | 105 |
SendMessageW(GetDlgItem(hwndDlg, idInterpolation), CB_SETCURSEL, this->interpolation, 0); |
| 106 | 106 |
// Mutes |
| 107 | 107 |
for (int x = 0, numMutes = this->mutes.size(); x < numMutes; ++x) |
| ... | ... |
@@ -142,5 +142,5 @@ void XSFConfig_NCSF::CopySpecificConfigToMemory(XSFPlayer *xSFPlayer, bool) |
| 142 | 142 |
void XSFConfig_NCSF::About(HWND parent) |
| 143 | 143 |
{
|
| 144 | 144 |
MessageBox(parent, (XSFConfig::commonName + L" v" + XSFConfig::versionNumber + L", using xSF Winamp plugin framework (based on the vio*sf plugins) by Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]\n\n" |
| 145 |
- L"Utilizes code adapted from the FeOS Sound System library by fincs, git revision 9cb9820 on GitHub, for audio playback.").c_str(), (XSFConfig::commonName + L" v" + XSFConfig::versionNumber).c_str(), MB_OK); |
|
| 145 |
+ L"Utilizes code adapted from the FeOS Sound System library by fincs, git revision 5204c55 on GitHub, for audio playback.").c_str(), (XSFConfig::commonName + L" v" + XSFConfig::versionNumber).c_str(), MB_OK); |
|
| 146 | 146 |
} |
| ... | ... |
@@ -1,7 +1,7 @@ |
| 1 | 1 |
/* |
| 2 | 2 |
* xSF - Core Player |
| 3 | 3 |
* By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com] |
| 4 |
- * Last modification on 2013-04-26 |
|
| 4 |
+ * Last modification on 2013-05-07 |
|
| 5 | 5 |
* |
| 6 | 6 |
* Partially based on the vio*sf framework |
| 7 | 7 |
*/ |
| ... | ... |
@@ -169,8 +169,8 @@ bool XSFPlayer::FillBuffer(std::vector<uint8_t> &buf, unsigned &samplesWritten) |
| 169 | 169 |
double s1 = bufLong[2 * ofs] * scale, s2 = bufLong[2 * ofs + 1] * scale; |
| 170 | 170 |
if (!this->uses32BitSamplesClampedTo16Bit) |
| 171 | 171 |
{
|
| 172 |
- clamp(s1, -0x7FFF, 0x8000); |
|
| 173 |
- clamp(s2, -0x7FFF, 0x8000); |
|
| 172 |
+ clamp(s1, std::numeric_limits<int16_t>::min(), std::numeric_limits<int16_t>::max()); |
|
| 173 |
+ clamp(s2, std::numeric_limits<int16_t>::min(), std::numeric_limits<int16_t>::max()); |
|
| 174 | 174 |
} |
| 175 | 175 |
bufLong[2 * ofs] = static_cast<int32_t>(s1); |
| 176 | 176 |
bufLong[2 * ofs + 1] = static_cast<int32_t>(s2); |
| ... | ... |
@@ -183,8 +183,8 @@ bool XSFPlayer::FillBuffer(std::vector<uint8_t> &buf, unsigned &samplesWritten) |
| 183 | 183 |
for (unsigned ofs = 0; ofs < bufsize; ++ofs) |
| 184 | 184 |
{
|
| 185 | 185 |
int32_t s1 = bufLong[2 * ofs], s2 = bufLong[2 * ofs + 1]; |
| 186 |
- clamp(s1, -0x7FFF, 0x8000); |
|
| 187 |
- clamp(s2, -0x7FFF, 0x8000); |
|
| 186 |
+ clamp(s1, std::numeric_limits<int16_t>::min(), std::numeric_limits<int16_t>::max()); |
|
| 187 |
+ clamp(s2, std::numeric_limits<int16_t>::min(), std::numeric_limits<int16_t>::max()); |
|
| 188 | 188 |
bufShort[2 * ofs] = static_cast<int16_t>(s1); |
| 189 | 189 |
bufShort[2 * ofs + 1] = static_cast<int16_t>(s2); |
| 190 | 190 |
} |
| ... | ... |
@@ -1,7 +1,7 @@ |
| 1 | 1 |
/* |
| 2 | 2 |
* xSF - Core Player |
| 3 | 3 |
* By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com] |
| 4 |
- * Last modification on 2013-04-26 |
|
| 4 |
+ * Last modification on 2013-05-07 |
|
| 5 | 5 |
* |
| 6 | 6 |
* Partially based on the vio*sf framework |
| 7 | 7 |
*/ |
| ... | ... |
@@ -12,6 +12,7 @@ |
| 12 | 12 |
#include "XSFFile.h" |
| 13 | 13 |
|
| 14 | 14 |
#ifdef WINAMP_PLUGIN |
| 15 |
+# include "windowsh_wrapper.h" |
|
| 15 | 16 |
# include <winamp/out.h> |
| 16 | 17 |
#endif |
| 17 | 18 |
|