SPC_DSP.cpp
1 // snes_spc 0.9.0. http://www.slack.net/~ant/ 2 #include "SPC_DSP.h" 3 4 #include "blargg_endian.h" 5 #include <string.h> 6 7 /* Copyright (C) 2007 Shay Green. This module is free software; you 8 can redistribute it and/or modify it under the terms of the GNU Lesser 9 General Public License as published by the Free Software Foundation; either 10 version 2.1 of the License, or (at your option) any later version. This 11 module is distributed in the hope that it will be useful, but WITHOUT ANY 12 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 13 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 14 details. You should have received a copy of the GNU Lesser General Public 15 License along with this module; if not, write to the Free Software Foundation, 16 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ 17 18 #include "blargg_source.h" 19 20 #ifdef BLARGG_ENABLE_OPTIMIZER 21 #include BLARGG_ENABLE_OPTIMIZER 22 #endif 23 24 #if INT_MAX < 0x7FFFFFFF 25 #error "Requires that int type have at least 32 bits" 26 #endif 27 28 // TODO: add to blargg_endian.h 29 #define GET_LE16SA( addr ) ((BOOST::int16_t) GET_LE16( addr )) 30 #define GET_LE16A( addr ) GET_LE16( addr ) 31 #define SET_LE16A( addr, data ) SET_LE16( addr, data ) 32 33 static BOOST::uint8_t const initial_regs [SPC_DSP::register_count] = 34 { 35 0x45,0x8B,0x5A,0x9A,0xE4,0x82,0x1B,0x78,0x00,0x00,0xAA,0x96,0x89,0x0E,0xE0,0x80, 36 0x2A,0x49,0x3D,0xBA,0x14,0xA0,0xAC,0xC5,0x00,0x00,0x51,0xBB,0x9C,0x4E,0x7B,0xFF, 37 0xF4,0xFD,0x57,0x32,0x37,0xD9,0x42,0x22,0x00,0x00,0x5B,0x3C,0x9F,0x1B,0x87,0x9A, 38 0x6F,0x27,0xAF,0x7B,0xE5,0x68,0x0A,0xD9,0x00,0x00,0x9A,0xC5,0x9C,0x4E,0x7B,0xFF, 39 0xEA,0x21,0x78,0x4F,0xDD,0xED,0x24,0x14,0x00,0x00,0x77,0xB1,0xD1,0x36,0xC1,0x67, 40 0x52,0x57,0x46,0x3D,0x59,0xF4,0x87,0xA4,0x00,0x00,0x7E,0x44,0x9C,0x4E,0x7B,0xFF, 41 0x75,0xF5,0x06,0x97,0x10,0xC3,0x24,0xBB,0x00,0x00,0x7B,0x7A,0xE0,0x60,0x12,0x0F, 42 0xF7,0x74,0x1C,0xE5,0x39,0x3D,0x73,0xC1,0x00,0x00,0x7A,0xB3,0xFF,0x4E,0x7B,0xFF 43 }; 44 45 // if ( io < -32768 ) io = -32768; 46 // if ( io > 32767 ) io = 32767; 47 #define CLAMP16( io )\ 48 {\ 49 if ( (int16_t) io != io )\ 50 io = (io >> 31) ^ 0x7FFF;\ 51 } 52 53 // Access global DSP register 54 #define REG(n) m.regs [r_##n] 55 56 // Access voice DSP register 57 #define VREG(r,n) r [v_##n] 58 59 #define WRITE_SAMPLES( l, r, out ) \ 60 {\ 61 out [0] = l;\ 62 out [1] = r;\ 63 out += 2;\ 64 if ( out >= m.out_end )\ 65 {\ 66 check( out == m.out_end );\ 67 check( m.out_end != &m.extra [extra_size] || \ 68 (m.extra <= m.out_begin && m.extra < &m.extra [extra_size]) );\ 69 out = m.extra;\ 70 m.out_end = &m.extra [extra_size];\ 71 }\ 72 }\ 73 74 void SPC_DSP::set_output( sample_t* out, int size ) 75 { 76 require( (size & 1) == 0 ); // must be even 77 if ( !out ) 78 { 79 out = m.extra; 80 size = extra_size; 81 } 82 m.out_begin = out; 83 m.out = out; 84 m.out_end = out + size; 85 } 86 87 // Volume registers and efb are signed! Easy to forget int8_t cast. 88 // Prefixes are to avoid accidental use of locals with same names. 89 90 // Gaussian interpolation 91 92 static short const gauss [512] = 93 { 94 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 96 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 97 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 98 11, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 15, 16, 16, 17, 17, 99 18, 19, 19, 20, 20, 21, 21, 22, 23, 23, 24, 24, 25, 26, 27, 27, 100 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 36, 36, 37, 38, 39, 40, 101 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 102 58, 59, 60, 61, 62, 64, 65, 66, 67, 69, 70, 71, 73, 74, 76, 77, 103 78, 80, 81, 83, 84, 86, 87, 89, 90, 92, 94, 95, 97, 99, 100, 102, 104 104, 106, 107, 109, 111, 113, 115, 117, 118, 120, 122, 124, 126, 128, 130, 132, 105 134, 137, 139, 141, 143, 145, 147, 150, 152, 154, 156, 159, 161, 163, 166, 168, 106 171, 173, 175, 178, 180, 183, 186, 188, 191, 193, 196, 199, 201, 204, 207, 210, 107 212, 215, 218, 221, 224, 227, 230, 233, 236, 239, 242, 245, 248, 251, 254, 257, 108 260, 263, 267, 270, 273, 276, 280, 283, 286, 290, 293, 297, 300, 304, 307, 311, 109 314, 318, 321, 325, 328, 332, 336, 339, 343, 347, 351, 354, 358, 362, 366, 370, 110 374, 378, 381, 385, 389, 393, 397, 401, 405, 410, 414, 418, 422, 426, 430, 434, 111 439, 443, 447, 451, 456, 460, 464, 469, 473, 477, 482, 486, 491, 495, 499, 504, 112 508, 513, 517, 522, 527, 531, 536, 540, 545, 550, 554, 559, 563, 568, 573, 577, 113 582, 587, 592, 596, 601, 606, 611, 615, 620, 625, 630, 635, 640, 644, 649, 654, 114 659, 664, 669, 674, 678, 683, 688, 693, 698, 703, 708, 713, 718, 723, 728, 732, 115 737, 742, 747, 752, 757, 762, 767, 772, 777, 782, 787, 792, 797, 802, 806, 811, 116 816, 821, 826, 831, 836, 841, 846, 851, 855, 860, 865, 870, 875, 880, 884, 889, 117 894, 899, 904, 908, 913, 918, 923, 927, 932, 937, 941, 946, 951, 955, 960, 965, 118 969, 974, 978, 983, 988, 992, 997,1001,1005,1010,1014,1019,1023,1027,1032,1036, 119 1040,1045,1049,1053,1057,1061,1066,1070,1074,1078,1082,1086,1090,1094,1098,1102, 120 1106,1109,1113,1117,1121,1125,1128,1132,1136,1139,1143,1146,1150,1153,1157,1160, 121 1164,1167,1170,1174,1177,1180,1183,1186,1190,1193,1196,1199,1202,1205,1207,1210, 122 1213,1216,1219,1221,1224,1227,1229,1232,1234,1237,1239,1241,1244,1246,1248,1251, 123 1253,1255,1257,1259,1261,1263,1265,1267,1269,1270,1272,1274,1275,1277,1279,1280, 124 1282,1283,1284,1286,1287,1288,1290,1291,1292,1293,1294,1295,1296,1297,1297,1298, 125 1299,1300,1300,1301,1302,1302,1303,1303,1303,1304,1304,1304,1304,1304,1305,1305, 126 }; 127 128 inline int SPC_DSP::interpolate( voice_t const* v ) 129 { 130 // Make pointers into gaussian based on fractional position between samples 131 int offset = v->interp_pos >> 4 & 0xFF; 132 short const* fwd = gauss + 255 - offset; 133 short const* rev = gauss + offset; // mirror left half of gaussian 134 135 int const* in = &v->buf [(v->interp_pos >> 12) + v->buf_pos]; 136 int out; 137 out = (fwd [ 0] * in [0]) >> 11; 138 out += (fwd [256] * in [1]) >> 11; 139 out += (rev [256] * in [2]) >> 11; 140 out = (int16_t) out; 141 out += (rev [ 0] * in [3]) >> 11; 142 143 CLAMP16( out ); 144 out &= ~1; 145 return out; 146 } 147 148 149 //// Counters 150 151 int const simple_counter_range = 2048 * 5 * 3; // 30720 152 153 static unsigned const counter_rates [32] = 154 { 155 simple_counter_range + 1, // never fires 156 2048, 1536, 157 1280, 1024, 768, 158 640, 512, 384, 159 320, 256, 192, 160 160, 128, 96, 161 80, 64, 48, 162 40, 32, 24, 163 20, 16, 12, 164 10, 8, 6, 165 5, 4, 3, 166 2, 167 1 168 }; 169 170 static unsigned const counter_offsets [32] = 171 { 172 1, 0, 1040, 173 536, 0, 1040, 174 536, 0, 1040, 175 536, 0, 1040, 176 536, 0, 1040, 177 536, 0, 1040, 178 536, 0, 1040, 179 536, 0, 1040, 180 536, 0, 1040, 181 536, 0, 1040, 182 0, 183 0 184 }; 185 186 inline void SPC_DSP::init_counter() 187 { 188 m.counter = 0; 189 } 190 191 inline void SPC_DSP::run_counters() 192 { 193 if ( --m.counter < 0 ) 194 m.counter = simple_counter_range - 1; 195 } 196 197 inline unsigned SPC_DSP::read_counter( int rate ) 198 { 199 return ((unsigned) m.counter + counter_offsets [rate]) % counter_rates [rate]; 200 } 201 202 203 //// Envelope 204 205 inline void SPC_DSP::run_envelope( voice_t* const v ) 206 { 207 int env = v->env; 208 if ( v->env_mode == env_release ) // 60% 209 { 210 if ( (env -= 0x8) < 0 ) 211 env = 0; 212 v->env = env; 213 } 214 else 215 { 216 int rate; 217 int env_data = VREG(v->regs,adsr1); 218 if ( m.t_adsr0 & 0x80 ) // 99% ADSR 219 { 220 if ( v->env_mode >= env_decay ) // 99% 221 { 222 env--; 223 env -= env >> 8; 224 rate = env_data & 0x1F; 225 if ( v->env_mode == env_decay ) // 1% 226 rate = (m.t_adsr0 >> 3 & 0x0E) + 0x10; 227 } 228 else // env_attack 229 { 230 rate = (m.t_adsr0 & 0x0F) * 2 + 1; 231 env += rate < 31 ? 0x20 : 0x400; 232 } 233 } 234 else // GAIN 235 { 236 int mode; 237 env_data = VREG(v->regs,gain); 238 mode = env_data >> 5; 239 if ( mode < 4 ) // direct 240 { 241 env = env_data * 0x10; 242 rate = 31; 243 } 244 else 245 { 246 rate = env_data & 0x1F; 247 if ( mode == 4 ) // 4: linear decrease 248 { 249 env -= 0x20; 250 } 251 else if ( mode < 6 ) // 5: exponential decrease 252 { 253 env--; 254 env -= env >> 8; 255 } 256 else // 6,7: linear increase 257 { 258 env += 0x20; 259 if ( mode > 6 && (unsigned) v->hidden_env >= 0x600 ) 260 env += 0x8 - 0x20; // 7: two-slope linear increase 261 } 262 } 263 } 264 265 // Sustain level 266 if ( (env >> 8) == (env_data >> 5) && v->env_mode == env_decay ) 267 v->env_mode = env_sustain; 268 269 v->hidden_env = env; 270 271 // unsigned cast because linear decrease going negative also triggers this 272 if ( (unsigned) env > 0x7FF ) 273 { 274 env = (env < 0 ? 0 : 0x7FF); 275 if ( v->env_mode == env_attack ) 276 v->env_mode = env_decay; 277 } 278 279 if ( !read_counter( rate ) ) 280 v->env = env; // nothing else is controlled by the counter 281 } 282 } 283 284 285 //// BRR Decoding 286 287 inline void SPC_DSP::decode_brr( voice_t* v ) 288 { 289 // Arrange the four input nybbles in 0xABCD order for easy decoding 290 int nybbles = m.t_brr_byte * 0x100 + m.ram [(v->brr_addr + v->brr_offset + 1) & 0xFFFF]; 291 292 int const header = m.t_brr_header; 293 294 // Write to next four samples in circular buffer 295 int* pos = &v->buf [v->buf_pos]; 296 int* end; 297 if ( (v->buf_pos += 4) >= brr_buf_size ) 298 v->buf_pos = 0; 299 300 // Decode four samples 301 for ( end = pos + 4; pos < end; pos++, nybbles <<= 4 ) 302 { 303 // Extract nybble and sign-extend 304 int s = (int16_t) nybbles >> 12; 305 306 // Shift sample based on header 307 int const shift = header >> 4; 308 s = (s << shift) >> 1; 309 if ( shift >= 0xD ) // handle invalid range 310 s = (s >> 25) << 11; // same as: s = (s < 0 ? -0x800 : 0) 311 312 // Apply IIR filter (8 is the most commonly used) 313 int const filter = header & 0x0C; 314 int const p1 = pos [brr_buf_size - 1]; 315 int const p2 = pos [brr_buf_size - 2] >> 1; 316 if ( filter >= 8 ) 317 { 318 s += p1; 319 s -= p2; 320 if ( filter == 8 ) // s += p1 * 0.953125 - p2 * 0.46875 321 { 322 s += p2 >> 4; 323 s += (p1 * -3) >> 6; 324 } 325 else // s += p1 * 0.8984375 - p2 * 0.40625 326 { 327 s += (p1 * -13) >> 7; 328 s += (p2 * 3) >> 4; 329 } 330 } 331 else if ( filter ) // s += p1 * 0.46875 332 { 333 s += p1 >> 1; 334 s += (-p1) >> 5; 335 } 336 337 // Adjust and write sample 338 CLAMP16( s ); 339 s = (int16_t) (s * 2); 340 pos [brr_buf_size] = pos [0] = s; // second copy simplifies wrap-around 341 } 342 } 343 344 345 //// Misc 346 347 #define MISC_CLOCK( n ) inline void SPC_DSP::misc_##n() 348 349 MISC_CLOCK( 27 ) 350 { 351 m.t_pmon = REG(pmon) & 0xFE; // voice 0 doesn't support PMON 352 } 353 MISC_CLOCK( 28 ) 354 { 355 m.t_non = REG(non); 356 m.t_eon = REG(eon); 357 m.t_dir = REG(dir); 358 } 359 MISC_CLOCK( 29 ) 360 { 361 if ( (m.every_other_sample ^= 1) != 0 ) 362 m.new_kon &= ~m.kon; // clears KON 63 clocks after it was last read 363 } 364 MISC_CLOCK( 30 ) 365 { 366 if ( m.every_other_sample ) 367 { 368 m.kon = m.new_kon; 369 m.t_koff = REG(koff) | m.mute_mask; 370 } 371 372 run_counters(); 373 374 // Noise 375 if ( !read_counter( REG(flg) & 0x1F ) ) 376 { 377 int feedback = (m.noise << 13) ^ (m.noise << 14); 378 m.noise = (feedback & 0x4000) ^ (m.noise >> 1); 379 } 380 } 381 382 383 //// Voices 384 385 #define VOICE_CLOCK( n ) void SPC_DSP::voice_##n( voice_t* const v ) 386 387 inline VOICE_CLOCK( V1 ) 388 { 389 m.t_dir_addr = m.t_dir * 0x100 + m.t_srcn * 4; 390 m.t_srcn = VREG(v->regs,srcn); 391 } 392 inline VOICE_CLOCK( V2 ) 393 { 394 // Read sample pointer (ignored if not needed) 395 uint8_t const* entry = &m.ram [m.t_dir_addr]; 396 if ( !v->kon_delay ) 397 entry += 2; 398 m.t_brr_next_addr = GET_LE16A( entry ); 399 400 m.t_adsr0 = VREG(v->regs,adsr0); 401 402 // Read pitch, spread over two clocks 403 m.t_pitch = VREG(v->regs,pitchl); 404 } 405 inline VOICE_CLOCK( V3a ) 406 { 407 m.t_pitch += (VREG(v->regs,pitchh) & 0x3F) << 8; 408 } 409 inline VOICE_CLOCK( V3b ) 410 { 411 // Read BRR header and byte 412 m.t_brr_byte = m.ram [(v->brr_addr + v->brr_offset) & 0xFFFF]; 413 m.t_brr_header = m.ram [v->brr_addr]; // brr_addr doesn't need masking 414 } 415 VOICE_CLOCK( V3c ) 416 { 417 // Pitch modulation using previous voice's output 418 if ( m.t_pmon & v->vbit ) 419 m.t_pitch += ((m.t_output >> 5) * m.t_pitch) >> 10; 420 421 if ( v->kon_delay ) 422 { 423 // Get ready to start BRR decoding on next sample 424 if ( v->kon_delay == 5 ) 425 { 426 v->brr_addr = m.t_brr_next_addr; 427 v->brr_offset = 1; 428 v->buf_pos = 0; 429 m.t_brr_header = 0; // header is ignored on this sample 430 m.kon_check = true; 431 432 if (take_spc_snapshot) 433 { 434 take_spc_snapshot = 0; 435 if (spc_snapshot_callback) 436 spc_snapshot_callback(); 437 } 438 } 439 440 // Envelope is never run during KON 441 v->env = 0; 442 v->hidden_env = 0; 443 444 // Disable BRR decoding until last three samples 445 v->interp_pos = 0; 446 if ( --v->kon_delay & 3 ) 447 v->interp_pos = 0x4000; 448 449 // Pitch is never added during KON 450 m.t_pitch = 0; 451 } 452 453 // Gaussian interpolation 454 { 455 int output = interpolate( v ); 456 457 // Noise 458 if ( m.t_non & v->vbit ) 459 output = (int16_t) (m.noise * 2); 460 461 // Apply envelope 462 m.t_output = (output * v->env) >> 11 & ~1; 463 v->t_envx_out = (uint8_t) (v->env >> 4); 464 } 465 466 // Immediate silence due to end of sample or soft reset 467 if ( REG(flg) & 0x80 || (m.t_brr_header & 3) == 1 ) 468 { 469 v->env_mode = env_release; 470 v->env = 0; 471 } 472 473 if ( m.every_other_sample ) 474 { 475 // KOFF 476 if ( m.t_koff & v->vbit ) 477 v->env_mode = env_release; 478 479 // KON 480 if ( m.kon & v->vbit ) 481 { 482 v->kon_delay = 5; 483 v->env_mode = env_attack; 484 } 485 } 486 487 // Run envelope for next sample 488 if ( !v->kon_delay ) 489 run_envelope( v ); 490 } 491 492 inline void SPC_DSP::voice_output( voice_t const* v, int ch ) 493 { 494 // Apply left/right volume 495 int amp = (m.t_output * (int8_t) VREG(v->regs,voll + ch)) >> 7; 496 amp *= ((stereo_switch & (1 << (v->voice_number + ch * voice_count))) ? 1 : 0); 497 498 // Add to output total 499 m.t_main_out [ch] += amp; 500 CLAMP16( m.t_main_out [ch] ); 501 502 // Optionally add to echo total 503 if ( m.t_eon & v->vbit ) 504 { 505 m.t_echo_out [ch] += amp; 506 CLAMP16( m.t_echo_out [ch] ); 507 } 508 } 509 VOICE_CLOCK( V4 ) 510 { 511 // Decode BRR 512 m.t_looped = 0; 513 if ( v->interp_pos >= 0x4000 ) 514 { 515 decode_brr( v ); 516 517 if ( (v->brr_offset += 2) >= brr_block_size ) 518 { 519 // Start decoding next BRR block 520 assert( v->brr_offset == brr_block_size ); 521 v->brr_addr = (v->brr_addr + brr_block_size) & 0xFFFF; 522 if ( m.t_brr_header & 1 ) 523 { 524 v->brr_addr = m.t_brr_next_addr; 525 m.t_looped = v->vbit; 526 } 527 v->brr_offset = 1; 528 } 529 } 530 531 // Apply pitch 532 v->interp_pos = (v->interp_pos & 0x3FFF) + m.t_pitch; 533 534 // Keep from getting too far ahead (when using pitch modulation) 535 if ( v->interp_pos > 0x7FFF ) 536 v->interp_pos = 0x7FFF; 537 538 // Output left 539 voice_output( v, 0 ); 540 } 541 inline VOICE_CLOCK( V5 ) 542 { 543 // Output right 544 voice_output( v, 1 ); 545 546 // ENDX, OUTX, and ENVX won't update if you wrote to them 1-2 clocks earlier 547 int endx_buf = REG(endx) | m.t_looped; 548 549 // Clear bit in ENDX if KON just began 550 if ( v->kon_delay == 5 ) 551 endx_buf &= ~v->vbit; 552 m.endx_buf = (uint8_t) endx_buf; 553 } 554 inline VOICE_CLOCK( V6 ) 555 { 556 (void) v; // avoid compiler warning about unused v 557 m.outx_buf = (uint8_t) (m.t_output >> 8); 558 } 559 inline VOICE_CLOCK( V7 ) 560 { 561 // Update ENDX 562 REG(endx) = m.endx_buf; 563 564 m.envx_buf = v->t_envx_out; 565 } 566 inline VOICE_CLOCK( V8 ) 567 { 568 // Update OUTX 569 VREG(v->regs,outx) = m.outx_buf; 570 } 571 inline VOICE_CLOCK( V9 ) 572 { 573 // Update ENVX 574 VREG(v->regs,envx) = m.envx_buf; 575 } 576 577 // Most voices do all these in one clock, so make a handy composite 578 inline VOICE_CLOCK( V3 ) 579 { 580 voice_V3a( v ); 581 voice_V3b( v ); 582 voice_V3c( v ); 583 } 584 585 // Common combinations of voice steps on different voices. This greatly reduces 586 // code size and allows everything to be inlined in these functions. 587 VOICE_CLOCK(V7_V4_V1) { voice_V7(v); voice_V1(v+3); voice_V4(v+1); } 588 VOICE_CLOCK(V8_V5_V2) { voice_V8(v); voice_V5(v+1); voice_V2(v+2); } 589 VOICE_CLOCK(V9_V6_V3) { voice_V9(v); voice_V6(v+1); voice_V3(v+2); } 590 591 592 //// Echo 593 594 // Current echo buffer pointer for left/right channel 595 #define ECHO_PTR( ch ) (&m.ram [m.t_echo_ptr + ch * 2]) 596 597 // Sample in echo history buffer, where 0 is the oldest 598 #define ECHO_FIR( i ) (m.echo_hist_pos [i]) 599 600 // Calculate FIR point for left/right channel 601 #define CALC_FIR( i, ch ) ((ECHO_FIR( i + 1 ) [ch] * (int8_t) REG(fir + i * 0x10)) >> 6) 602 603 #define ECHO_CLOCK( n ) inline void SPC_DSP::echo_##n() 604 605 inline void SPC_DSP::echo_read( int ch ) 606 { 607 int s = GET_LE16SA( ECHO_PTR( ch ) ); 608 // second copy simplifies wrap-around handling 609 ECHO_FIR( 0 ) [ch] = ECHO_FIR( 8 ) [ch] = s >> 1; 610 } 611 612 ECHO_CLOCK( 22 ) 613 { 614 // History 615 if ( ++m.echo_hist_pos >= &m.echo_hist [echo_hist_size] ) 616 m.echo_hist_pos = m.echo_hist; 617 618 m.t_echo_ptr = (m.t_esa * 0x100 + m.echo_offset) & 0xFFFF; 619 echo_read( 0 ); 620 621 // FIR (using l and r temporaries below helps compiler optimize) 622 int l = CALC_FIR( 0, 0 ); 623 int r = CALC_FIR( 0, 1 ); 624 625 m.t_echo_in [0] = l; 626 m.t_echo_in [1] = r; 627 } 628 ECHO_CLOCK( 23 ) 629 { 630 int l = CALC_FIR( 1, 0 ) + CALC_FIR( 2, 0 ); 631 int r = CALC_FIR( 1, 1 ) + CALC_FIR( 2, 1 ); 632 633 m.t_echo_in [0] += l; 634 m.t_echo_in [1] += r; 635 636 echo_read( 1 ); 637 } 638 ECHO_CLOCK( 24 ) 639 { 640 int l = CALC_FIR( 3, 0 ) + CALC_FIR( 4, 0 ) + CALC_FIR( 5, 0 ); 641 int r = CALC_FIR( 3, 1 ) + CALC_FIR( 4, 1 ) + CALC_FIR( 5, 1 ); 642 643 m.t_echo_in [0] += l; 644 m.t_echo_in [1] += r; 645 } 646 ECHO_CLOCK( 25 ) 647 { 648 int l = m.t_echo_in [0] + CALC_FIR( 6, 0 ); 649 int r = m.t_echo_in [1] + CALC_FIR( 6, 1 ); 650 651 l = (int16_t) l; 652 r = (int16_t) r; 653 654 l += (int16_t) CALC_FIR( 7, 0 ); 655 r += (int16_t) CALC_FIR( 7, 1 ); 656 657 CLAMP16( l ); 658 CLAMP16( r ); 659 660 m.t_echo_in [0] = l & ~1; 661 m.t_echo_in [1] = r & ~1; 662 } 663 inline int SPC_DSP::echo_output( int ch ) 664 { 665 int out = (int16_t) ((m.t_main_out [ch] * (int8_t) REG(mvoll + ch * 0x10)) >> 7) + 666 (int16_t) ((m.t_echo_in [ch] * (int8_t) REG(evoll + ch * 0x10)) >> 7); 667 CLAMP16( out ); 668 return out; 669 } 670 ECHO_CLOCK( 26 ) 671 { 672 // Left output volumes 673 // (save sample for next clock so we can output both together) 674 m.t_main_out [0] = echo_output( 0 ); 675 676 // Echo feedback 677 int l = m.t_echo_out [0] + (int16_t) ((m.t_echo_in [0] * (int8_t) REG(efb)) >> 7); 678 int r = m.t_echo_out [1] + (int16_t) ((m.t_echo_in [1] * (int8_t) REG(efb)) >> 7); 679 680 CLAMP16( l ); 681 CLAMP16( r ); 682 683 m.t_echo_out [0] = l & ~1; 684 m.t_echo_out [1] = r & ~1; 685 } 686 ECHO_CLOCK( 27 ) 687 { 688 // Output 689 int l = m.t_main_out [0]; 690 int r = echo_output( 1 ); 691 m.t_main_out [0] = 0; 692 m.t_main_out [1] = 0; 693 694 // TODO: global muting isn't this simple (turns DAC on and off 695 // or something, causing small ~37-sample pulse when first muted) 696 if ( REG(flg) & 0x40 ) 697 { 698 l = 0; 699 r = 0; 700 } 701 702 // Output sample to DAC 703 #ifdef SPC_DSP_OUT_HOOK 704 SPC_DSP_OUT_HOOK( l, r ); 705 #else 706 sample_t* out = m.out; 707 WRITE_SAMPLES( l, r, out ); 708 m.out = out; 709 #endif 710 } 711 ECHO_CLOCK( 28 ) 712 { 713 m.t_echo_enabled = REG(flg); 714 } 715 inline void SPC_DSP::echo_write( int ch ) 716 { 717 if ( !(m.t_echo_enabled & 0x20) ) 718 SET_LE16A( ECHO_PTR( ch ), m.t_echo_out [ch] ); 719 m.t_echo_out [ch] = 0; 720 } 721 ECHO_CLOCK( 29 ) 722 { 723 m.t_esa = REG(esa); 724 725 if ( !m.echo_offset ) 726 m.echo_length = (REG(edl) & 0x0F) * 0x800; 727 728 m.echo_offset += 4; 729 if ( m.echo_offset >= m.echo_length ) 730 m.echo_offset = 0; 731 732 // Write left echo 733 echo_write( 0 ); 734 735 m.t_echo_enabled = REG(flg); 736 } 737 ECHO_CLOCK( 30 ) 738 { 739 // Write right echo 740 echo_write( 1 ); 741 } 742 743 744 //// Timing 745 746 // Execute clock for a particular voice 747 #define V( clock, voice ) voice_##clock( &m.voices [voice] ); 748 749 /* The most common sequence of clocks uses composite operations 750 for efficiency. For example, the following are equivalent to the 751 individual steps on the right: 752 753 V(V7_V4_V1,2) -> V(V7,2) V(V4,3) V(V1,5) 754 V(V8_V5_V2,2) -> V(V8,2) V(V5,3) V(V2,4) 755 V(V9_V6_V3,2) -> V(V9,2) V(V6,3) V(V3,4) */ 756 757 // Voice 0 1 2 3 4 5 6 7 758 #define GEN_DSP_TIMING \ 759 PHASE( 0) V(V5,0)V(V2,1)\ 760 PHASE( 1) V(V6,0)V(V3,1)\ 761 PHASE( 2) V(V7_V4_V1,0)\ 762 PHASE( 3) V(V8_V5_V2,0)\ 763 PHASE( 4) V(V9_V6_V3,0)\ 764 PHASE( 5) V(V7_V4_V1,1)\ 765 PHASE( 6) V(V8_V5_V2,1)\ 766 PHASE( 7) V(V9_V6_V3,1)\ 767 PHASE( 8) V(V7_V4_V1,2)\ 768 PHASE( 9) V(V8_V5_V2,2)\ 769 PHASE(10) V(V9_V6_V3,2)\ 770 PHASE(11) V(V7_V4_V1,3)\ 771 PHASE(12) V(V8_V5_V2,3)\ 772 PHASE(13) V(V9_V6_V3,3)\ 773 PHASE(14) V(V7_V4_V1,4)\ 774 PHASE(15) V(V8_V5_V2,4)\ 775 PHASE(16) V(V9_V6_V3,4)\ 776 PHASE(17) V(V1,0) V(V7,5)V(V4,6)\ 777 PHASE(18) V(V8_V5_V2,5)\ 778 PHASE(19) V(V9_V6_V3,5)\ 779 PHASE(20) V(V1,1) V(V7,6)V(V4,7)\ 780 PHASE(21) V(V8,6)V(V5,7) V(V2,0) /* t_brr_next_addr order dependency */\ 781 PHASE(22) V(V3a,0) V(V9,6)V(V6,7) echo_22();\ 782 PHASE(23) V(V7,7) echo_23();\ 783 PHASE(24) V(V8,7) echo_24();\ 784 PHASE(25) V(V3b,0) V(V9,7) echo_25();\ 785 PHASE(26) echo_26();\ 786 PHASE(27) misc_27(); echo_27();\ 787 PHASE(28) misc_28(); echo_28();\ 788 PHASE(29) misc_29(); echo_29();\ 789 PHASE(30) misc_30();V(V3c,0) echo_30();\ 790 PHASE(31) V(V4,0) V(V1,2)\ 791 792 #if !SPC_DSP_CUSTOM_RUN 793 794 void SPC_DSP::run( int clocks_remain ) 795 { 796 require( clocks_remain > 0 ); 797 798 int const phase = m.phase; 799 m.phase = (phase + clocks_remain) & 31; 800 switch ( phase ) 801 { 802 loop: 803 804 #define PHASE( n ) if ( n && !--clocks_remain ) break; case n: 805 GEN_DSP_TIMING 806 #undef PHASE 807 808 if ( --clocks_remain ) 809 goto loop; 810 } 811 } 812 813 #endif 814 815 816 //// Setup 817 818 void SPC_DSP::init( void* ram_64k ) 819 { 820 m.ram = (uint8_t*) ram_64k; 821 mute_voices( 0 ); 822 disable_surround( false ); 823 set_output( 0, 0 ); 824 reset(); 825 826 stereo_switch = 0xffff; 827 take_spc_snapshot = 0; 828 spc_snapshot_callback = 0; 829 830 #ifndef NDEBUG 831 // be sure this sign-extends 832 assert( (int16_t) 0x8000 == -0x8000 ); 833 834 // be sure right shift preserves sign 835 assert( (-1 >> 1) == -1 ); 836 837 // check clamp macro 838 int i; 839 i = +0x8000; CLAMP16( i ); assert( i == +0x7FFF ); 840 i = -0x8001; CLAMP16( i ); assert( i == -0x8000 ); 841 842 blargg_verify_byte_order(); 843 #endif 844 } 845 846 void SPC_DSP::soft_reset_common() 847 { 848 require( m.ram ); // init() must have been called already 849 850 m.noise = 0x4000; 851 m.echo_hist_pos = m.echo_hist; 852 m.every_other_sample = 1; 853 m.echo_offset = 0; 854 m.phase = 0; 855 856 init_counter(); 857 858 for (int i = 0; i < voice_count; i++) 859 m.voices[i].voice_number = i; 860 } 861 862 void SPC_DSP::soft_reset() 863 { 864 REG(flg) = 0xE0; 865 soft_reset_common(); 866 } 867 868 void SPC_DSP::load( uint8_t const regs [register_count] ) 869 { 870 memcpy( m.regs, regs, sizeof m.regs ); 871 memset( &m.regs [register_count], 0, offsetof (state_t,ram) - register_count ); 872 873 // Internal state 874 for ( int i = voice_count; --i >= 0; ) 875 { 876 voice_t* v = &m.voices [i]; 877 v->brr_offset = 1; 878 v->vbit = 1 << i; 879 v->regs = &m.regs [i * 0x10]; 880 } 881 m.new_kon = REG(kon); 882 m.t_dir = REG(dir); 883 m.t_esa = REG(esa); 884 885 soft_reset_common(); 886 } 887 888 void SPC_DSP::reset() { load( initial_regs ); } 889 890 891 //// State save/load 892 893 #if !SPC_NO_COPY_STATE_FUNCS 894 895 void SPC_State_Copier::copy( void* state, size_t size ) 896 { 897 func( buf, state, size ); 898 } 899 900 int SPC_State_Copier::copy_int( int state, int size ) 901 { 902 BOOST::uint8_t s [2]; 903 SET_LE16( s, state ); 904 func( buf, &s, size ); 905 return GET_LE16( s ); 906 } 907 908 void SPC_State_Copier::skip( int count ) 909 { 910 if ( count > 0 ) 911 { 912 char temp [64]; 913 memset( temp, 0, sizeof temp ); 914 do 915 { 916 int n = sizeof temp; 917 if ( n > count ) 918 n = count; 919 count -= n; 920 func( buf, temp, n ); 921 } 922 while ( count ); 923 } 924 } 925 926 void SPC_State_Copier::extra() 927 { 928 int n = 0; 929 SPC_State_Copier& copier = *this; 930 SPC_COPY( uint8_t, n ); 931 skip( n ); 932 } 933 934 void SPC_DSP::copy_state( unsigned char** io, copy_func_t copy ) 935 { 936 SPC_State_Copier copier( io, copy ); 937 938 // DSP registers 939 copier.copy( m.regs, register_count ); 940 941 // Internal state 942 943 // Voices 944 int i; 945 for ( i = 0; i < voice_count; i++ ) 946 { 947 voice_t* v = &m.voices [i]; 948 949 // BRR buffer 950 int i; 951 for ( i = 0; i < brr_buf_size; i++ ) 952 { 953 int s = v->buf [i]; 954 SPC_COPY( int16_t, s ); 955 v->buf [i] = v->buf [i + brr_buf_size] = s; 956 } 957 958 SPC_COPY( uint16_t, v->interp_pos ); 959 SPC_COPY( uint16_t, v->brr_addr ); 960 SPC_COPY( uint16_t, v->env ); 961 SPC_COPY( int16_t, v->hidden_env ); 962 SPC_COPY( uint8_t, v->buf_pos ); 963 SPC_COPY( uint8_t, v->brr_offset ); 964 SPC_COPY( uint8_t, v->kon_delay ); 965 { 966 int m = v->env_mode; 967 SPC_COPY( uint8_t, m ); 968 v->env_mode = (enum env_mode_t) m; 969 } 970 SPC_COPY( uint8_t, v->t_envx_out ); 971 972 copier.extra(); 973 } 974 975 // Echo history 976 for ( i = 0; i < echo_hist_size; i++ ) 977 { 978 int j; 979 for ( j = 0; j < 2; j++ ) 980 { 981 int s = m.echo_hist_pos [i] [j]; 982 SPC_COPY( int16_t, s ); 983 m.echo_hist [i] [j] = s; // write back at offset 0 984 } 985 } 986 m.echo_hist_pos = m.echo_hist; 987 memcpy( &m.echo_hist [echo_hist_size], m.echo_hist, echo_hist_size * sizeof m.echo_hist [0] ); 988 989 // Misc 990 SPC_COPY( uint8_t, m.every_other_sample ); 991 SPC_COPY( uint8_t, m.kon ); 992 993 SPC_COPY( uint16_t, m.noise ); 994 SPC_COPY( uint16_t, m.counter ); 995 SPC_COPY( uint16_t, m.echo_offset ); 996 SPC_COPY( uint16_t, m.echo_length ); 997 SPC_COPY( uint8_t, m.phase ); 998 999 SPC_COPY( uint8_t, m.new_kon ); 1000 SPC_COPY( uint8_t, m.endx_buf ); 1001 SPC_COPY( uint8_t, m.envx_buf ); 1002 SPC_COPY( uint8_t, m.outx_buf ); 1003 1004 SPC_COPY( uint8_t, m.t_pmon ); 1005 SPC_COPY( uint8_t, m.t_non ); 1006 SPC_COPY( uint8_t, m.t_eon ); 1007 SPC_COPY( uint8_t, m.t_dir ); 1008 SPC_COPY( uint8_t, m.t_koff ); 1009 1010 SPC_COPY( uint16_t, m.t_brr_next_addr ); 1011 SPC_COPY( uint8_t, m.t_adsr0 ); 1012 SPC_COPY( uint8_t, m.t_brr_header ); 1013 SPC_COPY( uint8_t, m.t_brr_byte ); 1014 SPC_COPY( uint8_t, m.t_srcn ); 1015 SPC_COPY( uint8_t, m.t_esa ); 1016 SPC_COPY( uint8_t, m.t_echo_enabled ); 1017 1018 SPC_COPY( int16_t, m.t_main_out [0] ); 1019 SPC_COPY( int16_t, m.t_main_out [1] ); 1020 SPC_COPY( int16_t, m.t_echo_out [0] ); 1021 SPC_COPY( int16_t, m.t_echo_out [1] ); 1022 SPC_COPY( int16_t, m.t_echo_in [0] ); 1023 SPC_COPY( int16_t, m.t_echo_in [1] ); 1024 1025 SPC_COPY( uint16_t, m.t_dir_addr ); 1026 SPC_COPY( uint16_t, m.t_pitch ); 1027 SPC_COPY( int16_t, m.t_output ); 1028 SPC_COPY( uint16_t, m.t_echo_ptr ); 1029 SPC_COPY( uint8_t, m.t_looped ); 1030 1031 copier.extra(); 1032 } 1033 #endif 1034 1035 1036 //// Snes9x Accessor 1037 1038 void SPC_DSP::set_spc_snapshot_callback( void (*callback) (void) ) 1039 { 1040 spc_snapshot_callback = callback; 1041 } 1042 1043 void SPC_DSP::dump_spc_snapshot( void ) 1044 { 1045 take_spc_snapshot = 1; 1046 } 1047 1048 void SPC_DSP::set_stereo_switch( int value ) 1049 { 1050 stereo_switch = value; 1051 } 1052 1053 SPC_DSP::uint8_t SPC_DSP::reg_value( int ch, int addr ) 1054 { 1055 return m.voices[ch].regs[addr]; 1056 } 1057 1058 int SPC_DSP::envx_value( int ch ) 1059 { 1060 return m.voices[ch].env; 1061 }