From f40bfc9267b13b54e6379dfe7539447662879d24 Mon Sep 17 00:00:00 2001 From: Sean Bartell Date: Sat, 25 Jun 2011 21:32:25 -0400 Subject: Add codecs to librbcodec. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Id7f4717d51ed02d67cb9f9cb3c0ada4a81843f97 Reviewed-on: http://gerrit.rockbox.org/137 Reviewed-by: Nils Wallménius Tested-by: Nils Wallménius --- lib/rbcodec/codecs/libgme/nes_oscs.h | 164 +++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 lib/rbcodec/codecs/libgme/nes_oscs.h (limited to 'lib/rbcodec/codecs/libgme/nes_oscs.h') diff --git a/lib/rbcodec/codecs/libgme/nes_oscs.h b/lib/rbcodec/codecs/libgme/nes_oscs.h new file mode 100644 index 0000000000..1eeb302e6c --- /dev/null +++ b/lib/rbcodec/codecs/libgme/nes_oscs.h @@ -0,0 +1,164 @@ +// Private oscillators used by Nes_Apu + +// Nes_Snd_Emu 0.1.8 +#ifndef NES_OSCS_H +#define NES_OSCS_H + +#include "blargg_common.h" +#include "blip_buffer.h" +#include "nes_cpu.h" + +struct Nes_Apu; + +struct Nes_Osc +{ + unsigned char regs [4]; + bool reg_written [4]; + struct Blip_Buffer* output; + int length_counter;// length counter (0 if unused by oscillator) + int delay; // delay until next (potential) transition + int last_amp; // last amplitude oscillator was outputting +}; + +void Osc_clock_length( struct Nes_Osc* this, int halt_mask ); +static inline int Osc_period( struct Nes_Osc* this ) +{ + return (this->regs [3] & 7) * 0x100 + (this->regs [2] & 0xFF); +} + +static inline void Osc_reset( struct Nes_Osc* this ) +{ + this->delay = 0; + this->last_amp = 0; +} + +static inline int Osc_update_amp( struct Nes_Osc* this, int amp ) +{ + int delta = amp - this->last_amp; + this->last_amp = amp; + return delta; +} + +// Nes_Square + +enum { negate_flag = 0x08 }; +enum { shift_mask = 0x07 }; +enum { square_phase_range = 8 }; + +typedef struct Blip_Synth Synth; + +struct Nes_Square +{ + struct Nes_Osc osc; + int envelope; + int env_delay; + int phase; + int sweep_delay; + + Synth* synth; // shared between squares +}; + +static inline void Square_set_synth( struct Nes_Square* this, Synth* s ) { this->synth = s; } + +void Square_clock_sweep( struct Nes_Square* this, int adjust ); +void Square_run( struct Nes_Square* this, nes_time_t, nes_time_t ); + +static inline void Square_reset( struct Nes_Square* this ) +{ + this->sweep_delay = 0; + this->envelope = 0; + this->env_delay = 0; + Osc_reset( &this->osc ); +} + +void Square_clock_envelope( struct Nes_Square* this ); +int Square_volume( struct Nes_Square* this ); + +// Nes_Triangle + +enum { Triangle_phase_range = 16 }; + +struct Nes_Triangle +{ + struct Nes_Osc osc; + + int phase; + int linear_counter; + struct Blip_Synth synth; +}; + +void Triangle_run( struct Nes_Triangle* this, nes_time_t, nes_time_t ); +void Triangle_clock_linear_counter( struct Nes_Triangle* this ); + +static inline void Triangle_reset( struct Nes_Triangle* this ) +{ + this->linear_counter = 0; + this->phase = 1; + Osc_reset( &this->osc ); +} + +// Nes_Noise +struct Nes_Noise +{ + struct Nes_Osc osc; + + int envelope; + int env_delay; + int noise; + struct Blip_Synth synth; +}; + +void Noise_clock_envelope( struct Nes_Noise* this ); +int Noise_volume( struct Nes_Noise* this ); +void Noise_run( struct Nes_Noise* this, nes_time_t, nes_time_t ); + +static inline void Noise_reset( struct Nes_Noise* this ) +{ + this->noise = 1 << 14; + this->envelope = 0; + this->env_delay = 0; + Osc_reset( &this->osc ); +} + +// Nes_Dmc + +enum { loop_flag = 0x40 }; + +struct Nes_Dmc +{ + struct Nes_Osc osc; + + int address; // address of next byte to read + int period; + int buf; + int bits_remain; + int bits; + bool buf_full; + bool silence; + + int dac; + + nes_time_t next_irq; + bool irq_enabled; + bool irq_flag; + bool pal_mode; + bool nonlinear; + + int (*prg_reader)( void*, int ); // needs to be initialized to prg read function + void* prg_reader_data; + + struct Nes_Apu* apu; + + struct Blip_Synth synth; +}; + +void Dmc_start( struct Nes_Dmc* this ); +void Dmc_write_register( struct Nes_Dmc* this, int, int ); +void Dmc_run( struct Nes_Dmc* this, nes_time_t, nes_time_t ); +void Dmc_recalc_irq( struct Nes_Dmc* this ); +void Dmc_fill_buffer( struct Nes_Dmc* this ); +void Dmc_reset( struct Nes_Dmc* this ); + +int Dmc_count_reads( struct Nes_Dmc* this, nes_time_t, nes_time_t* ); + +#endif -- cgit v1.2.3