Mercurial > audlegacy-plugins
annotate src/console/Ay_Apu.cxx @ 1263:458d46e65a86
wav-sndfile: in is_our_file, ensure that filename is not NULL before passing it to sf_open
author | Giacomo Lozito <james@develia.org> |
---|---|
date | Fri, 13 Jul 2007 20:55:42 +0200 |
parents | 986f098da058 |
children |
rev | line source |
---|---|
341 | 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 "Ay_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 // Emulation inaccuracies: |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
19 // * Noise isn't run when not in use |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
20 // * Changes to envelope and noise periods are delayed until next reload |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
21 // * Super-sonic tone should attenuate output to about 60%, not 50% |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
22 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
23 // Tones above this frequency are treated as disabled tone at half volume. |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
24 // Power of two is more efficient (avoids division). |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
25 unsigned const inaudible_freq = 16384; |
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 int const period_factor = 16; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
28 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
29 static byte const amp_table [16] = |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
30 { |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
31 #define ENTRY( n ) byte (n * Ay_Apu::amp_range + 0.5) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
32 // With channels tied together and 1K resistor to ground (as datasheet recommends), |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
33 // output nearly matches logarithmic curve as claimed. Approx. 1.5 dB per step. |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
34 ENTRY(0.000000),ENTRY(0.007813),ENTRY(0.011049),ENTRY(0.015625), |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
35 ENTRY(0.022097),ENTRY(0.031250),ENTRY(0.044194),ENTRY(0.062500), |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
36 ENTRY(0.088388),ENTRY(0.125000),ENTRY(0.176777),ENTRY(0.250000), |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
37 ENTRY(0.353553),ENTRY(0.500000),ENTRY(0.707107),ENTRY(1.000000), |
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 /* |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
40 // Measured from an AY-3-8910A chip with date code 8611. |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
41 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
42 // Direct voltages without any load (very linear) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
43 ENTRY(0.000000),ENTRY(0.046237),ENTRY(0.064516),ENTRY(0.089785), |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
44 ENTRY(0.124731),ENTRY(0.173118),ENTRY(0.225806),ENTRY(0.329032), |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
45 ENTRY(0.360215),ENTRY(0.494624),ENTRY(0.594624),ENTRY(0.672043), |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
46 ENTRY(0.766129),ENTRY(0.841935),ENTRY(0.926882),ENTRY(1.000000), |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
47 // With only some load |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
48 ENTRY(0.000000),ENTRY(0.011940),ENTRY(0.017413),ENTRY(0.024876), |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
49 ENTRY(0.036318),ENTRY(0.054229),ENTRY(0.072637),ENTRY(0.122388), |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
50 ENTRY(0.174129),ENTRY(0.239303),ENTRY(0.323881),ENTRY(0.410945), |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
51 ENTRY(0.527363),ENTRY(0.651741),ENTRY(0.832338),ENTRY(1.000000), |
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 #undef ENTRY |
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 static byte const modes [8] = |
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 #define MODE( a0,a1, b0,b1, c0,c1 ) \ |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
59 (a0 | a1<<1 | b0<<2 | b1<<3 | c0<<4 | c1<<5) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
60 MODE( 1,0, 1,0, 1,0 ), |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
61 MODE( 1,0, 0,0, 0,0 ), |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
62 MODE( 1,0, 0,1, 1,0 ), |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
63 MODE( 1,0, 1,1, 1,1 ), |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
64 MODE( 0,1, 0,1, 0,1 ), |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
65 MODE( 0,1, 1,1, 1,1 ), |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
66 MODE( 0,1, 1,0, 0,1 ), |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
67 MODE( 0,1, 0,0, 0,0 ), |
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 Ay_Apu::Ay_Apu() |
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 // build full table of the upper 8 envelope waveforms |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
73 for ( int m = 8; m--; ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
74 { |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
75 byte* out = env.modes [m]; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
76 int flags = modes [m]; |
341 | 77 for ( int x = 3; --x >= 0; ) |
316
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 amp = flags & 1; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
80 int end = flags >> 1 & 1; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
81 int step = end - amp; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
82 amp *= 15; |
341 | 83 for ( int y = 16; --y >= 0; ) |
316
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
84 { |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
85 *out++ = amp_table [amp]; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
86 amp += step; |
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 flags >>= 2; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
89 } |
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 output( 0 ); |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
93 volume( 1.0 ); |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
94 reset(); |
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 void Ay_Apu::reset() |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
98 { |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
99 last_time = 0; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
100 noise.delay = 0; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
101 noise.lfsr = 1; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
102 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
103 osc_t* osc = &oscs [osc_count]; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
104 do |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
105 { |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
106 osc--; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
107 osc->period = period_factor; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
108 osc->delay = 0; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
109 osc->last_amp = 0; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
110 osc->phase = 0; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
111 } |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
112 while ( osc != oscs ); |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
113 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
114 for ( int i = sizeof regs; --i >= 0; ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
115 regs [i] = 0; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
116 regs [7] = 0xFF; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
117 write_data_( 13, 0 ); |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
118 } |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
119 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
120 void Ay_Apu::write_data_( int addr, int data ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
121 { |
341 | 122 assert( (unsigned) addr < reg_count ); |
123 | |
316
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
124 if ( (unsigned) addr >= 14 ) |
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 #ifdef dprintf |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
127 dprintf( "Wrote to I/O port %02X\n", (int) addr ); |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
128 #endif |
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 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
131 // envelope mode |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
132 if ( addr == 13 ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
133 { |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
134 if ( !(data & 8) ) // convert modes 0-7 to proper equivalents |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
135 data = (data & 4) ? 15 : 9; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
136 env.wave = env.modes [data - 7]; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
137 env.pos = -48; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
138 env.delay = 0; // will get set to envelope period in run_until() |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
139 } |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
140 regs [addr] = data; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
141 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
142 // handle period changes accurately |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
143 int i = addr >> 1; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
144 if ( i < osc_count ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
145 { |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
146 blip_time_t period = (regs [i * 2 + 1] & 0x0F) * (0x100L * period_factor) + |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
147 regs [i * 2] * period_factor; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
148 if ( !period ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
149 period = period_factor; |
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 // adjust time of next timer expiration based on change in period |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
152 osc_t& osc = oscs [i]; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
153 if ( (osc.delay += period - osc.period) < 0 ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
154 osc.delay = 0; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
155 osc.period = 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 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
158 // TODO: same as above for envelope timer, and it also has a divide by two after it |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
159 } |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
160 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
161 int const noise_off = 0x08; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
162 int const tone_off = 0x01; |
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 void Ay_Apu::run_until( blip_time_t final_end_time ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
165 { |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
166 require( final_end_time >= last_time ); |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
167 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
168 // noise period and initial values |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
169 blip_time_t const noise_period_factor = period_factor * 2; // verified |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
170 blip_time_t noise_period = (regs [6] & 0x1F) * noise_period_factor; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
171 if ( !noise_period ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
172 noise_period = noise_period_factor; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
173 blip_time_t const old_noise_delay = noise.delay; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
174 blargg_ulong const old_noise_lfsr = noise.lfsr; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
175 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
176 // envelope period |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
177 blip_time_t const env_period_factor = period_factor * 2; // verified |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
178 blip_time_t env_period = (regs [12] * 0x100L + regs [11]) * env_period_factor; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
179 if ( !env_period ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
180 env_period = env_period_factor; // same as period 1 on my AY chip |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
181 if ( !env.delay ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
182 env.delay = env_period; |
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 // run each osc separately |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
185 for ( int index = 0; index < osc_count; index++ ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
186 { |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
187 osc_t* const osc = &oscs [index]; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
188 int osc_mode = regs [7] >> index; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
189 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
190 // output |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
191 Blip_Buffer* const osc_output = osc->output; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
192 if ( !osc_output ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
193 continue; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
194 osc_output->set_modified(); |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
195 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
196 // period |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
197 int half_vol = 0; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
198 blip_time_t inaudible_period = (blargg_ulong) (osc_output->clock_rate() + |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
199 inaudible_freq) / (inaudible_freq * 2); |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
200 if ( osc->period <= inaudible_period && !(osc_mode & tone_off) ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
201 { |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
202 half_vol = 1; // Actually around 60%, but 50% is close enough |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
203 osc_mode |= tone_off; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
204 } |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
205 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
206 // envelope |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
207 blip_time_t start_time = last_time; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
208 blip_time_t end_time = final_end_time; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
209 int const vol_mode = regs [0x08 + index]; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
210 int volume = amp_table [vol_mode & 0x0F] >> half_vol; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
211 int osc_env_pos = env.pos; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
212 if ( vol_mode & 0x10 ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
213 { |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
214 volume = env.wave [osc_env_pos] >> half_vol; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
215 // use envelope only if it's a repeating wave or a ramp that hasn't finished |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
216 if ( !(regs [13] & 1) || osc_env_pos < -32 ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
217 { |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
218 end_time = start_time + env.delay; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
219 if ( end_time >= final_end_time ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
220 end_time = final_end_time; |
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 //if ( !(regs [12] | regs [11]) ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
223 // dprintf( "Used envelope period 0\n" ); |
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 else if ( !volume ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
226 { |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
227 osc_mode = noise_off | tone_off; |
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 else if ( !volume ) |
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 osc_mode = noise_off | tone_off; |
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 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
235 // tone time |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
236 blip_time_t const period = osc->period; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
237 blip_time_t time = start_time + osc->delay; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
238 if ( osc_mode & tone_off ) // maintain tone's phase when off |
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 blargg_long count = (final_end_time - time + period - 1) / period; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
241 time += count * period; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
242 osc->phase ^= count & 1; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
243 } |
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 // noise time |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
246 blip_time_t ntime = final_end_time; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
247 blargg_ulong noise_lfsr = 1; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
248 if ( !(osc_mode & noise_off) ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
249 { |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
250 ntime = start_time + old_noise_delay; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
251 noise_lfsr = old_noise_lfsr; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
252 //if ( (regs [6] & 0x1F) == 0 ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
253 // dprintf( "Used noise period 0\n" ); |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
254 } |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
255 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
256 // The following efficiently handles several cases (least demanding first): |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
257 // * Tone, noise, and envelope disabled, where channel acts as 4-bit DAC |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
258 // * Just tone or just noise, envelope disabled |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
259 // * Envelope controlling tone and/or noise |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
260 // * Tone and noise disabled, envelope enabled with high frequency |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
261 // * Tone and noise together |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
262 // * Tone and noise together with envelope |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
263 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
264 // This loop only runs one iteration if envelope is disabled. If envelope |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
265 // is being used as a waveform (tone and noise disabled), this loop will |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
266 // still be reasonably efficient since the bulk of it will be skipped. |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
267 while ( 1 ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
268 { |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
269 // current amplitude |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
270 int amp = 0; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
271 if ( (osc_mode | osc->phase) & 1 & (osc_mode >> 3 | noise_lfsr) ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
272 amp = volume; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
273 { |
341 | 274 int delta = amp - osc->last_amp; |
275 if ( delta ) | |
276 { | |
277 osc->last_amp = amp; | |
278 synth_.offset( start_time, delta, osc_output ); | |
279 } | |
316
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
280 } |
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 // Run wave and noise interleved with each catching up to the other. |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
283 // If one or both are disabled, their "current time" will be past end time, |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
284 // so there will be no significant performance hit. |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
285 if ( ntime < end_time || time < end_time ) |
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 // Since amplitude was updated above, delta will always be +/- volume, |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
288 // so we can avoid using last_amp every time to calculate the delta. |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
289 int delta = amp * 2 - volume; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
290 int delta_non_zero = delta != 0; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
291 int phase = osc->phase | (osc_mode & tone_off); assert( tone_off == 0x01 ); |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
292 do |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
293 { |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
294 // run noise |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
295 blip_time_t end = end_time; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
296 if ( end_time > time ) end = time; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
297 if ( phase & delta_non_zero ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
298 { |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
299 while ( ntime <= end ) // must advance *past* time to avoid hang |
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 int changed = noise_lfsr + 1; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
302 noise_lfsr = (-(noise_lfsr & 1) & 0x12000) ^ (noise_lfsr >> 1); |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
303 if ( changed & 2 ) |
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 delta = -delta; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
306 synth_.offset( ntime, delta, osc_output ); |
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 ntime += noise_period; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
309 } |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
310 } |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
311 else |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
312 { |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
313 // 20 or more noise periods on average for some music |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
314 blargg_long remain = end - ntime; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
315 blargg_long count = remain / noise_period; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
316 if ( remain >= 0 ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
317 ntime += noise_period + count * noise_period; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
318 } |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
319 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
320 // run tone |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
321 end = end_time; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
322 if ( end_time > ntime ) end = ntime; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
323 if ( noise_lfsr & delta_non_zero ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
324 { |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
325 while ( time < end ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
326 { |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
327 delta = -delta; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
328 synth_.offset( time, delta, osc_output ); |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
329 time += period; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
330 //phase ^= 1; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
331 } |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
332 //assert( phase == (delta > 0) ); |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
333 phase = unsigned (-delta) >> (CHAR_BIT * sizeof (unsigned) - 1); |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
334 // (delta > 0) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
335 } |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
336 else |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
337 { |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
338 // loop usually runs less than once |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
339 //SUB_CASE_COUNTER( (time < end) * (end - time + period - 1) / period ); |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
340 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
341 while ( time < end ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
342 { |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
343 time += period; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
344 phase ^= 1; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
345 } |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
346 } |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
347 } |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
348 while ( time < end_time || ntime < end_time ); |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
349 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
350 osc->last_amp = (delta + volume) >> 1; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
351 if ( !(osc_mode & tone_off) ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
352 osc->phase = phase; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
353 } |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
354 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
355 if ( end_time >= final_end_time ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
356 break; // breaks first time when envelope is disabled |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
357 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
358 // next envelope step |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
359 if ( ++osc_env_pos >= 0 ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
360 osc_env_pos -= 32; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
361 volume = env.wave [osc_env_pos] >> half_vol; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
362 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
363 start_time = end_time; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
364 end_time += env_period; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
365 if ( end_time > final_end_time ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
366 end_time = final_end_time; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
367 } |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
368 osc->delay = time - final_end_time; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
369 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
370 if ( !(osc_mode & noise_off) ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
371 { |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
372 noise.delay = ntime - final_end_time; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
373 noise.lfsr = noise_lfsr; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
374 } |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
375 } |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
376 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
377 // TODO: optimized saw wave envelope? |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
378 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
379 // maintain envelope phase |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
380 blip_time_t remain = final_end_time - last_time - env.delay; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
381 if ( remain >= 0 ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
382 { |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
383 blargg_long count = (remain + env_period) / env_period; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
384 env.pos += count; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
385 if ( env.pos >= 0 ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
386 env.pos = (env.pos & 31) - 32; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
387 remain -= count * env_period; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
388 assert( -remain <= env_period ); |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
389 } |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
390 env.delay = -remain; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
391 assert( env.delay > 0 ); |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
392 assert( env.pos < 0 ); |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
393 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
394 last_time = final_end_time; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
395 } |