BIN
Documents/discoDSP/OB-Xd/Banks/000 - FMR OB-Xa Patch Book.fxb
Normal file
BIN
Documents/discoDSP/OB-Xd/Banks/001 - Init Bank.fxb
Normal file
BIN
Documents/discoDSP/OB-Xd/Banks/002 - KVR Bass.fxb
Normal file
BIN
Documents/discoDSP/OB-Xd/Banks/003 - KVR Brass + Synths.fxb
Normal file
BIN
Documents/discoDSP/OB-Xd/Banks/006 - KVR Leads.fxb
Normal file
BIN
Documents/discoDSP/OB-Xd/Banks/008 - ABS Custom Shop v1.fxb
Normal file
BIN
Documents/discoDSP/OB-Xd/Banks/009 - Breeze Meat-n-Potatoes.fxb
Normal file
BIN
Documents/discoDSP/OB-Xd/Banks/011 - IW Bank 1.fxb
Normal file
BIN
Documents/discoDSP/OB-Xd/Banks/012 - Kujashi.fxb
Normal file
BIN
Documents/discoDSP/OB-Xd/Banks/015 - Rin Elyran Bank.fxb
Normal file
BIN
Documents/discoDSP/OB-Xd/Banks/016 - Xenos Soundworks.fxb
Normal file
BIN
Documents/discoDSP/OB-Xd/Banks/017 - Joel Obxd.FXB
Normal file
BIN
Documents/discoDSP/OB-Xd/Banks/019 - Phace.FXB
Normal file
82
Documents/discoDSP/OB-Xd/MIDI CC.txt
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
OB-Xd 2.0 default MIDI CC controller table.
|
||||||
|
Modify by clicking LEARN button, moving a GUI element and then sending MIDI CC data.
|
||||||
|
All values can be reset using CLEAN button.
|
||||||
|
|
||||||
|
CC# CONTROL
|
||||||
|
|
||||||
|
21 ASPLAYEDALLOCATION
|
||||||
|
105 BANDPASS
|
||||||
|
75 BENDLFORATE
|
||||||
|
34 BENDOSC2
|
||||||
|
118 BENDRANGE
|
||||||
|
62 BRIGHTNESS
|
||||||
|
74 CUTOFF
|
||||||
|
111 ECONOMY_MODE
|
||||||
|
115 ENV_PITCH_BOTH
|
||||||
|
108 ENVDER
|
||||||
|
107 ENVELOPE_AMT
|
||||||
|
63 ENVPITCH
|
||||||
|
38 FATK
|
||||||
|
39 FDEC
|
||||||
|
116 FENV_INVERT
|
||||||
|
18 FILTER_WARM
|
||||||
|
109 FILTERDER
|
||||||
|
103 FLT_KF
|
||||||
|
106 FOURPOLE
|
||||||
|
41 FREL
|
||||||
|
40 FSUS
|
||||||
|
73 LATK
|
||||||
|
36 LDEC
|
||||||
|
35 LEGATOMODE
|
||||||
|
118 LEVEL_DIF
|
||||||
|
22 LFO1AMT
|
||||||
|
25 LFO2AMT
|
||||||
|
49 LFOFILTER
|
||||||
|
19 LFOFREQ
|
||||||
|
47 LFOOSC1
|
||||||
|
48 LFOOSC2
|
||||||
|
50 LFOPW1
|
||||||
|
51 LFOPW2
|
||||||
|
46 LFOSHWAVE
|
||||||
|
44 LFOSINWAVE
|
||||||
|
45 LFOSQUAREWAVE
|
||||||
|
72 LREL
|
||||||
|
37 LSUS
|
||||||
|
104 MULTIMODE
|
||||||
|
102 NOISEMIX
|
||||||
|
17 OCTAVE
|
||||||
|
100 OSC1MIX
|
||||||
|
54 OSC1P
|
||||||
|
58 OSC1Pul
|
||||||
|
57 OSC1Saw
|
||||||
|
43 OSC2_DET
|
||||||
|
52 OSC2HS
|
||||||
|
101 OSC2MIX
|
||||||
|
55 OSC2P
|
||||||
|
60 OSC2Pul
|
||||||
|
59 OSC2Saw
|
||||||
|
56 OSCQuantize
|
||||||
|
81 PAN1
|
||||||
|
82 PAN2
|
||||||
|
83 PAN3
|
||||||
|
84 PAN4
|
||||||
|
85 PAN5
|
||||||
|
86 PAN6
|
||||||
|
87 PAN7
|
||||||
|
88 PAN8
|
||||||
|
110 PORTADER
|
||||||
|
23 PORTAMENTO
|
||||||
|
61 PW
|
||||||
|
113 PW_ENV
|
||||||
|
114 PW_ENV_BOTH
|
||||||
|
117 PW_OSC2_OFS
|
||||||
|
42 RESONANCE
|
||||||
|
119 SELF_OSC_PUSH
|
||||||
|
33 TUNE
|
||||||
|
24 UDET
|
||||||
|
16 UNISON
|
||||||
|
20 VAMPENV
|
||||||
|
76 VFLTENV
|
||||||
|
15 VOICE_COUNT
|
||||||
|
71 VOLUME
|
||||||
|
53 XMOD
|
BIN
Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/button.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/button@2x.png
Normal file
After Width: | Height: | Size: 36 KiB |
116
Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/coords.xml
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<PROPERTIES>
|
||||||
|
<VALUE NAME="guisize" x="1150" y="486"/>
|
||||||
|
<VALUE NAME="menu" x="54" y="423" d="37"/>
|
||||||
|
|
||||||
|
<!--MASTER-->
|
||||||
|
|
||||||
|
<VALUE NAME="volumeKnob" x="58" y="151" d="35"/>
|
||||||
|
<VALUE NAME="tuneKnob" x="125" y="151" d="35"/>
|
||||||
|
<VALUE NAME="transposeKnob" x="192" y="151" d="35"/>
|
||||||
|
|
||||||
|
<!--GLOBAL-->
|
||||||
|
|
||||||
|
<VALUE NAME="voiceDetuneKnob" x="58" y="273" d="35"/>
|
||||||
|
<VALUE NAME="unisonButton" x="127" y="275" w="37" h="37"/>
|
||||||
|
<VALUE NAME="portamentoKnob" x="192" y="273" d="35"/>
|
||||||
|
|
||||||
|
<VALUE NAME="voiceSwitch" x="189" y="350" w="48" h="35"/>
|
||||||
|
<VALUE NAME="legatoSwitch" x="53" y="350" w="122" h="35"/>
|
||||||
|
|
||||||
|
<VALUE NAME="asPlayedAllocButton" x="102" y="423" w="37" h="37"/>
|
||||||
|
<VALUE NAME="midiLearnButton" x="152" y="423" w="37" h="37"/>
|
||||||
|
<VALUE NAME="midiUnlearnButton" x="200" y="423" w="37" h="37"/>
|
||||||
|
|
||||||
|
<!--CONTROL-->
|
||||||
|
|
||||||
|
<VALUE NAME="bendRangeButton" x="291" y="412" w="37" h="37"/>
|
||||||
|
<VALUE NAME="bendOsc2OnlyButton" x="344" y="412" w="37" h="37"/>
|
||||||
|
|
||||||
|
<VALUE NAME="bendLfoRateKnob" x="403" y="408" d="35"/>
|
||||||
|
<VALUE NAME="veloFltEnvKnob" x="463" y="408" d="35"/>
|
||||||
|
<VALUE NAME="veloAmpEnvKnob" x="521" y="408" d="35"/>
|
||||||
|
|
||||||
|
<!--OSCILLATORS-->
|
||||||
|
|
||||||
|
<VALUE NAME="osc1PitchKnob" x="290" y="49" d="35"/>
|
||||||
|
<VALUE NAME="pulseWidthKnob" x="356" y="49" d="35"/>
|
||||||
|
<VALUE NAME="osc2PitchKnob" x="424" y="49" d="35"/>
|
||||||
|
|
||||||
|
<VALUE NAME="osc1SawButton" x="269" y="126" w="37" h="37"/>
|
||||||
|
<VALUE NAME="osc1PulButton" x="313" y="126" w="37" h="37"/>
|
||||||
|
<VALUE NAME="osc2DetuneKnob" x="357" y="123" d="35"/>
|
||||||
|
<VALUE NAME="osc2SawButton" x="404" y="126" w="37" h="37"/>
|
||||||
|
<VALUE NAME="osc2PulButton" x="447" y="126" w="37" h="37"/>
|
||||||
|
|
||||||
|
<VALUE NAME="hardSyncButton" x="291" y="201" w="37" h="37"/>
|
||||||
|
<VALUE NAME="xmodKnob" x="357" y="198" d="35"/>
|
||||||
|
<VALUE NAME="pitchQuantButton" x="426" y="201" w="37" h="37"/>
|
||||||
|
|
||||||
|
<VALUE NAME="brightnessKnob" x="290" y="272" d="35"/>
|
||||||
|
<VALUE NAME="envPitchModKnob" x="424" y="272" d="35"/>
|
||||||
|
|
||||||
|
<!--MIX-->
|
||||||
|
|
||||||
|
<VALUE NAME="osc1MixKnob" x="521" y="49" d="35"/>
|
||||||
|
<VALUE NAME="osc2MixKnob" x="521" y="123" d="35"/>
|
||||||
|
<VALUE NAME="noiseMixKnob" x="521" y="198" d="35"/>
|
||||||
|
|
||||||
|
<!--FILTER-->
|
||||||
|
|
||||||
|
<VALUE NAME="cutoffKnob" x="619" y="49" d="35"/>
|
||||||
|
<VALUE NAME="resonanceKnob" x="686" y="49" d="35"/>
|
||||||
|
<VALUE NAME="filterEnvelopeAmtKnob" x="753" y="49" d="35"/>
|
||||||
|
|
||||||
|
<VALUE NAME="filterKeyFollowButton" x="598" y="126" w="37" h="37"/>
|
||||||
|
<VALUE NAME="filterHQButton" x="642" y="126" w="37" h="37"/>
|
||||||
|
<VALUE NAME="multimodeKnob" x="686" y="123" d="35"/>
|
||||||
|
<VALUE NAME="filterBPBlendButton" x="733" y="126" w="37" h="37"/>
|
||||||
|
<VALUE NAME="fourPoleButton" x="776" y="126" w="37" h="37"/>
|
||||||
|
|
||||||
|
<!--ENVELOPES-->
|
||||||
|
|
||||||
|
<VALUE NAME="fattackKnob" x="850" y="49" d="35"/>
|
||||||
|
<VALUE NAME="fdecayKnob" x="917" y="49" d="35"/>
|
||||||
|
<VALUE NAME="fsustainKnob" x="984" y="49" d="35"/>
|
||||||
|
<VALUE NAME="freleaseKnob" x="1052" y="49" d="35"/>
|
||||||
|
|
||||||
|
<VALUE NAME="attackKnob" x="850" y="174" d="35"/>
|
||||||
|
<VALUE NAME="decayKnob" x="917" y="174" d="35"/>
|
||||||
|
<VALUE NAME="sustainKnob" x="984" y="174" d="35"/>
|
||||||
|
<VALUE NAME="releaseKnob" x="1052" y="174" d="35"/>
|
||||||
|
|
||||||
|
<!--MODULATION-->
|
||||||
|
|
||||||
|
<VALUE NAME="lfoFrequencyKnob" x="618" y="239" d="35"/>
|
||||||
|
<VALUE NAME="lfoAmt1Knob" x="685" y="239" d="35"/>
|
||||||
|
<VALUE NAME="lfoAmt2Knob" x="753" y="239" d="35"/>
|
||||||
|
|
||||||
|
<VALUE NAME="lfoSinButton" x="620" y="302" d="40" w="37" h="37"/>
|
||||||
|
<VALUE NAME="lfoSquareButton" x="620" y="363" d="40" w="37" h="37"/>
|
||||||
|
<VALUE NAME="lfoSHButton" x="620" y="423" d="40" w="37" h="37"/>
|
||||||
|
|
||||||
|
<VALUE NAME="lfoOsc1Button" x="687" y="302" w="37" h="37"/>
|
||||||
|
<VALUE NAME="lfoOsc2Button" x="687" y="363" w="37" h="37"/>
|
||||||
|
<VALUE NAME="lfoFilterButton" x="687" y="423" w="37" h="37"/>
|
||||||
|
|
||||||
|
<VALUE NAME="lfoPwm1Button" x="754" y="302" w="37" h="37"/>
|
||||||
|
<VALUE NAME="lfoPwm2Button" x="754" y="363" w="37" h="37"/>
|
||||||
|
|
||||||
|
<!--VOICE VARIATION-->
|
||||||
|
|
||||||
|
<VALUE NAME="filterDetuneKnob" x="850" y="298" d="35"/>
|
||||||
|
<VALUE NAME="portamentoDetuneKnob" x="917" y="298" d="35"/>
|
||||||
|
<VALUE NAME="envelopeDetuneKnob" x="984" y="298" d="35"/>
|
||||||
|
|
||||||
|
<VALUE NAME="pan1Knob" x="850" y="360" d="35"/>
|
||||||
|
<VALUE NAME="pan2Knob" x="917" y="360" d="35"/>
|
||||||
|
<VALUE NAME="pan3Knob" x="984" y="360" d="35"/>
|
||||||
|
<VALUE NAME="pan4Knob" x="1052" y="360" d="35"/>
|
||||||
|
|
||||||
|
<VALUE NAME="pan5Knob" x="850" y="420" d="35"/>
|
||||||
|
<VALUE NAME="pan6Knob" x="917" y="420" d="35"/>
|
||||||
|
<VALUE NAME="pan7Knob" x="984" y="420" d="35"/>
|
||||||
|
<VALUE NAME="pan8Knob" x="1052" y="420" d="35"/>
|
||||||
|
|
||||||
|
</PROPERTIES>
|
BIN
Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/knob.png
Normal file
After Width: | Height: | Size: 507 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/knob@2x.png
Normal file
After Width: | Height: | Size: 1.7 MiB |
BIN
Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/legato.png
Normal file
After Width: | Height: | Size: 27 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/legato@2x.png
Normal file
After Width: | Height: | Size: 78 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/main.png
Normal file
After Width: | Height: | Size: 742 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/main@2x.png
Normal file
After Width: | Height: | Size: 2.5 MiB |
BIN
Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/menu.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/menu@2x.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/voices.png
Normal file
After Width: | Height: | Size: 68 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/voices@2x.png
Normal file
After Width: | Height: | Size: 234 KiB |
10
Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/About.rtf
Executable file
|
@ -0,0 +1,10 @@
|
||||||
|
{\rtf1\ansi\ansicpg1252\cocoartf1671\cocoasubrtf600
|
||||||
|
{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
|
||||||
|
{\colortbl;\red255\green255\blue255;}
|
||||||
|
{\*\expandedcolortbl;;}
|
||||||
|
\paperw11900\paperh16840\margl1440\margr1440\vieww10800\viewh8400\viewkind0
|
||||||
|
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0
|
||||||
|
|
||||||
|
\f0\fs24 \cf0 By rin_elyran {\field{\*\fldinst{HYPERLINK "https://www.kvraudio.com/forum/viewtopic.php?p=6596898#p6596898"}}{\fldrslt https://www.kvraudio.com/forum/viewtopic.php?p=6596898#p6596898}}\
|
||||||
|
\
|
||||||
|
2.0 Retina rework by discoDSP.}
|
BIN
Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/button.png
Executable file
After Width: | Height: | Size: 1.9 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/button@2x.png
Executable file
After Width: | Height: | Size: 4.5 KiB |
117
Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/coords.xml
Executable file
|
@ -0,0 +1,117 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<PROPERTIES>
|
||||||
|
<VALUE NAME="guisize" x="1087" y="442"/>
|
||||||
|
<VALUE NAME="menu" x="23" y="30" d="20"/>
|
||||||
|
|
||||||
|
<!------- MASTER ----->
|
||||||
|
|
||||||
|
<VALUE NAME="volumeKnob" x="53" y="120" d="40"/>
|
||||||
|
<VALUE NAME="tuneKnob" x="116" y="120" d="40"/>
|
||||||
|
<VALUE NAME="transposeKnob" x="181" y="120" d="40"/>
|
||||||
|
|
||||||
|
<!------- GLOBAL ----->
|
||||||
|
|
||||||
|
<VALUE NAME="voiceDetuneKnob" x="58" y="241" d="40" w="28" h="35"/>
|
||||||
|
<VALUE NAME="unisonButton" x="125" y="251" w="28" h="35"/>
|
||||||
|
<VALUE NAME="portamentoKnob" x="175" y="241" d="40"/>
|
||||||
|
|
||||||
|
<VALUE NAME="voiceSwitch" x="172" y="321" w="38" h="32"/>
|
||||||
|
<VALUE NAME="legatoSwitch" x="66" y="321" w="89" h="32"/>
|
||||||
|
|
||||||
|
<VALUE NAME="asPlayedAllocButton" x="65" y="372" d="32" w="28" h="35"/>
|
||||||
|
<VALUE NAME="midiLearnButton" x="126" y="372" d="40" w="28" h="35"/>
|
||||||
|
<VALUE NAME="midiUnlearnButton" x="185" y="372" d="40" w="28" h="35"/>
|
||||||
|
|
||||||
|
<!------- CONTROL ----->
|
||||||
|
|
||||||
|
<VALUE NAME="bendOsc2OnlyButton" x="321" y="354" d="32" w="28" h="35"/>
|
||||||
|
<VALUE NAME="bendRangeButton" x="267" y="354" d="32" w="28" h="35"/>
|
||||||
|
|
||||||
|
<VALUE NAME="bendLfoRateKnob" x="369" y="345" d="40" w="28" h="35"/>
|
||||||
|
<VALUE NAME="veloFltEnvKnob" x="433" y="345" d="40" w="28" h="35"/>
|
||||||
|
<VALUE NAME="veloAmpEnvKnob" x="491" y="345" d="40" w="28" h="35"/>
|
||||||
|
|
||||||
|
<!------- OSCILLATORS ----->
|
||||||
|
|
||||||
|
<VALUE NAME="osc1PitchKnob" x="276" y="40" d="40"/>
|
||||||
|
<VALUE NAME="pulseWidthKnob" x="339" y="40" d="40"/>
|
||||||
|
<VALUE NAME="osc2PitchKnob" x="402" y="40" d="40"/>
|
||||||
|
|
||||||
|
<VALUE NAME="xmodKnob" x="339" y="168" d="40"/>
|
||||||
|
<VALUE NAME="osc2DetuneKnob" x="339" y="104" d="40"/>
|
||||||
|
<VALUE NAME="pitchQuantButton" x="407" y="178" w="28" h="35"/>
|
||||||
|
|
||||||
|
<VALUE NAME="envPitchModKnob" x="381" y="232" d="40"/>
|
||||||
|
<VALUE NAME="brightnessKnob" x="296" y="232" d="40"/>
|
||||||
|
|
||||||
|
<!------- MIX ----->
|
||||||
|
|
||||||
|
<VALUE NAME="osc1MixKnob" x="492" y="40" d="40"/>
|
||||||
|
<VALUE NAME="osc2MixKnob" x="492" y="132" d="40"/>
|
||||||
|
<VALUE NAME="noiseMixKnob" x="492" y="224" d="40"/>
|
||||||
|
|
||||||
|
<!------- FILTER ----->
|
||||||
|
|
||||||
|
<VALUE NAME="cutoffKnob" x="582" y="40" d="40"/>
|
||||||
|
<VALUE NAME="resonanceKnob" x="640" y="40" d="40"/>
|
||||||
|
<VALUE NAME="filterEnvelopeAmtKnob" x="704" y="40" d="40"/>
|
||||||
|
|
||||||
|
<VALUE NAME="multimodeKnob" x="640" y="104" d="40"/>
|
||||||
|
<VALUE NAME="filterKeyFollowButton" x="573" y="110" w="28" h="35"/>
|
||||||
|
|
||||||
|
<VALUE NAME="filterBPBlendButton" x="697" y="110" w="28" h="35"/>
|
||||||
|
<VALUE NAME="fourPoleButton" x="728" y="110" w="28" h="35"/>
|
||||||
|
<VALUE NAME="filterHQButton" x="604" y="110" w="28" h="35"/>
|
||||||
|
|
||||||
|
<!------- ENVELOPES ----->
|
||||||
|
|
||||||
|
<VALUE NAME="attackKnob" x="793" y="132" d="40"/>
|
||||||
|
<VALUE NAME="decayKnob" x="855" y="132" d="40"/>
|
||||||
|
<VALUE NAME="sustainKnob" x="918" y="132" d="40"/>
|
||||||
|
<VALUE NAME="releaseKnob" x="982" y="132" d="40"/>
|
||||||
|
|
||||||
|
<VALUE NAME="fattackKnob" x="793" y="40" d="40"/>
|
||||||
|
<VALUE NAME="fdecayKnob" x="855" y="40" d="40"/>
|
||||||
|
<VALUE NAME="fsustainKnob" x="918" y="40" d="40"/>
|
||||||
|
<VALUE NAME="freleaseKnob" x="982" y="40" d="40"/>
|
||||||
|
|
||||||
|
<!------- MODULATION ----->
|
||||||
|
|
||||||
|
<VALUE NAME="lfoFrequencyKnob" x="581" y="207" d="40"/>
|
||||||
|
<VALUE NAME="lfoAmt1Knob" x="640" y="207" d="40"/>
|
||||||
|
<VALUE NAME="lfoAmt2Knob" x="704" y="207" d="40"/>
|
||||||
|
|
||||||
|
<VALUE NAME="lfoSinButton" x="587" y="269" d="40" w="28" h="35"/>
|
||||||
|
<VALUE NAME="lfoSquareButton" x="587" y="323" d="40" w="28" h="35"/>
|
||||||
|
<VALUE NAME="lfoSHButton" x="587" y="378" d="40" w="28" h="35"/>
|
||||||
|
|
||||||
|
<VALUE NAME="lfoOsc1Button" x="651" y="269" w="28" h="35"/>
|
||||||
|
<VALUE NAME="lfoOsc2Button" x="651" y="323" w="28" h="35"/>
|
||||||
|
<VALUE NAME="lfoFilterButton" x="651" y="378" w="28" h="35"/>
|
||||||
|
|
||||||
|
<VALUE NAME="lfoPwm1Button" x="714" y="269" w="28" h="35"/>
|
||||||
|
<VALUE NAME="lfoPwm2Button" x="714" y="323" w="28" h="35"/>
|
||||||
|
|
||||||
|
<VALUE NAME="hardSyncButton" x="282" y="178" w="28" h="35"/>
|
||||||
|
<VALUE NAME="osc1SawButton" x="265" y="114" w="28" h="35"/>
|
||||||
|
<VALUE NAME="osc2SawButton" x="394" y="114" w="28" h="35"/>
|
||||||
|
|
||||||
|
<VALUE NAME="osc1PulButton" x="296" y="114" w="28" h="35"/>
|
||||||
|
<VALUE NAME="osc2PulButton" x="425" y="114" w="28" h="35"/>
|
||||||
|
|
||||||
|
<!------- VOICE VARIATION ----->
|
||||||
|
|
||||||
|
<VALUE NAME="filterDetuneKnob" x="819" y="240" d="32" w="28" h="35"/>
|
||||||
|
<VALUE NAME="envelopeDetuneKnob" x="965" y="240" d="32" w="28" h="35"/>
|
||||||
|
<VALUE NAME="portamentoDetuneKnob" x="892" y="240" d="32" w="28" h="35"/>
|
||||||
|
|
||||||
|
<VALUE NAME="pan1Knob" x="801" y="323" d="32"/>
|
||||||
|
<VALUE NAME="pan2Knob" x="860" y="323" d="32"/>
|
||||||
|
<VALUE NAME="pan3Knob" x="924" y="323" d="32"/>
|
||||||
|
<VALUE NAME="pan4Knob" x="987" y="323" d="32"/>
|
||||||
|
|
||||||
|
<VALUE NAME="pan5Knob" x="801" y="376" d="32"/>
|
||||||
|
<VALUE NAME="pan6Knob" x="860" y="376" d="32"/>
|
||||||
|
<VALUE NAME="pan7Knob" x="924" y="376" d="32"/>
|
||||||
|
<VALUE NAME="pan8Knob" x="987" y="376" d="32"/>
|
||||||
|
</PROPERTIES>
|
BIN
Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/knob.png
Normal file
After Width: | Height: | Size: 214 KiB |
After Width: | Height: | Size: 1.2 MiB |
BIN
Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/legato.png
Executable file
After Width: | Height: | Size: 9.9 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/legato@2x.png
Executable file
After Width: | Height: | Size: 2.3 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/main.png
Executable file
After Width: | Height: | Size: 222 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/main@2x.png
Executable file
After Width: | Height: | Size: 85 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/menu.png
Executable file
After Width: | Height: | Size: 9.2 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/menu@2x.png
Executable file
After Width: | Height: | Size: 1.8 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/voices.png
Executable file
After Width: | Height: | Size: 16 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/voices@2x.png
Executable file
After Width: | Height: | Size: 4.4 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/button.png
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/button@2x.png
Executable file
After Width: | Height: | Size: 5.4 KiB |
116
Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/coords.xml
Executable file
|
@ -0,0 +1,116 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<PROPERTIES>
|
||||||
|
<VALUE NAME="guisize" x="1440" y="450"/>
|
||||||
|
<VALUE NAME="menu" x="14" y="25" d="20"/>
|
||||||
|
|
||||||
|
<!------- MANUAL ----->
|
||||||
|
|
||||||
|
<VALUE NAME="volumeKnob" x="51" y="77" d="48"/>
|
||||||
|
|
||||||
|
<VALUE NAME="asPlayedAllocButton" x="25" y="162" w="19" h="35"/>
|
||||||
|
<VALUE NAME="midiLearnButton" x="74" y="162" w="19" h="35"/>
|
||||||
|
<VALUE NAME="midiUnlearnButton" x="122" y="162" w="19" h="35"/>
|
||||||
|
|
||||||
|
<VALUE NAME="tuneKnob" x="25" y="252" d="48"/>
|
||||||
|
<VALUE NAME="transposeKnob" x="85" y="252" d="48"/>
|
||||||
|
|
||||||
|
<VALUE NAME="voiceSwitch" x="124" y="338" w="17" h="24"/>
|
||||||
|
<VALUE NAME="legatoSwitch" x="25" y="338" w="65" h="24"/>
|
||||||
|
|
||||||
|
<!------- CONTROL ----->
|
||||||
|
|
||||||
|
<VALUE NAME="portamentoKnob" x="185" y="77" d="48"/>
|
||||||
|
<VALUE NAME="unisonButton" x="205" y="162" w="19" h="35"/>
|
||||||
|
<VALUE NAME="voiceDetuneKnob" x="185" y="252" d="48"/>
|
||||||
|
|
||||||
|
<VALUE NAME="bendRangeButton" x="183" y="335" w="19" h="35"/>
|
||||||
|
<VALUE NAME="bendOsc2OnlyButton" x="228" y="335" w="19" h="35"/>
|
||||||
|
|
||||||
|
<!------- MODULATION ----->
|
||||||
|
|
||||||
|
<VALUE NAME="lfoFrequencyKnob" x="293" y="77" d="48"/>
|
||||||
|
<VALUE NAME="lfoAmt1Knob" x="390" y="77" d="48"/>
|
||||||
|
<VALUE NAME="lfoAmt2Knob" x="488" y="77" d="48"/>
|
||||||
|
|
||||||
|
<VALUE NAME="lfoSinButton" x="309" y="162" w="19" h="35"/>
|
||||||
|
<VALUE NAME="lfoSquareButton" x="309" y="252" w="19" h="35"/>
|
||||||
|
<VALUE NAME="lfoSHButton" x="309" y="335" w="19" h="35"/>
|
||||||
|
|
||||||
|
<VALUE NAME="lfoOsc1Button" x="406" y="162" w="19" h="35"/>
|
||||||
|
<VALUE NAME="lfoOsc2Button" x="406" y="252" w="19" h="35"/>
|
||||||
|
<VALUE NAME="lfoFilterButton" x="406" y="335" w="19" h="35"/>
|
||||||
|
|
||||||
|
<VALUE NAME="lfoPwm1Button" x="504" y="162" w="19" h="35"/>
|
||||||
|
<VALUE NAME="lfoPwm2Button" x="504" y="252" w="19" h="35"/>
|
||||||
|
|
||||||
|
<!------- OSCILLATORS ----->
|
||||||
|
|
||||||
|
<VALUE NAME="osc1PitchKnob" x="593" y="77" d="48"/>
|
||||||
|
<VALUE NAME="pulseWidthKnob" x="691" y="77" d="48"/>
|
||||||
|
<VALUE NAME="osc2PitchKnob" x="788" y="77" d="48"/>
|
||||||
|
|
||||||
|
<VALUE NAME="osc1SawButton" x="587" y="162" w="19" h="35"/>
|
||||||
|
<VALUE NAME="osc1PulButton" x="632" y="162" w="19" h="35"/>
|
||||||
|
|
||||||
|
<VALUE NAME="pitchQuantButton" x="684" y="162" w="19" h="35"/>
|
||||||
|
<VALUE NAME="hardSyncButton" x="730" y="162" w="19" h="35"/>
|
||||||
|
|
||||||
|
<VALUE NAME="osc2SawButton" x="782" y="162" w="19" h="35"/>
|
||||||
|
<VALUE NAME="osc2PulButton" x="827" y="162" w="19" h="35"/>
|
||||||
|
|
||||||
|
<VALUE NAME="osc1MixKnob" x="592" y="237" d="48"/>
|
||||||
|
<VALUE NAME="noiseMixKnob" x="686" y="237" d="48"/>
|
||||||
|
<VALUE NAME="osc2MixKnob" x="783" y="237" d="48"/>
|
||||||
|
|
||||||
|
<VALUE NAME="brightnessKnob" x="581" y="324" d="48"/>
|
||||||
|
<VALUE NAME="xmodKnob" x="656" y="324" d="48"/>
|
||||||
|
|
||||||
|
<VALUE NAME="envPitchModKnob" x="723" y="324" d="48"/>
|
||||||
|
<VALUE NAME="osc2DetuneKnob" x="795" y="324" d="48"/>
|
||||||
|
|
||||||
|
<!------- FILTER ----->
|
||||||
|
|
||||||
|
<VALUE NAME="cutoffKnob" x="893" y="77" d="48"/>
|
||||||
|
<VALUE NAME="resonanceKnob" x="990" y="77" d="48"/>
|
||||||
|
<VALUE NAME="filterEnvelopeAmtKnob" x="1088" y="77" d="48"/>
|
||||||
|
<VALUE NAME="multimodeKnob" x="990" y="167" d="48"/>
|
||||||
|
|
||||||
|
<VALUE NAME="filterBPBlendButton" x="1082" y="162" w="19" h="35"/>
|
||||||
|
<VALUE NAME="filterHQButton" x="932" y="162" w="19" h="35"/>
|
||||||
|
|
||||||
|
<VALUE NAME="filterKeyFollowButton" x="887" y="162" w="19" h="35"/>
|
||||||
|
<VALUE NAME="fourPoleButton" x="1127" y="162" w="19" h="35"/>
|
||||||
|
|
||||||
|
<!------- FILTER ENVELOPE ----->
|
||||||
|
|
||||||
|
<VALUE NAME="attackKnob" x="1182" y="165" d="48"/>
|
||||||
|
<VALUE NAME="decayKnob" x="1246" y="165" d="48"/>
|
||||||
|
<VALUE NAME="sustainKnob" x="1309" y="165" d="48"/>
|
||||||
|
<VALUE NAME="releaseKnob" x="1373" y="165" d="48"/>
|
||||||
|
|
||||||
|
<!------- LOUDNESS ENVELOPE ----->
|
||||||
|
|
||||||
|
<VALUE NAME="fattackKnob" x="1182" y="75" d="48"/>
|
||||||
|
<VALUE NAME="fdecayKnob" x="1246" y="75" d="48"/>
|
||||||
|
<VALUE NAME="fsustainKnob" x="1309" y="75" d="48"/>
|
||||||
|
<VALUE NAME="freleaseKnob" x="1373" y="75" d="48"/>
|
||||||
|
|
||||||
|
<!------- VOICE VARIATION ----->
|
||||||
|
|
||||||
|
<VALUE NAME="bendLfoRateKnob" x="928" y="300" d="36"/>
|
||||||
|
<VALUE NAME="veloFltEnvKnob" x="1013" y="300" d="36"/>
|
||||||
|
<VALUE NAME="veloAmpEnvKnob" x="1111" y="300" d="36"/>
|
||||||
|
|
||||||
|
<VALUE NAME="pan1Knob" x="914" y="368" d="36"/>
|
||||||
|
<VALUE NAME="pan2Knob" x="977" y="368" d="36"/>
|
||||||
|
<VALUE NAME="pan3Knob" x="1040" y="368" d="36"/>
|
||||||
|
<VALUE NAME="pan4Knob" x="1103" y="368" d="36"/>
|
||||||
|
<VALUE NAME="pan5Knob" x="1165" y="368" d="36"/>
|
||||||
|
<VALUE NAME="pan6Knob" x="1228" y="368" d="36"/>
|
||||||
|
<VALUE NAME="pan7Knob" x="1290" y="368" d="36"/>
|
||||||
|
<VALUE NAME="pan8Knob" x="1353" y="368" d="36"/>
|
||||||
|
|
||||||
|
<VALUE NAME="filterDetuneKnob" x="1228" y="300" d="36"/>
|
||||||
|
<VALUE NAME="portamentoDetuneKnob" x="1291" y="300" d="36"/>
|
||||||
|
<VALUE NAME="envelopeDetuneKnob" x="1353" y="300" d="36"/>
|
||||||
|
</PROPERTIES>
|
BIN
Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/knob.png
Normal file
After Width: | Height: | Size: 61 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/knob@2x.png
Normal file
After Width: | Height: | Size: 828 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/knob@2x_old.png
Executable file
After Width: | Height: | Size: 1.3 MiB |
BIN
Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/legato.png
Normal file
After Width: | Height: | Size: 8.1 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/legato@2x.png
Executable file
After Width: | Height: | Size: 1.4 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/main.png
Normal file
After Width: | Height: | Size: 225 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/main@2x.png
Executable file
After Width: | Height: | Size: 120 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/menu.png
Executable file
After Width: | Height: | Size: 1.8 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/menu@2x.png
Executable file
After Width: | Height: | Size: 1.8 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/voices.png
Normal file
After Width: | Height: | Size: 7.9 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/voices@2x.png
Executable file
After Width: | Height: | Size: 1.1 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/button.png
Executable file
After Width: | Height: | Size: 2.4 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/button@2x.png
Executable file
After Width: | Height: | Size: 2.7 KiB |
117
Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/coords.xml
Executable file
|
@ -0,0 +1,117 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<PROPERTIES>
|
||||||
|
<VALUE NAME="guisize" x="1087" y="442"/>
|
||||||
|
<VALUE NAME="menu" x="28" y="30" d="20"/>
|
||||||
|
|
||||||
|
<!------- MASTER ----->
|
||||||
|
|
||||||
|
<VALUE NAME="volumeKnob" x="53" y="120" d="40"/>
|
||||||
|
<VALUE NAME="tuneKnob" x="116" y="120" d="40"/>
|
||||||
|
<VALUE NAME="transposeKnob" x="181" y="120" d="40"/>
|
||||||
|
|
||||||
|
<!------- GLOBAL ----->
|
||||||
|
|
||||||
|
<VALUE NAME="voiceDetuneKnob" x="58" y="241" d="40" w="28" h="35"/>
|
||||||
|
<VALUE NAME="unisonButton" x="125" y="251" w="28" h="35"/>
|
||||||
|
<VALUE NAME="portamentoKnob" x="175" y="241" d="40"/>
|
||||||
|
|
||||||
|
<VALUE NAME="voiceSwitch" x="172" y="311" w="38" h="32"/>
|
||||||
|
<VALUE NAME="legatoSwitch" x="66" y="311" w="89" h="32"/>
|
||||||
|
|
||||||
|
<VALUE NAME="asPlayedAllocButton" x="65" y="372" d="32" w="28" h="35"/>
|
||||||
|
<VALUE NAME="midiLearnButton" x="126" y="372" d="40" w="28" h="35"/>
|
||||||
|
<VALUE NAME="midiUnlearnButton" x="185" y="372" d="40" w="28" h="35"/>
|
||||||
|
|
||||||
|
<!------- CONTROL ----->
|
||||||
|
|
||||||
|
<VALUE NAME="bendOsc2OnlyButton" x="321" y="354" d="32" w="28" h="35"/>
|
||||||
|
<VALUE NAME="bendRangeButton" x="267" y="354" d="32" w="28" h="35"/>
|
||||||
|
|
||||||
|
<VALUE NAME="bendLfoRateKnob" x="369" y="345" d="40" w="28" h="35"/>
|
||||||
|
<VALUE NAME="veloFltEnvKnob" x="433" y="345" d="40" w="28" h="35"/>
|
||||||
|
<VALUE NAME="veloAmpEnvKnob" x="491" y="345" d="40" w="28" h="35"/>
|
||||||
|
|
||||||
|
<!------- OSCILLATORS ----->
|
||||||
|
|
||||||
|
<VALUE NAME="osc1PitchKnob" x="276" y="40" d="40"/>
|
||||||
|
<VALUE NAME="pulseWidthKnob" x="339" y="40" d="40"/>
|
||||||
|
<VALUE NAME="osc2PitchKnob" x="402" y="40" d="40"/>
|
||||||
|
|
||||||
|
<VALUE NAME="xmodKnob" x="339" y="168" d="40"/>
|
||||||
|
<VALUE NAME="osc2DetuneKnob" x="339" y="104" d="40"/>
|
||||||
|
<VALUE NAME="pitchQuantButton" x="407" y="178" w="28" h="35"/>
|
||||||
|
|
||||||
|
<VALUE NAME="envPitchModKnob" x="381" y="232" d="40"/>
|
||||||
|
<VALUE NAME="brightnessKnob" x="296" y="232" d="40"/>
|
||||||
|
|
||||||
|
<!------- MIX ----->
|
||||||
|
|
||||||
|
<VALUE NAME="osc1MixKnob" x="492" y="40" d="40"/>
|
||||||
|
<VALUE NAME="osc2MixKnob" x="492" y="132" d="40"/>
|
||||||
|
<VALUE NAME="noiseMixKnob" x="492" y="224" d="40"/>
|
||||||
|
|
||||||
|
<!------- FILTER ----->
|
||||||
|
|
||||||
|
<VALUE NAME="cutoffKnob" x="582" y="40" d="40"/>
|
||||||
|
<VALUE NAME="resonanceKnob" x="640" y="40" d="40"/>
|
||||||
|
<VALUE NAME="filterEnvelopeAmtKnob" x="704" y="40" d="40"/>
|
||||||
|
|
||||||
|
<VALUE NAME="multimodeKnob" x="640" y="104" d="40"/>
|
||||||
|
<VALUE NAME="filterKeyFollowButton" x="573" y="110" w="28" h="35"/>
|
||||||
|
|
||||||
|
<VALUE NAME="filterBPBlendButton" x="697" y="110" w="28" h="35"/>
|
||||||
|
<VALUE NAME="fourPoleButton" x="728" y="110" w="28" h="35"/>
|
||||||
|
<VALUE NAME="filterHQButton" x="604" y="110" w="28" h="35"/>
|
||||||
|
|
||||||
|
<!------- ENVELOPES ----->
|
||||||
|
|
||||||
|
<VALUE NAME="attackKnob" x="793" y="132" d="40"/>
|
||||||
|
<VALUE NAME="decayKnob" x="855" y="132" d="40"/>
|
||||||
|
<VALUE NAME="sustainKnob" x="918" y="132" d="40"/>
|
||||||
|
<VALUE NAME="releaseKnob" x="982" y="132" d="40"/>
|
||||||
|
|
||||||
|
<VALUE NAME="fattackKnob" x="793" y="40" d="40"/>
|
||||||
|
<VALUE NAME="fdecayKnob" x="855" y="40" d="40"/>
|
||||||
|
<VALUE NAME="fsustainKnob" x="918" y="40" d="40"/>
|
||||||
|
<VALUE NAME="freleaseKnob" x="982" y="40" d="40"/>
|
||||||
|
|
||||||
|
<!------- MODULATION ----->
|
||||||
|
|
||||||
|
<VALUE NAME="lfoFrequencyKnob" x="581" y="207" d="40"/>
|
||||||
|
<VALUE NAME="lfoAmt1Knob" x="640" y="207" d="40"/>
|
||||||
|
<VALUE NAME="lfoAmt2Knob" x="704" y="207" d="40"/>
|
||||||
|
|
||||||
|
<VALUE NAME="lfoSinButton" x="587" y="269" d="40" w="28" h="35"/>
|
||||||
|
<VALUE NAME="lfoSquareButton" x="587" y="323" d="40" w="28" h="35"/>
|
||||||
|
<VALUE NAME="lfoSHButton" x="587" y="378" d="40" w="28" h="35"/>
|
||||||
|
|
||||||
|
<VALUE NAME="lfoOsc1Button" x="651" y="269" w="28" h="35"/>
|
||||||
|
<VALUE NAME="lfoOsc2Button" x="651" y="323" w="28" h="35"/>
|
||||||
|
<VALUE NAME="lfoFilterButton" x="651" y="378" w="28" h="35"/>
|
||||||
|
|
||||||
|
<VALUE NAME="lfoPwm1Button" x="714" y="269" w="28" h="35"/>
|
||||||
|
<VALUE NAME="lfoPwm2Button" x="714" y="323" w="28" h="35"/>
|
||||||
|
|
||||||
|
<VALUE NAME="hardSyncButton" x="282" y="178" w="28" h="35"/>
|
||||||
|
<VALUE NAME="osc1SawButton" x="265" y="114" w="28" h="35"/>
|
||||||
|
<VALUE NAME="osc2SawButton" x="394" y="114" w="28" h="35"/>
|
||||||
|
|
||||||
|
<VALUE NAME="osc1PulButton" x="296" y="114" w="28" h="35"/>
|
||||||
|
<VALUE NAME="osc2PulButton" x="425" y="114" w="28" h="35"/>
|
||||||
|
|
||||||
|
<!------- VOICE VARIATION ----->
|
||||||
|
|
||||||
|
<VALUE NAME="filterDetuneKnob" x="819" y="240" d="32" w="28" h="35"/>
|
||||||
|
<VALUE NAME="envelopeDetuneKnob" x="965" y="240" d="32" w="28" h="35"/>
|
||||||
|
<VALUE NAME="portamentoDetuneKnob" x="892" y="240" d="32" w="28" h="35"/>
|
||||||
|
|
||||||
|
<VALUE NAME="pan1Knob" x="801" y="323" d="32"/>
|
||||||
|
<VALUE NAME="pan2Knob" x="860" y="323" d="32"/>
|
||||||
|
<VALUE NAME="pan3Knob" x="924" y="323" d="32"/>
|
||||||
|
<VALUE NAME="pan4Knob" x="987" y="323" d="32"/>
|
||||||
|
|
||||||
|
<VALUE NAME="pan5Knob" x="801" y="376" d="32"/>
|
||||||
|
<VALUE NAME="pan6Knob" x="860" y="376" d="32"/>
|
||||||
|
<VALUE NAME="pan7Knob" x="924" y="376" d="32"/>
|
||||||
|
<VALUE NAME="pan8Knob" x="987" y="376" d="32"/>
|
||||||
|
</PROPERTIES>
|
BIN
Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/knob.png
Executable file
After Width: | Height: | Size: 214 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/knob@2x.png
Executable file
After Width: | Height: | Size: 1.2 MiB |
BIN
Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/legato.png
Executable file
After Width: | Height: | Size: 9.9 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/legato@2x.png
Executable file
After Width: | Height: | Size: 2.3 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/main.png
Executable file
After Width: | Height: | Size: 176 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/main@2x.png
Executable file
After Width: | Height: | Size: 107 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/menu.png
Executable file
After Width: | Height: | Size: 1.8 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/menu@2x.png
Executable file
After Width: | Height: | Size: 1.8 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/voices.png
Executable file
After Width: | Height: | Size: 4.4 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/voices@2x.png
Executable file
After Width: | Height: | Size: 4.4 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/button.png
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/button@2x.png
Executable file
After Width: | Height: | Size: 5.4 KiB |
116
Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/coords.xml
Executable file
|
@ -0,0 +1,116 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<PROPERTIES>
|
||||||
|
<VALUE NAME="guisize" x="1440" y="450"/>
|
||||||
|
<VALUE NAME="menu" x="14" y="25" d="20"/>
|
||||||
|
|
||||||
|
<!------- MANUAL ----->
|
||||||
|
|
||||||
|
<VALUE NAME="volumeKnob" x="51" y="77" d="48"/>
|
||||||
|
|
||||||
|
<VALUE NAME="asPlayedAllocButton" x="25" y="162" w="19" h="35"/>
|
||||||
|
<VALUE NAME="midiLearnButton" x="74" y="162" w="19" h="35"/>
|
||||||
|
<VALUE NAME="midiUnlearnButton" x="122" y="162" w="19" h="35"/>
|
||||||
|
|
||||||
|
<VALUE NAME="tuneKnob" x="25" y="252" d="48"/>
|
||||||
|
<VALUE NAME="transposeKnob" x="85" y="252" d="48"/>
|
||||||
|
|
||||||
|
<VALUE NAME="voiceSwitch" x="124" y="338" w="17" h="24"/>
|
||||||
|
<VALUE NAME="legatoSwitch" x="25" y="338" w="65" h="24"/>
|
||||||
|
|
||||||
|
<!------- CONTROL ----->
|
||||||
|
|
||||||
|
<VALUE NAME="portamentoKnob" x="185" y="77" d="48"/>
|
||||||
|
<VALUE NAME="unisonButton" x="205" y="162" w="19" h="35"/>
|
||||||
|
<VALUE NAME="voiceDetuneKnob" x="185" y="252" d="48"/>
|
||||||
|
|
||||||
|
<VALUE NAME="bendRangeButton" x="183" y="335" w="19" h="35"/>
|
||||||
|
<VALUE NAME="bendOsc2OnlyButton" x="228" y="335" w="19" h="35"/>
|
||||||
|
|
||||||
|
<!------- MODULATION ----->
|
||||||
|
|
||||||
|
<VALUE NAME="lfoFrequencyKnob" x="293" y="77" d="48"/>
|
||||||
|
<VALUE NAME="lfoAmt1Knob" x="390" y="77" d="48"/>
|
||||||
|
<VALUE NAME="lfoAmt2Knob" x="488" y="77" d="48"/>
|
||||||
|
|
||||||
|
<VALUE NAME="lfoSinButton" x="309" y="162" w="19" h="35"/>
|
||||||
|
<VALUE NAME="lfoSquareButton" x="309" y="252" w="19" h="35"/>
|
||||||
|
<VALUE NAME="lfoSHButton" x="309" y="335" w="19" h="35"/>
|
||||||
|
|
||||||
|
<VALUE NAME="lfoOsc1Button" x="406" y="162" w="19" h="35"/>
|
||||||
|
<VALUE NAME="lfoOsc2Button" x="406" y="252" w="19" h="35"/>
|
||||||
|
<VALUE NAME="lfoFilterButton" x="406" y="335" w="19" h="35"/>
|
||||||
|
|
||||||
|
<VALUE NAME="lfoPwm1Button" x="504" y="162" w="19" h="35"/>
|
||||||
|
<VALUE NAME="lfoPwm2Button" x="504" y="252" w="19" h="35"/>
|
||||||
|
|
||||||
|
<!------- OSCILLATORS ----->
|
||||||
|
|
||||||
|
<VALUE NAME="osc1PitchKnob" x="593" y="77" d="48"/>
|
||||||
|
<VALUE NAME="pulseWidthKnob" x="691" y="77" d="48"/>
|
||||||
|
<VALUE NAME="osc2PitchKnob" x="788" y="77" d="48"/>
|
||||||
|
|
||||||
|
<VALUE NAME="osc1SawButton" x="587" y="162" w="19" h="35"/>
|
||||||
|
<VALUE NAME="osc1PulButton" x="632" y="162" w="19" h="35"/>
|
||||||
|
|
||||||
|
<VALUE NAME="pitchQuantButton" x="684" y="162" w="19" h="35"/>
|
||||||
|
<VALUE NAME="hardSyncButton" x="730" y="162" w="19" h="35"/>
|
||||||
|
|
||||||
|
<VALUE NAME="osc2SawButton" x="782" y="162" w="19" h="35"/>
|
||||||
|
<VALUE NAME="osc2PulButton" x="827" y="162" w="19" h="35"/>
|
||||||
|
|
||||||
|
<VALUE NAME="osc1MixKnob" x="592" y="237" d="48"/>
|
||||||
|
<VALUE NAME="noiseMixKnob" x="686" y="237" d="48"/>
|
||||||
|
<VALUE NAME="osc2MixKnob" x="783" y="237" d="48"/>
|
||||||
|
|
||||||
|
<VALUE NAME="brightnessKnob" x="581" y="324" d="48"/>
|
||||||
|
<VALUE NAME="xmodKnob" x="656" y="324" d="48"/>
|
||||||
|
|
||||||
|
<VALUE NAME="envPitchModKnob" x="723" y="324" d="48"/>
|
||||||
|
<VALUE NAME="osc2DetuneKnob" x="795" y="324" d="48"/>
|
||||||
|
|
||||||
|
<!------- FILTER ----->
|
||||||
|
|
||||||
|
<VALUE NAME="cutoffKnob" x="893" y="77" d="48"/>
|
||||||
|
<VALUE NAME="resonanceKnob" x="990" y="77" d="48"/>
|
||||||
|
<VALUE NAME="filterEnvelopeAmtKnob" x="1088" y="77" d="48"/>
|
||||||
|
<VALUE NAME="multimodeKnob" x="990" y="167" d="48"/>
|
||||||
|
|
||||||
|
<VALUE NAME="filterBPBlendButton" x="1082" y="162" w="19" h="35"/>
|
||||||
|
<VALUE NAME="filterHQButton" x="932" y="162" w="19" h="35"/>
|
||||||
|
|
||||||
|
<VALUE NAME="filterKeyFollowButton" x="887" y="162" w="19" h="35"/>
|
||||||
|
<VALUE NAME="fourPoleButton" x="1127" y="162" w="19" h="35"/>
|
||||||
|
|
||||||
|
<!------- FILTER ENVELOPE ----->
|
||||||
|
|
||||||
|
<VALUE NAME="attackKnob" x="1182" y="165" d="48"/>
|
||||||
|
<VALUE NAME="decayKnob" x="1246" y="165" d="48"/>
|
||||||
|
<VALUE NAME="sustainKnob" x="1309" y="165" d="48"/>
|
||||||
|
<VALUE NAME="releaseKnob" x="1373" y="165" d="48"/>
|
||||||
|
|
||||||
|
<!------- LOUDNESS ENVELOPE ----->
|
||||||
|
|
||||||
|
<VALUE NAME="fattackKnob" x="1182" y="75" d="48"/>
|
||||||
|
<VALUE NAME="fdecayKnob" x="1246" y="75" d="48"/>
|
||||||
|
<VALUE NAME="fsustainKnob" x="1309" y="75" d="48"/>
|
||||||
|
<VALUE NAME="freleaseKnob" x="1373" y="75" d="48"/>
|
||||||
|
|
||||||
|
<!------- VOICE VARIATION ----->
|
||||||
|
|
||||||
|
<VALUE NAME="bendLfoRateKnob" x="928" y="300" d="36"/>
|
||||||
|
<VALUE NAME="veloFltEnvKnob" x="1013" y="300" d="36"/>
|
||||||
|
<VALUE NAME="veloAmpEnvKnob" x="1111" y="300" d="36"/>
|
||||||
|
|
||||||
|
<VALUE NAME="pan1Knob" x="914" y="368" d="36"/>
|
||||||
|
<VALUE NAME="pan2Knob" x="977" y="368" d="36"/>
|
||||||
|
<VALUE NAME="pan3Knob" x="1040" y="368" d="36"/>
|
||||||
|
<VALUE NAME="pan4Knob" x="1103" y="368" d="36"/>
|
||||||
|
<VALUE NAME="pan5Knob" x="1165" y="368" d="36"/>
|
||||||
|
<VALUE NAME="pan6Knob" x="1228" y="368" d="36"/>
|
||||||
|
<VALUE NAME="pan7Knob" x="1290" y="368" d="36"/>
|
||||||
|
<VALUE NAME="pan8Knob" x="1353" y="368" d="36"/>
|
||||||
|
|
||||||
|
<VALUE NAME="filterDetuneKnob" x="1228" y="300" d="36"/>
|
||||||
|
<VALUE NAME="portamentoDetuneKnob" x="1291" y="300" d="36"/>
|
||||||
|
<VALUE NAME="envelopeDetuneKnob" x="1353" y="300" d="36"/>
|
||||||
|
</PROPERTIES>
|
BIN
Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/knob.png
Executable file
After Width: | Height: | Size: 159 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/knob@2x.png
Executable file
After Width: | Height: | Size: 1.3 MiB |
BIN
Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/legato.png
Executable file
After Width: | Height: | Size: 1.4 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/legato@2x.png
Executable file
After Width: | Height: | Size: 1.4 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/main.png
Executable file
After Width: | Height: | Size: 62 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/main@2x.png
Executable file
After Width: | Height: | Size: 62 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/menu.png
Executable file
After Width: | Height: | Size: 1.8 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/menu@2x.png
Executable file
After Width: | Height: | Size: 1.8 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/voices.png
Executable file
After Width: | Height: | Size: 1.1 KiB |
BIN
Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/voices@2x.png
Executable file
After Width: | Height: | Size: 1.1 KiB |
|
@ -0,0 +1,946 @@
|
||||||
|
/*
|
||||||
|
==============================================================================
|
||||||
|
|
||||||
|
This file is part of the JUCE library.
|
||||||
|
Copyright (c) 2017 - ROLI Ltd.
|
||||||
|
|
||||||
|
JUCE is an open source library subject to commercial or open-source
|
||||||
|
licensing.
|
||||||
|
|
||||||
|
By using JUCE, you agree to the terms of both the JUCE 5 End-User License
|
||||||
|
Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
|
||||||
|
27th April 2017).
|
||||||
|
|
||||||
|
End User License Agreement: www.juce.com/juce-5-licence
|
||||||
|
Privacy Policy: www.juce.com/juce-5-privacy-policy
|
||||||
|
|
||||||
|
Or: You may also use this code under the terms of the GPL v3 (see
|
||||||
|
www.gnu.org/licenses).
|
||||||
|
|
||||||
|
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||||
|
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||||
|
DISCLAIMED.
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if JUCE_MODULE_AVAILABLE_juce_audio_plugin_client
|
||||||
|
extern juce::AudioProcessor* JUCE_API JUCE_CALLTYPE createPluginFilterOfType (juce::AudioProcessor::WrapperType type);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace juce
|
||||||
|
{
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
/**
|
||||||
|
An object that creates and plays a standalone instance of an AudioProcessor.
|
||||||
|
|
||||||
|
The object will create your processor using the same createPluginFilter()
|
||||||
|
function that the other plugin wrappers use, and will run it through the
|
||||||
|
computer's audio/MIDI devices using AudioDeviceManager and AudioProcessorPlayer.
|
||||||
|
|
||||||
|
@tags{Audio}
|
||||||
|
*/
|
||||||
|
class StandalonePluginHolder : private AudioIODeviceCallback,
|
||||||
|
private Timer,
|
||||||
|
private Value::Listener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//==============================================================================
|
||||||
|
/** Structure used for the number of inputs and outputs. */
|
||||||
|
struct PluginInOuts { short numIns, numOuts; };
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
/** Creates an instance of the default plugin.
|
||||||
|
|
||||||
|
The settings object can be a PropertySet that the class should use to store its
|
||||||
|
settings - the takeOwnershipOfSettings indicates whether this object will delete
|
||||||
|
the settings automatically when no longer needed. The settings can also be nullptr.
|
||||||
|
|
||||||
|
A default device name can be passed in.
|
||||||
|
|
||||||
|
Preferably a complete setup options object can be used, which takes precedence over
|
||||||
|
the preferredDefaultDeviceName and allows you to select the input & output device names,
|
||||||
|
sample rate, buffer size etc.
|
||||||
|
|
||||||
|
In all instances, the settingsToUse will take precedence over the "preferred" options if not null.
|
||||||
|
*/
|
||||||
|
StandalonePluginHolder (PropertySet* settingsToUse,
|
||||||
|
bool takeOwnershipOfSettings = true,
|
||||||
|
const String& preferredDefaultDeviceName = String(),
|
||||||
|
const AudioDeviceManager::AudioDeviceSetup* preferredSetupOptions = nullptr,
|
||||||
|
const Array<PluginInOuts>& channels = Array<PluginInOuts>(),
|
||||||
|
#if JUCE_ANDROID || JUCE_IOS
|
||||||
|
bool shouldAutoOpenMidiDevices = true
|
||||||
|
#else
|
||||||
|
bool shouldAutoOpenMidiDevices = true
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
|
||||||
|
: settings (settingsToUse, takeOwnershipOfSettings),
|
||||||
|
channelConfiguration (channels),
|
||||||
|
autoOpenMidiDevices (shouldAutoOpenMidiDevices)
|
||||||
|
{
|
||||||
|
shouldMuteInput.addListener (this);
|
||||||
|
shouldMuteInput = ! isInterAppAudioConnected();
|
||||||
|
|
||||||
|
createPlugin();
|
||||||
|
|
||||||
|
auto inChannels = (channelConfiguration.size() > 0 ? channelConfiguration[0].numIns
|
||||||
|
: processor->getMainBusNumInputChannels());
|
||||||
|
|
||||||
|
if (preferredSetupOptions != nullptr)
|
||||||
|
options.reset (new AudioDeviceManager::AudioDeviceSetup (*preferredSetupOptions));
|
||||||
|
|
||||||
|
auto audioInputRequired = (inChannels > 0);
|
||||||
|
|
||||||
|
if (audioInputRequired && RuntimePermissions::isRequired (RuntimePermissions::recordAudio)
|
||||||
|
&& ! RuntimePermissions::isGranted (RuntimePermissions::recordAudio))
|
||||||
|
RuntimePermissions::request (RuntimePermissions::recordAudio,
|
||||||
|
[this, preferredDefaultDeviceName] (bool granted) { init (granted, preferredDefaultDeviceName); });
|
||||||
|
else
|
||||||
|
init (audioInputRequired, preferredDefaultDeviceName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void init (bool enableAudioInput, const String& preferredDefaultDeviceName)
|
||||||
|
{
|
||||||
|
setupAudioDevices (enableAudioInput, preferredDefaultDeviceName, options.get());
|
||||||
|
reloadPluginState();
|
||||||
|
startPlaying();
|
||||||
|
|
||||||
|
if (autoOpenMidiDevices)
|
||||||
|
startTimer (500);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~StandalonePluginHolder() override
|
||||||
|
{
|
||||||
|
stopTimer();
|
||||||
|
|
||||||
|
deletePlugin();
|
||||||
|
shutDownAudioDevices();
|
||||||
|
}
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
virtual void createPlugin()
|
||||||
|
{
|
||||||
|
#if JUCE_MODULE_AVAILABLE_juce_audio_plugin_client
|
||||||
|
processor.reset (::createPluginFilterOfType (AudioProcessor::wrapperType_Standalone));
|
||||||
|
#else
|
||||||
|
AudioProcessor::setTypeOfNextNewPlugin (AudioProcessor::wrapperType_Standalone);
|
||||||
|
processor.reset (createPluginFilter());
|
||||||
|
AudioProcessor::setTypeOfNextNewPlugin (AudioProcessor::wrapperType_Undefined);
|
||||||
|
#endif
|
||||||
|
jassert (processor != nullptr); // Your createPluginFilter() function must return a valid object!
|
||||||
|
|
||||||
|
processor->disableNonMainBuses();
|
||||||
|
processor->setRateAndBufferSizeDetails (44100, 512);
|
||||||
|
|
||||||
|
int inChannels = (channelConfiguration.size() > 0 ? channelConfiguration[0].numIns
|
||||||
|
: processor->getMainBusNumInputChannels());
|
||||||
|
|
||||||
|
int outChannels = (channelConfiguration.size() > 0 ? channelConfiguration[0].numOuts
|
||||||
|
: processor->getMainBusNumOutputChannels());
|
||||||
|
|
||||||
|
processorHasPotentialFeedbackLoop = (inChannels > 0 && outChannels > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void deletePlugin()
|
||||||
|
{
|
||||||
|
stopPlaying();
|
||||||
|
processor = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static String getFilePatterns (const String& fileSuffix)
|
||||||
|
{
|
||||||
|
if (fileSuffix.isEmpty())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
return (fileSuffix.startsWithChar ('.') ? "*" : "*.") + fileSuffix;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
Value& getMuteInputValue() { return shouldMuteInput; }
|
||||||
|
bool getProcessorHasPotentialFeedbackLoop() const { return processorHasPotentialFeedbackLoop; }
|
||||||
|
void valueChanged (Value& value) override { muteInput = (bool) value.getValue(); }
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
File getLastFile() const
|
||||||
|
{
|
||||||
|
File f;
|
||||||
|
|
||||||
|
if (settings != nullptr)
|
||||||
|
f = File (settings->getValue ("lastStateFile"));
|
||||||
|
|
||||||
|
if (f == File())
|
||||||
|
f = File::getSpecialLocation (File::userDocumentsDirectory);
|
||||||
|
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setLastFile (const FileChooser& fc)
|
||||||
|
{
|
||||||
|
if (settings != nullptr)
|
||||||
|
settings->setValue ("lastStateFile", fc.getResult().getFullPathName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Pops up a dialog letting the user save the processor's state to a file. */
|
||||||
|
void askUserToSaveState (const String& fileSuffix = String())
|
||||||
|
{
|
||||||
|
#if JUCE_MODAL_LOOPS_PERMITTED
|
||||||
|
FileChooser fc (TRANS("Save current state"), getLastFile(), getFilePatterns (fileSuffix));
|
||||||
|
|
||||||
|
if (fc.browseForFileToSave (true))
|
||||||
|
{
|
||||||
|
setLastFile (fc);
|
||||||
|
|
||||||
|
MemoryBlock data;
|
||||||
|
processor->getStateInformation (data);
|
||||||
|
|
||||||
|
if (! fc.getResult().replaceWithData (data.getData(), data.getSize()))
|
||||||
|
AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon,
|
||||||
|
TRANS("Error whilst saving"),
|
||||||
|
TRANS("Couldn't write to the specified file!"));
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
ignoreUnused (fileSuffix);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Pops up a dialog letting the user re-load the processor's state from a file. */
|
||||||
|
void askUserToLoadState (const String& fileSuffix = String())
|
||||||
|
{
|
||||||
|
#if JUCE_MODAL_LOOPS_PERMITTED
|
||||||
|
FileChooser fc (TRANS("Load a saved state"), getLastFile(), getFilePatterns (fileSuffix));
|
||||||
|
|
||||||
|
if (fc.browseForFileToOpen())
|
||||||
|
{
|
||||||
|
setLastFile (fc);
|
||||||
|
|
||||||
|
MemoryBlock data;
|
||||||
|
|
||||||
|
if (fc.getResult().loadFileAsData (data))
|
||||||
|
processor->setStateInformation (data.getData(), (int) data.getSize());
|
||||||
|
else
|
||||||
|
AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon,
|
||||||
|
TRANS("Error whilst loading"),
|
||||||
|
TRANS("Couldn't read from the specified file!"));
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
ignoreUnused (fileSuffix);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
void startPlaying()
|
||||||
|
{
|
||||||
|
player.setProcessor (processor.get());
|
||||||
|
|
||||||
|
#if JucePlugin_Enable_IAA && JUCE_IOS
|
||||||
|
if (auto device = dynamic_cast<iOSAudioIODevice*> (deviceManager.getCurrentAudioDevice()))
|
||||||
|
{
|
||||||
|
processor->setPlayHead (device->getAudioPlayHead());
|
||||||
|
device->setMidiMessageCollector (&player.getMidiMessageCollector());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void stopPlaying()
|
||||||
|
{
|
||||||
|
player.setProcessor (nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
/** Shows an audio properties dialog box modally. */
|
||||||
|
void showAudioSettingsDialog()
|
||||||
|
{
|
||||||
|
DialogWindow::LaunchOptions o;
|
||||||
|
|
||||||
|
int maxNumInputs = 0, maxNumOutputs = 0;
|
||||||
|
|
||||||
|
if (channelConfiguration.size() > 0)
|
||||||
|
{
|
||||||
|
auto& defaultConfig = channelConfiguration.getReference (0);
|
||||||
|
|
||||||
|
maxNumInputs = jmax (0, (int) defaultConfig.numIns);
|
||||||
|
maxNumOutputs = jmax (0, (int) defaultConfig.numOuts);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto* bus = processor->getBus (true, 0))
|
||||||
|
maxNumInputs = jmax (0, bus->getDefaultLayout().size());
|
||||||
|
|
||||||
|
if (auto* bus = processor->getBus (false, 0))
|
||||||
|
maxNumOutputs = jmax (0, bus->getDefaultLayout().size());
|
||||||
|
|
||||||
|
o.content.setOwned (new SettingsComponent (*this, deviceManager, maxNumInputs, maxNumOutputs));
|
||||||
|
//#if JUCE_MAC
|
||||||
|
o.content->setSize (500, 400);
|
||||||
|
//#endif
|
||||||
|
//#if ! JUCE_MAC
|
||||||
|
// o.content->setSize (500, 450);
|
||||||
|
//#endif
|
||||||
|
o.dialogTitle = TRANS("Audio/MIDI Settings");
|
||||||
|
o.dialogBackgroundColour = o.content->getLookAndFeel().findColour (ResizableWindow::backgroundColourId);
|
||||||
|
o.escapeKeyTriggersCloseButton = true;
|
||||||
|
o.useNativeTitleBar = true;
|
||||||
|
o.resizable = false;
|
||||||
|
|
||||||
|
o.launchAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
void saveAudioDeviceState()
|
||||||
|
{
|
||||||
|
if (settings != nullptr)
|
||||||
|
{
|
||||||
|
auto xml = deviceManager.createStateXml();
|
||||||
|
|
||||||
|
settings->setValue ("audioSetup", xml.get());
|
||||||
|
|
||||||
|
#if ! (JUCE_IOS || JUCE_ANDROID)
|
||||||
|
settings->setValue ("shouldMuteInput", (bool) shouldMuteInput.getValue());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void reloadAudioDeviceState (bool enableAudioInput,
|
||||||
|
const String& preferredDefaultDeviceName,
|
||||||
|
const AudioDeviceManager::AudioDeviceSetup* preferredSetupOptions)
|
||||||
|
{
|
||||||
|
std::unique_ptr<XmlElement> savedState;
|
||||||
|
|
||||||
|
if (settings != nullptr)
|
||||||
|
{
|
||||||
|
savedState = settings->getXmlValue ("audioSetup");
|
||||||
|
|
||||||
|
#if ! (JUCE_IOS || JUCE_ANDROID)
|
||||||
|
shouldMuteInput.setValue (settings->getBoolValue ("shouldMuteInput", true));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
auto totalInChannels = processor->getMainBusNumInputChannels();
|
||||||
|
auto totalOutChannels = processor->getMainBusNumOutputChannels();
|
||||||
|
|
||||||
|
if (channelConfiguration.size() > 0)
|
||||||
|
{
|
||||||
|
auto defaultConfig = channelConfiguration.getReference (0);
|
||||||
|
totalInChannels = defaultConfig.numIns;
|
||||||
|
totalOutChannels = defaultConfig.numOuts;
|
||||||
|
}
|
||||||
|
|
||||||
|
deviceManager.initialise (enableAudioInput ? totalInChannels : 0,
|
||||||
|
totalOutChannels,
|
||||||
|
savedState.get(),
|
||||||
|
true,
|
||||||
|
preferredDefaultDeviceName,
|
||||||
|
preferredSetupOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
void savePluginState()
|
||||||
|
{
|
||||||
|
if (settings != nullptr && processor != nullptr)
|
||||||
|
{
|
||||||
|
MemoryBlock data;
|
||||||
|
processor->getStateInformation (data);
|
||||||
|
|
||||||
|
settings->setValue ("filterState", data.toBase64Encoding());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void reloadPluginState()
|
||||||
|
{
|
||||||
|
if (settings != nullptr)
|
||||||
|
{
|
||||||
|
MemoryBlock data;
|
||||||
|
|
||||||
|
if (data.fromBase64Encoding (settings->getValue ("filterState")) && data.getSize() > 0)
|
||||||
|
processor->setStateInformation (data.getData(), (int) data.getSize());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
void switchToHostApplication()
|
||||||
|
{
|
||||||
|
#if JUCE_IOS
|
||||||
|
if (auto device = dynamic_cast<iOSAudioIODevice*> (deviceManager.getCurrentAudioDevice()))
|
||||||
|
device->switchApplication();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isInterAppAudioConnected()
|
||||||
|
{
|
||||||
|
#if JUCE_IOS
|
||||||
|
if (auto device = dynamic_cast<iOSAudioIODevice*> (deviceManager.getCurrentAudioDevice()))
|
||||||
|
return device->isInterAppAudioConnected();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if JUCE_MODULE_AVAILABLE_juce_gui_basics
|
||||||
|
Image getIAAHostIcon (int size)
|
||||||
|
{
|
||||||
|
#if JUCE_IOS && JucePlugin_Enable_IAA
|
||||||
|
if (auto device = dynamic_cast<iOSAudioIODevice*> (deviceManager.getCurrentAudioDevice()))
|
||||||
|
return device->getIcon (size);
|
||||||
|
#else
|
||||||
|
ignoreUnused (size);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static StandalonePluginHolder* getInstance();
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
OptionalScopedPointer<PropertySet> settings;
|
||||||
|
std::unique_ptr<AudioProcessor> processor;
|
||||||
|
AudioDeviceManager deviceManager;
|
||||||
|
AudioProcessorPlayer player;
|
||||||
|
Array<PluginInOuts> channelConfiguration;
|
||||||
|
|
||||||
|
// avoid feedback loop by default
|
||||||
|
bool processorHasPotentialFeedbackLoop = true;
|
||||||
|
std::atomic<bool> muteInput { true };
|
||||||
|
Value shouldMuteInput;
|
||||||
|
AudioBuffer<float> emptyBuffer;
|
||||||
|
bool autoOpenMidiDevices;
|
||||||
|
|
||||||
|
std::unique_ptr<AudioDeviceManager::AudioDeviceSetup> options;
|
||||||
|
Array<MidiDeviceInfo> lastMidiDevices;
|
||||||
|
|
||||||
|
private:
|
||||||
|
//==============================================================================
|
||||||
|
class SettingsComponent : public Component
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SettingsComponent (StandalonePluginHolder& pluginHolder,
|
||||||
|
AudioDeviceManager& deviceManagerToUse,
|
||||||
|
int maxAudioInputChannels,
|
||||||
|
int maxAudioOutputChannels)
|
||||||
|
: owner (pluginHolder),
|
||||||
|
deviceSelector (deviceManagerToUse,
|
||||||
|
0, maxAudioInputChannels,
|
||||||
|
0, maxAudioOutputChannels,
|
||||||
|
true,
|
||||||
|
false, // disables MIDI Out // (pluginHolder.processor.get() != nullptr && pluginHolder.processor->producesMidi()),
|
||||||
|
true, false),
|
||||||
|
shouldMuteLabel ("Feedback Loop:", "Feedback Loop:"),
|
||||||
|
shouldMuteButton ("Mute audio input")
|
||||||
|
{
|
||||||
|
setOpaque (true);
|
||||||
|
|
||||||
|
shouldMuteButton.setClickingTogglesState (true);
|
||||||
|
shouldMuteButton.getToggleStateValue().referTo (owner.shouldMuteInput);
|
||||||
|
|
||||||
|
addAndMakeVisible (deviceSelector);
|
||||||
|
|
||||||
|
if (owner.getProcessorHasPotentialFeedbackLoop())
|
||||||
|
{
|
||||||
|
addAndMakeVisible (shouldMuteButton);
|
||||||
|
addAndMakeVisible (shouldMuteLabel);
|
||||||
|
|
||||||
|
shouldMuteLabel.attachToComponent (&shouldMuteButton, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void paint (Graphics& g) override
|
||||||
|
{
|
||||||
|
g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId));
|
||||||
|
}
|
||||||
|
|
||||||
|
void resized() override
|
||||||
|
{
|
||||||
|
auto r = getLocalBounds();
|
||||||
|
|
||||||
|
if (owner.getProcessorHasPotentialFeedbackLoop())
|
||||||
|
{
|
||||||
|
auto itemHeight = deviceSelector.getItemHeight();
|
||||||
|
auto extra = r.removeFromTop (itemHeight);
|
||||||
|
|
||||||
|
auto seperatorHeight = (itemHeight >> 1);
|
||||||
|
shouldMuteButton.setBounds (Rectangle<int> (extra.proportionOfWidth (0.35f), seperatorHeight,
|
||||||
|
extra.proportionOfWidth (0.60f), deviceSelector.getItemHeight()));
|
||||||
|
|
||||||
|
r.removeFromTop (seperatorHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
deviceSelector.setBounds (r);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
//==============================================================================
|
||||||
|
StandalonePluginHolder& owner;
|
||||||
|
AudioDeviceSelectorComponent deviceSelector;
|
||||||
|
Label shouldMuteLabel;
|
||||||
|
ToggleButton shouldMuteButton;
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SettingsComponent)
|
||||||
|
};
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
void audioDeviceIOCallback (const float** inputChannelData,
|
||||||
|
int numInputChannels,
|
||||||
|
float** outputChannelData,
|
||||||
|
int numOutputChannels,
|
||||||
|
int numSamples) override
|
||||||
|
{
|
||||||
|
if (muteInput)
|
||||||
|
{
|
||||||
|
emptyBuffer.clear();
|
||||||
|
inputChannelData = emptyBuffer.getArrayOfReadPointers();
|
||||||
|
}
|
||||||
|
|
||||||
|
player.audioDeviceIOCallback (inputChannelData, numInputChannels,
|
||||||
|
outputChannelData, numOutputChannels, numSamples);
|
||||||
|
}
|
||||||
|
|
||||||
|
void audioDeviceAboutToStart (AudioIODevice* device) override
|
||||||
|
{
|
||||||
|
emptyBuffer.setSize (device->getActiveInputChannels().countNumberOfSetBits(), device->getCurrentBufferSizeSamples());
|
||||||
|
emptyBuffer.clear();
|
||||||
|
|
||||||
|
player.audioDeviceAboutToStart (device);
|
||||||
|
player.setMidiOutput (deviceManager.getDefaultMidiOutput());
|
||||||
|
}
|
||||||
|
|
||||||
|
void audioDeviceStopped() override
|
||||||
|
{
|
||||||
|
player.setMidiOutput (nullptr);
|
||||||
|
player.audioDeviceStopped();
|
||||||
|
emptyBuffer.setSize (0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
void setupAudioDevices (bool enableAudioInput,
|
||||||
|
const String& preferredDefaultDeviceName,
|
||||||
|
const AudioDeviceManager::AudioDeviceSetup* preferredSetupOptions)
|
||||||
|
{
|
||||||
|
deviceManager.addAudioCallback (this);
|
||||||
|
deviceManager.addMidiInputDeviceCallback ({}, &player);
|
||||||
|
|
||||||
|
reloadAudioDeviceState (enableAudioInput, preferredDefaultDeviceName, preferredSetupOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
void shutDownAudioDevices()
|
||||||
|
{
|
||||||
|
saveAudioDeviceState();
|
||||||
|
|
||||||
|
deviceManager.removeMidiInputDeviceCallback ({}, &player);
|
||||||
|
deviceManager.removeAudioCallback (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void timerCallback() override
|
||||||
|
{
|
||||||
|
auto newMidiDevices = MidiInput::getAvailableDevices();
|
||||||
|
|
||||||
|
if (newMidiDevices != lastMidiDevices)
|
||||||
|
{
|
||||||
|
for (auto& oldDevice : lastMidiDevices)
|
||||||
|
if (! newMidiDevices.contains (oldDevice))
|
||||||
|
deviceManager.setMidiInputDeviceEnabled (oldDevice.identifier, false);
|
||||||
|
|
||||||
|
for (auto& newDevice : newMidiDevices)
|
||||||
|
if (! lastMidiDevices.contains (newDevice))
|
||||||
|
deviceManager.setMidiInputDeviceEnabled (newDevice.identifier, true);
|
||||||
|
|
||||||
|
lastMidiDevices = newMidiDevices;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (StandalonePluginHolder)
|
||||||
|
};
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
/**
|
||||||
|
A class that can be used to run a simple standalone application containing your filter.
|
||||||
|
|
||||||
|
Just create one of these objects in your JUCEApplicationBase::initialise() method, and
|
||||||
|
let it do its work. It will create your filter object using the same createPluginFilter() function
|
||||||
|
that the other plugin wrappers use.
|
||||||
|
|
||||||
|
@tags{Audio}
|
||||||
|
*/
|
||||||
|
class StandaloneFilterWindow : public DocumentWindow,
|
||||||
|
public Button::Listener,
|
||||||
|
public MenuBarModel
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//==============================================================================
|
||||||
|
typedef StandalonePluginHolder::PluginInOuts PluginInOuts;
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
/** Creates a window with a given title and colour.
|
||||||
|
The settings object can be a PropertySet that the class should use to
|
||||||
|
store its settings (it can also be null). If takeOwnershipOfSettings is
|
||||||
|
true, then the settings object will be owned and deleted by this object.
|
||||||
|
*/
|
||||||
|
StandaloneFilterWindow (const String& title,
|
||||||
|
Colour backgroundColour,
|
||||||
|
PropertySet* settingsToUse,
|
||||||
|
bool takeOwnershipOfSettings,
|
||||||
|
const String& preferredDefaultDeviceName = String(),
|
||||||
|
const AudioDeviceManager::AudioDeviceSetup* preferredSetupOptions = nullptr,
|
||||||
|
const Array<PluginInOuts>& constrainToConfiguration = {},
|
||||||
|
#if JUCE_ANDROID || JUCE_IOS
|
||||||
|
bool autoOpenMidiDevices = true
|
||||||
|
#else
|
||||||
|
bool autoOpenMidiDevices = true
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
: DocumentWindow ("", Colour::fromHSV (0.0f, 0.0f, 0.1f, 1.0f), DocumentWindow::minimiseButton | DocumentWindow::closeButton)
|
||||||
|
, menuBar(this)
|
||||||
|
#if ! JUCE_MAC
|
||||||
|
, optionsButton ("Settings")
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#if JUCE_IOS || JUCE_ANDROID
|
||||||
|
setTitleBarHeight (0);
|
||||||
|
#else
|
||||||
|
setTitleBarButtonsRequired (DocumentWindow::minimiseButton | DocumentWindow::closeButton, false);
|
||||||
|
|
||||||
|
#if JUCE_MAC
|
||||||
|
setUsingNativeTitleBar(true);
|
||||||
|
menu.addItem (1, TRANS("Audio/MIDI Settings..."));
|
||||||
|
MenuBarModel::setMacMainMenu (this, &menu);
|
||||||
|
#else
|
||||||
|
Component::addAndMakeVisible (optionsButton);
|
||||||
|
optionsButton.addListener (this);
|
||||||
|
optionsButton.setTriggeredOnMouseDown (true);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
pluginHolder.reset (new StandalonePluginHolder (settingsToUse, takeOwnershipOfSettings,
|
||||||
|
preferredDefaultDeviceName, preferredSetupOptions,
|
||||||
|
constrainToConfiguration, autoOpenMidiDevices));
|
||||||
|
|
||||||
|
#if JUCE_IOS || JUCE_ANDROID
|
||||||
|
setFullScreen (true);
|
||||||
|
setContentOwned (new MainContentComponent (*this), false);
|
||||||
|
#else
|
||||||
|
setContentOwned (new MainContentComponent (*this), true);
|
||||||
|
|
||||||
|
if (auto* props = pluginHolder->settings.get())
|
||||||
|
{
|
||||||
|
const int x = props->getIntValue ("windowX", -100);
|
||||||
|
const int y = props->getIntValue ("windowY", -100);
|
||||||
|
|
||||||
|
if (x != -100 && y != -100)
|
||||||
|
setBoundsConstrained ({ x, y, getWidth(), getHeight() });
|
||||||
|
else
|
||||||
|
centreWithSize (getWidth(), getHeight());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
centreWithSize (getWidth(), getHeight());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
~StandaloneFilterWindow() override
|
||||||
|
{
|
||||||
|
#if JUCE_MAC
|
||||||
|
setMacMainMenu(nullptr);
|
||||||
|
#endif
|
||||||
|
#if (! JUCE_IOS) && (! JUCE_ANDROID)
|
||||||
|
if (auto* props = pluginHolder->settings.get())
|
||||||
|
{
|
||||||
|
props->setValue ("windowX", getX());
|
||||||
|
props->setValue ("windowY", getY());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
pluginHolder->stopPlaying();
|
||||||
|
clearContentComponent();
|
||||||
|
pluginHolder = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
AudioProcessor* getAudioProcessor() const noexcept { return pluginHolder->processor.get(); }
|
||||||
|
AudioDeviceManager& getDeviceManager() const noexcept { return pluginHolder->deviceManager; }
|
||||||
|
|
||||||
|
/** Deletes and re-creates the plugin, resetting it to its default state. */
|
||||||
|
void resetToDefaultState()
|
||||||
|
{
|
||||||
|
pluginHolder->stopPlaying();
|
||||||
|
clearContentComponent();
|
||||||
|
pluginHolder->deletePlugin();
|
||||||
|
|
||||||
|
if (auto* props = pluginHolder->settings.get())
|
||||||
|
props->removeValue ("filterState");
|
||||||
|
|
||||||
|
pluginHolder->createPlugin();
|
||||||
|
setContentOwned (new MainContentComponent (*this), true);
|
||||||
|
pluginHolder->startPlaying();
|
||||||
|
}
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
void closeButtonPressed() override
|
||||||
|
{
|
||||||
|
pluginHolder->savePluginState();
|
||||||
|
|
||||||
|
JUCEApplicationBase::quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
StringArray getMenuBarNames() override
|
||||||
|
{
|
||||||
|
// StringArray menuBarNames;
|
||||||
|
// menuBarNames.add("Options");
|
||||||
|
// return menuBarNames;
|
||||||
|
const char *menuNames[] = { 0 };
|
||||||
|
|
||||||
|
return StringArray (menuNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
PopupMenu getMenuForIndex (int topLevelMenuIndex, const String& menuName) override
|
||||||
|
{
|
||||||
|
PopupMenu m;
|
||||||
|
// m.addItem (1, TRANS("Audio Settings..."));
|
||||||
|
// m.addSeparator();
|
||||||
|
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
void menuItemSelected (int menuItemID, int topLevelMenuIndex) override
|
||||||
|
{
|
||||||
|
handleMenuResult(menuItemID);
|
||||||
|
}
|
||||||
|
|
||||||
|
void menuBarActivated (bool isActive) override {};
|
||||||
|
|
||||||
|
void buttonClicked (Button*) override
|
||||||
|
{
|
||||||
|
pluginHolder->showAudioSettingsDialog();
|
||||||
|
|
||||||
|
// PopupMenu m;
|
||||||
|
// m.addItem (1, TRANS("Audio/MIDI Settings..."));
|
||||||
|
// m.addSeparator();
|
||||||
|
// m.addItem (2, TRANS("Save current state..."));
|
||||||
|
// m.addItem (3, TRANS("Load a saved state..."));
|
||||||
|
// m.addSeparator();
|
||||||
|
// m.addItem (4, TRANS("Reset to default state"));
|
||||||
|
|
||||||
|
// m.showMenuAsync (PopupMenu::Options(),ModalCallbackFunction::forComponent (menuCallback, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleMenuResult (int result)
|
||||||
|
{
|
||||||
|
switch (result)
|
||||||
|
{
|
||||||
|
case 1: pluginHolder->showAudioSettingsDialog(); break;
|
||||||
|
case 2: pluginHolder->askUserToSaveState(); break;
|
||||||
|
case 3: pluginHolder->askUserToLoadState(); break;
|
||||||
|
case 4: resetToDefaultState(); break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void menuCallback (int result, StandaloneFilterWindow* button)
|
||||||
|
{
|
||||||
|
if (button != nullptr && result != 0)
|
||||||
|
button->handleMenuResult (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
void resized() override
|
||||||
|
{
|
||||||
|
DocumentWindow::resized();
|
||||||
|
#if ! JUCE_MAC
|
||||||
|
optionsButton.setBounds (8, 6, 60, getTitleBarHeight() - 8);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual StandalonePluginHolder* getPluginHolder() { return pluginHolder.get(); }
|
||||||
|
|
||||||
|
std::unique_ptr<StandalonePluginHolder> pluginHolder;
|
||||||
|
MenuBarComponent menuBar;
|
||||||
|
PopupMenu menu;
|
||||||
|
|
||||||
|
private:
|
||||||
|
//==============================================================================
|
||||||
|
class MainContentComponent : public Component,
|
||||||
|
private Value::Listener,
|
||||||
|
private Button::Listener,
|
||||||
|
private ComponentListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MainContentComponent (StandaloneFilterWindow& filterWindow)
|
||||||
|
: owner (filterWindow), notification (this),
|
||||||
|
editor (owner.getAudioProcessor()->hasEditor() ? owner.getAudioProcessor()->createEditorIfNeeded()
|
||||||
|
: new GenericAudioProcessorEditor (*owner.getAudioProcessor()))
|
||||||
|
{
|
||||||
|
Value& inputMutedValue = owner.pluginHolder->getMuteInputValue();
|
||||||
|
|
||||||
|
if (editor != nullptr)
|
||||||
|
{
|
||||||
|
editor->addComponentListener (this);
|
||||||
|
componentMovedOrResized (*editor, false, true);
|
||||||
|
|
||||||
|
addAndMakeVisible (editor.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
addChildComponent (notification);
|
||||||
|
|
||||||
|
if (owner.pluginHolder->getProcessorHasPotentialFeedbackLoop())
|
||||||
|
{
|
||||||
|
inputMutedValue.addListener (this);
|
||||||
|
shouldShowNotification = inputMutedValue.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
inputMutedChanged (shouldShowNotification);
|
||||||
|
}
|
||||||
|
|
||||||
|
~MainContentComponent() override
|
||||||
|
{
|
||||||
|
if (editor != nullptr)
|
||||||
|
{
|
||||||
|
editor->removeComponentListener (this);
|
||||||
|
owner.pluginHolder->processor->editorBeingDeleted (editor.get());
|
||||||
|
editor = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void resized() override
|
||||||
|
{
|
||||||
|
auto r = getLocalBounds();
|
||||||
|
|
||||||
|
if (shouldShowNotification)
|
||||||
|
notification.setBounds (r.removeFromTop (NotificationArea::height));
|
||||||
|
|
||||||
|
if (editor != nullptr)
|
||||||
|
editor->setBounds (editor->getLocalArea (this, r)
|
||||||
|
.withPosition (r.getTopLeft().transformedBy (editor->getTransform().inverted())));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
//==============================================================================
|
||||||
|
class NotificationArea : public Component
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum { height = 30 };
|
||||||
|
|
||||||
|
NotificationArea (Button::Listener* settingsButtonListener)
|
||||||
|
: notification ("notification", "Audio input is muted to avoid feedback loop"),
|
||||||
|
#if JUCE_IOS || JUCE_ANDROID
|
||||||
|
settingsButton ("Unmute Input")
|
||||||
|
#else
|
||||||
|
settingsButton ("Settings...")
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
setOpaque (true);
|
||||||
|
|
||||||
|
notification.setColour (Label::textColourId, Colours::black);
|
||||||
|
|
||||||
|
settingsButton.addListener (settingsButtonListener);
|
||||||
|
|
||||||
|
addAndMakeVisible (notification);
|
||||||
|
addAndMakeVisible (settingsButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
void paint (Graphics& g) override
|
||||||
|
{
|
||||||
|
auto r = getLocalBounds();
|
||||||
|
|
||||||
|
g.setColour (Colours::darkgoldenrod);
|
||||||
|
g.fillRect (r.removeFromBottom (1));
|
||||||
|
|
||||||
|
g.setColour (Colours::lightgoldenrodyellow);
|
||||||
|
g.fillRect (r);
|
||||||
|
}
|
||||||
|
|
||||||
|
void resized() override
|
||||||
|
{
|
||||||
|
auto r = getLocalBounds().reduced (5);
|
||||||
|
|
||||||
|
settingsButton.setBounds (r.removeFromRight (70));
|
||||||
|
notification.setBounds (r);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
Label notification;
|
||||||
|
TextButton settingsButton;
|
||||||
|
};
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
void inputMutedChanged (bool newInputMutedValue)
|
||||||
|
{
|
||||||
|
shouldShowNotification = newInputMutedValue;
|
||||||
|
notification.setVisible (shouldShowNotification);
|
||||||
|
|
||||||
|
#if JUCE_IOS || JUCE_ANDROID
|
||||||
|
resized();
|
||||||
|
#else
|
||||||
|
if (editor != nullptr)
|
||||||
|
{
|
||||||
|
auto rect = getSizeToContainEditor();
|
||||||
|
|
||||||
|
setSize (rect.getWidth(),
|
||||||
|
rect.getHeight() + (shouldShowNotification ? NotificationArea::height : 0));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void valueChanged (Value& value) override { inputMutedChanged (value.getValue()); }
|
||||||
|
void buttonClicked (Button*) override
|
||||||
|
{
|
||||||
|
#if JUCE_IOS || JUCE_ANDROID
|
||||||
|
owner.pluginHolder->getMuteInputValue().setValue (false);
|
||||||
|
#else
|
||||||
|
owner.pluginHolder->showAudioSettingsDialog();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
void componentMovedOrResized (Component&, bool, bool) override
|
||||||
|
{
|
||||||
|
if (editor != nullptr)
|
||||||
|
{
|
||||||
|
auto rect = getSizeToContainEditor();
|
||||||
|
|
||||||
|
setSize (rect.getWidth(),
|
||||||
|
rect.getHeight() + (shouldShowNotification ? NotificationArea::height : 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle<int> getSizeToContainEditor() const
|
||||||
|
{
|
||||||
|
if (editor != nullptr)
|
||||||
|
return getLocalArea (editor.get(), editor->getLocalBounds());
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
StandaloneFilterWindow& owner;
|
||||||
|
NotificationArea notification;
|
||||||
|
std::unique_ptr<AudioProcessorEditor> editor;
|
||||||
|
bool shouldShowNotification = false;
|
||||||
|
|
||||||
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainContentComponent)
|
||||||
|
};
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
#if ! JUCE_MAC
|
||||||
|
TextButton optionsButton;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (StandaloneFilterWindow)
|
||||||
|
};
|
||||||
|
|
||||||
|
inline StandalonePluginHolder* StandalonePluginHolder::getInstance()
|
||||||
|
{
|
||||||
|
#if JucePlugin_Enable_IAA || JucePlugin_Build_Standalone
|
||||||
|
if (PluginHostType::getPluginLoadedAs() == AudioProcessor::wrapperType_Standalone)
|
||||||
|
{
|
||||||
|
auto& desktop = Desktop::getInstance();
|
||||||
|
const int numTopLevelWindows = desktop.getNumComponents();
|
||||||
|
|
||||||
|
for (int i = 0; i < numTopLevelWindows; ++i)
|
||||||
|
if (auto window = dynamic_cast<StandaloneFilterWindow*> (desktop.getComponent (i)))
|
||||||
|
return window->getPluginHolder();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace juce
|
201
OB-Xd.jucer
|
@ -1,28 +1,24 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
<JUCERPROJECT id="mxW328" name="Obxd" projectType="audioplug" version="1.5.0"
|
<JUCERPROJECT id="mxW328" name="OB-Xd" projectType="audioplug" version="2.0.0"
|
||||||
bundleIdentifier="com.Datsounds.Obxd" includeBinaryInAppConfig="1"
|
bundleIdentifier="com.discoDSP.Obxd" includeBinaryInAppConfig="1"
|
||||||
buildVST="1" buildVST3="1" buildAU="1" buildRTAS="0" buildAAX="0"
|
|
||||||
pluginName="OB-Xd" pluginDesc="Emulation of famous OB-X, OB-Xa and OB-8 synths"
|
pluginName="OB-Xd" pluginDesc="Emulation of famous OB-X, OB-Xa and OB-8 synths"
|
||||||
pluginManufacturer="Datsounds" pluginManufacturerCode="Dats"
|
pluginManufacturer="discoDSP" pluginManufacturerCode="DDSP" pluginCode="Obxd"
|
||||||
pluginCode="Obxd" pluginChannelConfigs="{0, 2}" pluginIsSynth="1"
|
pluginChannelConfigs="{0, 2}" pluginIsSynth="1" pluginWantsMidiIn="1"
|
||||||
pluginWantsMidiIn="1" pluginProducesMidiOut="0" pluginSilenceInIsSilenceOut="0"
|
pluginProducesMidiOut="0" pluginSilenceInIsSilenceOut="0" pluginEditorRequiresKeys="0"
|
||||||
pluginEditorRequiresKeys="0" pluginAUExportPrefix="" pluginRTASCategory="2048"
|
pluginAUExportPrefix="" pluginRTASCategory="2048" aaxIdentifier=""
|
||||||
aaxIdentifier="" pluginAAXCategory="" jucerVersion="5.4.4" companyName="2Dat"
|
pluginAAXCategory="" jucerVersion="5.4.7" companyName="discoDSP"
|
||||||
companyWebsite="https://www.discodsp.com/obxd/" companyEmail=""
|
companyWebsite="https://www.discodsp.com/" companyEmail="contactus@discodsp.com"
|
||||||
buildAUv3="0" pluginIsMidiEffectPlugin="0" pluginFormats="buildAU,buildStandalone,buildVST,buildVST3"
|
pluginIsMidiEffectPlugin="0" pluginCharacteristicsValue="pluginIsSynth,pluginWantsMidiIn"
|
||||||
pluginCharacteristicsValue="pluginIsSynth,pluginWantsMidiIn"
|
pluginFormats="buildAU,buildStandalone,buildVST3" buildVST="0"
|
||||||
|
buildVST3="1" buildAU="1" buildAUv3="0" buildRTAS="0" buildAAX="0"
|
||||||
buildStandalone="1" enableIAA="0">
|
buildStandalone="1" enableIAA="0">
|
||||||
<MAINGROUP id="NZ3n4V" name="Obxd">
|
<MAINGROUP id="NZ3n4V" name="OB-Xd">
|
||||||
<GROUP id="{90740217-84AB-FD0D-FBC4-CA9EA2C68D5E}" name="Source">
|
<GROUP id="{90740217-84AB-FD0D-FBC4-CA9EA2C68D5E}" name="Source">
|
||||||
<GROUP id="{5F0B15D1-4D92-B2FF-5904-9CF4C3CE645F}" name="Images">
|
<GROUP id="{5F0B15D1-4D92-B2FF-5904-9CF4C3CE645F}" name="Images">
|
||||||
<FILE id="nnY63W" name="appicon.png" compile="0" resource="1" file="Source/Images/appicon.png"/>
|
<FILE id="nnY63W" name="appicon.png" compile="0" resource="1" file="Source/Images/appicon.png"/>
|
||||||
<FILE id="IV8Ubu" name="button.png" compile="0" resource="1" file="Source/Images/button.png"/>
|
|
||||||
<FILE id="gUrdhJ" name="knoblsd.png" compile="0" resource="1" file="Source/Images/knoblsd.png"/>
|
|
||||||
<FILE id="FzhdQQ" name="knobssd.png" compile="0" resource="1" file="Source/Images/knobssd.png"/>
|
|
||||||
<FILE id="syMyon" name="legato.png" compile="0" resource="1" file="Source/Images/legato.png"/>
|
|
||||||
<FILE id="kwaOoZ" name="main.png" compile="0" resource="1" file="Source/Images/main.png"/>
|
<FILE id="kwaOoZ" name="main.png" compile="0" resource="1" file="Source/Images/main.png"/>
|
||||||
<FILE id="UHyt7V" name="voices.png" compile="0" resource="1" file="Source/Images/voices.png"/>
|
<FILE id="l84SVW" name="menu.png" compile="0" resource="1" file="Source/Images/menu.png"/>
|
||||||
</GROUP>
|
</GROUP>
|
||||||
<GROUP id="{6995BDF2-263F-3CA7-8CA4-4E21F325477A}" name="Gui">
|
<GROUP id="{6995BDF2-263F-3CA7-8CA4-4E21F325477A}" name="Gui">
|
||||||
<FILE id="zJoidp" name="ButtonList.h" compile="0" resource="0" file="Source/Gui/ButtonList.h"/>
|
<FILE id="zJoidp" name="ButtonList.h" compile="0" resource="0" file="Source/Gui/ButtonList.h"/>
|
||||||
|
@ -65,118 +61,105 @@
|
||||||
</GROUP>
|
</GROUP>
|
||||||
</MAINGROUP>
|
</MAINGROUP>
|
||||||
<EXPORTFORMATS>
|
<EXPORTFORMATS>
|
||||||
<XCODE_MAC targetFolder="Builds/MacOSX" bigIcon="nnY63W" smallIcon="nnY63W">
|
<XCODE_MAC targetFolder="Builds/MacOSX" bigIcon="nnY63W" smallIcon="nnY63W"
|
||||||
|
vstLegacyFolder="Modules/vstsdk2.4" vst3Folder="Modules/vstsdk3">
|
||||||
<CONFIGURATIONS>
|
<CONFIGURATIONS>
|
||||||
<CONFIGURATION name="Debug" isDebug="1" optimisation="1" targetName="Obxd" stripLocalSymbols="0"
|
<CONFIGURATION name="Debug" isDebug="1" optimisation="1" targetName="OB-Xd"
|
||||||
osxCompatibility="10.6 SDK" linkTimeOptimisation="0"/>
|
stripLocalSymbols="0" osxCompatibility="10.6 SDK" linkTimeOptimisation="0"/>
|
||||||
<CONFIGURATION name="Release" isDebug="0" optimisation="3" targetName="Obxd"
|
<CONFIGURATION name="Release" isDebug="0" optimisation="3" targetName="OB-Xd"
|
||||||
stripLocalSymbols="1" osxCompatibility="10.6 SDK" linkTimeOptimisation="0"
|
stripLocalSymbols="1" osxArchitecture="64BitIntel" linkTimeOptimisation="1"/>
|
||||||
osxArchitecture="64BitIntel"/>
|
<CONFIGURATION name="Demo" isDebug="0" optimisation="3" targetName="OB-Xd" stripLocalSymbols="1"
|
||||||
|
osxArchitecture="64BitIntel" linkTimeOptimisation="1" defines="DEMOVERSION=1"/>
|
||||||
</CONFIGURATIONS>
|
</CONFIGURATIONS>
|
||||||
<MODULEPATHS>
|
<MODULEPATHS>
|
||||||
<MODULEPATH id="juce_opengl" path="~/JUCE/modules"/>
|
<MODULEPATH id="juce_opengl" path="Modules"/>
|
||||||
<MODULEPATH id="juce_gui_extra" path="~/JUCE/modules"/>
|
<MODULEPATH id="juce_gui_extra" path="Modules"/>
|
||||||
<MODULEPATH id="juce_gui_basics" path="~/JUCE/modules"/>
|
<MODULEPATH id="juce_gui_basics" path="Modules"/>
|
||||||
<MODULEPATH id="juce_graphics" path="~/JUCE/modules"/>
|
<MODULEPATH id="juce_graphics" path="Modules"/>
|
||||||
<MODULEPATH id="juce_events" path="~/JUCE/modules"/>
|
<MODULEPATH id="juce_events" path="Modules"/>
|
||||||
<MODULEPATH id="juce_data_structures" path="~/JUCE/modules"/>
|
<MODULEPATH id="juce_data_structures" path="Modules"/>
|
||||||
<MODULEPATH id="juce_core" path="~/JUCE/modules"/>
|
<MODULEPATH id="juce_core" path="Modules"/>
|
||||||
<MODULEPATH id="juce_audio_processors" path="~/JUCE/modules"/>
|
<MODULEPATH id="juce_audio_processors" path="Modules"/>
|
||||||
<MODULEPATH id="juce_audio_plugin_client" path="~/JUCE/modules"/>
|
<MODULEPATH id="juce_audio_plugin_client" path="Modules"/>
|
||||||
<MODULEPATH id="juce_audio_formats" path="~/JUCE/modules"/>
|
<MODULEPATH id="juce_audio_formats" path="Modules"/>
|
||||||
<MODULEPATH id="juce_audio_devices" path="~/JUCE/modules"/>
|
<MODULEPATH id="juce_audio_devices" path="Modules"/>
|
||||||
<MODULEPATH id="juce_audio_basics"/>
|
<MODULEPATH id="juce_audio_basics" path="Modules"/>
|
||||||
<MODULEPATH id="juce_audio_utils" path="~/JUCE/modules"/>
|
<MODULEPATH id="juce_audio_utils" path="Modules"/>
|
||||||
</MODULEPATHS>
|
</MODULEPATHS>
|
||||||
</XCODE_MAC>
|
</XCODE_MAC>
|
||||||
<LINUX_MAKE targetFolder="Builds/LinuxMakefile" extraLinkerFlags="-no-pie">
|
<LINUX_MAKE targetFolder="Builds/LinuxMakefile" extraLinkerFlags="-no-pie">
|
||||||
<CONFIGURATIONS>
|
<CONFIGURATIONS>
|
||||||
<CONFIGURATION name="Release64" libraryPath="/usr/X11R6/lib/" isDebug="0" optimisation="3"
|
<CONFIGURATION name="Release64" libraryPath="/usr/X11R6/lib/" isDebug="0" optimisation="3"
|
||||||
targetName="Obxd64" linuxArchitecture="-m64"/>
|
targetName="OB-Xd" linuxArchitecture="-m64"/>
|
||||||
|
<CONFIGURATION name="Demo64" libraryPath="/usr/X11R6/lib/" isDebug="0" optimisation="3"
|
||||||
|
targetName="OB-Xd" linuxArchitecture="-m64" defines="DEMOVERSION=1"/>
|
||||||
</CONFIGURATIONS>
|
</CONFIGURATIONS>
|
||||||
<MODULEPATHS>
|
<MODULEPATHS>
|
||||||
<MODULEPATH id="juce_opengl" path="~/JUCE/modules"/>
|
<MODULEPATH id="juce_opengl" path="Modules"/>
|
||||||
<MODULEPATH id="juce_gui_extra" path="~/JUCE/modules"/>
|
<MODULEPATH id="juce_gui_extra" path="Modules"/>
|
||||||
<MODULEPATH id="juce_gui_basics" path="~/JUCE/modules"/>
|
<MODULEPATH id="juce_gui_basics" path="Modules"/>
|
||||||
<MODULEPATH id="juce_graphics" path="~/JUCE/modules"/>
|
<MODULEPATH id="juce_graphics" path="Modules"/>
|
||||||
<MODULEPATH id="juce_events" path="~/JUCE/modules"/>
|
<MODULEPATH id="juce_events" path="Modules"/>
|
||||||
<MODULEPATH id="juce_data_structures" path="~/JUCE/modules"/>
|
<MODULEPATH id="juce_data_structures" path="Modules"/>
|
||||||
<MODULEPATH id="juce_core" path="~/JUCE/modules"/>
|
<MODULEPATH id="juce_core" path="Modules"/>
|
||||||
<MODULEPATH id="juce_audio_utils" path="~/JUCE/modules"/>
|
<MODULEPATH id="juce_audio_utils" path="Modules"/>
|
||||||
<MODULEPATH id="juce_audio_processors" path="~/JUCE/modules"/>
|
<MODULEPATH id="juce_audio_processors" path="Modules"/>
|
||||||
<MODULEPATH id="juce_audio_plugin_client" path="~/JUCE/modules"/>
|
<MODULEPATH id="juce_audio_plugin_client" path="Modules"/>
|
||||||
<MODULEPATH id="juce_audio_formats" path="~/JUCE/modules"/>
|
<MODULEPATH id="juce_audio_formats" path="Modules"/>
|
||||||
<MODULEPATH id="juce_audio_devices" path="~/JUCE/modules"/>
|
<MODULEPATH id="juce_audio_devices" path="Modules"/>
|
||||||
<MODULEPATH id="juce_audio_basics"/>
|
<MODULEPATH id="juce_audio_basics" path="Modules"/>
|
||||||
</MODULEPATHS>
|
</MODULEPATHS>
|
||||||
</LINUX_MAKE>
|
</LINUX_MAKE>
|
||||||
<VS2013 targetFolder="Builds/VisualStudio2013">
|
<VS2019 targetFolder="Builds/VisualStudio2019" smallIcon="nnY63W" bigIcon="nnY63W"
|
||||||
|
vstLegacyFolder="Modules/vstsdk2.4" vst3Folder="Modules/vstsdk3">
|
||||||
<CONFIGURATIONS>
|
<CONFIGURATIONS>
|
||||||
<CONFIGURATION name="Debug" winWarningLevel="4" generateManifest="1" winArchitecture="x64"
|
<CONFIGURATION isDebug="1" name="Debug" useRuntimeLibDLL="0" targetName="OB-Xd"
|
||||||
isDebug="1" optimisation="3" targetName="Obxd"/>
|
headerPath="../../Modules/asiosdk2.3.2/common"/>
|
||||||
<CONFIGURATION name="Release64" winWarningLevel="4" generateManifest="1" winArchitecture="x64"
|
<CONFIGURATION isDebug="0" name="Release64" useRuntimeLibDLL="0" winArchitecture="x64"
|
||||||
isDebug="0" optimisation="3" targetName="Obxd64" useRuntimeLibDLL="0"/>
|
targetName="OB-Xd" headerPath="../../Modules/asiosdk2.3.2/common"/>
|
||||||
<CONFIGURATION name="Release32" winWarningLevel="4" generateManifest="1" winArchitecture="32-bit"
|
<CONFIGURATION isDebug="0" name="Demo64" useRuntimeLibDLL="0" winArchitecture="x64"
|
||||||
isDebug="0" optimisation="3" targetName="Obxd" useRuntimeLibDLL="0"/>
|
targetName="OB-Xd" headerPath="../../Modules/asiosdk2.3.2/common"
|
||||||
|
defines="DEMOVERSION=1"/>
|
||||||
</CONFIGURATIONS>
|
</CONFIGURATIONS>
|
||||||
<MODULEPATHS>
|
<MODULEPATHS>
|
||||||
<MODULEPATH id="juce_opengl" path="modules"/>
|
<MODULEPATH id="juce_opengl" path="Modules"/>
|
||||||
<MODULEPATH id="juce_gui_extra" path="modules"/>
|
<MODULEPATH id="juce_gui_extra" path="Modules"/>
|
||||||
<MODULEPATH id="juce_gui_basics" path="modules"/>
|
<MODULEPATH id="juce_gui_basics" path="Modules"/>
|
||||||
<MODULEPATH id="juce_graphics" path="modules"/>
|
<MODULEPATH id="juce_graphics" path="Modules"/>
|
||||||
<MODULEPATH id="juce_events" path="modules"/>
|
<MODULEPATH id="juce_events" path="Modules"/>
|
||||||
<MODULEPATH id="juce_data_structures" path="modules"/>
|
<MODULEPATH id="juce_data_structures" path="Modules"/>
|
||||||
<MODULEPATH id="juce_core" path="modules"/>
|
<MODULEPATH id="juce_core" path="Modules"/>
|
||||||
<MODULEPATH id="juce_audio_utils" path="modules"/>
|
<MODULEPATH id="juce_audio_utils" path="Modules"/>
|
||||||
<MODULEPATH id="juce_audio_processors" path="modules"/>
|
<MODULEPATH id="juce_audio_processors" path="Modules"/>
|
||||||
<MODULEPATH id="juce_audio_plugin_client" path="modules"/>
|
<MODULEPATH id="juce_audio_plugin_client" path="Modules"/>
|
||||||
<MODULEPATH id="juce_audio_formats" path="modules"/>
|
<MODULEPATH id="juce_audio_formats" path="Modules"/>
|
||||||
<MODULEPATH id="juce_audio_devices" path="modules"/>
|
<MODULEPATH id="juce_audio_devices" path="Modules"/>
|
||||||
<MODULEPATH id="juce_audio_basics" path="modules"/>
|
<MODULEPATH id="juce_audio_basics" path="Modules"/>
|
||||||
</MODULEPATHS>
|
|
||||||
</VS2013>
|
|
||||||
<VS2019 targetFolder="Builds/VisualStudio2019" smallIcon="nnY63W" bigIcon="nnY63W">
|
|
||||||
<CONFIGURATIONS>
|
|
||||||
<CONFIGURATION isDebug="1" name="Debug" useRuntimeLibDLL="0"/>
|
|
||||||
<CONFIGURATION isDebug="0" name="Release32" useRuntimeLibDLL="0" winArchitecture="Win32"/>
|
|
||||||
<CONFIGURATION isDebug="0" name="Release64" useRuntimeLibDLL="0" winArchitecture="x64"/>
|
|
||||||
</CONFIGURATIONS>
|
|
||||||
<MODULEPATHS>
|
|
||||||
<MODULEPATH id="juce_opengl" path="C:\JUCE\modules"/>
|
|
||||||
<MODULEPATH id="juce_gui_extra" path="C:\JUCE\modules"/>
|
|
||||||
<MODULEPATH id="juce_gui_basics" path="C:\JUCE\modules"/>
|
|
||||||
<MODULEPATH id="juce_graphics" path="C:\JUCE\modules"/>
|
|
||||||
<MODULEPATH id="juce_events" path="C:\JUCE\modules"/>
|
|
||||||
<MODULEPATH id="juce_data_structures" path="C:\JUCE\modules"/>
|
|
||||||
<MODULEPATH id="juce_core" path="C:\JUCE\modules"/>
|
|
||||||
<MODULEPATH id="juce_audio_utils" path="C:\JUCE\modules"/>
|
|
||||||
<MODULEPATH id="juce_audio_processors" path="C:\JUCE\modules"/>
|
|
||||||
<MODULEPATH id="juce_audio_plugin_client" path="C:\JUCE\modules"/>
|
|
||||||
<MODULEPATH id="juce_audio_formats" path="C:\JUCE\modules"/>
|
|
||||||
<MODULEPATH id="juce_audio_devices" path="C:\JUCE\modules"/>
|
|
||||||
<MODULEPATH id="juce_audio_basics"/>
|
|
||||||
</MODULEPATHS>
|
</MODULEPATHS>
|
||||||
</VS2019>
|
</VS2019>
|
||||||
<VS2017 targetFolder="Builds/VisualStudio2017">
|
<VS2017 targetFolder="Builds/VisualStudio2017" vstLegacyFolder="Modules/vstsdk2.4"
|
||||||
|
vst3Folder="Modules/vstsdk3">
|
||||||
<CONFIGURATIONS>
|
<CONFIGURATIONS>
|
||||||
<CONFIGURATION isDebug="1" name="Debug"/>
|
<CONFIGURATION isDebug="1" name="Debug" targetName="OB-Xd" headerPath="../../Modules/asiosdk2.3.2/common"/>
|
||||||
<CONFIGURATION isDebug="0" name="Release32" winArchitecture="Win32"/>
|
<CONFIGURATION isDebug="0" name="Release64" winArchitecture="x64" targetName="OB-Xd"
|
||||||
<CONFIGURATION isDebug="0" name="Release64" winArchitecture="x64"/>
|
headerPath="../../Modules/asiosdk2.3.2/common"/>
|
||||||
|
<CONFIGURATION isDebug="0" name="Demo64" winArchitecture="x64" targetName="OB-Xd"
|
||||||
|
headerPath="../../Modules/asiosdk2.3.2/common" defines="DEMOVERSION=1"/>
|
||||||
</CONFIGURATIONS>
|
</CONFIGURATIONS>
|
||||||
<MODULEPATHS>
|
<MODULEPATHS>
|
||||||
<MODULEPATH id="juce_opengl" path="C:\JUCE\modules"/>
|
<MODULEPATH id="juce_opengl" path="Modules"/>
|
||||||
<MODULEPATH id="juce_gui_extra" path="C:\JUCE\modules"/>
|
<MODULEPATH id="juce_gui_extra" path="Modules"/>
|
||||||
<MODULEPATH id="juce_gui_basics" path="C:\JUCE\modules"/>
|
<MODULEPATH id="juce_gui_basics" path="Modules"/>
|
||||||
<MODULEPATH id="juce_graphics" path="C:\JUCE\modules"/>
|
<MODULEPATH id="juce_graphics" path="Modules"/>
|
||||||
<MODULEPATH id="juce_events" path="C:\JUCE\modules"/>
|
<MODULEPATH id="juce_events" path="Modules"/>
|
||||||
<MODULEPATH id="juce_data_structures" path="C:\JUCE\modules"/>
|
<MODULEPATH id="juce_data_structures" path="Modules"/>
|
||||||
<MODULEPATH id="juce_core" path="C:\JUCE\modules"/>
|
<MODULEPATH id="juce_core" path="Modules"/>
|
||||||
<MODULEPATH id="juce_audio_utils" path="C:\JUCE\modules"/>
|
<MODULEPATH id="juce_audio_utils" path="Modules"/>
|
||||||
<MODULEPATH id="juce_audio_processors" path="C:\JUCE\modules"/>
|
<MODULEPATH id="juce_audio_processors" path="Modules"/>
|
||||||
<MODULEPATH id="juce_audio_plugin_client" path="C:\JUCE\modules"/>
|
<MODULEPATH id="juce_audio_plugin_client" path="Modules"/>
|
||||||
<MODULEPATH id="juce_audio_formats" path="C:\JUCE\modules"/>
|
<MODULEPATH id="juce_audio_formats" path="Modules"/>
|
||||||
<MODULEPATH id="juce_audio_devices" path="C:\JUCE\modules"/>
|
<MODULEPATH id="juce_audio_devices" path="Modules"/>
|
||||||
<MODULEPATH id="juce_audio_basics"/>
|
<MODULEPATH id="juce_audio_basics" path="Modules"/>
|
||||||
</MODULEPATHS>
|
</MODULEPATHS>
|
||||||
</VS2017>
|
</VS2017>
|
||||||
</EXPORTFORMATS>
|
</EXPORTFORMATS>
|
||||||
|
|
17
README.md
|
@ -1,15 +1,18 @@
|
||||||
# discoDSP OB-Xd
|
# discoDSP OB-Xd
|
||||||
Download binaries at https://www.discodsp.com/obxd/
|
![](https://www.discodsp.com/img/obxd.png)
|
||||||
|
|
||||||
# About
|
# About
|
||||||
|
|
||||||
While not copying originals, some of the features were taken to a better point. Continuous blendable multimode filter (HP-Notch(BP)-HP in 12 dB mode and 4-1 pole in 24 dB mode). 32 and 64 bit versions included.
|
OB-Xd is based on the [Oberheim OB-X](https://wikipedia.org/wiki/Oberheim_OB-X). It attempts to recreate its sound and behavior, but as the original was very limited in some important ways a number of things were added or altered to the original design. OB-Xd was designed to sound as good and as rich as the original. It implements micro random detuning which is a big part of that sound.
|
||||||
|
|
||||||
Thanks to 2Dat for the original OB-Xd and Soshi Studio for giving the rights to continue this wonderful product.
|
While not copying originals, some of the features were taken to a better point. Continuous blendable multimode filter (HP-Notch(BP)-HP in 12 dB mode and 4-1 pole in 24 dB mode). Also, like many synths of the OB-X's generation, the OB-Xd has no internal effects so its sounds and textures can be greatly enhanced by the use of additional processing like chorus, reverb, delay, etc.
|
||||||
Also thanks to all KVR members for making the amazing skins!
|
|
||||||
|
|
||||||
OB-Xd is based on the Oberheim OB-X. It attempts to recreate its sound and behavior, but as the original was very limited in some important ways a number of things were added or altered to the original design.
|
Thanks to [2Dat](https://github.com/2DaT/Obxd) for the original OB-Xd and Soshi Studio for giving the rights to continue this wonderful product. Also thanks to [KVR artists for creating some amazing skins!](https://www.kvraudio.com/forum/viewtopic.php?f=1&t=471926)
|
||||||
|
|
||||||
The OB-Xd was designed to sound as good and as rich as the original. It implements micro random detuning which is a big part of that sound. However, it was not designed as a self-contained completely independent soft-synth. It needs to be contained within a VST framework where things like transposition, automation, layering, arpeggiation, etc., are available.
|
# Binaries
|
||||||
|
|
||||||
Also, like many synths of the OB-X's generation, the OB-Xd has no internal effects so its sounds and textures can be greatly enhanced by the use of additional processing like chorus, reverb, delay, etc.
|
Latest binaries can be downloaded at https://www.discodsp.com/obxd/
|
||||||
|
|
||||||
|
# Building
|
||||||
|
|
||||||
|
Source code can be compiled with [JUCE 5.4.7](https://github.com/juce-framework/JUCE/archive/5.4.7.zip) and VST3 SDK.
|
|
@ -25,7 +25,7 @@
|
||||||
#include "ObxdVoice.h"
|
#include "ObxdVoice.h"
|
||||||
enum ObxdParameters
|
enum ObxdParameters
|
||||||
{
|
{
|
||||||
UNDEFINED,
|
UNDEFINED = 0,
|
||||||
MIDILEARN,
|
MIDILEARN,
|
||||||
VOLUME,
|
VOLUME,
|
||||||
VOICE_COUNT,
|
VOICE_COUNT,
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
==============================================================================
|
==============================================================================
|
||||||
This file is part of Obxd synthesizer.
|
This file is part of Obxd synthesizer.
|
||||||
|
|
||||||
Copyright © 2013-2014 Filatov Vadim
|
Copyright © 2013-2014 Filatov Vadim
|
||||||
|
|
||||||
Contact author via email :
|
Contact author via email :
|
||||||
justdat_@_e1.ru
|
justdat_@_e1.ru
|
||||||
|
@ -23,13 +23,286 @@
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "SynthEngine.h"
|
#include "SynthEngine.h"
|
||||||
|
#include "ParamsEnum.h"
|
||||||
|
#include "../JuceLibraryCode/JuceHeader.h"
|
||||||
class MidiMap
|
class MidiMap
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
int controllers[255];
|
int controllers[255];
|
||||||
|
int controllers_default[255];
|
||||||
|
|
||||||
|
bool loaded = false;
|
||||||
MidiMap()
|
MidiMap()
|
||||||
{
|
{
|
||||||
for(int i = 0 ; i < 255;i++)
|
reset();
|
||||||
|
set_default();
|
||||||
|
}
|
||||||
|
void reset(){
|
||||||
|
for(int i = 0 ; i < 255;i++){
|
||||||
controllers[i] = 0;
|
controllers[i] = 0;
|
||||||
|
controllers_default[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_default(){
|
||||||
|
int midicc = 71;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = VOLUME;
|
||||||
|
|
||||||
|
midicc = 15;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = VOICE_COUNT;
|
||||||
|
|
||||||
|
midicc = 33;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = TUNE;
|
||||||
|
|
||||||
|
midicc = 17;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = OCTAVE;
|
||||||
|
|
||||||
|
midicc = 118;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = BENDRANGE;
|
||||||
|
|
||||||
|
midicc = 34;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = BENDOSC2;
|
||||||
|
|
||||||
|
midicc = 35;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = LEGATOMODE;
|
||||||
|
|
||||||
|
midicc = 75;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = BENDLFORATE;
|
||||||
|
|
||||||
|
midicc = 76;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = VFLTENV;
|
||||||
|
|
||||||
|
midicc = 20;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = VAMPENV;
|
||||||
|
|
||||||
|
midicc = 21;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = ASPLAYEDALLOCATION;
|
||||||
|
|
||||||
|
midicc = 23;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = PORTAMENTO;
|
||||||
|
|
||||||
|
midicc = 16;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = UNISON;
|
||||||
|
|
||||||
|
midicc = 24;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = UDET;
|
||||||
|
|
||||||
|
midicc = 43;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = OSC2_DET;
|
||||||
|
|
||||||
|
midicc = 19;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = LFOFREQ;
|
||||||
|
|
||||||
|
midicc = 44;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = LFOSINWAVE;
|
||||||
|
|
||||||
|
midicc = 45;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = LFOSQUAREWAVE;
|
||||||
|
|
||||||
|
midicc = 46;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = LFOSHWAVE;
|
||||||
|
|
||||||
|
midicc = 22;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = LFO1AMT;
|
||||||
|
|
||||||
|
midicc = 25;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = LFO2AMT;
|
||||||
|
|
||||||
|
midicc = 47;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = LFOOSC1;
|
||||||
|
|
||||||
|
midicc = 48;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = LFOOSC2;
|
||||||
|
|
||||||
|
midicc = 49;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = LFOFILTER;
|
||||||
|
|
||||||
|
midicc = 50;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = LFOPW1;
|
||||||
|
|
||||||
|
midicc = 51;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = LFOPW2;
|
||||||
|
|
||||||
|
midicc = 52;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = OSC2HS;
|
||||||
|
|
||||||
|
midicc = 53;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = XMOD;
|
||||||
|
|
||||||
|
midicc = 54;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = OSC1P;
|
||||||
|
|
||||||
|
midicc = 55;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = OSC2P;
|
||||||
|
|
||||||
|
midicc = 56;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = OSCQuantize;
|
||||||
|
|
||||||
|
midicc = 57;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = OSC1Saw;
|
||||||
|
|
||||||
|
midicc = 58;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = OSC1Pul;
|
||||||
|
|
||||||
|
midicc = 59;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = OSC2Saw;
|
||||||
|
|
||||||
|
midicc = 60;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = OSC2Pul;
|
||||||
|
|
||||||
|
midicc = 61;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = PW;
|
||||||
|
|
||||||
|
midicc = 62;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = BRIGHTNESS;
|
||||||
|
|
||||||
|
midicc = 63;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = ENVPITCH;
|
||||||
|
|
||||||
|
midicc = 100;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = OSC1MIX;
|
||||||
|
|
||||||
|
midicc = 101;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = OSC2MIX;
|
||||||
|
|
||||||
|
midicc = 102;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = NOISEMIX;
|
||||||
|
|
||||||
|
midicc = 103;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = FLT_KF;
|
||||||
|
|
||||||
|
midicc = 74;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = CUTOFF;
|
||||||
|
|
||||||
|
midicc = 42;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = RESONANCE;
|
||||||
|
|
||||||
|
midicc = 104;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = MULTIMODE;
|
||||||
|
|
||||||
|
midicc = 18;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = FILTER_WARM;
|
||||||
|
|
||||||
|
midicc = 105;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = BANDPASS;
|
||||||
|
|
||||||
|
midicc = 106;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = FOURPOLE;
|
||||||
|
|
||||||
|
midicc = 107;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = ENVELOPE_AMT;
|
||||||
|
|
||||||
|
midicc = 73;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = LATK;
|
||||||
|
|
||||||
|
midicc = 36;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = LDEC;
|
||||||
|
|
||||||
|
midicc = 37;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = LSUS;
|
||||||
|
|
||||||
|
midicc = 72;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = LREL;
|
||||||
|
|
||||||
|
midicc = 38;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = FATK;
|
||||||
|
|
||||||
|
midicc = 39;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = FDEC;
|
||||||
|
|
||||||
|
midicc = 40;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = FSUS;
|
||||||
|
|
||||||
|
midicc = 41;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = FREL;
|
||||||
|
|
||||||
|
midicc = 108;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = ENVDER;
|
||||||
|
|
||||||
|
midicc = 109;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = FILTERDER;
|
||||||
|
|
||||||
|
midicc = 110;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = PORTADER;
|
||||||
|
|
||||||
|
midicc = 81;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = PAN1;
|
||||||
|
|
||||||
|
midicc = 82;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = PAN2;
|
||||||
|
|
||||||
|
midicc = 83;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = PAN3;
|
||||||
|
|
||||||
|
midicc = 84;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = PAN4;
|
||||||
|
|
||||||
|
midicc = 85;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = PAN5;
|
||||||
|
|
||||||
|
midicc = 86;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = PAN6;
|
||||||
|
|
||||||
|
midicc = 87;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = PAN7;
|
||||||
|
|
||||||
|
midicc = 88;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = PAN8;
|
||||||
|
|
||||||
|
midicc = 111;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = ECONOMY_MODE;
|
||||||
|
|
||||||
|
//midicc = 112;
|
||||||
|
//controllers[midicc] = controllers_default[midicc] = LFO_SYNC;
|
||||||
|
|
||||||
|
midicc = 113;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = PW_ENV;
|
||||||
|
|
||||||
|
midicc = 114;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = PW_ENV_BOTH;
|
||||||
|
|
||||||
|
midicc = 115;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = ENV_PITCH_BOTH;
|
||||||
|
|
||||||
|
midicc = 116;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = FENV_INVERT;
|
||||||
|
|
||||||
|
midicc = 117;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = PW_OSC2_OFS;
|
||||||
|
|
||||||
|
midicc = 118;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = LEVEL_DIF;
|
||||||
|
|
||||||
|
midicc = 119;
|
||||||
|
controllers[midicc] = controllers_default[midicc] = SELF_OSC_PUSH;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int& operator[](int index)
|
||||||
|
{
|
||||||
|
if (index >= 255) {
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
return controllers[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
void setXml( XmlElement &xml){
|
||||||
|
for (int i = 0; i < 255; ++i)
|
||||||
|
{
|
||||||
|
xml.setAttribute("Val_" + String(i), controllers[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void getXml(XmlElement &xml){
|
||||||
|
for (int i = 0; i < 255; ++i)
|
||||||
|
{
|
||||||
|
int tmp = xml.getIntAttribute("Val_" + String(i), controllers_default[i]);
|
||||||
|
if (tmp == 0){
|
||||||
|
tmp = controllers_default[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
controllers[i] = tmp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
|
@ -23,11 +23,9 @@
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "../Source/Engine/SynthEngine.h"
|
#include "../Source/Engine/SynthEngine.h"
|
||||||
class ButtonList : public ComboBox{
|
|
||||||
private :
|
class ButtonList : public ComboBox
|
||||||
int count;
|
{
|
||||||
Image kni;
|
|
||||||
int w2,h2;
|
|
||||||
public:
|
public:
|
||||||
ButtonList (Image k, int fh) : ComboBox("cb")
|
ButtonList (Image k, int fh) : ComboBox("cb")
|
||||||
{
|
{
|
||||||
|
@ -37,24 +35,71 @@ public:
|
||||||
w2 = k.getWidth();
|
w2 = k.getWidth();
|
||||||
}
|
}
|
||||||
//int addItem
|
//int addItem
|
||||||
void addChoise(String name)
|
|
||||||
|
// Source: https://git.iem.at/audioplugins/IEMPluginSuite/-/blob/master/resources/customComponents/ReverseSlider.h
|
||||||
|
public:
|
||||||
|
class ButtonListAttachment : public juce::AudioProcessorValueTreeState::ComboBoxAttachment
|
||||||
|
{
|
||||||
|
RangedAudioParameter* parameter = nullptr;
|
||||||
|
ButtonList* buttonListToControl = nullptr;
|
||||||
|
public:
|
||||||
|
ButtonListAttachment (juce::AudioProcessorValueTreeState& stateToControl,
|
||||||
|
const juce::String& parameterID,
|
||||||
|
ButtonList& buttonListToControl) : AudioProcessorValueTreeState::ComboBoxAttachment (stateToControl, parameterID, buttonListToControl), buttonListToControl(&buttonListToControl)
|
||||||
|
{
|
||||||
|
parameter = stateToControl.getParameter (parameterID);
|
||||||
|
buttonListToControl.setParameter (parameter);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
ButtonListAttachment (juce::AudioProcessorValueTreeState& stateToControl,
|
||||||
|
const juce::String& parameterID,
|
||||||
|
ComboBox& buttonListToControl) : AudioProcessorValueTreeState::ComboBoxAttachment (stateToControl, parameterID, buttonListToControl)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
void updateToSlider(){
|
||||||
|
float val = parameter->getValue();
|
||||||
|
//buttonListToControl->setValue(val, NotificationType::dontSendNotification);
|
||||||
|
//buttonListToControl->setValue(parameter->convertFrom0to1(val0to1), NotificationType::dontSendNotification);
|
||||||
|
buttonListToControl->setValue(val, NotificationType::dontSendNotification);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~ButtonListAttachment() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
void setParameter (const AudioProcessorParameter* p)
|
||||||
|
{
|
||||||
|
if (parameter == p)
|
||||||
|
return;
|
||||||
|
|
||||||
|
parameter = p;
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
void addChoice (String name)
|
||||||
{
|
{
|
||||||
addItem (name, ++count);
|
addItem (name, ++count);
|
||||||
}
|
}
|
||||||
|
|
||||||
float getValue()
|
float getValue()
|
||||||
{
|
{
|
||||||
return ((getSelectedId() - 1) / (float) (count - 1));
|
return ((getSelectedId() - 1) / (float) (count - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void setValue (float val, NotificationType notify)
|
void setValue (float val, NotificationType notify)
|
||||||
{
|
{
|
||||||
setSelectedId ((int) (val * (count - 1) + 1), notify);
|
setSelectedId ((int) (val * (count - 1) + 1), notify);
|
||||||
}
|
}
|
||||||
void paintOverChildren(Graphics& g)
|
|
||||||
|
void paintOverChildren (Graphics& g) override
|
||||||
{
|
{
|
||||||
int ofs = getSelectedId() - 1;
|
int ofs = getSelectedId() - 1;
|
||||||
g.drawImage(kni, 0, 0, getWidth(), getHeight(),
|
g.drawImage(kni, 0, 0, getWidth(), getHeight(), 0, h2 * ofs, w2, h2);
|
||||||
0, h2*ofs, w2, h2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int count;
|
||||||
|
Image kni;
|
||||||
|
int w2, h2;
|
||||||
|
const AudioProcessorParameter* parameter {nullptr};
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
==============================================================================
|
==============================================================================
|
||||||
This file is part of Obxd synthesizer.
|
This file is part of Obxd synthesizer.
|
||||||
|
|
||||||
Copyright © 2013-2014 Filatov Vadim
|
Copyright <EFBFBD> 2013-2014 Filatov Vadim
|
||||||
|
|
||||||
Contact author via email :
|
Contact author via email :
|
||||||
justdat_@_e1.ru
|
justdat_@_e1.ru
|
||||||
|
@ -23,6 +23,7 @@
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "../Source/Engine/SynthEngine.h"
|
#include "../Source/Engine/SynthEngine.h"
|
||||||
|
|
||||||
class Knob : public Slider
|
class Knob : public Slider
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -41,15 +42,58 @@ public:
|
||||||
kni = k;
|
kni = k;
|
||||||
};
|
};
|
||||||
|
|
||||||
void paint(Graphics& g)
|
// Source: https://git.iem.at/audioplugins/IEMPluginSuite/-/blob/master/resources/customComponents/ReverseSlider.h
|
||||||
|
public:
|
||||||
|
class KnobAttachment : public juce::AudioProcessorValueTreeState::SliderAttachment
|
||||||
|
{
|
||||||
|
RangedAudioParameter* parameter = nullptr;
|
||||||
|
Knob* sliderToControl = nullptr;
|
||||||
|
public:
|
||||||
|
KnobAttachment (juce::AudioProcessorValueTreeState& stateToControl,
|
||||||
|
const juce::String& parameterID,
|
||||||
|
Knob& sliderToControl) : AudioProcessorValueTreeState::SliderAttachment (stateToControl, parameterID, sliderToControl), sliderToControl(&sliderToControl)
|
||||||
|
{
|
||||||
|
parameter = stateToControl.getParameter (parameterID);
|
||||||
|
sliderToControl.setParameter (parameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*KnobAttachment (juce::AudioProcessorValueTreeState& stateToControl,
|
||||||
|
const juce::String& parameterID,
|
||||||
|
Slider& sliderToControl) : AudioProcessorValueTreeState::SliderAttachment (stateToControl, parameterID, sliderToControl)
|
||||||
|
{
|
||||||
|
}*/
|
||||||
|
|
||||||
|
void updateToSlider(){
|
||||||
|
float val = parameter->getValue();
|
||||||
|
//sliderToControl->setValue(parameter->convertFrom0to1(val0to1));
|
||||||
|
sliderToControl->setValue(val, NotificationType::dontSendNotification);
|
||||||
|
DBG(" Slider: " << sliderToControl->getName() << " " << sliderToControl->getValue() << " Parameter: "<< " " << parameter->getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~KnobAttachment() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
void setParameter (AudioProcessorParameter* p)
|
||||||
|
{
|
||||||
|
if (parameter == p)
|
||||||
|
return;
|
||||||
|
|
||||||
|
parameter = p;
|
||||||
|
updateText();
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
void paint (Graphics& g) override
|
||||||
{
|
{
|
||||||
int ofs = (int) ((getValue() - getMinimum()) / (getMaximum() - getMinimum()) * (numFr - 1));
|
int ofs = (int) ((getValue() - getMinimum()) / (getMaximum() - getMinimum()) * (numFr - 1));
|
||||||
g.drawImage(kni, 0, 0, getWidth(), getHeight(),
|
g.drawImage (kni, 0, 0, getWidth(), getHeight(), 0, h2 * ofs, w2, h2);
|
||||||
0, h2*ofs, w2, h2);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~Knob() override {};
|
||||||
private:
|
private:
|
||||||
Image kni;
|
Image kni;
|
||||||
int fh, numFr;
|
int fh, numFr;
|
||||||
int w2, h2;
|
int w2, h2;
|
||||||
|
AudioProcessorParameter* parameter {nullptr};
|
||||||
};
|
};
|
|
@ -2,7 +2,7 @@
|
||||||
==============================================================================
|
==============================================================================
|
||||||
This file is part of Obxd synthesizer.
|
This file is part of Obxd synthesizer.
|
||||||
|
|
||||||
Copyright © 2013-2014 Filatov Vadim
|
Copyright <EFBFBD> 2013-2014 Filatov Vadim
|
||||||
|
|
||||||
Contact author via email :
|
Contact author via email :
|
||||||
justdat_@_e1.ru
|
justdat_@_e1.ru
|
||||||
|
@ -23,10 +23,10 @@
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "../Source/Engine/SynthEngine.h"
|
#include "../Source/Engine/SynthEngine.h"
|
||||||
|
|
||||||
class TooglableButton : public ImageButton
|
class TooglableButton : public ImageButton
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool toogled;
|
|
||||||
TooglableButton (Image k) : ImageButton()
|
TooglableButton (Image k) : ImageButton()
|
||||||
{
|
{
|
||||||
//this->setImages
|
//this->setImages
|
||||||
|
@ -38,7 +38,47 @@ public:
|
||||||
h2 = height / 2;
|
h2 = height / 2;
|
||||||
this->setClickingTogglesState (true);
|
this->setClickingTogglesState (true);
|
||||||
}
|
}
|
||||||
void clicked()
|
~TooglableButton() override{
|
||||||
|
|
||||||
|
};
|
||||||
|
// Source: https://git.iem.at/audioplugins/IEMPluginSuite/-/blob/master/resources/customComponents/ReverseSlider.h
|
||||||
|
public:
|
||||||
|
class ToggleAttachment : public juce::AudioProcessorValueTreeState::ButtonAttachment
|
||||||
|
{
|
||||||
|
RangedAudioParameter* parameter = nullptr;
|
||||||
|
TooglableButton* buttonToControl = nullptr;
|
||||||
|
public:
|
||||||
|
ToggleAttachment (juce::AudioProcessorValueTreeState& stateToControl,
|
||||||
|
const juce::String& parameterID,
|
||||||
|
TooglableButton& buttonToControl) : AudioProcessorValueTreeState::ButtonAttachment (stateToControl, parameterID, buttonToControl), buttonToControl(&buttonToControl)
|
||||||
|
{
|
||||||
|
parameter = stateToControl.getParameter (parameterID);
|
||||||
|
buttonToControl.setParameter (parameter);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
ToggleAttachment (juce::AudioProcessorValueTreeState& stateToControl,
|
||||||
|
const juce::String& parameterID,
|
||||||
|
Button& buttonToControl) : AudioProcessorValueTreeState::ButtonAttachment (stateToControl, parameterID, buttonToControl)
|
||||||
|
{
|
||||||
|
}*/
|
||||||
|
void updateToSlider(){
|
||||||
|
float val = parameter->getValue();
|
||||||
|
//buttonToControl->setValue(parameter->convertFrom0to1(val0to1), NotificationType::dontSendNotification);
|
||||||
|
buttonToControl->setValue(val, NotificationType::dontSendNotification);
|
||||||
|
}
|
||||||
|
virtual ~ToggleAttachment() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
void setParameter (const AudioProcessorParameter* p)
|
||||||
|
{
|
||||||
|
if (parameter == p)
|
||||||
|
return;
|
||||||
|
|
||||||
|
parameter = p;
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
void clicked() override
|
||||||
{
|
{
|
||||||
toogled = ! toogled;
|
toogled = ! toogled;
|
||||||
//this->setColour(1,Colours::blue);
|
//this->setColour(1,Colours::blue);
|
||||||
|
@ -50,23 +90,28 @@ public:
|
||||||
Button::clicked();
|
Button::clicked();
|
||||||
|
|
||||||
};
|
};
|
||||||
void paintButton(Graphics& g, bool isMouseOverButton, bool isButtonDown)
|
|
||||||
|
void paintButton (Graphics& g, bool isMouseOverButton, bool isButtonDown) override
|
||||||
{
|
{
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
|
|
||||||
if (toogled)
|
if (toogled)
|
||||||
{
|
{
|
||||||
offset = 1;
|
offset = 1;
|
||||||
}
|
}
|
||||||
g.drawImage(kni, 0, 0, getWidth(), getHeight(),
|
|
||||||
0, offset *h2, w2,h2);
|
g.drawImage(kni, 0, 0, getWidth(), getHeight(), 0, offset * h2, w2, h2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setValue (float state, int notify)
|
void setValue (float state, int notify)
|
||||||
{
|
{
|
||||||
if (state > 0.5)
|
if (state > 0.5)
|
||||||
toogled = true;
|
toogled = true;
|
||||||
else toogled = false;
|
else toogled = false;
|
||||||
|
|
||||||
repaint();
|
repaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
float getValue()
|
float getValue()
|
||||||
{
|
{
|
||||||
if (toogled)
|
if (toogled)
|
||||||
|
@ -77,7 +122,11 @@ public:
|
||||||
//{
|
//{
|
||||||
// g.drawImageTransformed(kni,AffineTransform::rotation(((getValue() - getMinimum())/(getMaximum() - getMinimum()))*float_Pi - float_Pi*2));
|
// g.drawImageTransformed(kni,AffineTransform::rotation(((getValue() - getMinimum())/(getMaximum() - getMinimum()))*float_Pi - float_Pi*2));
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
bool toogled;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Image kni;
|
Image kni;
|
||||||
int width, height, w2, h2;
|
int width, height, w2, h2;
|
||||||
|
const AudioProcessorParameter* parameter {nullptr};
|
||||||
};
|
};
|
Before Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 210 KiB |
Before Width: | Height: | Size: 171 KiB |
Before Width: | Height: | Size: 7.7 KiB |