2024-08-10 19:26:56 +00:00
# pragma once
2024-09-12 22:09:54 +00:00
# define VERSION_HINT 2
2024-08-10 19:26:56 +00:00
# include <JuceHeader.h>
2024-11-06 20:15:09 +00:00
# include "../components/EffectComponent.h"
# include "../components/SvgButton.h"
2024-08-13 13:55:30 +00:00
# include "../LookAndFeel.h"
2024-11-06 20:15:09 +00:00
# include "../components/SwitchButton.h"
2024-11-09 22:51:42 +00:00
# include "../audio/SmoothEffect.h"
2024-08-10 19:26:56 +00:00
2024-12-26 23:00:52 +00:00
enum class ScreenType : int {
Empty = 1 ,
Graticule = 2 ,
Smudged = 3 ,
SmudgedGraticule = 4 ,
2024-12-30 11:55:45 +00:00
# if SOSCI_FEATURES
2024-12-28 15:37:19 +00:00
Real = 5 ,
VectorDisplay = 6 ,
2024-12-30 11:55:45 +00:00
MAX = 6 ,
# else
MAX = 4 ,
# endif
2024-12-26 23:00:52 +00:00
} ;
class ScreenTypeParameter : public IntParameter {
public :
2024-12-30 11:55:45 +00:00
ScreenTypeParameter ( juce : : String name , juce : : String id , int versionHint , ScreenType value ) : IntParameter ( name , id , versionHint , ( int ) value , 1 , ( int ) ScreenType : : MAX ) { }
2024-12-26 23:00:52 +00:00
juce : : String getText ( float value , int maximumStringLength = 100 ) const override {
switch ( ( ScreenType ) ( int ) getUnnormalisedValue ( value ) ) {
case ScreenType : : Empty :
return " Empty " ;
case ScreenType : : Graticule :
return " Graticule " ;
case ScreenType : : Smudged :
return " Smudged " ;
case ScreenType : : SmudgedGraticule :
return " Smudged Graticule " ;
2024-12-30 11:55:45 +00:00
# if SOSCI_FEATURES
2024-12-26 23:00:52 +00:00
case ScreenType : : Real :
return " Real Oscilloscope " ;
2024-12-28 15:37:19 +00:00
case ScreenType : : VectorDisplay :
return " Vector Display " ;
2024-12-30 11:55:45 +00:00
# endif
2024-12-26 23:00:52 +00:00
default :
return " Unknown " ;
}
}
float getValueForText ( const juce : : String & text ) const override {
int unnormalisedValue ;
if ( text = = " Empty " ) {
unnormalisedValue = ( int ) ScreenType : : Empty ;
} else if ( text = = " Graticule " ) {
unnormalisedValue = ( int ) ScreenType : : Graticule ;
} else if ( text = = " Smudged " ) {
unnormalisedValue = ( int ) ScreenType : : Smudged ;
} else if ( text = = " Smudged Graticule " ) {
unnormalisedValue = ( int ) ScreenType : : SmudgedGraticule ;
2024-12-30 11:55:45 +00:00
# if SOSCI_FEATURES
2024-12-26 23:00:52 +00:00
} else if ( text = = " Real Oscilloscope " ) {
unnormalisedValue = ( int ) ScreenType : : Real ;
2024-12-28 15:37:19 +00:00
} else if ( text = = " Vector Display " ) {
unnormalisedValue = ( int ) ScreenType : : VectorDisplay ;
2024-12-30 11:55:45 +00:00
# endif
2024-12-26 23:00:52 +00:00
} else {
unnormalisedValue = ( int ) ScreenType : : Empty ;
}
return getNormalisedValue ( unnormalisedValue ) ;
}
void save ( juce : : XmlElement * xml ) {
xml - > setAttribute ( " screenType " , getText ( getValue ( ) ) ) ;
}
void load ( juce : : XmlElement * xml ) {
setValueNotifyingHost ( getValueForText ( xml - > getStringAttribute ( " screenType " ) ) ) ;
}
2024-12-28 15:37:19 +00:00
2024-12-30 11:55:45 +00:00
# if SOSCI_FEATURES
2024-12-28 15:37:19 +00:00
bool isRealisticDisplay ( ) {
ScreenType type = ( ScreenType ) ( int ) getValueUnnormalised ( ) ;
return type = = ScreenType : : Real | | type = = ScreenType : : VectorDisplay ;
}
2024-12-30 11:55:45 +00:00
# endif
2024-12-26 23:00:52 +00:00
} ;
2024-09-12 22:09:54 +00:00
class VisualiserParameters {
public :
2024-12-26 23:00:52 +00:00
ScreenTypeParameter * screenType = new ScreenTypeParameter ( " Screen Type " , " screenType " , VERSION_HINT , ScreenType : : SmudgedGraticule ) ;
2024-11-17 12:18:30 +00:00
BooleanParameter * upsamplingEnabled = new BooleanParameter ( " Upsample Audio " , " upsamplingEnabled " , VERSION_HINT , true , " Upsamples the audio before visualising it to make it appear more realistic, at the expense of performance. " ) ;
BooleanParameter * sweepEnabled = new BooleanParameter ( " Sweep " , " sweepEnabled " , VERSION_HINT , false , " Plots the audio signal over time, sweeping from left to right " ) ;
2024-09-12 22:09:54 +00:00
BooleanParameter * visualiserFullScreen = new BooleanParameter ( " Visualiser Fullscreen " , " visualiserFullScreen " , VERSION_HINT , false , " Makes the software visualiser fullscreen. " ) ;
std : : shared_ptr < Effect > persistenceEffect = std : : make_shared < Effect > (
new EffectParameter (
" Persistence " ,
" Controls how long the light glows for on the oscilloscope display. " ,
" persistence " ,
VERSION_HINT , 0.5 , 0 , 6.0
)
) ;
std : : shared_ptr < Effect > hueEffect = std : : make_shared < Effect > (
new EffectParameter (
" Hue " ,
" Controls the hue/colour of the oscilloscope display. " ,
" hue " ,
VERSION_HINT , 125 , 0 , 359 , 1
)
) ;
std : : shared_ptr < Effect > intensityEffect = std : : make_shared < Effect > (
new EffectParameter (
" Intensity " ,
" Controls how bright the electron beam of the oscilloscope is. " ,
" intensity " ,
2024-11-17 12:18:30 +00:00
VERSION_HINT , 5.0 , 0.0 , 10.0
2024-09-12 22:09:54 +00:00
)
) ;
2024-09-29 18:46:35 +00:00
std : : shared_ptr < Effect > saturationEffect = std : : make_shared < Effect > (
new EffectParameter (
" Saturation " ,
" Controls how saturated the colours are on the oscilloscope. " ,
" saturation " ,
VERSION_HINT , 1.0 , 0.0 , 5.0
)
) ;
2024-09-29 19:36:16 +00:00
std : : shared_ptr < Effect > focusEffect = std : : make_shared < Effect > (
new EffectParameter (
" Focus " ,
" Controls how focused the electron beam of the oscilloscope is. " ,
" focus " ,
VERSION_HINT , 1.0 , 0.01 , 10.0
)
) ;
2024-11-06 20:15:09 +00:00
std : : shared_ptr < Effect > noiseEffect = std : : make_shared < Effect > (
new EffectParameter (
" Noise " ,
" Controls how much noise/grain is added to the oscilloscope display. " ,
" noise " ,
2024-11-17 12:18:30 +00:00
VERSION_HINT , 0.0 , 0.0 , 1.0
2024-11-06 20:15:09 +00:00
)
) ;
2024-11-09 21:37:20 +00:00
std : : shared_ptr < Effect > glowEffect = std : : make_shared < Effect > (
new EffectParameter (
" Glow " ,
" Controls how much the light glows on the oscilloscope display. " ,
" glow " ,
VERSION_HINT , 0.3 , 0.0 , 1.0
)
) ;
2024-12-26 23:00:52 +00:00
std : : shared_ptr < Effect > ambientEffect = std : : make_shared < Effect > (
new EffectParameter (
" Ambient Light " ,
" Controls how much ambient light is added to the oscilloscope display. " ,
" ambient " ,
2024-12-28 15:37:19 +00:00
VERSION_HINT , 0.7 , 0.0 , 5.0
2024-12-26 23:00:52 +00:00
)
) ;
2024-11-09 22:51:42 +00:00
std : : shared_ptr < Effect > smoothEffect = std : : make_shared < Effect > (
std : : make_shared < SmoothEffect > ( ) ,
new EffectParameter (
" Smoothing " ,
" This works as a low-pass frequency filter, effectively reducing the sample rate of the audio being visualised. " ,
" visualiserSmoothing " ,
VERSION_HINT , 0 , 0.0 , 1.0
)
) ;
2024-11-17 12:18:30 +00:00
std : : shared_ptr < Effect > sweepMsEffect = std : : make_shared < Effect > (
new EffectParameter (
" Sweep (ms) " ,
" The number of milliseconds it takes for the oscilloscope to sweep from left to right. " ,
" sweepMs " ,
VERSION_HINT , 0.3 , 0.0 , 1.0
)
) ;
2024-11-09 22:51:42 +00:00
2024-12-26 23:00:52 +00:00
std : : vector < std : : shared_ptr < Effect > > effects = { persistenceEffect , hueEffect , intensityEffect , saturationEffect , focusEffect , noiseEffect , glowEffect , ambientEffect , sweepMsEffect } ;
std : : vector < BooleanParameter * > booleans = { upsamplingEnabled , visualiserFullScreen , sweepEnabled } ;
std : : vector < IntParameter * > integers = { screenType } ;
2024-09-12 22:09:54 +00:00
} ;
2024-08-10 19:26:56 +00:00
class VisualiserSettings : public juce : : Component {
public :
2024-09-22 17:49:58 +00:00
VisualiserSettings ( VisualiserParameters & , int numChannels = 2 ) ;
2024-08-10 19:26:56 +00:00
~ VisualiserSettings ( ) ;
void resized ( ) override ;
2024-10-22 21:25:09 +00:00
double getIntensity ( ) {
return parameters . intensityEffect - > getActualValue ( ) / 100 ;
}
double getPersistence ( ) {
return parameters . persistenceEffect - > getActualValue ( ) - 1.33 ;
}
double getHue ( ) {
return parameters . hueEffect - > getActualValue ( ) ;
}
double getSaturation ( ) {
return parameters . saturationEffect - > getActualValue ( ) ;
}
double getFocus ( ) {
return parameters . focusEffect - > getActualValue ( ) / 100 ;
}
2024-11-06 20:15:09 +00:00
double getNoise ( ) {
return parameters . noiseEffect - > getActualValue ( ) ;
}
2024-11-09 21:37:20 +00:00
double getGlow ( ) {
return parameters . glowEffect - > getActualValue ( ) * 3 ;
}
2024-12-26 23:00:52 +00:00
double getAmbient ( ) {
return parameters . ambientEffect - > getActualValue ( ) ;
2024-10-22 21:25:09 +00:00
}
2024-12-26 23:00:52 +00:00
ScreenType getScreenType ( ) {
return ( ScreenType ) parameters . screenType - > getValueUnnormalised ( ) ;
2024-10-22 21:25:09 +00:00
}
bool getUpsamplingEnabled ( ) {
return parameters . upsamplingEnabled - > getBoolValue ( ) ;
}
2024-08-10 19:26:56 +00:00
2024-09-12 22:09:54 +00:00
VisualiserParameters & parameters ;
2024-09-22 17:49:58 +00:00
int numChannels ;
2024-09-12 22:09:54 +00:00
private :
EffectComponent intensity { * parameters . intensityEffect } ;
EffectComponent persistence { * parameters . persistenceEffect } ;
EffectComponent hue { * parameters . hueEffect } ;
2024-09-29 18:46:35 +00:00
EffectComponent saturation { * parameters . saturationEffect } ;
2024-09-29 19:36:16 +00:00
EffectComponent focus { * parameters . focusEffect } ;
2024-11-09 21:37:20 +00:00
EffectComponent noise { * parameters . noiseEffect } ;
EffectComponent glow { * parameters . glowEffect } ;
2024-12-26 23:00:52 +00:00
EffectComponent ambient { * parameters . ambientEffect } ;
2024-11-09 22:51:42 +00:00
EffectComponent smooth { * parameters . smoothEffect } ;
2024-11-17 12:18:30 +00:00
EffectComponent sweepMs { * parameters . sweepMsEffect } ;
2024-08-13 13:55:30 +00:00
2024-12-26 23:00:52 +00:00
juce : : Label screenTypeLabel { " Screen Type " , " Screen Type " } ;
juce : : ComboBox screenType ;
2024-09-12 22:09:54 +00:00
jux : : SwitchButton upsamplingToggle { parameters . upsamplingEnabled } ;
2024-11-17 12:18:30 +00:00
jux : : SwitchButton sweepToggle { parameters . sweepEnabled } ;
2024-08-10 19:26:56 +00:00
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR ( VisualiserSettings )
} ;
2024-08-13 13:55:30 +00:00
class SettingsWindow : public juce : : DocumentWindow {
public :
2025-01-01 16:38:58 +00:00
SettingsWindow ( juce : : String name , juce : : Component & component ) : juce : : DocumentWindow ( name , Colours : : darker , juce : : DocumentWindow : : TitleBarButtons : : closeButton ) , component ( component ) {
juce : : Component : : addAndMakeVisible ( viewport ) ;
2024-12-15 19:23:31 +00:00
setResizable ( false , false ) ;
2025-01-01 16:38:58 +00:00
viewport . setViewedComponent ( & component , false ) ;
viewport . setScrollBarsShown ( false , false , true , false ) ;
setAlwaysOnTop ( true ) ;
2024-12-15 19:23:31 +00:00
}
2024-08-13 13:55:30 +00:00
void closeButtonPressed ( ) override {
setVisible ( false ) ;
}
2025-01-01 16:38:58 +00:00
void resized ( ) override {
viewport . setBounds ( getLocalBounds ( ) ) ;
}
private :
juce : : Viewport viewport ;
juce : : Component & component ;
2024-08-13 13:55:30 +00:00
} ;