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