3rd part of FS#12176. Gain setting migrated to fixed point for libgme.
[kugel-rb.git] / apps / codecs / libgme / gbs_emu.c
blob664510d5fafe3a610ed8764e8f239f6f3647ee38
1 // Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
3 #include "gbs_emu.h"
5 #include "blargg_endian.h"
6 #include "blargg_source.h"
8 /* Copyright (C) 2003-2006 Shay Green. this module is free software; you
9 can redistribute it and/or modify it under the terms of the GNU Lesser
10 General Public License as published by the Free Software Foundation; either
11 version 2.1 of the License, or (at your option) any later version. this
12 module is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
15 details. You should have received a copy of the GNU Lesser General Public
16 License along with this module; if not, write to the Free Software Foundation,
17 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
20 const char gme_wrong_file_type [] ICONST_ATTR = "Wrong file type for this emulator";
22 int const idle_addr = 0xF00D;
23 int const tempo_unit = 16;
25 int const stereo = 2; // number of channels for stereo
26 int const silence_max = 6; // seconds
27 int const silence_threshold = 0x10;
28 long const fade_block_size = 512;
29 int const fade_shift = 8; // fade ends with gain at 1.0 / (1 << fade_shift)
31 void clear_track_vars( struct Gbs_Emu* this )
33 this->current_track_ = -1;
34 this->out_time = 0;
35 this->emu_time = 0;
36 this->emu_track_ended_ = true;
37 this->track_ended = true;
38 this->fade_start = (blargg_long)(LONG_MAX / 2 + 1);
39 this->fade_step = 1;
40 this->silence_time = 0;
41 this->silence_count = 0;
42 this->buf_remain = 0;
45 void Gbs_init( struct Gbs_Emu* this )
47 this->sample_rate_ = 0;
48 this->mute_mask_ = 0;
49 this->tempo_ = (int)(FP_ONE_TEMPO);
51 // Unload
52 this->header.timer_mode = 0;
53 clear_track_vars( this );
55 this->ignore_silence = false;
56 this->silence_lookahead = 6;
57 this->max_initial_silence = 21;
58 Sound_set_gain( this, (int)(FP_ONE_GAIN*1.2) );
60 Rom_init( &this->rom, 0x4000 );
62 Apu_init( &this->apu );
63 Cpu_init( &this->cpu );
65 this->tempo = tempo_unit;
66 this->sound_hardware = sound_gbs;
68 // Reduce apu sound clicks?
69 Apu_reduce_clicks( &this->apu, true );
72 static blargg_err_t check_gbs_header( void const* header )
74 if ( memcmp( header, "GBS", 3 ) )
75 return gme_wrong_file_type;
76 return 0;
79 // Setup
81 blargg_err_t Gbs_load( struct Gbs_Emu* this, void* data, long size )
83 // Unload
84 this->header.timer_mode = 0;
85 this->voice_count_ = 0;
86 this->m3u.size = 0;
87 clear_track_vars( this );
89 assert( offsetof (struct header_t,copyright [32]) == header_size );
90 RETURN_ERR( Rom_load( &this->rom, data, size, header_size, &this->header, 0 ) );
92 RETURN_ERR( check_gbs_header( &this->header ) );
94 /* Ignore warnings? */
95 /*if ( header_.vers != 1 )
96 warning( "Unknown file version" );
98 if ( header_.timer_mode & 0x78 )
99 warning( "Invalid timer mode" ); */
101 /* unsigned load_addr = get_le16( this->header.load_addr ); */
102 /* if ( (header_.load_addr [1] | header_.init_addr [1] | header_.play_addr [1]) > 0x7F ||
103 load_addr < 0x400 )
104 warning( "Invalid load/init/play address" ); */
106 unsigned load_addr = get_le16( this->header.load_addr );
107 /* if ( (this->header.load_addr [1] | this->header.init_addr [1] | this->header.play_addr [1]) > 0x7F ||
108 load_addr < 0x400 )
109 warning( "Invalid load/init/play address" ); */
111 this->cpu.rst_base = load_addr;
112 Rom_set_addr( &this->rom, load_addr );
114 this->voice_count_ = osc_count;
115 Apu_volume( &this->apu, (double)(this->gain_)/FP_ONE_GAIN );
117 // Change clock rate & setup buffer
118 this->clock_rate_ = 4194304;
119 Buffer_clock_rate( &this->stereo_buf, 4194304 );
120 this->buf_changed_count = Buffer_channels_changed_count( &this->stereo_buf );
122 // Post load
123 Sound_set_tempo( this, this->tempo_ );
125 // Remute voices
126 Sound_mute_voices( this, this->mute_mask_ );
128 // Reset track count
129 this->track_count = this->header.track_count;
130 return 0;
133 // Emulation
135 // see gb_cpu_io.h for read/write functions
137 void Set_bank( struct Gbs_Emu* this, int n )
139 addr_t addr = mask_addr( n * this->rom.bank_size, this->rom.mask );
140 if ( addr == 0 && this->rom.size > this->rom.bank_size )
141 addr = this->rom.bank_size; // MBC1&2 behavior, bank 0 acts like bank 1
142 Cpu_map_code( &this->cpu, this->rom.bank_size, this->rom.bank_size, Rom_at_addr( &this->rom, addr ) );
145 void Update_timer( struct Gbs_Emu* this )
147 this->play_period = 70224 / tempo_unit; /// 59.73 Hz
149 if ( this->header.timer_mode & 0x04 )
151 // Using custom rate
152 static byte const rates [4] = { 6, 0, 2, 4 };
153 // TODO: emulate double speed CPU mode rather than halving timer rate
154 int double_speed = this->header.timer_mode >> 7;
155 int shift = rates [this->ram [hi_page + 7] & 3] - double_speed;
156 this->play_period = (256 - this->ram [hi_page + 6]) << shift;
159 this->play_period *= this->tempo;
162 // Jumps to routine, given pointer to address in file header. Pushes idle_addr
163 // as return address, NOT old PC.
164 void Jsr_then_stop( struct Gbs_Emu* this, byte const addr [] )
166 check( this->cpu.r.sp == get_le16( this->header.stack_ptr ) );
167 this->cpu.r.pc = get_le16( addr );
168 Write_mem( this, --this->cpu.r.sp, idle_addr >> 8 );
169 Write_mem( this, --this->cpu.r.sp, idle_addr );
172 blargg_err_t Run_until( struct Gbs_Emu* this, int end )
174 this->end_time = end;
175 Cpu_set_time( &this->cpu, Cpu_time( &this->cpu ) - end );
176 while ( true )
178 Run_cpu( this );
179 if ( Cpu_time( &this->cpu ) >= 0 )
180 break;
182 if ( this->cpu.r.pc == idle_addr )
184 if ( this->next_play > this->end_time )
186 Cpu_set_time( &this->cpu, 0 );
187 break;
190 if ( Cpu_time( &this->cpu ) < this->next_play - this->end_time )
191 Cpu_set_time( &this->cpu, this->next_play - this->end_time );
192 this->next_play += this->play_period;
193 Jsr_then_stop( this, this->header.play_addr );
195 else if ( this->cpu.r.pc > 0xFFFF )
197 /* warning( "PC wrapped around\n" ); */
198 this->cpu.r.pc &= 0xFFFF;
200 else
202 /* warning( "Emulation error (illegal/unsupported instruction)" ); */
203 this->cpu.r.pc = (this->cpu.r.pc + 1) & 0xFFFF;
204 Cpu_set_time( &this->cpu, Cpu_time( &this->cpu ) + 6 );
208 return 0;
211 blargg_err_t End_frame( struct Gbs_Emu* this, int end )
213 RETURN_ERR( Run_until( this, end ) );
215 this->next_play -= end;
216 if ( this->next_play < 0 ) // happens when play routine takes too long
218 #if !defined(GBS_IGNORE_STARVED_PLAY)
219 check( false );
220 #endif
221 this->next_play = 0;
224 Apu_end_frame( &this->apu, end );
226 return 0;
229 blargg_err_t Run_clocks( struct Gbs_Emu* this, blip_time_t duration )
231 return End_frame( this, duration );
234 blargg_err_t play_( struct Gbs_Emu* this, long count, sample_t* out )
236 long remain = count;
237 while ( remain )
239 remain -= Buffer_read_samples( &this->stereo_buf, &out [count - remain], remain );
240 if ( remain )
242 if ( this->buf_changed_count != Buffer_channels_changed_count( &this->stereo_buf ) )
244 this->buf_changed_count = Buffer_channels_changed_count( &this->stereo_buf );
246 // Remute voices
247 Sound_mute_voices( this, this->mute_mask_ );
249 int msec = Buffer_length( &this->stereo_buf );
250 blip_time_t clocks_emulated = (blargg_long) msec * this->clock_rate_ / 1000;
251 RETURN_ERR( Run_clocks( this, clocks_emulated ) );
252 assert( clocks_emulated );
253 Buffer_end_frame( &this->stereo_buf, clocks_emulated );
256 return 0;
259 blargg_err_t Gbs_set_sample_rate( struct Gbs_Emu* this, long rate )
261 require( !this->sample_rate_ ); // sample rate can't be changed once set
262 Buffer_init( &this->stereo_buf );
263 RETURN_ERR( Buffer_set_sample_rate( &this->stereo_buf, rate, 1000 / 20 ) );
265 // Set bass frequency
266 Buffer_bass_freq( &this->stereo_buf, 300 );
268 this->sample_rate_ = rate;
269 return 0;
273 // Sound
275 void Sound_mute_voice( struct Gbs_Emu* this, int index, bool mute )
277 require( (unsigned) index < (unsigned) this->voice_count_ );
278 int bit = 1 << index;
279 int mask = this->mute_mask_ | bit;
280 if ( !mute )
281 mask ^= bit;
282 Sound_mute_voices( this, mask );
285 void Sound_mute_voices( struct Gbs_Emu* this, int mask )
287 require( this->sample_rate_ ); // sample rate must be set first
288 this->mute_mask_ = mask;
290 int i;
291 for ( i = this->voice_count_; i--; )
293 if ( mask & (1 << i) )
295 Apu_set_output( &this->apu, i, 0, 0, 0 );
297 else
299 struct channel_t ch = Buffer_channel( &this->stereo_buf );
300 assert( (ch.center && ch.left && ch.right) ||
301 (!ch.center && !ch.left && !ch.right) ); // all or nothing
302 Apu_set_output( &this->apu, i, ch.center, ch.left, ch.right );
307 void Sound_set_tempo( struct Gbs_Emu* this, int t )
309 require( this->sample_rate_ ); // sample rate must be set first
310 int const min = (int)(FP_ONE_TEMPO*0.02);
311 int const max = (int)(FP_ONE_TEMPO*4.00);
312 if ( t < min ) t = min;
313 if ( t > max ) t = max;
314 this->tempo_ = t;
316 this->tempo = (int) ((tempo_unit * FP_ONE_TEMPO) / t);
317 Apu_set_tempo( &this->apu, t );
318 Update_timer( this );
321 void fill_buf( struct Gbs_Emu* this );
322 blargg_err_t Gbs_start_track( struct Gbs_Emu* this, int track )
324 clear_track_vars( this );
326 // Remap track if playlist available
327 if ( this->m3u.size > 0 ) {
328 struct entry_t* e = &this->m3u.entries[track];
329 track = e->track;
332 this->current_track_ = track;
334 Buffer_clear( &this->stereo_buf );
336 // Reset APU to state expected by most rips
337 static byte const sound_data [] ICONST_ATTR = {
338 0x80, 0xBF, 0x00, 0x00, 0xB8, // square 1 DAC disabled
339 0x00, 0x3F, 0x00, 0x00, 0xB8, // square 2 DAC disabled
340 0x7F, 0xFF, 0x9F, 0x00, 0xB8, // wave DAC disabled
341 0x00, 0xFF, 0x00, 0x00, 0xB8, // noise DAC disabled
342 0x77, 0xFF, 0x80, // max volume, all chans in center, power on
345 enum sound_t mode = this->sound_hardware;
346 if ( mode == sound_gbs )
347 mode = (this->header.timer_mode & 0x80) ? sound_cgb : sound_dmg;
349 Apu_reset( &this->apu, (enum gb_mode_t) mode, false );
350 Apu_write_register( &this->apu, 0, 0xFF26, 0x80 ); // power on
351 int i;
352 for ( i = 0; i < (int) sizeof sound_data; i++ )
353 Apu_write_register( &this->apu, 0, i + io_addr, sound_data [i] );
354 Apu_end_frame( &this->apu, 1 ); // necessary to get click out of the way */
356 memset( this->ram, 0, 0x4000 );
357 memset( this->ram + 0x4000, 0xFF, 0x1F80 );
358 memset( this->ram + 0x5F80, 0, sizeof this->ram - 0x5F80 );
359 this->ram [hi_page] = 0; // joypad reads back as 0
360 this->ram [idle_addr - ram_addr] = 0xED; // illegal instruction
361 this->ram [hi_page + 6] = this->header.timer_modulo;
362 this->ram [hi_page + 7] = this->header.timer_mode;
364 Cpu_reset( &this->cpu, this->rom.unmapped );
365 Cpu_map_code( &this->cpu, ram_addr, 0x10000 - ram_addr, this->ram );
366 Cpu_map_code( &this->cpu, 0, this->rom.bank_size, Rom_at_addr( &this->rom, 0 ) );
367 Set_bank( this, this->rom.size > this->rom.bank_size );
369 Update_timer( this );
370 this->next_play = this->play_period;
371 this->cpu.r.rp.fa = track;
372 this->cpu.r.sp = get_le16( this->header.stack_ptr );
373 this->cpu_time = 0;
374 Jsr_then_stop( this, this->header.init_addr );
376 this->emu_track_ended_ = false;
377 this->track_ended = false;
379 if ( !this->ignore_silence )
381 // play until non-silence or end of track
382 long end;
383 for ( end = this->max_initial_silence * stereo * this->sample_rate_; this->emu_time < end; )
385 fill_buf( this );
386 if ( this->buf_remain | (int) this->emu_track_ended_ )
387 break;
390 this->emu_time = this->buf_remain;
391 this->out_time = 0;
392 this->silence_time = 0;
393 this->silence_count = 0;
395 /* return track_ended() ? warning() : 0; */
396 return 0;
400 // Track
402 blargg_long msec_to_samples( blargg_long msec, long sample_rate )
404 blargg_long sec = msec / 1000;
405 msec -= sec * 1000;
406 return (sec * sample_rate + msec * sample_rate / 1000) * stereo;
409 long Track_tell( struct Gbs_Emu* this )
411 blargg_long rate = this->sample_rate_ * stereo;
412 blargg_long sec = this->out_time / rate;
413 return sec * 1000 + (this->out_time - sec * rate) * 1000 / rate;
416 blargg_err_t Track_seek( struct Gbs_Emu* this, long msec )
418 blargg_long time = msec_to_samples( msec, this->sample_rate_ );
419 if ( time < this->out_time )
420 RETURN_ERR( Gbs_start_track( this, this->current_track_ ) );
421 return Track_skip( this, time - this->out_time );
424 blargg_err_t skip_( struct Gbs_Emu* this, long count )
426 // for long skip, mute sound
427 const long threshold = 30000;
428 if ( count > threshold )
430 int saved_mute = this->mute_mask_;
431 Sound_mute_voices( this, ~0 );
433 while ( count > threshold / 2 && !this->emu_track_ended_ )
435 RETURN_ERR( play_( this, buf_size, this->buf ) );
436 count -= buf_size;
439 Sound_mute_voices( this, saved_mute );
442 while ( count && !this->emu_track_ended_ )
444 long n = buf_size;
445 if ( n > count )
446 n = count;
447 count -= n;
448 RETURN_ERR( play_( this, n, this->buf ) );
450 return 0;
453 blargg_err_t Track_skip( struct Gbs_Emu* this, long count )
455 require( this->current_track_ >= 0 ); // start_track() must have been called already
456 this->out_time += count;
458 // remove from silence and buf first
460 long n = min( count, this->silence_count );
461 this->silence_count -= n;
462 count -= n;
464 n = min( count, this->buf_remain );
465 this->buf_remain -= n;
466 count -= n;
469 if ( count && !this->emu_track_ended_ )
471 this->emu_time += count;
472 // End track if error
473 if ( skip_( this, count ) )
474 this->emu_track_ended_ = true;
477 if ( !(this->silence_count | this->buf_remain) ) // caught up to emulator, so update track ended
478 this->track_ended |= this->emu_track_ended_;
480 return 0;
483 // Fading
485 void Track_set_fade( struct Gbs_Emu* this, long start_msec, long length_msec )
487 this->fade_step = this->sample_rate_ * length_msec / (fade_block_size * fade_shift * 1000 / stereo);
488 this->fade_start = msec_to_samples( start_msec, this->sample_rate_ );
491 // unit / pow( 2.0, (double) x / step )
492 static int int_log( blargg_long x, int step, int unit )
494 int shift = x / step;
495 int fraction = (x - shift * step) * unit / step;
496 return ((unit - fraction) + (fraction >> 1)) >> shift;
499 void handle_fade( struct Gbs_Emu* this, long out_count, sample_t* out )
501 int i;
502 for ( i = 0; i < out_count; i += fade_block_size )
504 int const shift = 14;
505 int const unit = 1 << shift;
506 int gain = int_log( (this->out_time + i - this->fade_start) / fade_block_size,
507 this->fade_step, unit );
508 if ( gain < (unit >> fade_shift) )
509 this->track_ended = this->emu_track_ended_ = true;
511 sample_t* io = &out [i];
512 int count;
513 for ( count = min( fade_block_size, out_count - i ); count; --count )
515 *io = (sample_t) ((*io * gain) >> shift);
516 ++io;
521 // Silence detection
523 void emu_play( struct Gbs_Emu* this, long count, sample_t* out )
525 check( current_track_ >= 0 );
526 this->emu_time += count;
527 if ( this->current_track_ >= 0 && !this->emu_track_ended_ ) {
528 // End track if error
529 if ( play_( this, count, out ) ) this->emu_track_ended_ = true;
531 else
532 memset( out, 0, count * sizeof *out );
535 // number of consecutive silent samples at end
536 static long count_silence( sample_t* begin, long size )
538 sample_t first = *begin;
539 *begin = silence_threshold; // sentinel
540 sample_t* p = begin + size;
541 while ( (unsigned) (*--p + silence_threshold / 2) <= (unsigned) silence_threshold ) { }
542 *begin = first;
543 return size - (p - begin);
546 // fill internal buffer and check it for silence
547 void fill_buf( struct Gbs_Emu* this )
549 assert( !this->buf_remain );
550 if ( !this->emu_track_ended_ )
552 emu_play( this, buf_size, this->buf );
553 long silence = count_silence( this->buf, buf_size );
554 if ( silence < buf_size )
556 this->silence_time = this->emu_time - silence;
557 this->buf_remain = buf_size;
558 return;
561 this->silence_count += buf_size;
564 blargg_err_t Gbs_play( struct Gbs_Emu* this, long out_count, sample_t* out )
566 if ( this->track_ended )
568 memset( out, 0, out_count * sizeof *out );
570 else
572 require( this->current_track_ >= 0 );
573 require( out_count % stereo == 0 );
575 assert( this->emu_time >= this->out_time );
577 long pos = 0;
578 if ( this->silence_count )
580 // during a run of silence, run emulator at >=2x speed so it gets ahead
581 long ahead_time = this->silence_lookahead * (this->out_time + out_count - this->silence_time) + this->silence_time;
582 while ( this->emu_time < ahead_time && !(this->buf_remain | this->emu_track_ended_) )
583 fill_buf( this );
585 // fill with silence
586 pos = min( this->silence_count, out_count );
587 memset( out, 0, pos * sizeof *out );
588 this->silence_count -= pos;
590 if ( this->emu_time - this->silence_time > silence_max * stereo * this->sample_rate_ )
592 this->track_ended = this->emu_track_ended_ = true;
593 this->silence_count = 0;
594 this->buf_remain = 0;
598 if ( this->buf_remain )
600 // empty silence buf
601 long n = min( this->buf_remain, out_count - pos );
602 memcpy( &out [pos], this->buf + (buf_size - this->buf_remain), n * sizeof *out );
603 this->buf_remain -= n;
604 pos += n;
607 // generate remaining samples normally
608 long remain = out_count - pos;
609 if ( remain )
611 emu_play( this, remain, out + pos );
612 this->track_ended |= this->emu_track_ended_;
614 if ( !this->ignore_silence || this->out_time > this->fade_start )
616 // check end for a new run of silence
617 long silence = count_silence( out + pos, remain );
618 if ( silence < remain )
619 this->silence_time = this->emu_time - silence;
621 if ( this->emu_time - this->silence_time >= buf_size )
622 fill_buf( this ); // cause silence detection on next play()
626 if ( this->out_time > this->fade_start )
627 handle_fade( this, out_count, out );
629 this->out_time += out_count;
630 return 0;