diff --git a/MusicBeam/Effect.pde b/MusicBeam/Effect.pde index 4468f4a..a923299 100644 --- a/MusicBeam/Effect.pde +++ b/MusicBeam/Effect.pde @@ -37,7 +37,7 @@ public abstract class Effect stg = controller.stage; frameRate = stg.frameRate; - int posy = 115+(i*50); + int posy = 170+(i*50); controlGroup = cp5.addGroup(getName()+"SettingsGroup").hide().setPosition(10,195).setWidth(395).setHeight(30); controlGroup.disableCollapse(); diff --git a/MusicBeam/MusicBeam.pde b/MusicBeam/MusicBeam.pde index 346739f..74047fb 100644 --- a/MusicBeam/MusicBeam.pde +++ b/MusicBeam/MusicBeam.pde @@ -34,16 +34,18 @@ Effect[] effectArray; DropdownList displays; -Toggle projectorToggle, randomToggle; +Toggle projectorToggle, randomToggle, blackoutOnSilenceToggle; Slider randomTimeSlider, beatDelaySlider, minLevelSlider; Button nextButton; RadioButton activeEffect, activeSetting; float randomTimer = 0; +int lastAudibleMillis = 0; + int randomEffect = 0; int width = 775; -int height = 670; +int height = 725; float maxLevel = 0; float goalMaxLevel=0; @@ -235,8 +237,11 @@ void initRandomControls() { nextButton = cp5.addButton("next").setSize(350, 45).setPosition(415, 60); nextButton.getCaptionLabel().set("Next Effect").align(ControlP5.CENTER, ControlP5.CENTER); - activeEffect = cp5.addRadioButton("activeEffects").setPosition(415, 115).setSize(250, 45).setItemsPerRow(1).setSpacingRow(5).setNoneSelectedAllowed(true); - activeSetting = cp5.addRadioButton("activeSettings").setPosition(720, 115).setSize(45, 45).setItemsPerRow(1).setSpacingRow(5); + blackoutOnSilenceToggle = cp5.addToggle("blackoutOnSilence").setSize(350, 45).setPosition(415, 110); + blackoutOnSilenceToggle.getCaptionLabel().set("Blackout on Silence").align(ControlP5.CENTER, ControlP5.CENTER); + + activeEffect = cp5.addRadioButton("activeEffects").setPosition(415, 170).setSize(250, 45).setItemsPerRow(1).setSpacingRow(5).setNoneSelectedAllowed(true); + activeSetting = cp5.addRadioButton("activeSettings").setPosition(720, 170).setSize(45, 45).setItemsPerRow(1).setSpacingRow(5); } void initEffects() @@ -272,6 +277,9 @@ void beatDetect() bdFreq.setSensitivity(int(beatDelaySlider.getValue())); bdSound.detect(in.mix); bdFreq.detect(in.mix); + + if (getLevel()>minLevelSlider.getValue()) + lastAudibleMillis = millis(); } void checkForUpdate() @@ -338,6 +346,20 @@ float getLevel() return in.mix.level(); } +// 1 while audible (or toggle off); after a 1.5s silence grace period, +// fades to 0 over the next second so the stage dims to black. +float silenceFade() +{ + float fade = 1; + if (blackoutOnSilenceToggle.getState()) + { + int quiet = millis()-lastAudibleMillis; + if (quiet > 1500) + fade = max(0, 1 - (quiet-1500)/1000.0); + } + return fade; +} + private boolean hasEnoughScreenDevices() { GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); //<>// //<>// diff --git a/MusicBeam/Stage.pde b/MusicBeam/Stage.pde index b4d99d1..657d7a1 100644 --- a/MusicBeam/Stage.pde +++ b/MusicBeam/Stage.pde @@ -21,7 +21,7 @@ public class Stage extends PApplet { } public void setup() { - colorMode(HSB, 360, 100, 100); + colorMode(HSB, 360, 100, 100, 100); try { blendMode(ADD); } catch (Exception e) { @@ -41,9 +41,22 @@ public class Stage extends PApplet { } translate(width/2, height/2); - for (int i = 0; i < effectArray.length; i++) - if (effectArray[i].isActive()) - effectArray[i].refresh(); + float fade = ctrl.silenceFade(); + if (fade > 0) { + for (int i = 0; i < effectArray.length; i++) + if (effectArray[i].isActive()) + effectArray[i].refresh(); + + if (fade < 1) { + // additive blending cannot darken, so switch to normal blending + // for a translucent black overlay while fading out + blendMode(BLEND); + noStroke(); + fill(0, 0, 0, (1-fade)*100); + rect(-width/2, -height/2, width, height); + blendMode(ADD); + } + } } public int getMaxRadius(){