2nd part of FS#12176. Tempo setting migrated to fixed point for libgme.
[kugel-rb.git] / apps / codecs / libgme / ay_emu.c
blob78d4556bf54838c5ed6e4c03a54d7d9f00909aaf
1 // Game_Music_Emu 0.6-pre. http://www.slack.net/~ant/
3 #include "ay_emu.h"
5 #include "blargg_endian.h"
7 /* Copyright (C) 2006-2009 Shay Green. This module is free software; you
8 can redistribute it and/or modify it under the terms of the GNU Lesser
9 General Public License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version. This
11 module is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
14 details. You should have received a copy of the GNU Lesser General Public
15 License along with this module; if not, write to the Free Software Foundation,
16 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
18 #include "blargg_source.h"
20 int const stereo = 2; // number of channels for stereo
21 int const silence_max = 6; // seconds
22 int const silence_threshold = 0x10;
23 long const fade_block_size = 512;
24 int const fade_shift = 8; // fade ends with gain at 1.0 / (1 << fade_shift)
26 const char* const gme_wrong_file_type = "Wrong file type for this emulator";
28 // TODO: probably don't need detailed errors as to why file is corrupt
30 int const spectrum_clock = 3546900; // 128K Spectrum
31 int const spectrum_period = 70908;
33 //int const spectrum_clock = 3500000; // 48K Spectrum
34 //int const spectrum_period = 69888;
36 int const cpc_clock = 2000000;
38 void clear_track_vars( struct Ay_Emu *this )
40 this->current_track = -1;
41 this->out_time = 0;
42 this->emu_time = 0;
43 this->emu_track_ended_ = true;
44 this->track_ended = true;
45 this->fade_start = INT_MAX / 2 + 1;
46 this->fade_step = 1;
47 this->silence_time = 0;
48 this->silence_count = 0;
49 this->buf_remain = 0;
50 /* warning(); // clear warning */
53 void Ay_init( struct Ay_Emu *this )
55 this->sample_rate = 0;
56 this->mute_mask_ = 0;
57 this->tempo = (int)FP_ONE_TEMPO;
58 this->gain = 1.0;
59 this->track_count = 0;
61 // defaults
62 this->max_initial_silence = 2;
63 this->ignore_silence = false;
65 this->voice_count = 0;
66 clear_track_vars( this );
67 this->beeper_output = NULL;
68 disable_beeper( this );
70 Ay_apu_init( &this->apu );
71 Z80_init( &this->cpu );
73 this->silence_lookahead = 6 ;
76 // Track info
78 // Given pointer to 2-byte offset of data, returns pointer to data, or NULL if
79 // offset is 0 or there is less than min_size bytes of data available.
80 static byte const* get_data( struct file_t const* file, byte const ptr [], int min_size )
82 int offset = (int16_t) get_be16( ptr );
83 int pos = ptr - (byte const*) file->header;
84 int size = file->end - (byte const*) file->header;
85 assert( (unsigned) pos <= (unsigned) size - 2 );
86 int limit = size - min_size;
87 if ( limit < 0 || !offset || (unsigned) (pos + offset) > (unsigned) limit )
88 return NULL;
89 return ptr + offset;
92 static blargg_err_t parse_header( byte const in [], int size, struct file_t* out )
94 if ( size < header_size )
95 return gme_wrong_file_type;
97 out->header = (struct header_t const*) in;
98 out->end = in + size;
99 struct header_t const* h = (struct header_t const*) in;
100 if ( memcmp( h->tag, "ZXAYEMUL", 8 ) )
101 return gme_wrong_file_type;
103 out->tracks = get_data( out, h->track_info, (h->max_track + 1) * 4 );
104 if ( !out->tracks )
105 return "missing track data";
107 return 0;
110 long Track_get_length( struct Ay_Emu* this, int n )
112 long length = 0;
114 byte const* track_info = get_data( &this->file, this->file.tracks + n * 4 + 2, 6 );
115 if ( track_info )
116 length = get_be16( track_info + 4 ) * (1000 / 50); // frames to msec
118 if ( (this->m3u.size > 0) && (n < this->m3u.size) ) {
119 struct entry_t* entry = &this->m3u.entries [n];
120 length = entry->length;
123 if ( length <= 0 )
124 length = 120 * 1000; /* 2 minutes */
126 return length;
129 // Setup
131 void change_clock_rate( struct Ay_Emu *this, long rate )
133 this->clock_rate_ = rate;
134 Buffer_clock_rate( &this->stereo_buf, rate );
137 blargg_err_t Ay_load_mem( struct Ay_Emu *this, byte const in [], int size )
139 assert( offsetof (struct header_t,track_info [2]) == header_size );
141 RETURN_ERR( parse_header( in, size, &this->file ) );
143 /* if ( file.header->vers > 2 )
144 warning( "Unknown file version" ); */
146 this->voice_count = ay_osc_count + 1; // +1 for beeper
147 Ay_apu_volume( &this->apu, this->gain );
149 // Setup buffer
150 change_clock_rate( this, spectrum_clock );
151 this->buf_changed_count = Buffer_channels_changed_count( &this->stereo_buf );
153 Sound_set_tempo( this, this->tempo );
155 // Remute voices
156 Sound_mute_voices( this, this->mute_mask_ );
158 this->track_count = this->file.header->max_track + 1;
159 this->m3u.size = 0;
160 return 0;
163 void set_beeper_output( struct Ay_Emu *this, struct Blip_Buffer* b )
165 this->beeper_output = b;
166 if ( b && !this->cpc_mode )
167 this->beeper_mask = 0x10;
168 else
169 disable_beeper( this );
172 void set_voice( struct Ay_Emu *this, int i, struct Blip_Buffer* center )
174 if ( i >= ay_osc_count )
175 set_beeper_output( this, center );
176 else
177 Ay_apu_set_output( &this->apu, i, center );
180 blargg_err_t run_clocks( struct Ay_Emu *this, blip_time_t* duration, int msec )
182 #if defined(ROCKBOX)
183 (void) msec;
184 #endif
186 cpu_time_t *end = duration;
187 struct Z80_Cpu* cpu = &this->cpu;
188 Z80_set_time( cpu, 0 );
190 // Since detection of CPC mode will halve clock rate during the frame
191 // and thus generate up to twice as much sound, we must generate half
192 // as much until mode is known.
193 if ( !(this->spectrum_mode | this->cpc_mode) )
194 *end /= 2;
196 while ( Z80_time( cpu ) < *end )
198 run_cpu( this, min( *end, this->next_play ) );
200 if ( Z80_time( cpu ) >= this->next_play )
202 // next frame
203 this->next_play += this->play_period;
205 if ( cpu->r.iff1 )
207 // interrupt enabled
209 if ( this->mem.ram [cpu->r.pc] == 0x76 )
210 cpu->r.pc++; // advance past HALT instruction
212 cpu->r.iff1 = 0;
213 cpu->r.iff2 = 0;
215 this->mem.ram [--cpu->r.sp] = (byte) (cpu->r.pc >> 8);
216 this->mem.ram [--cpu->r.sp] = (byte) (cpu->r.pc);
218 // fixed interrupt
219 cpu->r.pc = 0x38;
220 Z80_adjust_time( cpu, 12 );
222 if ( cpu->r.im == 2 )
224 // vectored interrupt
225 addr_t addr = cpu->r.i * 0x100 + 0xFF;
226 cpu->r.pc = this->mem.ram [(addr + 1) & 0xFFFF] * 0x100 + this->mem.ram [addr];
227 Z80_adjust_time( cpu, 6 );
233 // End time frame
234 *end = Z80_time( cpu );
235 this->next_play -= *end;
236 check( this->next_play >= 0 );
237 Z80_adjust_time( cpu, -*end );
238 Ay_apu_end_frame( &this->apu, *end );
239 return 0;
242 // Emulation
244 void cpu_out_( struct Ay_Emu *this, cpu_time_t time, addr_t addr, int data )
246 // Spectrum
247 if ( !this->cpc_mode )
249 switch ( addr & 0xFEFF )
251 case 0xFEFD:
252 this->spectrum_mode = true;
253 Ay_apu_write_addr( &this->apu, data );
254 return;
256 case 0xBEFD:
257 this->spectrum_mode = true;
258 Ay_apu_write_data( &this->apu, time, data );
259 return;
263 // CPC
264 if ( !this->spectrum_mode )
266 switch ( addr >> 8 )
268 case 0xF6:
269 switch ( data & 0xC0 )
271 case 0xC0:
272 Ay_apu_write_addr( &this->apu, this->cpc_latch );
273 goto enable_cpc;
275 case 0x80:
276 Ay_apu_write_data( &this->apu, time, this->cpc_latch );
277 goto enable_cpc;
279 break;
281 case 0xF4:
282 this->cpc_latch = data;
283 goto enable_cpc;
287 /* dprintf( "Unmapped OUT: $%04X <- $%02X\n", addr, data ); */
288 return;
290 enable_cpc:
291 if ( !this->cpc_mode )
293 this->cpc_mode = true;
294 disable_beeper( this );
296 change_clock_rate( this, cpc_clock );
297 Sound_set_tempo( this, this->tempo );
301 blargg_err_t Ay_set_sample_rate( struct Ay_Emu *this, long rate )
303 require( !this->sample_rate ); // sample rate can't be changed once set
304 Buffer_init( &this->stereo_buf );
305 RETURN_ERR( Buffer_set_sample_rate( &this->stereo_buf, rate, 1000 / 20 ) );
307 // Set buffer bass
308 Buffer_bass_freq( &this->stereo_buf, 160 );
310 this->sample_rate = rate;
311 return 0;
314 void Sound_mute_voice( struct Ay_Emu *this, int index, bool mute )
316 require( (unsigned) index < (unsigned) this->voice_count );
317 int bit = 1 << index;
318 int mask = this->mute_mask_ | bit;
319 if ( !mute )
320 mask ^= bit;
321 Sound_mute_voices( this, mask );
324 void Sound_mute_voices( struct Ay_Emu *this, int mask )
326 require( this->sample_rate ); // sample rate must be set first
327 this->mute_mask_ = mask;
329 int i;
330 for ( i = this->voice_count; i--; )
332 if ( mask & (1 << i) )
334 set_voice( this, i, 0 );
336 else
338 struct channel_t ch = Buffer_channel( &this->stereo_buf );
339 assert( (ch.center && ch.left && ch.right) ||
340 (!ch.center && !ch.left && !ch.right) ); // all or nothing
341 set_voice( this, i, ch.center );
346 void Sound_set_tempo( struct Ay_Emu *this, int t )
348 require( this->sample_rate ); // sample rate must be set first
349 int const min = (int)(FP_ONE_TEMPO*0.02);
350 int const max = (int)(FP_ONE_TEMPO*4.00);
351 if ( t < min ) t = min;
352 if ( t > max ) t = max;
353 this->tempo = t;
355 int p = spectrum_period;
356 if ( this->clock_rate_ != spectrum_clock )
357 p = this->clock_rate_ / 50;
359 this->play_period = (blip_time_t) ((p * FP_ONE_TEMPO) / t);
362 void fill_buf( struct Ay_Emu *this ) ICODE_ATTR;;
363 blargg_err_t Ay_start_track( struct Ay_Emu *this, int track )
365 clear_track_vars( this );
367 // Remap track if playlist available
368 if ( this->m3u.size > 0 ) {
369 struct entry_t* e = &this->m3u.entries[track];
370 track = e->track;
373 this->current_track = track;
374 Buffer_clear( &this->stereo_buf );
376 byte* const mem = this->mem.ram;
378 memset( mem + 0x0000, 0xC9, 0x100 ); // fill RST vectors with RET
379 memset( mem + 0x0100, 0xFF, 0x4000 - 0x100 );
380 memset( mem + ram_addr, 0x00, mem_size - ram_addr );
382 // locate data blocks
383 byte const* const data = get_data( &this->file, this->file.tracks + track * 4 + 2, 14 );
384 if ( !data )
385 return "file data missing";
387 byte const* const more_data = get_data( &this->file, data + 10, 6 );
388 if ( !more_data )
389 return "file data missing";
391 byte const* blocks = get_data( &this->file, data + 12, 8 );
392 if ( !blocks )
393 return "file data missing";
395 // initial addresses
396 unsigned addr = get_be16( blocks );
397 if ( !addr )
398 return "file data missing";
400 unsigned init = get_be16( more_data + 2 );
401 if ( !init )
402 init = addr;
404 // copy blocks into memory
407 blocks += 2;
408 unsigned len = get_be16( blocks ); blocks += 2;
409 if ( addr + len > mem_size )
411 /* warning( "Bad data block size" ); */
412 len = mem_size - addr;
414 check( len );
415 byte const* in = get_data( &this->file, blocks, 0 ); blocks += 2;
416 if ( len > (unsigned) (this->file.end - in) )
418 /* warning( "File data missing" ); */
419 len = this->file.end - in;
422 memcpy( mem + addr, in, len );
424 if ( this->file.end - blocks < 8 )
426 /* warning( "File data missing" ); */
427 break;
430 while ( (addr = get_be16( blocks )) != 0 );
432 // copy and configure driver
433 static byte const passive [] = {
434 0xF3, // DI
435 0xCD, 0, 0, // CALL init
436 0xED, 0x5E, // LOOP: IM 2
437 0xFB, // EI
438 0x76, // HALT
439 0x18, 0xFA // JR LOOP
441 static byte const active [] = {
442 0xF3, // DI
443 0xCD, 0, 0, // CALL init
444 0xED, 0x56, // LOOP: IM 1
445 0xFB, // EI
446 0x76, // HALT
447 0xCD, 0, 0, // CALL play
448 0x18, 0xF7 // JR LOOP
450 memcpy( mem, passive, sizeof passive );
451 int const play_addr = get_be16( more_data + 4 );
452 if ( play_addr )
454 memcpy( mem, active, sizeof active );
455 mem [ 9] = play_addr;
456 mem [10] = play_addr >> 8;
458 mem [2] = init;
459 mem [3] = init >> 8;
461 mem [0x38] = 0xFB; // Put EI at interrupt vector (followed by RET)
463 // start at spectrum speed
464 change_clock_rate( this, spectrum_clock );
465 Sound_set_tempo( this, this->tempo );
467 struct registers_t r;
468 memset( &r, 0, sizeof(struct registers_t) );
470 r.sp = get_be16( more_data );
471 r.b.a = r.b.b = r.b.d = r.b.h = data [8];
472 r.b.flags = r.b.c = r.b.e = r.b.l = data [9];
473 r.alt.w = r.w;
474 r.ix = r.iy = r.w.hl;
476 memset( this->mem.padding1, 0xFF, sizeof this->mem.padding1 );
478 int const mirrored = 0x80; // this much is mirrored after end of memory
479 memset( this->mem.ram + mem_size + mirrored, 0xFF, sizeof this->mem.ram - mem_size - mirrored );
480 memcpy( this->mem.ram + mem_size, this->mem.ram, mirrored ); // some code wraps around (ugh)
482 Z80_reset( &this->cpu, this->mem.padding1, this->mem.padding1 );
483 Z80_map_mem( &this->cpu, 0, mem_size, this->mem.ram, this->mem.ram );
484 this->cpu.r = r;
486 this->beeper_delta = (int) (ay_amp_range * 0.8);
487 this->last_beeper = 0;
488 this->next_play = this->play_period;
489 this->spectrum_mode = false;
490 this->cpc_mode = false;
491 this->cpc_latch = 0;
492 set_beeper_output( this, this->beeper_output );
493 Ay_apu_reset( &this->apu );
495 // a few tunes rely on channels having tone enabled at the beginning
496 Ay_apu_write_addr( &this->apu, 7 );
497 Ay_apu_write_data( &this->apu, 0, 0x38 );
499 this->emu_track_ended_ = false;
500 this->track_ended = false;
502 if ( !this->ignore_silence )
504 // play until non-silence or end of track
505 long end;
506 for ( end = this->max_initial_silence * stereo * this->sample_rate; this->emu_time < end; )
508 fill_buf( this );
509 if ( this->buf_remain | (int) this->emu_track_ended_ )
510 break;
513 this->emu_time = this->buf_remain;
514 this->out_time = 0;
515 this->silence_time = 0;
516 this->silence_count = 0;
518 /* return track_ended() ? warning() : 0; */
519 return 0;
522 // Tell/Seek
524 blargg_long msec_to_samples( blargg_long msec, long sample_rate )
526 blargg_long sec = msec / 1000;
527 msec -= sec * 1000;
528 return (sec * sample_rate + msec * sample_rate / 1000) * stereo;
531 long Track_tell( struct Ay_Emu *this )
533 blargg_long rate = this->sample_rate * stereo;
534 blargg_long sec = this->out_time / rate;
535 return sec * 1000 + (this->out_time - sec * rate) * 1000 / rate;
538 blargg_err_t Track_seek( struct Ay_Emu *this, long msec )
540 blargg_long time = msec_to_samples( msec, this->sample_rate );
541 if ( time < this->out_time )
542 RETURN_ERR( Ay_start_track( this, this->current_track ) );
543 return Track_skip( this, time - this->out_time );
546 blargg_err_t play_( struct Ay_Emu *this, long count, sample_t* out ) ICODE_ATTR;
547 blargg_err_t skip_( struct Ay_Emu *this, long count )
549 // for long skip, mute sound
550 const long threshold = 30000;
551 if ( count > threshold )
553 int saved_mute = this->mute_mask_;
554 Sound_mute_voices( this, ~0 );
556 while ( count > threshold / 2 && !this->emu_track_ended_ )
558 RETURN_ERR( play_( this, buf_size, this->buf ) );
559 count -= buf_size;
562 Sound_mute_voices( this, saved_mute );
565 while ( count && !this->emu_track_ended_ )
567 long n = buf_size;
568 if ( n > count )
569 n = count;
570 count -= n;
571 RETURN_ERR( play_( this, n, this->buf ) );
573 return 0;
576 blargg_err_t Track_skip( struct Ay_Emu *this, long count )
578 require( this->current_track >= 0 ); // start_track() must have been called already
579 this->out_time += count;
581 // remove from silence and buf first
583 long n = min( count, this->silence_count );
584 this->silence_count -= n;
585 count -= n;
587 n = min( count, this->buf_remain );
588 this->buf_remain -= n;
589 count -= n;
592 if ( count && !this->emu_track_ended_ )
594 this->emu_time += count;
596 // End track if error
597 if ( skip_( this, count ) )
598 this->emu_track_ended_ = true;
601 if ( !(this->silence_count | this->buf_remain) ) // caught up to emulator, so update track ended
602 this->track_ended |= this->emu_track_ended_;
604 return 0;
607 // Fading
609 void Track_set_fade( struct Ay_Emu *this, long start_msec, long length_msec )
611 this->fade_step = this->sample_rate * length_msec / (fade_block_size * fade_shift * 1000 / stereo);
612 this->fade_start = msec_to_samples( start_msec, this->sample_rate );
615 // unit / pow( 2.0, (double) x / step )
616 static int int_log( blargg_long x, int step, int unit )
618 int shift = x / step;
619 int fraction = (x - shift * step) * unit / step;
620 return ((unit - fraction) + (fraction >> 1)) >> shift;
623 void handle_fade( struct Ay_Emu *this, long out_count, sample_t* out )
625 int i;
626 for ( i = 0; i < out_count; i += fade_block_size )
628 int const shift = 14;
629 int const unit = 1 << shift;
630 int gain = int_log( (this->out_time + i - this->fade_start) / fade_block_size,
631 this->fade_step, unit );
632 if ( gain < (unit >> fade_shift) )
633 this->track_ended = this->emu_track_ended_ = true;
635 sample_t* io = &out [i];
636 int count;
637 for ( count = min( fade_block_size, out_count - i ); count; --count )
639 *io = (sample_t) ((*io * gain) >> shift);
640 ++io;
645 // Silence detection
647 void emu_play( struct Ay_Emu *this, long count, sample_t* out )
649 check( current_track_ >= 0 );
650 this->emu_time += count;
651 if ( this->current_track >= 0 && !this->emu_track_ended_ ) {
652 if ( play_( this, count, out ) )
653 this->emu_track_ended_ = true;
655 else
656 memset( out, 0, count * sizeof *out );
659 // number of consecutive silent samples at end
660 static long count_silence( sample_t* begin, long size )
662 sample_t first = *begin;
663 *begin = silence_threshold; // sentinel
664 sample_t* p = begin + size;
665 while ( (unsigned) (*--p + silence_threshold / 2) <= (unsigned) silence_threshold ) { }
666 *begin = first;
667 return size - (p - begin);
670 // fill internal buffer and check it for silence
671 void fill_buf( struct Ay_Emu *this )
673 assert( !this->buf_remain );
674 if ( !this->emu_track_ended_ )
676 emu_play( this, buf_size, this->buf );
677 long silence = count_silence( this->buf, buf_size );
678 if ( silence < buf_size )
680 this->silence_time = this->emu_time - silence;
681 this->buf_remain = buf_size;
682 return;
685 this->silence_count += buf_size;
688 blargg_err_t Ay_play( struct Ay_Emu *this, long out_count, sample_t* out )
690 if ( this->track_ended )
692 memset( out, 0, out_count * sizeof *out );
694 else
696 require( this->current_track >= 0 );
697 require( out_count % stereo == 0 );
699 assert( this->emu_time >= this->out_time );
701 // prints nifty graph of how far ahead we are when searching for silence
702 //debug_printf( "%*s \n", int ((emu_time - out_time) * 7 / sample_rate()), "*" );
704 long pos = 0;
705 if ( this->silence_count )
707 // during a run of silence, run emulator at >=2x speed so it gets ahead
708 long ahead_time = this->silence_lookahead * (this->out_time + out_count - this->silence_time) + this->silence_time;
709 while ( this->emu_time < ahead_time && !(this->buf_remain | this->emu_track_ended_) )
710 fill_buf( this );
712 // fill with silence
713 pos = min( this->silence_count, out_count );
714 memset( out, 0, pos * sizeof *out );
715 this->silence_count -= pos;
717 if ( this->emu_time - this->silence_time > silence_max * stereo * this->sample_rate )
719 this->track_ended = this->emu_track_ended_ = true;
720 this->silence_count = 0;
721 this->buf_remain = 0;
725 if ( this->buf_remain )
727 // empty silence buf
728 long n = min( this->buf_remain, out_count - pos );
729 memcpy( &out [pos], this->buf + (buf_size - this->buf_remain), n * sizeof *out );
730 this->buf_remain -= n;
731 pos += n;
734 // generate remaining samples normally
735 long remain = out_count - pos;
736 if ( remain )
738 emu_play( this, remain, out + pos );
739 this->track_ended |= this->emu_track_ended_;
741 if ( !this->ignore_silence || this->out_time > this->fade_start )
743 // check end for a new run of silence
744 long silence = count_silence( out + pos, remain );
745 if ( silence < remain )
746 this->silence_time = this->emu_time - silence;
748 if ( this->emu_time - this->silence_time >= buf_size )
749 fill_buf( this ); // cause silence detection on next play()
753 if ( this->out_time > this->fade_start )
754 handle_fade( this, out_count, out );
756 this->out_time += out_count;
757 return 0;
760 blargg_err_t play_( struct Ay_Emu *this, long count, sample_t* out )
762 long remain = count;
763 while ( remain )
765 remain -= Buffer_read_samples( &this->stereo_buf, &out [count - remain], remain );
766 if ( remain )
768 if ( this->buf_changed_count != Buffer_channels_changed_count( &this->stereo_buf ) )
770 this->buf_changed_count = Buffer_channels_changed_count( &this->stereo_buf );
772 // Remute voices
773 Sound_mute_voices( this, this->mute_mask_ );
775 int msec = Buffer_length( &this->stereo_buf );
776 blip_time_t clocks_emulated = (blargg_long) msec * this->clock_rate_ / 1000 - 100;
777 RETURN_ERR( run_clocks( this, &clocks_emulated, msec ) );
778 assert( clocks_emulated );
779 Buffer_end_frame( &this->stereo_buf, clocks_emulated );
782 return 0;