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, Dag Lem, Antti Lankila
-
Verschachtelte Klassen - Übersicht
Verschachtelte KlassenModifizierer und TypKlasseBeschreibungprivate static enumThe envelope state machine's distinct states. -
Feldübersicht
FelderModifizierer und TypFeldBeschreibungprivate intAttack registerprivate final short[]Emulated nonlinearity of the envelope DAC.private intDecay registerprivate byteThe current digital value of envelope output.private static final int[]Lookup table to convert from attack, decay, or release value to rate counter period.private booleanprivate intDuring release mode, the SID approximates envelope decay via piecewise linear decay rate.private intComparison value (period) of the exponential decay counter before next decrement.private booleanGate bitprivate booleanWhether hold is enabled.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 next event.private intRelease registerprivate EnvelopeGenerator.StateCurrent envelope stateprivate intSustain register -
Konstruktorübersicht
Konstruktoren -
Methodenübersicht
Modifizierer und TypMethodeBeschreibungprotected voidclock()SID clocking - 1 cycle.protected intoutput()bytereadENV()Return the envelope current value.protected voidreset()SID reset.private voidprotected voidsetChipModel(ChipModel chipModel) Set 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.protected voidwriteATTACK_DECAY(byte attack_decay) protected voidwriteCONTROL_REG(byte control) protected voidwriteSUSTAIN_RELEASE(byte sustain_release)
-
Felddetails
-
hold_zero
private boolean hold_zeroWhether hold is enabled. Only switching to ATTACK can release envelope. -
envelope_pipeline
private boolean envelope_pipeline -
rate_counter
private int rate_counterXOR 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. -
rate_period
private int rate_periodComparison value (period) of the rate counter before next event. -
exponential_counter
private int exponential_counterDuring release mode, the SID approximates envelope decay via piecewise linear decay rate. -
exponential_counter_period
private int exponential_counter_periodComparison value (period) of the exponential decay counter before next decrement. -
envelope_counter
private byte envelope_counterThe current digital value of 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 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 which is 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 beed 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 can not 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 sufficient for exact calculation of the rate periods. -
dac
private final short[] dacEmulated nonlinearity of the envelope DAC.- Siehe auch:
-
-
Konstruktordetails
-
EnvelopeGenerator
protected EnvelopeGenerator()Constructor.
-
-
Methodendetails
-
setChipModel
Set 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:
chipModel- The chip model to use.
-
clock
protected void clock()SID clocking - 1 cycle. -
output
protected int output() -
set_exponential_counter
private void set_exponential_counter() -
reset
protected void reset()SID reset. -
writeCONTROL_REG
protected void writeCONTROL_REG(byte control) - Parameter:
control- control register
-
writeATTACK_DECAY
protected void writeATTACK_DECAY(byte attack_decay) - Parameter:
attack_decay- attack/decay value
-
writeSUSTAIN_RELEASE
protected void writeSUSTAIN_RELEASE(byte sustain_release) - Parameter:
sustain_release- sustain/release value
-
readENV
public byte readENV()Return the envelope current value.- Gibt zurück:
- envelope counter
-