package com.domemusictechnologies.solaris;


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;

//[/user-imports]


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

public Solaris( long moduleID, VoltageObjects voltageObjects )
{
   super( moduleID, voltageObjects, "Solaris Ensemble", ModuleType.ModuleType_Effect, 2.0 );

   InitializeControls();


   canBeBypassed = true;
   SetSkin( "ef4b7d2cc91e44e49ccb5d59f787832f" );
}

void InitializeControls()
{

   inputSync = new VoltageAudioJack( "LFO Sync Input", "LFO Sync Input", this, JackType.JackType_AudioInput );
   AddComponent( inputSync );
   inputSync.SetWantsMouseNotifications( false );
   inputSync.SetPosition( 67, 310 );
   inputSync.SetSize( 25, 25 );
   inputSync.SetSkin( "Jack Round Marine Blue Ring" );

   textLabel1 = new VoltageLabel( "textLabel1", "textLabel1", this, "Reset" );
   AddComponent( textLabel1 );
   textLabel1.SetWantsMouseNotifications( false );
   textLabel1.SetPosition( 62, 288 );
   textLabel1.SetSize( 35, 21 );
   textLabel1.SetEditable( false, false );
   textLabel1.SetJustificationFlags( VoltageLabel.Justification.HorizCentered );
   textLabel1.SetJustificationFlags( VoltageLabel.Justification.VertCentered );
   textLabel1.SetColor( new Color( 255, 215, 0, 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", 12, false, false );

   switchPhaseOffset = new VoltageSwitch( "LFO Phase Offset", "LFO Phase Offset", this, 0 );
   AddComponent( switchPhaseOffset );
   switchPhaseOffset.SetWantsMouseNotifications( false );
   switchPhaseOffset.SetPosition( 105, 289 );
   switchPhaseOffset.SetSize( 15, 51 );
   switchPhaseOffset.SetSkin( "4-State Slide Vertical" );

   textLabel2 = new VoltageLabel( "textLabel2", "textLabel2", this, "0" );
   AddComponent( textLabel2 );
   textLabel2.SetWantsMouseNotifications( false );
   textLabel2.SetPosition( 120, 324 );
   textLabel2.SetSize( 16, 17 );
   textLabel2.SetEditable( false, false );
   textLabel2.SetJustificationFlags( VoltageLabel.Justification.HorizCentered );
   textLabel2.SetJustificationFlags( VoltageLabel.Justification.VertCentered );
   textLabel2.SetColor( new Color( 255, 215, 0, 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 );

   textLabel3 = new VoltageLabel( "textLabel3", "textLabel3", this, "30" );
   AddComponent( textLabel3 );
   textLabel3.SetWantsMouseNotifications( false );
   textLabel3.SetPosition( 118, 311 );
   textLabel3.SetSize( 20, 18 );
   textLabel3.SetEditable( false, false );
   textLabel3.SetJustificationFlags( VoltageLabel.Justification.HorizCentered );
   textLabel3.SetJustificationFlags( VoltageLabel.Justification.VertCentered );
   textLabel3.SetColor( new Color( 255, 215, 0, 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 );

   textLabel4 = new VoltageLabel( "textLabel4", "textLabel4", this, "60" );
   AddComponent( textLabel4 );
   textLabel4.SetWantsMouseNotifications( false );
   textLabel4.SetPosition( 117, 301 );
   textLabel4.SetSize( 22, 15 );
   textLabel4.SetEditable( false, false );
   textLabel4.SetJustificationFlags( VoltageLabel.Justification.HorizCentered );
   textLabel4.SetJustificationFlags( VoltageLabel.Justification.VertCentered );
   textLabel4.SetColor( new Color( 255, 215, 0, 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 );

   textLabel5 = new VoltageLabel( "textLabel5", "textLabel5", this, "90" );
   AddComponent( textLabel5 );
   textLabel5.SetWantsMouseNotifications( false );
   textLabel5.SetPosition( 116, 286 );
   textLabel5.SetSize( 24, 20 );
   textLabel5.SetEditable( false, false );
   textLabel5.SetJustificationFlags( VoltageLabel.Justification.HorizCentered );
   textLabel5.SetJustificationFlags( VoltageLabel.Justification.VertCentered );
   textLabel5.SetColor( new Color( 255, 215, 0, 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 );

   textLabel6 = new VoltageLabel( "textLabel6", "textLabel6", this, "Dome Music Technologies" );
   AddComponent( textLabel6 );
   textLabel6.SetWantsMouseNotifications( false );
   textLabel6.SetPosition( 14, 342 );
   textLabel6.SetSize( 117, 18 );
   textLabel6.SetEditable( false, false );
   textLabel6.SetJustificationFlags( VoltageLabel.Justification.HorizCentered );
   textLabel6.SetJustificationFlags( VoltageLabel.Justification.VertCentered );
   textLabel6.SetColor( new Color( 255, 215, 0, 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", 10, false, false );

   inputAudio = new VoltageAudioJack( "Audio Input", "Audio Input", this, JackType.JackType_AudioInput );
   AddComponent( inputAudio );
   inputAudio.SetWantsMouseNotifications( false );
   inputAudio.SetPosition( 19, 48 );
   inputAudio.SetSize( 25, 25 );
   inputAudio.SetSkin( "Jack Round Yellow Ring" );

   outputEnsemble = new VoltageAudioJack( "Left / Mono Output", "Left / Mono Output", this, JackType.JackType_AudioOutput );
   AddComponent( outputEnsemble );
   outputEnsemble.SetWantsMouseNotifications( false );
   outputEnsemble.SetPosition( 19, 118 );
   outputEnsemble.SetSize( 25, 25 );
   outputEnsemble.SetSkin( "Jack Round Mint Ring" );

   outputChannel3 = new VoltageAudioJack( "Channel 3 Output", "Channel 3 Output", this, JackType.JackType_AudioOutput );
   AddComponent( outputChannel3 );
   outputChannel3.SetWantsMouseNotifications( false );
   outputChannel3.SetPosition( 109, 244 );
   outputChannel3.SetSize( 25, 25 );
   outputChannel3.SetSkin( "Jack Round Teal Ring" );

   outputChannel2 = new VoltageAudioJack( "Channel 2 Output", "Channel 2 Output", this, JackType.JackType_AudioOutput );
   AddComponent( outputChannel2 );
   outputChannel2.SetWantsMouseNotifications( false );
   outputChannel2.SetPosition( 59, 244 );
   outputChannel2.SetSize( 25, 25 );
   outputChannel2.SetSkin( "Jack Round Teal Ring" );

   outputChannel1 = new VoltageAudioJack( "Channel 1 Output", "Channel 1 Output", this, JackType.JackType_AudioOutput );
   AddComponent( outputChannel1 );
   outputChannel1.SetWantsMouseNotifications( false );
   outputChannel1.SetPosition( 9, 244 );
   outputChannel1.SetSize( 25, 25 );
   outputChannel1.SetSkin( "Jack Round Teal Ring" );

   textLabel7 = new VoltageLabel( "textLabel7", "textLabel7", this, "Solaris Ensemble" );
   AddComponent( textLabel7 );
   textLabel7.SetWantsMouseNotifications( false );
   textLabel7.SetPosition( 14, 0 );
   textLabel7.SetSize( 115, 16 );
   textLabel7.SetEditable( false, false );
   textLabel7.SetJustificationFlags( VoltageLabel.Justification.HorizCentered );
   textLabel7.SetJustificationFlags( VoltageLabel.Justification.VertCentered );
   textLabel7.SetColor( new Color( 255, 215, 0, 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", 14, false, false );

   textLabel9 = new VoltageLabel( "textLabel9", "textLabel9", this, "Input" );
   AddComponent( textLabel9 );
   textLabel9.SetWantsMouseNotifications( false );
   textLabel9.SetPosition( 49, 52 );
   textLabel9.SetSize( 36, 16 );
   textLabel9.SetEditable( false, false );
   textLabel9.SetJustificationFlags( VoltageLabel.Justification.HorizCentered );
   textLabel9.SetJustificationFlags( VoltageLabel.Justification.VertCentered );
   textLabel9.SetColor( new Color( 255, 215, 0, 255 ) );
   textLabel9.SetBkColor( new Color( 65, 65, 65, 0 ) );
   textLabel9.SetBorderColor( new Color( 0, 0, 0, 0 ) );
   textLabel9.SetBorderSize( 1 );
   textLabel9.SetMultiLineEdit( false );
   textLabel9.SetIsNumberEditor( false );
   textLabel9.SetNumberEditorRange( 0, 100 );
   textLabel9.SetNumberEditorInterval( 1 );
   textLabel9.SetNumberEditorUsesMouseWheel( false );
   textLabel9.SetHasCustomTextHoverColor( false );
   textLabel9.SetTextHoverColor( new Color( 0, 0, 0, 255 ) );
   textLabel9.SetFont( "Verdana", 12, false, false );

   textLabel12 = new VoltageLabel( "textLabel12", "textLabel12", this, "Mono (L)" );
   AddComponent( textLabel12 );
   textLabel12.SetWantsMouseNotifications( false );
   textLabel12.SetPosition( 10, 142 );
   textLabel12.SetSize( 51, 16 );
   textLabel12.SetEditable( false, false );
   textLabel12.SetJustificationFlags( VoltageLabel.Justification.Left );
   textLabel12.SetJustificationFlags( VoltageLabel.Justification.VertCentered );
   textLabel12.SetColor( new Color( 255, 215, 0, 255 ) );
   textLabel12.SetBkColor( new Color( 65, 65, 65, 0 ) );
   textLabel12.SetBorderColor( new Color( 0, 0, 0, 0 ) );
   textLabel12.SetBorderSize( 1 );
   textLabel12.SetMultiLineEdit( false );
   textLabel12.SetIsNumberEditor( false );
   textLabel12.SetNumberEditorRange( 0, 100 );
   textLabel12.SetNumberEditorInterval( 1 );
   textLabel12.SetNumberEditorUsesMouseWheel( false );
   textLabel12.SetHasCustomTextHoverColor( false );
   textLabel12.SetTextHoverColor( new Color( 0, 0, 0, 255 ) );
   textLabel12.SetFont( "Verdana", 12, false, false );

   textLabel13 = new VoltageLabel( "textLabel13", "textLabel13", this, "Right" );
   AddComponent( textLabel13 );
   textLabel13.SetWantsMouseNotifications( false );
   textLabel13.SetPosition( 92, 142 );
   textLabel13.SetSize( 37, 16 );
   textLabel13.SetEditable( false, false );
   textLabel13.SetJustificationFlags( VoltageLabel.Justification.HorizCentered );
   textLabel13.SetJustificationFlags( VoltageLabel.Justification.VertCentered );
   textLabel13.SetColor( new Color( 255, 215, 0, 255 ) );
   textLabel13.SetBkColor( new Color( 65, 65, 65, 0 ) );
   textLabel13.SetBorderColor( new Color( 0, 0, 0, 0 ) );
   textLabel13.SetBorderSize( 1 );
   textLabel13.SetMultiLineEdit( false );
   textLabel13.SetIsNumberEditor( false );
   textLabel13.SetNumberEditorRange( 0, 100 );
   textLabel13.SetNumberEditorInterval( 1 );
   textLabel13.SetNumberEditorUsesMouseWheel( false );
   textLabel13.SetHasCustomTextHoverColor( false );
   textLabel13.SetTextHoverColor( new Color( 0, 0, 0, 255 ) );
   textLabel13.SetFont( "Verdana", 12, false, false );

   textLabel24 = new VoltageLabel( "textLabel24", "textLabel24", this, "Ensemble" );
   AddComponent( textLabel24 );
   textLabel24.SetWantsMouseNotifications( false );
   textLabel24.SetPosition( 3, 91 );
   textLabel24.SetSize( 54, 19 );
   textLabel24.SetEditable( false, false );
   textLabel24.SetJustificationFlags( VoltageLabel.Justification.Left );
   textLabel24.SetJustificationFlags( VoltageLabel.Justification.VertCentered );
   textLabel24.SetColor( new Color( 255, 215, 0, 255 ) );
   textLabel24.SetBkColor( new Color( 65, 65, 65, 0 ) );
   textLabel24.SetBorderColor( new Color( 0, 0, 0, 0 ) );
   textLabel24.SetBorderSize( 1 );
   textLabel24.SetMultiLineEdit( false );
   textLabel24.SetIsNumberEditor( false );
   textLabel24.SetNumberEditorRange( 0, 100 );
   textLabel24.SetNumberEditorInterval( 1 );
   textLabel24.SetNumberEditorUsesMouseWheel( false );
   textLabel24.SetHasCustomTextHoverColor( false );
   textLabel24.SetTextHoverColor( new Color( 0, 0, 0, 255 ) );
   textLabel24.SetFont( "Verdana", 12, false, false );

   textLabel25 = new VoltageLabel( "textLabel25", "textLabel25", this, "Chorus" );
   AddComponent( textLabel25 );
   textLabel25.SetWantsMouseNotifications( false );
   textLabel25.SetPosition( 90, 91 );
   textLabel25.SetSize( 47, 19 );
   textLabel25.SetEditable( false, false );
   textLabel25.SetJustificationFlags( VoltageLabel.Justification.Left );
   textLabel25.SetJustificationFlags( VoltageLabel.Justification.VertCentered );
   textLabel25.SetColor( new Color( 255, 215, 0, 255 ) );
   textLabel25.SetBkColor( new Color( 65, 65, 65, 0 ) );
   textLabel25.SetBorderColor( new Color( 0, 0, 0, 0 ) );
   textLabel25.SetBorderSize( 1 );
   textLabel25.SetMultiLineEdit( false );
   textLabel25.SetIsNumberEditor( false );
   textLabel25.SetNumberEditorRange( 0, 100 );
   textLabel25.SetNumberEditorInterval( 1 );
   textLabel25.SetNumberEditorUsesMouseWheel( false );
   textLabel25.SetHasCustomTextHoverColor( false );
   textLabel25.SetTextHoverColor( new Color( 0, 0, 0, 255 ) );
   textLabel25.SetFont( "Verdana", 12, false, false );

   textLabel10 = new VoltageLabel( "textLabel10", "textLabel10", this, "Output" );
   AddComponent( textLabel10 );
   textLabel10.SetWantsMouseNotifications( false );
   textLabel10.SetPosition( 52, 121 );
   textLabel10.SetSize( 44, 18 );
   textLabel10.SetEditable( false, false );
   textLabel10.SetJustificationFlags( VoltageLabel.Justification.Left );
   textLabel10.SetJustificationFlags( VoltageLabel.Justification.VertCentered );
   textLabel10.SetColor( new Color( 255, 215, 0, 255 ) );
   textLabel10.SetBkColor( new Color( 65, 65, 65, 0 ) );
   textLabel10.SetBorderColor( new Color( 0, 0, 0, 0 ) );
   textLabel10.SetBorderSize( 1 );
   textLabel10.SetMultiLineEdit( false );
   textLabel10.SetIsNumberEditor( false );
   textLabel10.SetNumberEditorRange( 0, 100 );
   textLabel10.SetNumberEditorInterval( 1 );
   textLabel10.SetNumberEditorUsesMouseWheel( false );
   textLabel10.SetHasCustomTextHoverColor( false );
   textLabel10.SetTextHoverColor( new Color( 0, 0, 0, 255 ) );
   textLabel10.SetFont( "Verdana", 12, false, false );

   textLabel11 = new VoltageLabel( "textLabel11", "textLabel11", this, "Solo Channel Outputs" );
   AddComponent( textLabel11 );
   textLabel11.SetWantsMouseNotifications( false );
   textLabel11.SetPosition( 16, 225 );
   textLabel11.SetSize( 113, 20 );
   textLabel11.SetEditable( false, false );
   textLabel11.SetJustificationFlags( VoltageLabel.Justification.Left );
   textLabel11.SetJustificationFlags( VoltageLabel.Justification.VertCentered );
   textLabel11.SetColor( new Color( 255, 215, 0, 255 ) );
   textLabel11.SetBkColor( new Color( 65, 65, 65, 0 ) );
   textLabel11.SetBorderColor( new Color( 0, 0, 0, 0 ) );
   textLabel11.SetBorderSize( 1 );
   textLabel11.SetMultiLineEdit( false );
   textLabel11.SetIsNumberEditor( false );
   textLabel11.SetNumberEditorRange( 0, 100 );
   textLabel11.SetNumberEditorInterval( 1 );
   textLabel11.SetNumberEditorUsesMouseWheel( false );
   textLabel11.SetHasCustomTextHoverColor( false );
   textLabel11.SetTextHoverColor( new Color( 0, 0, 0, 255 ) );
   textLabel11.SetFont( "Verdana", 12, false, false );

   image1 = new VoltageImage( "image1", "image1", this, false );
   AddComponent( image1 );
   image1.SetWantsMouseNotifications( false );
   image1.SetPosition( 14, 18 );
   image1.SetSize( 112, 29 );
   image1.SetCurrentImage( "image image.png" );

   rateLFO1 = new VoltageKnob( "LFO 1 Rate", "LFO 1 Rate", this, 0.25, 5.0, 1.21 );
   AddComponent( rateLFO1 );
   rateLFO1.SetWantsMouseNotifications( false );
   rateLFO1.SetPosition( 7, 179 );
   rateLFO1.SetSize( 27, 27 );
   rateLFO1.SetSkin( "Plastic Blue" );
   rateLFO1.SetRange( 0.25, 5.0, 1.21, false, 0 );
   rateLFO1.SetKnobParams( 215, 145 );
   rateLFO1.DisplayValueInPercent( false );
   rateLFO1.SetKnobAdjustsRing( true );
   rateLFO1.SetMidpointValue( 1.21 );

   depthLFO1 = new VoltageKnob( "LFO 1 Depth", "LFO 1 Depth", this, 0.0, 1.0, 0.68 );
   AddComponent( depthLFO1 );
   depthLFO1.SetWantsMouseNotifications( false );
   depthLFO1.SetPosition( 41, 179 );
   depthLFO1.SetSize( 27, 27 );
   depthLFO1.SetSkin( "Plastic Mint" );
   depthLFO1.SetRange( 0.0, 1.0, 0.68, false, 0 );
   depthLFO1.SetKnobParams( 215, 145 );
   depthLFO1.DisplayValueInPercent( true );
   depthLFO1.SetKnobAdjustsRing( true );
   depthLFO1.SetMidpointValue( 0.68 );

   rateLFO2 = new VoltageKnob( "LFO 2 Rate", "LFO 2 Rate", this, 1.0, 10.0, 5.82 );
   AddComponent( rateLFO2 );
   rateLFO2.SetWantsMouseNotifications( false );
   rateLFO2.SetPosition( 75, 179 );
   rateLFO2.SetSize( 27, 27 );
   rateLFO2.SetSkin( "Plastic Blue" );
   rateLFO2.SetRange( 1.0, 10.0, 5.82, false, 0 );
   rateLFO2.SetKnobParams( 215, 145 );
   rateLFO2.DisplayValueInPercent( false );
   rateLFO2.SetKnobAdjustsRing( true );
   rateLFO2.SetMidpointValue( 5.82 );

   depthLFO2 = new VoltageKnob( "LFO 2 Depth", "LFO 2 Depth", this, 0.0, 1.0, 0.69 );
   AddComponent( depthLFO2 );
   depthLFO2.SetWantsMouseNotifications( false );
   depthLFO2.SetPosition( 109, 179 );
   depthLFO2.SetSize( 27, 27 );
   depthLFO2.SetSkin( "Plastic Mint" );
   depthLFO2.SetRange( 0.0, 1.0, 0.69, false, 0 );
   depthLFO2.SetKnobParams( 215, 145 );
   depthLFO2.DisplayValueInPercent( true );
   depthLFO2.SetKnobAdjustsRing( true );
   depthLFO2.SetMidpointValue( 0.69 );

   inputModCV = new VoltageAudioJack( "Mod Depth CV In", "Mod Depth CV In", this, JackType.JackType_AudioInput );
   AddComponent( inputModCV );
   inputModCV.SetWantsMouseNotifications( false );
   inputModCV.SetPosition( 17, 310 );
   inputModCV.SetSize( 25, 25 );
   inputModCV.SetSkin( "Jack Round Sky Ring" );

   textLabel14 = new VoltageLabel( "textLabel14", "textLabel14", this, "Mod CV" );
   AddComponent( textLabel14 );
   textLabel14.SetWantsMouseNotifications( false );
   textLabel14.SetPosition( 5, 288 );
   textLabel14.SetSize( 48, 22 );
   textLabel14.SetEditable( false, false );
   textLabel14.SetJustificationFlags( VoltageLabel.Justification.HorizCentered );
   textLabel14.SetJustificationFlags( VoltageLabel.Justification.VertCentered );
   textLabel14.SetColor( new Color( 255, 215, 0, 255 ) );
   textLabel14.SetBkColor( new Color( 65, 65, 65, 0 ) );
   textLabel14.SetBorderColor( new Color( 0, 0, 0, 0 ) );
   textLabel14.SetBorderSize( 1 );
   textLabel14.SetMultiLineEdit( false );
   textLabel14.SetIsNumberEditor( false );
   textLabel14.SetNumberEditorRange( 0, 100 );
   textLabel14.SetNumberEditorInterval( 1 );
   textLabel14.SetNumberEditorUsesMouseWheel( false );
   textLabel14.SetHasCustomTextHoverColor( false );
   textLabel14.SetTextHoverColor( new Color( 0, 0, 0, 255 ) );
   textLabel14.SetFont( "Verdana", 12, false, false );

   textLabel15 = new VoltageLabel( "textLabel15", "textLabel15", this, "LFO 1" );
   AddComponent( textLabel15 );
   textLabel15.SetWantsMouseNotifications( false );
   textLabel15.SetPosition( 15, 160 );
   textLabel15.SetSize( 47, 24 );
   textLabel15.SetEditable( false, false );
   textLabel15.SetJustificationFlags( VoltageLabel.Justification.HorizCentered );
   textLabel15.SetJustificationFlags( VoltageLabel.Justification.VertCentered );
   textLabel15.SetColor( new Color( 255, 215, 0, 255 ) );
   textLabel15.SetBkColor( new Color( 65, 65, 65, 0 ) );
   textLabel15.SetBorderColor( new Color( 0, 0, 0, 0 ) );
   textLabel15.SetBorderSize( 1 );
   textLabel15.SetMultiLineEdit( false );
   textLabel15.SetIsNumberEditor( false );
   textLabel15.SetNumberEditorRange( 0, 100 );
   textLabel15.SetNumberEditorInterval( 1 );
   textLabel15.SetNumberEditorUsesMouseWheel( false );
   textLabel15.SetHasCustomTextHoverColor( false );
   textLabel15.SetTextHoverColor( new Color( 0, 0, 0, 255 ) );
   textLabel15.SetFont( "Verdana", 12, false, false );

   textLabel16 = new VoltageLabel( "textLabel16", "textLabel16", this, "LFO 2" );
   AddComponent( textLabel16 );
   textLabel16.SetWantsMouseNotifications( false );
   textLabel16.SetPosition( 83, 162 );
   textLabel16.SetSize( 44, 20 );
   textLabel16.SetEditable( false, false );
   textLabel16.SetJustificationFlags( VoltageLabel.Justification.HorizCentered );
   textLabel16.SetJustificationFlags( VoltageLabel.Justification.VertCentered );
   textLabel16.SetColor( new Color( 255, 215, 0, 255 ) );
   textLabel16.SetBkColor( new Color( 65, 65, 65, 0 ) );
   textLabel16.SetBorderColor( new Color( 0, 0, 0, 0 ) );
   textLabel16.SetBorderSize( 1 );
   textLabel16.SetMultiLineEdit( false );
   textLabel16.SetIsNumberEditor( false );
   textLabel16.SetNumberEditorRange( 0, 100 );
   textLabel16.SetNumberEditorInterval( 1 );
   textLabel16.SetNumberEditorUsesMouseWheel( false );
   textLabel16.SetHasCustomTextHoverColor( false );
   textLabel16.SetTextHoverColor( new Color( 0, 0, 0, 255 ) );
   textLabel16.SetFont( "Verdana", 12, false, false );

   textLabel17 = new VoltageLabel( "textLabel17", "textLabel17", this, "Rate" );
   AddComponent( textLabel17 );
   textLabel17.SetWantsMouseNotifications( false );
   textLabel17.SetPosition( 7, 203 );
   textLabel17.SetSize( 27, 18 );
   textLabel17.SetEditable( false, false );
   textLabel17.SetJustificationFlags( VoltageLabel.Justification.Left );
   textLabel17.SetJustificationFlags( VoltageLabel.Justification.VertCentered );
   textLabel17.SetColor( new Color( 255, 215, 0, 255 ) );
   textLabel17.SetBkColor( new Color( 65, 65, 65, 0 ) );
   textLabel17.SetBorderColor( new Color( 0, 0, 0, 0 ) );
   textLabel17.SetBorderSize( 1 );
   textLabel17.SetMultiLineEdit( false );
   textLabel17.SetIsNumberEditor( false );
   textLabel17.SetNumberEditorRange( 0, 100 );
   textLabel17.SetNumberEditorInterval( 1 );
   textLabel17.SetNumberEditorUsesMouseWheel( false );
   textLabel17.SetHasCustomTextHoverColor( false );
   textLabel17.SetTextHoverColor( new Color( 0, 0, 0, 255 ) );
   textLabel17.SetFont( "Verdana", 12, false, false );

   textLabel18 = new VoltageLabel( "textLabel18", "textLabel18", this, "Rate" );
   AddComponent( textLabel18 );
   textLabel18.SetWantsMouseNotifications( false );
   textLabel18.SetPosition( 77, 203 );
   textLabel18.SetSize( 27, 18 );
   textLabel18.SetEditable( false, false );
   textLabel18.SetJustificationFlags( VoltageLabel.Justification.Left );
   textLabel18.SetJustificationFlags( VoltageLabel.Justification.VertCentered );
   textLabel18.SetColor( new Color( 255, 215, 0, 255 ) );
   textLabel18.SetBkColor( new Color( 65, 65, 65, 0 ) );
   textLabel18.SetBorderColor( new Color( 0, 0, 0, 0 ) );
   textLabel18.SetBorderSize( 1 );
   textLabel18.SetMultiLineEdit( false );
   textLabel18.SetIsNumberEditor( false );
   textLabel18.SetNumberEditorRange( 0, 100 );
   textLabel18.SetNumberEditorInterval( 1 );
   textLabel18.SetNumberEditorUsesMouseWheel( false );
   textLabel18.SetHasCustomTextHoverColor( false );
   textLabel18.SetTextHoverColor( new Color( 0, 0, 0, 255 ) );
   textLabel18.SetFont( "Verdana", 12, false, false );

   textLabel19 = new VoltageLabel( "textLabel19", "textLabel19", this, "Depth" );
   AddComponent( textLabel19 );
   textLabel19.SetWantsMouseNotifications( false );
   textLabel19.SetPosition( 39, 203 );
   textLabel19.SetSize( 35, 18 );
   textLabel19.SetEditable( false, false );
   textLabel19.SetJustificationFlags( VoltageLabel.Justification.Left );
   textLabel19.SetJustificationFlags( VoltageLabel.Justification.VertCentered );
   textLabel19.SetColor( new Color( 255, 215, 0, 255 ) );
   textLabel19.SetBkColor( new Color( 65, 65, 65, 0 ) );
   textLabel19.SetBorderColor( new Color( 0, 0, 0, 0 ) );
   textLabel19.SetBorderSize( 1 );
   textLabel19.SetMultiLineEdit( false );
   textLabel19.SetIsNumberEditor( false );
   textLabel19.SetNumberEditorRange( 0, 100 );
   textLabel19.SetNumberEditorInterval( 1 );
   textLabel19.SetNumberEditorUsesMouseWheel( false );
   textLabel19.SetHasCustomTextHoverColor( false );
   textLabel19.SetTextHoverColor( new Color( 0, 0, 0, 255 ) );
   textLabel19.SetFont( "Verdana", 12, false, false );

   textLabel20 = new VoltageLabel( "textLabel20", "textLabel20", this, "Depth" );
   AddComponent( textLabel20 );
   textLabel20.SetWantsMouseNotifications( false );
   textLabel20.SetPosition( 107, 203 );
   textLabel20.SetSize( 35, 18 );
   textLabel20.SetEditable( false, false );
   textLabel20.SetJustificationFlags( VoltageLabel.Justification.Left );
   textLabel20.SetJustificationFlags( VoltageLabel.Justification.VertCentered );
   textLabel20.SetColor( new Color( 255, 215, 0, 255 ) );
   textLabel20.SetBkColor( new Color( 65, 65, 65, 0 ) );
   textLabel20.SetBorderColor( new Color( 0, 0, 0, 0 ) );
   textLabel20.SetBorderSize( 1 );
   textLabel20.SetMultiLineEdit( false );
   textLabel20.SetIsNumberEditor( false );
   textLabel20.SetNumberEditorRange( 0, 100 );
   textLabel20.SetNumberEditorInterval( 1 );
   textLabel20.SetNumberEditorUsesMouseWheel( false );
   textLabel20.SetHasCustomTextHoverColor( false );
   textLabel20.SetTextHoverColor( new Color( 0, 0, 0, 255 ) );
   textLabel20.SetFont( "Verdana", 12, false, false );

   textLabel21 = new VoltageLabel( "textLabel21", "textLabel21", this, "Ch 1" );
   AddComponent( textLabel21 );
   textLabel21.SetWantsMouseNotifications( false );
   textLabel21.SetPosition( 7, 265 );
   textLabel21.SetSize( 30, 23 );
   textLabel21.SetEditable( false, false );
   textLabel21.SetJustificationFlags( VoltageLabel.Justification.HorizCentered );
   textLabel21.SetJustificationFlags( VoltageLabel.Justification.VertCentered );
   textLabel21.SetColor( new Color( 255, 215, 0, 255 ) );
   textLabel21.SetBkColor( new Color( 65, 65, 65, 0 ) );
   textLabel21.SetBorderColor( new Color( 0, 0, 0, 0 ) );
   textLabel21.SetBorderSize( 1 );
   textLabel21.SetMultiLineEdit( false );
   textLabel21.SetIsNumberEditor( false );
   textLabel21.SetNumberEditorRange( 0, 100 );
   textLabel21.SetNumberEditorInterval( 1 );
   textLabel21.SetNumberEditorUsesMouseWheel( false );
   textLabel21.SetHasCustomTextHoverColor( false );
   textLabel21.SetTextHoverColor( new Color( 0, 0, 0, 255 ) );
   textLabel21.SetFont( "Verdana", 12, false, false );

   textLabel22 = new VoltageLabel( "textLabel22", "textLabel22", this, "Ch 2" );
   AddComponent( textLabel22 );
   textLabel22.SetWantsMouseNotifications( false );
   textLabel22.SetPosition( 56, 265 );
   textLabel22.SetSize( 31, 23 );
   textLabel22.SetEditable( false, false );
   textLabel22.SetJustificationFlags( VoltageLabel.Justification.HorizCentered );
   textLabel22.SetJustificationFlags( VoltageLabel.Justification.VertCentered );
   textLabel22.SetColor( new Color( 255, 215, 0, 255 ) );
   textLabel22.SetBkColor( new Color( 65, 65, 65, 0 ) );
   textLabel22.SetBorderColor( new Color( 0, 0, 0, 0 ) );
   textLabel22.SetBorderSize( 1 );
   textLabel22.SetMultiLineEdit( false );
   textLabel22.SetIsNumberEditor( false );
   textLabel22.SetNumberEditorRange( 0, 100 );
   textLabel22.SetNumberEditorInterval( 1 );
   textLabel22.SetNumberEditorUsesMouseWheel( false );
   textLabel22.SetHasCustomTextHoverColor( false );
   textLabel22.SetTextHoverColor( new Color( 0, 0, 0, 255 ) );
   textLabel22.SetFont( "Verdana", 12, false, false );

   textLabel23 = new VoltageLabel( "textLabel23", "textLabel23", this, "Ch 3" );
   AddComponent( textLabel23 );
   textLabel23.SetWantsMouseNotifications( false );
   textLabel23.SetPosition( 105, 265 );
   textLabel23.SetSize( 34, 22 );
   textLabel23.SetEditable( false, false );
   textLabel23.SetJustificationFlags( VoltageLabel.Justification.HorizCentered );
   textLabel23.SetJustificationFlags( VoltageLabel.Justification.VertCentered );
   textLabel23.SetColor( new Color( 255, 215, 0, 255 ) );
   textLabel23.SetBkColor( new Color( 65, 65, 65, 0 ) );
   textLabel23.SetBorderColor( new Color( 0, 0, 0, 0 ) );
   textLabel23.SetBorderSize( 1 );
   textLabel23.SetMultiLineEdit( false );
   textLabel23.SetIsNumberEditor( false );
   textLabel23.SetNumberEditorRange( 0, 100 );
   textLabel23.SetNumberEditorInterval( 1 );
   textLabel23.SetNumberEditorUsesMouseWheel( false );
   textLabel23.SetHasCustomTextHoverColor( false );
   textLabel23.SetTextHoverColor( new Color( 0, 0, 0, 255 ) );
   textLabel23.SetFont( "Verdana", 12, false, false );

   outputEnsembleRight = new VoltageAudioJack( "Right Stereo Output", "Right Stereo Output", this, JackType.JackType_AudioOutput );
   AddComponent( outputEnsembleRight );
   outputEnsembleRight.SetWantsMouseNotifications( false );
   outputEnsembleRight.SetPosition( 98, 118 );
   outputEnsembleRight.SetSize( 25, 25 );
   outputEnsembleRight.SetSkin( "Jack Round Mint Ring" );

   switchEnsemble = new VoltageSwitch( "Mode Switch", "Mode Switch", this, 0 );
   AddComponent( switchEnsemble );
   switchEnsemble.SetWantsMouseNotifications( false );
   switchEnsemble.SetPosition( 54, 84 );
   switchEnsemble.SetSize( 35, 35 );
   switchEnsemble.SetSkin( "3-State Bar Horizontal" );

   textLabel26 = new VoltageLabel( "textLabel26", "textLabel26", this, "Off" );
   AddComponent( textLabel26 );
   textLabel26.SetWantsMouseNotifications( false );
   textLabel26.SetPosition( 62, 76 );
   textLabel26.SetSize( 21, 19 );
   textLabel26.SetEditable( false, false );
   textLabel26.SetJustificationFlags( VoltageLabel.Justification.Left );
   textLabel26.SetJustificationFlags( VoltageLabel.Justification.VertCentered );
   textLabel26.SetColor( new Color( 255, 215, 0, 255 ) );
   textLabel26.SetBkColor( new Color( 65, 65, 65, 0 ) );
   textLabel26.SetBorderColor( new Color( 0, 0, 0, 0 ) );
   textLabel26.SetBorderSize( 1 );
   textLabel26.SetMultiLineEdit( false );
   textLabel26.SetIsNumberEditor( false );
   textLabel26.SetNumberEditorRange( 0, 100 );
   textLabel26.SetNumberEditorInterval( 1 );
   textLabel26.SetNumberEditorUsesMouseWheel( false );
   textLabel26.SetHasCustomTextHoverColor( false );
   textLabel26.SetTextHoverColor( new Color( 0, 0, 0, 255 ) );
   textLabel26.SetFont( "Verdana", 12, false, false );
}



//-------------------------------------------------------------------------------
//  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

   CheckConnections();

   currentLFO1Rate = rateLFO1.GetValue();
   currentLFO1Depth = depthLFO1.GetValue();
   currentLFO2Rate = rateLFO2.GetValue();
   currentLFO2Depth = depthLFO2.GetValue();
   
   smoothLFO1Rate.SetValue(currentLFO1Rate);
   smoothLFO1Depth.SetValue(currentLFO1Depth);
   smoothLFO2Rate.SetValue(currentLFO2Rate);
   smoothLFO2Depth.SetValue(currentLFO2Depth);
   
   previousLFO1Rate = currentLFO1Rate;
   previousLFO1Depth = currentLFO1Depth;
   previousLFO2Rate = currentLFO2Rate;
   previousLFO2Depth = currentLFO2Depth;

   SlowLFO1.SetFrequency(currentLFO1Rate);
   SlowLFO2.SetFrequency(currentLFO1Rate);
   SlowLFO3.SetFrequency(currentLFO1Rate);

   FastLFO1.SetFrequency(currentLFO2Rate);
   FastLFO2.SetFrequency(currentLFO2Rate);
   FastLFO3.SetFrequency(currentLFO2Rate);
   
   syncHigh = (inputSync.GetValue() > 2.5);
   syncHighPrevious = syncHigh;
   
   SetMode(switchEnsemble.GetValue());
   SetLFOPhaseOffset();
   RestartLFOs();
   
   delayWritePos = 0;

   //[/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 == rateLFO1)
         {
            smoothLFO1Rate.SetValue(doubleValue);
         }
         else if (component == depthLFO1)
         {
            smoothLFO1Depth.SetValue(doubleValue);
         }
         else if (component == rateLFO2)
         {
            smoothLFO2Rate.SetValue(doubleValue);
         }
         else if (component == depthLFO2)
         {
            smoothLFO2Depth.SetValue(doubleValue);
         }
         
      }
      break;
   
      case Slider_Changed:   // doubleValue is the new slider value
      {
      }
      break;
   
      case Button_Changed:   // doubleValue is the new button/toggle button value
      {
      }
      break;
   
      case Switch_Changed:   // doubleValue is the new switch value
      {
         if (component == switchPhaseOffset)
         {
            SetLFOPhaseOffset();
            RestartLFOs();
         }
         else if (component == switchEnsemble)
         {
            SetMode (doubleValue);
            RestartLFOs();
         }
      }
      break;
   
      case Jack_Connected:   // longValue is the new cable ID
      {
         CheckConnections();
      }
      break;
   
      case Jack_Disconnected:   // All cables have been disconnected from this jack
      {
         CheckConnections();
      }
      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 temp;
   double deviation;
   int tempIndex;
   double intIndex;
   double fractIndex;
   double valuePosN;
   double valuePosNplus1;
   double modAtten;
   double slowLFOcompoundDepth;
   double fastLFOcompoundDepth;
   double out1;
   double out2;
   double out3;
   double dryValue;
   
   // Get current smoothed knob positions
   
   currentLFO1Rate = smoothLFO1Rate.GetSmoothValue();
   currentLFO1Depth = smoothLFO1Depth.GetSmoothValue();
   currentLFO2Rate = smoothLFO2Rate.GetSmoothValue();
   currentLFO2Depth = smoothLFO2Depth.GetSmoothValue();
   
   if (currentLFO1Rate != previousLFO1Rate)
   {
      SlowLFO1.SetFrequency(currentLFO1Rate);
      SlowLFO2.SetFrequency(currentLFO1Rate);
      SlowLFO3.SetFrequency(currentLFO1Rate);
      previousLFO1Rate = currentLFO1Rate;
   }
   
   if (currentLFO2Rate != previousLFO2Rate)
   {
      FastLFO1.SetFrequency(currentLFO2Rate);
      FastLFO2.SetFrequency(currentLFO2Rate);
      FastLFO3.SetFrequency(currentLFO2Rate);
      previousLFO2Rate = currentLFO2Rate;
   }
   
   if (modCVconnected)
   {
      temp = inputModCV.GetValue();
      
      // Limit input range to 0V - 5V
      
      if (temp > 5.0)
      {
         temp = 5.0;
      }
      
      if (temp < 0.0)
      {
         temp = 0.0;
      }
      
      // Attenuation = 0% at 0V and 100% at 5V
      modAtten = temp / 5.0;
      
   }
   else
   {
      modAtten = 1.0;
   }
   
   slowLFOcompoundDepth = currentLFO1Depth *
                          modAtten *
                          SLOW_LFO_DEPTH;
   
   fastLFOcompoundDepth = currentLFO2Depth *
                          modAtten *
                          FAST_LFO_DEPTH;
   
   // Read audio input to delay line
   
   dryValue = inputAudio.GetValue();
   delayLine[delayWritePos] = dryValue;
   delayWritePos++;
   if (delayWritePos >= DELAY_LINE_LENGTH)
   {
      delayWritePos = 0;
   }
   
   // Check for rising edge on Sync input
   
   syncHigh = (inputSync.GetValue() > 2.5);
   
   if (syncHigh && !syncHighPrevious)
   {
      RestartLFOs();
   }
   
   syncHighPrevious = syncHigh;

   // Advance LFOs
   SlowLFO1.AdvanceSample();
   SlowLFO2.AdvanceSample();
   SlowLFO3.AdvanceSample();

   FastLFO1.AdvanceSample();
   FastLFO2.AdvanceSample();
   FastLFO3.AdvanceSample();
   
   if (outputConnected)
   {
      // ----------------------------- Calculate channel 1 output
   
      if (ensembleMode == EnsembleSetting.OFF)
      {
         // Off mode - channel 1 delayed but not modulated
         
         intIndex = 0.0;
         fractIndex = 0.0;
      }
      else
      {
         // Ensemble & Chorus modes - modulate channel 1
         
         temp = SlowLFO1.GetSineValue() * slowLFOcompoundDepth;
         temp += FastLFO1.GetSineValue() * fastLFOcompoundDepth;
   
         intIndex = floor(temp);
         fractIndex = temp - intIndex;
      }
   
      tempIndex = (int)(intIndex);
   
      tempIndex += delayWritePos + DELAY_LINE_MIDPOINT;
      if (tempIndex >= DELAY_LINE_LENGTH)
      {
         tempIndex -= DELAY_LINE_LENGTH;
      }   
      valuePosN = delayLine[tempIndex];
   
      tempIndex++;
      if (tempIndex >= DELAY_LINE_LENGTH)
      {
         tempIndex -= DELAY_LINE_LENGTH;
      }
      valuePosNplus1 = delayLine[tempIndex];
   
      // Linear interpolation between successive values
   
      temp = valuePosN * (1.0 - fractIndex) +
             valuePosNplus1 * fractIndex;

      outputChannel1.SetValue(temp);
   
      out1 = temp;

      // ----------------------------- Calculate channel 2 output
      
      if (ensembleMode == EnsembleSetting.ENSEMBLE)
      {
         // Ensemble mode - modulate channel 2
         
         temp = SlowLFO2.GetSineValue() * slowLFOcompoundDepth;
         temp += FastLFO2.GetSineValue() * fastLFOcompoundDepth;
   
         intIndex = floor(temp);
         fractIndex = temp - intIndex;
      }
      else
      {
         // Off & Chorus modes - channel 2 delayed but not modulated
         
         intIndex = 0.0;
         fractIndex = 0.0;
      }
   
      tempIndex = (int)(intIndex);
   
      tempIndex += delayWritePos + DELAY_LINE_MIDPOINT;
      if (tempIndex >= DELAY_LINE_LENGTH)
      {
         tempIndex -= DELAY_LINE_LENGTH;
      }   
      valuePosN = delayLine[tempIndex];
   
      tempIndex++;
      if (tempIndex >= DELAY_LINE_LENGTH)
      {
         tempIndex -= DELAY_LINE_LENGTH;
      }
      valuePosNplus1 = delayLine[tempIndex];
   
      // Linear interpolation between successive values
   
      temp = valuePosN * (1.0 - fractIndex) +
             valuePosNplus1 * fractIndex;

      outputChannel2.SetValue(temp);
   
      out2 = temp;

      // ----------------------------- Calculate channel 3 output
   
      if (ensembleMode == EnsembleSetting.OFF)
      {
         // Off mode - channel 3 delayed but not modulated
         
         intIndex = 0.0;
         fractIndex = 0.0;
      }
      else
      {
         // Ensemble & Chorus modes - modulate channel 3
         
         temp = SlowLFO3.GetSineValue() * slowLFOcompoundDepth;
         temp += FastLFO3.GetSineValue() * fastLFOcompoundDepth;
   
         intIndex = floor(temp);
         fractIndex = temp - intIndex;
      }
   
      tempIndex = (int)(intIndex);
   
      tempIndex += delayWritePos + DELAY_LINE_MIDPOINT;
      if (tempIndex >= DELAY_LINE_LENGTH)
      {
         tempIndex -= DELAY_LINE_LENGTH;
      }   
      valuePosN = delayLine[tempIndex];
   
      tempIndex++;
      if (tempIndex >= DELAY_LINE_LENGTH)
      {
         tempIndex -= DELAY_LINE_LENGTH;
      }
      valuePosNplus1 = delayLine[tempIndex];
   
      // Linear interpolation between successive values
   
      temp = valuePosN * (1.0 - fractIndex) +
             valuePosNplus1 * fractIndex;

      outputChannel3.SetValue(temp);
   
      out3 = temp;
   
      // ----------------------------- Calculate Ensemble Left / Mono and Right outputs
   
      if (stereoOutput)
      {
         switch (ensembleMode)
         {
            case ENSEMBLE:
            {
               // Ensemble mode stereo processing
            
               // Left stereo output
               temp = 0.333 * (out1 + out1 + out2);
               outputEnsemble.SetValue(temp);

               // Right stereo output
               temp = 0.333 * (out3 + out3 + out2);
               outputEnsembleRight.SetValue(temp);
            }
            break;
            
            case CHORUS:
            {
               // Chorus mode stereo processing
            
               // Left stereo output
               temp = 0.5 * (out1 + out2);
               outputEnsemble.SetValue(temp);

               // Right stereo output
               temp = 0.5 * (out3 + out2);
               outputEnsembleRight.SetValue(temp);
            }
            break;
            
            case OFF:
            {
               // Off mode stereo processing
            
               // Left stereo output
               outputEnsemble.SetValue(out2);

               // Right stereo output
               outputEnsembleRight.SetValue(out2);
            }
            break;
            
         }
      }
      else
      {
         switch (ensembleMode)
         {
            case ENSEMBLE:
            {
               // Ensemble mode mono processing
            
               temp = 0.333 * (out1 + out2 + out3);
               outputEnsemble.SetValue(temp);
            }
            break;
            
            case CHORUS:
            {
               // Chorus mode mono processing
            
               temp = 0.5 * (out1 + out2);
               outputEnsemble.SetValue(temp);
            }
            break;
            
            case OFF:
            {
               // Off mode mono processing
            
               outputEnsemble.SetValue(out2);
            }
            break;
            
         }
      }
      
   }  // End of if (outputConnected)

   //[/user-ProcessSample]
}


//-------------------------------------------------------------------------------
//  public void ProcessBypassedSample()

//  ProcessBypassedSample gets called instead of ProcessSample when you've checked the "Can Be Bypassed" box
//  and a user has bypassed your module. If your module processes data from input jacks and then sends it to
//  output jack(s), make ProcessBypassedSample just send the data from the input jacks to the output jacks without
//  processing it.
//-------------------------------------------------------------------------------
@Override
public void ProcessBypassedSample()
{
   //[user-ProcessBypassedSample]   Add your own code here

   double temp;

   temp = inputAudio.GetValue();
   
   outputChannel1.SetValue(temp);
   outputChannel2.SetValue(temp);
   outputChannel3.SetValue(temp);
   outputEnsemble.SetValue(temp);
   outputEnsembleRight.SetValue(temp);

   //[/user-ProcessBypassedSample]
}


//-------------------------------------------------------------------------------
//  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 VoltageLabel textLabel26;
private VoltageSwitch switchEnsemble;
private VoltageAudioJack outputEnsembleRight;
private VoltageLabel textLabel23;
private VoltageLabel textLabel22;
private VoltageLabel textLabel21;
private VoltageLabel textLabel20;
private VoltageLabel textLabel19;
private VoltageLabel textLabel18;
private VoltageLabel textLabel17;
private VoltageLabel textLabel16;
private VoltageLabel textLabel15;
private VoltageLabel textLabel14;
private VoltageAudioJack inputModCV;
private VoltageKnob depthLFO2;
private VoltageKnob rateLFO2;
private VoltageKnob depthLFO1;
private VoltageKnob rateLFO1;
private VoltageImage image1;
private VoltageLabel textLabel11;
private VoltageLabel textLabel10;
private VoltageLabel textLabel25;
private VoltageLabel textLabel24;
private VoltageLabel textLabel13;
private VoltageLabel textLabel12;
private VoltageLabel textLabel9;
private VoltageLabel textLabel7;
private VoltageAudioJack outputChannel1;
private VoltageAudioJack outputChannel2;
private VoltageAudioJack outputChannel3;
private VoltageAudioJack outputEnsemble;
private VoltageAudioJack inputAudio;
private VoltageLabel textLabel6;
private VoltageLabel textLabel5;
private VoltageLabel textLabel4;
private VoltageLabel textLabel3;
private VoltageLabel textLabel2;
private VoltageSwitch switchPhaseOffset;
private VoltageLabel textLabel1;
private VoltageAudioJack inputSync;


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

// Types

private enum EnsembleSetting
{
   ENSEMBLE,
   OFF,
   CHORUS
}

// Constants

private final double DEGREES_000 = 0.0;
private final double DEGREES_360 = 1.0;
private final double DEGREES_030 = DEGREES_360 / 12.0;
private final double DEGREES_060 = DEGREES_360 / 6.0;
private final double DEGREES_090 = DEGREES_360 / 4.0;
private final double DEGREES_120 = DEGREES_360 / 3.0;
private final double DEGREES_240 = DEGREES_120 * 2.0;

private final double SLOW_LFO_DEPTH = 29.0 / 5.0;
private final double FAST_LFO_DEPTH = 19.0 / 5.0;

private final int DELAY_LINE_LENGTH = 100;
private final int DELAY_LINE_MIDPOINT = DELAY_LINE_LENGTH / 2;

// Variables

private double phaseOffsetLFO;
private double[] delayLine = new double[DELAY_LINE_LENGTH];
private int delayWritePos;
private boolean syncHigh;
private boolean syncHighPrevious;

private double currentLFO1Rate;
private double currentLFO1Depth;
private double currentLFO2Rate;
private double currentLFO2Depth;

private double previousLFO1Rate;
private double previousLFO1Depth;
private double previousLFO2Rate;
private double previousLFO2Depth;

private boolean modCVconnected;
private boolean outputConnected;
private boolean stereoOutput;
private EnsembleSetting ensembleMode;


// Objects

protected DigitalOscillator SlowLFO1 = new DigitalOscillator();
protected DigitalOscillator SlowLFO2 = new DigitalOscillator();
protected DigitalOscillator SlowLFO3 = new DigitalOscillator();
protected DigitalOscillator FastLFO1 = new DigitalOscillator();
protected DigitalOscillator FastLFO2 = new DigitalOscillator();
protected DigitalOscillator FastLFO3 = new DigitalOscillator();

private SmoothValue smoothLFO1Rate = new SmoothValue();
private SmoothValue smoothLFO1Depth = new SmoothValue();
private SmoothValue smoothLFO2Rate = new SmoothValue();
private SmoothValue smoothLFO2Depth = new SmoothValue();

// Functions

private void SetLFOPhaseOffset()
{
   double switchPos;
   
   switchPos = switchPhaseOffset.GetValue();
   if (switchPos < 0.5)
   {
      phaseOffsetLFO = DEGREES_000;
   }
   else if (switchPos < 1.5)
   {
      phaseOffsetLFO = DEGREES_030;
   }
   else if (switchPos < 2.5)
   {
      phaseOffsetLFO = DEGREES_060;
   }
   else
   {
      phaseOffsetLFO = DEGREES_090;
   }
}

private void SetMode(double modeSetting)
{
   if (modeSetting < 0.5)
   {
      ensembleMode = EnsembleSetting.ENSEMBLE;
   }
   else if (modeSetting < 1.5)
   {
      ensembleMode = EnsembleSetting.OFF;
   }
   else
   {
      ensembleMode = EnsembleSetting.CHORUS;
   }
}

private void RestartLFOs()
{
   SlowLFO1.SetCycle(DEGREES_000 + phaseOffsetLFO);
   SlowLFO2.SetCycle(DEGREES_120 + phaseOffsetLFO);
   SlowLFO3.SetCycle(DEGREES_240 + phaseOffsetLFO);

   FastLFO1.SetCycle(DEGREES_000 + phaseOffsetLFO);
   FastLFO2.SetCycle(DEGREES_120 + phaseOffsetLFO);
   FastLFO3.SetCycle(DEGREES_240 + phaseOffsetLFO);
   
}

private void CheckConnections()
{
   stereoOutput = outputEnsembleRight.IsConnected();
   
   outputConnected = stereoOutput ||
                     outputEnsemble.IsConnected() ||
                     outputChannel1.IsConnected() ||
                     outputChannel2.IsConnected() ||
                     outputChannel3.IsConnected();
   
   modCVconnected = inputModCV.IsConnected();
   
}

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

 