package com.domemusictechnologies.bitreducer;


import voltage.controllers.*;
import voltage.core.*;
import voltage.core.Jack.JackType;
import voltage.sources.*;
import voltage.utility.*;
import voltage.processors.*;
import voltage.effects.*;
import java.awt.*;

//[user-imports]   Add your own imports here

import static java.lang.Math.floor;
import static java.lang.Math.pow;

//[/user-imports]


public class BitReducer extends VoltageModule
//[user-inheritance]
//[/user-inheritance]
{

public BitReducer( long moduleID, VoltageObjects voltageObjects )
{
   super( moduleID, voltageObjects, "Bit Reducer", ModuleType.ModuleType_CVProcessors, 1.0 );

   InitializeControls();


   canBeBypassed = false;
   SetSkin( "ea00e7c4bcf54cad960425ab9d8cab9c" );
}

void InitializeControls()
{

   sliderDitherBits = new VoltageSlider( "Dither Bits", "Dither Bits", this, false, 0.0, 2.0, 1.0, 0 );
   AddComponent( sliderDitherBits );
   sliderDitherBits.SetWantsMouseNotifications( false );
   sliderDitherBits.SetPosition( 5, 186 );
   sliderDitherBits.SetSize( 61, 17 );
   sliderDitherBits.SetSkin( "Straight Black Plain Horizontal Ext Track" );
   sliderDitherBits.DisplayValueInPercent( true );

   knobBitDepth = new VoltageKnob( "Bit Depth", "Bit Depth", this, 1, 24, 24 );
   AddComponent( knobBitDepth );
   knobBitDepth.SetWantsMouseNotifications( false );
   knobBitDepth.SetPosition( 12, 79 );
   knobBitDepth.SetSize( 47, 47 );
   knobBitDepth.SetSkin( "7 edge silver" );
   knobBitDepth.SetRange( 1, 24, 24, false, 24 );
   knobBitDepth.SetKnobParams( 215, 145 );
   knobBitDepth.DisplayValueInPercent( false );
   knobBitDepth.SetKnobAdjustsRing( true );

   inputJackLeft = new VoltageAudioJack( "Left Input", "Left Input", this, JackType.JackType_AudioInput );
   AddComponent( inputJackLeft );
   inputJackLeft.SetWantsMouseNotifications( false );
   inputJackLeft.SetPosition( 5, 50 );
   inputJackLeft.SetSize( 25, 25 );
   inputJackLeft.SetSkin( "Jack Round White Ring" );

   inputJackRight = new VoltageAudioJack( "Right Input", "Right Input", this, JackType.JackType_AudioInput );
   AddComponent( inputJackRight );
   inputJackRight.SetWantsMouseNotifications( false );
   inputJackRight.SetPosition( 42, 50 );
   inputJackRight.SetSize( 25, 25 );
   inputJackRight.SetSkin( "Jack Round Red Ring" );

   textLabel1 = new VoltageLabel( "textLabel1", "textLabel1", this, "Bit Reducer" );
   AddComponent( textLabel1 );
   textLabel1.SetWantsMouseNotifications( false );
   textLabel1.SetPosition( 2, 0 );
   textLabel1.SetSize( 66, 29 );
   textLabel1.SetEditable( false, false );
   textLabel1.SetJustificationFlags( VoltageLabel.Justification.HorizCentered );
   textLabel1.SetJustificationFlags( VoltageLabel.Justification.VertCentered );
   textLabel1.SetColor( new Color( 255, 255, 255, 255 ) );
   textLabel1.SetBkColor( new Color( 65, 65, 65, 0 ) );
   textLabel1.SetBorderColor( new Color( 0, 0, 0, 0 ) );
   textLabel1.SetBorderSize( 1 );
   textLabel1.SetMultiLineEdit( true );
   textLabel1.SetIsNumberEditor( false );
   textLabel1.SetNumberEditorRange( 0, 100 );
   textLabel1.SetNumberEditorInterval( 1 );
   textLabel1.SetNumberEditorUsesMouseWheel( false );
   textLabel1.SetHasCustomTextHoverColor( false );
   textLabel1.SetTextHoverColor( new Color( 0, 0, 0, 255 ) );
   textLabel1.SetFont( "Verdana", 14, false, false );

   textLabel6 = new VoltageLabel( "textLabel6", "textLabel6", this, "Dome Music Technologies" );
   AddComponent( textLabel6 );
   textLabel6.SetWantsMouseNotifications( false );
   textLabel6.SetPosition( 8, 342 );
   textLabel6.SetSize( 56, 18 );
   textLabel6.SetEditable( false, false );
   textLabel6.SetJustificationFlags( VoltageLabel.Justification.HorizCentered );
   textLabel6.SetJustificationFlags( VoltageLabel.Justification.VertCentered );
   textLabel6.SetColor( new Color( 255, 255, 255, 255 ) );
   textLabel6.SetBkColor( new Color( 65, 65, 65, 0 ) );
   textLabel6.SetBorderColor( new Color( 0, 0, 0, 0 ) );
   textLabel6.SetBorderSize( 1 );
   textLabel6.SetMultiLineEdit( true );
   textLabel6.SetIsNumberEditor( false );
   textLabel6.SetNumberEditorRange( 0, 100 );
   textLabel6.SetNumberEditorInterval( 1 );
   textLabel6.SetNumberEditorUsesMouseWheel( false );
   textLabel6.SetHasCustomTextHoverColor( false );
   textLabel6.SetTextHoverColor( new Color( 0, 0, 0, 255 ) );
   textLabel6.SetFont( "Verdana", 7, false, false );

   textLabel3 = new VoltageLabel( "textLabel3", "textLabel3", this, "Processed" );
   AddComponent( textLabel3 );
   textLabel3.SetWantsMouseNotifications( false );
   textLabel3.SetPosition( 5, 214 );
   textLabel3.SetSize( 62, 21 );
   textLabel3.SetEditable( false, false );
   textLabel3.SetJustificationFlags( VoltageLabel.Justification.HorizCentered );
   textLabel3.SetJustificationFlags( VoltageLabel.Justification.VertCentered );
   textLabel3.SetColor( new Color( 255, 255, 255, 255 ) );
   textLabel3.SetBkColor( new Color( 65, 65, 65, 0 ) );
   textLabel3.SetBorderColor( new Color( 0, 0, 0, 0 ) );
   textLabel3.SetBorderSize( 1 );
   textLabel3.SetMultiLineEdit( false );
   textLabel3.SetIsNumberEditor( false );
   textLabel3.SetNumberEditorRange( 0, 100 );
   textLabel3.SetNumberEditorInterval( 1 );
   textLabel3.SetNumberEditorUsesMouseWheel( false );
   textLabel3.SetHasCustomTextHoverColor( false );
   textLabel3.SetTextHoverColor( new Color( 0, 0, 0, 255 ) );
   textLabel3.SetFont( "Verdana", 12, false, false );

   textLabel5 = new VoltageLabel( "textLabel5", "textLabel5", this, "Unprocessed" );
   AddComponent( textLabel5 );
   textLabel5.SetWantsMouseNotifications( false );
   textLabel5.SetPosition( 1, 254 );
   textLabel5.SetSize( 70, 21 );
   textLabel5.SetEditable( false, false );
   textLabel5.SetJustificationFlags( VoltageLabel.Justification.HorizCentered );
   textLabel5.SetJustificationFlags( VoltageLabel.Justification.VertCentered );
   textLabel5.SetColor( new Color( 255, 255, 255, 255 ) );
   textLabel5.SetBkColor( new Color( 65, 65, 65, 0 ) );
   textLabel5.SetBorderColor( new Color( 0, 0, 0, 0 ) );
   textLabel5.SetBorderSize( 1 );
   textLabel5.SetMultiLineEdit( false );
   textLabel5.SetIsNumberEditor( false );
   textLabel5.SetNumberEditorRange( 0, 100 );
   textLabel5.SetNumberEditorInterval( 1 );
   textLabel5.SetNumberEditorUsesMouseWheel( false );
   textLabel5.SetHasCustomTextHoverColor( false );
   textLabel5.SetTextHoverColor( new Color( 0, 0, 0, 255 ) );
   textLabel5.SetFont( "Verdana", 12, false, false );

   textLabel2 = new VoltageLabel( "textLabel2", "textLabel2", this, "Inputs" );
   AddComponent( textLabel2 );
   textLabel2.SetWantsMouseNotifications( false );
   textLabel2.SetPosition( 5, 26 );
   textLabel2.SetSize( 62, 30 );
   textLabel2.SetEditable( false, false );
   textLabel2.SetJustificationFlags( VoltageLabel.Justification.HorizCentered );
   textLabel2.SetJustificationFlags( VoltageLabel.Justification.VertCentered );
   textLabel2.SetColor( new Color( 255, 255, 255, 255 ) );
   textLabel2.SetBkColor( new Color( 65, 65, 65, 0 ) );
   textLabel2.SetBorderColor( new Color( 0, 0, 0, 0 ) );
   textLabel2.SetBorderSize( 1 );
   textLabel2.SetMultiLineEdit( false );
   textLabel2.SetIsNumberEditor( false );
   textLabel2.SetNumberEditorRange( 0, 100 );
   textLabel2.SetNumberEditorInterval( 1 );
   textLabel2.SetNumberEditorUsesMouseWheel( false );
   textLabel2.SetHasCustomTextHoverColor( false );
   textLabel2.SetTextHoverColor( new Color( 0, 0, 0, 255 ) );
   textLabel2.SetFont( "Verdana", 12, false, false );

   textLabel7 = new VoltageLabel( "textLabel7", "textLabel7", this, "Difference" );
   AddComponent( textLabel7 );
   textLabel7.SetWantsMouseNotifications( false );
   textLabel7.SetPosition( 5, 294 );
   textLabel7.SetSize( 62, 21 );
   textLabel7.SetEditable( false, false );
   textLabel7.SetJustificationFlags( VoltageLabel.Justification.HorizCentered );
   textLabel7.SetJustificationFlags( VoltageLabel.Justification.VertCentered );
   textLabel7.SetColor( new Color( 255, 255, 255, 255 ) );
   textLabel7.SetBkColor( new Color( 65, 65, 65, 0 ) );
   textLabel7.SetBorderColor( new Color( 0, 0, 0, 0 ) );
   textLabel7.SetBorderSize( 1 );
   textLabel7.SetMultiLineEdit( false );
   textLabel7.SetIsNumberEditor( false );
   textLabel7.SetNumberEditorRange( 0, 100 );
   textLabel7.SetNumberEditorInterval( 1 );
   textLabel7.SetNumberEditorUsesMouseWheel( false );
   textLabel7.SetHasCustomTextHoverColor( false );
   textLabel7.SetTextHoverColor( new Color( 0, 0, 0, 255 ) );
   textLabel7.SetFont( "Verdana", 12, false, false );

   textBitDepth = new VoltageLabel( "Bit Depth Label", "Bit Depth Label", this, "24 Bits" );
   AddComponent( textBitDepth );
   textBitDepth.SetWantsMouseNotifications( false );
   textBitDepth.SetPosition( 5, 122 );
   textBitDepth.SetSize( 62, 23 );
   textBitDepth.SetEditable( false, false );
   textBitDepth.SetJustificationFlags( VoltageLabel.Justification.HorizCentered );
   textBitDepth.SetJustificationFlags( VoltageLabel.Justification.VertCentered );
   textBitDepth.SetColor( new Color( 255, 255, 255, 255 ) );
   textBitDepth.SetBkColor( new Color( 65, 65, 65, 0 ) );
   textBitDepth.SetBorderColor( new Color( 0, 0, 0, 0 ) );
   textBitDepth.SetBorderSize( 1 );
   textBitDepth.SetMultiLineEdit( false );
   textBitDepth.SetIsNumberEditor( false );
   textBitDepth.SetNumberEditorRange( 0, 100 );
   textBitDepth.SetNumberEditorInterval( 1 );
   textBitDepth.SetNumberEditorUsesMouseWheel( false );
   textBitDepth.SetHasCustomTextHoverColor( false );
   textBitDepth.SetTextHoverColor( new Color( 0, 0, 0, 255 ) );
   textBitDepth.SetFont( "Verdana", 12, false, false );

   textBitDepth_1 = new VoltageLabel( "Bit Depth Label_1", "Bit Depth Label_1", this, "1" );
   AddComponent( textBitDepth_1 );
   textBitDepth_1.SetWantsMouseNotifications( false );
   textBitDepth_1.SetPosition( 26, 199 );
   textBitDepth_1.SetSize( 16, 16 );
   textBitDepth_1.SetEditable( false, false );
   textBitDepth_1.SetJustificationFlags( VoltageLabel.Justification.HorizCentered );
   textBitDepth_1.SetJustificationFlags( VoltageLabel.Justification.VertCentered );
   textBitDepth_1.SetColor( new Color( 255, 255, 255, 255 ) );
   textBitDepth_1.SetBkColor( new Color( 65, 65, 65, 0 ) );
   textBitDepth_1.SetBorderColor( new Color( 0, 0, 0, 0 ) );
   textBitDepth_1.SetBorderSize( 1 );
   textBitDepth_1.SetMultiLineEdit( false );
   textBitDepth_1.SetIsNumberEditor( false );
   textBitDepth_1.SetNumberEditorRange( 0, 100 );
   textBitDepth_1.SetNumberEditorInterval( 1 );
   textBitDepth_1.SetNumberEditorUsesMouseWheel( false );
   textBitDepth_1.SetHasCustomTextHoverColor( false );
   textBitDepth_1.SetTextHoverColor( new Color( 0, 0, 0, 255 ) );
   textBitDepth_1.SetFont( "Verdana", 12, false, false );

   textBitDepth_2 = new VoltageLabel( "Bit Depth Label_2", "Bit Depth Label_2", this, "0" );
   AddComponent( textBitDepth_2 );
   textBitDepth_2.SetWantsMouseNotifications( false );
   textBitDepth_2.SetPosition( 2, 199 );
   textBitDepth_2.SetSize( 16, 16 );
   textBitDepth_2.SetEditable( false, false );
   textBitDepth_2.SetJustificationFlags( VoltageLabel.Justification.HorizCentered );
   textBitDepth_2.SetJustificationFlags( VoltageLabel.Justification.VertCentered );
   textBitDepth_2.SetColor( new Color( 255, 255, 255, 255 ) );
   textBitDepth_2.SetBkColor( new Color( 65, 65, 65, 0 ) );
   textBitDepth_2.SetBorderColor( new Color( 0, 0, 0, 0 ) );
   textBitDepth_2.SetBorderSize( 1 );
   textBitDepth_2.SetMultiLineEdit( false );
   textBitDepth_2.SetIsNumberEditor( false );
   textBitDepth_2.SetNumberEditorRange( 0, 100 );
   textBitDepth_2.SetNumberEditorInterval( 1 );
   textBitDepth_2.SetNumberEditorUsesMouseWheel( false );
   textBitDepth_2.SetHasCustomTextHoverColor( false );
   textBitDepth_2.SetTextHoverColor( new Color( 0, 0, 0, 255 ) );
   textBitDepth_2.SetFont( "Verdana", 12, false, false );

   textBitDepth_3 = new VoltageLabel( "Bit Depth Label_3", "Bit Depth Label_3", this, "2" );
   AddComponent( textBitDepth_3 );
   textBitDepth_3.SetWantsMouseNotifications( false );
   textBitDepth_3.SetPosition( 52, 199 );
   textBitDepth_3.SetSize( 16, 16 );
   textBitDepth_3.SetEditable( false, false );
   textBitDepth_3.SetJustificationFlags( VoltageLabel.Justification.HorizCentered );
   textBitDepth_3.SetJustificationFlags( VoltageLabel.Justification.VertCentered );
   textBitDepth_3.SetColor( new Color( 255, 255, 255, 255 ) );
   textBitDepth_3.SetBkColor( new Color( 65, 65, 65, 0 ) );
   textBitDepth_3.SetBorderColor( new Color( 0, 0, 0, 0 ) );
   textBitDepth_3.SetBorderSize( 1 );
   textBitDepth_3.SetMultiLineEdit( false );
   textBitDepth_3.SetIsNumberEditor( false );
   textBitDepth_3.SetNumberEditorRange( 0, 100 );
   textBitDepth_3.SetNumberEditorInterval( 1 );
   textBitDepth_3.SetNumberEditorUsesMouseWheel( false );
   textBitDepth_3.SetHasCustomTextHoverColor( false );
   textBitDepth_3.SetTextHoverColor( new Color( 0, 0, 0, 255 ) );
   textBitDepth_3.SetFont( "Verdana", 12, false, false );

   inputJackNoiseL = new VoltageAudioJack( "Left Noise In", "Left Noise In", this, JackType.JackType_AudioInput );
   AddComponent( inputJackNoiseL );
   inputJackNoiseL.SetWantsMouseNotifications( false );
   inputJackNoiseL.SetPosition( 5, 160 );
   inputJackNoiseL.SetSize( 25, 25 );
   inputJackNoiseL.SetSkin( "Jack Round White Ring" );

   inputJackNoiseR = new VoltageAudioJack( "Right Noise In", "Right Noise In", this, JackType.JackType_AudioInput );
   AddComponent( inputJackNoiseR );
   inputJackNoiseR.SetWantsMouseNotifications( false );
   inputJackNoiseR.SetPosition( 42, 160 );
   inputJackNoiseR.SetSize( 25, 25 );
   inputJackNoiseR.SetSkin( "Jack Round Red Ring" );

   textLabel4 = new VoltageLabel( "textLabel4", "textLabel4", this, "Noise In" );
   AddComponent( textLabel4 );
   textLabel4.SetWantsMouseNotifications( false );
   textLabel4.SetPosition( 11, 139 );
   textLabel4.SetSize( 51, 26 );
   textLabel4.SetEditable( false, false );
   textLabel4.SetJustificationFlags( VoltageLabel.Justification.HorizCentered );
   textLabel4.SetJustificationFlags( VoltageLabel.Justification.VertCentered );
   textLabel4.SetColor( new Color( 255, 255, 255, 255 ) );
   textLabel4.SetBkColor( new Color( 65, 65, 65, 0 ) );
   textLabel4.SetBorderColor( new Color( 0, 0, 0, 0 ) );
   textLabel4.SetBorderSize( 1 );
   textLabel4.SetMultiLineEdit( false );
   textLabel4.SetIsNumberEditor( false );
   textLabel4.SetNumberEditorRange( 0, 100 );
   textLabel4.SetNumberEditorInterval( 1 );
   textLabel4.SetNumberEditorUsesMouseWheel( false );
   textLabel4.SetHasCustomTextHoverColor( false );
   textLabel4.SetTextHoverColor( new Color( 0, 0, 0, 255 ) );
   textLabel4.SetFont( "Verdana", 12, false, false );

   outputJackProcessedL = new VoltageAudioJack( "Processed Left", "Processed Left", this, JackType.JackType_AudioOutput );
   AddComponent( outputJackProcessedL );
   outputJackProcessedL.SetWantsMouseNotifications( false );
   outputJackProcessedL.SetPosition( 5, 232 );
   outputJackProcessedL.SetSize( 25, 25 );
   outputJackProcessedL.SetSkin( "Jack Round White Ring" );

   outputJackUnprocessedL = new VoltageAudioJack( "Unprocessed Left", "Unprocessed Left", this, JackType.JackType_AudioOutput );
   AddComponent( outputJackUnprocessedL );
   outputJackUnprocessedL.SetWantsMouseNotifications( false );
   outputJackUnprocessedL.SetPosition( 5, 272 );
   outputJackUnprocessedL.SetSize( 25, 25 );
   outputJackUnprocessedL.SetSkin( "Jack Round White Ring" );

   outputJackDifferenceL = new VoltageAudioJack( "Difference Left", "Difference Left", this, JackType.JackType_AudioOutput );
   AddComponent( outputJackDifferenceL );
   outputJackDifferenceL.SetWantsMouseNotifications( false );
   outputJackDifferenceL.SetPosition( 5, 312 );
   outputJackDifferenceL.SetSize( 25, 25 );
   outputJackDifferenceL.SetSkin( "Jack Round White Ring" );

   outputJackUnprocessedR = new VoltageAudioJack( "Unprocessed Right", "Unprocessed Right", this, JackType.JackType_AudioOutput );
   AddComponent( outputJackUnprocessedR );
   outputJackUnprocessedR.SetWantsMouseNotifications( false );
   outputJackUnprocessedR.SetPosition( 42, 272 );
   outputJackUnprocessedR.SetSize( 25, 25 );
   outputJackUnprocessedR.SetSkin( "Jack Round Red Ring" );

   outputJackProcessedR = new VoltageAudioJack( "Processed Right", "Processed Right", this, JackType.JackType_AudioOutput );
   AddComponent( outputJackProcessedR );
   outputJackProcessedR.SetWantsMouseNotifications( false );
   outputJackProcessedR.SetPosition( 42, 232 );
   outputJackProcessedR.SetSize( 25, 25 );
   outputJackProcessedR.SetSkin( "Jack Round Red Ring" );

   outputJackDifferenceR = new VoltageAudioJack( "Difference Right", "Difference Right", this, JackType.JackType_AudioOutput );
   AddComponent( outputJackDifferenceR );
   outputJackDifferenceR.SetWantsMouseNotifications( false );
   outputJackDifferenceR.SetPosition( 42, 312 );
   outputJackDifferenceR.SetSize( 25, 25 );
   outputJackDifferenceR.SetSkin( "Jack Round Red Ring" );
}



//-------------------------------------------------------------------------------
//  public void Initialize()

//  Initialize will get called shortly after your module's constructor runs. You can use it to
//  do any initialization that the auto-generated code doesn't handle.
//-------------------------------------------------------------------------------
@Override
public void Initialize()
{
   //[user-Initialize]   Add your own initialization code here

   ReadBitDepthKnob(knobBitDepth.GetValue());
   smoothNoiseLevel.SetValue(sliderDitherBits.GetValue());

   //[/user-Initialize]
}


//-------------------------------------------------------------------------------
//  public void Destroy()

//  Destroy will get called just before your module gets deleted. You can use it to perform any
//  cleanup that's not handled automatically by Java.
//-------------------------------------------------------------------------------
@Override
public void Destroy()
{
   super.Destroy();
   //[user-Destroy]   Add your own module-getting-deleted code here



   //[/user-Destroy]
}


//-------------------------------------------------------------------------------
//  public boolean Notify( VoltageComponent component, ModuleNotifications notification, double doubleValue, long longValue, int x, int y, Object object )

//  Notify will get called when various events occur - control values changing, timers firing, etc.
//-------------------------------------------------------------------------------
@Override
public boolean Notify( VoltageComponent component, ModuleNotifications notification, double doubleValue, long longValue, int x, int y, Object object )
{
   //[user-Notify]   Add your own notification handling code between this line and the notify-close comment
   switch( notification )
   {
      case Knob_Changed:   // doubleValue is the new VoltageKnob value
      {
         if (component == knobBitDepth)
         {
            ReadBitDepthKnob(doubleValue);
         }
      }
      break;
   
      case Slider_Changed:   // doubleValue is the new slider value
      {
         if (component == sliderDitherBits)
         {
            smoothNoiseLevel.SetValue(doubleValue);
         }
      }
      break;
   
      case Button_Changed:   // doubleValue is the new button/toggle button value
      {
      }
      break;
   
      case Switch_Changed:   // doubleValue is the new switch value
      {
      }
      break;
   
      case Jack_Connected:   // longValue is the new cable ID
      {
      }
      break;
   
      case Jack_Disconnected:   // All cables have been disconnected from this jack
      {
      }
      break;
   
      case GUI_Update_Timer:   // Called every 50ms (by default) if turned on
      {
      }
      break;
   
      case Object_MouseMove:   // called when mouse is over an object that receives mouse notifications. 'object' parameter is a VoltageMouseKeyFlags object.
      {
      }
      break;
   
      case Object_MouseLeave:  // called when mouse leaves an object that receives mouse notifications. 'object' parameter is a VoltageMouseKeyFlags object.
      {
      }
      break;
   
      case Object_LeftButtonDown:   // called when user left-clicks on an object that receives mouse notifications. 'object' parameter is a VoltageMouseKeyFlags object.
      {
      }
      break;
   
      case Object_LeftButtonUp:   // called when user releases left mouse button on an object that receives mouse notifications. 'object' parameter is a VoltageMouseKeyFlags object.
      {
      }
      break;
   
      case Object_RightButtonDown:   // called when user releases right mouse button on an object that receives mouse notifications. 'object' parameter is a VoltageMouseKeyFlags object.
      {
      }
      break;
   
      case Object_RightButtonUp:   // called when user right-clicks on an object that receives mouse notifications
      {
      }
      break;
   
      case Object_LeftButtonDoubleClick: // called when user left-button double-clicks on an object that receives mouse notifications
      {
      }
      break;
   
      // Less common notifications:
   
      case Named_Timer:   // object contains a String with the name of the timer that has fired
      {
      }
      break;
   
      case Canvas_Painting:   // About to paint canvas.  object is a java.awt.Rectangle with painting boundaries
      {
      }
      break;
   
      case Canvas_Painted:   // Canvas painting is complete
      {
      }
      break;
   
      case Control_DragStart:    // A user has started dragging on a control that has been marked as draggable
      {
      }
      break;
   
      case Control_DragOn:       // This control has been dragged over during a drag operation. object contains the dragged object
      {
      }
      break;
   
      case Control_DragOff:      // This control has been dragged over during a drag operation. object contains the dragged object
      {
      }
      break;
   
      case Control_DragEnd:      // A user has ended their drag on a control that has been marked as draggable
      {
      }
      break;
   
      case Label_Changed:        // The text of an editable text control has changed
      {
      }
      break;
   
      case SoundPlayback_Start:   // A sound has begun playback
      {
      }
      break;
   
      case SoundPlayback_End:     // A sound has ended playback
      {
      }
      break;
   
      case Scrollbar_Position:    // longValue is the new scrollbar position
      {
      }
      break;
   
      case PolyVoices_Changed:    // longValue is the new number of poly voices
      {
      }
      break;
   
      case File_Dropped:     // 'object' is a String containing the file path
      {
      }
      break;
   
      case Preset_Loading_Start:   // called when preset loading begins
      {
      }
      break;
   
      case Preset_Loading_Finish:  // called when preset loading finishes
      {
      }
      break;
   
      case Variation_Loading_Start:    // sent when a variation is about to load
      {
      }
      break;
   
      case Variation_Loading_Finish:   // sent when a variation has just finished loading
      {
      }
      break;
   
      case Tempo_Changed:     // doubleValue is the new tempo
      {
      }
      break;
   
      case Randomized:     // called when the module's controls get randomized
      {
      }
      break;
   
      case VariationListChanged:   // sent when a variation gets added, deleted, or renamed, or the variations list gets reordered
      {
      }
      break;
   
      case Key_Press:     // sent when module has keyboard focus and a key is pressed; object is a VoltageKeyPressInfo object
      {
      }
      break;
   
      case Reset:    // sent when the module has been reset to default settings
      {
      }
      break;
   
      case Keyboard_NoteOn:   // sent when a note has been pressed on a VoltageKeyboard object. longValue is the note value ( 0-127 )
      {
      }
      break;
   
      case Keyboard_NoteOff:   // sent when a note has been released on a VoltageKeyboard object. longValue is the note value ( 0-127 )
      {
      }
      break;
   
      case Curve_Changed:   // sent when user has edited a curve's value. 'object' will be a VoltageCurve.CurveChangeNotification object.
      {
      }
      break;
   }



   return false;
   //[/user-Notify]
}


//-------------------------------------------------------------------------------
//  public void ProcessSample()

//  ProcessSample is called once per sample. Usually it's where you read
//  from input jacks, process audio, and write it to your output jacks.
//  Since ProcesssSample gets called 48,000 times per second, offload CPU-intensive operations
//  to other threads when possible and avoid calling native functions.
//-------------------------------------------------------------------------------
@Override
public void ProcessSample()
{
   //[user-ProcessSample]   Add your own process-sampling code here

double dLeftInput;
double dRightInput;
double dTempDouble;
double dLeftRounded;
double dRightRounded;
double dMult;
double dDiv;
double dSmoothedNoiseLevel;

   dMult = dBitMultiplier;
   dDiv = dBitDivider;
   dSmoothedNoiseLevel = smoothNoiseLevel.GetSmoothValue() * FIVE_TO_ONE_VOLTS;

   // Read left signal channel and project into multiplier space
   dLeftInput = inputJackLeft.GetValue();
   dTempDouble = dLeftInput * FIVE_TO_ONE_VOLTS * dMult;
   
   // Read left noise channel, attenuate and add to multiplier space
   dTempDouble += inputJackNoiseL.GetValue() * dSmoothedNoiseLevel;
   
   // Perform floor to round to nearest integer;
   dLeftRounded = floor(dTempDouble + 0.5);
   dLeftRounded *= dDiv;
   
   // Read right signal channel and project into multiplier space
   dRightInput = inputJackRight.GetValue();
   dTempDouble = dRightInput * FIVE_TO_ONE_VOLTS * dMult;
   
   // Read right noise channel, attenuate and add to multiplier space
   dTempDouble += inputJackNoiseR.GetValue() * dSmoothedNoiseLevel;
   
   // Perform floor to round to nearest integer;
   dRightRounded = floor(dTempDouble + 0.5);
   dRightRounded *= dDiv;
   
   // Set all left channel outputs
   outputJackProcessedL.SetValue(dLeftRounded);
   outputJackUnprocessedL.SetValue(dLeftInput);
   outputJackDifferenceL.SetValue(dLeftInput - dLeftRounded);
   
   // Set all right channel outputs
   outputJackProcessedR.SetValue(dRightRounded);
   outputJackUnprocessedR.SetValue(dRightInput);
   outputJackDifferenceR.SetValue(dRightInput - dRightRounded);
   
   
   //[/user-ProcessSample]
}


//-------------------------------------------------------------------------------
//  public String GetTooltipText( VoltageComponent component )

//  Gets called when a tooltip is about to display for a control. Override it if
//  you want to change what the tooltip displays - if you want a knob to work in logarithmic fashion,
//  for instance, you can translate the knob's current value to a log-based string and display it here.
//-------------------------------------------------------------------------------
@Override
public String GetTooltipText( VoltageComponent component )
{
   //[user-GetTooltipText]   Add your own code here



   return super.GetTooltipText( component );
   //[/user-GetTooltipText]
}


//-------------------------------------------------------------------------------
//  public void EditComponentValue( VoltageComponent component, double newValue, String newText )

//  Gets called after a user clicks on a tooltip and types in a new value for a control. Override this if
//  you've changed the default tooltip display (translating a linear value to logarithmic, for instance)
//  in GetTooltipText().
//-------------------------------------------------------------------------------
@Override
public void EditComponentValue( VoltageComponent component, double newValue, String newText )
{
   //[user-EditComponentValue]   Add your own code here



   //[/user-EditComponentValue]
   super.EditComponentValue( component, newValue, newText );
}


//-------------------------------------------------------------------------------
//  public void OnUndoRedo( String undoType, double newValue, Object optionalObject )

//  If you've created custom undo events via calls to CreateUndoEvent, you'll need to
//  process them in this function when they get triggered by undo/redo actions.
//-------------------------------------------------------------------------------
@Override
public void OnUndoRedo( String undoType, double newValue, Object optionalObject )
{
   //[user-OnUndoRedo]   Add your own code here



   //[/user-OnUndoRedo]
}


//-------------------------------------------------------------------------------
//  public byte[] GetStateInformation()

//  Gets called when the module's state gets saved, typically when the user saves a preset with
//  this module in it. Voltage Modular will automatically save the states of knobs, sliders, etc.,
//  but if you have any custom state information you need to save, return it from this function.
//-------------------------------------------------------------------------------
@Override
public byte[] GetStateInformation()
{
   //[user-GetStateInformation]   Add your own code here



   return null;
   //[/user-GetStateInformation]
}


//-------------------------------------------------------------------------------
//  public void SetStateInformation(byte[] stateInfo)

//  Gets called when this module's state is getting restored, typically when a user opens a preset with
//  this module in it. The stateInfo parameter will contain whatever custom data you stored in GetStateInformation().
//-------------------------------------------------------------------------------
@Override
public void SetStateInformation(byte[] stateInfo)
{
   //[user-SetStateInformation]   Add your own code here



   //[/user-SetStateInformation]
}


//-------------------------------------------------------------------------------
//  public byte[] GetStateInformationForVariations()

//  Gets called when a user saves a variation with this module in it.
//  Voltage Modular will automatically save the states of knobs, sliders, etc.,
//  but if you have any custom state information you need to save, return it from this function.
//-------------------------------------------------------------------------------
@Override
public byte[] GetStateInformationForVariations()
{
   //[user-GetStateInformationForVariations]   Add your own code here



   return GetStateInformation();
   //[/user-GetStateInformationForVariations]
}


//-------------------------------------------------------------------------------
//  public void SetStateInformationForVariations(byte[] stateInfo)

//  Gets called when a user loads a variation with this module in it.
//  The stateInfo parameter will contain whatever custom data you stored in GetStateInformationForVariations().
//-------------------------------------------------------------------------------
@Override
public void SetStateInformationForVariations(byte[] stateInfo)
{
   //[user-SetStateInformationForVariations]   Add your own code here
   SetStateInformation(stateInfo);



   //[/user-SetStateInformationForVariations]
}


// Auto-generated variables
private VoltageAudioJack outputJackDifferenceR;
private VoltageAudioJack outputJackProcessedR;
private VoltageAudioJack outputJackUnprocessedR;
private VoltageAudioJack outputJackDifferenceL;
private VoltageAudioJack outputJackUnprocessedL;
private VoltageAudioJack outputJackProcessedL;
private VoltageLabel textLabel4;
private VoltageAudioJack inputJackNoiseR;
private VoltageAudioJack inputJackNoiseL;
private VoltageLabel textBitDepth_3;
private VoltageLabel textBitDepth_2;
private VoltageLabel textBitDepth_1;
private VoltageLabel textBitDepth;
private VoltageLabel textLabel7;
private VoltageLabel textLabel2;
private VoltageLabel textLabel5;
private VoltageLabel textLabel3;
private VoltageLabel textLabel6;
private VoltageLabel textLabel1;
private VoltageAudioJack inputJackRight;
private VoltageAudioJack inputJackLeft;
private VoltageKnob knobBitDepth;
private VoltageSlider sliderDitherBits;


//[user-code-and-variables]    Add your own variables and functions here

// Constants

private final double FIVE_TO_ONE_VOLTS = 0.2;
private final double ONE_TO_FIVE_VOLTS = 5.0;

// Variables

private double dBitDepth;
private double dBitMultiplier;
private double dBitDivider;
private String strBitDepth;

private int    iDisplayBitDepth;

// Objects

private SmoothValue smoothNoiseLevel = new SmoothValue();

// Functions

void ReadBitDepthKnob(double bits)
{
   dBitDepth = bits;
   dBitMultiplier = pow (2.0, (dBitDepth - 1.0));
   dBitDivider = ONE_TO_FIVE_VOLTS / dBitMultiplier;
   iDisplayBitDepth = (int)bits;
   strBitDepth = String.format("%d Bits", iDisplayBitDepth);
   textBitDepth.SetText (strBitDepth);
}


//[/user-code-and-variables]
}

 