2
0
Fork 0

Merge pull request #19 from reales/development

2.0 release
This commit is contained in:
reales 2020-08-01 12:02:00 +02:00 committed by GitHub
commit 640eeb8036
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
107 changed files with 3299 additions and 1412 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 507 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 742 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 KiB

View 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.}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 828 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

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

View file

@ -1,28 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<JUCERPROJECT id="mxW328" name="Obxd" projectType="audioplug" version="1.5.0"
bundleIdentifier="com.Datsounds.Obxd" includeBinaryInAppConfig="1"
buildVST="1" buildVST3="1" buildAU="1" buildRTAS="0" buildAAX="0"
<JUCERPROJECT id="mxW328" name="OB-Xd" projectType="audioplug" version="2.0.0"
bundleIdentifier="com.discoDSP.Obxd" includeBinaryInAppConfig="1"
pluginName="OB-Xd" pluginDesc="Emulation of famous OB-X, OB-Xa and OB-8 synths"
pluginManufacturer="Datsounds" pluginManufacturerCode="Dats"
pluginCode="Obxd" pluginChannelConfigs="{0, 2}" pluginIsSynth="1"
pluginWantsMidiIn="1" pluginProducesMidiOut="0" pluginSilenceInIsSilenceOut="0"
pluginEditorRequiresKeys="0" pluginAUExportPrefix="" pluginRTASCategory="2048"
aaxIdentifier="" pluginAAXCategory="" jucerVersion="5.4.4" companyName="2Dat"
companyWebsite="https://www.discodsp.com/obxd/" companyEmail=""
buildAUv3="0" pluginIsMidiEffectPlugin="0" pluginFormats="buildAU,buildStandalone,buildVST,buildVST3"
pluginCharacteristicsValue="pluginIsSynth,pluginWantsMidiIn"
pluginManufacturer="discoDSP" pluginManufacturerCode="DDSP" pluginCode="Obxd"
pluginChannelConfigs="{0, 2}" pluginIsSynth="1" pluginWantsMidiIn="1"
pluginProducesMidiOut="0" pluginSilenceInIsSilenceOut="0" pluginEditorRequiresKeys="0"
pluginAUExportPrefix="" pluginRTASCategory="2048" aaxIdentifier=""
pluginAAXCategory="" jucerVersion="5.4.7" companyName="discoDSP"
companyWebsite="https://www.discodsp.com/" companyEmail="contactus@discodsp.com"
pluginIsMidiEffectPlugin="0" pluginCharacteristicsValue="pluginIsSynth,pluginWantsMidiIn"
pluginFormats="buildAU,buildStandalone,buildVST3" buildVST="0"
buildVST3="1" buildAU="1" buildAUv3="0" buildRTAS="0" buildAAX="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="{5F0B15D1-4D92-B2FF-5904-9CF4C3CE645F}" name="Images">
<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="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 id="{6995BDF2-263F-3CA7-8CA4-4E21F325477A}" name="Gui">
<FILE id="zJoidp" name="ButtonList.h" compile="0" resource="0" file="Source/Gui/ButtonList.h"/>
@ -65,118 +61,105 @@
</GROUP>
</MAINGROUP>
<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>
<CONFIGURATION name="Debug" isDebug="1" optimisation="1" targetName="Obxd" stripLocalSymbols="0"
osxCompatibility="10.6 SDK" linkTimeOptimisation="0"/>
<CONFIGURATION name="Release" isDebug="0" optimisation="3" targetName="Obxd"
stripLocalSymbols="1" osxCompatibility="10.6 SDK" linkTimeOptimisation="0"
osxArchitecture="64BitIntel"/>
<CONFIGURATION name="Debug" isDebug="1" optimisation="1" targetName="OB-Xd"
stripLocalSymbols="0" osxCompatibility="10.6 SDK" linkTimeOptimisation="0"/>
<CONFIGURATION name="Release" isDebug="0" optimisation="3" targetName="OB-Xd"
stripLocalSymbols="1" osxArchitecture="64BitIntel" linkTimeOptimisation="1"/>
<CONFIGURATION name="Demo" isDebug="0" optimisation="3" targetName="OB-Xd" stripLocalSymbols="1"
osxArchitecture="64BitIntel" linkTimeOptimisation="1" defines="DEMOVERSION=1"/>
</CONFIGURATIONS>
<MODULEPATHS>
<MODULEPATH id="juce_opengl" path="~/JUCE/modules"/>
<MODULEPATH id="juce_gui_extra" path="~/JUCE/modules"/>
<MODULEPATH id="juce_gui_basics" path="~/JUCE/modules"/>
<MODULEPATH id="juce_graphics" path="~/JUCE/modules"/>
<MODULEPATH id="juce_events" path="~/JUCE/modules"/>
<MODULEPATH id="juce_data_structures" path="~/JUCE/modules"/>
<MODULEPATH id="juce_core" path="~/JUCE/modules"/>
<MODULEPATH id="juce_audio_processors" path="~/JUCE/modules"/>
<MODULEPATH id="juce_audio_plugin_client" path="~/JUCE/modules"/>
<MODULEPATH id="juce_audio_formats" path="~/JUCE/modules"/>
<MODULEPATH id="juce_audio_devices" path="~/JUCE/modules"/>
<MODULEPATH id="juce_audio_basics"/>
<MODULEPATH id="juce_audio_utils" path="~/JUCE/modules"/>
<MODULEPATH id="juce_opengl" path="Modules"/>
<MODULEPATH id="juce_gui_extra" path="Modules"/>
<MODULEPATH id="juce_gui_basics" path="Modules"/>
<MODULEPATH id="juce_graphics" path="Modules"/>
<MODULEPATH id="juce_events" path="Modules"/>
<MODULEPATH id="juce_data_structures" path="Modules"/>
<MODULEPATH id="juce_core" path="Modules"/>
<MODULEPATH id="juce_audio_processors" path="Modules"/>
<MODULEPATH id="juce_audio_plugin_client" path="Modules"/>
<MODULEPATH id="juce_audio_formats" path="Modules"/>
<MODULEPATH id="juce_audio_devices" path="Modules"/>
<MODULEPATH id="juce_audio_basics" path="Modules"/>
<MODULEPATH id="juce_audio_utils" path="Modules"/>
</MODULEPATHS>
</XCODE_MAC>
<LINUX_MAKE targetFolder="Builds/LinuxMakefile" extraLinkerFlags="-no-pie">
<CONFIGURATIONS>
<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>
<MODULEPATHS>
<MODULEPATH id="juce_opengl" path="~/JUCE/modules"/>
<MODULEPATH id="juce_gui_extra" path="~/JUCE/modules"/>
<MODULEPATH id="juce_gui_basics" path="~/JUCE/modules"/>
<MODULEPATH id="juce_graphics" path="~/JUCE/modules"/>
<MODULEPATH id="juce_events" path="~/JUCE/modules"/>
<MODULEPATH id="juce_data_structures" path="~/JUCE/modules"/>
<MODULEPATH id="juce_core" path="~/JUCE/modules"/>
<MODULEPATH id="juce_audio_utils" path="~/JUCE/modules"/>
<MODULEPATH id="juce_audio_processors" path="~/JUCE/modules"/>
<MODULEPATH id="juce_audio_plugin_client" path="~/JUCE/modules"/>
<MODULEPATH id="juce_audio_formats" path="~/JUCE/modules"/>
<MODULEPATH id="juce_audio_devices" path="~/JUCE/modules"/>
<MODULEPATH id="juce_audio_basics"/>
<MODULEPATH id="juce_opengl" path="Modules"/>
<MODULEPATH id="juce_gui_extra" path="Modules"/>
<MODULEPATH id="juce_gui_basics" path="Modules"/>
<MODULEPATH id="juce_graphics" path="Modules"/>
<MODULEPATH id="juce_events" path="Modules"/>
<MODULEPATH id="juce_data_structures" path="Modules"/>
<MODULEPATH id="juce_core" path="Modules"/>
<MODULEPATH id="juce_audio_utils" path="Modules"/>
<MODULEPATH id="juce_audio_processors" path="Modules"/>
<MODULEPATH id="juce_audio_plugin_client" path="Modules"/>
<MODULEPATH id="juce_audio_formats" path="Modules"/>
<MODULEPATH id="juce_audio_devices" path="Modules"/>
<MODULEPATH id="juce_audio_basics" path="Modules"/>
</MODULEPATHS>
</LINUX_MAKE>
<VS2013 targetFolder="Builds/VisualStudio2013">
<VS2019 targetFolder="Builds/VisualStudio2019" smallIcon="nnY63W" bigIcon="nnY63W"
vstLegacyFolder="Modules/vstsdk2.4" vst3Folder="Modules/vstsdk3">
<CONFIGURATIONS>
<CONFIGURATION name="Debug" winWarningLevel="4" generateManifest="1" winArchitecture="x64"
isDebug="1" optimisation="3" targetName="Obxd"/>
<CONFIGURATION name="Release64" winWarningLevel="4" generateManifest="1" winArchitecture="x64"
isDebug="0" optimisation="3" targetName="Obxd64" useRuntimeLibDLL="0"/>
<CONFIGURATION name="Release32" winWarningLevel="4" generateManifest="1" winArchitecture="32-bit"
isDebug="0" optimisation="3" targetName="Obxd" useRuntimeLibDLL="0"/>
<CONFIGURATION isDebug="1" name="Debug" useRuntimeLibDLL="0" targetName="OB-Xd"
headerPath="../../Modules/asiosdk2.3.2/common"/>
<CONFIGURATION isDebug="0" name="Release64" useRuntimeLibDLL="0" winArchitecture="x64"
targetName="OB-Xd" headerPath="../../Modules/asiosdk2.3.2/common"/>
<CONFIGURATION isDebug="0" name="Demo64" useRuntimeLibDLL="0" winArchitecture="x64"
targetName="OB-Xd" headerPath="../../Modules/asiosdk2.3.2/common"
defines="DEMOVERSION=1"/>
</CONFIGURATIONS>
<MODULEPATHS>
<MODULEPATH id="juce_opengl" path="modules"/>
<MODULEPATH id="juce_gui_extra" path="modules"/>
<MODULEPATH id="juce_gui_basics" path="modules"/>
<MODULEPATH id="juce_graphics" path="modules"/>
<MODULEPATH id="juce_events" path="modules"/>
<MODULEPATH id="juce_data_structures" path="modules"/>
<MODULEPATH id="juce_core" path="modules"/>
<MODULEPATH id="juce_audio_utils" path="modules"/>
<MODULEPATH id="juce_audio_processors" path="modules"/>
<MODULEPATH id="juce_audio_plugin_client" path="modules"/>
<MODULEPATH id="juce_audio_formats" path="modules"/>
<MODULEPATH id="juce_audio_devices" 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"/>
<MODULEPATH id="juce_opengl" path="Modules"/>
<MODULEPATH id="juce_gui_extra" path="Modules"/>
<MODULEPATH id="juce_gui_basics" path="Modules"/>
<MODULEPATH id="juce_graphics" path="Modules"/>
<MODULEPATH id="juce_events" path="Modules"/>
<MODULEPATH id="juce_data_structures" path="Modules"/>
<MODULEPATH id="juce_core" path="Modules"/>
<MODULEPATH id="juce_audio_utils" path="Modules"/>
<MODULEPATH id="juce_audio_processors" path="Modules"/>
<MODULEPATH id="juce_audio_plugin_client" path="Modules"/>
<MODULEPATH id="juce_audio_formats" path="Modules"/>
<MODULEPATH id="juce_audio_devices" path="Modules"/>
<MODULEPATH id="juce_audio_basics" path="Modules"/>
</MODULEPATHS>
</VS2019>
<VS2017 targetFolder="Builds/VisualStudio2017">
<VS2017 targetFolder="Builds/VisualStudio2017" vstLegacyFolder="Modules/vstsdk2.4"
vst3Folder="Modules/vstsdk3">
<CONFIGURATIONS>
<CONFIGURATION isDebug="1" name="Debug"/>
<CONFIGURATION isDebug="0" name="Release32" winArchitecture="Win32"/>
<CONFIGURATION isDebug="0" name="Release64" winArchitecture="x64"/>
<CONFIGURATION isDebug="1" name="Debug" targetName="OB-Xd" headerPath="../../Modules/asiosdk2.3.2/common"/>
<CONFIGURATION isDebug="0" name="Release64" winArchitecture="x64" targetName="OB-Xd"
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>
<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"/>
<MODULEPATH id="juce_opengl" path="Modules"/>
<MODULEPATH id="juce_gui_extra" path="Modules"/>
<MODULEPATH id="juce_gui_basics" path="Modules"/>
<MODULEPATH id="juce_graphics" path="Modules"/>
<MODULEPATH id="juce_events" path="Modules"/>
<MODULEPATH id="juce_data_structures" path="Modules"/>
<MODULEPATH id="juce_core" path="Modules"/>
<MODULEPATH id="juce_audio_utils" path="Modules"/>
<MODULEPATH id="juce_audio_processors" path="Modules"/>
<MODULEPATH id="juce_audio_plugin_client" path="Modules"/>
<MODULEPATH id="juce_audio_formats" path="Modules"/>
<MODULEPATH id="juce_audio_devices" path="Modules"/>
<MODULEPATH id="juce_audio_basics" path="Modules"/>
</MODULEPATHS>
</VS2017>
</EXPORTFORMATS>

View file

@ -1,15 +1,18 @@
# discoDSP OB-Xd
Download binaries at https://www.discodsp.com/obxd/
![](https://www.discodsp.com/img/obxd.png)
# 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.
Also thanks to all KVR members for making the amazing skins!
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.
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.

View file

@ -25,7 +25,7 @@
#include "ObxdVoice.h"
enum ObxdParameters
{
UNDEFINED,
UNDEFINED = 0,
MIDILEARN,
VOLUME,
VOICE_COUNT,

View file

@ -2,7 +2,7 @@
==============================================================================
This file is part of Obxd synthesizer.
Copyright © 2013-2014 Filatov Vadim
Copyright © 2013-2014 Filatov Vadim
Contact author via email :
justdat_@_e1.ru
@ -23,13 +23,286 @@
*/
#pragma once
#include "SynthEngine.h"
#include "ParamsEnum.h"
#include "../JuceLibraryCode/JuceHeader.h"
class MidiMap
{
public:
int controllers[255];
int controllers_default[255];
bool loaded = false;
MidiMap()
{
for(int i = 0 ; i < 255;i++)
reset();
set_default();
}
void reset(){
for(int i = 0 ; i < 255;i++){
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;
}
}
};

View file

@ -23,11 +23,9 @@
*/
#pragma once
#include "../Source/Engine/SynthEngine.h"
class ButtonList : public ComboBox{
private :
int count;
Image kni;
int w2,h2;
class ButtonList : public ComboBox
{
public:
ButtonList (Image k, int fh) : ComboBox("cb")
{
@ -37,24 +35,71 @@ public:
w2 = k.getWidth();
}
//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);
}
float getValue()
{
return ((getSelectedId() - 1) / (float) (count - 1));
}
void setValue (float val, NotificationType notify)
{
setSelectedId ((int) (val * (count - 1) + 1), notify);
}
void paintOverChildren(Graphics& g)
void paintOverChildren (Graphics& g) override
{
int ofs = getSelectedId() - 1;
g.drawImage(kni, 0, 0, getWidth(), getHeight(),
0, h2*ofs, w2, h2);
g.drawImage(kni, 0, 0, getWidth(), getHeight(), 0, h2 * ofs, w2, h2);
}
private:
int count;
Image kni;
int w2, h2;
const AudioProcessorParameter* parameter {nullptr};
};

View file

@ -2,7 +2,7 @@
==============================================================================
This file is part of Obxd synthesizer.
Copyright © 2013-2014 Filatov Vadim
Copyright <EFBFBD> 2013-2014 Filatov Vadim
Contact author via email :
justdat_@_e1.ru
@ -23,6 +23,7 @@
*/
#pragma once
#include "../Source/Engine/SynthEngine.h"
class Knob : public Slider
{
public:
@ -41,15 +42,58 @@ public:
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));
g.drawImage(kni, 0, 0, getWidth(), getHeight(),
0, h2*ofs, w2, h2);
g.drawImage (kni, 0, 0, getWidth(), getHeight(), 0, h2 * ofs, w2, h2);
}
~Knob() override {};
private:
Image kni;
int fh, numFr;
int w2, h2;
AudioProcessorParameter* parameter {nullptr};
};

View file

@ -2,7 +2,7 @@
==============================================================================
This file is part of Obxd synthesizer.
Copyright © 2013-2014 Filatov Vadim
Copyright <EFBFBD> 2013-2014 Filatov Vadim
Contact author via email :
justdat_@_e1.ru
@ -23,10 +23,10 @@
*/
#pragma once
#include "../Source/Engine/SynthEngine.h"
class TooglableButton : public ImageButton
{
public:
bool toogled;
TooglableButton (Image k) : ImageButton()
{
//this->setImages
@ -38,7 +38,47 @@ public:
h2 = height / 2;
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;
//this->setColour(1,Colours::blue);
@ -50,23 +90,28 @@ public:
Button::clicked();
};
void paintButton(Graphics& g, bool isMouseOverButton, bool isButtonDown)
void paintButton (Graphics& g, bool isMouseOverButton, bool isButtonDown) override
{
int offset = 0;
if (toogled)
{
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)
{
if (state > 0.5)
toogled = true;
else toogled = false;
repaint();
}
float getValue()
{
if (toogled)
@ -77,7 +122,11 @@ public:
//{
// g.drawImageTransformed(kni,AffineTransform::rotation(((getValue() - getMinimum())/(getMaximum() - getMinimum()))*float_Pi - float_Pi*2));
//}
bool toogled;
private:
Image kni;
int width, height, w2, h2;
const AudioProcessorParameter* parameter {nullptr};
};

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 210 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 171 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

Some files were not shown because too many files have changed in this diff Show more