Klasse EnvelopeGenerator
In addition, another counter is used to implement the exponential envelope decay, in effect further dividing the clock to the envelope counter. The period of this counter is set to 1, 2, 4, 8, 16, 30 at the envelope counter values 255, 93, 54, 26, 14, 6, respectively.
- Autor:
- Ken Händel
-
Verschachtelte Klassen - Übersicht
Verschachtelte KlassenModifizierer und TypKlasseBeschreibungprivate static enumThe envelope state machine's distinct states. -
Feldübersicht
FelderModifizierer und TypFeldBeschreibungprivate intAttack registerprivate final float[]Emulated nonlinearity of the envelope DAC.private intDecay registerprivate static final int[]Lookup table to convert from attack, decay, or release value to a rate counter- * period.private byteThe current digital value of envelope output.private floatThe current analog value of the envelope output.private intDuring release mode, the SID arpproximates envelope decay via piecewise linear decay rate.private intComparison value (period) of the exponential decay counter before the next decrement.private booleanGate bit(Package privat) booleanWhether hold is enabled.private booleanVoice mute (kill envelope output)private intXOR shift register emulated via normal integer which implements delay until the next envelope operation occurs.private intComparison value (period) of the rate counter before the next event.private intRelease registerprivate EnvelopeGenerator.StateCurrent envelope stateprivate intSustain register -
Konstruktorübersicht
Konstruktoren -
Methodenübersicht
Modifizierer und TypMethodeBeschreibung(Package privat) voidclock()SID clocking - 1 cycle.private voidcpuUpdateRatePeriod(int newRateCounterPeriod) When CPU updates a rate period, check for the ADSR delay bug before allowing the update to proceed.(Package privat) voidmute(boolean enable) Mute this voice.floatoutput()Return the analog value of the envelope.bytereadENV()Return the envelope's current value.(Package privat) voidreset()SID reset.(Package privat) voidsetNonLinearity(float nonLinearity) Set a nonlinearity parameter for imperfect analog DAC emulation. 1.0 means perfect 8580-like linearity, values between 0.95 - 0.97 are probably realistic 6581 nonlinearity values.(Package privat) voidwriteATTACK_DECAY(byte attack_decay) (Package privat) voidwriteCONTROL_REG(byte control) (Package privat) voidwriteSUSTAIN_RELEASE(byte sustain_release)
-
Felddetails
-
hold
boolean holdWhether hold is enabled. Only switching to ATTACK can release the envelope. -
rateCounter
private int rateCounterXOR shift register emulated via normal integer which implements delay until the next envelope operation occurs. The XOR shift register has 0x7fff different values to scan. -
rateCounterPeriod
private int rateCounterPeriodComparison value (period) of the rate counter before the next event. -
exponentialCounter
private int exponentialCounterDuring release mode, the SID arpproximates envelope decay via piecewise linear decay rate. -
exponentialCounterPeriod
private int exponentialCounterPeriodComparison value (period) of the exponential decay counter before the next decrement. -
envelopeValue
private byte envelopeValueThe current digital value of envelope output. -
envelopeValueDac
private float envelopeValueDacThe current analog value of the envelope output. -
muted
private boolean mutedVoice mute (kill envelope output) -
attack
private int attackAttack register -
decay
private int decayDecay register -
sustain
private int sustainSustain register -
release
private int releaseRelease register -
gate
private boolean gateGate bit -
state
Current envelope state -
ENVELOPE_PERIOD
private static final int[] ENVELOPE_PERIODLookup table to convert from attack, decay, or release value to a rate counter- * period.Rate counter periods are calculated from the Envelope Rates table in the Programmer's Reference Guide. The rate counter period is the number of cycles between each increment of the envelope counter. The rates have been verified by sampling ENV3.
The rate counter is a 16-bit register incremented each cycle. When the counter reaches a specific comparison value, the envelope counter is incremented (attack) or decremented (decay/release), and the counter is zeroed.
NB! Sampling ENV3 shows that the calculated values are not exact. It may seem like most calculated values have been rounded (.5 is rounded down) and 1 has been added to the result. A possible explanation for this is that the SID designers have used the calculated values directly as rate counter comparison values, not considering a one-cycle delay to zero the counter. This would yield an actual period of comparison value + 1.
The time of the first envelope count cannot be exactly controlled, except possibly by resetting the chip. Because of this we cannot do cycle exact sampling and must devise another method to calculate the rate counter periods.
The exact rate counter periods can be determined e.g., by counting the number of cycles from envelope level 1 to envelope level 129, and dividing the number of cycles by 128. CIA1 timer A and B in linked mode can perform the cycle count. This is the method used to find the rates below.
To avoid the ADSR delay bug, sampling of ENV3 should be done using sustain = release = 0. This ensures that the attack state will not lower the current rate counter period.
The ENV3 sampling code below yields a maximum timing error of 14 cycles.
lda #$01 l1: cmp $d41c bne l1 ... lda #$ff l2: cmp $d41c bne l2This yields a maximum error for the calculated rate period of 14/128 cycles. The described method is thus enough for an exact calculation of the rate periods.
-
dac
private final float[] dacEmulated nonlinearity of the envelope DAC.- Siehe auch:
-
-
Konstruktordetails
-
EnvelopeGenerator
EnvelopeGenerator()Constructor.
-
-
Methodendetails
-
clock
void clock()SID clocking - 1 cycle. -
setNonLinearity
void setNonLinearity(float nonLinearity) Set a nonlinearity parameter for imperfect analog DAC emulation. 1.0 means perfect 8580-like linearity, values between 0.95 - 0.97 are probably realistic 6581 nonlinearity values.- Parameter:
nonLinearity- non-linearity
-
reset
void reset()SID reset. -
mute
void mute(boolean enable) Mute this voice. (Triggered at next envelope event.)- Parameter:
enable- enable
-
writeCONTROL_REG
void writeCONTROL_REG(byte control) - Parameter:
control- control register
-
writeATTACK_DECAY
void writeATTACK_DECAY(byte attack_decay) - Parameter:
attack_decay- attack/decay value
-
writeSUSTAIN_RELEASE
void writeSUSTAIN_RELEASE(byte sustain_release) - Parameter:
sustain_release- sustain/release value
-
readENV
public byte readENV()Return the envelope's current value.- Gibt zurück:
- envelope counter
-
output
public float output()Return the analog value of the envelope.- Gibt zurück:
- envelope analog output
-
cpuUpdateRatePeriod
private void cpuUpdateRatePeriod(int newRateCounterPeriod) When CPU updates a rate period, check for the ADSR delay bug before allowing the update to proceed.- Parameter:
newRateCounterPeriod- rate counter period
-