Mercurial > audlegacy
comparison Plugins/Input/console/Nes_Fme7_Apu.cxx @ 1691:e24213152357 trunk
[svn] .cpp -> .cxx
This has the nice side effect that we don't need to add .cpp to .SUFFIXES for OpenBSD.
author | js |
---|---|
date | Thu, 14 Sep 2006 13:33:10 -0700 |
parents | Plugins/Input/console/Nes_Fme7_Apu.cpp@705d4c089fce |
children |
comparison
equal
deleted
inserted
replaced
1690:bb1323938306 | 1691:e24213152357 |
---|---|
1 | |
2 // Game_Music_Emu 0.3.0. http://www.slack.net/~ant/ | |
3 | |
4 #include "Nes_Fme7_Apu.h" | |
5 | |
6 #include <string.h> | |
7 | |
8 /* Copyright (C) 2003-2006 Shay Green. This module is free software; you | |
9 can redistribute it and/or modify it under the terms of the GNU Lesser | |
10 General Public License as published by the Free Software Foundation; either | |
11 version 2.1 of the License, or (at your option) any later version. This | |
12 module is distributed in the hope that it will be useful, but WITHOUT ANY | |
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |
14 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for | |
15 more details. You should have received a copy of the GNU Lesser General | |
16 Public License along with this module; if not, write to the Free Software | |
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ | |
18 | |
19 #include BLARGG_SOURCE_BEGIN | |
20 | |
21 void Nes_Fme7_Apu::reset() | |
22 { | |
23 last_time = 0; | |
24 | |
25 for ( int i = 0; i < osc_count; i++ ) | |
26 oscs [i].last_amp = 0; | |
27 | |
28 fme7_snapshot_t* state = this; | |
29 memset( state, 0, sizeof *state ); | |
30 } | |
31 | |
32 #include BLARGG_ENABLE_OPTIMIZER | |
33 | |
34 unsigned char Nes_Fme7_Apu::amp_table [16] = | |
35 { | |
36 #define ENTRY( n ) (unsigned char) (n * amp_range + 0.5) | |
37 ENTRY(0.0000), ENTRY(0.0078), ENTRY(0.0110), ENTRY(0.0156), | |
38 ENTRY(0.0221), ENTRY(0.0312), ENTRY(0.0441), ENTRY(0.0624), | |
39 ENTRY(0.0883), ENTRY(0.1249), ENTRY(0.1766), ENTRY(0.2498), | |
40 ENTRY(0.3534), ENTRY(0.4998), ENTRY(0.7070), ENTRY(1.0000) | |
41 #undef ENTRY | |
42 }; | |
43 | |
44 void Nes_Fme7_Apu::run_until( blip_time_t end_time ) | |
45 { | |
46 require( end_time >= last_time ); | |
47 | |
48 for ( int index = 0; index < osc_count; index++ ) | |
49 { | |
50 int mode = regs [7] >> index; | |
51 int vol_mode = regs [010 + index]; | |
52 int volume = amp_table [vol_mode & 0x0f]; | |
53 | |
54 if ( !oscs [index].output ) | |
55 continue; | |
56 | |
57 // check for unsupported mode | |
58 #ifndef NDEBUG | |
59 if ( (mode & 011) <= 001 && vol_mode & 0x1f ) | |
60 dprintf( "FME7 used unimplemented sound mode: %02X, vol_mode: %02X\n", | |
61 mode, vol_mode & 0x1f ); | |
62 #endif | |
63 | |
64 if ( (mode & 001) | (vol_mode & 0x10) ) | |
65 volume = 0; // noise and envelope aren't supported | |
66 | |
67 // period | |
68 int const period_factor = 16; | |
69 unsigned period = (regs [index * 2 + 1] & 0x0f) * 0x100 * period_factor + | |
70 regs [index * 2] * period_factor; | |
71 if ( period < 50 ) // around 22 kHz | |
72 { | |
73 volume = 0; | |
74 if ( !period ) // on my AY-3-8910A, period doesn't have extra one added | |
75 period = period_factor; | |
76 } | |
77 | |
78 // current amplitude | |
79 int amp = volume; | |
80 if ( !phases [index] ) | |
81 amp = 0; | |
82 int delta = amp - oscs [index].last_amp; | |
83 if ( delta ) | |
84 { | |
85 oscs [index].last_amp = amp; | |
86 synth.offset( last_time, delta, oscs [index].output ); | |
87 } | |
88 | |
89 blip_time_t time = last_time + delays [index]; | |
90 if ( time < end_time ) | |
91 { | |
92 Blip_Buffer* const osc_output = oscs [index].output; | |
93 int delta = amp * 2 - volume; | |
94 | |
95 if ( volume ) | |
96 { | |
97 do | |
98 { | |
99 delta = -delta; | |
100 synth.offset_inline( time, delta, osc_output ); | |
101 time += period; | |
102 } | |
103 while ( time < end_time ); | |
104 | |
105 oscs [index].last_amp = (delta + volume) >> 1; | |
106 phases [index] = (delta > 0); | |
107 } | |
108 else | |
109 { | |
110 // maintain phase when silent | |
111 int count = (end_time - time + period - 1) / period; | |
112 phases [index] ^= count & 1; | |
113 time += (long) count * period; | |
114 } | |
115 } | |
116 | |
117 delays [index] = time - end_time; | |
118 } | |
119 | |
120 last_time = end_time; | |
121 } | |
122 |