summaryrefslogtreecommitdiff
path: root/apps/codecs/libgme/nes_oscs.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/codecs/libgme/nes_oscs.c')
-rw-r--r--apps/codecs/libgme/nes_oscs.c73
1 files changed, 41 insertions, 32 deletions
diff --git a/apps/codecs/libgme/nes_oscs.c b/apps/codecs/libgme/nes_oscs.c
index 4402b60a61..f97ce2176d 100644
--- a/apps/codecs/libgme/nes_oscs.c
+++ b/apps/codecs/libgme/nes_oscs.c
@@ -90,7 +90,7 @@ static inline nes_time_t Square_maintain_phase( struct Nes_Square* this, nes_tim
90 { 90 {
91 int count = (remain + timer_period - 1) / timer_period; 91 int count = (remain + timer_period - 1) / timer_period;
92 this->phase = (this->phase + count) & (square_phase_range - 1); 92 this->phase = (this->phase + count) & (square_phase_range - 1);
93 time += (blargg_long) count * timer_period; 93 time += count * timer_period;
94 } 94 }
95 return time; 95 return time;
96} 96}
@@ -107,8 +107,6 @@ void Square_run( struct Nes_Square* this, nes_time_t time, nes_time_t end_time )
107 return; 107 return;
108 } 108 }
109 109
110 Blip_set_modified( osc->output );
111
112 int offset = period >> (osc->regs [1] & shift_mask); 110 int offset = period >> (osc->regs [1] & shift_mask);
113 if ( osc->regs [1] & negate_flag ) 111 if ( osc->regs [1] & negate_flag )
114 offset = 0; 112 offset = 0;
@@ -117,6 +115,7 @@ void Square_run( struct Nes_Square* this, nes_time_t time, nes_time_t end_time )
117 if ( volume == 0 || period < 8 || (period + offset) >= 0x800 ) 115 if ( volume == 0 || period < 8 || (period + offset) >= 0x800 )
118 { 116 {
119 if ( osc->last_amp ) { 117 if ( osc->last_amp ) {
118 Blip_set_modified( osc->output );
120 Synth_offset( this->synth, time, -osc->last_amp, osc->output ); 119 Synth_offset( this->synth, time, -osc->last_amp, osc->output );
121 osc->last_amp = 0; 120 osc->last_amp = 0;
122 } 121 }
@@ -137,6 +136,7 @@ void Square_run( struct Nes_Square* this, nes_time_t time, nes_time_t end_time )
137 if ( this->phase < duty ) 136 if ( this->phase < duty )
138 amp ^= volume; 137 amp ^= volume;
139 138
139 Blip_set_modified( osc->output );
140 { 140 {
141 int delta = Osc_update_amp( osc, amp ); 141 int delta = Osc_update_amp( osc, amp );
142 if ( delta ) 142 if ( delta )
@@ -201,7 +201,7 @@ static inline nes_time_t Triangle_maintain_phase( struct Nes_Triangle* this, nes
201 int count = (remain + timer_period - 1) / timer_period; 201 int count = (remain + timer_period - 1) / timer_period;
202 this->phase = ((unsigned) this->phase + 1 - count) & (Triangle_phase_range * 2 - 1); 202 this->phase = ((unsigned) this->phase + 1 - count) & (Triangle_phase_range * 2 - 1);
203 this->phase++; 203 this->phase++;
204 time += (blargg_long) count * timer_period; 204 time += count * timer_period;
205 } 205 }
206 return time; 206 return time;
207} 207}
@@ -219,14 +219,15 @@ void Triangle_run( struct Nes_Triangle* this, nes_time_t time, nes_time_t end_ti
219 return; 219 return;
220 } 220 }
221 221
222 Blip_set_modified( osc->output );
223
224 // to do: track phase when period < 3 222 // to do: track phase when period < 3
225 // to do: Output 7.5 on dac when period < 2? More accurate, but results in more clicks. 223 // to do: Output 7.5 on dac when period < 2? More accurate, but results in more clicks.
226 224
227 int delta = Osc_update_amp( osc, Triangle_calc_amp( this ) ); 225 int delta = Osc_update_amp( osc, Triangle_calc_amp( this ) );
228 if ( delta ) 226 if ( delta )
227 {
228 Blip_set_modified( osc->output );
229 Synth_offset( &this->synth, time, delta, osc->output ); 229 Synth_offset( &this->synth, time, delta, osc->output );
230 }
230 231
231 time += osc->delay; 232 time += osc->delay;
232 if ( osc->length_counter == 0 || this->linear_counter == 0 || timer_period < 3 ) 233 if ( osc->length_counter == 0 || this->linear_counter == 0 || timer_period < 3 )
@@ -243,13 +244,15 @@ void Triangle_run( struct Nes_Triangle* this, nes_time_t time, nes_time_t end_ti
243 phase -= Triangle_phase_range; 244 phase -= Triangle_phase_range;
244 volume = -volume; 245 volume = -volume;
245 } 246 }
247 Blip_set_modified( osc->output );
246 248
247 do { 249 do {
248 if ( --phase == 0 ) { 250 if ( --phase == 0 ) {
249 phase = Triangle_phase_range; 251 phase = Triangle_phase_range;
250 volume = -volume; 252 volume = -volume;
251 } 253 }
252 else { 254 else
255 {
253 Synth_offset_inline( &this->synth, time, volume, output ); 256 Synth_offset_inline( &this->synth, time, volume, output );
254 } 257 }
255 258
@@ -340,18 +343,27 @@ static inline void Dmc_reload_sample( struct Nes_Dmc* this )
340 this->osc.length_counter = this->osc.regs [3] * 0x10 + 1; 343 this->osc.length_counter = this->osc.regs [3] * 0x10 + 1;
341} 344}
342 345
343static byte const dac_table [128] = 346static int const dmc_table [128] =
344{ 347{
345 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 9,10,11,12,13,14, 348 0, 24, 48, 71, 94, 118, 141, 163, 186, 209, 231, 253, 275, 297, 319, 340,
346 15,15,16,17,18,19,20,20,21,22,23,24,24,25,26,27, 349 361, 383, 404, 425, 445, 466, 486, 507, 527, 547, 567, 587, 606, 626, 645, 664,
347 27,28,29,30,31,31,32,33,33,34,35,36,36,37,38,38, 350 683, 702, 721, 740, 758, 777, 795, 813, 832, 850, 867, 885, 903, 920, 938, 955,
348 39,40,41,41,42,43,43,44,45,45,46,47,47,48,48,49, 351 972, 989,1006,1023,1040,1056,1073,1089,1105,1122,1138,1154,1170,1185,1201,1217,
349 50,50,51,52,52,53,53,54,55,55,56,56,57,58,58,59, 3521232,1248,1263,1278,1293,1308,1323,1338,1353,1368,1382,1397,1411,1425,1440,1454,
350 59,60,60,61,61,62,63,63,64,64,65,65,66,66,67,67, 3531468,1482,1496,1510,1523,1537,1551,1564,1578,1591,1604,1618,1631,1644,1657,1670,
351 68,68,69,70,70,71,71,72,72,73,73,74,74,75,75,75, 3541683,1695,1708,1721,1733,1746,1758,1771,1783,1795,1807,1819,1831,1843,1855,1867,
352 76,76,77,77,78,78,79,79,80,80,81,81,82,82,82,83, 3551879,1890,1902,1914,1925,1937,1948,1959,1971,1982,1993,2004,2015,2026,2037,2048,
353}; 356};
354 357
358static inline int update_amp_nonlinear( struct Nes_Dmc* this, int in )
359{
360 if ( !this->nonlinear )
361 in = dmc_table [in];
362 int delta = in - this->osc.last_amp;
363 this->osc.last_amp = in;
364 return delta;
365}
366
355void Dmc_write_register( struct Nes_Dmc* this, int addr, int data ) 367void Dmc_write_register( struct Nes_Dmc* this, int addr, int data )
356{ 368{
357 if ( addr == 0 ) 369 if ( addr == 0 )
@@ -363,14 +375,7 @@ void Dmc_write_register( struct Nes_Dmc* this, int addr, int data )
363 } 375 }
364 else if ( addr == 1 ) 376 else if ( addr == 1 )
365 { 377 {
366 int old_dac = this->dac;
367 this->dac = data & 0x7F; 378 this->dac = data & 0x7F;
368
369 // adjust last_amp so that "pop" amplitude will be properly non-linear
370 // with respect to change in dac
371 int faked_nonlinear = this->dac - (dac_table [this->dac] - dac_table [old_dac]);
372 if ( !this->nonlinear )
373 this->osc.last_amp = faked_nonlinear;
374 } 379 }
375} 380}
376 381
@@ -407,16 +412,15 @@ void Dmc_fill_buffer( struct Nes_Dmc* this )
407void Dmc_run( struct Nes_Dmc* this, nes_time_t time, nes_time_t end_time ) 412void Dmc_run( struct Nes_Dmc* this, nes_time_t time, nes_time_t end_time )
408{ 413{
409 struct Nes_Osc* osc = &this->osc; 414 struct Nes_Osc* osc = &this->osc;
410 int delta = Osc_update_amp( osc, this->dac ); 415 int delta = update_amp_nonlinear( this, this->dac );
411 if ( !osc->output ) 416 if ( !osc->output )
412 { 417 {
413 this->silence = true; 418 this->silence = true;
414 } 419 }
415 else 420 else if ( delta )
416 { 421 {
417 Blip_set_modified( osc->output ); 422 Blip_set_modified( osc->output );
418 if ( delta ) 423 Synth_offset( &this->synth, time, delta, osc->output );
419 Synth_offset( &this->synth, time, delta, osc->output );
420 } 424 }
421 425
422 time += osc->delay; 426 time += osc->delay;
@@ -435,6 +439,8 @@ void Dmc_run( struct Nes_Dmc* this, nes_time_t time, nes_time_t end_time )
435 const int period = this->period; 439 const int period = this->period;
436 int bits = this->bits; 440 int bits = this->bits;
437 int dac = this->dac; 441 int dac = this->dac;
442 if ( output )
443 Blip_set_modified( output );
438 444
439 do 445 do
440 { 446 {
@@ -444,7 +450,7 @@ void Dmc_run( struct Nes_Dmc* this, nes_time_t time, nes_time_t end_time )
444 bits >>= 1; 450 bits >>= 1;
445 if ( (unsigned) (dac + step) <= 0x7F ) { 451 if ( (unsigned) (dac + step) <= 0x7F ) {
446 dac += step; 452 dac += step;
447 Synth_offset_inline( &this->synth, time, step, output ); 453 Synth_offset_inline( &this->synth, time, update_amp_nonlinear( this, dac ), output );
448 } 454 }
449 } 455 }
450 456
@@ -456,7 +462,8 @@ void Dmc_run( struct Nes_Dmc* this, nes_time_t time, nes_time_t end_time )
456 if ( !this->buf_full ) { 462 if ( !this->buf_full ) {
457 this->silence = true; 463 this->silence = true;
458 } 464 }
459 else { 465 else
466 {
460 this->silence = false; 467 this->silence = false;
461 bits = this->buf; 468 bits = this->buf;
462 this->buf_full = false; 469 this->buf_full = false;
@@ -469,7 +476,7 @@ void Dmc_run( struct Nes_Dmc* this, nes_time_t time, nes_time_t end_time )
469 while ( time < end_time ); 476 while ( time < end_time );
470 477
471 this->dac = dac; 478 this->dac = dac;
472 osc->last_amp = dac; 479 //osc->last_amp = dac;
473 this->bits = bits; 480 this->bits = bits;
474 } 481 }
475 this->bits_remain = bits_remain; 482 this->bits_remain = bits_remain;
@@ -519,14 +526,15 @@ void Noise_run( struct Nes_Noise* this, nes_time_t time, nes_time_t end_time )
519 return; 526 return;
520 } 527 }
521 528
522 Blip_set_modified( osc->output );
523
524 const int volume = Noise_volume( this ); 529 const int volume = Noise_volume( this );
525 int amp = (this->noise & 1) ? volume : 0; 530 int amp = (this->noise & 1) ? volume : 0;
526 { 531 {
527 int delta = Osc_update_amp( osc, amp ); 532 int delta = Osc_update_amp( osc, amp );
528 if ( delta ) 533 if ( delta )
534 {
535 Blip_set_modified( osc->output );
529 Synth_offset( &this->synth, time, delta, osc->output ); 536 Synth_offset( &this->synth, time, delta, osc->output );
537 }
530 } 538 }
531 539
532 time += osc->delay; 540 time += osc->delay;
@@ -557,6 +565,7 @@ void Noise_run( struct Nes_Noise* this, nes_time_t time, nes_time_t end_time )
557 int noise = this->noise; 565 int noise = this->noise;
558 int delta = amp * 2 - volume; 566 int delta = amp * 2 - volume;
559 const int tap = (osc->regs [2] & mode_flag ? 8 : 13); 567 const int tap = (osc->regs [2] & mode_flag ? 8 : 13);
568 Blip_set_modified( osc->output );
560 569
561 do { 570 do {
562 int feedback = (noise << tap) ^ (noise << 14); 571 int feedback = (noise << tap) ^ (noise << 14);