view src/gb/gbSound.cpp @ 378:5c4a30521d09

created efficient frame-metronome program
author Robert McIntyre <rlm@mit.edu>
date Wed, 11 Apr 2012 11:43:51 -0500
parents f9f4f1b99eed
children 7ef5c73ea8fa
line wrap: on
line source
1 #ifdef WIN32
2 # include "../win32/stdafx.h"
3 # include "../win32/VBA.h"
4 #endif
6 #include <cstring>
7 #include <cassert>
9 #include "../common/System.h"
10 #include "../common/Util.h"
11 //#include "../Blip_Buffer.h"
12 #include "gbGlobals.h"
13 #include "gbSound.h"
15 #ifndef countof
16 #define countof(a) (sizeof(a) / sizeof(a[0]))
17 #endif
19 extern u8 soundBuffer[6][735];
20 extern u16 soundFinalWave[1470];
21 extern u16 soundFrameSound[735 * 30 * 2];
22 extern int32 soundVolume;
24 soundtick_t GB_USE_TICKS_AS = 24; // (1048576.0/44100.0); // FIXME: (4194304.0/70224.0)(fps) vs 60.0fps?
26 #define SOUND_MAGIC 0x60000000
27 #define SOUND_MAGIC_2 0x30000000
28 #define NOISE_MAGIC (2097152.0 / 44100.0)
30 extern int32 speed;
32 extern u8 soundWavePattern[4][32];
34 extern u32 soundBufferLen;
35 extern u32 soundBufferTotalLen;
36 extern int32 soundQuality;
37 extern int32 soundPaused;
38 extern int32 soundPlay;
39 extern soundtick_t soundTicks;
40 extern soundtick_t SOUND_CLOCK_TICKS;
41 extern u32 soundNextPosition;
43 extern int32 soundLevel1;
44 extern int32 soundLevel2;
45 extern int32 soundBalance;
46 extern int32 soundMasterOn;
47 extern u32 soundIndex;
48 extern u32 soundBufferIndex;
49 extern int32 soundFrameSoundWritten;
50 int32 soundVIN = 0;
51 extern int32 soundDebug;
53 extern int32 sound1On;
54 extern int32 sound1ATL;
55 extern int32 sound1Skip;
56 extern int32 sound1Index;
57 extern int32 sound1Continue;
58 extern int32 sound1EnvelopeVolume;
59 extern int32 sound1EnvelopeATL;
60 extern int32 sound1EnvelopeUpDown;
61 extern int32 sound1EnvelopeATLReload;
62 extern int32 sound1SweepATL;
63 extern int32 sound1SweepATLReload;
64 extern int32 sound1SweepSteps;
65 extern int32 sound1SweepUpDown;
66 extern int32 sound1SweepStep;
67 extern u8 * sound1Wave;
69 extern int32 sound2On;
70 extern int32 sound2ATL;
71 extern int32 sound2Skip;
72 extern int32 sound2Index;
73 extern int32 sound2Continue;
74 extern int32 sound2EnvelopeVolume;
75 extern int32 sound2EnvelopeATL;
76 extern int32 sound2EnvelopeUpDown;
77 extern int32 sound2EnvelopeATLReload;
78 extern u8 * sound2Wave;
80 extern int32 sound3On;
81 extern int32 sound3ATL;
82 extern int32 sound3Skip;
83 extern int32 sound3Index;
84 extern int32 sound3Continue;
85 extern int32 sound3OutputLevel;
86 extern int32 sound3Last;
88 extern int32 sound4On;
89 extern int32 sound4Clock;
90 extern int32 sound4ATL;
91 extern int32 sound4Skip;
92 extern int32 sound4Index;
93 extern int32 sound4ShiftRight;
94 extern int32 sound4ShiftSkip;
95 extern int32 sound4ShiftIndex;
96 extern int32 sound4NSteps;
97 extern int32 sound4CountDown;
98 extern int32 sound4Continue;
99 extern int32 sound4EnvelopeVolume;
100 extern int32 sound4EnvelopeATL;
101 extern int32 sound4EnvelopeUpDown;
102 extern int32 sound4EnvelopeATLReload;
104 extern int32 soundEnableFlag;
105 extern int32 soundMutedFlag;
107 extern int32 soundFreqRatio[8];
108 extern int32 soundShiftClock[16];
110 extern s16 soundFilter[4000];
111 extern s16 soundLeft[5];
112 extern s16 soundRight[5];
113 extern int32 soundEchoIndex;
114 extern bool8 soundEcho;
115 extern bool8 soundLowPass;
116 extern bool8 soundReverse;
117 extern bool8 soundOffFlag;
119 bool8 gbDigitalSound = false;
121 void gbSoundEvent(register u16 address, register int data)
122 {
123 int freq = 0;
125 gbMemory[address] = data;
127 #ifndef FINAL_VERSION
128 if (soundDebug)
129 {
130 // don't translate. debug only
131 log("Sound event: %08lx %02x\n", address, data);
132 }
133 #endif
134 switch (address)
135 {
136 case NR10:
137 sound1SweepATL = sound1SweepATLReload = 344 * ((data >> 4) & 7);
138 sound1SweepSteps = data & 7;
139 sound1SweepUpDown = data & 0x08;
140 sound1SweepStep = 0;
141 break;
142 case NR11:
143 sound1Wave = soundWavePattern[data >> 6];
144 sound1ATL = 172 * (64 - (data & 0x3f));
145 break;
146 case NR12:
147 sound1EnvelopeVolume = data >> 4;
148 sound1EnvelopeUpDown = data & 0x08;
149 sound1EnvelopeATLReload = sound1EnvelopeATL = 689 * (data & 7);
150 break;
151 case NR13:
152 freq = (((int)(gbMemory[NR14] & 7)) << 8) | data;
153 sound1ATL = 172 * (64 - (gbMemory[NR11] & 0x3f));
154 freq = 2048 - freq;
155 if (freq)
156 {
157 sound1Skip = SOUND_MAGIC / freq;
158 }
159 else
160 sound1Skip = 0;
161 break;
162 case NR14:
163 freq = (((int)(data & 7) << 8) | gbMemory[NR13]);
164 freq = 2048 - freq;
165 sound1ATL = 172 * (64 - (gbMemory[NR11] & 0x3f));
166 sound1Continue = data & 0x40;
167 if (freq)
168 {
169 sound1Skip = SOUND_MAGIC / freq;
170 }
171 else
172 sound1Skip = 0;
173 if (data & 0x80)
174 {
175 gbMemory[NR52] |= 1;
176 sound1EnvelopeVolume = gbMemory[NR12] >> 4;
177 sound1EnvelopeUpDown = gbMemory[NR12] & 0x08;
178 sound1ATL = 172 * (64 - (gbMemory[NR11] & 0x3f));
179 sound1EnvelopeATLReload = sound1EnvelopeATL = 689 * (gbMemory[NR12] & 7);
180 sound1SweepATL = sound1SweepATLReload = 344 * ((gbMemory[NR10] >> 4) & 7);
181 sound1SweepSteps = gbMemory[NR10] & 7;
182 sound1SweepUpDown = gbMemory[NR10] & 0x08;
183 sound1SweepStep = 0;
185 sound1Index = 0;
186 sound1On = 1;
187 }
188 break;
189 case NR21:
190 sound2Wave = soundWavePattern[data >> 6];
191 sound2ATL = 172 * (64 - (data & 0x3f));
192 break;
193 case NR22:
194 sound2EnvelopeVolume = data >> 4;
195 sound2EnvelopeUpDown = data & 0x08;
196 sound2EnvelopeATLReload = sound2EnvelopeATL = 689 * (data & 7);
197 break;
198 case NR23:
199 freq = (((int)(gbMemory[NR24] & 7)) << 8) | data;
200 sound2ATL = 172 * (64 - (gbMemory[NR21] & 0x3f));
201 freq = 2048 - freq;
202 if (freq)
203 {
204 sound2Skip = SOUND_MAGIC / freq;
205 }
206 else
207 sound2Skip = 0;
208 break;
209 case NR24:
210 freq = (((int)(data & 7) << 8) | gbMemory[NR23]);
211 freq = 2048 - freq;
212 sound2ATL = 172 * (64 - (gbMemory[NR21] & 0x3f));
213 sound2Continue = data & 0x40;
214 if (freq)
215 {
216 sound2Skip = SOUND_MAGIC / freq;
217 }
218 else
219 sound2Skip = 0;
220 if (data & 0x80)
221 {
222 gbMemory[NR52] |= 2;
223 sound2EnvelopeVolume = gbMemory[NR22] >> 4;
224 sound2EnvelopeUpDown = gbMemory[NR22] & 0x08;
225 sound2ATL = 172 * (64 - (gbMemory[NR21] & 0x3f));
226 sound2EnvelopeATLReload = sound2EnvelopeATL = 689 * (gbMemory[NR22] & 7);
228 sound2Index = 0;
229 sound2On = 1;
230 }
231 break;
232 case NR30:
233 if (!(data & 0x80))
234 {
235 gbMemory[NR52] &= 0xfb;
236 sound3On = 0;
237 }
238 break;
239 case NR31:
240 sound3ATL = 172 * (256 - data);
241 break;
242 case NR32:
243 sound3OutputLevel = (data >> 5) & 3;
244 break;
245 case NR33:
246 freq = 2048 - (((int)(gbMemory[NR34] & 7) << 8) | data);
247 if (freq)
248 {
249 sound3Skip = SOUND_MAGIC_2 / freq;
250 }
251 else
252 sound3Skip = 0;
253 break;
254 case NR34:
255 freq = 2048 - (((data & 7) << 8) | (int)gbMemory[NR33]);
256 if (freq)
257 {
258 sound3Skip = SOUND_MAGIC_2 / freq;
259 }
260 else
261 {
262 sound3Skip = 0;
263 }
264 sound3Continue = data & 0x40;
265 if ((data & 0x80) && (gbMemory[NR30] & 0x80))
266 {
267 gbMemory[NR52] |= 4;
268 sound3ATL = 172 * (256 - gbMemory[NR31]);
269 sound3Index = 0;
270 sound3On = 1;
271 }
272 break;
273 case NR41:
274 sound4ATL = 172 * (64 - (data & 0x3f));
275 break;
276 case NR42:
277 sound4EnvelopeVolume = data >> 4;
278 sound4EnvelopeUpDown = data & 0x08;
279 sound4EnvelopeATLReload = sound4EnvelopeATL = 689 * (data & 7);
280 break;
281 case NR43:
282 freq = soundFreqRatio[data & 7];
283 sound4NSteps = data & 0x08;
285 sound4Skip = freq * NOISE_MAGIC;
287 sound4Clock = data >> 4;
289 freq = freq / soundShiftClock[sound4Clock];
291 sound4ShiftSkip = freq * NOISE_MAGIC;
293 break;
294 case NR44:
295 sound4Continue = data & 0x40;
296 if (data & 0x80)
297 {
298 gbMemory[NR52] |= 8;
299 sound4EnvelopeVolume = gbMemory[NR42] >> 4;
300 sound4EnvelopeUpDown = gbMemory[NR42] & 0x08;
301 sound4ATL = 172 * (64 - (gbMemory[NR41] & 0x3f));
302 sound4EnvelopeATLReload = sound4EnvelopeATL = 689 * (gbMemory[NR42] & 7);
304 sound4On = 1;
306 sound4Index = 0;
307 sound4ShiftIndex = 0;
309 freq = soundFreqRatio[gbMemory[NR43] & 7];
311 sound4Skip = freq * NOISE_MAGIC;
313 sound4NSteps = gbMemory[NR43] & 0x08;
315 freq = freq / soundShiftClock[gbMemory[NR43] >> 4];
317 sound4ShiftSkip = freq * NOISE_MAGIC;
318 if (sound4NSteps)
319 sound4ShiftRight = 0x7f;
320 else
321 sound4ShiftRight = 0x7fff;
322 }
323 break;
324 case NR50:
325 soundVIN = data & 0x88;
326 soundLevel1 = data & 7;
327 soundLevel2 = (data >> 4) & 7;
328 break;
329 case NR51:
330 soundBalance = (data & soundEnableFlag);
331 gbMemory[address] = data;
332 break;
333 case NR52:
334 soundMasterOn = data & 0x80;
335 if (!(data & 0x80))
336 {
337 sound1On = 0;
338 sound2On = 0;
339 sound3On = 0;
340 sound4On = 0;
341 }
342 break;
343 }
345 gbDigitalSound = true;
347 if (sound1On && sound1EnvelopeVolume != 0)
348 gbDigitalSound = false;
349 if (sound2On && sound2EnvelopeVolume != 0)
350 gbDigitalSound = false;
351 if (sound3On && sound3OutputLevel != 0)
352 gbDigitalSound = false;
353 if (sound4On && sound4EnvelopeVolume != 0)
354 gbDigitalSound = false;
355 }
357 void gbSoundChannel1()
358 {
359 int vol = sound1EnvelopeVolume;
361 int freq = 0;
363 int value = 0;
365 if (sound1On && (sound1ATL || !sound1Continue))
366 {
367 sound1Index += soundQuality * sound1Skip;
368 sound1Index &= 0x1fffffff;
370 value = ((s8)sound1Wave[sound1Index >> 24]) * vol;
371 }
373 soundBuffer[0][soundIndex] = value;
375 if (sound1On)
376 {
377 if (sound1ATL)
378 {
379 sound1ATL -= soundQuality;
381 if (sound1ATL <= 0 && sound1Continue)
382 {
383 gbMemory[NR52] &= 0xfe;
384 sound1On = 0;
385 }
386 }
388 if (sound1EnvelopeATL)
389 {
390 sound1EnvelopeATL -= soundQuality;
392 if (sound1EnvelopeATL <= 0)
393 {
394 if (sound1EnvelopeUpDown)
395 {
396 if (sound1EnvelopeVolume < 15)
397 sound1EnvelopeVolume++;
398 }
399 else
400 {
401 if (sound1EnvelopeVolume)
402 sound1EnvelopeVolume--;
403 }
405 sound1EnvelopeATL += sound1EnvelopeATLReload;
406 }
407 }
409 if (sound1SweepATL)
410 {
411 sound1SweepATL -= soundQuality;
413 if (sound1SweepATL <= 0)
414 {
415 freq = (((int)(gbMemory[NR14] & 7) << 8) | gbMemory[NR13]);
417 int updown = 1;
419 if (sound1SweepUpDown)
420 updown = -1;
422 int newfreq = 0;
423 if (sound1SweepSteps)
424 {
425 newfreq = freq + updown * freq / (1 << sound1SweepSteps);
426 if (newfreq == freq)
427 newfreq = 0;
428 }
429 else
430 newfreq = freq;
432 if (newfreq < 0)
433 {
434 sound1SweepATL += sound1SweepATLReload;
435 }
436 else if (newfreq > 2047)
437 {
438 sound1SweepATL = 0;
439 sound1On = 0;
440 gbMemory[NR52] &= 0xfe;
441 }
442 else
443 {
444 sound1SweepATL += sound1SweepATLReload;
445 sound1Skip = SOUND_MAGIC / (2048 - newfreq);
447 gbMemory[NR13] = newfreq & 0xff;
448 gbMemory[NR14] = (gbMemory[NR14] & 0xf8) | ((newfreq >> 8) & 7);
449 }
450 }
451 }
452 }
453 }
455 void gbSoundChannel2()
456 {
457 // int freq = 0;
458 int vol = sound2EnvelopeVolume;
460 int value = 0;
462 if (sound2On && (sound2ATL || !sound2Continue))
463 {
464 sound2Index += soundQuality * sound2Skip;
465 sound2Index &= 0x1fffffff;
467 value = ((s8)sound2Wave[sound2Index >> 24]) * vol;
468 }
470 soundBuffer[1][soundIndex] = value;
472 if (sound2On)
473 {
474 if (sound2ATL)
475 {
476 sound2ATL -= soundQuality;
478 if (sound2ATL <= 0 && sound2Continue)
479 {
480 gbMemory[NR52] &= 0xfd;
481 sound2On = 0;
482 }
483 }
485 if (sound2EnvelopeATL)
486 {
487 sound2EnvelopeATL -= soundQuality;
489 if (sound2EnvelopeATL <= 0)
490 {
491 if (sound2EnvelopeUpDown)
492 {
493 if (sound2EnvelopeVolume < 15)
494 sound2EnvelopeVolume++;
495 }
496 else
497 {
498 if (sound2EnvelopeVolume)
499 sound2EnvelopeVolume--;
500 }
501 sound2EnvelopeATL += sound2EnvelopeATLReload;
502 }
503 }
504 }
505 }
507 void gbSoundChannel3()
508 {
509 int value = sound3Last;
511 if (sound3On && (sound3ATL || !sound3Continue))
512 {
513 sound3Index += soundQuality * sound3Skip;
514 sound3Index &= 0x1fffffff;
516 value = gbMemory[0xff30 + (sound3Index >> 25)];
518 if ((sound3Index & 0x01000000))
519 {
520 value &= 0x0f;
521 }
522 else
523 {
524 value >>= 4;
525 }
527 value -= 8;
528 value *= 2;
530 switch (sound3OutputLevel)
531 {
532 case 0:
533 value = 0;
534 break;
535 case 1:
536 break;
537 case 2:
538 value = (value >> 1);
539 break;
540 case 3:
541 value = (value >> 2);
542 break;
543 }
544 //value += 1;
545 sound3Last = value;
546 }
548 soundBuffer[2][soundIndex] = value;
550 if (sound3On)
551 {
552 if (sound3ATL)
553 {
554 sound3ATL -= soundQuality;
556 if (sound3ATL <= 0 && sound3Continue)
557 {
558 gbMemory[NR52] &= 0xfb;
559 sound3On = 0;
560 }
561 }
562 }
563 }
565 void gbSoundChannel4()
566 {
567 int vol = sound4EnvelopeVolume;
569 int value = 0;
571 if (sound4Clock <= 0x0c)
572 {
573 if (sound4On && (sound4ATL || !sound4Continue))
574 {
575 #define NOISE_ONE_SAMP_SCALE 0x200000
577 sound4Index += soundQuality * sound4Skip;
578 sound4ShiftIndex += soundQuality * sound4ShiftSkip;
580 if (sound4NSteps)
581 {
582 while (sound4ShiftIndex >= NOISE_ONE_SAMP_SCALE)
583 {
584 sound4ShiftRight = (((sound4ShiftRight << 6) ^
585 (sound4ShiftRight << 5)) & 0x40) |
586 (sound4ShiftRight >> 1);
587 sound4ShiftIndex -= NOISE_ONE_SAMP_SCALE;
588 }
589 }
590 else
591 {
592 while (sound4ShiftIndex >= NOISE_ONE_SAMP_SCALE)
593 {
594 sound4ShiftRight = (((sound4ShiftRight << 14) ^
595 (sound4ShiftRight << 13)) & 0x4000) |
596 (sound4ShiftRight >> 1);
598 sound4ShiftIndex -= NOISE_ONE_SAMP_SCALE;
599 }
600 }
602 sound4Index %= NOISE_ONE_SAMP_SCALE;
603 sound4ShiftIndex %= NOISE_ONE_SAMP_SCALE;
605 value = ((sound4ShiftRight & 1) * 2 - 1) * vol;
606 }
607 else
608 {
609 value = 0;
610 }
611 }
613 soundBuffer[3][soundIndex] = value;
615 if (sound4On)
616 {
617 if (sound4ATL)
618 {
619 sound4ATL -= soundQuality;
621 if (sound4ATL <= 0 && sound4Continue)
622 {
623 gbMemory[NR52] &= 0xfd;
624 sound4On = 0;
625 }
626 }
628 if (sound4EnvelopeATL)
629 {
630 sound4EnvelopeATL -= soundQuality;
632 if (sound4EnvelopeATL <= 0)
633 {
634 if (sound4EnvelopeUpDown)
635 {
636 if (sound4EnvelopeVolume < 15)
637 sound4EnvelopeVolume++;
638 }
639 else
640 {
641 if (sound4EnvelopeVolume)
642 sound4EnvelopeVolume--;
643 }
644 sound4EnvelopeATL += sound4EnvelopeATLReload;
645 }
646 }
647 }
648 }
650 void gbSoundMix()
651 {
652 int res = 0;
654 if (gbMemory)
655 soundBalance = (gbMemory[NR51] & soundEnableFlag & ~soundMutedFlag);
657 if (soundBalance & 16)
658 {
659 res += ((s8)soundBuffer[0][soundIndex]);
660 }
661 if (soundBalance & 32)
662 {
663 res += ((s8)soundBuffer[1][soundIndex]);
664 }
665 if (soundBalance & 64)
666 {
667 res += ((s8)soundBuffer[2][soundIndex]);
668 }
669 if (soundBalance & 128)
670 {
671 res += ((s8)soundBuffer[3][soundIndex]);
672 }
674 if (gbDigitalSound)
675 res = soundLevel1 * 256;
676 else
677 res *= soundLevel1 * 60;
679 if (soundEcho)
680 {
681 res *= 2;
682 res += soundFilter[soundEchoIndex];
683 res /= 2;
684 soundFilter[soundEchoIndex++] = res;
685 }
687 if (soundLowPass)
688 {
689 soundLeft[4] = soundLeft[3];
690 soundLeft[3] = soundLeft[2];
691 soundLeft[2] = soundLeft[1];
692 soundLeft[1] = soundLeft[0];
693 soundLeft[0] = res;
694 res = (soundLeft[4] + 2 * soundLeft[3] + 8 * soundLeft[2] + 2 * soundLeft[1] +
695 soundLeft[0]) / 14;
696 }
698 bool noSpecialEffects = false;
699 #if (defined(WIN32) && !defined(SDL))
700 if (theApp.soundRecording || theApp.aviRecording || theApp.nvAudioLog)
701 noSpecialEffects = true;
702 #endif
704 if (!noSpecialEffects)
705 {
706 switch (soundVolume)
707 {
708 case 0:
709 case 1:
710 case 2:
711 case 3:
712 res *= (soundVolume + 1);
713 break;
714 case 4:
715 res >>= 2;
716 break;
717 case 5:
718 res >>= 1;
719 break;
720 }
721 }
723 if (res > 32767)
724 res = 32767;
725 if (res < -32768)
726 res = -32768;
728 if (soundReverse && !noSpecialEffects)
729 {
730 soundFinalWave[++soundBufferIndex] = res;
731 if ((soundFrameSoundWritten + 1) >= countof(soundFrameSound))
732 /*assert(false)*/;
733 else
734 soundFrameSound[++soundFrameSoundWritten] = res;
735 }
736 else
737 {
738 soundFinalWave[soundBufferIndex++] = res;
739 if (soundFrameSoundWritten >= countof(soundFrameSound))
740 /*assert(false)*/;
741 else
742 soundFrameSound[soundFrameSoundWritten++] = res;
743 }
745 res = 0;
747 if (soundBalance & 1)
748 {
749 res += ((s8)soundBuffer[0][soundIndex]);
750 }
751 if (soundBalance & 2)
752 {
753 res += ((s8)soundBuffer[1][soundIndex]);
754 }
755 if (soundBalance & 4)
756 {
757 res += ((s8)soundBuffer[2][soundIndex]);
758 }
759 if (soundBalance & 8)
760 {
761 res += ((s8)soundBuffer[3][soundIndex]);
762 }
764 if (gbDigitalSound)
765 res = soundLevel2 * 256;
766 else
767 res *= soundLevel2 * 60;
769 if (soundEcho)
770 {
771 res *= 2;
772 res += soundFilter[soundEchoIndex];
773 res /= 2;
774 soundFilter[soundEchoIndex++] = res;
776 if (soundEchoIndex >= 4000)
777 soundEchoIndex = 0;
778 }
780 if (soundLowPass)
781 {
782 soundRight[4] = soundRight[3];
783 soundRight[3] = soundRight[2];
784 soundRight[2] = soundRight[1];
785 soundRight[1] = soundRight[0];
786 soundRight[0] = res;
787 res = (soundRight[4] + 2 * soundRight[3] + 8 * soundRight[2] + 2 * soundRight[1] +
788 soundRight[0]) / 14;
789 }
791 if (!noSpecialEffects)
792 {
793 switch (soundVolume)
794 {
795 case 0:
796 case 1:
797 case 2:
798 case 3:
799 res *= (soundVolume + 1);
800 break;
801 case 4:
802 res >>= 2;
803 break;
804 case 5:
805 res >>= 1;
806 break;
807 }
808 }
810 if (res > 32767)
811 res = 32767;
812 if (res < -32768)
813 res = -32768;
815 if (soundReverse && !noSpecialEffects)
816 {
817 soundFinalWave[-1 + soundBufferIndex++] = res;
818 if ((soundFrameSoundWritten) >= countof(soundFrameSound))
819 /*assert(false)*/;
820 else
821 soundFrameSound[-1 + soundFrameSoundWritten++] = res;
822 }
823 else
824 {
825 soundFinalWave[soundBufferIndex++] = res;
826 if ((soundFrameSoundWritten + 1) >= countof(soundFrameSound))
827 /*assert(false)*/;
828 else
829 soundFrameSound[soundFrameSoundWritten++] = res;
830 }
831 }
833 void gbSoundTick()
834 {
835 if (systemSoundOn)
836 {
837 if (soundMasterOn)
838 {
839 gbSoundChannel1();
840 gbSoundChannel2();
841 gbSoundChannel3();
842 gbSoundChannel4();
844 gbSoundMix();
845 }
846 else
847 {
848 soundFinalWave[soundBufferIndex++] = 0;
849 soundFinalWave[soundBufferIndex++] = 0;
850 if ((soundFrameSoundWritten + 1) >= countof(soundFrameSound))
851 /*assert(false)*/;
852 else
853 {
854 soundFrameSound[soundFrameSoundWritten++] = 0;
855 soundFrameSound[soundFrameSoundWritten++] = 0;
856 }
857 }
859 soundIndex++;
861 if (2 * soundBufferIndex >= soundBufferLen)
862 {
863 if (systemSoundOn)
864 {
865 if (soundPaused)
866 {
867 extern void soundResume();
868 soundResume();
869 }
871 systemSoundWriteToBuffer();
872 }
873 soundIndex = 0;
874 soundBufferIndex = 0;
875 }
876 }
877 }
879 void gbSoundReset()
880 {
881 soundPaused = 1;
882 soundPlay = 0;
883 SOUND_CLOCK_TICKS = soundQuality * GB_USE_TICKS_AS;
884 // soundTicks = SOUND_CLOCK_TICKS;
885 soundTicks = 0;
886 soundNextPosition = 0;
887 soundMasterOn = 1;
888 soundIndex = 0;
889 soundBufferIndex = 0;
890 soundLevel1 = 7;
891 soundLevel2 = 7;
892 soundVIN = 0;
894 sound1On = 0;
895 sound1ATL = 0;
896 sound1Skip = 0;
897 sound1Index = 0;
898 sound1Continue = 0;
899 sound1EnvelopeVolume = 0;
900 sound1EnvelopeATL = 0;
901 sound1EnvelopeUpDown = 0;
902 sound1EnvelopeATLReload = 0;
903 sound1SweepATL = 0;
904 sound1SweepATLReload = 0;
905 sound1SweepSteps = 0;
906 sound1SweepUpDown = 0;
907 sound1SweepStep = 0;
908 sound1Wave = soundWavePattern[2];
910 sound2On = 0;
911 sound2ATL = 0;
912 sound2Skip = 0;
913 sound2Index = 0;
914 sound2Continue = 0;
915 sound2EnvelopeVolume = 0;
916 sound2EnvelopeATL = 0;
917 sound2EnvelopeUpDown = 0;
918 sound2EnvelopeATLReload = 0;
919 sound2Wave = soundWavePattern[2];
921 sound3On = 0;
922 sound3ATL = 0;
923 sound3Skip = 0;
924 sound3Index = 0;
925 sound3Continue = 0;
926 sound3OutputLevel = 0;
928 sound4On = 0;
929 sound4Clock = 0;
930 sound4ATL = 0;
931 sound4Skip = 0;
932 sound4Index = 0;
933 sound4ShiftRight = 0x7f;
934 sound4NSteps = 0;
935 sound4CountDown = 0;
936 sound4Continue = 0;
937 sound4EnvelopeVolume = 0;
938 sound4EnvelopeATL = 0;
939 sound4EnvelopeUpDown = 0;
940 sound4EnvelopeATLReload = 0;
942 // don't translate
943 if (soundDebug)
944 {
945 log("*** Sound Init ***\n");
946 }
948 gbSoundEvent(0xff10, 0x80);
949 gbSoundEvent(0xff11, 0xbf);
950 gbSoundEvent(0xff12, 0xf3);
951 gbSoundEvent(0xff14, 0xbf);
952 gbSoundEvent(0xff16, 0x3f);
953 gbSoundEvent(0xff17, 0x00);
954 gbSoundEvent(0xff19, 0xbf);
956 gbSoundEvent(0xff1a, 0x7f);
957 gbSoundEvent(0xff1b, 0xff);
958 gbSoundEvent(0xff1c, 0xbf);
959 gbSoundEvent(0xff1e, 0xbf);
961 gbSoundEvent(0xff20, 0xff);
962 gbSoundEvent(0xff21, 0x00);
963 gbSoundEvent(0xff22, 0x00);
964 gbSoundEvent(0xff23, 0xbf);
965 gbSoundEvent(0xff24, 0x77);
966 gbSoundEvent(0xff25, 0xf3);
968 gbSoundEvent(0xff26, 0xf0);
970 // don't translate
971 if (soundDebug)
972 {
973 log("*** Sound Init Complete ***\n");
974 }
976 sound1On = 0;
977 sound2On = 0;
978 sound3On = 0;
979 sound4On = 0;
981 int addr = 0xff30;
983 while (addr < 0xff40)
984 {
985 gbMemory[addr++] = 0x00;
986 gbMemory[addr++] = 0xff;
987 }
989 memset(soundFinalWave, 0x00, soundBufferLen);
991 memset(soundFilter, 0, sizeof(soundFilter));
992 soundEchoIndex = 0;
993 }
995 extern bool soundInit();
996 extern void soundShutdown();
998 void gbSoundSetQuality(int quality)
999 {
1000 if (soundQuality != quality && systemSoundCanChangeQuality())
1002 if (!soundOffFlag)
1003 soundShutdown();
1004 soundQuality = quality;
1005 soundNextPosition = 0;
1006 if (!soundOffFlag)
1007 soundInit();
1008 SOUND_CLOCK_TICKS = (gbSpeed ? 2 : 1) * GB_USE_TICKS_AS * soundQuality;
1009 soundIndex = 0;
1010 soundBufferIndex = 0;
1012 else
1014 soundNextPosition = 0;
1015 SOUND_CLOCK_TICKS = (gbSpeed ? 2 : 1) * GB_USE_TICKS_AS * soundQuality;
1016 soundIndex = 0;
1017 soundBufferIndex = 0;
1021 static int32 soundTicks_int32;
1022 static int32 SOUND_CLOCK_TICKS_int32;
1023 variable_desc gbSoundSaveStruct[] = {
1024 { &soundPaused, sizeof(int32) },
1025 { &soundPlay, sizeof(int32) },
1026 { &soundTicks_int32, sizeof(int32) },
1027 { &SOUND_CLOCK_TICKS_int32, sizeof(int32) },
1028 { &soundLevel1, sizeof(int32) },
1029 { &soundLevel2, sizeof(int32) },
1030 { &soundBalance, sizeof(int32) },
1031 { &soundMasterOn, sizeof(int32) },
1032 { &soundIndex, sizeof(int32) },
1033 { &soundVIN, sizeof(int32) },
1034 { &sound1On, sizeof(int32) },
1035 { &sound1ATL, sizeof(int32) },
1036 { &sound1Skip, sizeof(int32) },
1037 { &sound1Index, sizeof(int32) },
1038 { &sound1Continue, sizeof(int32) },
1039 { &sound1EnvelopeVolume, sizeof(int32) },
1040 { &sound1EnvelopeATL, sizeof(int32) },
1041 { &sound1EnvelopeATLReload, sizeof(int32) },
1042 { &sound1EnvelopeUpDown, sizeof(int32) },
1043 { &sound1SweepATL, sizeof(int32) },
1044 { &sound1SweepATLReload, sizeof(int32) },
1045 { &sound1SweepSteps, sizeof(int32) },
1046 { &sound1SweepUpDown, sizeof(int32) },
1047 { &sound1SweepStep, sizeof(int32) },
1048 { &sound2On, sizeof(int32) },
1049 { &sound2ATL, sizeof(int32) },
1050 { &sound2Skip, sizeof(int32) },
1051 { &sound2Index, sizeof(int32) },
1052 { &sound2Continue, sizeof(int32) },
1053 { &sound2EnvelopeVolume, sizeof(int32) },
1054 { &sound2EnvelopeATL, sizeof(int32) },
1055 { &sound2EnvelopeATLReload, sizeof(int32) },
1056 { &sound2EnvelopeUpDown, sizeof(int32) },
1057 { &sound3On, sizeof(int32) },
1058 { &sound3ATL, sizeof(int32) },
1059 { &sound3Skip, sizeof(int32) },
1060 { &sound3Index, sizeof(int32) },
1061 { &sound3Continue, sizeof(int32) },
1062 { &sound3OutputLevel, sizeof(int32) },
1063 { &sound4On, sizeof(int32) },
1064 { &sound4ATL, sizeof(int32) },
1065 { &sound4Skip, sizeof(int32) },
1066 { &sound4Index, sizeof(int32) },
1067 { &sound4Clock, sizeof(int32) },
1068 { &sound4ShiftRight, sizeof(int32) },
1069 { &sound4ShiftSkip, sizeof(int32) },
1070 { &sound4ShiftIndex, sizeof(int32) },
1071 { &sound4NSteps, sizeof(int32) },
1072 { &sound4CountDown, sizeof(int32) },
1073 { &sound4Continue, sizeof(int32) },
1074 { &sound4EnvelopeVolume, sizeof(int32) },
1075 { &sound4EnvelopeATL, sizeof(int32) },
1076 { &sound4EnvelopeATLReload, sizeof(int32) },
1077 { &sound4EnvelopeUpDown, sizeof(int32) },
1078 { &soundEnableFlag, sizeof(int32) },
1079 { NULL, 0 }
1080 };
1082 //variable_desc gbSoundSaveStructV2[] = {
1083 // { &soundTicks, sizeof(soundtick_t) },
1084 // { &SOUND_CLOCK_TICKS, sizeof(soundtick_t) },
1085 // { &GB_USE_TICKS_AS, sizeof(soundtick_t) },
1086 // { NULL, 0 }
1087 //};
1089 void gbSoundSaveGame(gzFile gzFile)
1091 soundTicks_int32 = (int32) soundTicks;
1092 SOUND_CLOCK_TICKS_int32 = (int32) SOUND_CLOCK_TICKS;
1094 utilWriteData(gzFile, gbSoundSaveStruct);
1096 utilGzWrite(gzFile, soundBuffer, 4 * 735);
1097 utilGzWrite(gzFile, soundFinalWave, 2 * 735);
1098 utilGzWrite(gzFile, &soundQuality, sizeof(int32));
1100 //utilWriteData(gzFile, gbSoundSaveStructV2);
1103 void gbSoundReadGame(int version, gzFile gzFile)
1105 int32 oldSoundPaused = soundPaused;
1106 int32 oldSoundEnableFlag = soundEnableFlag;
1107 utilReadData(gzFile, gbSoundSaveStruct);
1108 soundPaused = oldSoundPaused;
1109 soundEnableFlag = oldSoundEnableFlag;
1111 soundBufferIndex = soundIndex * 2;
1113 utilGzRead(gzFile, soundBuffer, 4 * 735);
1114 utilGzRead(gzFile, soundFinalWave, 2 * 735);
1116 if (version >= 7)
1118 int quality = 1;
1119 utilGzRead(gzFile, &quality, sizeof(int32));
1120 gbSoundSetQuality(quality);
1122 else
1124 soundQuality = -1;
1125 gbSoundSetQuality(1);
1128 sound1Wave = soundWavePattern[gbMemory[NR11] >> 6];
1129 sound2Wave = soundWavePattern[gbMemory[NR21] >> 6];
1131 //if(version >= 14) {
1132 // utilReadData(gzFile, gbSoundSaveStructV2);
1133 //}
1134 //else {
1135 soundTicks = (soundtick_t) soundTicks_int32;
1136 SOUND_CLOCK_TICKS = (soundtick_t) SOUND_CLOCK_TICKS_int32;
1137 //}