Notable differences from upstream:
* Did not use the same #include setup for the new byuu apu and instead chose to do things more traditionally, as the latter is also much easier to deal with in Visual Studio than just including .cpp files into other .cpp files...
* MSU1 support not included (I see no need for this in a plugin meant to be used for original SNES music).
* The dynamic rate control on the APU not included (I also see no need for it in this plugin).
* The extra resamplers I added in were removed as the original hermite resampler was folded into a single non-inhertiable resampler.
* Bits of cleanup.
| 1 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,100 +0,0 @@ |
| 1 |
-/* Simple fixed-point linear resampler by BearOso*/ |
|
| 2 |
- |
|
| 3 |
-#pragma once |
|
| 4 |
- |
|
| 5 |
-#include "resampler.h" |
|
| 6 |
-#include "XSFCommon.h" |
|
| 7 |
- |
|
| 8 |
-class LinearResampler : public Resampler |
|
| 9 |
-{
|
|
| 10 |
- static const int f_prec = 15; |
|
| 11 |
- static const uint32_t f__one = 1 << f_prec; |
|
| 12 |
- |
|
| 13 |
-protected: |
|
| 14 |
- uint32_t f__r_step; |
|
| 15 |
- uint32_t f__inv_r_step; |
|
| 16 |
- uint32_t f__r_frac; |
|
| 17 |
- int r_left, r_right; |
|
| 18 |
- |
|
| 19 |
- static short lerp(uint32_t t, int a, short b) { return (((b - a) * t) >> f_prec) + a; }
|
|
| 20 |
- |
|
| 21 |
-public: |
|
| 22 |
- LinearResampler(int num_samples) : Resampler(num_samples) |
|
| 23 |
- {
|
|
| 24 |
- this->f__r_frac = 0; |
|
| 25 |
- } |
|
| 26 |
- |
|
| 27 |
- void time_ratio(double ratio) |
|
| 28 |
- {
|
|
| 29 |
- if (fEqual(ratio, 0.0)) |
|
| 30 |
- ratio = 1.0; |
|
| 31 |
- this->f__r_step = static_cast<uint32_t>(ratio * f__one); |
|
| 32 |
- this->f__inv_r_step = static_cast<uint32_t>(f__one / ratio); |
|
| 33 |
- this->clear(); |
|
| 34 |
- } |
|
| 35 |
- |
|
| 36 |
- void clear() |
|
| 37 |
- {
|
|
| 38 |
- ring_buffer::clear(); |
|
| 39 |
- this->f__r_frac = 0; |
|
| 40 |
- this->r_left = 0; |
|
| 41 |
- this->r_right = 0; |
|
| 42 |
- } |
|
| 43 |
- |
|
| 44 |
- void read(short *data, int num_samples) |
|
| 45 |
- {
|
|
| 46 |
- int i_position = this->start >> 1; |
|
| 47 |
- short *internal_buffer = reinterpret_cast<short *>(&this->buffer[0]); |
|
| 48 |
- int o_position = 0; |
|
| 49 |
- int consumed = 0; |
|
| 50 |
- int max_samples = this->buffer_size >> 1; |
|
| 51 |
- |
|
| 52 |
- while (o_position < num_samples && consumed < this->buffer_size) |
|
| 53 |
- {
|
|
| 54 |
- if (this->f__r_step == f__one) |
|
| 55 |
- {
|
|
| 56 |
- data[o_position] = internal_buffer[i_position]; |
|
| 57 |
- data[o_position + 1] = internal_buffer[i_position + 1]; |
|
| 58 |
- |
|
| 59 |
- o_position += 2; |
|
| 60 |
- i_position += 2; |
|
| 61 |
- if (i_position >= max_samples) |
|
| 62 |
- i_position -= max_samples; |
|
| 63 |
- consumed += 2; |
|
| 64 |
- |
|
| 65 |
- continue; |
|
| 66 |
- } |
|
| 67 |
- |
|
| 68 |
- while (this->f__r_frac <= f__one && o_position < num_samples) |
|
| 69 |
- {
|
|
| 70 |
- data[o_position] = lerp(this->f__r_frac, this->r_left, internal_buffer[i_position]); |
|
| 71 |
- data[o_position + 1] = lerp(this->f__r_frac, this->r_right, internal_buffer[i_position + 1]); |
|
| 72 |
- |
|
| 73 |
- o_position += 2; |
|
| 74 |
- |
|
| 75 |
- this->f__r_frac += this->f__r_step; |
|
| 76 |
- } |
|
| 77 |
- |
|
| 78 |
- if (this->f__r_frac > f__one) |
|
| 79 |
- {
|
|
| 80 |
- this->f__r_frac -= f__one; |
|
| 81 |
- this->r_left = internal_buffer[i_position]; |
|
| 82 |
- this->r_right = internal_buffer[i_position + 1]; |
|
| 83 |
- i_position += 2; |
|
| 84 |
- if (i_position >= max_samples) |
|
| 85 |
- i_position -= max_samples; |
|
| 86 |
- consumed += 2; |
|
| 87 |
- } |
|
| 88 |
- } |
|
| 89 |
- |
|
| 90 |
- this->size -= consumed << 1; |
|
| 91 |
- this->start += consumed << 1; |
|
| 92 |
- if (this->start >= this->buffer_size) |
|
| 93 |
- this->start -= this->buffer_size; |
|
| 94 |
- } |
|
| 95 |
- |
|
| 96 |
- int avail() |
|
| 97 |
- {
|
|
| 98 |
- return (((this->size >> 2) * this->f__inv_r_step) - ((this->f__r_frac * this->f__inv_r_step) >> f_prec)) >> (f_prec - 1); |
|
| 99 |
- } |
|
| 100 |
-}; |
* [2SF] Used more up-to-date asmjit, despite the ugly looking code.
| ... | ... |
@@ -3,12 +3,13 @@ |
| 3 | 3 |
#pragma once |
| 4 | 4 |
|
| 5 | 5 |
#include "resampler.h" |
| 6 |
- |
|
| 7 |
-const int f_prec = 15; |
|
| 8 |
-const uint32_t f__one = 1 << f_prec; |
|
| 6 |
+#include "XSFCommon.h" |
|
| 9 | 7 |
|
| 10 | 8 |
class LinearResampler : public Resampler |
| 11 | 9 |
{
|
| 10 |
+ static const int f_prec = 15; |
|
| 11 |
+ static const uint32_t f__one = 1 << f_prec; |
|
| 12 |
+ |
|
| 12 | 13 |
protected: |
| 13 | 14 |
uint32_t f__r_step; |
| 14 | 15 |
uint32_t f__inv_r_step; |
| ... | ... |
@@ -25,7 +26,7 @@ public: |
| 25 | 26 |
|
| 26 | 27 |
void time_ratio(double ratio) |
| 27 | 28 |
{
|
| 28 |
- if (!ratio) |
|
| 29 |
+ if (fEqual(ratio, 0.0)) |
|
| 29 | 30 |
ratio = 1.0; |
| 30 | 31 |
this->f__r_step = static_cast<uint32_t>(ratio * f__one); |
| 31 | 32 |
this->f__inv_r_step = static_cast<uint32_t>(f__one / ratio); |
| ... | ... |
@@ -43,7 +44,7 @@ public: |
| 43 | 44 |
void read(short *data, int num_samples) |
| 44 | 45 |
{
|
| 45 | 46 |
int i_position = this->start >> 1; |
| 46 |
- short *internal_buffer = reinterpret_cast<short *>(this->buffer); |
|
| 47 |
+ short *internal_buffer = reinterpret_cast<short *>(&this->buffer[0]); |
|
| 47 | 48 |
int o_position = 0; |
| 48 | 49 |
int consumed = 0; |
| 49 | 50 |
int max_samples = this->buffer_size >> 1; |
| ... | ... |
@@ -1,7 +1,6 @@ |
| 1 | 1 |
/* Simple fixed-point linear resampler by BearOso*/ |
| 2 | 2 |
|
| 3 |
-#ifndef __LINEAR_RESAMPLER_H |
|
| 4 |
-#define __LINEAR_RESAMPLER_H |
|
| 3 |
+#pragma once |
|
| 5 | 4 |
|
| 6 | 5 |
#include "resampler.h" |
| 7 | 6 |
|
| ... | ... |
@@ -98,5 +97,3 @@ public: |
| 98 | 97 |
return (((this->size >> 2) * this->f__inv_r_step) - ((this->f__r_frac * this->f__inv_r_step) >> f_prec)) >> (f_prec - 1); |
| 99 | 98 |
} |
| 100 | 99 |
}; |
| 101 |
- |
|
| 102 |
-#endif /* __LINEAR_RESAMPLER_H */ |
| ... | ... |
@@ -4,112 +4,99 @@ |
| 4 | 4 |
#define __LINEAR_RESAMPLER_H |
| 5 | 5 |
|
| 6 | 6 |
#include "resampler.h" |
| 7 |
-#include "../snes9x.h" |
|
| 8 | 7 |
|
| 9 |
-static const int f_prec = 15; |
|
| 10 |
-static const uint32_t f__one = (1 << f_prec); |
|
| 11 |
- |
|
| 12 |
-#define lerp(t, a, b) (((((b) - (a)) * (t)) >> f_prec) + (a)) |
|
| 8 |
+const int f_prec = 15; |
|
| 9 |
+const uint32_t f__one = 1 << f_prec; |
|
| 13 | 10 |
|
| 14 | 11 |
class LinearResampler : public Resampler |
| 15 | 12 |
{
|
| 16 |
- protected: |
|
| 17 |
- uint32_t f__r_step; |
|
| 18 |
- uint32_t f__inv_r_step; |
|
| 19 |
- uint32_t f__r_frac; |
|
| 20 |
- int r_left, r_right; |
|
| 21 |
- |
|
| 22 |
- public: |
|
| 23 |
- LinearResampler (int num_samples) : Resampler (num_samples) |
|
| 24 |
- {
|
|
| 25 |
- f__r_frac = 0; |
|
| 26 |
- } |
|
| 27 |
- |
|
| 28 |
- ~LinearResampler () |
|
| 29 |
- {
|
|
| 30 |
- } |
|
| 31 |
- |
|
| 32 |
- void |
|
| 33 |
- time_ratio (double ratio) |
|
| 34 |
- {
|
|
| 35 |
- if (ratio == 0.0) |
|
| 36 |
- ratio = 1.0; |
|
| 37 |
- f__r_step = (uint32_t) (ratio * f__one); |
|
| 38 |
- f__inv_r_step = (uint32_t) (f__one / ratio); |
|
| 39 |
- clear (); |
|
| 40 |
- } |
|
| 41 |
- |
|
| 42 |
- void |
|
| 43 |
- clear() |
|
| 44 |
- {
|
|
| 45 |
- ring_buffer::clear (); |
|
| 46 |
- f__r_frac = 0; |
|
| 47 |
- r_left = 0; |
|
| 48 |
- r_right = 0; |
|
| 49 |
- } |
|
| 50 |
- |
|
| 51 |
- void |
|
| 52 |
- read (short *data, int num_samples) |
|
| 53 |
- {
|
|
| 54 |
- int i_position = start >> 1; |
|
| 55 |
- short *internal_buffer = (short *) buffer; |
|
| 56 |
- int o_position = 0; |
|
| 57 |
- int consumed = 0; |
|
| 58 |
- int max_samples = (buffer_size >> 1); |
|
| 59 |
- |
|
| 60 |
- while (o_position < num_samples && consumed < buffer_size) |
|
| 61 |
- {
|
|
| 62 |
- if (f__r_step == f__one) |
|
| 63 |
- {
|
|
| 64 |
- data[o_position] = internal_buffer[i_position]; |
|
| 65 |
- data[o_position + 1] = internal_buffer[i_position + 1]; |
|
| 66 |
- |
|
| 67 |
- o_position += 2; |
|
| 68 |
- i_position += 2; |
|
| 69 |
- if (i_position >= max_samples) |
|
| 70 |
- i_position -= max_samples; |
|
| 71 |
- consumed += 2; |
|
| 72 |
- |
|
| 73 |
- continue; |
|
| 74 |
- } |
|
| 75 |
- |
|
| 76 |
- while (f__r_frac <= f__one && o_position < num_samples) |
|
| 77 |
- {
|
|
| 78 |
- data[o_position] = lerp (f__r_frac, |
|
| 79 |
- r_left, |
|
| 80 |
- internal_buffer[i_position]); |
|
| 81 |
- data[o_position + 1] = lerp (f__r_frac, |
|
| 82 |
- r_right, |
|
| 83 |
- internal_buffer[i_position + 1]); |
|
| 84 |
- |
|
| 85 |
- o_position += 2; |
|
| 86 |
- |
|
| 87 |
- f__r_frac += f__r_step; |
|
| 88 |
- } |
|
| 89 |
- |
|
| 90 |
- if (f__r_frac > f__one) |
|
| 91 |
- {
|
|
| 92 |
- f__r_frac -= f__one; |
|
| 93 |
- r_left = internal_buffer[i_position]; |
|
| 94 |
- r_right = internal_buffer[i_position + 1]; |
|
| 95 |
- i_position += 2; |
|
| 96 |
- if (i_position >= max_samples) |
|
| 97 |
- i_position -= max_samples; |
|
| 98 |
- consumed += 2; |
|
| 99 |
- } |
|
| 100 |
- } |
|
| 101 |
- |
|
| 102 |
- size -= consumed << 1; |
|
| 103 |
- start += consumed << 1; |
|
| 104 |
- if (start >= buffer_size) |
|
| 105 |
- start -= buffer_size; |
|
| 106 |
- } |
|
| 107 |
- |
|
| 108 |
- inline int |
|
| 109 |
- avail() |
|
| 110 |
- {
|
|
| 111 |
- return (((size >> 2) * f__inv_r_step) - ((f__r_frac * f__inv_r_step) >> f_prec)) >> (f_prec - 1); |
|
| 112 |
- } |
|
| 13 |
+protected: |
|
| 14 |
+ uint32_t f__r_step; |
|
| 15 |
+ uint32_t f__inv_r_step; |
|
| 16 |
+ uint32_t f__r_frac; |
|
| 17 |
+ int r_left, r_right; |
|
| 18 |
+ |
|
| 19 |
+ static short lerp(uint32_t t, int a, short b) { return (((b - a) * t) >> f_prec) + a; }
|
|
| 20 |
+ |
|
| 21 |
+public: |
|
| 22 |
+ LinearResampler(int num_samples) : Resampler(num_samples) |
|
| 23 |
+ {
|
|
| 24 |
+ this->f__r_frac = 0; |
|
| 25 |
+ } |
|
| 26 |
+ |
|
| 27 |
+ void time_ratio(double ratio) |
|
| 28 |
+ {
|
|
| 29 |
+ if (!ratio) |
|
| 30 |
+ ratio = 1.0; |
|
| 31 |
+ this->f__r_step = static_cast<uint32_t>(ratio * f__one); |
|
| 32 |
+ this->f__inv_r_step = static_cast<uint32_t>(f__one / ratio); |
|
| 33 |
+ this->clear(); |
|
| 34 |
+ } |
|
| 35 |
+ |
|
| 36 |
+ void clear() |
|
| 37 |
+ {
|
|
| 38 |
+ ring_buffer::clear(); |
|
| 39 |
+ this->f__r_frac = 0; |
|
| 40 |
+ this->r_left = 0; |
|
| 41 |
+ this->r_right = 0; |
|
| 42 |
+ } |
|
| 43 |
+ |
|
| 44 |
+ void read(short *data, int num_samples) |
|
| 45 |
+ {
|
|
| 46 |
+ int i_position = this->start >> 1; |
|
| 47 |
+ short *internal_buffer = reinterpret_cast<short *>(this->buffer); |
|
| 48 |
+ int o_position = 0; |
|
| 49 |
+ int consumed = 0; |
|
| 50 |
+ int max_samples = this->buffer_size >> 1; |
|
| 51 |
+ |
|
| 52 |
+ while (o_position < num_samples && consumed < this->buffer_size) |
|
| 53 |
+ {
|
|
| 54 |
+ if (this->f__r_step == f__one) |
|
| 55 |
+ {
|
|
| 56 |
+ data[o_position] = internal_buffer[i_position]; |
|
| 57 |
+ data[o_position + 1] = internal_buffer[i_position + 1]; |
|
| 58 |
+ |
|
| 59 |
+ o_position += 2; |
|
| 60 |
+ i_position += 2; |
|
| 61 |
+ if (i_position >= max_samples) |
|
| 62 |
+ i_position -= max_samples; |
|
| 63 |
+ consumed += 2; |
|
| 64 |
+ |
|
| 65 |
+ continue; |
|
| 66 |
+ } |
|
| 67 |
+ |
|
| 68 |
+ while (this->f__r_frac <= f__one && o_position < num_samples) |
|
| 69 |
+ {
|
|
| 70 |
+ data[o_position] = lerp(this->f__r_frac, this->r_left, internal_buffer[i_position]); |
|
| 71 |
+ data[o_position + 1] = lerp(this->f__r_frac, this->r_right, internal_buffer[i_position + 1]); |
|
| 72 |
+ |
|
| 73 |
+ o_position += 2; |
|
| 74 |
+ |
|
| 75 |
+ this->f__r_frac += this->f__r_step; |
|
| 76 |
+ } |
|
| 77 |
+ |
|
| 78 |
+ if (this->f__r_frac > f__one) |
|
| 79 |
+ {
|
|
| 80 |
+ this->f__r_frac -= f__one; |
|
| 81 |
+ this->r_left = internal_buffer[i_position]; |
|
| 82 |
+ this->r_right = internal_buffer[i_position + 1]; |
|
| 83 |
+ i_position += 2; |
|
| 84 |
+ if (i_position >= max_samples) |
|
| 85 |
+ i_position -= max_samples; |
|
| 86 |
+ consumed += 2; |
|
| 87 |
+ } |
|
| 88 |
+ } |
|
| 89 |
+ |
|
| 90 |
+ this->size -= consumed << 1; |
|
| 91 |
+ this->start += consumed << 1; |
|
| 92 |
+ if (this->start >= this->buffer_size) |
|
| 93 |
+ this->start -= this->buffer_size; |
|
| 94 |
+ } |
|
| 95 |
+ |
|
| 96 |
+ int avail() |
|
| 97 |
+ {
|
|
| 98 |
+ return (((this->size >> 2) * this->f__inv_r_step) - ((this->f__r_frac * this->f__inv_r_step) >> f_prec)) >> (f_prec - 1); |
|
| 99 |
+ } |
|
| 113 | 100 |
}; |
| 114 | 101 |
|
| 115 | 102 |
#endif /* __LINEAR_RESAMPLER_H */ |
| 1 | 1 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,115 @@ |
| 1 |
+/* Simple fixed-point linear resampler by BearOso*/ |
|
| 2 |
+ |
|
| 3 |
+#ifndef __LINEAR_RESAMPLER_H |
|
| 4 |
+#define __LINEAR_RESAMPLER_H |
|
| 5 |
+ |
|
| 6 |
+#include "resampler.h" |
|
| 7 |
+#include "snes9x.h" |
|
| 8 |
+ |
|
| 9 |
+static const int f_prec = 15; |
|
| 10 |
+static const uint32_t f__one = (1 << f_prec); |
|
| 11 |
+ |
|
| 12 |
+#define lerp(t, a, b) (((((b) - (a)) * (t)) >> f_prec) + (a)) |
|
| 13 |
+ |
|
| 14 |
+class LinearResampler : public Resampler |
|
| 15 |
+{
|
|
| 16 |
+ protected: |
|
| 17 |
+ uint32_t f__r_step; |
|
| 18 |
+ uint32_t f__inv_r_step; |
|
| 19 |
+ uint32_t f__r_frac; |
|
| 20 |
+ int r_left, r_right; |
|
| 21 |
+ |
|
| 22 |
+ public: |
|
| 23 |
+ LinearResampler (int num_samples) : Resampler (num_samples) |
|
| 24 |
+ {
|
|
| 25 |
+ f__r_frac = 0; |
|
| 26 |
+ } |
|
| 27 |
+ |
|
| 28 |
+ ~LinearResampler () |
|
| 29 |
+ {
|
|
| 30 |
+ } |
|
| 31 |
+ |
|
| 32 |
+ void |
|
| 33 |
+ time_ratio (double ratio) |
|
| 34 |
+ {
|
|
| 35 |
+ if (ratio == 0.0) |
|
| 36 |
+ ratio = 1.0; |
|
| 37 |
+ f__r_step = (uint32_t) (ratio * f__one); |
|
| 38 |
+ f__inv_r_step = (uint32_t) (f__one / ratio); |
|
| 39 |
+ clear (); |
|
| 40 |
+ } |
|
| 41 |
+ |
|
| 42 |
+ void |
|
| 43 |
+ clear() |
|
| 44 |
+ {
|
|
| 45 |
+ ring_buffer::clear (); |
|
| 46 |
+ f__r_frac = 0; |
|
| 47 |
+ r_left = 0; |
|
| 48 |
+ r_right = 0; |
|
| 49 |
+ } |
|
| 50 |
+ |
|
| 51 |
+ void |
|
| 52 |
+ read (short *data, int num_samples) |
|
| 53 |
+ {
|
|
| 54 |
+ int i_position = start >> 1; |
|
| 55 |
+ short *internal_buffer = (short *) buffer; |
|
| 56 |
+ int o_position = 0; |
|
| 57 |
+ int consumed = 0; |
|
| 58 |
+ int max_samples = (buffer_size >> 1); |
|
| 59 |
+ |
|
| 60 |
+ while (o_position < num_samples && consumed < buffer_size) |
|
| 61 |
+ {
|
|
| 62 |
+ if (f__r_step == f__one) |
|
| 63 |
+ {
|
|
| 64 |
+ data[o_position] = internal_buffer[i_position]; |
|
| 65 |
+ data[o_position + 1] = internal_buffer[i_position + 1]; |
|
| 66 |
+ |
|
| 67 |
+ o_position += 2; |
|
| 68 |
+ i_position += 2; |
|
| 69 |
+ if (i_position >= max_samples) |
|
| 70 |
+ i_position -= max_samples; |
|
| 71 |
+ consumed += 2; |
|
| 72 |
+ |
|
| 73 |
+ continue; |
|
| 74 |
+ } |
|
| 75 |
+ |
|
| 76 |
+ while (f__r_frac <= f__one && o_position < num_samples) |
|
| 77 |
+ {
|
|
| 78 |
+ data[o_position] = lerp (f__r_frac, |
|
| 79 |
+ r_left, |
|
| 80 |
+ internal_buffer[i_position]); |
|
| 81 |
+ data[o_position + 1] = lerp (f__r_frac, |
|
| 82 |
+ r_right, |
|
| 83 |
+ internal_buffer[i_position + 1]); |
|
| 84 |
+ |
|
| 85 |
+ o_position += 2; |
|
| 86 |
+ |
|
| 87 |
+ f__r_frac += f__r_step; |
|
| 88 |
+ } |
|
| 89 |
+ |
|
| 90 |
+ if (f__r_frac > f__one) |
|
| 91 |
+ {
|
|
| 92 |
+ f__r_frac -= f__one; |
|
| 93 |
+ r_left = internal_buffer[i_position]; |
|
| 94 |
+ r_right = internal_buffer[i_position + 1]; |
|
| 95 |
+ i_position += 2; |
|
| 96 |
+ if (i_position >= max_samples) |
|
| 97 |
+ i_position -= max_samples; |
|
| 98 |
+ consumed += 2; |
|
| 99 |
+ } |
|
| 100 |
+ } |
|
| 101 |
+ |
|
| 102 |
+ size -= consumed << 1; |
|
| 103 |
+ start += consumed << 1; |
|
| 104 |
+ if (start >= buffer_size) |
|
| 105 |
+ start -= buffer_size; |
|
| 106 |
+ } |
|
| 107 |
+ |
|
| 108 |
+ inline int |
|
| 109 |
+ avail() |
|
| 110 |
+ {
|
|
| 111 |
+ return (((size >> 2) * f__inv_r_step) - ((f__r_frac * f__inv_r_step) >> f_prec)) >> (f_prec - 1); |
|
| 112 |
+ } |
|
| 113 |
+}; |
|
| 114 |
+ |
|
| 115 |
+#endif /* __LINEAR_RESAMPLER_H */ |