| 1 | |
| 2 | // Private oscillators used by Nes_Apu |
| 3 | |
| 4 | // Nes_Snd_Emu 0.1.7. Copyright (C) 2003-2005 Shay Green. GNU LGPL license. |
| 5 | |
| 6 | #ifndef NES_OSCS_H |
| 7 | #define NES_OSCS_H |
| 8 | |
| 9 | #include "Blip_Buffer.h" |
| 10 | |
| 11 | class Nes_Apu; |
| 12 | |
| 13 | struct Nes_Osc |
| 14 | { |
| 15 | unsigned char regs [4]; |
| 16 | bool reg_written [4]; |
| 17 | Blip_Buffer* output; |
| 18 | int length_counter;// length counter (0 if unused by oscillator) |
| 19 | int delay; // delay until next (potential) transition |
| 20 | int last_amp; // last amplitude oscillator was outputting |
| 21 | |
| 22 | void clock_length( int halt_mask ); |
| 23 | int period() const { |
| 24 | return (regs [3] & 7) * 0x100 + (regs [2] & 0xff); |
| 25 | } |
| 26 | void reset() { |
| 27 | delay = 0; |
| 28 | last_amp = 0; |
| 29 | } |
| 30 | int update_amp( int amp ) { |
| 31 | int delta = amp - last_amp; |
| 32 | last_amp = amp; |
| 33 | return delta; |
| 34 | } |
| 35 | }; |
| 36 | |
| 37 | struct Nes_Envelope : Nes_Osc |
| 38 | { |
| 39 | int envelope; |
| 40 | int env_delay; |
| 41 | |
| 42 | void clock_envelope(); |
| 43 | int volume() const; |
| 44 | void reset() { |
| 45 | envelope = 0; |
| 46 | env_delay = 0; |
| 47 | Nes_Osc::reset(); |
| 48 | } |
| 49 | }; |
| 50 | |
| 51 | // Nes_Square |
| 52 | struct Nes_Square : Nes_Envelope |
| 53 | { |
| 54 | enum { negate_flag = 0x08 }; |
| 55 | enum { shift_mask = 0x07 }; |
| 56 | enum { phase_range = 8 }; |
| 57 | int phase; |
| 58 | int sweep_delay; |
| 59 | |
| 60 | typedef Blip_Synth<blip_good_quality,15> Synth; |
| 61 | const Synth* synth; // shared between squares |
| 62 | |
| 63 | void clock_sweep( int adjust ); |
| 64 | void run( cpu_time_t, cpu_time_t ); |
| 65 | void reset() { |
| 66 | sweep_delay = 0; |
| 67 | Nes_Envelope::reset(); |
| 68 | } |
| 69 | }; |
| 70 | |
| 71 | // Nes_Triangle |
| 72 | struct Nes_Triangle : Nes_Osc |
| 73 | { |
| 74 | enum { phase_range = 16 }; |
| 75 | int phase; |
| 76 | int linear_counter; |
| 77 | Blip_Synth<blip_good_quality,15> synth; |
| 78 | |
| 79 | int calc_amp() const; |
| 80 | void run( cpu_time_t, cpu_time_t ); |
| 81 | void clock_linear_counter(); |
| 82 | void reset() { |
| 83 | linear_counter = 0; |
| 84 | phase = phase_range; |
| 85 | Nes_Osc::reset(); |
| 86 | } |
| 87 | }; |
| 88 | |
| 89 | // Nes_Noise |
| 90 | struct Nes_Noise : Nes_Envelope |
| 91 | { |
| 92 | int noise; |
| 93 | Blip_Synth<blip_med_quality,15> synth; |
| 94 | |
| 95 | void run( cpu_time_t, cpu_time_t ); |
| 96 | void reset() { |
| 97 | noise = 1 << 14; |
| 98 | Nes_Envelope::reset(); |
| 99 | } |
| 100 | }; |
| 101 | |
| 102 | // Nes_Dmc |
| 103 | struct Nes_Dmc : Nes_Osc |
| 104 | { |
| 105 | int address; // address of next byte to read |
| 106 | int period; |
| 107 | //int length_counter; // bytes remaining to play (already defined in Nes_Osc) |
| 108 | int buf; |
| 109 | int bits_remain; |
| 110 | int bits; |
| 111 | bool buf_empty; |
| 112 | bool silence; |
| 113 | |
| 114 | enum { loop_flag = 0x40 }; |
| 115 | |
| 116 | int dac; |
| 117 | |
| 118 | cpu_time_t next_irq; |
| 119 | bool irq_enabled; |
| 120 | bool irq_flag; |
| 121 | bool pal_mode; |
| 122 | bool nonlinear; |
| 123 | |
| 124 | int (*rom_reader)( void*, cpu_addr_t ); // needs to be initialized to rom read function |
| 125 | void* rom_reader_data; |
| 126 | |
| 127 | Nes_Apu* apu; |
| 128 | |
| 129 | Blip_Synth<blip_med_quality,127> synth; |
| 130 | |
| 131 | void start(); |
| 132 | void write_register( int, int ); |
| 133 | void run( cpu_time_t, cpu_time_t ); |
| 134 | void recalc_irq(); |
| 135 | void fill_buffer(); |
| 136 | void reload_sample(); |
| 137 | void reset(); |
| 138 | int count_reads( cpu_time_t, cpu_time_t* ) const; |
| 139 | }; |
| 140 | |
| 141 | #endif |
| 142 | |
| 143 | |