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
	
	 tildearrow
						tildearrow