summaryrefslogtreecommitdiff
path: root/lib/rbcodec/codecs/libgme/gb_oscs.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rbcodec/codecs/libgme/gb_oscs.c')
-rw-r--r--lib/rbcodec/codecs/libgme/gb_oscs.c787
1 files changed, 787 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libgme/gb_oscs.c b/lib/rbcodec/codecs/libgme/gb_oscs.c
new file mode 100644
index 0000000000..09bb98238e
--- /dev/null
+++ b/lib/rbcodec/codecs/libgme/gb_oscs.c
@@ -0,0 +1,787 @@
1// Gb_Snd_Emu 0.1.4. http://www.slack.net/~ant/
2
3#include "gb_apu.h"
4
5/* Copyright (C) 2003-2008 Shay Green. This module is free software; you
6can redistribute it and/or modify it under the terms of the GNU Lesser
7General Public License as published by the Free Software Foundation; either
8version 2.1 of the License, or (at your option) any later version. This
9module is distributed in the hope that it will be useful, but WITHOUT ANY
10WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12details. You should have received a copy of the GNU Lesser General Public
13License along with this module; if not, write to the Free Software Foundation,
14Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
15
16#include "blargg_source.h"
17
18int const cgb_02 = 0; // enables bug in early CGB units that causes problems in some games
19int const cgb_05 = 0; // enables CGB-05 zombie behavior
20
21int const trigger_mask = 0x80;
22int const length_enabled = 0x40;
23
24void Osc_reset( struct Gb_Osc* this )
25{
26 this->output = NULL;
27 this->last_amp = 0;
28 this->delay = 0;
29 this->phase = 0;
30 this->enabled = false;
31}
32
33static inline void Osc_update_amp( struct Gb_Osc* this, blip_time_t time, int new_amp )
34{
35 Blip_set_modified( this->output );
36 int delta = new_amp - this->last_amp;
37 if ( delta )
38 {
39 this->last_amp = new_amp;
40 Synth_offset( this->synth, time, delta, this->output );
41 }
42}
43
44// Units
45
46void Osc_clock_length( struct Gb_Osc* this )
47{
48 if ( (this->regs [4] & length_enabled) && this->length_ctr )
49 {
50 if ( --this->length_ctr <= 0 )
51 this->enabled = false;
52 }
53}
54
55void Noise_clock_envelope( struct Gb_Noise* this )
56{
57 if ( this->env_enabled && --this->env_delay <= 0 && Noise_reload_env_timer( this ) )
58 {
59 int v = this->volume + (this->osc.regs [2] & 0x08 ? +1 : -1);
60 if ( 0 <= v && v <= 15 )
61 this->volume = v;
62 else
63 this->env_enabled = false;
64 }
65}
66
67void Square_clock_envelope( struct Gb_Square* this )
68{
69 if ( this->env_enabled && --this->env_delay <= 0 && Square_reload_env_timer( this ) )
70 {
71 int v = this->volume + (this->osc.regs [2] & 0x08 ? +1 : -1);
72 if ( 0 <= v && v <= 15 )
73 this->volume = v;
74 else
75 this->env_enabled = false;
76 }
77}
78
79static inline void reload_sweep_timer( struct Gb_Square* this )
80{
81 this->sweep_delay = (this->osc.regs [0] & period_mask) >> 4;
82 if ( !this->sweep_delay )
83 this->sweep_delay = 8;
84}
85
86static void calc_sweep( struct Gb_Square* this, bool update )
87{
88 struct Gb_Osc* osc = &this->osc;
89 int const shift = osc->regs [0] & shift_mask;
90 int const delta = this->sweep_freq >> shift;
91 this->sweep_neg = (osc->regs [0] & 0x08) != 0;
92 int const freq = this->sweep_freq + (this->sweep_neg ? -delta : delta);
93
94 if ( freq > 0x7FF )
95 {
96 osc->enabled = false;
97 }
98 else if ( shift && update )
99 {
100 this->sweep_freq = freq;
101
102 osc->regs [3] = freq & 0xFF;
103 osc->regs [4] = (osc->regs [4] & ~0x07) | (freq >> 8 & 0x07);
104 }
105}
106
107void clock_sweep( struct Gb_Square* this )
108{
109 if ( --this->sweep_delay <= 0 )
110 {
111 reload_sweep_timer( this );
112 if ( this->sweep_enabled && (this->osc.regs [0] & period_mask) )
113 {
114 calc_sweep( this, true );
115 calc_sweep( this, false );
116 }
117 }
118}
119
120int wave_access( struct Gb_Wave* this, int addr )
121{
122 if ( this->osc.enabled )
123 {
124 addr = this->osc.phase & (wave_bank_size - 1);
125 if ( this->osc.mode == mode_dmg )
126 {
127 addr++;
128 if ( this->osc.delay > clk_mul )
129 return -1; // can only access within narrow time window while playing
130 }
131 addr >>= 1;
132 }
133 return addr & 0x0F;
134}
135
136// write_register
137
138static int write_trig( struct Gb_Osc* this, int frame_phase, int max_len, int old_data )
139{
140 int data = this->regs [4];
141
142 if ( (frame_phase & 1) && !(old_data & length_enabled) && this->length_ctr )
143 {
144 if ( (data & length_enabled) || cgb_02 )
145 this->length_ctr--;
146 }
147
148 if ( data & trigger_mask )
149 {
150 this->enabled = true;
151 if ( !this->length_ctr )
152 {
153 this->length_ctr = max_len;
154 if ( (frame_phase & 1) && (data & length_enabled) )
155 this->length_ctr--;
156 }
157 }
158
159 if ( !this->length_ctr )
160 this->enabled = false;
161
162 return data & trigger_mask;
163}
164
165static inline void Noise_zombie_volume( struct Gb_Noise* this, int old, int data )
166{
167 int v = this->volume;
168 if ( this->osc.mode == mode_agb || cgb_05 )
169 {
170 // CGB-05 behavior, very close to AGB behavior as well
171 if ( (old ^ data) & 8 )
172 {
173 if ( !(old & 8) )
174 {
175 v++;
176 if ( old & 7 )
177 v++;
178 }
179
180 v = 16 - v;
181 }
182 else if ( (old & 0x0F) == 8 )
183 {
184 v++;
185 }
186 }
187 else
188 {
189 // CGB-04&02 behavior, very close to MGB behavior as well
190 if ( !(old & 7) && this->env_enabled )
191 v++;
192 else if ( !(old & 8) )
193 v += 2;
194
195 if ( (old ^ data) & 8 )
196 v = 16 - v;
197 }
198 this->volume = v & 0x0F;
199}
200
201static inline void Square_zombie_volume( struct Gb_Square* this, int old, int data )
202{
203 int v = this->volume;
204 if ( this->osc.mode == mode_agb || cgb_05 )
205 {
206 // CGB-05 behavior, very close to AGB behavior as well
207 if ( (old ^ data) & 8 )
208 {
209 if ( !(old & 8) )
210 {
211 v++;
212 if ( old & 7 )
213 v++;
214 }
215
216 v = 16 - v;
217 }
218 else if ( (old & 0x0F) == 8 )
219 {
220 v++;
221 }
222 }
223 else
224 {
225 // CGB-04&02 behavior, very close to MGB behavior as well
226 if ( !(old & 7) && this->env_enabled )
227 v++;
228 else if ( !(old & 8) )
229 v += 2;
230
231 if ( (old ^ data) & 8 )
232 v = 16 - v;
233 }
234 this->volume = v & 0x0F;
235}
236
237static bool Square_write_register( struct Gb_Square* this, int frame_phase, int reg, int old_data, int data )
238{
239 int const max_len = 64;
240
241 switch ( reg )
242 {
243 case 1:
244 this->osc.length_ctr = max_len - (data & (max_len - 1));
245 break;
246
247 case 2:
248 if ( !Square_dac_enabled( this ) )
249 this->osc.enabled = false;
250
251 Square_zombie_volume( this, old_data, data );
252
253 if ( (data & 7) && this->env_delay == 8 )
254 {
255 this->env_delay = 1;
256 Square_clock_envelope( this ); // TODO: really happens at next length clock
257 }
258 break;
259
260 case 4:
261 if ( write_trig( &this->osc, frame_phase, max_len, old_data ) )
262 {
263 this->volume = this->osc.regs [2] >> 4;
264 Square_reload_env_timer( this );
265 this->env_enabled = true;
266 if ( frame_phase == 7 )
267 this->env_delay++;
268 if ( !Square_dac_enabled( this ) )
269 this->osc.enabled = false;
270 this->osc.delay = (this->osc.delay & (4 * clk_mul - 1)) + Square_period( this );
271 return true;
272 }
273 }
274
275 return false;
276}
277
278static inline void Noise_write_register( struct Gb_Noise* this, int frame_phase, int reg, int old_data, int data )
279{
280 int const max_len = 64;
281
282 switch ( reg )
283 {
284 case 1:
285 this->osc.length_ctr = max_len - (data & (max_len - 1));
286 break;
287
288 case 2:
289 if ( !Noise_dac_enabled( this ) )
290 this->osc.enabled = false;
291
292 Noise_zombie_volume( this, old_data, data );
293
294 if ( (data & 7) && this->env_delay == 8 )
295 {
296 this->env_delay = 1;
297 Noise_clock_envelope( this ); // TODO: really happens at next length clock
298 }
299 break;
300
301 case 4:
302 if ( write_trig( &this->osc, frame_phase, max_len, old_data ) )
303 {
304 this->volume = this->osc.regs [2] >> 4;
305 Noise_reload_env_timer( this );
306 this->env_enabled = true;
307 if ( frame_phase == 7 )
308 this->env_delay++;
309 if ( !Noise_dac_enabled( this ) )
310 this->osc.enabled = false;
311
312 this->osc.phase = 0x7FFF;
313 this->osc.delay += 8 * clk_mul;
314 }
315 }
316}
317
318static inline void Sweep_write_register( struct Gb_Square* this, int frame_phase, int reg, int old_data, int data )
319{
320 if ( reg == 0 && this->sweep_enabled && this->sweep_neg && !(data & 0x08) )
321 this->osc.enabled = false; // sweep negate disabled after used
322
323 if ( Square_write_register( this, frame_phase, reg, old_data, data ) )
324 {
325 this->sweep_freq = Osc_frequency( &this->osc );
326 this->sweep_neg = false;
327 reload_sweep_timer( this );
328 this->sweep_enabled = (this->osc.regs [0] & (period_mask | shift_mask)) != 0;
329 if ( this->osc.regs [0] & shift_mask )
330 calc_sweep( this, false );
331 }
332}
333
334static void corrupt_wave( struct Gb_Wave* this )
335{
336 int pos = ((this->osc.phase + 1) & (wave_bank_size - 1)) >> 1;
337 if ( pos < 4 )
338 this->wave_ram [0] = this->wave_ram [pos];
339 else {
340 int i;
341 for ( i = 4; --i >= 0; )
342 this->wave_ram [i] = this->wave_ram [(pos & ~3) + i];
343 }
344}
345
346static inline void Wave_write_register( struct Gb_Wave* this, int frame_phase, int reg, int old_data, int data )
347{
348 int const max_len = 256;
349
350 switch ( reg )
351 {
352 case 0:
353 if ( !Wave_dac_enabled( this ) )
354 this->osc.enabled = false;
355 break;
356
357 case 1:
358 this->osc.length_ctr = max_len - data;
359 break;
360
361 case 4:
362 {
363 bool was_enabled = this->osc.enabled;
364 if ( write_trig( &this->osc, frame_phase, max_len, old_data ) )
365 {
366 if ( !Wave_dac_enabled( this ) )
367 this->osc.enabled = false;
368 else if ( this->osc.mode == mode_dmg && was_enabled &&
369 (unsigned) (this->osc.delay - 2 * clk_mul) < 2 * clk_mul )
370 corrupt_wave( this );
371
372 this->osc.phase = 0;
373 this->osc.delay = Wave_period( this ) + 6 * clk_mul;
374 }
375 }
376 }
377}
378
379void write_osc( struct Gb_Apu* this, int reg, int old_data, int data )
380{
381 int index = (reg * 3 + 3) >> 4; // avoids divide
382 assert( index == reg / 5 );
383 reg -= index * 5;
384 switch ( index )
385 {
386 case 0: Sweep_write_register ( &this->square1, this->frame_phase, reg, old_data, data ); break;
387 case 1: Square_write_register( &this->square2, this->frame_phase, reg, old_data, data ); break;
388 case 2: Wave_write_register ( &this->wave, this->frame_phase, reg, old_data, data ); break;
389 case 3: Noise_write_register ( &this->noise, this->frame_phase, reg, old_data, data ); break;
390 }
391}
392
393// Synthesis
394
395void Square_run( struct Gb_Square* this, blip_time_t time, blip_time_t end_time )
396{
397 // Calc duty and phase
398 static byte const duty_offsets [4] = { 1, 1, 3, 7 };
399 static byte const duties [4] = { 1, 2, 4, 6 };
400
401 struct Gb_Osc* osc = &this->osc;
402 int const duty_code = osc->regs [1] >> 6;
403 int duty_offset = duty_offsets [duty_code];
404 int duty = duties [duty_code];
405 if ( osc->mode == mode_agb )
406 {
407 // AGB uses inverted duty
408 duty_offset -= duty;
409 duty = 8 - duty;
410 }
411 int ph = (osc->phase + duty_offset) & 7;
412
413 // Determine what will be generated
414 int vol = 0;
415 struct Blip_Buffer* const out = osc->output;
416 if ( out )
417 {
418 int amp = osc->dac_off_amp;
419 if ( Square_dac_enabled( this ) )
420 {
421 if ( osc->enabled )
422 vol = this->volume;
423
424 amp = -dac_bias;
425 if ( osc->mode == mode_agb )
426 amp = -(vol >> 1);
427
428 // Play inaudible frequencies as constant amplitude
429 if ( Osc_frequency( osc ) >= 0x7FA && osc->delay < 32 * clk_mul )
430 {
431 amp += (vol * duty) >> 3;
432 vol = 0;
433 }
434
435 if ( ph < duty )
436 {
437 amp += vol;
438 vol = -vol;
439 }
440 }
441 Osc_update_amp( osc, time, amp );
442 }
443
444 // Generate wave
445 time += osc->delay;
446 if ( time < end_time )
447 {
448 int const per = Square_period( this );
449 if ( !vol )
450 {
451 #ifdef GB_APU_FAST
452 time = end_time;
453 #else
454 // Maintain phase when not playing
455 int count = (end_time - time + per - 1) / per;
456 ph += count; // will be masked below
457 time += (blip_time_t) count * per;
458 #endif
459 }
460 else
461 {
462 // Output amplitude transitions
463 int delta = vol;
464 do
465 {
466 ph = (ph + 1) & 7;
467 if ( ph == 0 || ph == duty )
468 {
469 Synth_offset_inline( osc->synth, time, delta, out );
470 delta = -delta;
471 }
472 time += per;
473 }
474 while ( time < end_time );
475
476 if ( delta != vol )
477 osc->last_amp -= delta;
478 }
479 osc->phase = (ph - duty_offset) & 7;
480 }
481 osc->delay = time - end_time;
482}
483
484#ifndef GB_APU_FAST
485// Quickly runs LFSR for a large number of clocks. For use when noise is generating
486// no sound.
487static unsigned run_lfsr( unsigned s, unsigned mask, int count )
488{
489 bool const optimized = true; // set to false to use only unoptimized loop in middle
490
491 // optimization used in several places:
492 // ((s & (1 << b)) << n) ^ ((s & (1 << b)) << (n + 1)) = (s & (1 << b)) * (3 << n)
493
494 if ( mask == 0x4000 && optimized )
495 {
496 if ( count >= 32767 )
497 count %= 32767;
498
499 // Convert from Fibonacci to Galois configuration,
500 // shifted left 1 bit
501 s ^= (s & 1) * 0x8000;
502
503 // Each iteration is equivalent to clocking LFSR 255 times
504 while ( (count -= 255) > 0 )
505 s ^= ((s & 0xE) << 12) ^ ((s & 0xE) << 11) ^ (s >> 3);
506 count += 255;
507
508 // Each iteration is equivalent to clocking LFSR 15 times
509 // (interesting similarity to single clocking below)
510 while ( (count -= 15) > 0 )
511 s ^= ((s & 2) * (3 << 13)) ^ (s >> 1);
512 count += 15;
513
514 // Remaining singles
515 while ( --count >= 0 )
516 s = ((s & 2) * (3 << 13)) ^ (s >> 1);
517
518 // Convert back to Fibonacci configuration
519 s &= 0x7FFF;
520 }
521 else if ( count < 8 || !optimized )
522 {
523 // won't fully replace upper 8 bits, so have to do the unoptimized way
524 while ( --count >= 0 )
525 s = (s >> 1 | mask) ^ (mask & -((s - 1) & 2));
526 }
527 else
528 {
529 if ( count > 127 )
530 {
531 count %= 127;
532 if ( !count )
533 count = 127; // must run at least once
534 }
535
536 // Need to keep one extra bit of history
537 s = s << 1 & 0xFF;
538
539 // Convert from Fibonacci to Galois configuration,
540 // shifted left 2 bits
541 s ^= (s & 2) * 0x80;
542
543 // Each iteration is equivalent to clocking LFSR 7 times
544 // (interesting similarity to single clocking below)
545 while ( (count -= 7) > 0 )
546 s ^= ((s & 4) * (3 << 5)) ^ (s >> 1);
547 count += 7;
548
549 // Remaining singles
550 while ( --count >= 0 )
551 s = ((s & 4) * (3 << 5)) ^ (s >> 1);
552
553 // Convert back to Fibonacci configuration and
554 // repeat last 8 bits above significant 7
555 s = (s << 7 & 0x7F80) | (s >> 1 & 0x7F);
556 }
557
558 return s;
559}
560#endif
561
562void Noise_run( struct Gb_Noise* this, blip_time_t time, blip_time_t end_time )
563{
564 // Determine what will be generated
565 int vol = 0;
566 struct Gb_Osc* osc = &this->osc;
567 struct Blip_Buffer* const out = osc->output;
568 if ( out )
569 {
570 int amp = osc->dac_off_amp;
571 if ( Noise_dac_enabled( this ) )
572 {
573 if ( osc->enabled )
574 vol = this->volume;
575
576 amp = -dac_bias;
577 if ( osc->mode == mode_agb )
578 amp = -(vol >> 1);
579
580 if ( !(osc->phase & 1) )
581 {
582 amp += vol;
583 vol = -vol;
584 }
585 }
586
587 // AGB negates final output
588 if ( osc->mode == mode_agb )
589 {
590 vol = -vol;
591 amp = -amp;
592 }
593
594 Osc_update_amp( osc, time, amp );
595 }
596
597 // Run timer and calculate time of next LFSR clock
598 static byte const period1s [8] = { 1, 2, 4, 6, 8, 10, 12, 14 };
599 int const period1 = period1s [osc->regs [3] & 7] * clk_mul;
600
601 #ifdef GB_APU_FAST
602 time += delay;
603 #else
604 {
605 int extra = (end_time - time) - osc->delay;
606 int const per2 = period2( this, 8 );
607 time += osc->delay + ((this->divider ^ (per2 >> 1)) & (per2 - 1)) * period1;
608
609 int count = (extra < 0 ? 0 : (extra + period1 - 1) / period1);
610 this->divider = (this->divider - count) & period2_mask;
611 osc->delay = count * period1 - extra;
612 }
613 #endif
614
615 // Generate wave
616 if ( time < end_time )
617 {
618 unsigned const mask = lfsr_mask( this );
619 unsigned bits = osc->phase;
620
621 int per = period2( this, period1 * 8 );
622 #ifdef GB_APU_FAST
623 // Noise can be THE biggest time hog; adjust as necessary
624 int const min_period = 24;
625 if ( per < min_period )
626 per = min_period;
627 #endif
628 if ( period2_index( this ) >= 0xE )
629 {
630 time = end_time;
631 }
632 else if ( !vol )
633 {
634 #ifdef GB_APU_FAST
635 time = end_time;
636 #else
637 // Maintain phase when not playing
638 int count = (end_time - time + per - 1) / per;
639 time += (blip_time_t) count * per;
640 bits = run_lfsr( bits, ~mask, count );
641 #endif
642 }
643 else
644 {
645 struct Blip_Synth* synth = osc->synth; // cache
646
647 // Output amplitude transitions
648 int delta = -vol;
649 do
650 {
651 unsigned changed = bits + 1;
652 bits = bits >> 1 & mask;
653 if ( changed & 2 )
654 {
655 bits |= ~mask;
656 delta = -delta;
657 Synth_offset_inline( synth, time, delta, out );
658 }
659 time += per;
660 }
661 while ( time < end_time );
662
663 if ( delta == vol )
664 osc->last_amp += delta;
665 }
666 osc->phase = bits;
667 }
668
669 #ifdef GB_APU_FAST
670 osc->delay = time - end_time;
671 #endif
672}
673
674void Wave_run( struct Gb_Wave* this, blip_time_t time, blip_time_t end_time )
675{
676 // Calc volume
677#ifdef GB_APU_NO_AGB
678 static byte const shifts [4] = { 4+4, 0+4, 1+4, 2+4 };
679 int const volume_idx = this->regs [2] >> 5 & 3;
680 int const volume_shift = shifts [volume_idx];
681 int const volume_mul = 1;
682#else
683 static byte const volumes [8] = { 0, 4, 2, 1, 3, 3, 3, 3 };
684 int const volume_shift = 2 + 4;
685 int const volume_idx = this->osc.regs [2] >> 5 & (this->agb_mask | 3); // 2 bits on DMG/CGB, 3 on AGB
686 int const volume_mul = volumes [volume_idx];
687#endif
688
689 // Determine what will be generated
690 int playing = false;
691 struct Gb_Osc* osc = &this->osc;
692 struct Blip_Buffer* out = osc->output;
693 if ( out )
694 {
695 int amp = osc->dac_off_amp;
696 if ( Wave_dac_enabled( this ) )
697 {
698 // Play inaudible frequencies as constant amplitude
699 amp = 8 << 4; // really depends on average of all samples in wave
700
701 // if delay is larger, constant amplitude won't start yet
702 if ( Osc_frequency( osc ) <= 0x7FB || osc->delay > 15 * clk_mul )
703 {
704 if ( volume_mul && volume_shift != 4+4 )
705 playing = (int) osc->enabled;
706
707 amp = (this->sample_buf << (osc->phase << 2 & 4) & 0xF0) * playing;
708 }
709
710 amp = ((amp * volume_mul) >> volume_shift) - dac_bias;
711 }
712 Osc_update_amp( osc, time, amp );
713 }
714
715 // Generate wave
716 time += osc->delay;
717 if ( time < end_time )
718 {
719 byte const* wave = this->wave_ram;
720
721 // wave size and bank
722 #ifdef GB_APU_NO_AGB
723 int const wave_mask = 0x1F;
724 int const swap_banks = 0;
725 #else
726 int const size20_mask = 0x20;
727 int const flags = osc->regs [0] & this->agb_mask;
728 int const wave_mask = (flags & size20_mask) | 0x1F;
729 int swap_banks = 0;
730 if ( flags & bank40_mask )
731 {
732 swap_banks = flags & size20_mask;
733 wave += wave_bank_size/2 - (swap_banks >> 1);
734 }
735 #endif
736
737 int ph = osc->phase ^ swap_banks;
738 ph = (ph + 1) & wave_mask; // pre-advance
739
740 int const per = Wave_period( this );
741 if ( !playing )
742 {
743 #ifdef GB_APU_FAST
744 time = end_time;
745 #else
746 // Maintain phase when not playing
747 int count = (end_time - time + per - 1) / per;
748 ph += count; // will be masked below
749 time += (blip_time_t) count * per;
750 #endif
751 }
752 else
753 {
754 struct Blip_Synth* synth = osc->synth; // cache
755
756 // Output amplitude transitions
757 int lamp = osc->last_amp + dac_bias;
758 do
759 {
760 // Extract nibble
761 int nibble = wave [ph >> 1] << (ph << 2 & 4) & 0xF0;
762 ph = (ph + 1) & wave_mask;
763
764 // Scale by volume
765 int amp = (nibble * volume_mul) >> volume_shift;
766
767 int delta = amp - lamp;
768 if ( delta )
769 {
770 lamp = amp;
771 Synth_offset_inline( synth, time, delta, out );
772 }
773 time += per;
774 }
775 while ( time < end_time );
776 osc->last_amp = lamp - dac_bias;
777 }
778 ph = (ph - 1) & wave_mask; // undo pre-advance and mask position
779
780 // Keep track of last byte read
781 if ( osc->enabled )
782 this->sample_buf = wave [ph >> 1];
783
784 osc->phase = ph ^ swap_banks; // undo swapped banks
785 }
786 osc->delay = time - end_time;
787}