From acb0917556fc33681c1df5a530cf754193e67705 Mon Sep 17 00:00:00 2001 From: Andree Buschmann Date: Sun, 7 Aug 2011 20:01:04 +0000 Subject: Submit initial patch from FS#12176. Adds support for several new game music formats (AY, GBS, HES, KSS, SGC, VGM and VGZ) and replaces the current NSF and NSFE with a new implementation based on a port of the Game Music Emu library 'GME'. This first submit does not cover the full functionality provided by the author's original patch: Coleco-SGV is not supported, some GME-specific m3u-support has been removed and IRAM is not used yet. Further changes are very likely to follow this submit. Thanks to Mauricio Garrido. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30264 a1c6a512-1295-4272-9138-f99709370657 --- apps/codecs/libgme/ay_apu.h | 79 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 apps/codecs/libgme/ay_apu.h (limited to 'apps/codecs/libgme/ay_apu.h') diff --git a/apps/codecs/libgme/ay_apu.h b/apps/codecs/libgme/ay_apu.h new file mode 100644 index 0000000000..ccdd204c46 --- /dev/null +++ b/apps/codecs/libgme/ay_apu.h @@ -0,0 +1,79 @@ +// AY-3-8910 sound chip ulator + +// Game_Music_Emu 0.6-pre +#ifndef AY_APU_H +#define AY_APU_H + +#include "blargg_common.h" +#include "blargg_source.h" +#include "blip_buffer.h" + +// Number of registers +enum { ay_reg_count = 16 }; +enum { ay_osc_count = 3 }; +enum { ay_amp_range = 255 }; + +struct osc_t +{ + blip_time_t period; + blip_time_t delay; + short last_amp; + short phase; + struct Blip_Buffer* output; +}; + +struct Ay_Apu { + struct osc_t oscs [ay_osc_count]; + + blip_time_t last_time; + byte addr_; + byte regs [ay_reg_count]; + + blip_time_t noise_delay; + unsigned noise_lfsr; + + blip_time_t env_delay; + byte const* env_wave; + int env_pos; + byte env_modes [8] [48]; // values already passed through volume table + + struct Blip_Synth synth_; // used by Ay_Core for beeper sound +}; + +void Ay_apu_init( struct Ay_Apu* this ); + +// Writes to address register +static inline void Ay_apu_write_addr( struct Ay_Apu* this, int data ) { this->addr_ = data & 0x0F; } + +// Emulates to time t, then writes to current data register +void run_until( struct Ay_Apu* this, blip_time_t final_end_time ) ICODE_ATTR;; +void write_data_( struct Ay_Apu* this, int addr, int data ) ICODE_ATTR; +static inline void Ay_apu_write_data( struct Ay_Apu* this, blip_time_t t, int data ) { run_until( this, t ); write_data_( this, this->addr_, data ); } + +// Reads from current data register +int Ay_apu_read( struct Ay_Apu* this ); + +// Resets sound chip +void Ay_apu_reset( struct Ay_Apu* this ); + +// Sets overall volume, where 1.0 is normal +static inline void Ay_apu_volume( struct Ay_Apu* this, double v ) { Synth_volume( &this->synth_, 0.7/ay_osc_count/ay_amp_range * v ); } + +static inline void Ay_apu_set_output( struct Ay_Apu* this, int i, struct Blip_Buffer* out ) +{ + assert( (unsigned) i < ay_osc_count ); + this->oscs [i].output = out; +} + +// Emulates to time t, then subtracts t from the current time. +// OK if previous write call had time slightly after t. +static inline void Ay_apu_end_frame( struct Ay_Apu* this, blip_time_t time ) +{ + if ( time > this->last_time ) + run_until( this, time ); + + this->last_time -= time; + assert( this->last_time >= 0 ); +} + +#endif -- cgit v1.2.3