Mercurial > vba-clojure
diff src/gb/gbSound.cpp @ 17:75e5bb1e0aa1
going to now integrate the gb src tree since it has no dependencies
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 11:44:47 -0600 |
parents | f9f4f1b99eed |
children | 7ef5c73ea8fa |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/gb/gbSound.cpp Sat Mar 03 11:44:47 2012 -0600 1.3 @@ -0,0 +1,1139 @@ 1.4 +#ifdef WIN32 1.5 +# include "../win32/stdafx.h" 1.6 +# include "../win32/VBA.h" 1.7 +#endif 1.8 + 1.9 +#include <cstring> 1.10 +#include <cassert> 1.11 + 1.12 +#include "../common/System.h" 1.13 +#include "../common/Util.h" 1.14 +//#include "../Blip_Buffer.h" 1.15 +#include "gbGlobals.h" 1.16 +#include "gbSound.h" 1.17 + 1.18 +#ifndef countof 1.19 +#define countof(a) (sizeof(a) / sizeof(a[0])) 1.20 +#endif 1.21 + 1.22 +extern u8 soundBuffer[6][735]; 1.23 +extern u16 soundFinalWave[1470]; 1.24 +extern u16 soundFrameSound[735 * 30 * 2]; 1.25 +extern int32 soundVolume; 1.26 + 1.27 +soundtick_t GB_USE_TICKS_AS = 24; // (1048576.0/44100.0); // FIXME: (4194304.0/70224.0)(fps) vs 60.0fps? 1.28 + 1.29 +#define SOUND_MAGIC 0x60000000 1.30 +#define SOUND_MAGIC_2 0x30000000 1.31 +#define NOISE_MAGIC (2097152.0 / 44100.0) 1.32 + 1.33 +extern int32 speed; 1.34 + 1.35 +extern u8 soundWavePattern[4][32]; 1.36 + 1.37 +extern u32 soundBufferLen; 1.38 +extern u32 soundBufferTotalLen; 1.39 +extern int32 soundQuality; 1.40 +extern int32 soundPaused; 1.41 +extern int32 soundPlay; 1.42 +extern soundtick_t soundTicks; 1.43 +extern soundtick_t SOUND_CLOCK_TICKS; 1.44 +extern u32 soundNextPosition; 1.45 + 1.46 +extern int32 soundLevel1; 1.47 +extern int32 soundLevel2; 1.48 +extern int32 soundBalance; 1.49 +extern int32 soundMasterOn; 1.50 +extern u32 soundIndex; 1.51 +extern u32 soundBufferIndex; 1.52 +extern int32 soundFrameSoundWritten; 1.53 +int32 soundVIN = 0; 1.54 +extern int32 soundDebug; 1.55 + 1.56 +extern int32 sound1On; 1.57 +extern int32 sound1ATL; 1.58 +extern int32 sound1Skip; 1.59 +extern int32 sound1Index; 1.60 +extern int32 sound1Continue; 1.61 +extern int32 sound1EnvelopeVolume; 1.62 +extern int32 sound1EnvelopeATL; 1.63 +extern int32 sound1EnvelopeUpDown; 1.64 +extern int32 sound1EnvelopeATLReload; 1.65 +extern int32 sound1SweepATL; 1.66 +extern int32 sound1SweepATLReload; 1.67 +extern int32 sound1SweepSteps; 1.68 +extern int32 sound1SweepUpDown; 1.69 +extern int32 sound1SweepStep; 1.70 +extern u8 * sound1Wave; 1.71 + 1.72 +extern int32 sound2On; 1.73 +extern int32 sound2ATL; 1.74 +extern int32 sound2Skip; 1.75 +extern int32 sound2Index; 1.76 +extern int32 sound2Continue; 1.77 +extern int32 sound2EnvelopeVolume; 1.78 +extern int32 sound2EnvelopeATL; 1.79 +extern int32 sound2EnvelopeUpDown; 1.80 +extern int32 sound2EnvelopeATLReload; 1.81 +extern u8 * sound2Wave; 1.82 + 1.83 +extern int32 sound3On; 1.84 +extern int32 sound3ATL; 1.85 +extern int32 sound3Skip; 1.86 +extern int32 sound3Index; 1.87 +extern int32 sound3Continue; 1.88 +extern int32 sound3OutputLevel; 1.89 +extern int32 sound3Last; 1.90 + 1.91 +extern int32 sound4On; 1.92 +extern int32 sound4Clock; 1.93 +extern int32 sound4ATL; 1.94 +extern int32 sound4Skip; 1.95 +extern int32 sound4Index; 1.96 +extern int32 sound4ShiftRight; 1.97 +extern int32 sound4ShiftSkip; 1.98 +extern int32 sound4ShiftIndex; 1.99 +extern int32 sound4NSteps; 1.100 +extern int32 sound4CountDown; 1.101 +extern int32 sound4Continue; 1.102 +extern int32 sound4EnvelopeVolume; 1.103 +extern int32 sound4EnvelopeATL; 1.104 +extern int32 sound4EnvelopeUpDown; 1.105 +extern int32 sound4EnvelopeATLReload; 1.106 + 1.107 +extern int32 soundEnableFlag; 1.108 +extern int32 soundMutedFlag; 1.109 + 1.110 +extern int32 soundFreqRatio[8]; 1.111 +extern int32 soundShiftClock[16]; 1.112 + 1.113 +extern s16 soundFilter[4000]; 1.114 +extern s16 soundLeft[5]; 1.115 +extern s16 soundRight[5]; 1.116 +extern int32 soundEchoIndex; 1.117 +extern bool8 soundEcho; 1.118 +extern bool8 soundLowPass; 1.119 +extern bool8 soundReverse; 1.120 +extern bool8 soundOffFlag; 1.121 + 1.122 +bool8 gbDigitalSound = false; 1.123 + 1.124 +void gbSoundEvent(register u16 address, register int data) 1.125 +{ 1.126 + int freq = 0; 1.127 + 1.128 + gbMemory[address] = data; 1.129 + 1.130 +#ifndef FINAL_VERSION 1.131 + if (soundDebug) 1.132 + { 1.133 + // don't translate. debug only 1.134 + log("Sound event: %08lx %02x\n", address, data); 1.135 + } 1.136 +#endif 1.137 + switch (address) 1.138 + { 1.139 + case NR10: 1.140 + sound1SweepATL = sound1SweepATLReload = 344 * ((data >> 4) & 7); 1.141 + sound1SweepSteps = data & 7; 1.142 + sound1SweepUpDown = data & 0x08; 1.143 + sound1SweepStep = 0; 1.144 + break; 1.145 + case NR11: 1.146 + sound1Wave = soundWavePattern[data >> 6]; 1.147 + sound1ATL = 172 * (64 - (data & 0x3f)); 1.148 + break; 1.149 + case NR12: 1.150 + sound1EnvelopeVolume = data >> 4; 1.151 + sound1EnvelopeUpDown = data & 0x08; 1.152 + sound1EnvelopeATLReload = sound1EnvelopeATL = 689 * (data & 7); 1.153 + break; 1.154 + case NR13: 1.155 + freq = (((int)(gbMemory[NR14] & 7)) << 8) | data; 1.156 + sound1ATL = 172 * (64 - (gbMemory[NR11] & 0x3f)); 1.157 + freq = 2048 - freq; 1.158 + if (freq) 1.159 + { 1.160 + sound1Skip = SOUND_MAGIC / freq; 1.161 + } 1.162 + else 1.163 + sound1Skip = 0; 1.164 + break; 1.165 + case NR14: 1.166 + freq = (((int)(data & 7) << 8) | gbMemory[NR13]); 1.167 + freq = 2048 - freq; 1.168 + sound1ATL = 172 * (64 - (gbMemory[NR11] & 0x3f)); 1.169 + sound1Continue = data & 0x40; 1.170 + if (freq) 1.171 + { 1.172 + sound1Skip = SOUND_MAGIC / freq; 1.173 + } 1.174 + else 1.175 + sound1Skip = 0; 1.176 + if (data & 0x80) 1.177 + { 1.178 + gbMemory[NR52] |= 1; 1.179 + sound1EnvelopeVolume = gbMemory[NR12] >> 4; 1.180 + sound1EnvelopeUpDown = gbMemory[NR12] & 0x08; 1.181 + sound1ATL = 172 * (64 - (gbMemory[NR11] & 0x3f)); 1.182 + sound1EnvelopeATLReload = sound1EnvelopeATL = 689 * (gbMemory[NR12] & 7); 1.183 + sound1SweepATL = sound1SweepATLReload = 344 * ((gbMemory[NR10] >> 4) & 7); 1.184 + sound1SweepSteps = gbMemory[NR10] & 7; 1.185 + sound1SweepUpDown = gbMemory[NR10] & 0x08; 1.186 + sound1SweepStep = 0; 1.187 + 1.188 + sound1Index = 0; 1.189 + sound1On = 1; 1.190 + } 1.191 + break; 1.192 + case NR21: 1.193 + sound2Wave = soundWavePattern[data >> 6]; 1.194 + sound2ATL = 172 * (64 - (data & 0x3f)); 1.195 + break; 1.196 + case NR22: 1.197 + sound2EnvelopeVolume = data >> 4; 1.198 + sound2EnvelopeUpDown = data & 0x08; 1.199 + sound2EnvelopeATLReload = sound2EnvelopeATL = 689 * (data & 7); 1.200 + break; 1.201 + case NR23: 1.202 + freq = (((int)(gbMemory[NR24] & 7)) << 8) | data; 1.203 + sound2ATL = 172 * (64 - (gbMemory[NR21] & 0x3f)); 1.204 + freq = 2048 - freq; 1.205 + if (freq) 1.206 + { 1.207 + sound2Skip = SOUND_MAGIC / freq; 1.208 + } 1.209 + else 1.210 + sound2Skip = 0; 1.211 + break; 1.212 + case NR24: 1.213 + freq = (((int)(data & 7) << 8) | gbMemory[NR23]); 1.214 + freq = 2048 - freq; 1.215 + sound2ATL = 172 * (64 - (gbMemory[NR21] & 0x3f)); 1.216 + sound2Continue = data & 0x40; 1.217 + if (freq) 1.218 + { 1.219 + sound2Skip = SOUND_MAGIC / freq; 1.220 + } 1.221 + else 1.222 + sound2Skip = 0; 1.223 + if (data & 0x80) 1.224 + { 1.225 + gbMemory[NR52] |= 2; 1.226 + sound2EnvelopeVolume = gbMemory[NR22] >> 4; 1.227 + sound2EnvelopeUpDown = gbMemory[NR22] & 0x08; 1.228 + sound2ATL = 172 * (64 - (gbMemory[NR21] & 0x3f)); 1.229 + sound2EnvelopeATLReload = sound2EnvelopeATL = 689 * (gbMemory[NR22] & 7); 1.230 + 1.231 + sound2Index = 0; 1.232 + sound2On = 1; 1.233 + } 1.234 + break; 1.235 + case NR30: 1.236 + if (!(data & 0x80)) 1.237 + { 1.238 + gbMemory[NR52] &= 0xfb; 1.239 + sound3On = 0; 1.240 + } 1.241 + break; 1.242 + case NR31: 1.243 + sound3ATL = 172 * (256 - data); 1.244 + break; 1.245 + case NR32: 1.246 + sound3OutputLevel = (data >> 5) & 3; 1.247 + break; 1.248 + case NR33: 1.249 + freq = 2048 - (((int)(gbMemory[NR34] & 7) << 8) | data); 1.250 + if (freq) 1.251 + { 1.252 + sound3Skip = SOUND_MAGIC_2 / freq; 1.253 + } 1.254 + else 1.255 + sound3Skip = 0; 1.256 + break; 1.257 + case NR34: 1.258 + freq = 2048 - (((data & 7) << 8) | (int)gbMemory[NR33]); 1.259 + if (freq) 1.260 + { 1.261 + sound3Skip = SOUND_MAGIC_2 / freq; 1.262 + } 1.263 + else 1.264 + { 1.265 + sound3Skip = 0; 1.266 + } 1.267 + sound3Continue = data & 0x40; 1.268 + if ((data & 0x80) && (gbMemory[NR30] & 0x80)) 1.269 + { 1.270 + gbMemory[NR52] |= 4; 1.271 + sound3ATL = 172 * (256 - gbMemory[NR31]); 1.272 + sound3Index = 0; 1.273 + sound3On = 1; 1.274 + } 1.275 + break; 1.276 + case NR41: 1.277 + sound4ATL = 172 * (64 - (data & 0x3f)); 1.278 + break; 1.279 + case NR42: 1.280 + sound4EnvelopeVolume = data >> 4; 1.281 + sound4EnvelopeUpDown = data & 0x08; 1.282 + sound4EnvelopeATLReload = sound4EnvelopeATL = 689 * (data & 7); 1.283 + break; 1.284 + case NR43: 1.285 + freq = soundFreqRatio[data & 7]; 1.286 + sound4NSteps = data & 0x08; 1.287 + 1.288 + sound4Skip = freq * NOISE_MAGIC; 1.289 + 1.290 + sound4Clock = data >> 4; 1.291 + 1.292 + freq = freq / soundShiftClock[sound4Clock]; 1.293 + 1.294 + sound4ShiftSkip = freq * NOISE_MAGIC; 1.295 + 1.296 + break; 1.297 + case NR44: 1.298 + sound4Continue = data & 0x40; 1.299 + if (data & 0x80) 1.300 + { 1.301 + gbMemory[NR52] |= 8; 1.302 + sound4EnvelopeVolume = gbMemory[NR42] >> 4; 1.303 + sound4EnvelopeUpDown = gbMemory[NR42] & 0x08; 1.304 + sound4ATL = 172 * (64 - (gbMemory[NR41] & 0x3f)); 1.305 + sound4EnvelopeATLReload = sound4EnvelopeATL = 689 * (gbMemory[NR42] & 7); 1.306 + 1.307 + sound4On = 1; 1.308 + 1.309 + sound4Index = 0; 1.310 + sound4ShiftIndex = 0; 1.311 + 1.312 + freq = soundFreqRatio[gbMemory[NR43] & 7]; 1.313 + 1.314 + sound4Skip = freq * NOISE_MAGIC; 1.315 + 1.316 + sound4NSteps = gbMemory[NR43] & 0x08; 1.317 + 1.318 + freq = freq / soundShiftClock[gbMemory[NR43] >> 4]; 1.319 + 1.320 + sound4ShiftSkip = freq * NOISE_MAGIC; 1.321 + if (sound4NSteps) 1.322 + sound4ShiftRight = 0x7f; 1.323 + else 1.324 + sound4ShiftRight = 0x7fff; 1.325 + } 1.326 + break; 1.327 + case NR50: 1.328 + soundVIN = data & 0x88; 1.329 + soundLevel1 = data & 7; 1.330 + soundLevel2 = (data >> 4) & 7; 1.331 + break; 1.332 + case NR51: 1.333 + soundBalance = (data & soundEnableFlag); 1.334 + gbMemory[address] = data; 1.335 + break; 1.336 + case NR52: 1.337 + soundMasterOn = data & 0x80; 1.338 + if (!(data & 0x80)) 1.339 + { 1.340 + sound1On = 0; 1.341 + sound2On = 0; 1.342 + sound3On = 0; 1.343 + sound4On = 0; 1.344 + } 1.345 + break; 1.346 + } 1.347 + 1.348 + gbDigitalSound = true; 1.349 + 1.350 + if (sound1On && sound1EnvelopeVolume != 0) 1.351 + gbDigitalSound = false; 1.352 + if (sound2On && sound2EnvelopeVolume != 0) 1.353 + gbDigitalSound = false; 1.354 + if (sound3On && sound3OutputLevel != 0) 1.355 + gbDigitalSound = false; 1.356 + if (sound4On && sound4EnvelopeVolume != 0) 1.357 + gbDigitalSound = false; 1.358 +} 1.359 + 1.360 +void gbSoundChannel1() 1.361 +{ 1.362 + int vol = sound1EnvelopeVolume; 1.363 + 1.364 + int freq = 0; 1.365 + 1.366 + int value = 0; 1.367 + 1.368 + if (sound1On && (sound1ATL || !sound1Continue)) 1.369 + { 1.370 + sound1Index += soundQuality * sound1Skip; 1.371 + sound1Index &= 0x1fffffff; 1.372 + 1.373 + value = ((s8)sound1Wave[sound1Index >> 24]) * vol; 1.374 + } 1.375 + 1.376 + soundBuffer[0][soundIndex] = value; 1.377 + 1.378 + if (sound1On) 1.379 + { 1.380 + if (sound1ATL) 1.381 + { 1.382 + sound1ATL -= soundQuality; 1.383 + 1.384 + if (sound1ATL <= 0 && sound1Continue) 1.385 + { 1.386 + gbMemory[NR52] &= 0xfe; 1.387 + sound1On = 0; 1.388 + } 1.389 + } 1.390 + 1.391 + if (sound1EnvelopeATL) 1.392 + { 1.393 + sound1EnvelopeATL -= soundQuality; 1.394 + 1.395 + if (sound1EnvelopeATL <= 0) 1.396 + { 1.397 + if (sound1EnvelopeUpDown) 1.398 + { 1.399 + if (sound1EnvelopeVolume < 15) 1.400 + sound1EnvelopeVolume++; 1.401 + } 1.402 + else 1.403 + { 1.404 + if (sound1EnvelopeVolume) 1.405 + sound1EnvelopeVolume--; 1.406 + } 1.407 + 1.408 + sound1EnvelopeATL += sound1EnvelopeATLReload; 1.409 + } 1.410 + } 1.411 + 1.412 + if (sound1SweepATL) 1.413 + { 1.414 + sound1SweepATL -= soundQuality; 1.415 + 1.416 + if (sound1SweepATL <= 0) 1.417 + { 1.418 + freq = (((int)(gbMemory[NR14] & 7) << 8) | gbMemory[NR13]); 1.419 + 1.420 + int updown = 1; 1.421 + 1.422 + if (sound1SweepUpDown) 1.423 + updown = -1; 1.424 + 1.425 + int newfreq = 0; 1.426 + if (sound1SweepSteps) 1.427 + { 1.428 + newfreq = freq + updown * freq / (1 << sound1SweepSteps); 1.429 + if (newfreq == freq) 1.430 + newfreq = 0; 1.431 + } 1.432 + else 1.433 + newfreq = freq; 1.434 + 1.435 + if (newfreq < 0) 1.436 + { 1.437 + sound1SweepATL += sound1SweepATLReload; 1.438 + } 1.439 + else if (newfreq > 2047) 1.440 + { 1.441 + sound1SweepATL = 0; 1.442 + sound1On = 0; 1.443 + gbMemory[NR52] &= 0xfe; 1.444 + } 1.445 + else 1.446 + { 1.447 + sound1SweepATL += sound1SweepATLReload; 1.448 + sound1Skip = SOUND_MAGIC / (2048 - newfreq); 1.449 + 1.450 + gbMemory[NR13] = newfreq & 0xff; 1.451 + gbMemory[NR14] = (gbMemory[NR14] & 0xf8) | ((newfreq >> 8) & 7); 1.452 + } 1.453 + } 1.454 + } 1.455 + } 1.456 +} 1.457 + 1.458 +void gbSoundChannel2() 1.459 +{ 1.460 + // int freq = 0; 1.461 + int vol = sound2EnvelopeVolume; 1.462 + 1.463 + int value = 0; 1.464 + 1.465 + if (sound2On && (sound2ATL || !sound2Continue)) 1.466 + { 1.467 + sound2Index += soundQuality * sound2Skip; 1.468 + sound2Index &= 0x1fffffff; 1.469 + 1.470 + value = ((s8)sound2Wave[sound2Index >> 24]) * vol; 1.471 + } 1.472 + 1.473 + soundBuffer[1][soundIndex] = value; 1.474 + 1.475 + if (sound2On) 1.476 + { 1.477 + if (sound2ATL) 1.478 + { 1.479 + sound2ATL -= soundQuality; 1.480 + 1.481 + if (sound2ATL <= 0 && sound2Continue) 1.482 + { 1.483 + gbMemory[NR52] &= 0xfd; 1.484 + sound2On = 0; 1.485 + } 1.486 + } 1.487 + 1.488 + if (sound2EnvelopeATL) 1.489 + { 1.490 + sound2EnvelopeATL -= soundQuality; 1.491 + 1.492 + if (sound2EnvelopeATL <= 0) 1.493 + { 1.494 + if (sound2EnvelopeUpDown) 1.495 + { 1.496 + if (sound2EnvelopeVolume < 15) 1.497 + sound2EnvelopeVolume++; 1.498 + } 1.499 + else 1.500 + { 1.501 + if (sound2EnvelopeVolume) 1.502 + sound2EnvelopeVolume--; 1.503 + } 1.504 + sound2EnvelopeATL += sound2EnvelopeATLReload; 1.505 + } 1.506 + } 1.507 + } 1.508 +} 1.509 + 1.510 +void gbSoundChannel3() 1.511 +{ 1.512 + int value = sound3Last; 1.513 + 1.514 + if (sound3On && (sound3ATL || !sound3Continue)) 1.515 + { 1.516 + sound3Index += soundQuality * sound3Skip; 1.517 + sound3Index &= 0x1fffffff; 1.518 + 1.519 + value = gbMemory[0xff30 + (sound3Index >> 25)]; 1.520 + 1.521 + if ((sound3Index & 0x01000000)) 1.522 + { 1.523 + value &= 0x0f; 1.524 + } 1.525 + else 1.526 + { 1.527 + value >>= 4; 1.528 + } 1.529 + 1.530 + value -= 8; 1.531 + value *= 2; 1.532 + 1.533 + switch (sound3OutputLevel) 1.534 + { 1.535 + case 0: 1.536 + value = 0; 1.537 + break; 1.538 + case 1: 1.539 + break; 1.540 + case 2: 1.541 + value = (value >> 1); 1.542 + break; 1.543 + case 3: 1.544 + value = (value >> 2); 1.545 + break; 1.546 + } 1.547 + //value += 1; 1.548 + sound3Last = value; 1.549 + } 1.550 + 1.551 + soundBuffer[2][soundIndex] = value; 1.552 + 1.553 + if (sound3On) 1.554 + { 1.555 + if (sound3ATL) 1.556 + { 1.557 + sound3ATL -= soundQuality; 1.558 + 1.559 + if (sound3ATL <= 0 && sound3Continue) 1.560 + { 1.561 + gbMemory[NR52] &= 0xfb; 1.562 + sound3On = 0; 1.563 + } 1.564 + } 1.565 + } 1.566 +} 1.567 + 1.568 +void gbSoundChannel4() 1.569 +{ 1.570 + int vol = sound4EnvelopeVolume; 1.571 + 1.572 + int value = 0; 1.573 + 1.574 + if (sound4Clock <= 0x0c) 1.575 + { 1.576 + if (sound4On && (sound4ATL || !sound4Continue)) 1.577 + { 1.578 + #define NOISE_ONE_SAMP_SCALE 0x200000 1.579 + 1.580 + sound4Index += soundQuality * sound4Skip; 1.581 + sound4ShiftIndex += soundQuality * sound4ShiftSkip; 1.582 + 1.583 + if (sound4NSteps) 1.584 + { 1.585 + while (sound4ShiftIndex >= NOISE_ONE_SAMP_SCALE) 1.586 + { 1.587 + sound4ShiftRight = (((sound4ShiftRight << 6) ^ 1.588 + (sound4ShiftRight << 5)) & 0x40) | 1.589 + (sound4ShiftRight >> 1); 1.590 + sound4ShiftIndex -= NOISE_ONE_SAMP_SCALE; 1.591 + } 1.592 + } 1.593 + else 1.594 + { 1.595 + while (sound4ShiftIndex >= NOISE_ONE_SAMP_SCALE) 1.596 + { 1.597 + sound4ShiftRight = (((sound4ShiftRight << 14) ^ 1.598 + (sound4ShiftRight << 13)) & 0x4000) | 1.599 + (sound4ShiftRight >> 1); 1.600 + 1.601 + sound4ShiftIndex -= NOISE_ONE_SAMP_SCALE; 1.602 + } 1.603 + } 1.604 + 1.605 + sound4Index %= NOISE_ONE_SAMP_SCALE; 1.606 + sound4ShiftIndex %= NOISE_ONE_SAMP_SCALE; 1.607 + 1.608 + value = ((sound4ShiftRight & 1) * 2 - 1) * vol; 1.609 + } 1.610 + else 1.611 + { 1.612 + value = 0; 1.613 + } 1.614 + } 1.615 + 1.616 + soundBuffer[3][soundIndex] = value; 1.617 + 1.618 + if (sound4On) 1.619 + { 1.620 + if (sound4ATL) 1.621 + { 1.622 + sound4ATL -= soundQuality; 1.623 + 1.624 + if (sound4ATL <= 0 && sound4Continue) 1.625 + { 1.626 + gbMemory[NR52] &= 0xfd; 1.627 + sound4On = 0; 1.628 + } 1.629 + } 1.630 + 1.631 + if (sound4EnvelopeATL) 1.632 + { 1.633 + sound4EnvelopeATL -= soundQuality; 1.634 + 1.635 + if (sound4EnvelopeATL <= 0) 1.636 + { 1.637 + if (sound4EnvelopeUpDown) 1.638 + { 1.639 + if (sound4EnvelopeVolume < 15) 1.640 + sound4EnvelopeVolume++; 1.641 + } 1.642 + else 1.643 + { 1.644 + if (sound4EnvelopeVolume) 1.645 + sound4EnvelopeVolume--; 1.646 + } 1.647 + sound4EnvelopeATL += sound4EnvelopeATLReload; 1.648 + } 1.649 + } 1.650 + } 1.651 +} 1.652 + 1.653 +void gbSoundMix() 1.654 +{ 1.655 + int res = 0; 1.656 + 1.657 + if (gbMemory) 1.658 + soundBalance = (gbMemory[NR51] & soundEnableFlag & ~soundMutedFlag); 1.659 + 1.660 + if (soundBalance & 16) 1.661 + { 1.662 + res += ((s8)soundBuffer[0][soundIndex]); 1.663 + } 1.664 + if (soundBalance & 32) 1.665 + { 1.666 + res += ((s8)soundBuffer[1][soundIndex]); 1.667 + } 1.668 + if (soundBalance & 64) 1.669 + { 1.670 + res += ((s8)soundBuffer[2][soundIndex]); 1.671 + } 1.672 + if (soundBalance & 128) 1.673 + { 1.674 + res += ((s8)soundBuffer[3][soundIndex]); 1.675 + } 1.676 + 1.677 + if (gbDigitalSound) 1.678 + res = soundLevel1 * 256; 1.679 + else 1.680 + res *= soundLevel1 * 60; 1.681 + 1.682 + if (soundEcho) 1.683 + { 1.684 + res *= 2; 1.685 + res += soundFilter[soundEchoIndex]; 1.686 + res /= 2; 1.687 + soundFilter[soundEchoIndex++] = res; 1.688 + } 1.689 + 1.690 + if (soundLowPass) 1.691 + { 1.692 + soundLeft[4] = soundLeft[3]; 1.693 + soundLeft[3] = soundLeft[2]; 1.694 + soundLeft[2] = soundLeft[1]; 1.695 + soundLeft[1] = soundLeft[0]; 1.696 + soundLeft[0] = res; 1.697 + res = (soundLeft[4] + 2 * soundLeft[3] + 8 * soundLeft[2] + 2 * soundLeft[1] + 1.698 + soundLeft[0]) / 14; 1.699 + } 1.700 + 1.701 + bool noSpecialEffects = false; 1.702 +#if (defined(WIN32) && !defined(SDL)) 1.703 + if (theApp.soundRecording || theApp.aviRecording || theApp.nvAudioLog) 1.704 + noSpecialEffects = true; 1.705 +#endif 1.706 + 1.707 + if (!noSpecialEffects) 1.708 + { 1.709 + switch (soundVolume) 1.710 + { 1.711 + case 0: 1.712 + case 1: 1.713 + case 2: 1.714 + case 3: 1.715 + res *= (soundVolume + 1); 1.716 + break; 1.717 + case 4: 1.718 + res >>= 2; 1.719 + break; 1.720 + case 5: 1.721 + res >>= 1; 1.722 + break; 1.723 + } 1.724 + } 1.725 + 1.726 + if (res > 32767) 1.727 + res = 32767; 1.728 + if (res < -32768) 1.729 + res = -32768; 1.730 + 1.731 + if (soundReverse && !noSpecialEffects) 1.732 + { 1.733 + soundFinalWave[++soundBufferIndex] = res; 1.734 + if ((soundFrameSoundWritten + 1) >= countof(soundFrameSound)) 1.735 + /*assert(false)*/; 1.736 + else 1.737 + soundFrameSound[++soundFrameSoundWritten] = res; 1.738 + } 1.739 + else 1.740 + { 1.741 + soundFinalWave[soundBufferIndex++] = res; 1.742 + if (soundFrameSoundWritten >= countof(soundFrameSound)) 1.743 + /*assert(false)*/; 1.744 + else 1.745 + soundFrameSound[soundFrameSoundWritten++] = res; 1.746 + } 1.747 + 1.748 + res = 0; 1.749 + 1.750 + if (soundBalance & 1) 1.751 + { 1.752 + res += ((s8)soundBuffer[0][soundIndex]); 1.753 + } 1.754 + if (soundBalance & 2) 1.755 + { 1.756 + res += ((s8)soundBuffer[1][soundIndex]); 1.757 + } 1.758 + if (soundBalance & 4) 1.759 + { 1.760 + res += ((s8)soundBuffer[2][soundIndex]); 1.761 + } 1.762 + if (soundBalance & 8) 1.763 + { 1.764 + res += ((s8)soundBuffer[3][soundIndex]); 1.765 + } 1.766 + 1.767 + if (gbDigitalSound) 1.768 + res = soundLevel2 * 256; 1.769 + else 1.770 + res *= soundLevel2 * 60; 1.771 + 1.772 + if (soundEcho) 1.773 + { 1.774 + res *= 2; 1.775 + res += soundFilter[soundEchoIndex]; 1.776 + res /= 2; 1.777 + soundFilter[soundEchoIndex++] = res; 1.778 + 1.779 + if (soundEchoIndex >= 4000) 1.780 + soundEchoIndex = 0; 1.781 + } 1.782 + 1.783 + if (soundLowPass) 1.784 + { 1.785 + soundRight[4] = soundRight[3]; 1.786 + soundRight[3] = soundRight[2]; 1.787 + soundRight[2] = soundRight[1]; 1.788 + soundRight[1] = soundRight[0]; 1.789 + soundRight[0] = res; 1.790 + res = (soundRight[4] + 2 * soundRight[3] + 8 * soundRight[2] + 2 * soundRight[1] + 1.791 + soundRight[0]) / 14; 1.792 + } 1.793 + 1.794 + if (!noSpecialEffects) 1.795 + { 1.796 + switch (soundVolume) 1.797 + { 1.798 + case 0: 1.799 + case 1: 1.800 + case 2: 1.801 + case 3: 1.802 + res *= (soundVolume + 1); 1.803 + break; 1.804 + case 4: 1.805 + res >>= 2; 1.806 + break; 1.807 + case 5: 1.808 + res >>= 1; 1.809 + break; 1.810 + } 1.811 + } 1.812 + 1.813 + if (res > 32767) 1.814 + res = 32767; 1.815 + if (res < -32768) 1.816 + res = -32768; 1.817 + 1.818 + if (soundReverse && !noSpecialEffects) 1.819 + { 1.820 + soundFinalWave[-1 + soundBufferIndex++] = res; 1.821 + if ((soundFrameSoundWritten) >= countof(soundFrameSound)) 1.822 + /*assert(false)*/; 1.823 + else 1.824 + soundFrameSound[-1 + soundFrameSoundWritten++] = res; 1.825 + } 1.826 + else 1.827 + { 1.828 + soundFinalWave[soundBufferIndex++] = res; 1.829 + if ((soundFrameSoundWritten + 1) >= countof(soundFrameSound)) 1.830 + /*assert(false)*/; 1.831 + else 1.832 + soundFrameSound[soundFrameSoundWritten++] = res; 1.833 + } 1.834 +} 1.835 + 1.836 +void gbSoundTick() 1.837 +{ 1.838 + if (systemSoundOn) 1.839 + { 1.840 + if (soundMasterOn) 1.841 + { 1.842 + gbSoundChannel1(); 1.843 + gbSoundChannel2(); 1.844 + gbSoundChannel3(); 1.845 + gbSoundChannel4(); 1.846 + 1.847 + gbSoundMix(); 1.848 + } 1.849 + else 1.850 + { 1.851 + soundFinalWave[soundBufferIndex++] = 0; 1.852 + soundFinalWave[soundBufferIndex++] = 0; 1.853 + if ((soundFrameSoundWritten + 1) >= countof(soundFrameSound)) 1.854 + /*assert(false)*/; 1.855 + else 1.856 + { 1.857 + soundFrameSound[soundFrameSoundWritten++] = 0; 1.858 + soundFrameSound[soundFrameSoundWritten++] = 0; 1.859 + } 1.860 + } 1.861 + 1.862 + soundIndex++; 1.863 + 1.864 + if (2 * soundBufferIndex >= soundBufferLen) 1.865 + { 1.866 + if (systemSoundOn) 1.867 + { 1.868 + if (soundPaused) 1.869 + { 1.870 + extern void soundResume(); 1.871 + soundResume(); 1.872 + } 1.873 + 1.874 + systemSoundWriteToBuffer(); 1.875 + } 1.876 + soundIndex = 0; 1.877 + soundBufferIndex = 0; 1.878 + } 1.879 + } 1.880 +} 1.881 + 1.882 +void gbSoundReset() 1.883 +{ 1.884 + soundPaused = 1; 1.885 + soundPlay = 0; 1.886 + SOUND_CLOCK_TICKS = soundQuality * GB_USE_TICKS_AS; 1.887 +// soundTicks = SOUND_CLOCK_TICKS; 1.888 + soundTicks = 0; 1.889 + soundNextPosition = 0; 1.890 + soundMasterOn = 1; 1.891 + soundIndex = 0; 1.892 + soundBufferIndex = 0; 1.893 + soundLevel1 = 7; 1.894 + soundLevel2 = 7; 1.895 + soundVIN = 0; 1.896 + 1.897 + sound1On = 0; 1.898 + sound1ATL = 0; 1.899 + sound1Skip = 0; 1.900 + sound1Index = 0; 1.901 + sound1Continue = 0; 1.902 + sound1EnvelopeVolume = 0; 1.903 + sound1EnvelopeATL = 0; 1.904 + sound1EnvelopeUpDown = 0; 1.905 + sound1EnvelopeATLReload = 0; 1.906 + sound1SweepATL = 0; 1.907 + sound1SweepATLReload = 0; 1.908 + sound1SweepSteps = 0; 1.909 + sound1SweepUpDown = 0; 1.910 + sound1SweepStep = 0; 1.911 + sound1Wave = soundWavePattern[2]; 1.912 + 1.913 + sound2On = 0; 1.914 + sound2ATL = 0; 1.915 + sound2Skip = 0; 1.916 + sound2Index = 0; 1.917 + sound2Continue = 0; 1.918 + sound2EnvelopeVolume = 0; 1.919 + sound2EnvelopeATL = 0; 1.920 + sound2EnvelopeUpDown = 0; 1.921 + sound2EnvelopeATLReload = 0; 1.922 + sound2Wave = soundWavePattern[2]; 1.923 + 1.924 + sound3On = 0; 1.925 + sound3ATL = 0; 1.926 + sound3Skip = 0; 1.927 + sound3Index = 0; 1.928 + sound3Continue = 0; 1.929 + sound3OutputLevel = 0; 1.930 + 1.931 + sound4On = 0; 1.932 + sound4Clock = 0; 1.933 + sound4ATL = 0; 1.934 + sound4Skip = 0; 1.935 + sound4Index = 0; 1.936 + sound4ShiftRight = 0x7f; 1.937 + sound4NSteps = 0; 1.938 + sound4CountDown = 0; 1.939 + sound4Continue = 0; 1.940 + sound4EnvelopeVolume = 0; 1.941 + sound4EnvelopeATL = 0; 1.942 + sound4EnvelopeUpDown = 0; 1.943 + sound4EnvelopeATLReload = 0; 1.944 + 1.945 + // don't translate 1.946 + if (soundDebug) 1.947 + { 1.948 + log("*** Sound Init ***\n"); 1.949 + } 1.950 + 1.951 + gbSoundEvent(0xff10, 0x80); 1.952 + gbSoundEvent(0xff11, 0xbf); 1.953 + gbSoundEvent(0xff12, 0xf3); 1.954 + gbSoundEvent(0xff14, 0xbf); 1.955 + gbSoundEvent(0xff16, 0x3f); 1.956 + gbSoundEvent(0xff17, 0x00); 1.957 + gbSoundEvent(0xff19, 0xbf); 1.958 + 1.959 + gbSoundEvent(0xff1a, 0x7f); 1.960 + gbSoundEvent(0xff1b, 0xff); 1.961 + gbSoundEvent(0xff1c, 0xbf); 1.962 + gbSoundEvent(0xff1e, 0xbf); 1.963 + 1.964 + gbSoundEvent(0xff20, 0xff); 1.965 + gbSoundEvent(0xff21, 0x00); 1.966 + gbSoundEvent(0xff22, 0x00); 1.967 + gbSoundEvent(0xff23, 0xbf); 1.968 + gbSoundEvent(0xff24, 0x77); 1.969 + gbSoundEvent(0xff25, 0xf3); 1.970 + 1.971 + gbSoundEvent(0xff26, 0xf0); 1.972 + 1.973 + // don't translate 1.974 + if (soundDebug) 1.975 + { 1.976 + log("*** Sound Init Complete ***\n"); 1.977 + } 1.978 + 1.979 + sound1On = 0; 1.980 + sound2On = 0; 1.981 + sound3On = 0; 1.982 + sound4On = 0; 1.983 + 1.984 + int addr = 0xff30; 1.985 + 1.986 + while (addr < 0xff40) 1.987 + { 1.988 + gbMemory[addr++] = 0x00; 1.989 + gbMemory[addr++] = 0xff; 1.990 + } 1.991 + 1.992 + memset(soundFinalWave, 0x00, soundBufferLen); 1.993 + 1.994 + memset(soundFilter, 0, sizeof(soundFilter)); 1.995 + soundEchoIndex = 0; 1.996 +} 1.997 + 1.998 +extern bool soundInit(); 1.999 +extern void soundShutdown(); 1.1000 + 1.1001 +void gbSoundSetQuality(int quality) 1.1002 +{ 1.1003 + if (soundQuality != quality && systemSoundCanChangeQuality()) 1.1004 + { 1.1005 + if (!soundOffFlag) 1.1006 + soundShutdown(); 1.1007 + soundQuality = quality; 1.1008 + soundNextPosition = 0; 1.1009 + if (!soundOffFlag) 1.1010 + soundInit(); 1.1011 + SOUND_CLOCK_TICKS = (gbSpeed ? 2 : 1) * GB_USE_TICKS_AS * soundQuality; 1.1012 + soundIndex = 0; 1.1013 + soundBufferIndex = 0; 1.1014 + } 1.1015 + else 1.1016 + { 1.1017 + soundNextPosition = 0; 1.1018 + SOUND_CLOCK_TICKS = (gbSpeed ? 2 : 1) * GB_USE_TICKS_AS * soundQuality; 1.1019 + soundIndex = 0; 1.1020 + soundBufferIndex = 0; 1.1021 + } 1.1022 +} 1.1023 + 1.1024 +static int32 soundTicks_int32; 1.1025 +static int32 SOUND_CLOCK_TICKS_int32; 1.1026 +variable_desc gbSoundSaveStruct[] = { 1.1027 + { &soundPaused, sizeof(int32) }, 1.1028 + { &soundPlay, sizeof(int32) }, 1.1029 + { &soundTicks_int32, sizeof(int32) }, 1.1030 + { &SOUND_CLOCK_TICKS_int32, sizeof(int32) }, 1.1031 + { &soundLevel1, sizeof(int32) }, 1.1032 + { &soundLevel2, sizeof(int32) }, 1.1033 + { &soundBalance, sizeof(int32) }, 1.1034 + { &soundMasterOn, sizeof(int32) }, 1.1035 + { &soundIndex, sizeof(int32) }, 1.1036 + { &soundVIN, sizeof(int32) }, 1.1037 + { &sound1On, sizeof(int32) }, 1.1038 + { &sound1ATL, sizeof(int32) }, 1.1039 + { &sound1Skip, sizeof(int32) }, 1.1040 + { &sound1Index, sizeof(int32) }, 1.1041 + { &sound1Continue, sizeof(int32) }, 1.1042 + { &sound1EnvelopeVolume, sizeof(int32) }, 1.1043 + { &sound1EnvelopeATL, sizeof(int32) }, 1.1044 + { &sound1EnvelopeATLReload, sizeof(int32) }, 1.1045 + { &sound1EnvelopeUpDown, sizeof(int32) }, 1.1046 + { &sound1SweepATL, sizeof(int32) }, 1.1047 + { &sound1SweepATLReload, sizeof(int32) }, 1.1048 + { &sound1SweepSteps, sizeof(int32) }, 1.1049 + { &sound1SweepUpDown, sizeof(int32) }, 1.1050 + { &sound1SweepStep, sizeof(int32) }, 1.1051 + { &sound2On, sizeof(int32) }, 1.1052 + { &sound2ATL, sizeof(int32) }, 1.1053 + { &sound2Skip, sizeof(int32) }, 1.1054 + { &sound2Index, sizeof(int32) }, 1.1055 + { &sound2Continue, sizeof(int32) }, 1.1056 + { &sound2EnvelopeVolume, sizeof(int32) }, 1.1057 + { &sound2EnvelopeATL, sizeof(int32) }, 1.1058 + { &sound2EnvelopeATLReload, sizeof(int32) }, 1.1059 + { &sound2EnvelopeUpDown, sizeof(int32) }, 1.1060 + { &sound3On, sizeof(int32) }, 1.1061 + { &sound3ATL, sizeof(int32) }, 1.1062 + { &sound3Skip, sizeof(int32) }, 1.1063 + { &sound3Index, sizeof(int32) }, 1.1064 + { &sound3Continue, sizeof(int32) }, 1.1065 + { &sound3OutputLevel, sizeof(int32) }, 1.1066 + { &sound4On, sizeof(int32) }, 1.1067 + { &sound4ATL, sizeof(int32) }, 1.1068 + { &sound4Skip, sizeof(int32) }, 1.1069 + { &sound4Index, sizeof(int32) }, 1.1070 + { &sound4Clock, sizeof(int32) }, 1.1071 + { &sound4ShiftRight, sizeof(int32) }, 1.1072 + { &sound4ShiftSkip, sizeof(int32) }, 1.1073 + { &sound4ShiftIndex, sizeof(int32) }, 1.1074 + { &sound4NSteps, sizeof(int32) }, 1.1075 + { &sound4CountDown, sizeof(int32) }, 1.1076 + { &sound4Continue, sizeof(int32) }, 1.1077 + { &sound4EnvelopeVolume, sizeof(int32) }, 1.1078 + { &sound4EnvelopeATL, sizeof(int32) }, 1.1079 + { &sound4EnvelopeATLReload, sizeof(int32) }, 1.1080 + { &sound4EnvelopeUpDown, sizeof(int32) }, 1.1081 + { &soundEnableFlag, sizeof(int32) }, 1.1082 + { NULL, 0 } 1.1083 +}; 1.1084 + 1.1085 +//variable_desc gbSoundSaveStructV2[] = { 1.1086 +// { &soundTicks, sizeof(soundtick_t) }, 1.1087 +// { &SOUND_CLOCK_TICKS, sizeof(soundtick_t) }, 1.1088 +// { &GB_USE_TICKS_AS, sizeof(soundtick_t) }, 1.1089 +// { NULL, 0 } 1.1090 +//}; 1.1091 + 1.1092 +void gbSoundSaveGame(gzFile gzFile) 1.1093 +{ 1.1094 + soundTicks_int32 = (int32) soundTicks; 1.1095 + SOUND_CLOCK_TICKS_int32 = (int32) SOUND_CLOCK_TICKS; 1.1096 + 1.1097 + utilWriteData(gzFile, gbSoundSaveStruct); 1.1098 + 1.1099 + utilGzWrite(gzFile, soundBuffer, 4 * 735); 1.1100 + utilGzWrite(gzFile, soundFinalWave, 2 * 735); 1.1101 + utilGzWrite(gzFile, &soundQuality, sizeof(int32)); 1.1102 + 1.1103 + //utilWriteData(gzFile, gbSoundSaveStructV2); 1.1104 +} 1.1105 + 1.1106 +void gbSoundReadGame(int version, gzFile gzFile) 1.1107 +{ 1.1108 + int32 oldSoundPaused = soundPaused; 1.1109 + int32 oldSoundEnableFlag = soundEnableFlag; 1.1110 + utilReadData(gzFile, gbSoundSaveStruct); 1.1111 + soundPaused = oldSoundPaused; 1.1112 + soundEnableFlag = oldSoundEnableFlag; 1.1113 + 1.1114 + soundBufferIndex = soundIndex * 2; 1.1115 + 1.1116 + utilGzRead(gzFile, soundBuffer, 4 * 735); 1.1117 + utilGzRead(gzFile, soundFinalWave, 2 * 735); 1.1118 + 1.1119 + if (version >= 7) 1.1120 + { 1.1121 + int quality = 1; 1.1122 + utilGzRead(gzFile, &quality, sizeof(int32)); 1.1123 + gbSoundSetQuality(quality); 1.1124 + } 1.1125 + else 1.1126 + { 1.1127 + soundQuality = -1; 1.1128 + gbSoundSetQuality(1); 1.1129 + } 1.1130 + 1.1131 + sound1Wave = soundWavePattern[gbMemory[NR11] >> 6]; 1.1132 + sound2Wave = soundWavePattern[gbMemory[NR21] >> 6]; 1.1133 + 1.1134 + //if(version >= 14) { 1.1135 + // utilReadData(gzFile, gbSoundSaveStructV2); 1.1136 + //} 1.1137 + //else { 1.1138 + soundTicks = (soundtick_t) soundTicks_int32; 1.1139 + SOUND_CLOCK_TICKS = (soundtick_t) SOUND_CLOCK_TICKS_int32; 1.1140 + //} 1.1141 +} 1.1142 +