asd;klfj
This commit is contained in:
parent
23b65c61ce
commit
56b786f55e
19
src/engine/platform/sound/c64_d/LICENSE
Normal file
19
src/engine/platform/sound/c64_d/LICENSE
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
Copyright (c) 2021 DefleMask Team
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
11
src/engine/platform/sound/c64_d/README.md
Normal file
11
src/engine/platform/sound/c64_d/README.md
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
dSID
|
||||
===
|
||||
|
||||
This is the SID core used in DefleMask.
|
||||
|
||||
The project started as a very careful port from jsSID, comparing the wave
|
||||
output from both, ensuring they were exactly the same.
|
||||
|
||||
## License
|
||||
|
||||
MIT License
|
||||
346
src/engine/platform/sound/c64_d/dsid.c
Normal file
346
src/engine/platform/sound/c64_d/dsid.c
Normal file
|
|
@ -0,0 +1,346 @@
|
|||
#include "dsid.h"
|
||||
#include <math.h> // INFINITY
|
||||
#include <stdlib.h>
|
||||
#include <string.h> // memset, memcpy
|
||||
|
||||
// defle internals
|
||||
void waveforms_add_sample(uint8_t id, int16_t left, int16_t right);
|
||||
|
||||
struct SID_chip sid;
|
||||
static char init_wf = 1;
|
||||
|
||||
const int Aexp[256] = {
|
||||
1, 30, 30, 30, 30, 30, 30, 16, 16, 16, 16, 16, 16, 16, 16, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
|
||||
|
||||
double cmbWF(int chn, int *wfa, int index, int differ6581, struct SID_globals *g) {
|
||||
if (differ6581 && sid.g.model == 6581)
|
||||
index &= 0x7FF;
|
||||
|
||||
return wfa[index];
|
||||
}
|
||||
|
||||
void cCmbWF(int *wfa, double bitmul, double bstr, double trh) {
|
||||
for (int i = 0; i < 4096; i++) {
|
||||
wfa[i] = 0;
|
||||
for (int j = 0; j < 12; j++) {
|
||||
double blvl = 0;
|
||||
for (int k = 0; k < 12; k++) {
|
||||
blvl += (bitmul / pow(bstr, abs(k - j))) * (((i >> k) & 1) - 0.5);
|
||||
}
|
||||
wfa[i] += (blvl >= trh) ? pow(2, j) : 0;
|
||||
}
|
||||
wfa[i] *= 12;
|
||||
}
|
||||
}
|
||||
|
||||
void dSID_init(double samplingRate, int model) {
|
||||
if (model == 6581) {
|
||||
sid.g.model = 6581;
|
||||
} else {
|
||||
sid.g.model = 8580;
|
||||
}
|
||||
|
||||
// SID area
|
||||
for (int i = 0xD400; i <= 0xD7FF; i++)
|
||||
sid.M[i] = 0;
|
||||
// IO area
|
||||
for (int i = 0xDE00; i <= 0xDFFF; i++)
|
||||
sid.M[i] = 0;
|
||||
|
||||
memset(sid.SIDct, 0, sizeof(sid.SIDct));
|
||||
for (int i = 0; i < 3; i++) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
sid.SIDct[i].ch[j].Ast = _HZ;
|
||||
sid.SIDct[i].ch[j].nLFSR = 0x7FFFF8;
|
||||
sid.SIDct[i].ch[j].prevwfout = 0;
|
||||
}
|
||||
sid.SIDct[i].ch[0].FSW = 1;
|
||||
sid.SIDct[i].ch[1].FSW = 2;
|
||||
sid.SIDct[i].ch[2].FSW = 4;
|
||||
}
|
||||
|
||||
sid.g.ctfr = -2.0 * 3.14 * (12500.0 / 256.0) / samplingRate,
|
||||
sid.g.ctf_ratio_6581 = -2.0 * 3.14 * (20000.0 / 256.0) / samplingRate;
|
||||
sid.g.ckr = (double) SID_CLK / samplingRate;
|
||||
|
||||
const double bAprd[16] = {9, 32 * 1, 63 * 1, 95 * 1, 149 * 1, 220 * 1,
|
||||
267 * 1, 313 * 1, 392 * 1, 977 * 1, 1954 * 1, 3126 * 1,
|
||||
3907 * 1, 11720 * 1, 19532 * 1, 31251 * 1};
|
||||
const int bAstp[16] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
|
||||
memcpy(&sid.g.Aprd, &bAprd, sizeof(bAprd));
|
||||
memcpy(&sid.g.Astp, &bAstp, sizeof(bAstp));
|
||||
if (init_wf) {
|
||||
cCmbWF(sid.g.trsaw, 0.8, 2.4, 0.64);
|
||||
cCmbWF(sid.g.pusaw, 1.4, 1.9, 0.68);
|
||||
cCmbWF(sid.g.Pulsetrsaw, 0.8, 2.5, 0.64);
|
||||
init_wf = 0;
|
||||
}
|
||||
|
||||
double prd0 = sid.g.ckr > 9 ? sid.g.ckr : 9;
|
||||
sid.g.Aprd[0] = prd0;
|
||||
sid.g.Astp[0] = ceil(prd0 / 9);
|
||||
}
|
||||
|
||||
double dSID_render() {
|
||||
double flin = 0, output = 0;
|
||||
double wfout = 0;
|
||||
for (int chn = 0; chn < SID_CHA; chn++) {
|
||||
struct SIDVOICE *voic = &((struct SIDMEM *) (sid.M))->v[chn];
|
||||
double pgt = (sid.SIDct->ch[chn].Ast & GAT);
|
||||
uint8_t ctrl = voic->control;
|
||||
uint8_t wf = ctrl & 0xF0;
|
||||
uint8_t test = ctrl & TST;
|
||||
uint8_t SR = voic->susres;
|
||||
double tmp = 0;
|
||||
if (pgt != (ctrl & GAT)) {
|
||||
if (pgt) {
|
||||
sid.SIDct->ch[chn].Ast &= 0xFF - (GAT | ATK | DECSUS);
|
||||
} else {
|
||||
sid.SIDct->ch[chn].Ast = (GAT | ATK | DECSUS);
|
||||
if ((SR & 0xF) > (sid.SIDct->ch[chn].pSR & 0xF))
|
||||
tmp = 1;
|
||||
}
|
||||
}
|
||||
sid.SIDct->ch[chn].pSR = SR;
|
||||
sid.SIDct->ch[chn].rcnt += sid.g.ckr;
|
||||
if (sid.SIDct->ch[chn].rcnt >= 0x8000)
|
||||
sid.SIDct->ch[chn].rcnt -= 0x8000;
|
||||
|
||||
static double step;
|
||||
double prd;
|
||||
|
||||
if (sid.SIDct->ch[chn].Ast & ATK) {
|
||||
step = voic->attack;
|
||||
prd = sid.g.Aprd[(int) step];
|
||||
} else if (sid.SIDct->ch[chn].Ast & DECSUS) {
|
||||
step = voic->decay;
|
||||
prd = sid.g.Aprd[(int) step];
|
||||
} else {
|
||||
step = SR & 0xF;
|
||||
prd = sid.g.Aprd[(int) step];
|
||||
}
|
||||
step = sid.g.Astp[(int) step];
|
||||
if (sid.SIDct->ch[chn].rcnt >= prd && sid.SIDct->ch[chn].rcnt < prd + sid.g.ckr &&
|
||||
tmp == 0) {
|
||||
sid.SIDct->ch[chn].rcnt -= prd;
|
||||
if ((sid.SIDct->ch[chn].Ast & ATK) ||
|
||||
++sid.SIDct->ch[chn].expcnt == Aexp[(int) sid.SIDct->ch[chn].envcnt]) {
|
||||
if (!(sid.SIDct->ch[chn].Ast & _HZ)) {
|
||||
if (sid.SIDct->ch[chn].Ast & ATK) {
|
||||
sid.SIDct->ch[chn].envcnt += step;
|
||||
if (sid.SIDct->ch[chn].envcnt >= 0xFF) {
|
||||
sid.SIDct->ch[chn].envcnt = 0xFF;
|
||||
sid.SIDct->ch[chn].Ast &= 0xFF - ATK;
|
||||
}
|
||||
} else if (!(sid.SIDct->ch[chn].Ast & DECSUS) ||
|
||||
sid.SIDct->ch[chn].envcnt > (SR >> 4) + (SR & 0xF0)) {
|
||||
sid.SIDct->ch[chn].envcnt -= step;
|
||||
if (sid.SIDct->ch[chn].envcnt <= 0 &&
|
||||
sid.SIDct->ch[chn].envcnt + step != 0) {
|
||||
sid.SIDct->ch[chn].envcnt = 0;
|
||||
sid.SIDct->ch[chn].Ast |= _HZ;
|
||||
}
|
||||
}
|
||||
}
|
||||
sid.SIDct->ch[chn].expcnt = 0;
|
||||
} else {
|
||||
}
|
||||
}
|
||||
sid.SIDct->ch[chn].envcnt = (int) sid.SIDct->ch[chn].envcnt & 0xFF;
|
||||
double aAdd = (voic->freq_low + voic->freq_high * 256) * sid.g.ckr;
|
||||
if (test || ((ctrl & SYN) && sid.SIDct->sMSBrise)) {
|
||||
sid.SIDct->ch[chn].pacc = 0;
|
||||
} else {
|
||||
sid.SIDct->ch[chn].pacc += aAdd;
|
||||
if (sid.SIDct->ch[chn].pacc > 0xFFFFFF)
|
||||
sid.SIDct->ch[chn].pacc -= 0x1000000;
|
||||
}
|
||||
double MSB = (int) sid.SIDct->ch[chn].pacc & 0x800000;
|
||||
sid.SIDct->sMSBrise = (MSB > ((int) sid.SIDct->ch[chn].pracc & 0x800000)) ? 1 : 0;
|
||||
|
||||
if (wf & NOI) {
|
||||
tmp = sid.SIDct->ch[chn].nLFSR;
|
||||
if ((((int) sid.SIDct->ch[chn].pacc & 0x100000) !=
|
||||
((int) sid.SIDct->ch[chn].pracc & 0x100000)) ||
|
||||
aAdd >= 0x100000) {
|
||||
step = ((int) tmp & 0x400000) ^ (((int) tmp & 0x20000) << 5);
|
||||
tmp = (((int) tmp << 1) + (step > 0 || test)) & 0x7FFFFF;
|
||||
sid.SIDct->ch[chn].nLFSR = tmp;
|
||||
}
|
||||
wfout = (wf & 0x70) ? 0
|
||||
: (((int) tmp & 0x100000) >> 5) + (((int) tmp & 0x40000) >> 4) +
|
||||
(((int) tmp & 0x4000) >> 1) + (((int) tmp & 0x800) << 1) +
|
||||
(((int) tmp & 0x200) << 2) + (((int) tmp & 0x20) << 5) +
|
||||
(((int) tmp & 0x04) << 7) + (((int) tmp & 0x01) << 8);
|
||||
} else if (wf & PUL) {
|
||||
double pw = (voic->pw_low + (voic->pw_high) * 256) * 16;
|
||||
tmp = (int) aAdd >> 9;
|
||||
if (0 < pw && pw < tmp)
|
||||
pw = tmp;
|
||||
tmp = (int) tmp ^ 0xFFFF;
|
||||
if (pw > tmp)
|
||||
pw = tmp;
|
||||
tmp = (int) sid.SIDct->ch[chn].pacc >> 8;
|
||||
if (wf == PUL) {
|
||||
int lel = ((int) aAdd >> 16);
|
||||
if (lel > 0) {
|
||||
step = 256.0 / (double) lel;
|
||||
} else {
|
||||
step = INFINITY;
|
||||
}
|
||||
if (test)
|
||||
wfout = 0xFFFF;
|
||||
else if (tmp < pw) {
|
||||
double lim = (0xFFFF - pw) * step;
|
||||
if (lim > 0xFFFF)
|
||||
lim = 0xFFFF;
|
||||
wfout = lim - (pw - tmp) * step;
|
||||
if (wfout < 0)
|
||||
wfout = 0;
|
||||
} else {
|
||||
double lim = pw * step;
|
||||
if (lim > 0xFFFF)
|
||||
lim = 0xFFFF;
|
||||
wfout = (0xFFFF - tmp) * step - lim;
|
||||
if (wfout >= 0)
|
||||
wfout = 0xFFFF;
|
||||
wfout = (int) wfout & 0xFFFF;
|
||||
}
|
||||
} else {
|
||||
wfout = (tmp >= pw || test) ? 0xFFFF : 0;
|
||||
if (wf & TRI) {
|
||||
if (wf & SAW) {
|
||||
wfout =
|
||||
(wfout) ? cmbWF(chn, sid.g.Pulsetrsaw, (int) tmp >> 4, 1, &sid.g) : 0;
|
||||
} else {
|
||||
tmp = (int) sid.SIDct->ch[chn].pacc ^ (ctrl & RNG ? sid.SIDct->sMSB : 0);
|
||||
wfout =
|
||||
(wfout)
|
||||
? cmbWF(chn, sid.g.pusaw,
|
||||
((int) tmp ^ ((int) tmp & 0x800000 ? 0xFFFFFF : 0)) >> 11,
|
||||
0, &sid.g)
|
||||
: 0;
|
||||
}
|
||||
} else if (wf & SAW)
|
||||
wfout = (wfout) ? cmbWF(chn, sid.g.pusaw, (int) tmp >> 4, 1, &sid.g) : 0;
|
||||
}
|
||||
} else if (wf & SAW) {
|
||||
wfout = (int) sid.SIDct->ch[chn].pacc >> 8;
|
||||
if (wf & TRI)
|
||||
wfout = cmbWF(chn, sid.g.trsaw, (int) wfout >> 4, 1, &sid.g);
|
||||
else {
|
||||
step = aAdd / 0x1200000;
|
||||
wfout += wfout * step;
|
||||
if (wfout > 0xFFFF)
|
||||
wfout = 0xFFFF - (wfout - 0x10000) / step;
|
||||
}
|
||||
} else if (wf & TRI) {
|
||||
tmp = (int) sid.SIDct->ch[chn].pacc ^ (ctrl & RNG ? sid.SIDct->sMSB : 0);
|
||||
wfout = ((int) tmp ^ ((int) tmp & 0x800000 ? 0xFFFFFF : 0)) >> 7;
|
||||
}
|
||||
if (wf)
|
||||
sid.SIDct->ch[chn].prevwfout = wfout;
|
||||
else {
|
||||
wfout = sid.SIDct->ch[chn].prevwfout;
|
||||
}
|
||||
sid.SIDct->ch[chn].pracc = sid.SIDct->ch[chn].pacc;
|
||||
sid.SIDct->sMSB = MSB;
|
||||
// double preflin = flin;
|
||||
if ((sid.mute_mask & (1 << chn))) {
|
||||
if (sid.M[0x17] & sid.SIDct->ch[chn].FSW) {
|
||||
double chnout = (wfout - 0x8000) * (sid.SIDct->ch[chn].envcnt / 256);
|
||||
flin += chnout;
|
||||
|
||||
// defle fake filter for solo waveform ahead
|
||||
// mostly copypasted from below
|
||||
double fakeflin = chnout;
|
||||
double fakeflout = 0;
|
||||
static double fakeplp[SID_CHA] = {0};
|
||||
static double fakepbp[SID_CHA] = {0};
|
||||
double ctf = ((double) (sid.M[0x15] & 7)) / 8 + sid.M[0x16] + 0.2;
|
||||
double reso;
|
||||
if (sid.g.model == 8580) {
|
||||
ctf = 1 - exp(ctf * sid.g.ctfr);
|
||||
reso = pow(2, ((double) (4 - (double) (sid.M[0x17] >> 4)) / 8));
|
||||
} else {
|
||||
if (ctf < 24)
|
||||
ctf = 0.035;
|
||||
else
|
||||
ctf = 1 - 1.263 * exp(ctf * sid.g.ctf_ratio_6581);
|
||||
reso = (sid.M[0x17] > 0x5F) ? 8.0 / (double) (sid.M[0x17] >> 4) : 1.41;
|
||||
}
|
||||
double tmp = fakeflin + fakepbp[chn] * reso + fakeplp[chn];
|
||||
if (sid.M[0x18] & HP)
|
||||
fakeflout -= tmp;
|
||||
tmp = fakepbp[chn] - tmp * ctf;
|
||||
fakepbp[chn] = tmp;
|
||||
if (sid.M[0x18] & BP)
|
||||
fakeflout -= tmp;
|
||||
tmp = fakeplp[chn] + tmp * ctf;
|
||||
fakeplp[chn] = tmp;
|
||||
if (sid.M[0x18] & LP)
|
||||
fakeflout += tmp;
|
||||
|
||||
double defle_wf_out = (fakeflout / SID_OUT_SCALE) * (sid.M[0x18] & 0xF) * 65535;
|
||||
waveforms_add_sample(1 + chn, defle_wf_out, defle_wf_out);
|
||||
} else if ((chn % SID_CHA) != 2 || !(sid.M[0x18] & OFF3)) {
|
||||
double chnout = (wfout - 0x8000) * (sid.SIDct->ch[chn].envcnt / 256);
|
||||
output += chnout;
|
||||
|
||||
double defle_wf_out = (chnout / SID_OUT_SCALE) * (sid.M[0x18] & 0xF) * 65535;
|
||||
waveforms_add_sample(1 + chn, defle_wf_out, defle_wf_out);
|
||||
}
|
||||
} else {
|
||||
waveforms_add_sample(1 + chn, 0, 0);
|
||||
}
|
||||
}
|
||||
int M1 = 0;
|
||||
if (M1 & 3)
|
||||
sid.M[0x1B] = (int) wfout >> 8;
|
||||
sid.M[0x1C] = sid.SIDct->ch[2].envcnt;
|
||||
|
||||
double ctf = ((double) (sid.M[0x15] & 7)) / 8 + sid.M[0x16] + 0.2;
|
||||
double reso;
|
||||
if (sid.g.model == 8580) {
|
||||
ctf = 1 - exp(ctf * sid.g.ctfr);
|
||||
reso = pow(2, ((double) (4 - (double) (sid.M[0x17] >> 4)) / 8));
|
||||
} else {
|
||||
if (ctf < 24)
|
||||
ctf = 0.035;
|
||||
else
|
||||
ctf = 1 - 1.263 * exp(ctf * sid.g.ctf_ratio_6581);
|
||||
reso = (sid.M[0x17] > 0x5F) ? 8.0 / (double) (sid.M[0x17] >> 4) : 1.41;
|
||||
}
|
||||
|
||||
double tmp = flin + sid.SIDct->pbp * reso + sid.SIDct->plp;
|
||||
if (sid.M[0x18] & HP)
|
||||
output -= tmp;
|
||||
tmp = sid.SIDct->pbp - tmp * ctf;
|
||||
sid.SIDct->pbp = tmp;
|
||||
if (sid.M[0x18] & BP)
|
||||
output -= tmp;
|
||||
tmp = sid.SIDct->plp + tmp * ctf;
|
||||
sid.SIDct->plp = tmp;
|
||||
if (sid.M[0x18] & LP)
|
||||
output += tmp;
|
||||
return (output / SID_OUT_SCALE) * (sid.M[0x18] & 0xF);
|
||||
}
|
||||
|
||||
void dSID_setMuteMask(int mute_mask) {
|
||||
sid.mute_mask = mute_mask;
|
||||
}
|
||||
|
||||
float dSID_getVolume(int channel) {
|
||||
if ((sid.M[0x18] & 0xF) == 0)
|
||||
return 0;
|
||||
return sid.SIDct[0].ch[channel].envcnt / 256.0f;
|
||||
}
|
||||
112
src/engine/platform/sound/c64_d/dsid.h
Normal file
112
src/engine/platform/sound/c64_d/dsid.h
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define SID_CLK 985248
|
||||
#define SID_CHA 3
|
||||
#define SID_OUT_SCALE (0x10000 * SID_CHA * 16)
|
||||
|
||||
// TODO: prefix SID_
|
||||
|
||||
// CONTROL
|
||||
#define GAT 0x01
|
||||
#define SYN 0x02
|
||||
#define RNG 0x04
|
||||
#define TST 0x08
|
||||
#define TRI 0x10
|
||||
#define SAW 0x20
|
||||
#define PUL 0x40
|
||||
#define NOI 0x80
|
||||
|
||||
#define _HZ 0x10
|
||||
#define DECSUS 0x40
|
||||
#define ATK 0x80
|
||||
|
||||
// TODO: change
|
||||
// filter mode (high)
|
||||
#define LP 0x10
|
||||
#define BP 0x20
|
||||
#define HP 0x40
|
||||
#define OFF3 0x80
|
||||
|
||||
extern const int Aexp[256];
|
||||
|
||||
struct SID_ctx_chan {
|
||||
double rcnt;
|
||||
double envcnt;
|
||||
double expcnt;
|
||||
double pacc;
|
||||
double pracc;
|
||||
int FSW;
|
||||
int nLFSR;
|
||||
double prevwfout;
|
||||
uint8_t pSR;
|
||||
int Ast;
|
||||
};
|
||||
|
||||
struct SID_ctx {
|
||||
int sMSBrise;
|
||||
int sMSB;
|
||||
double plp;
|
||||
double pbp;
|
||||
struct SID_ctx_chan ch[3];
|
||||
};
|
||||
|
||||
struct SIDVOICE {
|
||||
uint8_t freq_low;
|
||||
uint8_t freq_high;
|
||||
uint8_t pw_low;
|
||||
uint8_t pw_high : 4;
|
||||
uint8_t UNUSED : 4;
|
||||
uint8_t control;
|
||||
uint8_t decay : 4;
|
||||
uint8_t attack : 4;
|
||||
uint8_t susres;
|
||||
// uint8_t release : 4;
|
||||
// uint8_t sustain : 4;
|
||||
};
|
||||
|
||||
struct SIDMEM {
|
||||
struct SIDVOICE v[SID_CHA];
|
||||
uint8_t UNUSED : 4;
|
||||
uint8_t cutoff_low : 4;
|
||||
uint8_t cutoff_high;
|
||||
uint8_t reso_rt : 4;
|
||||
uint8_t reso : 4;
|
||||
uint8_t volume : 4;
|
||||
uint8_t filter_mode : 4;
|
||||
uint8_t paddlex;
|
||||
uint8_t paddley;
|
||||
uint8_t osc3;
|
||||
uint8_t env3;
|
||||
};
|
||||
|
||||
struct SID_globals {
|
||||
double ckr;
|
||||
double ctfr;
|
||||
double ctf_ratio_6581;
|
||||
|
||||
int trsaw[4096];
|
||||
int pusaw[4096];
|
||||
int Pulsetrsaw[4096];
|
||||
|
||||
double Aprd[16];
|
||||
int Astp[16];
|
||||
int model;
|
||||
};
|
||||
|
||||
#define MemLen 65536
|
||||
|
||||
struct SID_chip {
|
||||
struct SID_globals g;
|
||||
struct SID_ctx SIDct[3];
|
||||
uint8_t M[MemLen];
|
||||
int mute_mask;
|
||||
};
|
||||
|
||||
extern struct SID_chip sid;
|
||||
|
||||
double dSID_render();
|
||||
void dSID_init(double samplingRate, int model);
|
||||
float dSID_getVolume(int channel);
|
||||
void dSID_setMuteMask(int mute_mask);
|
||||
Loading…
Reference in a new issue