20#ifndef RESID_ENVELOPE_H
21#define RESID_ENVELOPE_H
23#include "resid-config.h"
37class EnvelopeGenerator
43 enum :
int { ATTACK, DECAY_SUSTAIN, RELEASE, FREEZED };
47 void set_chip_model(chip_model model);
50 void clock(cycle_count delta_t);
53 void writeCONTROL_REG(reg8);
54 void writeATTACK_DECAY(reg8);
55 void writeSUSTAIN_RELEASE(reg8);
62 void set_exponential_counter();
68 reg8 exponential_counter;
69 reg8 exponential_counter_period;
70 reg8 new_exponential_counter_period;
71 reg8 envelope_counter;
74 cycle_count envelope_pipeline;
75 cycle_count exponential_pipeline;
76 cycle_count state_pipeline;
78 bool reset_rate_counter;
94 static reg16 rate_counter_period[];
97 static reg8 sustain_level[];
100 static unsigned short model_dac[2][1 << 8];
112#if RESID_INLINING || defined(RESID_ENVELOPE_CC)
118void EnvelopeGenerator::clock()
121 env3 = envelope_counter;
123 if (unlikely(state_pipeline)) {
129 if (unlikely(envelope_pipeline != 0) && (--envelope_pipeline == 0)) {
130 if (likely(!hold_zero)) {
131 if (state == ATTACK) {
132 ++envelope_counter &= 0xff;
133 if (unlikely(envelope_counter == 0xff)) {
134 state = DECAY_SUSTAIN;
135 rate_period = rate_counter_period[decay];
138 else if ((state == DECAY_SUSTAIN) || (state == RELEASE)) {
139 --envelope_counter &= 0xff;
142 set_exponential_counter();
146 if (unlikely(exponential_pipeline != 0) && (--exponential_pipeline == 0)) {
147 exponential_counter = 0;
149 if (((state == DECAY_SUSTAIN) && (envelope_counter != sustain_level[sustain]))
150 || (state == RELEASE)) {
156 envelope_pipeline = 1;
159 else if (unlikely(reset_rate_counter)) {
161 reset_rate_counter =
false;
163 if (state == ATTACK) {
166 exponential_counter = 0;
173 envelope_pipeline = 2;
176 if ((!hold_zero) && ++exponential_counter == exponential_counter_period) {
177 exponential_pipeline = exponential_counter_period != 1 ? 2 : 1;
189 if (likely(rate_counter != rate_period)) {
190 if (unlikely(++rate_counter & 0x8000)) {
191 ++rate_counter &= 0x7fff;
195 reset_rate_counter =
true;
203void EnvelopeGenerator::clock(cycle_count delta_t)
208 if (unlikely(state_pipeline)) {
209 if (next_state == ATTACK) {
212 rate_period = rate_counter_period[attack];
213 }
else if (next_state == RELEASE) {
215 rate_period = rate_counter_period[release];
216 }
else if (next_state == FREEZED) {
231 int rate_step = rate_period - rate_counter;
232 if (unlikely(rate_step <= 0)) {
237 if (delta_t < rate_step) {
239 rate_counter += delta_t;
240 if (unlikely(rate_counter & 0x8000)) {
241 ++rate_counter &= 0x7fff;
247 delta_t -= rate_step;
252 if (state == ATTACK || ++exponential_counter == exponential_counter_period) {
254 exponential_counter = 0;
257 if (unlikely(hold_zero)) {
258 rate_step = rate_period;
269 ++envelope_counter &= 0xff;
270 if (unlikely(envelope_counter == 0xff)) {
271 state = DECAY_SUSTAIN;
272 rate_period = rate_counter_period[decay];
276 if (likely(envelope_counter != sustain_level[sustain])) {
287 --envelope_counter &= 0xff;
295 set_exponential_counter();
296 if (unlikely(new_exponential_counter_period > 0)) {
297 exponential_counter_period = new_exponential_counter_period;
298 new_exponential_counter_period = 0;
299 if (next_state == FREEZED) {
305 rate_step = rate_period;
349void EnvelopeGenerator::state_change()
353 switch (next_state) {
355 if (state_pipeline == 0) {
358 rate_period = rate_counter_period[attack];
365 if (((state == ATTACK) && (state_pipeline == 0))
366 || ((state == DECAY_SUSTAIN) && (state_pipeline == 1))) {
368 rate_period = rate_counter_period[release];
381short EnvelopeGenerator::output()
385 return model_dac[sid_model][envelope_counter];
389void EnvelopeGenerator::set_exponential_counter()
392 switch (envelope_counter) {
394 exponential_counter_period = 1;
397 exponential_counter_period = 2;
400 exponential_counter_period = 4;
403 exponential_counter_period = 8;
406 exponential_counter_period = 16;
409 exponential_counter_period = 30;
415 exponential_counter_period = 1;