annotate Plugins/Input/console/Nes_Namco_Apu.cpp @ 493:c04dff121e1d trunk

[svn] hostile merge, phase 2: reimport based on new plugin code
author nenolod
date Tue, 24 Jan 2006 20:19:01 -0800
parents
children f12d7e208b43
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
493
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
1
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
2 // Nes_Snd_Emu 0.1.7. http://www.slack.net/~ant/
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
3
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
4 #include "Nes_Namco_Apu.h"
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
5
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
6 /* Copyright (C) 2003-2006 Shay Green. This module is free software; you
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
7 can redistribute it and/or modify it under the terms of the GNU Lesser
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
8 General Public License as published by the Free Software Foundation; either
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
9 version 2.1 of the License, or (at your option) any later version. This
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
10 module is distributed in the hope that it will be useful, but WITHOUT ANY
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
11 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
12 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
13 more details. You should have received a copy of the GNU Lesser General
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
14 Public License along with this module; if not, write to the Free Software
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
15 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
16
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
17 #include BLARGG_SOURCE_BEGIN
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
18
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
19 Nes_Namco_Apu::Nes_Namco_Apu()
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
20 {
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
21 output( NULL );
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
22 volume( 1.0 );
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
23 reset();
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
24 }
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
25
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
26 Nes_Namco_Apu::~Nes_Namco_Apu()
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
27 {
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
28 }
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
29
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
30 void Nes_Namco_Apu::reset()
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
31 {
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
32 last_time = 0;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
33 addr_reg = 0;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
34
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
35 int i;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
36 for ( i = 0; i < reg_count; i++ )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
37 reg [i] = 0;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
38
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
39 for ( i = 0; i < osc_count; i++ )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
40 {
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
41 Namco_Osc& osc = oscs [i];
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
42 osc.delay = 0;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
43 osc.last_amp = 0;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
44 osc.wave_pos = 0;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
45 }
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
46 }
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
47
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
48 void Nes_Namco_Apu::output( Blip_Buffer* buf )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
49 {
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
50 for ( int i = 0; i < osc_count; i++ )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
51 osc_output( i, buf );
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
52 }
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
53
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
54 /*
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
55 void Nes_Namco_Apu::reflect_state( Tagged_Data& data )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
56 {
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
57 reflect_int16( data, 'ADDR', &addr_reg );
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
58
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
59 static const char hex [17] = "0123456789ABCDEF";
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
60 int i;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
61 for ( i = 0; i < reg_count; i++ )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
62 reflect_int16( data, 'RG\0\0' + hex [i >> 4] * 0x100 + hex [i & 15], &reg [i] );
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
63
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
64 for ( i = 0; i < osc_count; i++ )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
65 {
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
66 reflect_int32( data, 'DLY0' + i, &oscs [i].delay );
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
67 reflect_int16( data, 'POS0' + i, &oscs [i].wave_pos );
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
68 }
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
69 }
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
70 */
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
71
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
72 void Nes_Namco_Apu::end_frame( nes_time_t time )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
73 {
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
74 if ( time > last_time )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
75 run_until( time );
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
76
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
77 assert( last_time >= time );
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
78 last_time -= time;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
79 }
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
80
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
81 #include BLARGG_ENABLE_OPTIMIZER
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
82
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
83 void Nes_Namco_Apu::run_until( nes_time_t nes_end_time )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
84 {
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
85 int active_oscs = (reg [0x7F] >> 4 & 7) + 1;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
86 for ( int i = osc_count - active_oscs; i < osc_count; i++ )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
87 {
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
88 Namco_Osc& osc = oscs [i];
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
89 Blip_Buffer* output = osc.output;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
90 if ( !output )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
91 continue;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
92
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
93 blip_resampled_time_t time =
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
94 output->resampled_time( last_time ) + osc.delay;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
95 blip_resampled_time_t end_time = output->resampled_time( nes_end_time );
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
96 osc.delay = 0;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
97 if ( time < end_time )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
98 {
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
99 const BOOST::uint8_t* osc_reg = &reg [i * 8 + 0x40];
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
100 if ( !(osc_reg [4] & 0xE0) )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
101 continue;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
102
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
103 int volume = osc_reg [7] & 15;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
104 if ( !volume )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
105 continue;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
106
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
107 long freq = (osc_reg [4] & 3) * 0x10000 + osc_reg [2] * 0x100L + osc_reg [0];
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
108 if ( freq < 64 * active_oscs )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
109 continue; // prevent low frequencies from excessively delaying freq changes
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
110 blip_resampled_time_t period =
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
111 output->resampled_duration( 983040 ) / freq * active_oscs;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
112
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
113 int wave_size = 32 - (osc_reg [4] >> 2 & 7) * 4;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
114 if ( !wave_size )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
115 continue;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
116
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
117 int last_amp = osc.last_amp;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
118 int wave_pos = osc.wave_pos;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
119
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
120 do
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
121 {
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
122 // read wave sample
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
123 int addr = wave_pos + osc_reg [6];
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
124 int sample = reg [addr >> 1] >> (addr << 2 & 4);
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
125 wave_pos++;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
126 sample = (sample & 15) * volume;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
127
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
128 // output impulse if amplitude changed
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
129 int delta = sample - last_amp;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
130 if ( delta )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
131 {
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
132 last_amp = sample;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
133 synth.offset_resampled( time, delta, output );
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
134 }
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
135
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
136 // next sample
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
137 time += period;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
138 if ( wave_pos >= wave_size )
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
139 wave_pos = 0;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
140 }
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
141 while ( time < end_time );
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
142
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
143 osc.wave_pos = wave_pos;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
144 osc.last_amp = last_amp;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
145 }
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
146 osc.delay = time - end_time;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
147 }
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
148
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
149 last_time = nes_end_time;
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
150 }
c04dff121e1d [svn] hostile merge, phase 2: reimport based on new plugin code
nenolod
parents:
diff changeset
151