Mercurial > audlegacy-plugins
comparison src/console/Nes_Fme7_Apu.h @ 12:3da1b8942b8b trunk
[svn] - remove src/Input src/Output src/Effect src/General src/Visualization src/Container
author | nenolod |
---|---|
date | Mon, 18 Sep 2006 03:14:20 -0700 |
parents | src/Input/console/Nes_Fme7_Apu.h@13389e613d67 |
children | fb513e10174e |
comparison
equal
deleted
inserted
replaced
11:cff1d04026ae | 12:3da1b8942b8b |
---|---|
1 | |
2 // Sunsoft FME-7 sound emulator | |
3 | |
4 // Game_Music_Emu 0.3.0 | |
5 | |
6 #ifndef NES_FME7_APU_H | |
7 #define NES_FME7_APU_H | |
8 | |
9 #include "blargg_common.h" | |
10 #include "Blip_Buffer.h" | |
11 | |
12 struct fme7_snapshot_t | |
13 { | |
14 enum { reg_count = 14 }; | |
15 BOOST::uint8_t regs [reg_count]; | |
16 BOOST::uint8_t phases [3]; // 0 or 1 | |
17 BOOST::uint8_t latch; | |
18 BOOST::uint16_t delays [3]; // a, b, c | |
19 }; | |
20 BOOST_STATIC_ASSERT( sizeof (fme7_snapshot_t) == 24 ); | |
21 | |
22 class Nes_Fme7_Apu : private fme7_snapshot_t { | |
23 public: | |
24 Nes_Fme7_Apu(); | |
25 | |
26 // See Nes_Apu.h for reference | |
27 void reset(); | |
28 void volume( double ); | |
29 void treble_eq( blip_eq_t const& ); | |
30 void output( Blip_Buffer* ); | |
31 enum { osc_count = 3 }; | |
32 void osc_output( int index, Blip_Buffer* ); | |
33 void end_frame( blip_time_t ); | |
34 void save_snapshot( fme7_snapshot_t* ) const; | |
35 void load_snapshot( fme7_snapshot_t const& ); | |
36 | |
37 // Mask and addresses of registers | |
38 enum { addr_mask = 0xe000 }; | |
39 enum { data_addr = 0xe000 }; | |
40 enum { latch_addr = 0xc000 }; | |
41 | |
42 // (addr & addr_mask) == latch_addr | |
43 void write_latch( int ); | |
44 | |
45 // (addr & addr_mask) == data_addr | |
46 void write_data( blip_time_t, int data ); | |
47 | |
48 // End of public interface | |
49 private: | |
50 // noncopyable | |
51 Nes_Fme7_Apu( const Nes_Fme7_Apu& ); | |
52 Nes_Fme7_Apu& operator = ( const Nes_Fme7_Apu& ); | |
53 | |
54 static unsigned char amp_table [16]; | |
55 | |
56 struct { | |
57 Blip_Buffer* output; | |
58 int last_amp; | |
59 } oscs [osc_count]; | |
60 blip_time_t last_time; | |
61 | |
62 enum { amp_range = 192 }; // can be any value; this gives best error/quality tradeoff | |
63 Blip_Synth<blip_good_quality,1> synth; | |
64 | |
65 void run_until( blip_time_t ); | |
66 }; | |
67 | |
68 inline void Nes_Fme7_Apu::volume( double v ) | |
69 { | |
70 synth.volume( 0.38 / amp_range * v ); // to do: fine-tune | |
71 } | |
72 | |
73 inline void Nes_Fme7_Apu::treble_eq( blip_eq_t const& eq ) | |
74 { | |
75 synth.treble_eq( eq ); | |
76 } | |
77 | |
78 inline void Nes_Fme7_Apu::osc_output( int i, Blip_Buffer* buf ) | |
79 { | |
80 assert( (unsigned) i < osc_count ); | |
81 oscs [i].output = buf; | |
82 } | |
83 | |
84 inline void Nes_Fme7_Apu::output( Blip_Buffer* buf ) | |
85 { | |
86 for ( int i = 0; i < osc_count; i++ ) | |
87 osc_output( i, buf ); | |
88 } | |
89 | |
90 inline Nes_Fme7_Apu::Nes_Fme7_Apu() | |
91 { | |
92 output( NULL ); | |
93 volume( 1.0 ); | |
94 reset(); | |
95 } | |
96 | |
97 inline void Nes_Fme7_Apu::write_latch( int data ) { latch = data; } | |
98 | |
99 inline void Nes_Fme7_Apu::write_data( blip_time_t time, int data ) | |
100 { | |
101 if ( (unsigned) latch >= reg_count ) | |
102 { | |
103 #ifdef dprintf | |
104 dprintf( "FME7 write to %02X (past end of sound registers)\n", (int) latch ); | |
105 #endif | |
106 return; | |
107 } | |
108 | |
109 run_until( time ); | |
110 regs [latch] = data; | |
111 } | |
112 | |
113 inline void Nes_Fme7_Apu::end_frame( blip_time_t time ) | |
114 { | |
115 if ( time > last_time ) | |
116 run_until( time ); | |
117 | |
118 assert( last_time >= time ); | |
119 last_time -= time; | |
120 } | |
121 | |
122 inline void Nes_Fme7_Apu::save_snapshot( fme7_snapshot_t* out ) const | |
123 { | |
124 *out = *this; | |
125 } | |
126 | |
127 inline void Nes_Fme7_Apu::load_snapshot( fme7_snapshot_t const& in ) | |
128 { | |
129 reset(); | |
130 fme7_snapshot_t* state = this; | |
131 *state = in; | |
132 } | |
133 | |
134 #endif | |
135 |