aboutsummaryrefslogtreecommitdiff
path: root/libopna/opnassg.c
diff options
context:
space:
mode:
Diffstat (limited to 'libopna/opnassg.c')
-rw-r--r--libopna/opnassg.c81
1 files changed, 64 insertions, 17 deletions
diff --git a/libopna/opnassg.c b/libopna/opnassg.c
index ec03437..4a12f76 100644
--- a/libopna/opnassg.c
+++ b/libopna/opnassg.c
@@ -1,5 +1,6 @@
#include "opnassg.h"
#include "oscillo/oscillo.h"
+#include <string.h>
/*
static const float voltable[32] = {
0.0f, 0.0f, 0x1.ae89f9p-8f, 0x1.000000p-7f,
@@ -27,9 +28,6 @@ static const int16_t voltable[32] = {
6494, 7723, 9185, 10922
};
-#define SINCTABLEBIT 7
-#define SINCTABLELEN (1<<SINCTABLEBIT)
-
// GNU Octave
// Fc = 7987200
// Ff = Fc/144
@@ -39,7 +37,8 @@ static const int16_t voltable[32] = {
// B = 128 * O / 2
// FILTER=sinc(linspace(-127.5,127.5,256)*2/9/2).*rotdim(kaiser(256,B))
// FILTERI=round(FILTER(1:128).*32768)
-static const int16_t sinctable[SINCTABLELEN] = {
+#if 0
+const int16_t opna_ssg_sinctable[OPNA_SSG_SINCTABLELEN*2] = {
1, 0, -1, -2, -3, -5, -6, -6,
-6, -5, -2, 2, 7, 11, 16, 19,
20, 18, 13, 5, -5, -17, -29, -38,
@@ -56,8 +55,61 @@ static const int16_t sinctable[SINCTABLELEN] = {
3306, 3714, 3690, 3185, 2206, 815, -868, -2673,
-4391, -5798, -6670, -6809, -6067, -4359, -1681, 1886,
6178, 10957, 15928, 20765, 25133, 28724, 31275, 32600,
+ 32600, 31275, 28724, 25133, 20765, 15928, 10957, 6178,
+ 1886, -1681, -4359, -6067, -6809, -6670, -5798, -4391,
+ -2673, -868, 815, 2206, 3185, 3690, 3714, 3306,
+ 2557, 1585, 523, -498, -1365, -1994, -2333, -2369,
+ -2125, -1655, -1032, -343, 328, 902, 1322, 1552,
+ 1580, 1421, 1108, 692, 230, -220, -607, -889,
+ -1043, -1062, -954, -744, -464, -154, 147, 405,
+ 593, 694, 705, 632, 491, 306, 101, -96,
+ -264, -385, -450, -455, -406, -315, -195, -64,
+ 61, 166, 241, 280, 282, 251, 193, 119,
+ 39, -37, -100, -144, -166, -166, -146, -112,
+ -68, -22, 21, 56, 80, 91, 90, 79,
+ 60, 36, 12, -11, -29, -40, -45, -44,
+ -38, -29, -17, -5, 5, 13, 18, 20,
+ 19, 16, 11, 7, 2, -2, -5, -6,
+ -6, -6, -5, -3, -2, -1, 0, 1,
+};
+#endif
+const int16_t opna_ssg_sinctable[OPNA_SSG_SINCTABLELEN*2] = {
+ 1, -1, -3, -6, -6, -2, 7, 16,
+ 20, 13, -5, -29, -44, -40, -11, 36,
+ 79, 91, 56, -22, -112, -166, -144, -37,
+ 119, 251, 280, 166, -64, -315, -455, -385,
+ -96, 306, 632, 694, 405, -154, -744, -1062,
+ -889, -220, 692, 1421, 1552, 902, -343, -1655,
+ -2369, -1994, -498, 1585, 3306, 3690, 2206, -868,
+ -4391, -6670, -6067, -1681, 6178, 15928, 25133, 31275,
+ 32600, 28724, 20765, 10957, 1886, -4359, -6809, -5798,
+ -2673, 815, 3185, 3714, 2557, 523, -1365, -2333,
+ -2125, -1032, 328, 1322, 1580, 1108, 230, -607,
+ -1043, -954, -464, 147, 593, 705, 491, 101,
+ -264, -450, -406, -195, 61, 241, 282, 193,
+ 39, -100, -166, -146, -68, 21, 80, 90,
+ 60, 12, -29, -45, -38, -17, 5, 18,
+ 19, 11, 2, -5, -6, -5, -2, 0,
+ 0, -2, -5, -6, -5, 2, 11, 19,
+ 18, 5, -17, -38, -45, -29, 12, 60,
+ 90, 80, 21, -68, -146, -166, -100, 39,
+ 193, 282, 241, 61, -195, -406, -450, -264,
+ 101, 491, 705, 593, 147, -464, -954, -1043,
+ -607, 230, 1108, 1580, 1322, 328, -1032, -2125,
+ -2333, -1365, 523, 2557, 3714, 3185, 815, -2673,
+ -5798, -6809, -4359, 1886, 10957, 20765, 28724, 32600,
+ 31275, 25133, 15928, 6178, -1681, -6067, -6670, -4391,
+ -868, 2206, 3690, 3306, 1585, -498, -1994, -2369,
+ -1655, -343, 902, 1552, 1421, 692, -220, -889,
+ -1062, -744, -154, 405, 694, 632, 306, -96,
+ -385, -455, -315, -64, 166, 280, 251, 119,
+ -37, -144, -166, -112, -22, 56, 91, 79,
+ 36, -11, -40, -44, -29, -5, 13, 20,
+ 16, 7, -2, -6, -6, -3, -1, 1,
};
+opna_ssg_sinc_calc_func_type opna_ssg_sinc_calc_func = opna_ssg_sinc_calc_c;
+
void opna_ssg_reset(struct opna_ssg *ssg) {
for (int i = 0; i < 3; i++) {
ssg->ch[i].tone_counter = 0;
@@ -78,7 +130,7 @@ void opna_ssg_reset(struct opna_ssg *ssg) {
}
void opna_ssg_resampler_reset(struct opna_ssg_resampler *resampler) {
- for (int i = 0; i < SINCTABLELEN; i++) {
+ for (int i = 0; i < OPNA_SSG_SINCTABLELEN; i++) {
resampler->buf[i] = 0;
}
resampler->index = 0;
@@ -215,7 +267,7 @@ void opna_ssg_generate_raw(struct opna_ssg *ssg, int16_t *buf, int samples) {
}
}
-#define BUFINDEX(n) ((((resampler->index)>>1)+n)&(SINCTABLELEN-1))
+#define BUFINDEX(n) ((((resampler->index)>>1)+n)&(OPNA_SSG_SINCTABLELEN-1))
void opna_ssg_mix_55466(
struct opna_ssg *ssg, struct opna_ssg_resampler *resampler,
@@ -246,18 +298,13 @@ void opna_ssg_mix_55466(
resampler->index += 9;
}
int32_t sample = 0;
+ resampler->index &= (1u<<(OPNA_SSG_SINCTABLEBIT+1))-1;
+ memcpy(resampler->buf + OPNA_SSG_SINCTABLELEN*3, resampler->buf, OPNA_SSG_SINCTABLELEN*3*sizeof(*resampler->buf));
+ int32_t outbuf[3];
+ opna_ssg_sinc_calc_func(resampler->index, resampler->buf, outbuf);
for (int ch = 0; ch < 3; ch++) {
- int32_t chsample = 0;
- for (int j = 0; j < SINCTABLELEN; j++) {
- unsigned sincindex = j*2;
- if (!(resampler->index&1)) sincindex++;
- bool sincsign = sincindex & (1<<(SINCTABLEBIT));
- unsigned sincmask = ((1<<(SINCTABLEBIT))-1);
- sincindex = (sincindex & sincmask) ^ (sincsign ? sincmask : 0);
- chsample += (resampler->buf[BUFINDEX(j)*3+ch] * sinctable[sincindex])>>2;
- }
- if (oscillo) oscillo[ch].buf[offset+i] = chsample >> 13;
- if (!(ssg->mask & (1<<ch))) sample += chsample;
+ if (oscillo) oscillo[ch].buf[offset+i] = outbuf[ch] >> 15;
+ if (!(ssg->mask & (1<<ch))) sample += outbuf[ch] >> 2;
}
sample >>= 16;
sample *= 13000;