Mercurial > vba-linux
diff src/gba/GBASound.cpp @ 1:f9f4f1b99eed
importing src directory
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 10:31:27 -0600 |
parents | |
children |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/gba/GBASound.cpp Sat Mar 03 10:31:27 2012 -0600 1.3 @@ -0,0 +1,1542 @@ 1.4 +#if (defined(WIN32) && !defined(SDL)) 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 "GBASound.h" 1.13 +#include "../common/System.h" // SDL build needs this 1.14 +#include "../common/Util.h" 1.15 +#include "GBA.h" 1.16 +#include "GBAGlobals.h" 1.17 + 1.18 +#ifndef countof 1.19 +#define countof(a) (sizeof(a) / sizeof(a[0])) 1.20 +#endif 1.21 + 1.22 +soundtick_t USE_TICKS_AS = 380; // (16777216.0/44100.0); // FIXME: (16777216.0/280896.0)(fps) vs 60.0fps? 1.23 + 1.24 +#define SOUND_MAGIC 0x60000000 1.25 +#define SOUND_MAGIC_2 0x30000000 1.26 +#define NOISE_MAGIC (2097152.0 / 44100.0) 1.27 + 1.28 +extern bool8 stopState; 1.29 + 1.30 +u8 soundWavePattern[4][32] = { 1.31 + { 0x01, 0x01, 0x01, 0x01, 1.32 + 0xff, 0xff, 0xff, 0xff, 1.33 + 0xff, 0xff, 0xff, 0xff, 1.34 + 0xff, 0xff, 0xff, 0xff, 1.35 + 0xff, 0xff, 0xff, 0xff, 1.36 + 0xff, 0xff, 0xff, 0xff, 1.37 + 0xff, 0xff, 0xff, 0xff, 1.38 + 0xff, 0xff, 0xff, 0xff }, 1.39 + { 0x01, 0x01, 0x01, 0x01, 1.40 + 0x01, 0x01, 0x01, 0x01, 1.41 + 0xff, 0xff, 0xff, 0xff, 1.42 + 0xff, 0xff, 0xff, 0xff, 1.43 + 0xff, 0xff, 0xff, 0xff, 1.44 + 0xff, 0xff, 0xff, 0xff, 1.45 + 0xff, 0xff, 0xff, 0xff, 1.46 + 0xff, 0xff, 0xff, 0xff }, 1.47 + { 0x01, 0x01, 0x01, 0x01, 1.48 + 0x01, 0x01, 0x01, 0x01, 1.49 + 0x01, 0x01, 0x01, 0x01, 1.50 + 0x01, 0x01, 0x01, 0x01, 1.51 + 0xff, 0xff, 0xff, 0xff, 1.52 + 0xff, 0xff, 0xff, 0xff, 1.53 + 0xff, 0xff, 0xff, 0xff, 1.54 + 0xff, 0xff, 0xff, 0xff }, 1.55 + { 0x01, 0x01, 0x01, 0x01, 1.56 + 0x01, 0x01, 0x01, 0x01, 1.57 + 0x01, 0x01, 0x01, 0x01, 1.58 + 0x01, 0x01, 0x01, 0x01, 1.59 + 0x01, 0x01, 0x01, 0x01, 1.60 + 0x01, 0x01, 0x01, 0x01, 1.61 + 0xff, 0xff, 0xff, 0xff, 1.62 + 0xff, 0xff, 0xff, 0xff } 1.63 +}; 1.64 + 1.65 +int32 soundFreqRatio[8] = { 1.66 + 1048576, // 0 1.67 + 524288, // 1 1.68 + 262144, // 2 1.69 + 174763, // 3 1.70 + 131072, // 4 1.71 + 104858, // 5 1.72 + 87381, // 6 1.73 + 74898 // 7 1.74 +}; 1.75 + 1.76 +int32 soundShiftClock[16] = { 1.77 + 2, // 0 1.78 + 4, // 1 1.79 + 8, // 2 1.80 + 16, // 3 1.81 + 32, // 4 1.82 + 64, // 5 1.83 + 128, // 6 1.84 + 256, // 7 1.85 + 512, // 8 1.86 + 1024, // 9 1.87 + 2048, // 10 1.88 + 4096, // 11 1.89 + 8192, // 12 1.90 + 16384, // 13 1.91 + 1, // 14 1.92 + 1 // 15 1.93 +}; 1.94 + 1.95 +int32 soundVolume = 0; 1.96 + 1.97 +u8 soundBuffer[6][735]; 1.98 +u16 soundFinalWave[1470]; 1.99 +u16 soundFrameSound[735 * 30 * 2]; // for avi logging 1.100 + 1.101 +u32 soundBufferLen = 1470; 1.102 +u32 soundBufferTotalLen = 14700; 1.103 +int32 soundQuality = 2; 1.104 +int32 soundPaused = 1; 1.105 +int32 soundPlay = 0; 1.106 +soundtick_t soundTicks = soundQuality * USE_TICKS_AS; 1.107 +soundtick_t SOUND_CLOCK_TICKS = soundQuality * USE_TICKS_AS; 1.108 +u32 soundNextPosition = 0; 1.109 + 1.110 +int32 soundLevel1 = 0; 1.111 +int32 soundLevel2 = 0; 1.112 +int32 soundBalance = 0; 1.113 +int32 soundMasterOn = 0; 1.114 +u32 soundIndex = 0; 1.115 +u32 soundBufferIndex = 0; 1.116 +int32 soundFrameSoundWritten = 0; 1.117 +int32 soundDebug = 0; 1.118 +bool8 soundOffFlag = false; 1.119 + 1.120 +int32 sound1On = 0; 1.121 +int32 sound1ATL = 0; 1.122 +int32 sound1Skip = 0; 1.123 +int32 sound1Index = 0; 1.124 +int32 sound1Continue = 0; 1.125 +int32 sound1EnvelopeVolume = 0; 1.126 +int32 sound1EnvelopeATL = 0; 1.127 +int32 sound1EnvelopeUpDown = 0; 1.128 +int32 sound1EnvelopeATLReload = 0; 1.129 +int32 sound1SweepATL = 0; 1.130 +int32 sound1SweepATLReload = 0; 1.131 +int32 sound1SweepSteps = 0; 1.132 +int32 sound1SweepUpDown = 0; 1.133 +int32 sound1SweepStep = 0; 1.134 +u8 * sound1Wave = soundWavePattern[2]; 1.135 + 1.136 +int32 sound2On = 0; 1.137 +int32 sound2ATL = 0; 1.138 +int32 sound2Skip = 0; 1.139 +int32 sound2Index = 0; 1.140 +int32 sound2Continue = 0; 1.141 +int32 sound2EnvelopeVolume = 0; 1.142 +int32 sound2EnvelopeATL = 0; 1.143 +int32 sound2EnvelopeUpDown = 0; 1.144 +int32 sound2EnvelopeATLReload = 0; 1.145 +u8 * sound2Wave = soundWavePattern[2]; 1.146 + 1.147 +int32 sound3On = 0; 1.148 +int32 sound3ATL = 0; 1.149 +int32 sound3Skip = 0; 1.150 +int32 sound3Index = 0; 1.151 +int32 sound3Continue = 0; 1.152 +int32 sound3OutputLevel = 0; 1.153 +int32 sound3Last = 0; 1.154 +u8 sound3WaveRam[0x20]; 1.155 +int32 sound3Bank = 0; 1.156 +int32 sound3DataSize = 0; 1.157 +int32 sound3ForcedOutput = 0; 1.158 + 1.159 +int32 sound4On = 0; 1.160 +int32 sound4Clock = 0; 1.161 +int32 sound4ATL = 0; 1.162 +int32 sound4Skip = 0; 1.163 +int32 sound4Index = 0; 1.164 +int32 sound4ShiftRight = 0x7f; 1.165 +int32 sound4ShiftSkip = 0; 1.166 +int32 sound4ShiftIndex = 0; 1.167 +int32 sound4NSteps = 0; 1.168 +int32 sound4CountDown = 0; 1.169 +int32 sound4Continue = 0; 1.170 +int32 sound4EnvelopeVolume = 0; 1.171 +int32 sound4EnvelopeATL = 0; 1.172 +int32 sound4EnvelopeUpDown = 0; 1.173 +int32 sound4EnvelopeATLReload = 0; 1.174 + 1.175 +int32 soundControl = 0; 1.176 + 1.177 +int32 soundDSFifoAIndex = 0; 1.178 +int32 soundDSFifoACount = 0; 1.179 +int32 soundDSFifoAWriteIndex = 0; 1.180 +bool8 soundDSAEnabled = false; 1.181 +int32 soundDSATimer = 0; 1.182 +u8 soundDSFifoA[32]; 1.183 +u8 soundDSAValue = 0; 1.184 + 1.185 +int32 soundDSFifoBIndex = 0; 1.186 +int32 soundDSFifoBCount = 0; 1.187 +int32 soundDSFifoBWriteIndex = 0; 1.188 +bool8 soundDSBEnabled = false; 1.189 +int32 soundDSBTimer = 0; 1.190 +u8 soundDSFifoB[32]; 1.191 +u8 soundDSBValue = 0; 1.192 + 1.193 +int32 soundEnableFlag = 0x3ff; 1.194 +int32 soundMutedFlag = 0; 1.195 + 1.196 +s16 soundFilter[4000]; 1.197 +s16 soundRight[5] = { 0, 0, 0, 0, 0 }; 1.198 +s16 soundLeft[5] = { 0, 0, 0, 0, 0 }; 1.199 +int32 soundEchoIndex = 0; 1.200 +bool8 soundEcho = false; 1.201 +bool8 soundLowPass = false; 1.202 +bool8 soundReverse = false; 1.203 + 1.204 +static int32 soundTicks_int32; 1.205 +static int32 SOUND_CLOCK_TICKS_int32; 1.206 +static int32 soundDSBValue_int32; 1.207 +variable_desc soundSaveStruct[] = { 1.208 + { &soundPaused, sizeof(int32) }, 1.209 + { &soundPlay, sizeof(int32) }, 1.210 + { &soundTicks_int32, sizeof(int32) }, 1.211 + { &SOUND_CLOCK_TICKS_int32, sizeof(int32) }, 1.212 + { &soundLevel1, sizeof(int32) }, 1.213 + { &soundLevel2, sizeof(int32) }, 1.214 + { &soundBalance, sizeof(int32) }, 1.215 + { &soundMasterOn, sizeof(int32) }, 1.216 + { &soundIndex, sizeof(int32) }, 1.217 + { &sound1On, sizeof(int32) }, 1.218 + { &sound1ATL, sizeof(int32) }, 1.219 + { &sound1Skip, sizeof(int32) }, 1.220 + { &sound1Index, sizeof(int32) }, 1.221 + { &sound1Continue, sizeof(int32) }, 1.222 + { &sound1EnvelopeVolume, sizeof(int32) }, 1.223 + { &sound1EnvelopeATL, sizeof(int32) }, 1.224 + { &sound1EnvelopeATLReload, sizeof(int32) }, 1.225 + { &sound1EnvelopeUpDown, sizeof(int32) }, 1.226 + { &sound1SweepATL, sizeof(int32) }, 1.227 + { &sound1SweepATLReload, sizeof(int32) }, 1.228 + { &sound1SweepSteps, sizeof(int32) }, 1.229 + { &sound1SweepUpDown, sizeof(int32) }, 1.230 + { &sound1SweepStep, sizeof(int32) }, 1.231 + { &sound2On, sizeof(int32) }, 1.232 + { &sound2ATL, sizeof(int32) }, 1.233 + { &sound2Skip, sizeof(int32) }, 1.234 + { &sound2Index, sizeof(int32) }, 1.235 + { &sound2Continue, sizeof(int32) }, 1.236 + { &sound2EnvelopeVolume, sizeof(int32) }, 1.237 + { &sound2EnvelopeATL, sizeof(int32) }, 1.238 + { &sound2EnvelopeATLReload, sizeof(int32) }, 1.239 + { &sound2EnvelopeUpDown, sizeof(int32) }, 1.240 + { &sound3On, sizeof(int32) }, 1.241 + { &sound3ATL, sizeof(int32) }, 1.242 + { &sound3Skip, sizeof(int32) }, 1.243 + { &sound3Index, sizeof(int32) }, 1.244 + { &sound3Continue, sizeof(int32) }, 1.245 + { &sound3OutputLevel, sizeof(int32) }, 1.246 + { &sound4On, sizeof(int32) }, 1.247 + { &sound4ATL, sizeof(int32) }, 1.248 + { &sound4Skip, sizeof(int32) }, 1.249 + { &sound4Index, sizeof(int32) }, 1.250 + { &sound4Clock, sizeof(int32) }, 1.251 + { &sound4ShiftRight, sizeof(int32) }, 1.252 + { &sound4ShiftSkip, sizeof(int32) }, 1.253 + { &sound4ShiftIndex, sizeof(int32) }, 1.254 + { &sound4NSteps, sizeof(int32) }, 1.255 + { &sound4CountDown, sizeof(int32) }, 1.256 + { &sound4Continue, sizeof(int32) }, 1.257 + { &sound4EnvelopeVolume, sizeof(int32) }, 1.258 + { &sound4EnvelopeATL, sizeof(int32) }, 1.259 + { &sound4EnvelopeATLReload, sizeof(int32) }, 1.260 + { &sound4EnvelopeUpDown, sizeof(int32) }, 1.261 + { &soundEnableFlag, sizeof(int32) }, 1.262 + { &soundControl, sizeof(int32) }, 1.263 + { &soundDSFifoAIndex, sizeof(int32) }, 1.264 + { &soundDSFifoACount, sizeof(int32) }, 1.265 + { &soundDSFifoAWriteIndex, sizeof(int32) }, 1.266 + { &soundDSAEnabled, sizeof(bool8) }, 1.267 + { &soundDSATimer, sizeof(int32) }, 1.268 + { &soundDSFifoA[0], 32 }, 1.269 + { &soundDSAValue, sizeof(u8) }, 1.270 + { &soundDSFifoBIndex, sizeof(int32) }, 1.271 + { &soundDSFifoBCount, sizeof(int32) }, 1.272 + { &soundDSFifoBWriteIndex, sizeof(int32) }, 1.273 + { &soundDSBEnabled, sizeof(int32) }, 1.274 + { &soundDSBTimer, sizeof(int32) }, 1.275 + { &soundDSFifoB[0], 32 }, 1.276 + { &soundDSBValue_int32, sizeof(int32) }, // save as int32 because of a mistake of the past. 1.277 + { &soundBuffer[0][0], 6 * 735 }, 1.278 + { &soundFinalWave[0], 2 * 735 }, 1.279 + { NULL, 0 } 1.280 +}; 1.281 + 1.282 +variable_desc soundSaveStructV2[] = { 1.283 + { &sound3WaveRam[0], 0x20 }, 1.284 + { &sound3Bank, sizeof(int32) }, 1.285 + { &sound3DataSize, sizeof(int32) }, 1.286 + { &sound3ForcedOutput, sizeof(int32) }, 1.287 + { NULL, 0 } 1.288 +}; 1.289 + 1.290 +//variable_desc soundSaveStructV3[] = { 1.291 +// { &soundTicks, sizeof(soundtick_t) }, 1.292 +// { &SOUND_CLOCK_TICKS, sizeof(soundtick_t) }, 1.293 +// { &USE_TICKS_AS, sizeof(soundtick_t) }, 1.294 +// { NULL, 0 } 1.295 +//}; 1.296 + 1.297 +void soundEvent(u32 address, u8 data) 1.298 +{ 1.299 + int freq = 0; 1.300 + 1.301 + switch (address) 1.302 + { 1.303 + case NR10: 1.304 + data &= 0x7f; 1.305 + sound1SweepATL = sound1SweepATLReload = 344 * ((data >> 4) & 7); 1.306 + sound1SweepSteps = data & 7; 1.307 + sound1SweepUpDown = data & 0x08; 1.308 + sound1SweepStep = 0; 1.309 + ioMem[address] = data; 1.310 + break; 1.311 + case NR11: 1.312 + sound1Wave = soundWavePattern[data >> 6]; 1.313 + sound1ATL = 172 * (64 - (data & 0x3f)); 1.314 + ioMem[address] = data; 1.315 + break; 1.316 + case NR12: 1.317 + sound1EnvelopeUpDown = data & 0x08; 1.318 + sound1EnvelopeATLReload = 689 * (data & 7); 1.319 + if ((data & 0xF8) == 0) 1.320 + sound1EnvelopeVolume = 0; 1.321 + ioMem[address] = data; 1.322 + break; 1.323 + case NR13: 1.324 + freq = (((int)(ioMem[NR14] & 7)) << 8) | data; 1.325 + sound1ATL = 172 * (64 - (ioMem[NR11] & 0x3f)); 1.326 + freq = 2048 - freq; 1.327 + if (freq) 1.328 + { 1.329 + sound1Skip = SOUND_MAGIC / freq; 1.330 + } 1.331 + else 1.332 + sound1Skip = 0; 1.333 + ioMem[address] = data; 1.334 + break; 1.335 + case NR14: 1.336 + data &= 0xC7; 1.337 + freq = (((int)(data & 7) << 8) | ioMem[NR13]); 1.338 + freq = 2048 - freq; 1.339 + sound1ATL = 172 * (64 - (ioMem[NR11] & 0x3f)); 1.340 + sound1Continue = data & 0x40; 1.341 + if (freq) 1.342 + { 1.343 + sound1Skip = SOUND_MAGIC / freq; 1.344 + } 1.345 + else 1.346 + sound1Skip = 0; 1.347 + if (data & 0x80) 1.348 + { 1.349 + ioMem[NR52] |= 1; 1.350 + sound1EnvelopeVolume = ioMem[NR12] >> 4; 1.351 + sound1EnvelopeUpDown = ioMem[NR12] & 0x08; 1.352 + sound1ATL = 172 * (64 - (ioMem[NR11] & 0x3f)); 1.353 + sound1EnvelopeATLReload = sound1EnvelopeATL = 689 * (ioMem[NR12] & 7); 1.354 + sound1SweepATL = sound1SweepATLReload = 344 * ((ioMem[NR10] >> 4) & 7); 1.355 + sound1SweepSteps = ioMem[NR10] & 7; 1.356 + sound1SweepUpDown = ioMem[NR10] & 0x08; 1.357 + sound1SweepStep = 0; 1.358 + 1.359 + sound1Index = 0; 1.360 + sound1On = 1; 1.361 + } 1.362 + ioMem[address] = data; 1.363 + break; 1.364 + case NR21: 1.365 + sound2Wave = soundWavePattern[data >> 6]; 1.366 + sound2ATL = 172 * (64 - (data & 0x3f)); 1.367 + ioMem[address] = data; 1.368 + break; 1.369 + case NR22: 1.370 + sound2EnvelopeUpDown = data & 0x08; 1.371 + sound2EnvelopeATLReload = 689 * (data & 7); 1.372 + if ((data & 0xF8) == 0) 1.373 + sound2EnvelopeVolume = 0; 1.374 + ioMem[address] = data; 1.375 + break; 1.376 + case NR23: 1.377 + freq = (((int)(ioMem[NR24] & 7)) << 8) | data; 1.378 + sound2ATL = 172 * (64 - (ioMem[NR21] & 0x3f)); 1.379 + freq = 2048 - freq; 1.380 + if (freq) 1.381 + { 1.382 + sound2Skip = SOUND_MAGIC / freq; 1.383 + } 1.384 + else 1.385 + sound2Skip = 0; 1.386 + ioMem[address] = data; 1.387 + break; 1.388 + case NR24: 1.389 + data &= 0xC7; 1.390 + freq = (((int)(data & 7) << 8) | ioMem[NR23]); 1.391 + freq = 2048 - freq; 1.392 + sound2ATL = 172 * (64 - (ioMem[NR21] & 0x3f)); 1.393 + sound2Continue = data & 0x40; 1.394 + if (freq) 1.395 + { 1.396 + sound2Skip = SOUND_MAGIC / freq; 1.397 + } 1.398 + else 1.399 + sound2Skip = 0; 1.400 + if (data & 0x80) 1.401 + { 1.402 + ioMem[NR52] |= 2; 1.403 + sound2EnvelopeVolume = ioMem[NR22] >> 4; 1.404 + sound2EnvelopeUpDown = ioMem[NR22] & 0x08; 1.405 + sound2ATL = 172 * (64 - (ioMem[NR21] & 0x3f)); 1.406 + sound2EnvelopeATLReload = sound2EnvelopeATL = 689 * (ioMem[NR22] & 7); 1.407 + 1.408 + sound2Index = 0; 1.409 + sound2On = 1; 1.410 + } 1.411 + ioMem[address] = data; 1.412 + break; 1.413 + case NR30: 1.414 + data &= 0xe0; 1.415 + if (!(data & 0x80)) 1.416 + { 1.417 + ioMem[NR52] &= 0xfb; 1.418 + sound3On = 0; 1.419 + } 1.420 + if (((data >> 6) & 1) != sound3Bank) 1.421 + memcpy(&ioMem[0x90], &sound3WaveRam[(((data >> 6) & 1) * 0x10) ^ 0x10], 1.422 + 0x10); 1.423 + sound3Bank = (data >> 6) & 1; 1.424 + sound3DataSize = (data >> 5) & 1; 1.425 + ioMem[address] = data; 1.426 + break; 1.427 + case NR31: 1.428 + sound3ATL = 172 * (256 - data); 1.429 + ioMem[address] = data; 1.430 + break; 1.431 + case NR32: 1.432 + data &= 0xe0; 1.433 + sound3OutputLevel = (data >> 5) & 3; 1.434 + sound3ForcedOutput = (data >> 7) & 1; 1.435 + ioMem[address] = data; 1.436 + break; 1.437 + case NR33: 1.438 + freq = 2048 - (((int)(ioMem[NR34] & 7) << 8) | data); 1.439 + if (freq) 1.440 + { 1.441 + sound3Skip = SOUND_MAGIC_2 / freq; 1.442 + } 1.443 + else 1.444 + sound3Skip = 0; 1.445 + ioMem[address] = data; 1.446 + break; 1.447 + case NR34: 1.448 + data &= 0xc7; 1.449 + freq = 2048 - (((data & 7) << 8) | (int)ioMem[NR33]); 1.450 + if (freq) 1.451 + { 1.452 + sound3Skip = SOUND_MAGIC_2 / freq; 1.453 + } 1.454 + else 1.455 + { 1.456 + sound3Skip = 0; 1.457 + } 1.458 + sound3Continue = data & 0x40; 1.459 + if ((data & 0x80) && (ioMem[NR30] & 0x80)) 1.460 + { 1.461 + ioMem[NR52] |= 4; 1.462 + sound3ATL = 172 * (256 - ioMem[NR31]); 1.463 + sound3Index = 0; 1.464 + sound3On = 1; 1.465 + } 1.466 + ioMem[address] = data; 1.467 + break; 1.468 + case NR41: 1.469 + data &= 0x3f; 1.470 + sound4ATL = 172 * (64 - (data & 0x3f)); 1.471 + ioMem[address] = data; 1.472 + break; 1.473 + case NR42: 1.474 + sound4EnvelopeUpDown = data & 0x08; 1.475 + sound4EnvelopeATLReload = 689 * (data & 7); 1.476 + if ((data & 0xF8) == 0) 1.477 + sound4EnvelopeVolume = 0; 1.478 + ioMem[address] = data; 1.479 + break; 1.480 + case NR43: 1.481 + freq = soundFreqRatio[data & 7]; 1.482 + sound4NSteps = data & 0x08; 1.483 + 1.484 + sound4Skip = freq * NOISE_MAGIC; 1.485 + 1.486 + sound4Clock = data >> 4; 1.487 + 1.488 + freq = freq / soundShiftClock[sound4Clock]; 1.489 + 1.490 + sound4ShiftSkip = freq * NOISE_MAGIC; 1.491 + ioMem[address] = data; 1.492 + break; 1.493 + case NR44: 1.494 + data &= 0xc0; 1.495 + sound4Continue = data & 0x40; 1.496 + if (data & 0x80) 1.497 + { 1.498 + ioMem[NR52] |= 8; 1.499 + sound4EnvelopeVolume = ioMem[NR42] >> 4; 1.500 + sound4EnvelopeUpDown = ioMem[NR42] & 0x08; 1.501 + sound4ATL = 172 * (64 - (ioMem[NR41] & 0x3f)); 1.502 + sound4EnvelopeATLReload = sound4EnvelopeATL = 689 * (ioMem[NR42] & 7); 1.503 + 1.504 + sound4On = 1; 1.505 + 1.506 + sound4Index = 0; 1.507 + sound4ShiftIndex = 0; 1.508 + 1.509 + freq = soundFreqRatio[ioMem[NR43] & 7]; 1.510 + 1.511 + sound4Skip = freq * NOISE_MAGIC; 1.512 + 1.513 + sound4NSteps = ioMem[NR43] & 0x08; 1.514 + 1.515 + freq = freq / soundShiftClock[ioMem[NR43] >> 4]; 1.516 + 1.517 + sound4ShiftSkip = freq * NOISE_MAGIC; 1.518 + if (sound4NSteps) 1.519 + sound4ShiftRight = 0x7f; 1.520 + else 1.521 + sound4ShiftRight = 0x7fff; 1.522 + } 1.523 + ioMem[address] = data; 1.524 + break; 1.525 + case NR50: 1.526 + data &= 0x77; 1.527 + soundLevel1 = data & 7; 1.528 + soundLevel2 = (data >> 4) & 7; 1.529 + ioMem[address] = data; 1.530 + break; 1.531 + case NR51: 1.532 + soundBalance = (data & soundEnableFlag); 1.533 + ioMem[address] = data; 1.534 + break; 1.535 + case NR52: 1.536 + data &= 0x80; 1.537 + data |= ioMem[NR52] & 15; 1.538 + soundMasterOn = data & 0x80; 1.539 + if (!(data & 0x80)) 1.540 + { 1.541 + sound1On = 0; 1.542 + sound2On = 0; 1.543 + sound3On = 0; 1.544 + sound4On = 0; 1.545 + } 1.546 + ioMem[address] = data; 1.547 + break; 1.548 + case 0x90: 1.549 + case 0x91: 1.550 + case 0x92: 1.551 + case 0x93: 1.552 + case 0x94: 1.553 + case 0x95: 1.554 + case 0x96: 1.555 + case 0x97: 1.556 + case 0x98: 1.557 + case 0x99: 1.558 + case 0x9a: 1.559 + case 0x9b: 1.560 + case 0x9c: 1.561 + case 0x9d: 1.562 + case 0x9e: 1.563 + case 0x9f: 1.564 + sound3WaveRam[(sound3Bank * 0x10) ^ 0x10 + (address & 15)] = data; 1.565 + break; 1.566 + } 1.567 +} 1.568 + 1.569 +void soundEvent(u32 address, u16 data) 1.570 +{ 1.571 + switch (address) 1.572 + { 1.573 + case SGCNT0_H: 1.574 + data &= 0xFF0F; 1.575 + soundControl = data & 0x770F;; 1.576 + if (data & 0x0800) 1.577 + { 1.578 + soundDSFifoAWriteIndex = 0; 1.579 + soundDSFifoAIndex = 0; 1.580 + soundDSFifoACount = 0; 1.581 + soundDSAValue = 0; 1.582 + memset(soundDSFifoA, 0, 32); 1.583 + } 1.584 + soundDSAEnabled = (data & 0x0300) ? true : false; 1.585 + soundDSATimer = (data & 0x0400) ? 1 : 0; 1.586 + if (data & 0x8000) 1.587 + { 1.588 + soundDSFifoBWriteIndex = 0; 1.589 + soundDSFifoBIndex = 0; 1.590 + soundDSFifoBCount = 0; 1.591 + soundDSBValue = 0; 1.592 + memset(soundDSFifoB, 0, 32); 1.593 + } 1.594 + soundDSBEnabled = (data & 0x3000) ? true : false; 1.595 + soundDSBTimer = (data & 0x4000) ? 1 : 0; 1.596 + *((u16 *)&ioMem[address]) = data; 1.597 + break; 1.598 + case FIFOA_L: 1.599 + case FIFOA_H: 1.600 + soundDSFifoA[soundDSFifoAWriteIndex++] = data & 0xFF; 1.601 + soundDSFifoA[soundDSFifoAWriteIndex++] = data >> 8; 1.602 + soundDSFifoACount += 2; 1.603 + soundDSFifoAWriteIndex &= 31; 1.604 + *((u16 *)&ioMem[address]) = data; 1.605 + break; 1.606 + case FIFOB_L: 1.607 + case FIFOB_H: 1.608 + soundDSFifoB[soundDSFifoBWriteIndex++] = data & 0xFF; 1.609 + soundDSFifoB[soundDSFifoBWriteIndex++] = data >> 8; 1.610 + soundDSFifoBCount += 2; 1.611 + soundDSFifoBWriteIndex &= 31; 1.612 + *((u16 *)&ioMem[address]) = data; 1.613 + break; 1.614 + case 0x88: 1.615 + data &= 0xC3FF; 1.616 + *((u16 *)&ioMem[address]) = data; 1.617 + break; 1.618 + case 0x90: 1.619 + case 0x92: 1.620 + case 0x94: 1.621 + case 0x96: 1.622 + case 0x98: 1.623 + case 0x9a: 1.624 + case 0x9c: 1.625 + case 0x9e: 1.626 + *((u16 *)&sound3WaveRam[(sound3Bank * 0x10) ^ 0x10 + (address & 14)]) = data; 1.627 + *((u16 *)&ioMem[address]) = data; 1.628 + break; 1.629 + } 1.630 +} 1.631 + 1.632 +void soundChannel1() 1.633 +{ 1.634 + int vol = sound1EnvelopeVolume; 1.635 + 1.636 + int freq = 0; 1.637 + int value = 0; 1.638 + 1.639 + if (sound1On && (sound1ATL || !sound1Continue)) 1.640 + { 1.641 + sound1Index += soundQuality * sound1Skip; 1.642 + sound1Index &= 0x1fffffff; 1.643 + 1.644 + value = ((s8)sound1Wave[sound1Index >> 24]) * vol; 1.645 + } 1.646 + 1.647 + soundBuffer[0][soundIndex] = value; 1.648 + 1.649 + if (sound1On) 1.650 + { 1.651 + if (sound1ATL) 1.652 + { 1.653 + sound1ATL -= soundQuality; 1.654 + 1.655 + if (sound1ATL <= 0 && sound1Continue) 1.656 + { 1.657 + ioMem[NR52] &= 0xfe; 1.658 + sound1On = 0; 1.659 + } 1.660 + } 1.661 + 1.662 + if (sound1EnvelopeATL) 1.663 + { 1.664 + sound1EnvelopeATL -= soundQuality; 1.665 + 1.666 + if (sound1EnvelopeATL <= 0) 1.667 + { 1.668 + if (sound1EnvelopeUpDown) 1.669 + { 1.670 + if (sound1EnvelopeVolume < 15) 1.671 + sound1EnvelopeVolume++; 1.672 + } 1.673 + else 1.674 + { 1.675 + if (sound1EnvelopeVolume) 1.676 + sound1EnvelopeVolume--; 1.677 + } 1.678 + 1.679 + sound1EnvelopeATL += sound1EnvelopeATLReload; 1.680 + } 1.681 + } 1.682 + 1.683 + if (sound1SweepATL) 1.684 + { 1.685 + sound1SweepATL -= soundQuality; 1.686 + 1.687 + if (sound1SweepATL <= 0) 1.688 + { 1.689 + freq = (((int)(ioMem[NR14] & 7) << 8) | ioMem[NR13]); 1.690 + 1.691 + int updown = 1; 1.692 + 1.693 + if (sound1SweepUpDown) 1.694 + updown = -1; 1.695 + 1.696 + int newfreq = 0; 1.697 + if (sound1SweepSteps) 1.698 + { 1.699 + newfreq = freq + updown * freq / (1 << sound1SweepSteps); 1.700 + if (newfreq == freq) 1.701 + newfreq = 0; 1.702 + } 1.703 + else 1.704 + newfreq = freq; 1.705 + 1.706 + if (newfreq < 0) 1.707 + { 1.708 + sound1SweepATL += sound1SweepATLReload; 1.709 + } 1.710 + else if (newfreq > 2047) 1.711 + { 1.712 + sound1SweepATL = 0; 1.713 + sound1On = 0; 1.714 + ioMem[NR52] &= 0xfe; 1.715 + } 1.716 + else 1.717 + { 1.718 + sound1SweepATL += sound1SweepATLReload; 1.719 + sound1Skip = SOUND_MAGIC / (2048 - newfreq); 1.720 + 1.721 + ioMem[NR13] = newfreq & 0xff; 1.722 + ioMem[NR14] = (ioMem[NR14] & 0xf8) | ((newfreq >> 8) & 7); 1.723 + } 1.724 + } 1.725 + } 1.726 + } 1.727 +} 1.728 + 1.729 +void soundChannel2() 1.730 +{ 1.731 + // int freq = 0; 1.732 + int vol = sound2EnvelopeVolume; 1.733 + 1.734 + int value = 0; 1.735 + 1.736 + if (sound2On && (sound2ATL || !sound2Continue)) 1.737 + { 1.738 + sound2Index += soundQuality * sound2Skip; 1.739 + sound2Index &= 0x1fffffff; 1.740 + 1.741 + value = ((s8)sound2Wave[sound2Index >> 24]) * vol; 1.742 + } 1.743 + 1.744 + soundBuffer[1][soundIndex] = value; 1.745 + 1.746 + if (sound2On) 1.747 + { 1.748 + if (sound2ATL) 1.749 + { 1.750 + sound2ATL -= soundQuality; 1.751 + 1.752 + if (sound2ATL <= 0 && sound2Continue) 1.753 + { 1.754 + ioMem[NR52] &= 0xfd; 1.755 + sound2On = 0; 1.756 + } 1.757 + } 1.758 + 1.759 + if (sound2EnvelopeATL) 1.760 + { 1.761 + sound2EnvelopeATL -= soundQuality; 1.762 + 1.763 + if (sound2EnvelopeATL <= 0) 1.764 + { 1.765 + if (sound2EnvelopeUpDown) 1.766 + { 1.767 + if (sound2EnvelopeVolume < 15) 1.768 + sound2EnvelopeVolume++; 1.769 + } 1.770 + else 1.771 + { 1.772 + if (sound2EnvelopeVolume) 1.773 + sound2EnvelopeVolume--; 1.774 + } 1.775 + sound2EnvelopeATL += sound2EnvelopeATLReload; 1.776 + } 1.777 + } 1.778 + } 1.779 +} 1.780 + 1.781 +void soundChannel3() 1.782 +{ 1.783 + int value = sound3Last; 1.784 + 1.785 + if (sound3On && (sound3ATL || !sound3Continue)) 1.786 + { 1.787 + sound3Index += soundQuality * sound3Skip; 1.788 + if (sound3DataSize) 1.789 + { 1.790 + sound3Index &= 0x3fffffff; 1.791 + value = sound3WaveRam[sound3Index >> 25]; 1.792 + } 1.793 + else 1.794 + { 1.795 + sound3Index &= 0x1fffffff; 1.796 + value = sound3WaveRam[sound3Bank * 0x10 + (sound3Index >> 25)]; 1.797 + } 1.798 + 1.799 + if ((sound3Index & 0x01000000)) 1.800 + { 1.801 + value &= 0x0f; 1.802 + } 1.803 + else 1.804 + { 1.805 + value >>= 4; 1.806 + } 1.807 + 1.808 + value -= 8; 1.809 + value *= 2; 1.810 + 1.811 + if (sound3ForcedOutput) 1.812 + { 1.813 + value = ((value >> 1) + value) >> 1; 1.814 + } 1.815 + else 1.816 + { 1.817 + switch (sound3OutputLevel) 1.818 + { 1.819 + case 0: 1.820 + value = 0; 1.821 + break; 1.822 + case 1: 1.823 + break; 1.824 + case 2: 1.825 + value = (value >> 1); 1.826 + break; 1.827 + case 3: 1.828 + value = (value >> 2); 1.829 + break; 1.830 + } 1.831 + } 1.832 + //value += 1; 1.833 + sound3Last = value; 1.834 + } 1.835 + 1.836 + soundBuffer[2][soundIndex] = value; 1.837 + 1.838 + if (sound3On) 1.839 + { 1.840 + if (sound3ATL) 1.841 + { 1.842 + sound3ATL -= soundQuality; 1.843 + 1.844 + if (sound3ATL <= 0 && sound3Continue) 1.845 + { 1.846 + ioMem[NR52] &= 0xfb; 1.847 + sound3On = 0; 1.848 + } 1.849 + } 1.850 + } 1.851 +} 1.852 + 1.853 +void soundChannel4() 1.854 +{ 1.855 + int vol = sound4EnvelopeVolume; 1.856 + 1.857 + int value = 0; 1.858 + 1.859 + if (sound4Clock <= 0x0c) 1.860 + { 1.861 + if (sound4On && (sound4ATL || !sound4Continue)) 1.862 + { 1.863 + #define NOISE_ONE_SAMP_SCALE 0x200000 1.864 + 1.865 + sound4Index += soundQuality * sound4Skip; 1.866 + sound4ShiftIndex += soundQuality * sound4ShiftSkip; 1.867 + 1.868 + if (sound4NSteps) 1.869 + { 1.870 + while (sound4ShiftIndex >= NOISE_ONE_SAMP_SCALE) 1.871 + { 1.872 + sound4ShiftRight = (((sound4ShiftRight << 6) ^ 1.873 + (sound4ShiftRight << 5)) & 0x40) | 1.874 + (sound4ShiftRight >> 1); 1.875 + sound4ShiftIndex -= NOISE_ONE_SAMP_SCALE; 1.876 + } 1.877 + } 1.878 + else 1.879 + { 1.880 + while (sound4ShiftIndex >= NOISE_ONE_SAMP_SCALE) 1.881 + { 1.882 + sound4ShiftRight = (((sound4ShiftRight << 14) ^ 1.883 + (sound4ShiftRight << 13)) & 0x4000) | 1.884 + (sound4ShiftRight >> 1); 1.885 + 1.886 + sound4ShiftIndex -= NOISE_ONE_SAMP_SCALE; 1.887 + } 1.888 + } 1.889 + 1.890 + sound4Index %= NOISE_ONE_SAMP_SCALE; 1.891 + sound4ShiftIndex %= NOISE_ONE_SAMP_SCALE; 1.892 + 1.893 + value = ((sound4ShiftRight & 1) * 2 - 1) * vol; 1.894 + } 1.895 + else 1.896 + { 1.897 + value = 0; 1.898 + } 1.899 + } 1.900 + 1.901 + soundBuffer[3][soundIndex] = value; 1.902 + 1.903 + if (sound4On) 1.904 + { 1.905 + if (sound4ATL) 1.906 + { 1.907 + sound4ATL -= soundQuality; 1.908 + 1.909 + if (sound4ATL <= 0 && sound4Continue) 1.910 + { 1.911 + ioMem[NR52] &= 0xfd; 1.912 + sound4On = 0; 1.913 + } 1.914 + } 1.915 + 1.916 + if (sound4EnvelopeATL) 1.917 + { 1.918 + sound4EnvelopeATL -= soundQuality; 1.919 + 1.920 + if (sound4EnvelopeATL <= 0) 1.921 + { 1.922 + if (sound4EnvelopeUpDown) 1.923 + { 1.924 + if (sound4EnvelopeVolume < 15) 1.925 + sound4EnvelopeVolume++; 1.926 + } 1.927 + else 1.928 + { 1.929 + if (sound4EnvelopeVolume) 1.930 + sound4EnvelopeVolume--; 1.931 + } 1.932 + sound4EnvelopeATL += sound4EnvelopeATLReload; 1.933 + } 1.934 + } 1.935 + } 1.936 +} 1.937 + 1.938 +void soundDirectSoundA() 1.939 +{ 1.940 + soundBuffer[4][soundIndex] = soundDSAValue; 1.941 +} 1.942 + 1.943 +void soundDirectSoundATimer() 1.944 +{ 1.945 + if (soundDSAEnabled) 1.946 + { 1.947 + if (soundDSFifoACount <= 16) 1.948 + { 1.949 + CPUCheckDMA(3, 2); 1.950 + if (soundDSFifoACount <= 16) 1.951 + { 1.952 + soundEvent(FIFOA_L, (u16)0); 1.953 + soundEvent(FIFOA_H, (u16)0); 1.954 + soundEvent(FIFOA_L, (u16)0); 1.955 + soundEvent(FIFOA_H, (u16)0); 1.956 + soundEvent(FIFOA_L, (u16)0); 1.957 + soundEvent(FIFOA_H, (u16)0); 1.958 + soundEvent(FIFOA_L, (u16)0); 1.959 + soundEvent(FIFOA_H, (u16)0); 1.960 + } 1.961 + } 1.962 + 1.963 + soundDSAValue = (soundDSFifoA[soundDSFifoAIndex]); 1.964 + soundDSFifoAIndex = (++soundDSFifoAIndex) & 31; 1.965 + soundDSFifoACount--; 1.966 + } 1.967 + else 1.968 + soundDSAValue = 0; 1.969 +} 1.970 + 1.971 +void soundDirectSoundB() 1.972 +{ 1.973 + soundBuffer[5][soundIndex] = soundDSBValue; 1.974 +} 1.975 + 1.976 +void soundDirectSoundBTimer() 1.977 +{ 1.978 + if (soundDSBEnabled) 1.979 + { 1.980 + if (soundDSFifoBCount <= 16) 1.981 + { 1.982 + CPUCheckDMA(3, 4); 1.983 + if (soundDSFifoBCount <= 16) 1.984 + { 1.985 + soundEvent(FIFOB_L, (u16)0); 1.986 + soundEvent(FIFOB_H, (u16)0); 1.987 + soundEvent(FIFOB_L, (u16)0); 1.988 + soundEvent(FIFOB_H, (u16)0); 1.989 + soundEvent(FIFOB_L, (u16)0); 1.990 + soundEvent(FIFOB_H, (u16)0); 1.991 + soundEvent(FIFOB_L, (u16)0); 1.992 + soundEvent(FIFOB_H, (u16)0); 1.993 + } 1.994 + } 1.995 + 1.996 + soundDSBValue = (soundDSFifoB[soundDSFifoBIndex]); 1.997 + soundDSFifoBIndex = (++soundDSFifoBIndex) & 31; 1.998 + soundDSFifoBCount--; 1.999 + } 1.1000 + else 1.1001 + { 1.1002 + soundDSBValue = 0; 1.1003 + } 1.1004 +} 1.1005 + 1.1006 +void soundTimerOverflow(int timer) 1.1007 +{ 1.1008 + if (soundDSAEnabled && (soundDSATimer == timer)) 1.1009 + { 1.1010 + soundDirectSoundATimer(); 1.1011 + } 1.1012 + if (soundDSBEnabled && (soundDSBTimer == timer)) 1.1013 + { 1.1014 + soundDirectSoundBTimer(); 1.1015 + } 1.1016 +} 1.1017 + 1.1018 +void soundMix() 1.1019 +{ 1.1020 + int res = 0; 1.1021 + int cgbRes = 0; 1.1022 + int ratio = ioMem[0x82] & 3; 1.1023 + int dsaRatio = ioMem[0x82] & 4; 1.1024 + int dsbRatio = ioMem[0x82] & 8; 1.1025 + 1.1026 + if (ioMem) 1.1027 + soundBalance = (ioMem[NR51] & soundEnableFlag & ~soundMutedFlag); 1.1028 + 1.1029 + if (soundBalance & 16) 1.1030 + { 1.1031 + cgbRes = ((s8)soundBuffer[0][soundIndex]); 1.1032 + } 1.1033 + if (soundBalance & 32) 1.1034 + { 1.1035 + cgbRes += ((s8)soundBuffer[1][soundIndex]); 1.1036 + } 1.1037 + if (soundBalance & 64) 1.1038 + { 1.1039 + cgbRes += ((s8)soundBuffer[2][soundIndex]); 1.1040 + } 1.1041 + if (soundBalance & 128) 1.1042 + { 1.1043 + cgbRes += ((s8)soundBuffer[3][soundIndex]); 1.1044 + } 1.1045 + 1.1046 + if ((soundControl & 0x0200) && (soundEnableFlag & 0x100)) 1.1047 + { 1.1048 + if (!dsaRatio) 1.1049 + res = ((s8)soundBuffer[4][soundIndex]) >> 1; 1.1050 + else 1.1051 + res = ((s8)soundBuffer[4][soundIndex]); 1.1052 + } 1.1053 + 1.1054 + if ((soundControl & 0x2000) && (soundEnableFlag & 0x200)) 1.1055 + { 1.1056 + if (!dsbRatio) 1.1057 + res += ((s8)soundBuffer[5][soundIndex]) >> 1; 1.1058 + else 1.1059 + res += ((s8)soundBuffer[5][soundIndex]); 1.1060 + } 1.1061 + 1.1062 + res = (res * 170); 1.1063 + cgbRes = (cgbRes * 52 * soundLevel1); 1.1064 + 1.1065 + switch (ratio) 1.1066 + { 1.1067 + case 0: 1.1068 + case 3: // prohibited, but 25% 1.1069 + cgbRes >>= 2; 1.1070 + break; 1.1071 + case 1: 1.1072 + cgbRes >>= 1; 1.1073 + break; 1.1074 + case 2: 1.1075 + break; 1.1076 + } 1.1077 + 1.1078 + res += cgbRes; 1.1079 + 1.1080 + if (soundEcho) 1.1081 + { 1.1082 + res *= 2; 1.1083 + res += soundFilter[soundEchoIndex]; 1.1084 + res /= 2; 1.1085 + soundFilter[soundEchoIndex++] = res; 1.1086 + } 1.1087 + 1.1088 + if (soundLowPass) 1.1089 + { 1.1090 + soundLeft[4] = soundLeft[3]; 1.1091 + soundLeft[3] = soundLeft[2]; 1.1092 + soundLeft[2] = soundLeft[1]; 1.1093 + soundLeft[1] = soundLeft[0]; 1.1094 + soundLeft[0] = res; 1.1095 + res = (soundLeft[4] + 2 * soundLeft[3] + 8 * soundLeft[2] + 2 * soundLeft[1] + 1.1096 + soundLeft[0]) / 14; 1.1097 + } 1.1098 + 1.1099 + bool noSpecialEffects = false; 1.1100 +#if (defined(WIN32) && !defined(SDL)) 1.1101 + if (theApp.soundRecording || theApp.aviRecording || theApp.nvAudioLog) 1.1102 + noSpecialEffects = true; 1.1103 +#endif 1.1104 + 1.1105 + if (!noSpecialEffects) 1.1106 + { 1.1107 + switch (soundVolume) 1.1108 + { 1.1109 + case 0: 1.1110 + case 1: 1.1111 + case 2: 1.1112 + case 3: 1.1113 + res *= (soundVolume + 1); 1.1114 + break; 1.1115 + case 4: 1.1116 + res >>= 2; 1.1117 + break; 1.1118 + case 5: 1.1119 + res >>= 1; 1.1120 + break; 1.1121 + } 1.1122 + } 1.1123 + 1.1124 + if (res > 32767) 1.1125 + res = 32767; 1.1126 + if (res < -32768) 1.1127 + res = -32768; 1.1128 + 1.1129 + if (soundReverse && !noSpecialEffects) 1.1130 + { 1.1131 + soundFinalWave[++soundBufferIndex] = res; 1.1132 + if ((soundFrameSoundWritten + 1) >= countof(soundFrameSound)) 1.1133 + /*assert(false)*/; 1.1134 + else 1.1135 + soundFrameSound[++soundFrameSoundWritten] = res; 1.1136 + } 1.1137 + else 1.1138 + { 1.1139 + soundFinalWave[soundBufferIndex++] = res; 1.1140 + if (soundFrameSoundWritten >= countof(soundFrameSound)) 1.1141 + /*assert(false)*/; 1.1142 + else 1.1143 + soundFrameSound[soundFrameSoundWritten++] = res; 1.1144 + } 1.1145 + 1.1146 + res = 0; 1.1147 + cgbRes = 0; 1.1148 + 1.1149 + if (soundBalance & 1) 1.1150 + { 1.1151 + cgbRes = ((s8)soundBuffer[0][soundIndex]); 1.1152 + } 1.1153 + if (soundBalance & 2) 1.1154 + { 1.1155 + cgbRes += ((s8)soundBuffer[1][soundIndex]); 1.1156 + } 1.1157 + if (soundBalance & 4) 1.1158 + { 1.1159 + cgbRes += ((s8)soundBuffer[2][soundIndex]); 1.1160 + } 1.1161 + if (soundBalance & 8) 1.1162 + { 1.1163 + cgbRes += ((s8)soundBuffer[3][soundIndex]); 1.1164 + } 1.1165 + 1.1166 + if ((soundControl & 0x0100) && (soundEnableFlag & 0x100)) 1.1167 + { 1.1168 + if (!dsaRatio) 1.1169 + res = ((s8)soundBuffer[4][soundIndex]) >> 1; 1.1170 + else 1.1171 + res = ((s8)soundBuffer[4][soundIndex]); 1.1172 + } 1.1173 + 1.1174 + if ((soundControl & 0x1000) && (soundEnableFlag & 0x200)) 1.1175 + { 1.1176 + if (!dsbRatio) 1.1177 + res += ((s8)soundBuffer[5][soundIndex]) >> 1; 1.1178 + else 1.1179 + res += ((s8)soundBuffer[5][soundIndex]); 1.1180 + } 1.1181 + 1.1182 + res = (res * 170); 1.1183 + cgbRes = (cgbRes * 52 * soundLevel1); 1.1184 + 1.1185 + switch (ratio) 1.1186 + { 1.1187 + case 0: 1.1188 + case 3: // prohibited, but 25% 1.1189 + cgbRes >>= 2; 1.1190 + break; 1.1191 + case 1: 1.1192 + cgbRes >>= 1; 1.1193 + break; 1.1194 + case 2: 1.1195 + break; 1.1196 + } 1.1197 + 1.1198 + res += cgbRes; 1.1199 + 1.1200 + if (soundEcho) 1.1201 + { 1.1202 + res *= 2; 1.1203 + res += soundFilter[soundEchoIndex]; 1.1204 + res /= 2; 1.1205 + soundFilter[soundEchoIndex++] = res; 1.1206 + 1.1207 + if (soundEchoIndex >= 4000) 1.1208 + soundEchoIndex = 0; 1.1209 + } 1.1210 + 1.1211 + if (soundLowPass) 1.1212 + { 1.1213 + soundRight[4] = soundRight[3]; 1.1214 + soundRight[3] = soundRight[2]; 1.1215 + soundRight[2] = soundRight[1]; 1.1216 + soundRight[1] = soundRight[0]; 1.1217 + soundRight[0] = res; 1.1218 + res = (soundRight[4] + 2 * soundRight[3] + 8 * soundRight[2] + 2 * soundRight[1] + 1.1219 + soundRight[0]) / 14; 1.1220 + } 1.1221 + 1.1222 + if (!noSpecialEffects) 1.1223 + { 1.1224 + switch (soundVolume) 1.1225 + { 1.1226 + case 0: 1.1227 + case 1: 1.1228 + case 2: 1.1229 + case 3: 1.1230 + res *= (soundVolume + 1); 1.1231 + break; 1.1232 + case 4: 1.1233 + res >>= 2; 1.1234 + break; 1.1235 + case 5: 1.1236 + res >>= 1; 1.1237 + break; 1.1238 + } 1.1239 + } 1.1240 + 1.1241 + if (res > 32767) 1.1242 + res = 32767; 1.1243 + if (res < -32768) 1.1244 + res = -32768; 1.1245 + 1.1246 + if (soundReverse && !noSpecialEffects) 1.1247 + { 1.1248 + soundFinalWave[-1 + soundBufferIndex++] = res; 1.1249 + if ((soundFrameSoundWritten) >= countof(soundFrameSound)) 1.1250 + /*assert(false)*/; 1.1251 + else 1.1252 + soundFrameSound[-1 + soundFrameSoundWritten++] = res; 1.1253 + } 1.1254 + else 1.1255 + { 1.1256 + soundFinalWave[soundBufferIndex++] = res; 1.1257 + if ((soundFrameSoundWritten + 1) >= countof(soundFrameSound)) 1.1258 + /*assert(false)*/; 1.1259 + else 1.1260 + soundFrameSound[soundFrameSoundWritten++] = res; 1.1261 + } 1.1262 +} 1.1263 + 1.1264 +void soundTick() 1.1265 +{ 1.1266 + if (systemSoundOn) 1.1267 + { 1.1268 + if (soundMasterOn && !stopState) 1.1269 + { 1.1270 + soundChannel1(); 1.1271 + soundChannel2(); 1.1272 + soundChannel3(); 1.1273 + soundChannel4(); 1.1274 + soundDirectSoundA(); 1.1275 + soundDirectSoundB(); 1.1276 + soundMix(); 1.1277 + } 1.1278 + else 1.1279 + { 1.1280 + soundFinalWave[soundBufferIndex++] = 0; 1.1281 + soundFinalWave[soundBufferIndex++] = 0; 1.1282 + if ((soundFrameSoundWritten + 1) >= countof(soundFrameSound)) 1.1283 + /*assert(false)*/; 1.1284 + else 1.1285 + { 1.1286 + soundFrameSound[soundFrameSoundWritten++] = 0; 1.1287 + soundFrameSound[soundFrameSoundWritten++] = 0; 1.1288 + } 1.1289 + } 1.1290 + 1.1291 + soundIndex++; 1.1292 + 1.1293 + if (2 * soundBufferIndex >= soundBufferLen) 1.1294 + { 1.1295 + if (systemSoundOn) 1.1296 + { 1.1297 + if (soundPaused) 1.1298 + { 1.1299 + soundResume(); 1.1300 + } 1.1301 + 1.1302 + systemSoundWriteToBuffer(); 1.1303 + } 1.1304 + soundIndex = 0; 1.1305 + soundBufferIndex = 0; 1.1306 + } 1.1307 + } 1.1308 +} 1.1309 + 1.1310 +void soundShutdown() 1.1311 +{ 1.1312 + systemSoundShutdown(); 1.1313 +} 1.1314 + 1.1315 +void soundPause() 1.1316 +{ 1.1317 + systemSoundPause(); 1.1318 +} 1.1319 + 1.1320 +void soundResume() 1.1321 +{ 1.1322 + systemSoundResume(); 1.1323 +} 1.1324 + 1.1325 +void soundEnableChannels(int channels) 1.1326 +{ 1.1327 + int c = (channels & 0x0f) << 4; 1.1328 + soundEnableFlag |= ((channels & 0x30f) | c); 1.1329 +} 1.1330 + 1.1331 +void soundDisableChannels(int channels) 1.1332 +{ 1.1333 + int c = (channels & 0x0f) << 4; 1.1334 + soundEnableFlag &= ~((channels & 0x30f) | c); 1.1335 +} 1.1336 + 1.1337 +int soundGetEnabledChannels() 1.1338 +{ 1.1339 + return (soundEnableFlag & 0x30f); 1.1340 +} 1.1341 + 1.1342 +#if 0 1.1343 +// unused 1.1344 +void soundMuteChannels(int channels) 1.1345 +{ 1.1346 + soundMutedFlag |= channels & 0x30f; 1.1347 +} 1.1348 + 1.1349 +void soundUnmuteChannels(int channels) 1.1350 +{ 1.1351 + soundMutedFlag &= ~(channels & 0x30f); 1.1352 +} 1.1353 + 1.1354 +int soundGetMutedChannels() 1.1355 +{ 1.1356 + return (soundMutedFlag & 0x30f); 1.1357 +} 1.1358 +#endif 1.1359 + 1.1360 +void soundReset() 1.1361 +{ 1.1362 + systemSoundReset(); 1.1363 + 1.1364 + soundPaused = 1; 1.1365 + soundPlay = 0; 1.1366 + SOUND_CLOCK_TICKS = soundQuality * USE_TICKS_AS; 1.1367 + soundTicks = SOUND_CLOCK_TICKS; 1.1368 + soundNextPosition = 0; 1.1369 + soundMasterOn = 1; 1.1370 + soundIndex = 0; 1.1371 + soundBufferIndex = 0; 1.1372 + soundLevel1 = 7; 1.1373 + soundLevel2 = 7; 1.1374 + 1.1375 + sound1On = 0; 1.1376 + sound1ATL = 0; 1.1377 + sound1Skip = 0; 1.1378 + sound1Index = 0; 1.1379 + sound1Continue = 0; 1.1380 + sound1EnvelopeVolume = 0; 1.1381 + sound1EnvelopeATL = 0; 1.1382 + sound1EnvelopeUpDown = 0; 1.1383 + sound1EnvelopeATLReload = 0; 1.1384 + sound1SweepATL = 0; 1.1385 + sound1SweepATLReload = 0; 1.1386 + sound1SweepSteps = 0; 1.1387 + sound1SweepUpDown = 0; 1.1388 + sound1SweepStep = 0; 1.1389 + sound1Wave = soundWavePattern[2]; 1.1390 + 1.1391 + sound2On = 0; 1.1392 + sound2ATL = 0; 1.1393 + sound2Skip = 0; 1.1394 + sound2Index = 0; 1.1395 + sound2Continue = 0; 1.1396 + sound2EnvelopeVolume = 0; 1.1397 + sound2EnvelopeATL = 0; 1.1398 + sound2EnvelopeUpDown = 0; 1.1399 + sound2EnvelopeATLReload = 0; 1.1400 + sound2Wave = soundWavePattern[2]; 1.1401 + 1.1402 + sound3On = 0; 1.1403 + sound3ATL = 0; 1.1404 + sound3Skip = 0; 1.1405 + sound3Index = 0; 1.1406 + sound3Continue = 0; 1.1407 + sound3OutputLevel = 0; 1.1408 + sound3Last = 0; 1.1409 + sound3Bank = 0; 1.1410 + sound3DataSize = 0; 1.1411 + sound3ForcedOutput = 0; 1.1412 + 1.1413 + sound4On = 0; 1.1414 + sound4Clock = 0; 1.1415 + sound4ATL = 0; 1.1416 + sound4Skip = 0; 1.1417 + sound4Index = 0; 1.1418 + sound4ShiftRight = 0x7f; 1.1419 + sound4NSteps = 0; 1.1420 + sound4CountDown = 0; 1.1421 + sound4Continue = 0; 1.1422 + sound4EnvelopeVolume = 0; 1.1423 + sound4EnvelopeATL = 0; 1.1424 + sound4EnvelopeUpDown = 0; 1.1425 + sound4EnvelopeATLReload = 0; 1.1426 + 1.1427 + sound1On = 0; 1.1428 + sound2On = 0; 1.1429 + sound3On = 0; 1.1430 + sound4On = 0; 1.1431 + 1.1432 + int addr = 0x90; 1.1433 + 1.1434 + while (addr < 0xA0) 1.1435 + { 1.1436 + ioMem[addr++] = 0x00; 1.1437 + ioMem[addr++] = 0xff; 1.1438 + } 1.1439 + 1.1440 + addr = 0; 1.1441 + while (addr < 0x20) 1.1442 + { 1.1443 + sound3WaveRam[addr++] = 0x00; 1.1444 + sound3WaveRam[addr++] = 0xff; 1.1445 + } 1.1446 + 1.1447 + memset(soundFinalWave, 0, soundBufferLen); 1.1448 + 1.1449 + memset(soundFilter, 0, sizeof(soundFilter)); 1.1450 + soundEchoIndex = 0; 1.1451 +} 1.1452 + 1.1453 +bool soundInit() 1.1454 +{ 1.1455 + if (systemSoundInit()) 1.1456 + { 1.1457 + memset(soundBuffer[0], 0, 735 * 2); 1.1458 + memset(soundBuffer[1], 0, 735 * 2); 1.1459 + memset(soundBuffer[2], 0, 735 * 2); 1.1460 + memset(soundBuffer[3], 0, 735 * 2); 1.1461 + 1.1462 + memset(soundFinalWave, 0, soundBufferLen); 1.1463 + 1.1464 + soundPaused = 1; 1.1465 + return true; 1.1466 + } 1.1467 + return false; 1.1468 +} 1.1469 + 1.1470 +void soundSetQuality(int quality) 1.1471 +{ 1.1472 + if (soundQuality != quality && systemSoundCanChangeQuality()) 1.1473 + { 1.1474 + if (!soundOffFlag) 1.1475 + soundShutdown(); 1.1476 + soundQuality = quality; 1.1477 + soundNextPosition = 0; 1.1478 + if (!soundOffFlag) 1.1479 + soundInit(); 1.1480 + SOUND_CLOCK_TICKS = USE_TICKS_AS * soundQuality; 1.1481 + soundIndex = 0; 1.1482 + soundBufferIndex = 0; 1.1483 + } 1.1484 + else if (soundQuality != quality) 1.1485 + { 1.1486 + soundNextPosition = 0; 1.1487 + SOUND_CLOCK_TICKS = USE_TICKS_AS * soundQuality; 1.1488 + soundIndex = 0; 1.1489 + soundBufferIndex = 0; 1.1490 + } 1.1491 +} 1.1492 + 1.1493 +void soundSaveGame(gzFile gzFile) 1.1494 +{ 1.1495 + soundTicks_int32 = (int32) soundTicks; 1.1496 + SOUND_CLOCK_TICKS_int32 = (int32) SOUND_CLOCK_TICKS; 1.1497 + soundDSBValue_int32 = (int32) soundDSBValue; 1.1498 + 1.1499 + utilWriteData(gzFile, soundSaveStruct); 1.1500 + utilWriteData(gzFile, soundSaveStructV2); 1.1501 + 1.1502 + utilGzWrite(gzFile, &soundQuality, sizeof(int32)); 1.1503 + //utilWriteData(gzFile, soundSaveStructV3); 1.1504 +} 1.1505 + 1.1506 +void soundReadGame(gzFile gzFile, int version) 1.1507 +{ 1.1508 + int32 oldSoundPaused = soundPaused; 1.1509 + int32 oldSoundEnableFlag = soundEnableFlag; 1.1510 + utilReadData(gzFile, soundSaveStruct); 1.1511 + soundPaused = oldSoundPaused; 1.1512 + soundEnableFlag = oldSoundEnableFlag; 1.1513 + 1.1514 + if (version >= SAVE_GAME_VERSION_3) 1.1515 + { 1.1516 + utilReadData(gzFile, soundSaveStructV2); 1.1517 + } 1.1518 + else 1.1519 + { 1.1520 + sound3Bank = (ioMem[NR30] >> 6) & 1; 1.1521 + sound3DataSize = (ioMem[NR30] >> 5) & 1; 1.1522 + sound3ForcedOutput = (ioMem[NR32] >> 7) & 1; 1.1523 + // nothing better to do here... 1.1524 + memcpy(&sound3WaveRam[0x00], &ioMem[0x90], 0x10); 1.1525 + memcpy(&sound3WaveRam[0x10], &ioMem[0x90], 0x10); 1.1526 + } 1.1527 + soundBufferIndex = soundIndex * 2; 1.1528 + 1.1529 + int quality = 1; 1.1530 + utilGzRead(gzFile, &quality, sizeof(int32)); 1.1531 + soundSetQuality(quality); 1.1532 + 1.1533 + sound1Wave = soundWavePattern[ioMem[NR11] >> 6]; 1.1534 + sound2Wave = soundWavePattern[ioMem[NR21] >> 6]; 1.1535 + 1.1536 + //if(version >= SAVE_GAME_VERSION_14) { 1.1537 + // utilReadData(gzFile, soundSaveStructV3); 1.1538 + //} 1.1539 + //else { 1.1540 + soundTicks = (soundtick_t) soundTicks_int32; 1.1541 + SOUND_CLOCK_TICKS = (soundtick_t) SOUND_CLOCK_TICKS_int32; 1.1542 + //} 1.1543 + soundDSBValue = (u8) (soundDSBValue_int32 & 0xff); 1.1544 +} 1.1545 +