1 #include <string.h>
2
3 #include "../gba/Sound.h"
4 #include "../Util.h"
5 #include "gbGlobals.h"
6 #include "gbSound.h"
7 #include "gb.h"
8
9 #include "../apu/Gb_Apu.h"
10 #include "../apu/Effects_Buffer.h"
11
12 extern long soundSampleRate; // current sound quality
13
14 gb_effects_config_t gb_effects_config = { false, 0.20f, 0.15f, false };
15
16 static gb_effects_config_t gb_effects_config_current;
17 static Simple_Effects_Buffer* stereo_buffer;
18 static Gb_Apu* gb_apu;
19
20 static float soundVolume_ = -1;
21 static int prevSoundEnable = -1;
22 static bool declicking = false;
23
24 int const chan_count = 4;
25 int const ticks_to_time = 2 * GB_APU_OVERCLOCK;
26
blip_time()27 static inline blip_time_t blip_time()
28 {
29 return (SOUND_CLOCK_TICKS - soundTicks) * ticks_to_time;
30 }
31
gbSoundRead(u16 address)32 u8 gbSoundRead( u16 address )
33 {
34 if ( gb_apu && address >= NR10 && address <= 0xFF3F )
35 return gb_apu->read_register( blip_time(), address );
36
37 return gbMemory[address];
38 }
39
gbSoundEvent(register u16 address,register int data)40 void gbSoundEvent(register u16 address, register int data)
41 {
42 gbMemory[address] = data;
43
44 if ( gb_apu && address >= NR10 && address <= 0xFF3F )
45 gb_apu->write_register( blip_time(), address, data );
46 }
47
end_frame(blip_time_t time)48 static void end_frame( blip_time_t time )
49 {
50 gb_apu ->end_frame( time );
51 stereo_buffer->end_frame( time );
52 }
53
apply_effects()54 static void apply_effects()
55 {
56 prevSoundEnable = soundGetEnable();
57 gb_effects_config_current = gb_effects_config;
58
59 stereo_buffer->config().enabled = gb_effects_config_current.enabled;
60 stereo_buffer->config().echo = gb_effects_config_current.echo;
61 stereo_buffer->config().stereo = gb_effects_config_current.stereo;
62 stereo_buffer->config().surround = gb_effects_config_current.surround;
63 stereo_buffer->apply_config();
64
65 for ( int i = 0; i < chan_count; i++ )
66 {
67 Multi_Buffer::channel_t ch = { 0, 0, 0 };
68 if ( prevSoundEnable >> i & 1 )
69 ch = stereo_buffer->channel( i );
70 gb_apu->set_output( ch.center, ch.left, ch.right, i );
71 }
72 }
73
gbSoundConfigEffects(gb_effects_config_t const & c)74 void gbSoundConfigEffects( gb_effects_config_t const& c )
75 {
76 gb_effects_config = c;
77 }
78
apply_volume()79 static void apply_volume()
80 {
81 soundVolume_ = soundGetVolume();
82
83 if ( gb_apu )
84 gb_apu->volume( soundVolume_ );
85 }
86
gbSoundTick()87 void gbSoundTick()
88 {
89 if ( gb_apu && stereo_buffer )
90 {
91 // Run sound hardware to present
92 end_frame( SOUND_CLOCK_TICKS * ticks_to_time );
93
94 flush_samples(stereo_buffer);
95
96 // Update effects config if it was changed
97 if ( memcmp( &gb_effects_config_current, &gb_effects_config,
98 sizeof gb_effects_config ) || soundGetEnable() != prevSoundEnable )
99 apply_effects();
100
101 if ( soundVolume_ != soundGetVolume() )
102 apply_volume();
103 }
104 }
105
reset_apu()106 static void reset_apu()
107 {
108 Gb_Apu::mode_t mode = Gb_Apu::mode_dmg;
109 if ( gbHardware & 2 )
110 mode = Gb_Apu::mode_cgb;
111 if ( gbHardware & 8 || declicking )
112 mode = Gb_Apu::mode_agb;
113 gb_apu->reset( mode );
114 gb_apu->reduce_clicks( declicking );
115
116 if ( stereo_buffer )
117 stereo_buffer->clear();
118
119 soundTicks = SOUND_CLOCK_TICKS;
120 }
121
remake_stereo_buffer()122 static void remake_stereo_buffer()
123 {
124 // APU
125 if ( !gb_apu )
126 {
127 gb_apu = new Gb_Apu; // TODO: handle errors
128 reset_apu();
129 }
130
131 // Stereo_Buffer
132 delete stereo_buffer;
133 stereo_buffer = 0;
134
135 stereo_buffer = new Simple_Effects_Buffer; // TODO: handle out of memory
136 if ( stereo_buffer->set_sample_rate( soundSampleRate ) ) { } // TODO: handle out of memory
137 stereo_buffer->clock_rate( gb_apu->clock_rate );
138
139 // Multi_Buffer
140 static int const chan_types [chan_count] = {
141 Multi_Buffer::wave_type+1, Multi_Buffer::wave_type+2,
142 Multi_Buffer::wave_type+3, Multi_Buffer::mixed_type+1
143 };
144 if ( stereo_buffer->set_channel_count( chan_count, chan_types ) ) { } // TODO: handle errors
145
146 // Volume Level
147 apply_effects();
148 apply_volume();
149 }
150
gbSoundSetDeclicking(bool enable)151 void gbSoundSetDeclicking( bool enable )
152 {
153 if ( declicking != enable )
154 {
155 declicking = enable;
156 if ( gb_apu )
157 {
158 // Can't change sound hardware mode without resetting APU, so save/load
159 // state around mode change
160 gb_apu_state_t state;
161 gb_apu->save_state( &state );
162 reset_apu();
163 if ( gb_apu->load_state( state ) ) { } // ignore error
164 }
165 }
166 }
167
gbSoundGetDeclicking()168 bool gbSoundGetDeclicking()
169 {
170 return declicking;
171 }
172
gbSoundReset()173 void gbSoundReset()
174 {
175 SOUND_CLOCK_TICKS = 20000; // 1/100 second
176
177 remake_stereo_buffer();
178 reset_apu();
179
180 soundPaused = 1;
181
182 gbSoundEvent(0xff10, 0x80);
183 gbSoundEvent(0xff11, 0xbf);
184 gbSoundEvent(0xff12, 0xf3);
185 gbSoundEvent(0xff14, 0xbf);
186 gbSoundEvent(0xff16, 0x3f);
187 gbSoundEvent(0xff17, 0x00);
188 gbSoundEvent(0xff19, 0xbf);
189
190 gbSoundEvent(0xff1a, 0x7f);
191 gbSoundEvent(0xff1b, 0xff);
192 gbSoundEvent(0xff1c, 0xbf);
193 gbSoundEvent(0xff1e, 0xbf);
194
195 gbSoundEvent(0xff20, 0xff);
196 gbSoundEvent(0xff21, 0x00);
197 gbSoundEvent(0xff22, 0x00);
198 gbSoundEvent(0xff23, 0xbf);
199 gbSoundEvent(0xff24, 0x77);
200 gbSoundEvent(0xff25, 0xf3);
201
202 if (gbHardware & 0x4)
203 gbSoundEvent(0xff26, 0xf0);
204 else
205 gbSoundEvent(0xff26, 0xf1);
206
207 /* workaround for game Beetlejuice */
208 if (gbHardware & 0x1) {
209 gbSoundEvent(0xff24, 0x77);
210 gbSoundEvent(0xff25, 0xf3);
211 }
212
213 int addr = 0xff30;
214
215 while(addr < 0xff40) {
216 gbMemory[addr++] = 0x00;
217 gbMemory[addr++] = 0xff;
218 }
219 }
220
gbSoundSetSampleRate(long sampleRate)221 void gbSoundSetSampleRate( long sampleRate )
222 {
223 if ( soundSampleRate != sampleRate )
224 {
225 if ( systemCanChangeSoundQuality() )
226 {
227 soundShutdown();
228 soundSampleRate = sampleRate;
229 soundInit();
230 }
231 else
232 {
233 soundSampleRate = sampleRate;
234 }
235
236 remake_stereo_buffer();
237 }
238 }
239
240 static struct {
241 int version;
242 gb_apu_state_t apu;
243 } state;
244
245 static char dummy_state [735 * 2];
246
247 #define SKIP( type, name ) { dummy_state, sizeof (type) }
248
249 #define LOAD( type, name ) { &name, sizeof (type) }
250
251 // Old save state support
252
253 static variable_desc gbsound_format [] =
254 {
255 SKIP( int, soundPaused ),
256 SKIP( int, soundPlay ),
257 SKIP( int, soundTicks ),
258 SKIP( int, SOUND_CLOCK_TICKS ),
259 SKIP( int, soundLevel1 ),
260 SKIP( int, soundLevel2 ),
261 SKIP( int, soundBalance ),
262 SKIP( int, soundMasterOn ),
263 SKIP( int, soundIndex ),
264 SKIP( int, soundVIN ),
265 SKIP( int, soundOn [0] ),
266 SKIP( int, soundATL [0] ),
267 SKIP( int, sound1Skip ),
268 SKIP( int, soundIndex [0] ),
269 SKIP( int, sound1Continue ),
270 SKIP( int, soundEnvelopeVolume [0] ),
271 SKIP( int, soundEnvelopeATL [0] ),
272 SKIP( int, sound1EnvelopeATLReload ),
273 SKIP( int, sound1EnvelopeUpDown ),
274 SKIP( int, sound1SweepATL ),
275 SKIP( int, sound1SweepATLReload ),
276 SKIP( int, sound1SweepSteps ),
277 SKIP( int, sound1SweepUpDown ),
278 SKIP( int, sound1SweepStep ),
279 SKIP( int, soundOn [1] ),
280 SKIP( int, soundATL [1] ),
281 SKIP( int, sound2Skip ),
282 SKIP( int, soundIndex [1] ),
283 SKIP( int, sound2Continue ),
284 SKIP( int, soundEnvelopeVolume [1] ),
285 SKIP( int, soundEnvelopeATL [1] ),
286 SKIP( int, sound2EnvelopeATLReload ),
287 SKIP( int, sound2EnvelopeUpDown ),
288 SKIP( int, soundOn [2] ),
289 SKIP( int, soundATL [2] ),
290 SKIP( int, sound3Skip ),
291 SKIP( int, soundIndex [2] ),
292 SKIP( int, sound3Continue ),
293 SKIP( int, sound3OutputLevel ),
294 SKIP( int, soundOn [3] ),
295 SKIP( int, soundATL [3] ),
296 SKIP( int, sound4Skip ),
297 SKIP( int, soundIndex [3] ),
298 SKIP( int, sound4Clock ),
299 SKIP( int, sound4ShiftRight ),
300 SKIP( int, sound4ShiftSkip ),
301 SKIP( int, sound4ShiftIndex ),
302 SKIP( int, sound4NSteps ),
303 SKIP( int, sound4CountDown ),
304 SKIP( int, sound4Continue ),
305 SKIP( int, soundEnvelopeVolume [2] ),
306 SKIP( int, soundEnvelopeATL [2] ),
307 SKIP( int, sound4EnvelopeATLReload ),
308 SKIP( int, sound4EnvelopeUpDown ),
309 SKIP( int, soundEnableFlag ),
310 { NULL, 0 }
311 };
312
313 static variable_desc gbsound_format2 [] =
314 {
315 SKIP( int, sound1ATLreload ),
316 SKIP( int, freq1low ),
317 SKIP( int, freq1high ),
318 SKIP( int, sound2ATLreload ),
319 SKIP( int, freq2low ),
320 SKIP( int, freq2high ),
321 SKIP( int, sound3ATLreload ),
322 SKIP( int, freq3low ),
323 SKIP( int, freq3high ),
324 SKIP( int, sound4ATLreload ),
325 SKIP( int, freq4 ),
326 { NULL, 0 }
327 };
328
329 static variable_desc gbsound_format3 [] =
330 {
331 SKIP( u8[2*735], soundBuffer ),
332 SKIP( u8[2*735], soundBuffer ),
333 SKIP( u16[735], soundFinalWave ),
334 { NULL, 0 }
335 };
336
337 enum {
338 nr10 = 0,
339 nr11, nr12, nr13, nr14,
340 nr20, nr21, nr22, nr23, nr24,
341 nr30, nr31, nr32, nr33, nr34,
342 nr40, nr41, nr42, nr43, nr44,
343 nr50, nr51, nr52
344 };
345
gbSoundReadGameOld(int version,gzFile gzFile)346 static void gbSoundReadGameOld(int version,gzFile gzFile)
347 {
348 if ( version == 11 )
349 {
350 // Version 11 didn't save any state
351 // TODO: same for version 10?
352 state.apu.regs [nr50] = 0x77; // volume at max
353 state.apu.regs [nr51] = 0xFF; // channels enabled
354 state.apu.regs [nr52] = 0x80; // power on
355 return;
356 }
357
358 // Load state
359 utilReadData( gzFile, gbsound_format );
360
361 if ( version >= 11 ) // TODO: never executed; remove?
362 utilReadData( gzFile, gbsound_format2 );
363
364 utilReadData( gzFile, gbsound_format3 );
365
366 int quality = 1;
367 if ( version >= 7 )
368 quality = utilReadInt( gzFile );
369
370 gbSoundSetSampleRate( 44100 / quality );
371
372 // Convert to format Gb_Apu uses
373 gb_apu_state_t& s = state.apu;
374
375 // Only some registers are properly preserved
376 static int const regs_to_copy [] = {
377 nr10, nr11, nr12, nr21, nr22, nr30, nr32, nr42, nr43, nr50, nr51, nr52, -1
378 };
379 for ( int i = 0; regs_to_copy [i] >= 0; i++ )
380 s.regs [regs_to_copy [i]] = gbMemory [0xFF10 + regs_to_copy [i]];
381
382 memcpy( &s.regs [0x20], &gbMemory [0xFF30], 0x10 ); // wave
383 }
384
385 // New state format
386
387 static variable_desc gb_state [] =
388 {
389 LOAD( int, state.version ), // room_for_expansion will be used by later versions
390
391 // APU
392 LOAD( u8 [0x40], state.apu.regs ), // last values written to registers and wave RAM (both banks)
393 LOAD( int, state.apu.frame_time ), // clocks until next frame sequencer action
394 LOAD( int, state.apu.frame_phase ), // next step frame sequencer will run
395
396 LOAD( int, state.apu.sweep_freq ), // sweep's internal frequency register
397 LOAD( int, state.apu.sweep_delay ), // clocks until next sweep action
398 LOAD( int, state.apu.sweep_enabled ),
399 LOAD( int, state.apu.sweep_neg ), // obscure internal flag
400 LOAD( int, state.apu.noise_divider ),
401 LOAD( int, state.apu.wave_buf ), // last read byte of wave RAM
402
403 LOAD( int [4], state.apu.delay ), // clocks until next channel action
404 LOAD( int [4], state.apu.length_ctr ),
405 LOAD( int [4], state.apu.phase ), // square/wave phase, noise LFSR
406 LOAD( int [4], state.apu.enabled ), // internal enabled flag
407
408 LOAD( int [3], state.apu.env_delay ), // clocks until next envelope action
409 LOAD( int [3], state.apu.env_volume ),
410 LOAD( int [3], state.apu.env_enabled ),
411
412 SKIP( int [13], room_for_expansion ),
413
414 // Emulator
415 SKIP( int [16], room_for_expansion ),
416
417 { NULL, 0 }
418 };
419
gbSoundSaveGame(gzFile out)420 void gbSoundSaveGame( gzFile out )
421 {
422 gb_apu->save_state( &state.apu );
423
424 // Be sure areas for expansion get written as zero
425 memset( dummy_state, 0, sizeof dummy_state );
426
427 state.version = 1;
428 utilWriteData( out, gb_state );
429 }
430
gbSoundReadGame(int version,gzFile in)431 void gbSoundReadGame( int version, gzFile in )
432 {
433 // Prepare APU and default state
434 reset_apu();
435 gb_apu->save_state( &state.apu );
436
437 if ( version > 11 )
438 utilReadData( in, gb_state );
439 else
440 gbSoundReadGameOld( version, in );
441
442 gb_apu->load_state( state.apu );
443 }
444