annotate src/console/Hes_Apu.cxx @ 952:87666f9bf6d0 trunk

[svn] Upstream commit "Vastly enhanced generic Protracker player and modified loaders accordingly. Copl now supports a getchip() method. A2M loader enhanced for OPL3 features." manually applied by decoding the actual changes from an ocean of whitespace damage. It compiles, but do test it.
author chainsaw
date Fri, 13 Apr 2007 09:09:50 -0700
parents 986f098da058
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
341
986f098da058 [svn] - merge in blargg's changes
nenolod
parents: 316
diff changeset
1 // Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
316
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
2
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
3 #include "Hes_Apu.h"
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
4
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
5 #include <string.h>
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
6
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
7 /* Copyright (C) 2006 Shay Green. This module is free software; you
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
8 can redistribute it and/or modify it under the terms of the GNU Lesser
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
9 General Public License as published by the Free Software Foundation; either
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
10 version 2.1 of the License, or (at your option) any later version. This
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
11 module is distributed in the hope that it will be useful, but WITHOUT ANY
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
13 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
14 details. You should have received a copy of the GNU Lesser General Public
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
15 License along with this module; if not, write to the Free Software Foundation,
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
16 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
17
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
18 #include "blargg_source.h"
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
19
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
20 bool const center_waves = true; // reduces asymmetry and clamping when starting notes
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
21
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
22 Hes_Apu::Hes_Apu()
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
23 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
24 Hes_Osc* osc = &oscs [osc_count];
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
25 do
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
26 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
27 osc--;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
28 osc->outputs [0] = 0;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
29 osc->outputs [1] = 0;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
30 osc->chans [0] = 0;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
31 osc->chans [1] = 0;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
32 osc->chans [2] = 0;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
33 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
34 while ( osc != oscs );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
35
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
36 reset();
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
37 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
38
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
39 void Hes_Apu::reset()
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
40 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
41 latch = 0;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
42 balance = 0xFF;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
43
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
44 Hes_Osc* osc = &oscs [osc_count];
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
45 do
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
46 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
47 osc--;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
48 memset( osc, 0, offsetof (Hes_Osc,outputs) );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
49 osc->noise_lfsr = 1;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
50 osc->control = 0x40;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
51 osc->balance = 0xFF;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
52 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
53 while ( osc != oscs );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
54 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
55
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
56 void Hes_Apu::osc_output( int index, Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
57 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
58 require( (unsigned) index < osc_count );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
59 oscs [index].chans [0] = center;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
60 oscs [index].chans [1] = left;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
61 oscs [index].chans [2] = right;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
62
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
63 Hes_Osc* osc = &oscs [osc_count];
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
64 do
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
65 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
66 osc--;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
67 balance_changed( *osc );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
68 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
69 while ( osc != oscs );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
70 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
71
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
72 void Hes_Osc::run_until( synth_t& synth_, blip_time_t end_time )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
73 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
74 Blip_Buffer* const osc_outputs_0 = outputs [0]; // cache often-used values
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
75 if ( osc_outputs_0 && control & 0x80 )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
76 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
77 int dac = this->dac;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
78
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
79 int const volume_0 = volume [0];
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
80 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
81 int delta = dac * volume_0 - last_amp [0];
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
82 if ( delta )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
83 synth_.offset( last_time, delta, osc_outputs_0 );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
84 osc_outputs_0->set_modified();
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
85 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
86
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
87 Blip_Buffer* const osc_outputs_1 = outputs [1];
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
88 int const volume_1 = volume [1];
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
89 if ( osc_outputs_1 )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
90 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
91 int delta = dac * volume_1 - last_amp [1];
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
92 if ( delta )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
93 synth_.offset( last_time, delta, osc_outputs_1 );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
94 osc_outputs_1->set_modified();
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
95 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
96
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
97 blip_time_t time = last_time + delay;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
98 if ( time < end_time )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
99 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
100 if ( noise & 0x80 )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
101 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
102 if ( volume_0 | volume_1 )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
103 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
104 // noise
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
105 int const period = (32 - (noise & 0x1F)) * 64; // TODO: correct?
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
106 unsigned noise_lfsr = this->noise_lfsr;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
107 do
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
108 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
109 int new_dac = 0x1F & -(noise_lfsr >> 1 & 1);
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
110 // Implemented using "Galios configuration"
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
111 // TODO: find correct LFSR algorithm
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
112 noise_lfsr = (noise_lfsr >> 1) ^ (0xE008 & -(noise_lfsr & 1));
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
113 //noise_lfsr = (noise_lfsr >> 1) ^ (0x6000 & -(noise_lfsr & 1));
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
114 int delta = new_dac - dac;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
115 if ( delta )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
116 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
117 dac = new_dac;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
118 synth_.offset( time, delta * volume_0, osc_outputs_0 );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
119 if ( osc_outputs_1 )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
120 synth_.offset( time, delta * volume_1, osc_outputs_1 );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
121 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
122 time += period;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
123 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
124 while ( time < end_time );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
125
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
126 this->noise_lfsr = noise_lfsr;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
127 assert( noise_lfsr );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
128 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
129 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
130 else if ( !(control & 0x40) )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
131 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
132 // wave
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
133 int phase = (this->phase + 1) & 0x1F; // pre-advance for optimal inner loop
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
134 int period = this->period * 2;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
135 if ( period >= 14 && (volume_0 | volume_1) )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
136 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
137 do
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
138 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
139 int new_dac = wave [phase];
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
140 phase = (phase + 1) & 0x1F;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
141 int delta = new_dac - dac;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
142 if ( delta )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
143 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
144 dac = new_dac;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
145 synth_.offset( time, delta * volume_0, osc_outputs_0 );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
146 if ( osc_outputs_1 )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
147 synth_.offset( time, delta * volume_1, osc_outputs_1 );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
148 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
149 time += period;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
150 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
151 while ( time < end_time );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
152 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
153 else
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
154 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
155 if ( !period )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
156 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
157 // TODO: Gekisha Boy assumes that period = 0 silences wave
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
158 //period = 0x1000 * 2;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
159 period = 1;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
160 //if ( !(volume_0 | volume_1) )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
161 // dprintf( "Used period 0\n" );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
162 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
163
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
164 // maintain phase when silent
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
165 blargg_long count = (end_time - time + period - 1) / period;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
166 phase += count; // phase will be masked below
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
167 time += count * period;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
168 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
169 this->phase = (phase - 1) & 0x1F; // undo pre-advance
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
170 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
171 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
172 time -= end_time;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
173 if ( time < 0 )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
174 time = 0;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
175 delay = time;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
176
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
177 this->dac = dac;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
178 last_amp [0] = dac * volume_0;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
179 last_amp [1] = dac * volume_1;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
180 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
181 last_time = end_time;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
182 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
183
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
184 void Hes_Apu::balance_changed( Hes_Osc& osc )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
185 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
186 static short const log_table [32] = { // ~1.5 db per step
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
187 #define ENTRY( factor ) short (factor * Hes_Osc::amp_range / 31.0 + 0.5)
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
188 ENTRY( 0.000000 ),ENTRY( 0.005524 ),ENTRY( 0.006570 ),ENTRY( 0.007813 ),
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
189 ENTRY( 0.009291 ),ENTRY( 0.011049 ),ENTRY( 0.013139 ),ENTRY( 0.015625 ),
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
190 ENTRY( 0.018581 ),ENTRY( 0.022097 ),ENTRY( 0.026278 ),ENTRY( 0.031250 ),
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
191 ENTRY( 0.037163 ),ENTRY( 0.044194 ),ENTRY( 0.052556 ),ENTRY( 0.062500 ),
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
192 ENTRY( 0.074325 ),ENTRY( 0.088388 ),ENTRY( 0.105112 ),ENTRY( 0.125000 ),
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
193 ENTRY( 0.148651 ),ENTRY( 0.176777 ),ENTRY( 0.210224 ),ENTRY( 0.250000 ),
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
194 ENTRY( 0.297302 ),ENTRY( 0.353553 ),ENTRY( 0.420448 ),ENTRY( 0.500000 ),
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
195 ENTRY( 0.594604 ),ENTRY( 0.707107 ),ENTRY( 0.840896 ),ENTRY( 1.000000 ),
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
196 #undef ENTRY
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
197 };
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
198
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
199 int vol = (osc.control & 0x1F) - 0x1E * 2;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
200
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
201 int left = vol + (osc.balance >> 3 & 0x1E) + (balance >> 3 & 0x1E);
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
202 if ( left < 0 ) left = 0;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
203
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
204 int right = vol + (osc.balance << 1 & 0x1E) + (balance << 1 & 0x1E);
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
205 if ( right < 0 ) right = 0;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
206
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
207 left = log_table [left ];
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
208 right = log_table [right];
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
209
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
210 // optimizing for the common case of being centered also allows easy
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
211 // panning using Effects_Buffer
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
212 osc.outputs [0] = osc.chans [0]; // center
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
213 osc.outputs [1] = 0;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
214 if ( left != right )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
215 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
216 osc.outputs [0] = osc.chans [1]; // left
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
217 osc.outputs [1] = osc.chans [2]; // right
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
218 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
219
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
220 if ( center_waves )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
221 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
222 osc.last_amp [0] += (left - osc.volume [0]) * 16;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
223 osc.last_amp [1] += (right - osc.volume [1]) * 16;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
224 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
225
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
226 osc.volume [0] = left;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
227 osc.volume [1] = right;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
228 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
229
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
230 void Hes_Apu::write_data( blip_time_t time, int addr, int data )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
231 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
232 if ( addr == 0x800 )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
233 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
234 latch = data & 7;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
235 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
236 else if ( addr == 0x801 )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
237 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
238 if ( balance != data )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
239 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
240 balance = data;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
241
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
242 Hes_Osc* osc = &oscs [osc_count];
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
243 do
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
244 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
245 osc--;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
246 osc->run_until( synth, time );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
247 balance_changed( *oscs );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
248 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
249 while ( osc != oscs );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
250 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
251 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
252 else if ( latch < osc_count )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
253 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
254 Hes_Osc& osc = oscs [latch];
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
255 osc.run_until( synth, time );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
256 switch ( addr )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
257 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
258 case 0x802:
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
259 osc.period = (osc.period & 0xF00) | data;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
260 break;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
261
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
262 case 0x803:
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
263 osc.period = (osc.period & 0x0FF) | ((data & 0x0F) << 8);
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
264 break;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
265
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
266 case 0x804:
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
267 if ( osc.control & 0x40 & ~data )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
268 osc.phase = 0;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
269 osc.control = data;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
270 balance_changed( osc );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
271 break;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
272
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
273 case 0x805:
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
274 osc.balance = data;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
275 balance_changed( osc );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
276 break;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
277
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
278 case 0x806:
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
279 data &= 0x1F;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
280 if ( !(osc.control & 0x40) )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
281 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
282 osc.wave [osc.phase] = data;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
283 osc.phase = (osc.phase + 1) & 0x1F;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
284 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
285 else if ( osc.control & 0x80 )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
286 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
287 osc.dac = data;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
288 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
289 break;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
290
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
291 case 0x807:
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
292 if ( &osc >= &oscs [4] )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
293 osc.noise = data;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
294 break;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
295
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
296 case 0x809:
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
297 if ( !(data & 0x80) && (data & 0x03) != 0 )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
298 dprintf( "HES LFO not supported\n" );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
299 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
300 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
301 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
302
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
303 void Hes_Apu::end_frame( blip_time_t end_time )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
304 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
305 Hes_Osc* osc = &oscs [osc_count];
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
306 do
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
307 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
308 osc--;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
309 if ( end_time > osc->last_time )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
310 osc->run_until( synth, end_time );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
311 assert( osc->last_time >= end_time );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
312 osc->last_time -= end_time;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
313 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
314 while ( osc != oscs );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
315 }