         else
             sweep
 
-    ###########################################################
-    # State
-    ###########################################################
-
-    updateState: ->
-        @timerPeriodValid = @timerPeriod >= 0x8 and @timerPeriod + @getSweep() < 0x800
-
-    updateVolume: ->
-        @volume = if @useConstantVolume then @constantVolume else @envelopeVolume
+    isTimerPeriodValid: ->
+        @timerPeriod >= 0x8 and @timerPeriod + @getSweep() < 0x800
 
     ###########################################################
     # Output value
     ###########################################################
 
     getOutputValue: ->
-        if @enabled and @timerPeriodValid and @lengthCounter
-            @volume * DUTY_WAVEFORMS[@dutySelection][@dutyPosition]
+        if @enabled and @lengthCounter and @$isTimerPeriodValid()
+            volume = if @useConstantVolume then @constantVolume else @envelopeVolume
+            volume * DUTY_WAVEFORMS[@dutySelection][@dutyPosition]
         else
             0
 

    ###########################################################

    writeDutyEnvelope: (value) ->
        @setDutyEnvelope value
        @updateState()
        @updateVolume()
        value

    setDutyEnvelope: (value) ->
        @dutySelection = (value & 0xC0) >>> 6      # Selects output waveform
        @lengthCounterHalt = (value & 0x20) isnt 0 # Disables length counter decrementation
        @useConstantVolume = (value & 0x10) isnt 0 # 0 - envelope volume is used / 1 - constant volume is used


    constructor: (@channelId) ->
        @setEnabled false
        @writeDutyEnvelope 0
        @writeSweep 0
        @writeTimer 0
        @writeLengthCounter 0

    setEnabled: (enabled) ->
        @enabled = enabled
