Klasse EnvelopeGenerator

java.lang.Object
builder.resid.residfp.EnvelopeGenerator

public final class EnvelopeGenerator extends Object
A 15 bit counter is used to implement the envelope rates, in effect dividing the clock to the envelope counter by the currently selected rate period.

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 Klassen
    Modifizierer und Typ
    Klasse
    Beschreibung
    private static enum 
    The envelope state machine's distinct states.
  • Feldübersicht

    Felder
    Modifizierer und Typ
    Feld
    Beschreibung
    private int
    Attack register
    private final float[]
    Emulated nonlinearity of the envelope DAC.
    private int
    Decay register
    private static final int[]
    Lookup table to convert from attack, decay, or release value to rate counter period.
    private byte
    The current digital value of envelope output.
    private float
    The current analog value of envelope output.
    private int
    During release mode, the SID arpproximates envelope decay via piecewise linear decay rate.
    private int
    Comparison value (period) of the exponential decay counter before next decrement.
    private boolean
    Gate bit
    (Package privat) boolean
    Whether hold is enabled.
    private boolean
    Voice mute (kill envelope output)
    private int
    XOR shift register emulated via normal integer which implements delay until the next envelope operation occurs.
    private int
    Comparison value (period) of the rate counter before next event.
    private int
    Release register
    Current envelope state
    private int
    Sustain register
  • Konstruktorübersicht

    Konstruktoren
    Modifizierer
    Konstruktor
    Beschreibung
    protected
    Constructor.
  • Methodenübersicht

    Modifizierer und Typ
    Methode
    Beschreibung
    protected void
    SID clocking - 1 cycle.
    private void
    cpuUpdateRatePeriod(int newRateCounterPeriod)
    When CPU updates rate period, check for ADSR delay bug before allowing the update to proceed.
    protected void
    mute(boolean enable)
    Mute this voice.
    float
    Return the analog value of envelope.
    byte
    Return the envelope current value.
    protected void
    SID reset.
    protected void
    setNonLinearity(float nonLinearity)
    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 void
    writeATTACK_DECAY(byte attack_decay)
     
    protected void
    writeCONTROL_REG(byte control)
     
    protected void
    writeSUSTAIN_RELEASE(byte sustain_release)
     

    Von Klasse geerbte Methoden java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Felddetails

    • hold

      boolean hold
      Whether hold is enabled. Only switching to ATTACK can release envelope.
    • rateCounter

      private int rateCounter
      XOR 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 rateCounterPeriod
      Comparison value (period) of the rate counter before next event.
    • exponentialCounter

      private int exponentialCounter
      During release mode, the SID arpproximates envelope decay via piecewise linear decay rate.
    • exponentialCounterPeriod

      private int exponentialCounterPeriod
      Comparison value (period) of the exponential decay counter before next decrement.
    • envelopeValue

      private byte envelopeValue
      The current digital value of envelope output.
    • envelopeValueDac

      private float envelopeValueDac
      The current analog value of envelope output.
    • muted

      private boolean muted
      Voice mute (kill envelope output)
    • attack

      private int attack
      Attack register
    • decay

      private int decay
      Decay register
    • sustain

      private int sustain
      Sustain register
    • release

      private int release
      Release register
    • gate

      private boolean gate
      Gate bit
    • state

      private EnvelopeGenerator.State state
      Current envelope state
    • ENVELOPE_PERIOD

      private static final int[] ENVELOPE_PERIOD
      Lookup 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 l2
       
      This 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 float[] dac
      Emulated nonlinearity of the envelope DAC.
      Siehe auch:
  • Konstruktordetails

    • EnvelopeGenerator

      protected EnvelopeGenerator()
      Constructor.
  • Methodendetails

    • clock

      protected void clock()
      SID clocking - 1 cycle.
    • setNonLinearity

      protected void setNonLinearity(float nonLinearity)
      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:
      nonLinearity -
    • reset

      protected void reset()
      SID reset.
    • mute

      protected void mute(boolean enable)
      Mute this voice. (Triggered at next envelope event.)
      Parameter:
      enable -
    • 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
    • output

      public float output()
      Return the analog value of envelope.
      Gibt zurück:
      envelope analog output
    • cpuUpdateRatePeriod

      private void cpuUpdateRatePeriod(int newRateCounterPeriod)
      When CPU updates rate period, check for ADSR delay bug before allowing the update to proceed.
      Parameter:
      newRateCounterPeriod -