view src/gba/GBASound.cpp @ 573:40f62391db9d

implemented row and column increment logic.
author Robert McIntyre <rlm@mit.edu>
date Sat, 01 Sep 2012 03:56:30 -0500
parents f9f4f1b99eed
children
line wrap: on
line source
1 #if (defined(WIN32) && !defined(SDL))
2 # include "../win32/stdafx.h"
3 # include "../win32/VBA.h"
4 #endif
6 #include <cstring>
7 #include <cassert>
9 #include "GBASound.h"
10 #include "../common/System.h" // SDL build needs this
11 #include "../common/Util.h"
12 #include "GBA.h"
13 #include "GBAGlobals.h"
15 #ifndef countof
16 #define countof(a) (sizeof(a) / sizeof(a[0]))
17 #endif
19 soundtick_t USE_TICKS_AS = 380; // (16777216.0/44100.0); // FIXME: (16777216.0/280896.0)(fps) vs 60.0fps?
21 #define SOUND_MAGIC 0x60000000
22 #define SOUND_MAGIC_2 0x30000000
23 #define NOISE_MAGIC (2097152.0 / 44100.0)
25 extern bool8 stopState;
27 u8 soundWavePattern[4][32] = {
28 { 0x01, 0x01, 0x01, 0x01,
29 0xff, 0xff, 0xff, 0xff,
30 0xff, 0xff, 0xff, 0xff,
31 0xff, 0xff, 0xff, 0xff,
32 0xff, 0xff, 0xff, 0xff,
33 0xff, 0xff, 0xff, 0xff,
34 0xff, 0xff, 0xff, 0xff,
35 0xff, 0xff, 0xff, 0xff },
36 { 0x01, 0x01, 0x01, 0x01,
37 0x01, 0x01, 0x01, 0x01,
38 0xff, 0xff, 0xff, 0xff,
39 0xff, 0xff, 0xff, 0xff,
40 0xff, 0xff, 0xff, 0xff,
41 0xff, 0xff, 0xff, 0xff,
42 0xff, 0xff, 0xff, 0xff,
43 0xff, 0xff, 0xff, 0xff },
44 { 0x01, 0x01, 0x01, 0x01,
45 0x01, 0x01, 0x01, 0x01,
46 0x01, 0x01, 0x01, 0x01,
47 0x01, 0x01, 0x01, 0x01,
48 0xff, 0xff, 0xff, 0xff,
49 0xff, 0xff, 0xff, 0xff,
50 0xff, 0xff, 0xff, 0xff,
51 0xff, 0xff, 0xff, 0xff },
52 { 0x01, 0x01, 0x01, 0x01,
53 0x01, 0x01, 0x01, 0x01,
54 0x01, 0x01, 0x01, 0x01,
55 0x01, 0x01, 0x01, 0x01,
56 0x01, 0x01, 0x01, 0x01,
57 0x01, 0x01, 0x01, 0x01,
58 0xff, 0xff, 0xff, 0xff,
59 0xff, 0xff, 0xff, 0xff }
60 };
62 int32 soundFreqRatio[8] = {
63 1048576, // 0
64 524288, // 1
65 262144, // 2
66 174763, // 3
67 131072, // 4
68 104858, // 5
69 87381, // 6
70 74898 // 7
71 };
73 int32 soundShiftClock[16] = {
74 2, // 0
75 4, // 1
76 8, // 2
77 16, // 3
78 32, // 4
79 64, // 5
80 128, // 6
81 256, // 7
82 512, // 8
83 1024, // 9
84 2048, // 10
85 4096, // 11
86 8192, // 12
87 16384, // 13
88 1, // 14
89 1 // 15
90 };
92 int32 soundVolume = 0;
94 u8 soundBuffer[6][735];
95 u16 soundFinalWave[1470];
96 u16 soundFrameSound[735 * 30 * 2]; // for avi logging
98 u32 soundBufferLen = 1470;
99 u32 soundBufferTotalLen = 14700;
100 int32 soundQuality = 2;
101 int32 soundPaused = 1;
102 int32 soundPlay = 0;
103 soundtick_t soundTicks = soundQuality * USE_TICKS_AS;
104 soundtick_t SOUND_CLOCK_TICKS = soundQuality * USE_TICKS_AS;
105 u32 soundNextPosition = 0;
107 int32 soundLevel1 = 0;
108 int32 soundLevel2 = 0;
109 int32 soundBalance = 0;
110 int32 soundMasterOn = 0;
111 u32 soundIndex = 0;
112 u32 soundBufferIndex = 0;
113 int32 soundFrameSoundWritten = 0;
114 int32 soundDebug = 0;
115 bool8 soundOffFlag = false;
117 int32 sound1On = 0;
118 int32 sound1ATL = 0;
119 int32 sound1Skip = 0;
120 int32 sound1Index = 0;
121 int32 sound1Continue = 0;
122 int32 sound1EnvelopeVolume = 0;
123 int32 sound1EnvelopeATL = 0;
124 int32 sound1EnvelopeUpDown = 0;
125 int32 sound1EnvelopeATLReload = 0;
126 int32 sound1SweepATL = 0;
127 int32 sound1SweepATLReload = 0;
128 int32 sound1SweepSteps = 0;
129 int32 sound1SweepUpDown = 0;
130 int32 sound1SweepStep = 0;
131 u8 * sound1Wave = soundWavePattern[2];
133 int32 sound2On = 0;
134 int32 sound2ATL = 0;
135 int32 sound2Skip = 0;
136 int32 sound2Index = 0;
137 int32 sound2Continue = 0;
138 int32 sound2EnvelopeVolume = 0;
139 int32 sound2EnvelopeATL = 0;
140 int32 sound2EnvelopeUpDown = 0;
141 int32 sound2EnvelopeATLReload = 0;
142 u8 * sound2Wave = soundWavePattern[2];
144 int32 sound3On = 0;
145 int32 sound3ATL = 0;
146 int32 sound3Skip = 0;
147 int32 sound3Index = 0;
148 int32 sound3Continue = 0;
149 int32 sound3OutputLevel = 0;
150 int32 sound3Last = 0;
151 u8 sound3WaveRam[0x20];
152 int32 sound3Bank = 0;
153 int32 sound3DataSize = 0;
154 int32 sound3ForcedOutput = 0;
156 int32 sound4On = 0;
157 int32 sound4Clock = 0;
158 int32 sound4ATL = 0;
159 int32 sound4Skip = 0;
160 int32 sound4Index = 0;
161 int32 sound4ShiftRight = 0x7f;
162 int32 sound4ShiftSkip = 0;
163 int32 sound4ShiftIndex = 0;
164 int32 sound4NSteps = 0;
165 int32 sound4CountDown = 0;
166 int32 sound4Continue = 0;
167 int32 sound4EnvelopeVolume = 0;
168 int32 sound4EnvelopeATL = 0;
169 int32 sound4EnvelopeUpDown = 0;
170 int32 sound4EnvelopeATLReload = 0;
172 int32 soundControl = 0;
174 int32 soundDSFifoAIndex = 0;
175 int32 soundDSFifoACount = 0;
176 int32 soundDSFifoAWriteIndex = 0;
177 bool8 soundDSAEnabled = false;
178 int32 soundDSATimer = 0;
179 u8 soundDSFifoA[32];
180 u8 soundDSAValue = 0;
182 int32 soundDSFifoBIndex = 0;
183 int32 soundDSFifoBCount = 0;
184 int32 soundDSFifoBWriteIndex = 0;
185 bool8 soundDSBEnabled = false;
186 int32 soundDSBTimer = 0;
187 u8 soundDSFifoB[32];
188 u8 soundDSBValue = 0;
190 int32 soundEnableFlag = 0x3ff;
191 int32 soundMutedFlag = 0;
193 s16 soundFilter[4000];
194 s16 soundRight[5] = { 0, 0, 0, 0, 0 };
195 s16 soundLeft[5] = { 0, 0, 0, 0, 0 };
196 int32 soundEchoIndex = 0;
197 bool8 soundEcho = false;
198 bool8 soundLowPass = false;
199 bool8 soundReverse = false;
201 static int32 soundTicks_int32;
202 static int32 SOUND_CLOCK_TICKS_int32;
203 static int32 soundDSBValue_int32;
204 variable_desc soundSaveStruct[] = {
205 { &soundPaused, sizeof(int32) },
206 { &soundPlay, sizeof(int32) },
207 { &soundTicks_int32, sizeof(int32) },
208 { &SOUND_CLOCK_TICKS_int32, sizeof(int32) },
209 { &soundLevel1, sizeof(int32) },
210 { &soundLevel2, sizeof(int32) },
211 { &soundBalance, sizeof(int32) },
212 { &soundMasterOn, sizeof(int32) },
213 { &soundIndex, sizeof(int32) },
214 { &sound1On, sizeof(int32) },
215 { &sound1ATL, sizeof(int32) },
216 { &sound1Skip, sizeof(int32) },
217 { &sound1Index, sizeof(int32) },
218 { &sound1Continue, sizeof(int32) },
219 { &sound1EnvelopeVolume, sizeof(int32) },
220 { &sound1EnvelopeATL, sizeof(int32) },
221 { &sound1EnvelopeATLReload, sizeof(int32) },
222 { &sound1EnvelopeUpDown, sizeof(int32) },
223 { &sound1SweepATL, sizeof(int32) },
224 { &sound1SweepATLReload, sizeof(int32) },
225 { &sound1SweepSteps, sizeof(int32) },
226 { &sound1SweepUpDown, sizeof(int32) },
227 { &sound1SweepStep, sizeof(int32) },
228 { &sound2On, sizeof(int32) },
229 { &sound2ATL, sizeof(int32) },
230 { &sound2Skip, sizeof(int32) },
231 { &sound2Index, sizeof(int32) },
232 { &sound2Continue, sizeof(int32) },
233 { &sound2EnvelopeVolume, sizeof(int32) },
234 { &sound2EnvelopeATL, sizeof(int32) },
235 { &sound2EnvelopeATLReload, sizeof(int32) },
236 { &sound2EnvelopeUpDown, sizeof(int32) },
237 { &sound3On, sizeof(int32) },
238 { &sound3ATL, sizeof(int32) },
239 { &sound3Skip, sizeof(int32) },
240 { &sound3Index, sizeof(int32) },
241 { &sound3Continue, sizeof(int32) },
242 { &sound3OutputLevel, sizeof(int32) },
243 { &sound4On, sizeof(int32) },
244 { &sound4ATL, sizeof(int32) },
245 { &sound4Skip, sizeof(int32) },
246 { &sound4Index, sizeof(int32) },
247 { &sound4Clock, sizeof(int32) },
248 { &sound4ShiftRight, sizeof(int32) },
249 { &sound4ShiftSkip, sizeof(int32) },
250 { &sound4ShiftIndex, sizeof(int32) },
251 { &sound4NSteps, sizeof(int32) },
252 { &sound4CountDown, sizeof(int32) },
253 { &sound4Continue, sizeof(int32) },
254 { &sound4EnvelopeVolume, sizeof(int32) },
255 { &sound4EnvelopeATL, sizeof(int32) },
256 { &sound4EnvelopeATLReload, sizeof(int32) },
257 { &sound4EnvelopeUpDown, sizeof(int32) },
258 { &soundEnableFlag, sizeof(int32) },
259 { &soundControl, sizeof(int32) },
260 { &soundDSFifoAIndex, sizeof(int32) },
261 { &soundDSFifoACount, sizeof(int32) },
262 { &soundDSFifoAWriteIndex, sizeof(int32) },
263 { &soundDSAEnabled, sizeof(bool8) },
264 { &soundDSATimer, sizeof(int32) },
265 { &soundDSFifoA[0], 32 },
266 { &soundDSAValue, sizeof(u8) },
267 { &soundDSFifoBIndex, sizeof(int32) },
268 { &soundDSFifoBCount, sizeof(int32) },
269 { &soundDSFifoBWriteIndex, sizeof(int32) },
270 { &soundDSBEnabled, sizeof(int32) },
271 { &soundDSBTimer, sizeof(int32) },
272 { &soundDSFifoB[0], 32 },
273 { &soundDSBValue_int32, sizeof(int32) }, // save as int32 because of a mistake of the past.
274 { &soundBuffer[0][0], 6 * 735 },
275 { &soundFinalWave[0], 2 * 735 },
276 { NULL, 0 }
277 };
279 variable_desc soundSaveStructV2[] = {
280 { &sound3WaveRam[0], 0x20 },
281 { &sound3Bank, sizeof(int32) },
282 { &sound3DataSize, sizeof(int32) },
283 { &sound3ForcedOutput, sizeof(int32) },
284 { NULL, 0 }
285 };
287 //variable_desc soundSaveStructV3[] = {
288 // { &soundTicks, sizeof(soundtick_t) },
289 // { &SOUND_CLOCK_TICKS, sizeof(soundtick_t) },
290 // { &USE_TICKS_AS, sizeof(soundtick_t) },
291 // { NULL, 0 }
292 //};
294 void soundEvent(u32 address, u8 data)
295 {
296 int freq = 0;
298 switch (address)
299 {
300 case NR10:
301 data &= 0x7f;
302 sound1SweepATL = sound1SweepATLReload = 344 * ((data >> 4) & 7);
303 sound1SweepSteps = data & 7;
304 sound1SweepUpDown = data & 0x08;
305 sound1SweepStep = 0;
306 ioMem[address] = data;
307 break;
308 case NR11:
309 sound1Wave = soundWavePattern[data >> 6];
310 sound1ATL = 172 * (64 - (data & 0x3f));
311 ioMem[address] = data;
312 break;
313 case NR12:
314 sound1EnvelopeUpDown = data & 0x08;
315 sound1EnvelopeATLReload = 689 * (data & 7);
316 if ((data & 0xF8) == 0)
317 sound1EnvelopeVolume = 0;
318 ioMem[address] = data;
319 break;
320 case NR13:
321 freq = (((int)(ioMem[NR14] & 7)) << 8) | data;
322 sound1ATL = 172 * (64 - (ioMem[NR11] & 0x3f));
323 freq = 2048 - freq;
324 if (freq)
325 {
326 sound1Skip = SOUND_MAGIC / freq;
327 }
328 else
329 sound1Skip = 0;
330 ioMem[address] = data;
331 break;
332 case NR14:
333 data &= 0xC7;
334 freq = (((int)(data & 7) << 8) | ioMem[NR13]);
335 freq = 2048 - freq;
336 sound1ATL = 172 * (64 - (ioMem[NR11] & 0x3f));
337 sound1Continue = data & 0x40;
338 if (freq)
339 {
340 sound1Skip = SOUND_MAGIC / freq;
341 }
342 else
343 sound1Skip = 0;
344 if (data & 0x80)
345 {
346 ioMem[NR52] |= 1;
347 sound1EnvelopeVolume = ioMem[NR12] >> 4;
348 sound1EnvelopeUpDown = ioMem[NR12] & 0x08;
349 sound1ATL = 172 * (64 - (ioMem[NR11] & 0x3f));
350 sound1EnvelopeATLReload = sound1EnvelopeATL = 689 * (ioMem[NR12] & 7);
351 sound1SweepATL = sound1SweepATLReload = 344 * ((ioMem[NR10] >> 4) & 7);
352 sound1SweepSteps = ioMem[NR10] & 7;
353 sound1SweepUpDown = ioMem[NR10] & 0x08;
354 sound1SweepStep = 0;
356 sound1Index = 0;
357 sound1On = 1;
358 }
359 ioMem[address] = data;
360 break;
361 case NR21:
362 sound2Wave = soundWavePattern[data >> 6];
363 sound2ATL = 172 * (64 - (data & 0x3f));
364 ioMem[address] = data;
365 break;
366 case NR22:
367 sound2EnvelopeUpDown = data & 0x08;
368 sound2EnvelopeATLReload = 689 * (data & 7);
369 if ((data & 0xF8) == 0)
370 sound2EnvelopeVolume = 0;
371 ioMem[address] = data;
372 break;
373 case NR23:
374 freq = (((int)(ioMem[NR24] & 7)) << 8) | data;
375 sound2ATL = 172 * (64 - (ioMem[NR21] & 0x3f));
376 freq = 2048 - freq;
377 if (freq)
378 {
379 sound2Skip = SOUND_MAGIC / freq;
380 }
381 else
382 sound2Skip = 0;
383 ioMem[address] = data;
384 break;
385 case NR24:
386 data &= 0xC7;
387 freq = (((int)(data & 7) << 8) | ioMem[NR23]);
388 freq = 2048 - freq;
389 sound2ATL = 172 * (64 - (ioMem[NR21] & 0x3f));
390 sound2Continue = data & 0x40;
391 if (freq)
392 {
393 sound2Skip = SOUND_MAGIC / freq;
394 }
395 else
396 sound2Skip = 0;
397 if (data & 0x80)
398 {
399 ioMem[NR52] |= 2;
400 sound2EnvelopeVolume = ioMem[NR22] >> 4;
401 sound2EnvelopeUpDown = ioMem[NR22] & 0x08;
402 sound2ATL = 172 * (64 - (ioMem[NR21] & 0x3f));
403 sound2EnvelopeATLReload = sound2EnvelopeATL = 689 * (ioMem[NR22] & 7);
405 sound2Index = 0;
406 sound2On = 1;
407 }
408 ioMem[address] = data;
409 break;
410 case NR30:
411 data &= 0xe0;
412 if (!(data & 0x80))
413 {
414 ioMem[NR52] &= 0xfb;
415 sound3On = 0;
416 }
417 if (((data >> 6) & 1) != sound3Bank)
418 memcpy(&ioMem[0x90], &sound3WaveRam[(((data >> 6) & 1) * 0x10) ^ 0x10],
419 0x10);
420 sound3Bank = (data >> 6) & 1;
421 sound3DataSize = (data >> 5) & 1;
422 ioMem[address] = data;
423 break;
424 case NR31:
425 sound3ATL = 172 * (256 - data);
426 ioMem[address] = data;
427 break;
428 case NR32:
429 data &= 0xe0;
430 sound3OutputLevel = (data >> 5) & 3;
431 sound3ForcedOutput = (data >> 7) & 1;
432 ioMem[address] = data;
433 break;
434 case NR33:
435 freq = 2048 - (((int)(ioMem[NR34] & 7) << 8) | data);
436 if (freq)
437 {
438 sound3Skip = SOUND_MAGIC_2 / freq;
439 }
440 else
441 sound3Skip = 0;
442 ioMem[address] = data;
443 break;
444 case NR34:
445 data &= 0xc7;
446 freq = 2048 - (((data & 7) << 8) | (int)ioMem[NR33]);
447 if (freq)
448 {
449 sound3Skip = SOUND_MAGIC_2 / freq;
450 }
451 else
452 {
453 sound3Skip = 0;
454 }
455 sound3Continue = data & 0x40;
456 if ((data & 0x80) && (ioMem[NR30] & 0x80))
457 {
458 ioMem[NR52] |= 4;
459 sound3ATL = 172 * (256 - ioMem[NR31]);
460 sound3Index = 0;
461 sound3On = 1;
462 }
463 ioMem[address] = data;
464 break;
465 case NR41:
466 data &= 0x3f;
467 sound4ATL = 172 * (64 - (data & 0x3f));
468 ioMem[address] = data;
469 break;
470 case NR42:
471 sound4EnvelopeUpDown = data & 0x08;
472 sound4EnvelopeATLReload = 689 * (data & 7);
473 if ((data & 0xF8) == 0)
474 sound4EnvelopeVolume = 0;
475 ioMem[address] = data;
476 break;
477 case NR43:
478 freq = soundFreqRatio[data & 7];
479 sound4NSteps = data & 0x08;
481 sound4Skip = freq * NOISE_MAGIC;
483 sound4Clock = data >> 4;
485 freq = freq / soundShiftClock[sound4Clock];
487 sound4ShiftSkip = freq * NOISE_MAGIC;
488 ioMem[address] = data;
489 break;
490 case NR44:
491 data &= 0xc0;
492 sound4Continue = data & 0x40;
493 if (data & 0x80)
494 {
495 ioMem[NR52] |= 8;
496 sound4EnvelopeVolume = ioMem[NR42] >> 4;
497 sound4EnvelopeUpDown = ioMem[NR42] & 0x08;
498 sound4ATL = 172 * (64 - (ioMem[NR41] & 0x3f));
499 sound4EnvelopeATLReload = sound4EnvelopeATL = 689 * (ioMem[NR42] & 7);
501 sound4On = 1;
503 sound4Index = 0;
504 sound4ShiftIndex = 0;
506 freq = soundFreqRatio[ioMem[NR43] & 7];
508 sound4Skip = freq * NOISE_MAGIC;
510 sound4NSteps = ioMem[NR43] & 0x08;
512 freq = freq / soundShiftClock[ioMem[NR43] >> 4];
514 sound4ShiftSkip = freq * NOISE_MAGIC;
515 if (sound4NSteps)
516 sound4ShiftRight = 0x7f;
517 else
518 sound4ShiftRight = 0x7fff;
519 }
520 ioMem[address] = data;
521 break;
522 case NR50:
523 data &= 0x77;
524 soundLevel1 = data & 7;
525 soundLevel2 = (data >> 4) & 7;
526 ioMem[address] = data;
527 break;
528 case NR51:
529 soundBalance = (data & soundEnableFlag);
530 ioMem[address] = data;
531 break;
532 case NR52:
533 data &= 0x80;
534 data |= ioMem[NR52] & 15;
535 soundMasterOn = data & 0x80;
536 if (!(data & 0x80))
537 {
538 sound1On = 0;
539 sound2On = 0;
540 sound3On = 0;
541 sound4On = 0;
542 }
543 ioMem[address] = data;
544 break;
545 case 0x90:
546 case 0x91:
547 case 0x92:
548 case 0x93:
549 case 0x94:
550 case 0x95:
551 case 0x96:
552 case 0x97:
553 case 0x98:
554 case 0x99:
555 case 0x9a:
556 case 0x9b:
557 case 0x9c:
558 case 0x9d:
559 case 0x9e:
560 case 0x9f:
561 sound3WaveRam[(sound3Bank * 0x10) ^ 0x10 + (address & 15)] = data;
562 break;
563 }
564 }
566 void soundEvent(u32 address, u16 data)
567 {
568 switch (address)
569 {
570 case SGCNT0_H:
571 data &= 0xFF0F;
572 soundControl = data & 0x770F;;
573 if (data & 0x0800)
574 {
575 soundDSFifoAWriteIndex = 0;
576 soundDSFifoAIndex = 0;
577 soundDSFifoACount = 0;
578 soundDSAValue = 0;
579 memset(soundDSFifoA, 0, 32);
580 }
581 soundDSAEnabled = (data & 0x0300) ? true : false;
582 soundDSATimer = (data & 0x0400) ? 1 : 0;
583 if (data & 0x8000)
584 {
585 soundDSFifoBWriteIndex = 0;
586 soundDSFifoBIndex = 0;
587 soundDSFifoBCount = 0;
588 soundDSBValue = 0;
589 memset(soundDSFifoB, 0, 32);
590 }
591 soundDSBEnabled = (data & 0x3000) ? true : false;
592 soundDSBTimer = (data & 0x4000) ? 1 : 0;
593 *((u16 *)&ioMem[address]) = data;
594 break;
595 case FIFOA_L:
596 case FIFOA_H:
597 soundDSFifoA[soundDSFifoAWriteIndex++] = data & 0xFF;
598 soundDSFifoA[soundDSFifoAWriteIndex++] = data >> 8;
599 soundDSFifoACount += 2;
600 soundDSFifoAWriteIndex &= 31;
601 *((u16 *)&ioMem[address]) = data;
602 break;
603 case FIFOB_L:
604 case FIFOB_H:
605 soundDSFifoB[soundDSFifoBWriteIndex++] = data & 0xFF;
606 soundDSFifoB[soundDSFifoBWriteIndex++] = data >> 8;
607 soundDSFifoBCount += 2;
608 soundDSFifoBWriteIndex &= 31;
609 *((u16 *)&ioMem[address]) = data;
610 break;
611 case 0x88:
612 data &= 0xC3FF;
613 *((u16 *)&ioMem[address]) = data;
614 break;
615 case 0x90:
616 case 0x92:
617 case 0x94:
618 case 0x96:
619 case 0x98:
620 case 0x9a:
621 case 0x9c:
622 case 0x9e:
623 *((u16 *)&sound3WaveRam[(sound3Bank * 0x10) ^ 0x10 + (address & 14)]) = data;
624 *((u16 *)&ioMem[address]) = data;
625 break;
626 }
627 }
629 void soundChannel1()
630 {
631 int vol = sound1EnvelopeVolume;
633 int freq = 0;
634 int value = 0;
636 if (sound1On && (sound1ATL || !sound1Continue))
637 {
638 sound1Index += soundQuality * sound1Skip;
639 sound1Index &= 0x1fffffff;
641 value = ((s8)sound1Wave[sound1Index >> 24]) * vol;
642 }
644 soundBuffer[0][soundIndex] = value;
646 if (sound1On)
647 {
648 if (sound1ATL)
649 {
650 sound1ATL -= soundQuality;
652 if (sound1ATL <= 0 && sound1Continue)
653 {
654 ioMem[NR52] &= 0xfe;
655 sound1On = 0;
656 }
657 }
659 if (sound1EnvelopeATL)
660 {
661 sound1EnvelopeATL -= soundQuality;
663 if (sound1EnvelopeATL <= 0)
664 {
665 if (sound1EnvelopeUpDown)
666 {
667 if (sound1EnvelopeVolume < 15)
668 sound1EnvelopeVolume++;
669 }
670 else
671 {
672 if (sound1EnvelopeVolume)
673 sound1EnvelopeVolume--;
674 }
676 sound1EnvelopeATL += sound1EnvelopeATLReload;
677 }
678 }
680 if (sound1SweepATL)
681 {
682 sound1SweepATL -= soundQuality;
684 if (sound1SweepATL <= 0)
685 {
686 freq = (((int)(ioMem[NR14] & 7) << 8) | ioMem[NR13]);
688 int updown = 1;
690 if (sound1SweepUpDown)
691 updown = -1;
693 int newfreq = 0;
694 if (sound1SweepSteps)
695 {
696 newfreq = freq + updown * freq / (1 << sound1SweepSteps);
697 if (newfreq == freq)
698 newfreq = 0;
699 }
700 else
701 newfreq = freq;
703 if (newfreq < 0)
704 {
705 sound1SweepATL += sound1SweepATLReload;
706 }
707 else if (newfreq > 2047)
708 {
709 sound1SweepATL = 0;
710 sound1On = 0;
711 ioMem[NR52] &= 0xfe;
712 }
713 else
714 {
715 sound1SweepATL += sound1SweepATLReload;
716 sound1Skip = SOUND_MAGIC / (2048 - newfreq);
718 ioMem[NR13] = newfreq & 0xff;
719 ioMem[NR14] = (ioMem[NR14] & 0xf8) | ((newfreq >> 8) & 7);
720 }
721 }
722 }
723 }
724 }
726 void soundChannel2()
727 {
728 // int freq = 0;
729 int vol = sound2EnvelopeVolume;
731 int value = 0;
733 if (sound2On && (sound2ATL || !sound2Continue))
734 {
735 sound2Index += soundQuality * sound2Skip;
736 sound2Index &= 0x1fffffff;
738 value = ((s8)sound2Wave[sound2Index >> 24]) * vol;
739 }
741 soundBuffer[1][soundIndex] = value;
743 if (sound2On)
744 {
745 if (sound2ATL)
746 {
747 sound2ATL -= soundQuality;
749 if (sound2ATL <= 0 && sound2Continue)
750 {
751 ioMem[NR52] &= 0xfd;
752 sound2On = 0;
753 }
754 }
756 if (sound2EnvelopeATL)
757 {
758 sound2EnvelopeATL -= soundQuality;
760 if (sound2EnvelopeATL <= 0)
761 {
762 if (sound2EnvelopeUpDown)
763 {
764 if (sound2EnvelopeVolume < 15)
765 sound2EnvelopeVolume++;
766 }
767 else
768 {
769 if (sound2EnvelopeVolume)
770 sound2EnvelopeVolume--;
771 }
772 sound2EnvelopeATL += sound2EnvelopeATLReload;
773 }
774 }
775 }
776 }
778 void soundChannel3()
779 {
780 int value = sound3Last;
782 if (sound3On && (sound3ATL || !sound3Continue))
783 {
784 sound3Index += soundQuality * sound3Skip;
785 if (sound3DataSize)
786 {
787 sound3Index &= 0x3fffffff;
788 value = sound3WaveRam[sound3Index >> 25];
789 }
790 else
791 {
792 sound3Index &= 0x1fffffff;
793 value = sound3WaveRam[sound3Bank * 0x10 + (sound3Index >> 25)];
794 }
796 if ((sound3Index & 0x01000000))
797 {
798 value &= 0x0f;
799 }
800 else
801 {
802 value >>= 4;
803 }
805 value -= 8;
806 value *= 2;
808 if (sound3ForcedOutput)
809 {
810 value = ((value >> 1) + value) >> 1;
811 }
812 else
813 {
814 switch (sound3OutputLevel)
815 {
816 case 0:
817 value = 0;
818 break;
819 case 1:
820 break;
821 case 2:
822 value = (value >> 1);
823 break;
824 case 3:
825 value = (value >> 2);
826 break;
827 }
828 }
829 //value += 1;
830 sound3Last = value;
831 }
833 soundBuffer[2][soundIndex] = value;
835 if (sound3On)
836 {
837 if (sound3ATL)
838 {
839 sound3ATL -= soundQuality;
841 if (sound3ATL <= 0 && sound3Continue)
842 {
843 ioMem[NR52] &= 0xfb;
844 sound3On = 0;
845 }
846 }
847 }
848 }
850 void soundChannel4()
851 {
852 int vol = sound4EnvelopeVolume;
854 int value = 0;
856 if (sound4Clock <= 0x0c)
857 {
858 if (sound4On && (sound4ATL || !sound4Continue))
859 {
860 #define NOISE_ONE_SAMP_SCALE 0x200000
862 sound4Index += soundQuality * sound4Skip;
863 sound4ShiftIndex += soundQuality * sound4ShiftSkip;
865 if (sound4NSteps)
866 {
867 while (sound4ShiftIndex >= NOISE_ONE_SAMP_SCALE)
868 {
869 sound4ShiftRight = (((sound4ShiftRight << 6) ^
870 (sound4ShiftRight << 5)) & 0x40) |
871 (sound4ShiftRight >> 1);
872 sound4ShiftIndex -= NOISE_ONE_SAMP_SCALE;
873 }
874 }
875 else
876 {
877 while (sound4ShiftIndex >= NOISE_ONE_SAMP_SCALE)
878 {
879 sound4ShiftRight = (((sound4ShiftRight << 14) ^
880 (sound4ShiftRight << 13)) & 0x4000) |
881 (sound4ShiftRight >> 1);
883 sound4ShiftIndex -= NOISE_ONE_SAMP_SCALE;
884 }
885 }
887 sound4Index %= NOISE_ONE_SAMP_SCALE;
888 sound4ShiftIndex %= NOISE_ONE_SAMP_SCALE;
890 value = ((sound4ShiftRight & 1) * 2 - 1) * vol;
891 }
892 else
893 {
894 value = 0;
895 }
896 }
898 soundBuffer[3][soundIndex] = value;
900 if (sound4On)
901 {
902 if (sound4ATL)
903 {
904 sound4ATL -= soundQuality;
906 if (sound4ATL <= 0 && sound4Continue)
907 {
908 ioMem[NR52] &= 0xfd;
909 sound4On = 0;
910 }
911 }
913 if (sound4EnvelopeATL)
914 {
915 sound4EnvelopeATL -= soundQuality;
917 if (sound4EnvelopeATL <= 0)
918 {
919 if (sound4EnvelopeUpDown)
920 {
921 if (sound4EnvelopeVolume < 15)
922 sound4EnvelopeVolume++;
923 }
924 else
925 {
926 if (sound4EnvelopeVolume)
927 sound4EnvelopeVolume--;
928 }
929 sound4EnvelopeATL += sound4EnvelopeATLReload;
930 }
931 }
932 }
933 }
935 void soundDirectSoundA()
936 {
937 soundBuffer[4][soundIndex] = soundDSAValue;
938 }
940 void soundDirectSoundATimer()
941 {
942 if (soundDSAEnabled)
943 {
944 if (soundDSFifoACount <= 16)
945 {
946 CPUCheckDMA(3, 2);
947 if (soundDSFifoACount <= 16)
948 {
949 soundEvent(FIFOA_L, (u16)0);
950 soundEvent(FIFOA_H, (u16)0);
951 soundEvent(FIFOA_L, (u16)0);
952 soundEvent(FIFOA_H, (u16)0);
953 soundEvent(FIFOA_L, (u16)0);
954 soundEvent(FIFOA_H, (u16)0);
955 soundEvent(FIFOA_L, (u16)0);
956 soundEvent(FIFOA_H, (u16)0);
957 }
958 }
960 soundDSAValue = (soundDSFifoA[soundDSFifoAIndex]);
961 soundDSFifoAIndex = (++soundDSFifoAIndex) & 31;
962 soundDSFifoACount--;
963 }
964 else
965 soundDSAValue = 0;
966 }
968 void soundDirectSoundB()
969 {
970 soundBuffer[5][soundIndex] = soundDSBValue;
971 }
973 void soundDirectSoundBTimer()
974 {
975 if (soundDSBEnabled)
976 {
977 if (soundDSFifoBCount <= 16)
978 {
979 CPUCheckDMA(3, 4);
980 if (soundDSFifoBCount <= 16)
981 {
982 soundEvent(FIFOB_L, (u16)0);
983 soundEvent(FIFOB_H, (u16)0);
984 soundEvent(FIFOB_L, (u16)0);
985 soundEvent(FIFOB_H, (u16)0);
986 soundEvent(FIFOB_L, (u16)0);
987 soundEvent(FIFOB_H, (u16)0);
988 soundEvent(FIFOB_L, (u16)0);
989 soundEvent(FIFOB_H, (u16)0);
990 }
991 }
993 soundDSBValue = (soundDSFifoB[soundDSFifoBIndex]);
994 soundDSFifoBIndex = (++soundDSFifoBIndex) & 31;
995 soundDSFifoBCount--;
996 }
997 else
998 {
999 soundDSBValue = 0;
1003 void soundTimerOverflow(int timer)
1005 if (soundDSAEnabled && (soundDSATimer == timer))
1007 soundDirectSoundATimer();
1009 if (soundDSBEnabled && (soundDSBTimer == timer))
1011 soundDirectSoundBTimer();
1015 void soundMix()
1017 int res = 0;
1018 int cgbRes = 0;
1019 int ratio = ioMem[0x82] & 3;
1020 int dsaRatio = ioMem[0x82] & 4;
1021 int dsbRatio = ioMem[0x82] & 8;
1023 if (ioMem)
1024 soundBalance = (ioMem[NR51] & soundEnableFlag & ~soundMutedFlag);
1026 if (soundBalance & 16)
1028 cgbRes = ((s8)soundBuffer[0][soundIndex]);
1030 if (soundBalance & 32)
1032 cgbRes += ((s8)soundBuffer[1][soundIndex]);
1034 if (soundBalance & 64)
1036 cgbRes += ((s8)soundBuffer[2][soundIndex]);
1038 if (soundBalance & 128)
1040 cgbRes += ((s8)soundBuffer[3][soundIndex]);
1043 if ((soundControl & 0x0200) && (soundEnableFlag & 0x100))
1045 if (!dsaRatio)
1046 res = ((s8)soundBuffer[4][soundIndex]) >> 1;
1047 else
1048 res = ((s8)soundBuffer[4][soundIndex]);
1051 if ((soundControl & 0x2000) && (soundEnableFlag & 0x200))
1053 if (!dsbRatio)
1054 res += ((s8)soundBuffer[5][soundIndex]) >> 1;
1055 else
1056 res += ((s8)soundBuffer[5][soundIndex]);
1059 res = (res * 170);
1060 cgbRes = (cgbRes * 52 * soundLevel1);
1062 switch (ratio)
1064 case 0:
1065 case 3: // prohibited, but 25%
1066 cgbRes >>= 2;
1067 break;
1068 case 1:
1069 cgbRes >>= 1;
1070 break;
1071 case 2:
1072 break;
1075 res += cgbRes;
1077 if (soundEcho)
1079 res *= 2;
1080 res += soundFilter[soundEchoIndex];
1081 res /= 2;
1082 soundFilter[soundEchoIndex++] = res;
1085 if (soundLowPass)
1087 soundLeft[4] = soundLeft[3];
1088 soundLeft[3] = soundLeft[2];
1089 soundLeft[2] = soundLeft[1];
1090 soundLeft[1] = soundLeft[0];
1091 soundLeft[0] = res;
1092 res = (soundLeft[4] + 2 * soundLeft[3] + 8 * soundLeft[2] + 2 * soundLeft[1] +
1093 soundLeft[0]) / 14;
1096 bool noSpecialEffects = false;
1097 #if (defined(WIN32) && !defined(SDL))
1098 if (theApp.soundRecording || theApp.aviRecording || theApp.nvAudioLog)
1099 noSpecialEffects = true;
1100 #endif
1102 if (!noSpecialEffects)
1104 switch (soundVolume)
1106 case 0:
1107 case 1:
1108 case 2:
1109 case 3:
1110 res *= (soundVolume + 1);
1111 break;
1112 case 4:
1113 res >>= 2;
1114 break;
1115 case 5:
1116 res >>= 1;
1117 break;
1121 if (res > 32767)
1122 res = 32767;
1123 if (res < -32768)
1124 res = -32768;
1126 if (soundReverse && !noSpecialEffects)
1128 soundFinalWave[++soundBufferIndex] = res;
1129 if ((soundFrameSoundWritten + 1) >= countof(soundFrameSound))
1130 /*assert(false)*/;
1131 else
1132 soundFrameSound[++soundFrameSoundWritten] = res;
1134 else
1136 soundFinalWave[soundBufferIndex++] = res;
1137 if (soundFrameSoundWritten >= countof(soundFrameSound))
1138 /*assert(false)*/;
1139 else
1140 soundFrameSound[soundFrameSoundWritten++] = res;
1143 res = 0;
1144 cgbRes = 0;
1146 if (soundBalance & 1)
1148 cgbRes = ((s8)soundBuffer[0][soundIndex]);
1150 if (soundBalance & 2)
1152 cgbRes += ((s8)soundBuffer[1][soundIndex]);
1154 if (soundBalance & 4)
1156 cgbRes += ((s8)soundBuffer[2][soundIndex]);
1158 if (soundBalance & 8)
1160 cgbRes += ((s8)soundBuffer[3][soundIndex]);
1163 if ((soundControl & 0x0100) && (soundEnableFlag & 0x100))
1165 if (!dsaRatio)
1166 res = ((s8)soundBuffer[4][soundIndex]) >> 1;
1167 else
1168 res = ((s8)soundBuffer[4][soundIndex]);
1171 if ((soundControl & 0x1000) && (soundEnableFlag & 0x200))
1173 if (!dsbRatio)
1174 res += ((s8)soundBuffer[5][soundIndex]) >> 1;
1175 else
1176 res += ((s8)soundBuffer[5][soundIndex]);
1179 res = (res * 170);
1180 cgbRes = (cgbRes * 52 * soundLevel1);
1182 switch (ratio)
1184 case 0:
1185 case 3: // prohibited, but 25%
1186 cgbRes >>= 2;
1187 break;
1188 case 1:
1189 cgbRes >>= 1;
1190 break;
1191 case 2:
1192 break;
1195 res += cgbRes;
1197 if (soundEcho)
1199 res *= 2;
1200 res += soundFilter[soundEchoIndex];
1201 res /= 2;
1202 soundFilter[soundEchoIndex++] = res;
1204 if (soundEchoIndex >= 4000)
1205 soundEchoIndex = 0;
1208 if (soundLowPass)
1210 soundRight[4] = soundRight[3];
1211 soundRight[3] = soundRight[2];
1212 soundRight[2] = soundRight[1];
1213 soundRight[1] = soundRight[0];
1214 soundRight[0] = res;
1215 res = (soundRight[4] + 2 * soundRight[3] + 8 * soundRight[2] + 2 * soundRight[1] +
1216 soundRight[0]) / 14;
1219 if (!noSpecialEffects)
1221 switch (soundVolume)
1223 case 0:
1224 case 1:
1225 case 2:
1226 case 3:
1227 res *= (soundVolume + 1);
1228 break;
1229 case 4:
1230 res >>= 2;
1231 break;
1232 case 5:
1233 res >>= 1;
1234 break;
1238 if (res > 32767)
1239 res = 32767;
1240 if (res < -32768)
1241 res = -32768;
1243 if (soundReverse && !noSpecialEffects)
1245 soundFinalWave[-1 + soundBufferIndex++] = res;
1246 if ((soundFrameSoundWritten) >= countof(soundFrameSound))
1247 /*assert(false)*/;
1248 else
1249 soundFrameSound[-1 + soundFrameSoundWritten++] = res;
1251 else
1253 soundFinalWave[soundBufferIndex++] = res;
1254 if ((soundFrameSoundWritten + 1) >= countof(soundFrameSound))
1255 /*assert(false)*/;
1256 else
1257 soundFrameSound[soundFrameSoundWritten++] = res;
1261 void soundTick()
1263 if (systemSoundOn)
1265 if (soundMasterOn && !stopState)
1267 soundChannel1();
1268 soundChannel2();
1269 soundChannel3();
1270 soundChannel4();
1271 soundDirectSoundA();
1272 soundDirectSoundB();
1273 soundMix();
1275 else
1277 soundFinalWave[soundBufferIndex++] = 0;
1278 soundFinalWave[soundBufferIndex++] = 0;
1279 if ((soundFrameSoundWritten + 1) >= countof(soundFrameSound))
1280 /*assert(false)*/;
1281 else
1283 soundFrameSound[soundFrameSoundWritten++] = 0;
1284 soundFrameSound[soundFrameSoundWritten++] = 0;
1288 soundIndex++;
1290 if (2 * soundBufferIndex >= soundBufferLen)
1292 if (systemSoundOn)
1294 if (soundPaused)
1296 soundResume();
1299 systemSoundWriteToBuffer();
1301 soundIndex = 0;
1302 soundBufferIndex = 0;
1307 void soundShutdown()
1309 systemSoundShutdown();
1312 void soundPause()
1314 systemSoundPause();
1317 void soundResume()
1319 systemSoundResume();
1322 void soundEnableChannels(int channels)
1324 int c = (channels & 0x0f) << 4;
1325 soundEnableFlag |= ((channels & 0x30f) | c);
1328 void soundDisableChannels(int channels)
1330 int c = (channels & 0x0f) << 4;
1331 soundEnableFlag &= ~((channels & 0x30f) | c);
1334 int soundGetEnabledChannels()
1336 return (soundEnableFlag & 0x30f);
1339 #if 0
1340 // unused
1341 void soundMuteChannels(int channels)
1343 soundMutedFlag |= channels & 0x30f;
1346 void soundUnmuteChannels(int channels)
1348 soundMutedFlag &= ~(channels & 0x30f);
1351 int soundGetMutedChannels()
1353 return (soundMutedFlag & 0x30f);
1355 #endif
1357 void soundReset()
1359 systemSoundReset();
1361 soundPaused = 1;
1362 soundPlay = 0;
1363 SOUND_CLOCK_TICKS = soundQuality * USE_TICKS_AS;
1364 soundTicks = SOUND_CLOCK_TICKS;
1365 soundNextPosition = 0;
1366 soundMasterOn = 1;
1367 soundIndex = 0;
1368 soundBufferIndex = 0;
1369 soundLevel1 = 7;
1370 soundLevel2 = 7;
1372 sound1On = 0;
1373 sound1ATL = 0;
1374 sound1Skip = 0;
1375 sound1Index = 0;
1376 sound1Continue = 0;
1377 sound1EnvelopeVolume = 0;
1378 sound1EnvelopeATL = 0;
1379 sound1EnvelopeUpDown = 0;
1380 sound1EnvelopeATLReload = 0;
1381 sound1SweepATL = 0;
1382 sound1SweepATLReload = 0;
1383 sound1SweepSteps = 0;
1384 sound1SweepUpDown = 0;
1385 sound1SweepStep = 0;
1386 sound1Wave = soundWavePattern[2];
1388 sound2On = 0;
1389 sound2ATL = 0;
1390 sound2Skip = 0;
1391 sound2Index = 0;
1392 sound2Continue = 0;
1393 sound2EnvelopeVolume = 0;
1394 sound2EnvelopeATL = 0;
1395 sound2EnvelopeUpDown = 0;
1396 sound2EnvelopeATLReload = 0;
1397 sound2Wave = soundWavePattern[2];
1399 sound3On = 0;
1400 sound3ATL = 0;
1401 sound3Skip = 0;
1402 sound3Index = 0;
1403 sound3Continue = 0;
1404 sound3OutputLevel = 0;
1405 sound3Last = 0;
1406 sound3Bank = 0;
1407 sound3DataSize = 0;
1408 sound3ForcedOutput = 0;
1410 sound4On = 0;
1411 sound4Clock = 0;
1412 sound4ATL = 0;
1413 sound4Skip = 0;
1414 sound4Index = 0;
1415 sound4ShiftRight = 0x7f;
1416 sound4NSteps = 0;
1417 sound4CountDown = 0;
1418 sound4Continue = 0;
1419 sound4EnvelopeVolume = 0;
1420 sound4EnvelopeATL = 0;
1421 sound4EnvelopeUpDown = 0;
1422 sound4EnvelopeATLReload = 0;
1424 sound1On = 0;
1425 sound2On = 0;
1426 sound3On = 0;
1427 sound4On = 0;
1429 int addr = 0x90;
1431 while (addr < 0xA0)
1433 ioMem[addr++] = 0x00;
1434 ioMem[addr++] = 0xff;
1437 addr = 0;
1438 while (addr < 0x20)
1440 sound3WaveRam[addr++] = 0x00;
1441 sound3WaveRam[addr++] = 0xff;
1444 memset(soundFinalWave, 0, soundBufferLen);
1446 memset(soundFilter, 0, sizeof(soundFilter));
1447 soundEchoIndex = 0;
1450 bool soundInit()
1452 if (systemSoundInit())
1454 memset(soundBuffer[0], 0, 735 * 2);
1455 memset(soundBuffer[1], 0, 735 * 2);
1456 memset(soundBuffer[2], 0, 735 * 2);
1457 memset(soundBuffer[3], 0, 735 * 2);
1459 memset(soundFinalWave, 0, soundBufferLen);
1461 soundPaused = 1;
1462 return true;
1464 return false;
1467 void soundSetQuality(int quality)
1469 if (soundQuality != quality && systemSoundCanChangeQuality())
1471 if (!soundOffFlag)
1472 soundShutdown();
1473 soundQuality = quality;
1474 soundNextPosition = 0;
1475 if (!soundOffFlag)
1476 soundInit();
1477 SOUND_CLOCK_TICKS = USE_TICKS_AS * soundQuality;
1478 soundIndex = 0;
1479 soundBufferIndex = 0;
1481 else if (soundQuality != quality)
1483 soundNextPosition = 0;
1484 SOUND_CLOCK_TICKS = USE_TICKS_AS * soundQuality;
1485 soundIndex = 0;
1486 soundBufferIndex = 0;
1490 void soundSaveGame(gzFile gzFile)
1492 soundTicks_int32 = (int32) soundTicks;
1493 SOUND_CLOCK_TICKS_int32 = (int32) SOUND_CLOCK_TICKS;
1494 soundDSBValue_int32 = (int32) soundDSBValue;
1496 utilWriteData(gzFile, soundSaveStruct);
1497 utilWriteData(gzFile, soundSaveStructV2);
1499 utilGzWrite(gzFile, &soundQuality, sizeof(int32));
1500 //utilWriteData(gzFile, soundSaveStructV3);
1503 void soundReadGame(gzFile gzFile, int version)
1505 int32 oldSoundPaused = soundPaused;
1506 int32 oldSoundEnableFlag = soundEnableFlag;
1507 utilReadData(gzFile, soundSaveStruct);
1508 soundPaused = oldSoundPaused;
1509 soundEnableFlag = oldSoundEnableFlag;
1511 if (version >= SAVE_GAME_VERSION_3)
1513 utilReadData(gzFile, soundSaveStructV2);
1515 else
1517 sound3Bank = (ioMem[NR30] >> 6) & 1;
1518 sound3DataSize = (ioMem[NR30] >> 5) & 1;
1519 sound3ForcedOutput = (ioMem[NR32] >> 7) & 1;
1520 // nothing better to do here...
1521 memcpy(&sound3WaveRam[0x00], &ioMem[0x90], 0x10);
1522 memcpy(&sound3WaveRam[0x10], &ioMem[0x90], 0x10);
1524 soundBufferIndex = soundIndex * 2;
1526 int quality = 1;
1527 utilGzRead(gzFile, &quality, sizeof(int32));
1528 soundSetQuality(quality);
1530 sound1Wave = soundWavePattern[ioMem[NR11] >> 6];
1531 sound2Wave = soundWavePattern[ioMem[NR21] >> 6];
1533 //if(version >= SAVE_GAME_VERSION_14) {
1534 // utilReadData(gzFile, soundSaveStructV3);
1535 //}
1536 //else {
1537 soundTicks = (soundtick_t) soundTicks_int32;
1538 SOUND_CLOCK_TICKS = (soundtick_t) SOUND_CLOCK_TICKS_int32;
1539 //}
1540 soundDSBValue = (u8) (soundDSBValue_int32 & 0xff);