Mercurial > audlegacy-plugins
annotate src/console/Kss_Scc_Apu.cxx @ 316:fb513e10174e trunk
[svn] - merge libconsole-blargg into mainline libconsole:
+ obsoletes plugins-ugly:sapplug
author | nenolod |
---|---|
date | Thu, 30 Nov 2006 19:54:33 -0800 |
parents | |
children | 986f098da058 |
rev | line source |
---|---|
316
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
1 // Game_Music_Emu 0.5.1. http://www.slack.net/~ant/ |
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 "Kss_Scc_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 /* Copyright (C) 2006 Shay Green. This module is free software; you |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
6 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
|
7 General Public License as published by the Free Software Foundation; either |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
8 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
|
9 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
|
10 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
11 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
|
12 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
|
13 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
|
14 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
15 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
16 #include "blargg_source.h" |
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 // Tones above this frequency are treated as disabled tone at half volume. |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
19 // Power of two is more efficient (avoids division). |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
20 unsigned const inaudible_freq = 16384; |
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 int const wave_size = 0x20; |
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 void Scc_Apu::run_until( blip_time_t end_time ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
25 { |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
26 for ( int index = 0; index < osc_count; index++ ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
27 { |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
28 osc_t& osc = oscs [index]; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
29 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
30 Blip_Buffer* const output = osc.output; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
31 if ( !output ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
32 continue; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
33 output->set_modified(); |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
34 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
35 blip_time_t period = (regs [0x80 + index * 2 + 1] & 0x0F) * 0x100 + |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
36 regs [0x80 + index * 2] + 1; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
37 int volume = 0; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
38 if ( regs [0x8F] & (1 << index) ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
39 { |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
40 blip_time_t inaudible_period = (blargg_ulong) (output->clock_rate() + |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
41 inaudible_freq * 32) / (inaudible_freq * 16); |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
42 if ( period > inaudible_period ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
43 volume = (regs [0x8A + index] & 0x0F) * (amp_range / 256 / 15); |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
44 } |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
45 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
46 BOOST::int8_t const* wave = (BOOST::int8_t*) regs + index * wave_size; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
47 if ( index == osc_count - 1 ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
48 wave -= wave_size; // last two oscs share wave |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
49 int amp = wave [osc.phase] * volume; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
50 int delta = amp - osc.last_amp; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
51 if ( delta ) |
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 osc.last_amp = amp; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
54 synth.offset( last_time, delta, output ); |
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 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
57 blip_time_t time = last_time + osc.delay; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
58 if ( time < end_time ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
59 { |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
60 if ( !volume ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
61 { |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
62 // maintain phase |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
63 blargg_long count = (end_time - time + period - 1) / period; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
64 osc.phase = (osc.phase + count) & (wave_size - 1); |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
65 time += count * period; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
66 } |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
67 else |
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 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
70 int phase = osc.phase; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
71 int last_wave = wave [phase]; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
72 phase = (phase + 1) & (wave_size - 1); // pre-advance for optimal inner loop |
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 do |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
75 { |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
76 int amp = wave [phase]; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
77 phase = (phase + 1) & (wave_size - 1); |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
78 int delta = amp - last_wave; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
79 if ( delta ) |
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 last_wave = amp; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
82 synth.offset( time, delta * volume, output ); |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
83 } |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
84 time += period; |
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 while ( time < end_time ); |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
87 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
88 osc.phase = phase = (phase - 1) & (wave_size - 1); // undo pre-advance |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
89 osc.last_amp = wave [phase] * volume; |
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 } |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
92 osc.delay = time - end_time; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
93 } |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
94 last_time = end_time; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
95 } |