├── .gitignore
├── Design.txt
├── Digits Manual.pdf
├── License.txt
├── README
├── graphics
└── digits
│ ├── CosNoiseRockerV.png
│ ├── CosSinRockerV.png
│ ├── DialHandle_LCD.png
│ ├── Dial_LCD.png
│ ├── DigitsBG.png
│ ├── DigitsBG.xcf
│ ├── HSliderBG.png
│ ├── HSliderNub.png
│ └── Logo.png
├── linux
└── Digits.make
├── mac
├── Digits-Info.plist
└── Main.xcodeproj
│ ├── PDVST.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ ├── xcshareddata
│ │ │ ├── PDVST.xccheckout
│ │ │ └── PDVST.xcscmblueprint
│ │ └── xcuserdata
│ │ │ └── louis.xcuserdatad
│ │ │ ├── UserInterfaceState.xcuserstate
│ │ │ └── WorkspaceSettings.xcsettings
│ └── xcuserdata
│ │ └── louis.xcuserdatad
│ │ └── xcschemes
│ │ ├── Digits.xcscheme
│ │ ├── DigitsBench.xcscheme
│ │ └── xcschememanagement.plist
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ ├── xcshareddata
│ │ ├── Main.xcscmblueprint
│ │ ├── PDVST.xccheckout
│ │ └── PDVST.xcscmblueprint
│ └── xcuserdata
│ │ └── louis.xcuserdatad
│ │ ├── UserInterfaceState.xcuserstate
│ │ └── WorkspaceSettings.xcsettings
│ └── xcuserdata
│ └── louis.xcuserdatad
│ ├── xcdebugger
│ └── Breakpoints_v2.xcbkptlist
│ └── xcschemes
│ ├── Digits.xcscheme
│ └── xcschememanagement.plist
├── patches
├── Basses
│ ├── 404.fxp
│ ├── ChorusBass.fxp
│ ├── ElBass II.fxp
│ ├── ElBass.fxp
│ ├── EyeEye.fxp
│ ├── FMBass.fxp
│ ├── FlangerBass.fxp
│ ├── LazyBass.fxp
│ ├── PWMBass.fxp
│ ├── PhatterBass.fxp
│ ├── RubberBand.fxp
│ ├── Splatter.fxp
│ ├── SquareBass.fxp
│ ├── Sub Fuzz.fxp
│ ├── Sub.fxp
│ └── ThunkyBass.fxp
├── Chords
│ ├── BrassEns.fxp
│ ├── ElectricOrgan II.fxp
│ ├── ElectricOrgan.fxp
│ ├── FunKeyRiffs.fxp
│ ├── Funkdafy II.fxp
│ ├── Funkdafy.fxp
│ ├── FuzzBox.fxp
│ ├── HiToneChords.fxp
│ ├── MusicBox.fxp
│ ├── ToySynthPiano II.fxp
│ └── ToySynthPiano.fxp
├── DemoBank
│ ├── BrassySlicerLead.fxp
│ ├── ChorusBass.fxp
│ ├── EasternArpeg.fxp
│ ├── ElBass.fxp
│ ├── FutureTines.fxp
│ ├── GhostChoir.fxp
│ ├── InitTone.fxp
│ ├── Jar.fxp
│ ├── SIDLead.fxp
│ ├── SeriousWhales.fxp
│ ├── StringEns.fxp
│ └── ThunkyBass.fxp
├── Leads
│ ├── AttackPoly.fxp
│ ├── BellLead.fxp
│ ├── BrassLead.fxp
│ ├── BrassLeadMellow.fxp
│ ├── BrassySlicerLead.fxp
│ ├── Chiff.fxp
│ ├── FierceLead.fxp
│ ├── FoggyCliff.fxp
│ ├── FuzzyHoover.fxp
│ ├── HardCorpLead.fxp
│ ├── HarshLead.fxp
│ ├── HollowTube.fxp
│ ├── Hyperflute.fxp
│ ├── Mystery.fxp
│ ├── RavingLunatic.fxp
│ ├── ResoLead.fxp
│ ├── SIDLead II.fxp
│ ├── SIDLead.fxp
│ ├── SeriousWhales.fxp
│ ├── SpaceOboe.fxp
│ ├── SynReed.fxp
│ └── ViolinLead.fxp
├── Pads
│ ├── Atlantis.fxp
│ ├── BellBrassPad.fxp
│ ├── Choir II.fxp
│ ├── DreamPad.fxp
│ ├── FilteryChorusy.fxp
│ ├── FilteryPads.fxp
│ ├── FlangerStringEns.fxp
│ ├── GhostChoir.fxp
│ ├── Jar II.fxp
│ ├── Jar.fxp
│ ├── Planetary.fxp
│ ├── StringEns.fxp
│ ├── StringEnsBright.fxp
│ ├── TheCreeps.fxp
│ └── WinteryPad.fxp
├── Stabs
│ ├── AlienChimes.fxp
│ ├── Bells.fxp
│ ├── Darius.fxp
│ ├── EasternArpeg.fxp
│ ├── FutureTines.fxp
│ ├── Ghosts.fxp
│ ├── HouseStabs.fxp
│ ├── POW.fxp
│ ├── Quack.fxp
│ ├── Soft Mallet.fxp
│ ├── ThunkyArp.fxp
│ └── VelocityRubber.fxp
└── Sweeps
│ ├── FunnyBone.fxp
│ ├── HiSweep-Overdrive.fxp
│ ├── HiSweep.fxp
│ ├── HowlingTubeSweep.fxp
│ ├── MeanSweeps.fxp
│ ├── Riser I.fxp
│ ├── Riser II.fxp
│ ├── Riser III.fxp
│ ├── Riser IV.fxp
│ ├── SeriousPad.fxp
│ ├── TubularBellSweep.fxp
│ ├── VisciousFM 2.fxp
│ ├── VisciousFM.fxp
│ ├── Whoosh.fxp
│ └── WobblySweep.fxp
├── src
├── components
│ ├── BufferManager.cpp
│ ├── BufferManager.h
│ ├── Chorus.cpp
│ ├── Chorus.h
│ ├── Compressor.cpp
│ ├── Compressor.h
│ ├── Contour.cpp
│ ├── Contour.h
│ ├── FauxVst.h
│ ├── FilterBank.h
│ ├── LFO.h
│ ├── LGDebug.h
│ ├── NoiseGen.cpp
│ ├── NoiseGen.h
│ ├── Oversampler.cpp
│ ├── Oversampler.h
│ ├── PatchBankList.h
│ ├── PatchBankListMac.cpp
│ ├── PatchBankListMac.h
│ ├── PatchBankListWin.cpp
│ ├── PatchBankListWin.h
│ ├── SndBuf.cpp
│ ├── SndBuf.h
│ ├── Tables.cpp
│ ├── Tables.h
│ ├── Voice.cpp
│ └── Voice.h
└── digits
│ ├── DigitsBench.cpp
│ ├── EditorWindow.cpp
│ ├── EditorWindow.h
│ ├── Patches.cpp
│ ├── Patches.h
│ ├── PhaseDist.cpp
│ ├── PhaseDist.h
│ ├── ResoGen.cpp
│ ├── ResoGen.h
│ ├── VstCore.cpp
│ └── VstCore.h
└── windows
├── Digits.rc
├── DigitsVST.vcxproj
├── Main.VC.opendb
├── Main.sln
└── vstplug.def
/.gitignore:
--------------------------------------------------------------------------------
1 | *.o
2 |
--------------------------------------------------------------------------------
/Design.txt:
--------------------------------------------------------------------------------
1 | Hi! Since I've opened up the source for Digits, I wanted to take a second to
2 | talk about some of the design decisions I made while writing it.
3 |
4 | If you didn't know, Digits started out as a simple project for me to work on
5 | while I was hanging out at hacker spaces. It started pretty modestly. The
6 | first version only sported one LFO, only had the delay effect, no filters,
7 | and the envelopes were trapezoidal. It has come a long way!
8 |
9 | One thing I was particularly happy with was how the phase distortion algorithm
10 | came out. While some examples I've seen use different routines for different
11 | waveshapes, Digits uses a consistent formula and just changes settings to
12 | produce all of its waveforms. For example, saw means you run the shaper
13 | once per cycle. Square means you run the shaper twice per cycle. Skew means
14 | that you alter position of the node where the knee in the phase distortion is.
15 | The pulse-width modulation is faked in by applying a second shaper to the
16 | entire generator (so, a shaper within a shaper). This is also why the
17 | pulse-width modulation causes the waveform to brighten as the pulse narrows.
18 |
19 | The design of Digits is not without some regrets: I went with a control rate
20 | for the main audio loop instead of making it 100% sample-accurate. This is
21 | because that's how I always did synthesizers, and this is how a lot of older
22 | synths operated. It makes for a messy loop and causes a tiny amount of jitter.
23 | A much better way of doing it would be to render the number of samples between
24 | MIDI events precisely.
25 |
26 | A big problem in the user interface is the Shaper Lock in the filter section.
27 | It provides a lot of flexibility, but at the cost of being unorthodox and
28 | confusing to many users.
29 |
30 | My final regret that I want to talk about is how much of a mess the UI code
31 | is! It really grew a lot. If I did it again, I'd leverage classes more to
32 | clean it up. This ended up looking more the way it'd look if you just wrote
33 | it in flat C. Oops.
34 |
35 | Optimization: While the oscillators look like they are doing a lot of heavy
36 | lifting, they are actually fairly fast. However, the LFOs and especially the
37 | envelopes are slow. I would suggest making a table-driven envelope to replace
38 | it. Be aware though that the attack is an inverse curve from the decay shape.
39 |
40 | You might also notice that the oscillator uses an uninterpolated lookup. I
41 | investigated on a few devices, seeing whether the increased table size might
42 | cause a CPU cache miss, or whether it would drastically hurt the sound
43 | quality. It was very fast without interpolation and did not appear to hurt
44 | the sound quality too much, so that is what I went for. My secret shame.
45 |
46 | Lastly, there are many, many areas where you could improve the speed with
47 | vector processing. However, this particular version of the Digits engine only
48 | uses basic C++ code and no inline assembly or vector intrinsics.
49 |
50 | As far as sound quality goes, it can alias a little bit at 44 or 48khz. I
51 | started on an oversampling routine but never fit it into the code (this is
52 | all done as an after-work hobby after all). Though aliasing is combated a bit
53 | by toning down the shaper at higher pitches, a little oversampling might
54 | go a long way.
55 |
56 | Anyway, that's about it! Happy hacking; be sure to read the License.txt!
57 | (Digits is licensed under GPL)
58 |
59 | Cheers,
60 | Louis "Extent of the Jam" Gorenfeld
61 | louis.gorenfeld@gmail.com
62 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/Digits Manual.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/Digits Manual.pdf
--------------------------------------------------------------------------------
/README:
--------------------------------------------------------------------------------
1 | # Digits VST
2 |
3 | http://www.extentofthejam.com/
4 |
5 | ## license
6 |
7 | Please read License.txt! :) Digits is licensed under the GPL.
8 |
9 | ## building
10 |
11 | ### prerequisites
12 |
13 | You'll need the Steinberg VST SDK downloaded into the sdks/vstsdk2.4 directory.
14 |
15 | ### linux
16 |
17 | cd linux
18 | make -f Digits.make
19 |
--------------------------------------------------------------------------------
/graphics/digits/CosNoiseRockerV.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/graphics/digits/CosNoiseRockerV.png
--------------------------------------------------------------------------------
/graphics/digits/CosSinRockerV.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/graphics/digits/CosSinRockerV.png
--------------------------------------------------------------------------------
/graphics/digits/DialHandle_LCD.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/graphics/digits/DialHandle_LCD.png
--------------------------------------------------------------------------------
/graphics/digits/Dial_LCD.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/graphics/digits/Dial_LCD.png
--------------------------------------------------------------------------------
/graphics/digits/DigitsBG.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/graphics/digits/DigitsBG.png
--------------------------------------------------------------------------------
/graphics/digits/DigitsBG.xcf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/graphics/digits/DigitsBG.xcf
--------------------------------------------------------------------------------
/graphics/digits/HSliderBG.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/graphics/digits/HSliderBG.png
--------------------------------------------------------------------------------
/graphics/digits/HSliderNub.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/graphics/digits/HSliderNub.png
--------------------------------------------------------------------------------
/graphics/digits/Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/graphics/digits/Logo.png
--------------------------------------------------------------------------------
/linux/Digits.make:
--------------------------------------------------------------------------------
1 | TARGET = DigitsVST.so
2 |
3 | CPP = g++
4 | CXXFLAGS = -Wall -O3 -D__cdecl="" -I../sdks/vstsdk2.4 -fvisibility=hidden -DNO_EDITOR -DDIGITS_PRO -I../src/digits -I../src/components -fPIC
5 |
6 | CSOURCES = ../src/components/BufferManager.cpp \
7 | ../src/components/Chorus.cpp ../src/components/Contour.cpp ../src/digits/PhaseDist.cpp ../src/digits/ResoGen.cpp ../src/components/SndBuf.cpp ../src/components/Tables.cpp ../src/components/Voice.cpp ../src/digits/VstCore.cpp ../sdks/vstsdk2.4/public.sdk/source/vst2.x/vstplugmain.cpp
8 | OBJS = $(CSOURCES:.cpp=.o)
9 | ALLOBJ = $(OBJS) $(VSTSDKDIR)/public.sdk/source/vst2.x/audioeffect.o $(VSTSDKDIR)/public.sdk/source/vst2.x/audioeffectx.o
10 | SRCDIR = ../src
11 | VSTSDKDIR = ../sdks/vstsdk2.4
12 |
13 | ${TARGET} : $(ALLOBJ)
14 | $(CPP) -fPIC -DPIC -shared ${CXXFLAGS} -o ${TARGET} ${ALLOBJ}
15 | strip ${TARGET}
16 |
17 | %.o : $(SRCDIR)/%.cpp
18 | $(CPP) -c $< -o $@ $(CXXFLAGS)
19 |
20 | #.c.o :
21 | # ${CC} ${CC_FLAGS} -c $<
22 |
23 | #.cpp.o:
24 | # ${CC} ${CC_FLAGS} -c $<
25 |
26 | clean :
27 | rm -f ${TARGET}
28 | rm -f ${ALLOBJ}
29 | rm -f *~
30 | rm -f source/*~
31 |
32 |
33 |
--------------------------------------------------------------------------------
/mac/Digits-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BuildMachineOSBuild
6 | 14F27
7 | CFBundleDevelopmentRegion
8 | English
9 | CFBundleExecutable
10 | Digits
11 | CFBundleIdentifier
12 | com.extentofthejam.Digits
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | Digits
17 | CFBundlePackageType
18 | BNDL
19 | CFBundleShortVersionString
20 | 2.0
21 | CFBundleSignature
22 | ????
23 | CFBundleSupportedPlatforms
24 |
25 | MacOSX
26 |
27 | CFBundleVersion
28 | 2
29 | CFPlugInDynamicRegisterFunction
30 |
31 | CFPlugInDynamicRegistration
32 |
33 | CFPlugInFactories
34 |
35 | 00000000-0000-0000-0000-000000000000
36 | MyFactoryFunction
37 |
38 | CFPlugInTypes
39 |
40 | 00000000-0000-0000-0000-000000000000
41 |
42 | 00000000-0000-0000-0000-000000000000
43 |
44 |
45 | CFPlugInUnloadFunction
46 |
47 | DTCompiler
48 | com.apple.compilers.llvm.clang.1_0
49 | DTPlatformBuild
50 | 7C1002
51 | DTPlatformVersion
52 | GM
53 | DTSDKBuild
54 | 15C43
55 | DTSDKName
56 | macosx10.11
57 | DTXcode
58 | 0721
59 | DTXcodeBuild
60 | 7C1002
61 |
62 |
63 |
--------------------------------------------------------------------------------
/mac/Main.xcodeproj/PDVST.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/mac/Main.xcodeproj/PDVST.xcodeproj/project.xcworkspace/xcshareddata/PDVST.xccheckout:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDESourceControlProjectFavoriteDictionaryKey
6 |
7 | IDESourceControlProjectIdentifier
8 | 389F805C-D228-474D-882B-A7E8333636C1
9 | IDESourceControlProjectName
10 | PDVST
11 | IDESourceControlProjectOriginsDictionary
12 |
13 | 17D9919C-DA53-4281-A0CD-C53F8CBB0AA6
14 | https://vstgui.svn.sourceforge.net/svnroot/vstgui/trunk/vstgui
15 | 3BE785E0-25D8-46D7-9C6D-695762A0F67B
16 | http://www.extentofthejam.com/DigitsVst/trunk
17 | 7F7CAD0D-C3BE-4BD1-8868-99E4543B06BB
18 | http://www.extentofthejam.com/DigitsVst/vstsdk2.4
19 |
20 | IDESourceControlProjectPath
21 | Mac/PDVST.xcodeproj/project.xcworkspace
22 | IDESourceControlProjectRelativeInstallPathDictionary
23 |
24 | 17D9919C-DA53-4281-A0CD-C53F8CBB0AA6
25 | ../../../vstgui
26 | 3BE785E0-25D8-46D7-9C6D-695762A0F67B
27 | ../../..
28 | 7F7CAD0D-C3BE-4BD1-8868-99E4543B06BB
29 | ../../../vstsdk2.4
30 |
31 | IDESourceControlProjectRepositoryRootDictionary
32 |
33 | 17D9919C-DA53-4281-A0CD-C53F8CBB0AA6
34 | https://vstgui.svn.sourceforge.net/svnroot/vstgui
35 | 3BE785E0-25D8-46D7-9C6D-695762A0F67B
36 | http://www.extentofthejam.com/DigitsVst
37 | 7F7CAD0D-C3BE-4BD1-8868-99E4543B06BB
38 | http://www.extentofthejam.com/DigitsVst
39 |
40 | IDESourceControlProjectURL
41 | http://www.extentofthejam.com/DigitsVst/trunk/Mac/PDVST.xcodeproj
42 | IDESourceControlProjectVersion
43 | 110
44 | IDESourceControlProjectWCCIdentifier
45 | 3BE785E0-25D8-46D7-9C6D-695762A0F67B
46 | IDESourceControlProjectWCConfigurations
47 |
48 |
49 | IDESourceControlRepositoryExtensionIdentifierKey
50 | public.vcs.subversion
51 | IDESourceControlRepositoryTrunkRelativeLocationKey
52 | trunk
53 | IDESourceControlWCCIdentifierKey
54 | 3BE785E0-25D8-46D7-9C6D-695762A0F67B
55 | IDESourceControlWCCName
56 | trunk
57 |
58 |
59 | IDESourceControlRepositoryExtensionIdentifierKey
60 | public.vcs.subversion
61 | IDESourceControlWCCIdentifierKey
62 | 17D9919C-DA53-4281-A0CD-C53F8CBB0AA6
63 | IDESourceControlWCCName
64 | vstgui
65 |
66 |
67 | IDESourceControlRepositoryExtensionIdentifierKey
68 | public.vcs.subversion
69 | IDESourceControlWCCIdentifierKey
70 | 7F7CAD0D-C3BE-4BD1-8868-99E4543B06BB
71 | IDESourceControlWCCName
72 | vstsdk2
73 |
74 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/mac/Main.xcodeproj/PDVST.xcodeproj/project.xcworkspace/xcshareddata/PDVST.xcscmblueprint:
--------------------------------------------------------------------------------
1 | {
2 | "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "3d0f6ae8-fa23-4685-9a80-cfccffeb77e4",
3 | "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : {
4 | "3d0f6ae8-fa23-4685-9a80-cfccffeb77e4" : {
5 |
6 | }
7 | },
8 | "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : {
9 | "3d0f6ae8-fa23-4685-9a80-cfccffeb77e4" : 0
10 | },
11 | "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "389F805C-D228-474D-882B-A7E8333636C1",
12 | "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : {
13 | "3d0f6ae8-fa23-4685-9a80-cfccffeb77e4" : "DigitsVst\/"
14 | },
15 | "DVTSourceControlWorkspaceBlueprintNameKey" : "PDVST",
16 | "DVTSourceControlWorkspaceBlueprintVersion" : 204,
17 | "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "trunk\/Mac\/PDVST.xcodeproj",
18 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [
19 | {
20 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "http:\/\/www.extentofthejam.com\/DigitsVst",
21 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Subversion",
22 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "3d0f6ae8-fa23-4685-9a80-cfccffeb77e4"
23 | }
24 | ]
25 | }
--------------------------------------------------------------------------------
/mac/Main.xcodeproj/PDVST.xcodeproj/project.xcworkspace/xcuserdata/louis.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/mac/Main.xcodeproj/PDVST.xcodeproj/project.xcworkspace/xcuserdata/louis.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/mac/Main.xcodeproj/PDVST.xcodeproj/project.xcworkspace/xcuserdata/louis.xcuserdatad/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BuildLocationStyle
6 | UseAppPreferences
7 | CustomBuildLocationType
8 | RelativeToDerivedData
9 | DerivedDataLocationStyle
10 | Default
11 | IssueFilterStyle
12 | ShowActiveSchemeOnly
13 | LiveSourceIssuesEnabled
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/mac/Main.xcodeproj/PDVST.xcodeproj/xcuserdata/louis.xcuserdatad/xcschemes/Digits.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
34 |
35 |
45 |
46 |
52 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
70 |
71 |
72 |
73 |
75 |
76 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/mac/Main.xcodeproj/PDVST.xcodeproj/xcuserdata/louis.xcuserdatad/xcschemes/DigitsBench.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/mac/Main.xcodeproj/PDVST.xcodeproj/xcuserdata/louis.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | Digits.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 | DigitsBench.xcscheme
13 |
14 | orderHint
15 | 1
16 |
17 |
18 | SuppressBuildableAutocreation
19 |
20 | 8D57630D048677EA00EA77CD
21 |
22 | primary
23 |
24 |
25 | BF8D1650160C075D002BAEBC
26 |
27 | primary
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/mac/Main.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/mac/Main.xcodeproj/project.xcworkspace/xcshareddata/Main.xcscmblueprint:
--------------------------------------------------------------------------------
1 | {
2 | "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "fda82bb9-77cd-40e1-9680-d2fdca61505c",
3 | "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : {
4 | "fda82bb9-77cd-40e1-9680-d2fdca61505c" : {
5 |
6 | }
7 | },
8 | "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : {
9 | "fda82bb9-77cd-40e1-9680-d2fdca61505c" : 9223372036854775807
10 | },
11 | "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "031BA8E8-F7BC-4D4E-90F7-0551FC4BDB0C",
12 | "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : {
13 | "fda82bb9-77cd-40e1-9680-d2fdca61505c" : "eojsource\/"
14 | },
15 | "DVTSourceControlWorkspaceBlueprintNameKey" : "Main",
16 | "DVTSourceControlWorkspaceBlueprintVersion" : 204,
17 | "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "trunk\/mac\/Main.xcodeproj",
18 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [
19 | {
20 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "http:\/\/www.extentofthejam.com\/eojsource",
21 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Subversion",
22 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "fda82bb9-77cd-40e1-9680-d2fdca61505c"
23 | }
24 | ]
25 | }
--------------------------------------------------------------------------------
/mac/Main.xcodeproj/project.xcworkspace/xcshareddata/PDVST.xccheckout:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDESourceControlProjectFavoriteDictionaryKey
6 |
7 | IDESourceControlProjectIdentifier
8 | 389F805C-D228-474D-882B-A7E8333636C1
9 | IDESourceControlProjectName
10 | PDVST
11 | IDESourceControlProjectOriginsDictionary
12 |
13 | 17D9919C-DA53-4281-A0CD-C53F8CBB0AA6
14 | https://vstgui.svn.sourceforge.net/svnroot/vstgui/trunk/vstgui
15 | 3BE785E0-25D8-46D7-9C6D-695762A0F67B
16 | http://www.extentofthejam.com/DigitsVst/trunk
17 | 7F7CAD0D-C3BE-4BD1-8868-99E4543B06BB
18 | http://www.extentofthejam.com/DigitsVst/vstsdk2.4
19 |
20 | IDESourceControlProjectPath
21 | Mac/PDVST.xcodeproj/project.xcworkspace
22 | IDESourceControlProjectRelativeInstallPathDictionary
23 |
24 | 17D9919C-DA53-4281-A0CD-C53F8CBB0AA6
25 | ../../../vstgui
26 | 3BE785E0-25D8-46D7-9C6D-695762A0F67B
27 | ../../..
28 | 7F7CAD0D-C3BE-4BD1-8868-99E4543B06BB
29 | ../../../vstsdk2.4
30 |
31 | IDESourceControlProjectRepositoryRootDictionary
32 |
33 | 17D9919C-DA53-4281-A0CD-C53F8CBB0AA6
34 | https://vstgui.svn.sourceforge.net/svnroot/vstgui
35 | 3BE785E0-25D8-46D7-9C6D-695762A0F67B
36 | http://www.extentofthejam.com/DigitsVst
37 | 7F7CAD0D-C3BE-4BD1-8868-99E4543B06BB
38 | http://www.extentofthejam.com/DigitsVst
39 |
40 | IDESourceControlProjectURL
41 | http://www.extentofthejam.com/DigitsVst/trunk/Mac/PDVST.xcodeproj
42 | IDESourceControlProjectVersion
43 | 110
44 | IDESourceControlProjectWCCIdentifier
45 | 3BE785E0-25D8-46D7-9C6D-695762A0F67B
46 | IDESourceControlProjectWCConfigurations
47 |
48 |
49 | IDESourceControlRepositoryExtensionIdentifierKey
50 | public.vcs.subversion
51 | IDESourceControlRepositoryTrunkRelativeLocationKey
52 | trunk
53 | IDESourceControlWCCIdentifierKey
54 | 3BE785E0-25D8-46D7-9C6D-695762A0F67B
55 | IDESourceControlWCCName
56 | trunk
57 |
58 |
59 | IDESourceControlRepositoryExtensionIdentifierKey
60 | public.vcs.subversion
61 | IDESourceControlWCCIdentifierKey
62 | 17D9919C-DA53-4281-A0CD-C53F8CBB0AA6
63 | IDESourceControlWCCName
64 | vstgui
65 |
66 |
67 | IDESourceControlRepositoryExtensionIdentifierKey
68 | public.vcs.subversion
69 | IDESourceControlWCCIdentifierKey
70 | 7F7CAD0D-C3BE-4BD1-8868-99E4543B06BB
71 | IDESourceControlWCCName
72 | vstsdk2
73 |
74 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/mac/Main.xcodeproj/project.xcworkspace/xcshareddata/PDVST.xcscmblueprint:
--------------------------------------------------------------------------------
1 | {
2 | "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "3d0f6ae8-fa23-4685-9a80-cfccffeb77e4",
3 | "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : {
4 | "3d0f6ae8-fa23-4685-9a80-cfccffeb77e4" : {
5 |
6 | }
7 | },
8 | "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : {
9 | "3d0f6ae8-fa23-4685-9a80-cfccffeb77e4" : 0
10 | },
11 | "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "389F805C-D228-474D-882B-A7E8333636C1",
12 | "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : {
13 | "3d0f6ae8-fa23-4685-9a80-cfccffeb77e4" : "DigitsVst\/"
14 | },
15 | "DVTSourceControlWorkspaceBlueprintNameKey" : "PDVST",
16 | "DVTSourceControlWorkspaceBlueprintVersion" : 204,
17 | "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "trunk\/Mac\/PDVST.xcodeproj",
18 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [
19 | {
20 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "http:\/\/www.extentofthejam.com\/DigitsVst",
21 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Subversion",
22 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "3d0f6ae8-fa23-4685-9a80-cfccffeb77e4"
23 | }
24 | ]
25 | }
--------------------------------------------------------------------------------
/mac/Main.xcodeproj/project.xcworkspace/xcuserdata/louis.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/mac/Main.xcodeproj/project.xcworkspace/xcuserdata/louis.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/mac/Main.xcodeproj/project.xcworkspace/xcuserdata/louis.xcuserdatad/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BuildLocationStyle
6 | UseAppPreferences
7 | CustomBuildLocationType
8 | RelativeToDerivedData
9 | DerivedDataLocationStyle
10 | Default
11 | IssueFilterStyle
12 | ShowActiveSchemeOnly
13 | LiveSourceIssuesEnabled
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/mac/Main.xcodeproj/xcuserdata/louis.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
8 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/mac/Main.xcodeproj/xcuserdata/louis.xcuserdatad/xcschemes/Digits.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
34 |
35 |
45 |
46 |
52 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
70 |
71 |
72 |
73 |
75 |
76 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/mac/Main.xcodeproj/xcuserdata/louis.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | Digits.xcscheme
8 |
9 | orderHint
10 | 1
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 8D57630D048677EA00EA77CD
16 |
17 | primary
18 |
19 |
20 | BF82490F1DC050C50073E18C
21 |
22 | primary
23 |
24 |
25 | BF8D1650160C075D002BAEBC
26 |
27 | primary
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/patches/Basses/404.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Basses/404.fxp
--------------------------------------------------------------------------------
/patches/Basses/ChorusBass.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Basses/ChorusBass.fxp
--------------------------------------------------------------------------------
/patches/Basses/ElBass II.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Basses/ElBass II.fxp
--------------------------------------------------------------------------------
/patches/Basses/ElBass.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Basses/ElBass.fxp
--------------------------------------------------------------------------------
/patches/Basses/EyeEye.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Basses/EyeEye.fxp
--------------------------------------------------------------------------------
/patches/Basses/FMBass.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Basses/FMBass.fxp
--------------------------------------------------------------------------------
/patches/Basses/FlangerBass.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Basses/FlangerBass.fxp
--------------------------------------------------------------------------------
/patches/Basses/LazyBass.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Basses/LazyBass.fxp
--------------------------------------------------------------------------------
/patches/Basses/PWMBass.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Basses/PWMBass.fxp
--------------------------------------------------------------------------------
/patches/Basses/PhatterBass.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Basses/PhatterBass.fxp
--------------------------------------------------------------------------------
/patches/Basses/RubberBand.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Basses/RubberBand.fxp
--------------------------------------------------------------------------------
/patches/Basses/Splatter.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Basses/Splatter.fxp
--------------------------------------------------------------------------------
/patches/Basses/SquareBass.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Basses/SquareBass.fxp
--------------------------------------------------------------------------------
/patches/Basses/Sub Fuzz.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Basses/Sub Fuzz.fxp
--------------------------------------------------------------------------------
/patches/Basses/Sub.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Basses/Sub.fxp
--------------------------------------------------------------------------------
/patches/Basses/ThunkyBass.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Basses/ThunkyBass.fxp
--------------------------------------------------------------------------------
/patches/Chords/BrassEns.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Chords/BrassEns.fxp
--------------------------------------------------------------------------------
/patches/Chords/ElectricOrgan II.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Chords/ElectricOrgan II.fxp
--------------------------------------------------------------------------------
/patches/Chords/ElectricOrgan.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Chords/ElectricOrgan.fxp
--------------------------------------------------------------------------------
/patches/Chords/FunKeyRiffs.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Chords/FunKeyRiffs.fxp
--------------------------------------------------------------------------------
/patches/Chords/Funkdafy II.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Chords/Funkdafy II.fxp
--------------------------------------------------------------------------------
/patches/Chords/Funkdafy.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Chords/Funkdafy.fxp
--------------------------------------------------------------------------------
/patches/Chords/FuzzBox.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Chords/FuzzBox.fxp
--------------------------------------------------------------------------------
/patches/Chords/HiToneChords.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Chords/HiToneChords.fxp
--------------------------------------------------------------------------------
/patches/Chords/MusicBox.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Chords/MusicBox.fxp
--------------------------------------------------------------------------------
/patches/Chords/ToySynthPiano II.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Chords/ToySynthPiano II.fxp
--------------------------------------------------------------------------------
/patches/Chords/ToySynthPiano.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Chords/ToySynthPiano.fxp
--------------------------------------------------------------------------------
/patches/DemoBank/BrassySlicerLead.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/DemoBank/BrassySlicerLead.fxp
--------------------------------------------------------------------------------
/patches/DemoBank/ChorusBass.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/DemoBank/ChorusBass.fxp
--------------------------------------------------------------------------------
/patches/DemoBank/EasternArpeg.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/DemoBank/EasternArpeg.fxp
--------------------------------------------------------------------------------
/patches/DemoBank/ElBass.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/DemoBank/ElBass.fxp
--------------------------------------------------------------------------------
/patches/DemoBank/FutureTines.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/DemoBank/FutureTines.fxp
--------------------------------------------------------------------------------
/patches/DemoBank/GhostChoir.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/DemoBank/GhostChoir.fxp
--------------------------------------------------------------------------------
/patches/DemoBank/InitTone.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/DemoBank/InitTone.fxp
--------------------------------------------------------------------------------
/patches/DemoBank/Jar.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/DemoBank/Jar.fxp
--------------------------------------------------------------------------------
/patches/DemoBank/SIDLead.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/DemoBank/SIDLead.fxp
--------------------------------------------------------------------------------
/patches/DemoBank/SeriousWhales.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/DemoBank/SeriousWhales.fxp
--------------------------------------------------------------------------------
/patches/DemoBank/StringEns.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/DemoBank/StringEns.fxp
--------------------------------------------------------------------------------
/patches/DemoBank/ThunkyBass.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/DemoBank/ThunkyBass.fxp
--------------------------------------------------------------------------------
/patches/Leads/AttackPoly.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Leads/AttackPoly.fxp
--------------------------------------------------------------------------------
/patches/Leads/BellLead.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Leads/BellLead.fxp
--------------------------------------------------------------------------------
/patches/Leads/BrassLead.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Leads/BrassLead.fxp
--------------------------------------------------------------------------------
/patches/Leads/BrassLeadMellow.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Leads/BrassLeadMellow.fxp
--------------------------------------------------------------------------------
/patches/Leads/BrassySlicerLead.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Leads/BrassySlicerLead.fxp
--------------------------------------------------------------------------------
/patches/Leads/Chiff.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Leads/Chiff.fxp
--------------------------------------------------------------------------------
/patches/Leads/FierceLead.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Leads/FierceLead.fxp
--------------------------------------------------------------------------------
/patches/Leads/FoggyCliff.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Leads/FoggyCliff.fxp
--------------------------------------------------------------------------------
/patches/Leads/FuzzyHoover.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Leads/FuzzyHoover.fxp
--------------------------------------------------------------------------------
/patches/Leads/HardCorpLead.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Leads/HardCorpLead.fxp
--------------------------------------------------------------------------------
/patches/Leads/HarshLead.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Leads/HarshLead.fxp
--------------------------------------------------------------------------------
/patches/Leads/HollowTube.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Leads/HollowTube.fxp
--------------------------------------------------------------------------------
/patches/Leads/Hyperflute.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Leads/Hyperflute.fxp
--------------------------------------------------------------------------------
/patches/Leads/Mystery.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Leads/Mystery.fxp
--------------------------------------------------------------------------------
/patches/Leads/RavingLunatic.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Leads/RavingLunatic.fxp
--------------------------------------------------------------------------------
/patches/Leads/ResoLead.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Leads/ResoLead.fxp
--------------------------------------------------------------------------------
/patches/Leads/SIDLead II.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Leads/SIDLead II.fxp
--------------------------------------------------------------------------------
/patches/Leads/SIDLead.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Leads/SIDLead.fxp
--------------------------------------------------------------------------------
/patches/Leads/SeriousWhales.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Leads/SeriousWhales.fxp
--------------------------------------------------------------------------------
/patches/Leads/SpaceOboe.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Leads/SpaceOboe.fxp
--------------------------------------------------------------------------------
/patches/Leads/SynReed.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Leads/SynReed.fxp
--------------------------------------------------------------------------------
/patches/Leads/ViolinLead.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Leads/ViolinLead.fxp
--------------------------------------------------------------------------------
/patches/Pads/Atlantis.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Pads/Atlantis.fxp
--------------------------------------------------------------------------------
/patches/Pads/BellBrassPad.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Pads/BellBrassPad.fxp
--------------------------------------------------------------------------------
/patches/Pads/Choir II.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Pads/Choir II.fxp
--------------------------------------------------------------------------------
/patches/Pads/DreamPad.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Pads/DreamPad.fxp
--------------------------------------------------------------------------------
/patches/Pads/FilteryChorusy.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Pads/FilteryChorusy.fxp
--------------------------------------------------------------------------------
/patches/Pads/FilteryPads.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Pads/FilteryPads.fxp
--------------------------------------------------------------------------------
/patches/Pads/FlangerStringEns.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Pads/FlangerStringEns.fxp
--------------------------------------------------------------------------------
/patches/Pads/GhostChoir.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Pads/GhostChoir.fxp
--------------------------------------------------------------------------------
/patches/Pads/Jar II.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Pads/Jar II.fxp
--------------------------------------------------------------------------------
/patches/Pads/Jar.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Pads/Jar.fxp
--------------------------------------------------------------------------------
/patches/Pads/Planetary.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Pads/Planetary.fxp
--------------------------------------------------------------------------------
/patches/Pads/StringEns.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Pads/StringEns.fxp
--------------------------------------------------------------------------------
/patches/Pads/StringEnsBright.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Pads/StringEnsBright.fxp
--------------------------------------------------------------------------------
/patches/Pads/TheCreeps.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Pads/TheCreeps.fxp
--------------------------------------------------------------------------------
/patches/Pads/WinteryPad.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Pads/WinteryPad.fxp
--------------------------------------------------------------------------------
/patches/Stabs/AlienChimes.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Stabs/AlienChimes.fxp
--------------------------------------------------------------------------------
/patches/Stabs/Bells.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Stabs/Bells.fxp
--------------------------------------------------------------------------------
/patches/Stabs/Darius.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Stabs/Darius.fxp
--------------------------------------------------------------------------------
/patches/Stabs/EasternArpeg.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Stabs/EasternArpeg.fxp
--------------------------------------------------------------------------------
/patches/Stabs/FutureTines.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Stabs/FutureTines.fxp
--------------------------------------------------------------------------------
/patches/Stabs/Ghosts.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Stabs/Ghosts.fxp
--------------------------------------------------------------------------------
/patches/Stabs/HouseStabs.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Stabs/HouseStabs.fxp
--------------------------------------------------------------------------------
/patches/Stabs/POW.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Stabs/POW.fxp
--------------------------------------------------------------------------------
/patches/Stabs/Quack.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Stabs/Quack.fxp
--------------------------------------------------------------------------------
/patches/Stabs/Soft Mallet.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Stabs/Soft Mallet.fxp
--------------------------------------------------------------------------------
/patches/Stabs/ThunkyArp.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Stabs/ThunkyArp.fxp
--------------------------------------------------------------------------------
/patches/Stabs/VelocityRubber.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Stabs/VelocityRubber.fxp
--------------------------------------------------------------------------------
/patches/Sweeps/FunnyBone.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Sweeps/FunnyBone.fxp
--------------------------------------------------------------------------------
/patches/Sweeps/HiSweep-Overdrive.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Sweeps/HiSweep-Overdrive.fxp
--------------------------------------------------------------------------------
/patches/Sweeps/HiSweep.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Sweeps/HiSweep.fxp
--------------------------------------------------------------------------------
/patches/Sweeps/HowlingTubeSweep.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Sweeps/HowlingTubeSweep.fxp
--------------------------------------------------------------------------------
/patches/Sweeps/MeanSweeps.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Sweeps/MeanSweeps.fxp
--------------------------------------------------------------------------------
/patches/Sweeps/Riser I.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Sweeps/Riser I.fxp
--------------------------------------------------------------------------------
/patches/Sweeps/Riser II.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Sweeps/Riser II.fxp
--------------------------------------------------------------------------------
/patches/Sweeps/Riser III.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Sweeps/Riser III.fxp
--------------------------------------------------------------------------------
/patches/Sweeps/Riser IV.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Sweeps/Riser IV.fxp
--------------------------------------------------------------------------------
/patches/Sweeps/SeriousPad.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Sweeps/SeriousPad.fxp
--------------------------------------------------------------------------------
/patches/Sweeps/TubularBellSweep.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Sweeps/TubularBellSweep.fxp
--------------------------------------------------------------------------------
/patches/Sweeps/VisciousFM 2.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Sweeps/VisciousFM 2.fxp
--------------------------------------------------------------------------------
/patches/Sweeps/VisciousFM.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Sweeps/VisciousFM.fxp
--------------------------------------------------------------------------------
/patches/Sweeps/Whoosh.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Sweeps/Whoosh.fxp
--------------------------------------------------------------------------------
/patches/Sweeps/WobblySweep.fxp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LouisGorenfeld/DigitsVst/f5ee4aa74e40b118bddcb3ef18d44b734e6fbef8/patches/Sweeps/WobblySweep.fxp
--------------------------------------------------------------------------------
/src/components/BufferManager.cpp:
--------------------------------------------------------------------------------
1 | /* Phase Distortion Synthesizer (c) 2011 Louis Gorenfeld */
2 |
3 | #include
4 | #include "BufferManager.h"
5 | #include
6 |
7 | void BufferManager::SetSamplingRate(float rate)
8 | {
9 | m_samplingRate = rate;
10 | m_ctlSize = rate;
11 | }
12 |
13 | void BufferManager::SetHostBlockSize(float blkSize)
14 | {
15 | m_blkSize = blkSize;
16 |
17 | if (m_bufList.empty())
18 | return;
19 |
20 | // Resize all the buffers so that they match the
21 | // block size
22 | for (bufList_t::iterator it = m_bufList.begin();
23 | it != m_bufList.end();
24 | ++it)
25 | {
26 | if (*it)
27 | (*it)->Resize(m_blkSize);
28 | }
29 | printf("Block size %f\n", blkSize);
30 | }
31 |
32 |
--------------------------------------------------------------------------------
/src/components/BufferManager.h:
--------------------------------------------------------------------------------
1 | /* Phase Distortion Synthesizer (c) 2011 Louis Gorenfeld */
2 |
3 | #ifndef _BUFFER_MANAGER_H_
4 | #define _BUFFER_MANAGER_H_
5 |
6 | #include
7 | #include "SndBuf.h"
8 |
9 | /* The SndBuf class is responsible for allocating and deallocating its
10 | * buffer, but the BufferManager class will automatically resize every
11 | * buffer when the block size changes in the host */
12 |
13 | class BufferManager
14 | {
15 | public:
16 | BufferManager() { /* Safe defaults for out-of-order init */ SetSamplingRate(96000); }
17 | ~BufferManager() {}
18 |
19 | void AddBuffer(SndBuf *buf) { m_bufList.push_back(buf); }
20 | void RemoveBuffer(SndBuf *buf) { m_bufList.remove(buf); }
21 |
22 | float GetSamplingRate() { return m_samplingRate; }
23 | float GetControlSize() { return m_ctlSize; }
24 | static float GetControlRate() { return kCtlRate; }
25 | float GetHostBlockSize() { return m_blkSize; }
26 |
27 | void SetSamplingRate(float rate);
28 | void SetHostBlockSize(float blkSize);
29 |
30 | private:
31 | float m_samplingRate;
32 | float m_ctlSize;
33 | float m_blkSize;
34 |
35 | // Control rate in hz
36 | // TODO: This can be low, but we need to generate envelope signals
37 | static const float kCtlRate;
38 |
39 | // Buffers are managed by static routines so that they can
40 | // all be resized easily
41 | typedef std::list bufList_t;
42 | bufList_t m_bufList;
43 | };
44 |
45 | #endif
--------------------------------------------------------------------------------
/src/components/Chorus.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include // rand
3 | #include "Chorus.h"
4 |
5 | Chorus::Chorus() :
6 | m_delBuf(0),
7 | m_wIndex(0),
8 | m_lfoPos(0),
9 | m_lfoDelta(0),
10 | m_lfoRate(0),
11 | m_minDelay(0),
12 | m_range(0),
13 | m_minDelaySamp(0),
14 | m_rangeSamp(0),
15 | m_lastOut(0),
16 | m_feedback(0),
17 | m_sR(0),
18 | m_wet(0),
19 | m_bufSize(0),
20 | m_bins(512),
21 | m_shLast(0),
22 | m_shPos(0),
23 | m_noiseAmt(1.0f/256.0f)
24 | {
25 | m_preLP[0].SetFrequency(6000);
26 | m_preLP[1].SetFrequency(6000);
27 | m_postLP[0].SetFrequency(4000);
28 | m_postLP[1].SetFrequency(4000);
29 | m_postHP.SetFrequency(500);
30 | m_triSmoother.SetFrequency(5);
31 | SetSamplingRate(44100); // Just so that m_delBuf gets initialized
32 | }
33 |
34 | Chorus::~Chorus()
35 | {
36 | }
37 |
38 | void Chorus::SetSamplingRate(float sR)
39 | {
40 | m_sR = sR;
41 | if (m_delBuf)
42 | delete[] m_delBuf;
43 | m_delBuf = new float[(int)sR+1];
44 | for (int i=0; i < sR+1; i++)
45 | m_delBuf[i] = 0;
46 | m_bufSize = sR;
47 | m_preLP[0].SetSamplingRate(sR);
48 | m_preLP[1].SetSamplingRate(sR);
49 | m_postLP[0].SetSamplingRate(sR);
50 | m_postLP[1].SetSamplingRate(sR);
51 | m_postHP.SetSamplingRate(sR);
52 | m_triSmoother.SetSamplingRate(sR);
53 | m_wIndex = 0;
54 | m_lfoPos = 0;
55 | m_shPos = 0;
56 | }
57 |
58 | void Chorus::RenderWet(float *in, float *out, int len)
59 | {
60 | // for (int i=0; i < len; i++)
61 | // in[i] = ((rand()&65536)/32767.0) - 1.0;
62 | // TODO: This could be made a lot more efficient
63 |
64 | m_preLP[0].Render(in, len);
65 | m_preLP[1].Render(in, len);
66 |
67 | for (int i=0; i= 1.0f)
72 | m_lfoPos -= 1.0f;
73 |
74 | if (m_lfoPos >= .5f)
75 | lfoSam = 2.0f - (m_lfoPos*2.0f);
76 | else
77 | lfoSam = m_lfoPos * 2.0f;
78 | lfoSam = m_triSmoother.Tick(lfoSam);
79 |
80 | float delay = m_minDelaySamp + (lfoSam*m_rangeSamp);
81 | float rIndex = (float)m_wIndex - delay;
82 | while (rIndex < 0)
83 | rIndex += m_bufSize;
84 |
85 | // fprintf(stderr, "delay=%d rIndex=%d, wIndex=%d\n", (int)delay, (int)rIndex, (int)m_wIndex);
86 |
87 | float rIndexFrac = fmod(rIndex, 1.0f);
88 | int rIndexInt = (int)rIndex;
89 | int rIndexInt2 = (int)rIndex - 1;
90 | while (rIndexInt2 < 0)
91 | rIndexInt2 += m_bufSize;
92 |
93 | // Sample hold to emulate bucket brigade
94 | float shDelta = (m_bins / (delay / m_sR)) / m_sR; // is this too slow? does m_sR cancel? :)
95 | if (shDelta >= 1.0f)
96 | {
97 | float n = ((rand() & 65535) - 32767.0) / (32767.0f);
98 | // TODO: Optimize noise
99 | m_shLast = in[i] + m_lastOut * m_feedback + n * m_noiseAmt;
100 | }
101 | else
102 | {
103 | m_shPos += shDelta;
104 | while (m_shPos >= 1.0f)
105 | {
106 | // TODO: Anti-aliasing pre-filter
107 | // TODO: Optimize noise
108 | float n = ((rand() & 65535) - 32767.0) / (32767.0f);
109 | m_shLast = in[i] + n * m_noiseAmt;
110 | m_shPos -= 1.0f;
111 | }
112 | }
113 |
114 | m_delBuf[m_wIndex] = m_shLast;
115 | // Linear interpolation between index int 1 & 2 depending
116 | // on amount of fraction
117 | out[i] = (m_delBuf[rIndexInt]*rIndexFrac + m_delBuf[rIndexInt2]*(1-rIndexFrac));
118 | m_lastOut = out[i];
119 | out[i] *= m_wet;
120 | m_wIndex = (m_wIndex + 1) % (m_bufSize);
121 | }
122 |
123 | m_postLP[0].Render(out, len);
124 | m_postLP[1].Render(out, len);
125 | m_postHP.Render(out, len);
126 | }
127 |
128 |
--------------------------------------------------------------------------------
/src/components/Chorus.h:
--------------------------------------------------------------------------------
1 | #ifndef _CHORUS_H_
2 | #define _CHORUS_H_
3 |
4 | #include "FilterBank.h"
5 |
6 | class Chorus
7 | {
8 | public:
9 | Chorus();
10 | ~Chorus();
11 | void SetSamplingRate(float sR);
12 | void RenderWet(float *in, float *out, int len);
13 | void SetMinDelay(float minDelay) { m_minDelay = minDelay; RecalcDelays(); }
14 | float GetMinDelay() { return m_minDelay; }
15 | void SetRange(float range) { m_range = range; RecalcDelays(); }
16 | float GetRange() { return m_range; }
17 | void SetLFORate(float hz) { m_lfoRate = hz; RecalcDelays(); }
18 | void SetWet(float wet) { m_wet = wet; }
19 | float GetWet() { return m_wet; }
20 | void SetBucketBins(int n) { m_bins = n; }
21 | void SetNoiseAmount(float x) { m_noiseAmt = x; }
22 | void SetOffset(float offset) { m_lfoPos = offset; }
23 | void SetFeedback(float fb) { m_feedback = fb; }
24 | float GetFeedback() { return m_feedback; }
25 | void SetTone(float prelp, float postlp, float hp)
26 | {
27 | m_preLP[0].SetFrequency(prelp);
28 | m_preLP[1].SetFrequency(prelp);
29 | m_postLP[0].SetFrequency(postlp);
30 | m_postLP[1].SetFrequency(postlp);
31 | m_postHP.SetFrequency(hp);
32 | }
33 | void RecalcDelays()
34 | {
35 | m_minDelaySamp = (m_minDelay/1000.0f)*m_sR;
36 | m_rangeSamp = (m_range/1000.0f)*m_sR;
37 | m_lfoDelta = m_lfoRate/m_sR;
38 | }
39 |
40 | private:
41 | // Delay buf. This should be enough
42 | // for a second and needs to be manually
43 | // resized when the buffer size changes
44 | // (not part of SndBuf's regular size).
45 | float* m_delBuf;
46 | // Write ptr
47 | int m_wIndex;
48 |
49 | float m_lfoPos;
50 | float m_lfoDelta;
51 | float m_lfoRate;
52 |
53 | float m_minDelay;
54 | float m_range;
55 | float m_minDelaySamp;
56 | float m_rangeSamp;
57 | float m_lastOut;
58 |
59 | float m_feedback;
60 | float m_sR;
61 |
62 | float m_wet;
63 | int m_bufSize;
64 |
65 | // Sample-hold for bucket brigade emulation
66 | float m_bins;
67 | float m_shLast; // last sample to hold
68 | float m_shPos;
69 |
70 | // Noise amount
71 | float m_noiseAmt;
72 |
73 | // Variables for pre and post anti-aliasing filters
74 | // (more bucket brigade emulation)
75 | // 6dB at 6khz
76 | LowPass1p m_preLP[2];
77 | LowPass1p m_postLP[2];
78 | LowPass1p m_triSmoother;
79 | HighPass m_postHP;
80 | };
81 |
82 | #endif
83 |
--------------------------------------------------------------------------------
/src/components/Compressor.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Compressor.cpp
3 | // DrumVST
4 | //
5 | // Created by Louis Gorenfeld on 10/2/16.
6 | //
7 | //
8 |
9 | #include "Compressor.h"
10 |
11 | Compressor::Compressor() :
12 | m_envFollowPos(0),
13 | m_attack(0),
14 | m_release(0),
15 | m_threshold(1.0),
16 | m_ratio(1.0/3.0)
17 | {
18 | }
19 |
20 | void Compressor::SetSamplingRate(float sR)
21 | {
22 | m_sR = sR;
23 | }
24 |
25 | void Compressor::Render(float *buf, int len)
26 | {
27 | float level;
28 | float peakLevel = 0;
29 |
30 | for (int i=0; i < len; i++)
31 | {
32 | level = buf[i];
33 | if (level > peakLevel)
34 | peakLevel = level;
35 | else
36 | peakLevel *= .9999;
37 |
38 | if (peakLevel > m_threshold)
39 | {
40 | // Instant attack; release determined in part by peaklevel fall
41 | buf[i] *= 1.0 + ((peakLevel - m_threshold) * m_ratio);
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/components/Compressor.h:
--------------------------------------------------------------------------------
1 | //
2 | // Compressor.h
3 | // DrumVST
4 | //
5 | // Created by Louis Gorenfeld on 10/2/16.
6 | //
7 | //
8 |
9 | #ifndef Compressor_h
10 | #define Compressor_h
11 |
12 | class Compressor
13 | {
14 | public:
15 | Compressor();
16 | ~Compressor();
17 | void SetSamplingRate(float sR);
18 | void Render(float *buf, int len);
19 | void SetThreshold(float threshold) { m_threshold = threshold; }
20 | void SetRatio(float ratio) { m_ratio = ratio; }
21 |
22 | private:
23 | float m_envFollowPos;
24 | float m_attack;
25 | float m_release;
26 | float m_threshold; // dB
27 | float m_ratio;
28 | };
29 |
30 | #endif /* Compressor_h */
31 |
--------------------------------------------------------------------------------
/src/components/Contour.cpp:
--------------------------------------------------------------------------------
1 | /* Phase Distortion Synthesizer (c) 2011 Louis Gorenfeld */
2 |
3 | #include
4 | #include "SndBuf.h"
5 | #include "Contour.h"
6 |
7 | Contour::Contour() :
8 | m_curValue(0),
9 | m_attack(1.0),
10 | m_decay(1.0),
11 | m_release(1.0),
12 | m_fade(0),
13 | m_sustain(false),
14 | m_sustainLevel(1.0),
15 | m_min(0),
16 | m_max(1.0),
17 | m_phase(kFinished),
18 | m_ctlIn(1.0f),
19 | m_ctlVal(1.0f),
20 | m_lastOut(0),
21 | m_noAttack(false)
22 | {
23 | m_decay1TimesSusLevel = m_decay1 * m_sustainLevel;
24 | }
25 |
26 | inline float Contour::Clip(float x)
27 | {
28 | if (x < 0)
29 | return 0;
30 | else if (x > 1.0f)
31 | return 1.0f;
32 |
33 | return x;
34 | }
35 |
36 |
37 | void Contour::Render(float *out, int len)
38 | {
39 | float range = m_max - m_min;
40 | float min = m_min;
41 |
42 | if (!out)
43 | return;
44 |
45 | assert(m_attack != 0);
46 | assert(m_release != 0);
47 |
48 | for (int i=0; i= .98)
59 | {
60 | m_curValue = .98;
61 | m_phase = kDecay;
62 | }
63 | }
64 | else if (m_phase == kDecay)
65 | {
66 | m_curValue = (m_decay*m_lastOut) + m_decay1TimesSusLevel;
67 | m_lastOut = m_curValue;
68 |
69 | if (m_curValue <= m_sustainLevel)
70 | {
71 | if (m_sustain)
72 | {
73 | m_phase = kSustain;
74 | }
75 | else
76 | {
77 | m_phase = kRelease;
78 | }
79 | }
80 | }
81 | else if (m_phase == kSustain)
82 | {
83 | m_curValue = (m_fade*m_lastOut);
84 | m_lastOut = m_curValue;
85 | if (m_curValue <= 0.001)
86 | {
87 | m_phase = kFinished;
88 | m_curValue = 0;
89 | m_lastOut = 0;
90 | }
91 | }
92 | else if (m_phase == kRelease)
93 | {
94 | m_curValue = (m_release*m_lastOut);
95 | m_lastOut = m_curValue;
96 |
97 | if (m_curValue <= 0.001)
98 | {
99 | m_phase = kFinished;
100 | m_curValue = 0;
101 | m_lastOut = 0;
102 | }
103 | }
104 |
105 | // TODO: Vary this with the sampling rate. It's really just
106 | // a smoothing function, so it's probably OK for now
107 | m_ctlVal = m_ctlVal*.99 + m_ctlIn*.01;
108 |
109 | *out++ = Clip(min + m_curValue * range * m_ctlVal);
110 | }
111 | }
112 |
113 |
--------------------------------------------------------------------------------
/src/components/Contour.h:
--------------------------------------------------------------------------------
1 | /* Phase Distortion Synthesizer (c) 2011 Louis Gorenfeld */
2 |
3 |
4 | #ifndef _CONTOUR_H_
5 | #define _CONTOUR_H_
6 |
7 | #include
8 | #include "SndBuf.h"
9 | #include "BufferManager.h"
10 |
11 | // Linear trapezoidal contour generator
12 | // (wow, that makes it sounds so much more complex than it is!)
13 | class Contour
14 | {
15 | public:
16 | Contour();
17 | ~Contour() {}
18 |
19 | // Set attack in ms
20 | void SetAttackExponential(float a, float sR)
21 | {
22 | float sams = (a/1000.0)*sR;
23 | m_attack = pow((float)M_E, (float)-1.0f/sams);
24 | m_attack1 = 1.0f - m_attack;
25 | }
26 | // Set Decay in ms, return seconds Release
27 | float SetDecayExponential(float d, float sR)
28 | {
29 | float sams = (d/1000.0)*sR;
30 | m_decay = pow((float)M_E, (float)-1.0f/sams);
31 | m_decay1 = 1.0f - m_decay;
32 | m_decay1TimesSusLevel = m_decay1*m_sustainLevel;
33 |
34 | sams = log(.001)/log(m_release);
35 | return (sams*1000.0f) / sR;
36 | }
37 | // Set Release in ms, return seconds Release
38 | float SetReleaseExponential(float d, float sR)
39 | {
40 | float sams = (d/1000.0)*sR;
41 | m_release = pow((float)M_E, (float)-1.0f/sams);
42 | m_release1 = 1.0f - m_release;
43 |
44 | sams = log(.001)/log(m_release);
45 | return (sams*1000.0f) / sR;
46 | }
47 | void SetFadeDirect(float f)
48 | {
49 | m_fade = f;
50 | m_fade1 = 1.0f - m_fade;
51 | m_sustain = (f > 0);
52 | }
53 | void SetFadeExponential(float f, float sR)
54 | {
55 | float sams = (f/1000.0)*sR;
56 | m_fade = pow((float)M_E, (float)-1.0f/sams);
57 | m_fade1 = 1.0f - m_fade;
58 | m_sustain = (f > 0);
59 | }
60 | // level is amplitude from 0 to 1.0
61 | void SetSustainLevel(float level)
62 | {
63 | m_sustainLevel = level;
64 | m_decay1TimesSusLevel = m_decay1*m_sustainLevel;
65 | }
66 | void SetMinimum(float min) { m_min = min; }
67 | void SetMaximum(float max) { m_max = max; }
68 | // Render REPLACING
69 | void Render(float *out, int len);
70 | SndBuf::sam_t GetValue() { return m_curValue; }
71 |
72 | void GateOn(bool reset=true)
73 | {
74 | if (reset)
75 | {
76 | m_lastOut = 0;
77 | m_curValue = m_noAttack? 1.0f : 0.0f;
78 | }
79 | m_phase = kAttack;
80 | }
81 | void GateOff()
82 | {
83 | if (m_phase != kFinished)
84 | {
85 | m_phase = kRelease;
86 | }
87 | }
88 | bool IsDone() { return m_phase == kFinished; }
89 | bool IsReleased() { return m_phase == kRelease; }
90 | void SetDone() { m_phase = kFinished; }
91 | inline float Clip(float x);
92 |
93 | void NoAttack(bool on=true) { m_noAttack = on; }
94 |
95 | // A control (such as modwheel) can be hooked to this to control
96 | // the brightness of the sound. The envelope wave is then multiplied
97 | // by it. It is smoothed to prevent clicking.
98 | inline void SetControlInput(float in)
99 | {
100 | m_ctlIn = in;
101 | }
102 |
103 | private:
104 | enum phase_t
105 | {
106 | kAttack,
107 | kDecay,
108 | kSustain, // ..and fade
109 | kRelease,
110 | kFinishing,
111 | kFinished,
112 | };
113 |
114 | SndBuf::sam_t m_curValue;
115 | float m_attack;
116 | float m_decay;
117 | float m_release;
118 | float m_fade;
119 | bool m_sustain;
120 | float m_sustainLevel;
121 | float m_min;
122 | float m_max;
123 | phase_t m_phase;
124 | // Discrete control value input here to control brightness
125 | float m_ctlIn;
126 | // Smoothed control value
127 | float m_ctlVal;
128 |
129 | // Coefficients and such the one-pole exponential glide filter
130 | float m_attack1;
131 | float m_decay1;
132 | float m_release1;
133 | float m_fade1;
134 | float m_lastOut;
135 |
136 | // m_decay1 * m_sustainLevel used for envelope decay calculation
137 | float m_decay1TimesSusLevel;
138 |
139 | bool m_noAttack;
140 | };
141 |
142 | #endif
143 |
144 |
145 |
--------------------------------------------------------------------------------
/src/components/FauxVst.h:
--------------------------------------------------------------------------------
1 | /*
2 | * FauxVst.h
3 | * PDVST
4 | *
5 | * Created by Louis Gorenfeld on 9/18/12.
6 | * Copyright 2012 Extent of the Jam. All rights reserved.
7 | *
8 | */
9 |
10 | // This header is intended to get Digits to compile for non-VST
11 | // builds. It's essentially a stub. DO NOT use it to figure out
12 | // the VST SDK since it diverges from the VST SDK spec
13 |
14 | #ifndef _FAUX_VST_H_
15 | #define _FAUX_VST_H_
16 |
17 | #define vst_strncpy strncpy
18 | #define vst_strncat strncat
19 |
20 | typedef int VstInt32;
21 | typedef int* VstIntPtr;
22 |
23 | // This is not used, but it should be non-zero when instantiating
24 | // the plugin (just set it to 1 or something)
25 | typedef void* audioMasterCallback;
26 |
27 | const int kVstMaxProgNameLen = 128;
28 | const int kVstMaxParamStrLen = 128;
29 | const int kVstMaxEffectNameLen = 128;
30 | const int kVstMaxVendorStrLen = 128;
31 | const int kVstMaxProductStrLen = 128;
32 |
33 | // Dummy declarations to make the compiler happy
34 | const int kVstMidiType = 0;
35 | const int kVstPinIsStereo = 0;
36 | const int kVstPinIsActive = 0;
37 |
38 | struct VstPinProperties
39 | {
40 | char label[kVstMaxParamStrLen];
41 | int flags;
42 | };
43 |
44 | struct VstMidiEvent
45 | {
46 | // NOTE: The official SDK uses 4 elements here
47 | char midiData[3];
48 | int deltaFrames;
49 | int type;
50 |
51 | VstMidiEvent() { type = kVstMidiType; }
52 | };
53 |
54 | struct VstEvents
55 | {
56 | int numEvents;
57 | // Only support VstMidiEvents for now
58 | VstMidiEvent *events[2];
59 | };
60 |
61 | class AudioEffect
62 | {
63 | public:
64 | AudioEffect() {}
65 | ~AudioEffect() {}
66 | };
67 |
68 | class AudioEffectX : public AudioEffect
69 | {
70 | public:
71 | AudioEffectX(audioMasterCallback audioMaster, int numPatches, int numParameters) {}
72 | ~AudioEffectX() {}
73 |
74 | protected:
75 | void setNumInputs(int num) {}
76 | void setNumOutputs(int num) {}
77 | void canProcessReplacing() {}
78 | void isSynth() {}
79 | void setUniqueID(int id) {}
80 | void programsAreChunks(bool yeah) {}
81 | void suspend() {}
82 | void resume() {}
83 | void updateDisplay() {}
84 | };
85 |
86 | #endif
87 |
--------------------------------------------------------------------------------
/src/components/FilterBank.h:
--------------------------------------------------------------------------------
1 | //
2 | // FilterBank.h
3 | // PDVST
4 | //
5 | // Created by Louis Gorenfeld on 11/16/12.
6 | //
7 | //
8 |
9 | #ifndef __PDVST__FilterBank__
10 | #define __PDVST__FilterBank__
11 |
12 | //
13 | // FilterBank.cpp
14 | // PDVST
15 | //
16 | // Created by Louis Gorenfeld on 11/16/12.
17 | //
18 | //
19 |
20 | #include
21 | #include "FilterBank.h"
22 |
23 | class FilterBase
24 | {
25 | public:
26 | FilterBase() {}
27 | ~FilterBase() {}
28 | inline void SetSharpness() {} // aka bandwidth, q, resonance
29 | inline void SetFrequency() {};
30 | virtual void SetSamplingRate(float f) { m_sR = f; }
31 |
32 | // If a filter has a control buffer (e.g., brightness), set it with this
33 | virtual void SetControlBuffer(float *buf) { }
34 |
35 | protected:
36 | float m_sR;
37 | };
38 |
39 | // No-resonance 1-pole lowpass filter
40 | class LowPass1p : public FilterBase
41 | {
42 | public:
43 | LowPass1p() : m_a(0), m_b(0), m_lastOut(0) {}
44 | ~LowPass1p() {}
45 | // virtual void SetControlBuffer(float *buf) { m_freqContour = buf; }
46 | inline void SetFrequency(float f)
47 | {
48 | // TODO: Table this?
49 | m_frequency = f;
50 | m_b = exp(-2.0f * M_PI * (f/m_sR));
51 | m_a = 1.0f - m_b;
52 |
53 | }
54 | inline float Tick(float in)
55 | {
56 | return m_lastOut = m_a*in + m_b*m_lastOut;
57 | }
58 | virtual void SetSamplingRate(float f)
59 | {
60 | m_sR = f;
61 | SetFrequency(m_frequency);
62 | }
63 | void Render(float* buf, int len)
64 | {
65 | for (int i=0; i 1.0f) return 1.0f;
354 | else if (x < -1.0f) return -1.0f;
355 | return x;
356 | }
357 | virtual void SetSamplingRate(float f)
358 | {
359 | m_sR = f * m_oversampling;
360 | m_lbFilter.SetSamplingRate(f);
361 | SetFrequency(m_frequency);
362 | }
363 |
364 | inline void SetSharpness(float x) { m_reso = x; }
365 | inline float Tick(float in)
366 | {
367 | for (int i=0; i < m_oversampling; i++)
368 | {
369 | m_lastOuts[0] = Clip(m_a*in + m_b*m_lastOuts[0] - ((m_reso*m_a)*(m_lbFilter.Tick(m_lastOuts[3]))));
370 | m_lastOuts[1] = Clip(m_a*m_lastOuts[0] + m_b*m_lastOuts[1]);
371 | m_lastOuts[2] = Clip(m_a*m_lastOuts[1] + m_b*m_lastOuts[2]);
372 | m_lastOuts[3] = Clip(m_a*m_lastOuts[2] + m_b*m_lastOuts[3]);
373 | }
374 |
375 | return m_lastOuts[m_poles];
376 | }
377 | void Render(float* buf, int len)
378 | {
379 | for (int i=0; i 4)
389 | return false;
390 |
391 | m_poles = poles - 1;
392 | return true;
393 | }
394 | void SetOversampling(int times) { m_oversampling = times; }
395 |
396 | private:
397 | // virtual void SetFrequency(float f)
398 |
399 | float m_lastOuts[4];
400 | int m_poles; // 0 (6db) to 3 (24db)
401 |
402 | float m_reso;
403 | float m_oversampling;
404 | LowPass1p m_lbFilter;
405 | };
406 |
407 | #endif /* defined(__PDVST__FilterBank__) */
408 |
409 |
--------------------------------------------------------------------------------
/src/components/LFO.h:
--------------------------------------------------------------------------------
1 | #ifndef _LFO_H_
2 | #define _LFO_H_
3 |
4 | #include
5 | #include
6 | #include "Tables.h"
7 |
8 | class LFO
9 | {
10 | public:
11 | enum lfoType_t
12 | {
13 | kLFO_Sin,
14 | kLFO_Noise,
15 | kLFO_RampUp,
16 | kLFO_RampDn
17 | };
18 |
19 | LFO() : m_type(kLFO_Sin), m_pos(0), m_thisNoise(0), m_lastNoise(0), m_delay(0), m_repeatCountDn(-1), m_repeatSetting(-1) {}
20 | ~LFO() {}
21 | void Render(float *out, int len)
22 | {
23 | for (int i=0; i 0)
30 | {
31 | out[i] = 0;
32 | m_delay--;
33 | }
34 | else if (m_type == kLFO_Sin)
35 | {
36 | out[i] = Tables::Sin(m_pos);
37 | m_pos += m_delta;
38 | }
39 | else if (m_type == kLFO_Noise)
40 | {
41 | // If the rate is above 40hz, start smoothing it (TODO, get rate :))
42 | // TODO: Use better equation (too lazy to think right now)
43 | out[i] = (m_lastNoise * (1.0f-m_pos)) + (m_thisNoise * m_pos);
44 | m_pos += m_delta;
45 | }
46 | else if (m_type == kLFO_RampDn)
47 | {
48 | out[i] = (m_pos - 1.0f);
49 | m_pos += m_delta;
50 | }
51 | else if (m_type == kLFO_RampUp)
52 | {
53 | out[i] = (1.0f - m_pos);
54 | m_pos += m_delta;
55 | }
56 |
57 | while (m_pos >= 1.0f)
58 | {
59 | if (m_type == 1)
60 | {
61 | m_lastNoise = m_thisNoise;
62 | // Normal distribution
63 | m_thisNoise = (((rand())&65535)/32767.0f)-1.0f;
64 | m_thisNoise += (((rand())&65535)/32767.0f)-1.0f;
65 | m_thisNoise /= 2.0f;
66 | }
67 | // Don't go past 0 (see comparison at beginning of fn)
68 | if (m_repeatCountDn > 0)
69 | m_repeatCountDn--;
70 | m_pos -= 1.0f;
71 | }
72 | }
73 | }
74 | void Reset() { m_pos = 0; m_delay = m_delayInit; m_repeatCountDn = m_repeatSetting; }
75 | void SetRate(float rate, float sR) { m_delta = rate/sR; }
76 | void SetDelay(float delayMs, float sR) { m_delayInit = m_delay = (delayMs*sR)/1000.0f; }
77 | void SetType(lfoType_t type) { m_type = type; }
78 | void SetRepeat(int repeat) { m_repeatSetting = repeat; }
79 | lfoType_t GetType() { return m_type; }
80 |
81 | private:
82 | lfoType_t m_type;
83 | float m_delta;
84 | float m_pos;
85 | float m_thisNoise;
86 | float m_lastNoise;
87 | int m_delay;
88 | int m_delayInit;
89 | // -1 for infinite
90 | int m_repeatCountDn;
91 | int m_repeatSetting;
92 | };
93 |
94 | #endif
95 |
--------------------------------------------------------------------------------
/src/components/LGDebug.h:
--------------------------------------------------------------------------------
1 |
2 | #ifndef _LGDEBUG_H_
3 | #define _LGDEBUG_H_
4 |
5 | #include
6 | #include
7 |
8 |
9 | // The following is cribbed from the GCC manual:
10 |
11 | /* Subtract the `struct timeval' values X and Y,
12 | storing the result in RESULT.
13 | Return 1 if the difference is negative, otherwise 0. */
14 |
15 | int
16 | timeval_subtract (struct timeval *result, struct timeval *x, struct timeval *y);
17 |
18 | class CPUBench
19 | {
20 | public:
21 | CPUBench()
22 | {
23 | gettimeofday(&m_start, 0);
24 | }
25 |
26 | ~CPUBench()
27 | {
28 | usec_t curTime;
29 |
30 | gettimeofday(&m_finish, 0);
31 |
32 | struct timeval diff;
33 | timeval_subtract(&diff, &m_finish, &m_start);
34 | curTime = (diff.tv_sec*1000000) + diff.tv_usec;
35 |
36 | if (s_peak < curTime)
37 | s_peak = curTime;
38 |
39 | s_sum += curTime;
40 | s_numBufs++;
41 | }
42 |
43 | // Reset the value for a new frame
44 | void Reset()
45 | {
46 | s_sum = 0;
47 | s_numBufs = 0;
48 | s_peak = 0;
49 | }
50 |
51 | // Print out the CPU% given the length of the buffer
52 | static void Print(float bufUs)
53 | {
54 | printf("Average: %02.2f; Peak: %02.2f\n", (((float)s_sum/(float)s_numBufs)/bufUs)*100, ((float)s_peak/bufUs)*100);
55 | // It's kind of weird to set lastAverage here, but it's convinient
56 | s_lastAverage = (((float)s_sum/(float)s_numBufs)/bufUs)*100;
57 | }
58 |
59 | static float GetLastAverage() { return s_lastAverage; }
60 |
61 | private:
62 | typedef long int usec_t;
63 |
64 | // Beginning and end of the interval currently measured
65 | struct timeval m_start;
66 | struct timeval m_finish;
67 |
68 | // Running sum of all the buffers so far
69 | static usec_t s_sum;
70 | // Number of buffers in sum
71 | static int s_numBufs;
72 |
73 | // Peak - worst buffer length so far
74 | static usec_t s_peak;
75 |
76 | static float s_lastAverage;
77 | };
78 |
79 | #endif
80 |
--------------------------------------------------------------------------------
/src/components/NoiseGen.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // NoiseGen.cpp
3 | // DrumVST
4 | //
5 | // Created by Louis Gorenfeld on 10/16/16.
6 | //
7 | //
8 |
9 | #include "NoiseGen.h"
10 | #include "Tables.h"
11 |
12 | NoiseGen::NoiseGen() :
13 | m_pos(0),
14 | m_delta(0)
15 | {
16 |
17 | }
18 |
19 | NoiseGen::~NoiseGen()
20 | {
21 |
22 | }
23 |
24 | void NoiseGen::SetSamplingRate(float sR)
25 | {
26 | m_delta = Tables::kNoiseRate / sR;
27 | }
28 |
29 | void NoiseGen::Render(float *out, int len)
30 | {
31 | for (int i=0; i < len; i++)
32 | {
33 | out[i] = Tables::Noise(m_pos);
34 |
35 | m_pos += m_delta;
36 | while (m_pos >= Tables::kNoisePoints)
37 | m_pos -= Tables::kNoisePoints;
38 | }
39 | }
40 |
41 | void NoiseGen::Trigger()
42 | {
43 | m_pos = rand() & Tables::kNoisePoints;
44 | }
45 |
--------------------------------------------------------------------------------
/src/components/NoiseGen.h:
--------------------------------------------------------------------------------
1 | //
2 | // NoiseGen.h
3 | // DrumVST
4 | //
5 | // Created by Louis Gorenfeld on 10/16/16.
6 | //
7 | //
8 |
9 | #ifndef NoiseGen_h
10 | #define NoiseGen_h
11 |
12 | class NoiseGen
13 | {
14 | public:
15 | NoiseGen();
16 | ~NoiseGen();
17 | void Render(float *out, int len);
18 | void SetSamplingRate(float sR);
19 | void Trigger();
20 |
21 | private:
22 | float m_pos;
23 | float m_delta;
24 | };
25 |
26 |
27 | #endif /* NoiseGen_h */
28 |
--------------------------------------------------------------------------------
/src/components/Oversampler.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include "Oversampler.h"
6 |
7 |
8 | Oversampler::Oversampler(int kernelSize, int times) :
9 | m_kernelSize(kernelSize),
10 | m_bufPos(0),
11 | m_times(times)
12 |
13 | {
14 | float cutoff = .5 / (float)times;
15 |
16 | m_kernel = new float[kernelSize];
17 | m_ins = new float[kernelSize];
18 | for (int i=0; i < kernelSize; i++)
19 | {
20 | float idx = i - (kernelSize/2.0);
21 | float winPos = (float)i / (float)kernelSize;
22 |
23 | // Blackman window
24 | float window = .42 - .5*cos(2.0*M_PI*winPos) + .08*cos(4.0*M_PI*winPos);
25 |
26 | if (idx == 0)
27 | m_kernel[i] = 2.0*M_PI*cutoff;
28 | else
29 | m_kernel[i] = sin(2.0*M_PI*cutoff*idx) / idx;
30 |
31 | m_kernel[i] *= window;
32 | m_ins[i] = 0;
33 | }
34 |
35 | // Normalize the kernels
36 | float sum = 0;
37 | for (int i=0; i < kernelSize; i++)
38 | sum += m_kernel[i];
39 |
40 | for (int i=0; i < kernelSize; i++)
41 | m_kernel[i] /= sum;
42 | }
43 |
44 |
45 | void Oversampler::render(float *in, float *out, int numInSamples)
46 | {
47 | memset(out, 0, sizeof(float)*numInSamples);
48 |
49 | for (int i=0; i < numInSamples; i+=m_times)
50 | {
51 | m_ins[m_bufPos] = *in++;
52 |
53 | int pos = m_bufPos;
54 | for (int j=0; j < m_kernelSize; j++)
55 | {
56 | *out += m_ins[pos] * m_kernel[j];
57 | if (--pos < 0)
58 | pos += m_kernelSize;
59 | }
60 |
61 | out++;
62 | m_bufPos = (m_bufPos + 1) % m_kernelSize;
63 | }
64 | }
65 |
66 | Oversampler::~Oversampler()
67 | {
68 | delete[] m_kernel;
69 | delete[] m_ins;
70 | }
71 |
72 |
73 |
74 | // For testing
75 |
76 | // OPTIMIZE: If we're going down to 1/8th of sR, every 4th sample in the filter is 0 (1/4 of Nyquist)
77 | // So, we can skip those. We could unroll it. We can also skip every 4th output sample.
78 | /*
79 | int main()
80 | {
81 | //WinSincFilter filter(128, .015);
82 | Oversampler filter(64, .125);
83 | float noise[44100];
84 | float out[44100];
85 |
86 | float pos = 0;
87 |
88 | for (int i=0; i < 44100; i++)
89 | {
90 | noise[i] = sin(M_PI*2.0*pos);
91 | pos += 8000/44100.0;
92 | }
93 |
94 | // for (int i=0; i < 44100; i++)
95 | // noise[i] = ((rand() & 255) - 127) / 127.0f;
96 |
97 | filter.render(noise, out, 44100, 1);
98 |
99 | FILE *fp = fopen("test.raw", "wb");
100 | fwrite(out, sizeof(float), 44100, fp);
101 |
102 | fclose(fp);
103 | }
104 | */
105 |
--------------------------------------------------------------------------------
/src/components/Oversampler.h:
--------------------------------------------------------------------------------
1 | #ifndef _OVERSAMPLER_H_
2 | #define _OVERSAMPLER_H_
3 |
4 | // Straight-forward non-convolving sinc filter
5 | class Oversampler
6 | {
7 | public:
8 | Oversampler(int kernelSize, int times);
9 | ~Oversampler();
10 |
11 | void render(float *in, float *out, int numInSamples);
12 |
13 | private:
14 | int m_kernelSize;
15 | int m_bufPos;
16 | int m_times;
17 | float *m_kernel;
18 | float *m_ins;
19 | };
20 |
21 | #endif
--------------------------------------------------------------------------------
/src/components/PatchBankList.h:
--------------------------------------------------------------------------------
1 | /*
2 | * PatchBankList.h
3 | * PDVST
4 | *
5 | * Created by Louis Gorenfeld on 8/18/12.
6 | * Copyright 2012 Extent of the Jam. All rights reserved.
7 | *
8 | */
9 |
10 | // This is a generic interface for the patch bank list
11 | // Use a subclass to use this!
12 |
13 | // The class' job is to return a list of filenames. Upon
14 | // an error, it should return a blank list.
15 |
16 | // For legacy reasons, this module is called PatchBankList.
17 | // But, the implementation-specific PatchBankList files
18 | // (PatchBankListMac, PatchBankListWin) actually are the
19 | // ones that supply the PatchBankList class. These only
20 | // supply PatchBankListBase.
21 |
22 | #ifndef _PATCHBANKLIST_H_
23 | #define _PATCHBANKLIST_H_
24 |
25 | #include
26 | #include
27 |
28 | class PatchBankListBase
29 | {
30 | public:
31 | typedef std::vector fileList_t;
32 |
33 | PatchBankListBase() : m_curPatch(0), m_curBank(0), m_numPatches(0) {}
34 | ~PatchBankListBase() {}
35 |
36 | void SetBankDir(std::string dir)
37 | {
38 | m_curBankDir = dir;
39 | }
40 |
41 | void SetBankDir(int index)
42 | {
43 | m_curBankDir = m_bankListCache[index];
44 | }
45 |
46 | virtual PatchBankListBase::fileList_t GetBankList() = 0;
47 | virtual PatchBankListBase::fileList_t GetPatchList() = 0;
48 | PatchBankListBase::fileList_t m_bankListCache;
49 | PatchBankListBase::fileList_t m_patchListCache;
50 | std::string GetCurBankDir() { return m_bankPrefix + "/" + m_curBankDir + "/"; }
51 | std::string GetUserBankDir() { return m_bankPrefix + "/" + "User"; }
52 | int GetCurBank() { return m_curBank; }
53 | std::string GetCurPatchName()
54 | {
55 | if (m_curPatch == -1 || m_patchListCache.size() == 0)
56 | return "";
57 | else
58 | return m_patchListCache[m_curPatch];
59 | }
60 | int GetCurPatch() { return m_curPatch; }
61 | int SetCurBankDir(std::string newDir)
62 | {
63 | m_curBankDir = newDir;
64 |
65 | unsigned int index = 0;
66 | for (PatchBankListBase::fileList_t::iterator it = m_bankListCache.begin();
67 | it != m_bankListCache.end();
68 | it++, index++)
69 | {
70 | if (*it == m_curBankDir)
71 | break;
72 | }
73 |
74 | if (index < m_bankListCache.size())
75 | m_curBank = index;
76 | else
77 | m_curBank = -1;
78 |
79 | return m_curBank;
80 | }
81 | void SetCurBankDir(int index) { m_curBankDir = m_bankListCache[index]; }
82 | void SetCurPatch(int index)
83 | {
84 | if (m_patchListCache.size() > 0)
85 | {
86 | m_curPatch = index;
87 | m_curPatchName = m_patchListCache[index];
88 | }
89 | }
90 | // When set like this, there's no knowledge of the patch index number. The EditorWindow will
91 | // try to correct it when it first opens. This function is only to be used during VstCore init.
92 | // Return now-current patch
93 | int SetCurPatch(std::string newPatch)
94 | {
95 | m_curPatchName = newPatch;
96 |
97 | unsigned int index = 0;
98 | for (PatchBankListBase::fileList_t::iterator it = m_patchListCache.begin();
99 | it != m_patchListCache.end();
100 | it++, index++)
101 | {
102 | if (*it == m_curPatchName)
103 | break;
104 | }
105 |
106 | if (index < m_patchListCache.size())
107 | m_curPatch = index;
108 | else
109 | m_curPatch = -1;
110 |
111 | return m_curPatch;
112 | }
113 | // Get the *cached* number of patches. A bank must be set and a patch
114 | // list obtained before this is valid.
115 | int GetNumPatches() { return m_numPatches; }
116 |
117 | protected:
118 | // Path to the currently-selected bank directory
119 | std::string m_curBankDir;
120 | std::string m_curPatchName;
121 | // Path to where the banks can be found
122 | std::string m_bankPrefix;
123 | // Index of the current patch and bank
124 | int m_curPatch;
125 | int m_curBank;
126 | // Cache of the number of patches in the bank (to avoid
127 | // getting a file list each time)
128 | int m_numPatches;
129 | };
130 |
131 | #ifdef _MSC_VER
132 | #include "PatchBankListWin.h"
133 | #elif __APPLE__
134 | #include "PatchBankListMac.h"
135 | #else
136 | #warning "Creating empty PatchBankList implementation for this platform!"
137 |
138 | class PatchBankList : public PatchBankListBase
139 | {
140 | public:
141 | PatchBankList() {}
142 | ~PatchBankList() {}
143 | virtual PatchBankListBase::fileList_t GetBankList()
144 | {
145 | return PatchBankListBase::fileList_t();
146 | }
147 | virtual PatchBankListBase::fileList_t GetPatchList()
148 | {
149 | return PatchBankListBase::fileList_t();
150 | }
151 | };
152 | #endif
153 | #endif // header compile-once
154 |
--------------------------------------------------------------------------------
/src/components/PatchBankListMac.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * PatchBankListMac.cpp
3 | * PDVST
4 | *
5 | * Created by Louis Gorenfeld on 8/18/12.
6 | * Copyright 2012 Extent of the Jam. All rights reserved.
7 | *
8 | */
9 |
10 | #include // sort
11 | #include
12 | #include "PatchBankListMac.h"
13 |
14 | PatchBankList::PatchBankList()
15 | {
16 | m_bankPrefix = "/Applications/Digits/Presets";
17 | }
18 |
19 | PatchBankList::~PatchBankList()
20 | {
21 | }
22 |
23 | PatchBankList::fileList_t PatchBankList::GetBankList()
24 | {
25 | return GetFileList(m_bankPrefix, true);
26 | }
27 |
28 | PatchBankList::fileList_t PatchBankList::GetPatchList()
29 | {
30 | PatchBankList::fileList_t files = GetFileList(m_bankPrefix + "/" + m_curBankDir);
31 | m_numPatches = files.size();
32 | return files;
33 | }
34 |
35 | PatchBankList::fileList_t PatchBankList::GetFileList(std::string dirStr, bool isBankList)
36 | {
37 | PatchBankList::fileList_t* files;
38 | if (isBankList)
39 | {
40 | m_bankListCache.clear();
41 | files = &m_bankListCache;
42 | }
43 | else
44 | {
45 | m_patchListCache.clear();
46 | files = &m_patchListCache;
47 | }
48 |
49 | DIR* dir = opendir(dirStr.c_str());
50 | struct dirent* file;
51 |
52 | if (!dir)
53 | {
54 | files->push_back("");
55 | return *files;
56 | }
57 |
58 | while ((file = readdir(dir)))
59 | {
60 | if ((!isBankList && file->d_type == DT_REG) || (isBankList && file->d_type == DT_DIR))
61 | {
62 | std::string stdname = file->d_name;
63 | if (stdname.at(0) == '.')
64 | continue;
65 |
66 | // strip '.fxp'
67 | if (!isBankList)
68 | {
69 | size_t pos = stdname.find(".fxp");
70 | if (pos != std::string::npos)
71 | stdname = stdname.substr(0, pos);
72 | }
73 |
74 | files->push_back(stdname);
75 | }
76 | }
77 |
78 | if (files->size() == 0)
79 | files->push_back("");
80 |
81 | std::sort(files->begin(), files->end());
82 |
83 | closedir(dir);
84 | return *files;
85 | }
86 |
--------------------------------------------------------------------------------
/src/components/PatchBankListMac.h:
--------------------------------------------------------------------------------
1 | /*
2 | * PatchBankListMac.h
3 | * PDVST
4 | *
5 | * Created by Louis Gorenfeld on 8/18/12.
6 | * Copyright 2012 LouisGorenfeld. All rights reserved.
7 | *
8 | */
9 |
10 | #ifndef _PATCHBANKLISTMAC_H_
11 | #define _PATCHBANKLISTMAC_H_
12 |
13 | #include "PatchBankList.h" // interface
14 |
15 | class PatchBankList : public PatchBankListBase
16 | {
17 | public:
18 | PatchBankList();
19 | ~PatchBankList();
20 |
21 | virtual PatchBankListBase::fileList_t GetBankList();
22 | virtual PatchBankListBase::fileList_t GetPatchList();
23 |
24 | private:
25 | static const char* s_banksPath;
26 | PatchBankListBase::fileList_t GetFileList(std::string dir, bool isBankList=false);
27 | };
28 |
29 | #endif
--------------------------------------------------------------------------------
/src/components/PatchBankListWin.cpp:
--------------------------------------------------------------------------------
1 | #include // sort
2 | #include
3 | #include // SHGetKnownFolderPath
4 | #include
5 | #include "PatchBankListWin.h"
6 |
7 | PatchBankList::PatchBankList()
8 | {
9 | TCHAR path[MAX_PATH];
10 | if (SHGetFolderPath(0, CSIDL_MYDOCUMENTS, 0, NULL, path) == S_OK)
11 | {
12 | m_bankPrefix = (char*)path;
13 | m_bankPrefix += "/Extent of the Jam/Digits/Patches";
14 | }
15 | }
16 |
17 | PatchBankList::~PatchBankList()
18 | {
19 | }
20 |
21 | PatchBankList::fileList_t PatchBankList::GetBankList()
22 | {
23 | return GetFileList(m_bankPrefix + "/*", true);
24 | }
25 |
26 | PatchBankList::fileList_t PatchBankList::GetPatchList()
27 | {
28 | PatchBankList::fileList_t files = GetFileList(m_bankPrefix + "/" + m_curBankDir + "/*", false);
29 | m_numPatches = files.size();
30 | return files;
31 | }
32 |
33 | PatchBankList::fileList_t PatchBankList::GetFileList(std::string dirStr, bool isBankList)
34 | {
35 | PatchBankListBase::fileList_t fileList;
36 | WIN32_FIND_DATA findData;
37 | HANDLE hFind;
38 |
39 | PatchBankList::fileList_t* files;
40 | if (isBankList)
41 | {
42 | m_bankListCache.clear();
43 | files = &m_bankListCache;
44 | }
45 | else
46 | {
47 | m_patchListCache.clear();
48 | files = &m_patchListCache;
49 | }
50 |
51 | hFind = FindFirstFile(dirStr.c_str(), &findData);
52 |
53 | if (hFind != INVALID_HANDLE_VALUE)
54 | {
55 | do
56 | {
57 | if ((isBankList && findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
58 | || (!isBankList && !(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)))
59 | {
60 |
61 | std::string stdname = findData.cFileName;
62 | if (stdname == "." || stdname == "..")
63 | continue;
64 |
65 | // strip '.fxp'
66 | if (!isBankList)
67 | {
68 | size_t pos = stdname.find(".fxp");
69 | if (pos != std::string::npos)
70 | stdname = stdname.substr(0, pos);
71 | }
72 |
73 | files->push_back(stdname.c_str());
74 | }
75 | } while (FindNextFile(hFind, &findData));
76 | }
77 |
78 | std::sort(files->begin(), files->end());
79 |
80 | return *files;
81 | }
82 |
83 |
--------------------------------------------------------------------------------
/src/components/PatchBankListWin.h:
--------------------------------------------------------------------------------
1 | #ifndef _PATCHBANKLISTWIN_H_
2 | #define _PATCHBANKLISTWIN_H_
3 |
4 | #include
5 | #include "PatchBankList.h"
6 |
7 | class PatchBankList : public PatchBankListBase
8 | {
9 | public:
10 | PatchBankList();
11 | ~PatchBankList();
12 | virtual PatchBankListBase::fileList_t GetBankList();
13 | virtual PatchBankListBase::fileList_t GetPatchList();
14 | PatchBankListBase::fileList_t GetFileList(std::string dirStr, bool isBankList);
15 | };
16 |
17 | #endif
--------------------------------------------------------------------------------
/src/components/SndBuf.cpp:
--------------------------------------------------------------------------------
1 | /* Phase Distortion Synthesizer (c) 2011 Louis Gorenfeld */
2 |
3 | #include "BufferManager.h"
4 | #include "SndBuf.h"
5 | #include "Tables.h"
6 |
7 | SndBuf::SndBuf(BufferManager &manager, std::string name) :
8 | m_manager(manager),
9 | m_name(name)
10 | {
11 | m_len = manager.GetHostBlockSize();
12 | m_buf = new sam_t[m_len];
13 | m_manager.AddBuffer(this);
14 | }
15 | /*
16 | SndBuf::SndBuf(BufferManager &manager, int len) :
17 | m_manager(manager),
18 | m_len(len)
19 | {
20 | m_buf = new sam_t[len];
21 | memset(m_buf, 0, sizeof(sam_t)*len);
22 | m_manager.AddBuffer(this);
23 | }
24 | */
25 | SndBuf::~SndBuf()
26 | {
27 | m_manager.RemoveBuffer(this);
28 | delete[] m_buf;
29 | }
30 |
31 | SndBuf::SndBuf(const SndBuf& b) :
32 | m_manager(b.m_manager)
33 | {
34 | m_len = b.m_len;
35 | memcpy(m_buf, b.m_buf, sizeof(sam_t)*b.m_len);
36 | }
37 |
38 |
39 | void SndBuf::Resize(int newSize)
40 | {
41 | if (m_buf)
42 | delete[] m_buf;
43 | m_buf = new sam_t[newSize];
44 | Tables::ZeroMem(m_buf, newSize);
45 | m_len = newSize;
46 | }
47 |
48 | float SndBuf::GetSamplingRate()
49 | {
50 | return m_manager.GetSamplingRate();
51 | }
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/src/components/SndBuf.h:
--------------------------------------------------------------------------------
1 | /* Phase Distortion Synthesizer (c) 2011 Louis Gorenfeld */
2 |
3 | /* The SndBuf class is responsible for allocating and deallocating its
4 | * buffer, but the BufferManager class will automatically resize every
5 | * buffer when the block size changes in the host */
6 |
7 | #ifndef _SNDBUF_H_
8 | #define _SNDBUF_H_
9 |
10 | #include
11 | #include
12 | #include
13 | #include "Tables.h"
14 |
15 | class BufferManager;
16 |
17 | class SndBuf
18 | {
19 | public:
20 | typedef float sam_t;
21 |
22 | SndBuf(BufferManager &manager, std::string name);
23 | //SndBuf(BufferManager &manager, int len);
24 | ~SndBuf();
25 | SndBuf(const SndBuf& buf);
26 |
27 | int Len() { return m_len; }
28 | sam_t* Data() { return m_buf; }
29 | void Resize(int newSize);
30 | // Return sampling rate from manager
31 | float GetSamplingRate();
32 | // Zero out buffer
33 | inline void Zero()
34 | {
35 | Tables::ZeroMem(m_buf, m_len);
36 | }
37 |
38 | private:
39 | BufferManager &m_manager;
40 | // Length of the buffer in frames
41 | int m_len;
42 | // Sample data for the buffer
43 | sam_t *m_buf;
44 | // Name of the buffer to make debugging less hellish
45 | std::string m_name;
46 | };
47 | #endif
48 |
49 |
--------------------------------------------------------------------------------
/src/components/Tables.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include "Tables.h"
4 |
5 | float Tables::g_sinTab[kSinePoints+1];
6 | float Tables::g_cosTab[kSinePoints+1];
7 | float Tables::g_softClipTab[kSoftClipPoints+1];
8 | float Tables::g_dbTab[kDbPoints+1];
9 | float Tables::g_pulseTab[kPulsePoints];
10 | float Tables::g_noiseTab[kNoisePoints+1];
11 |
12 | void Tables::Init()
13 | {
14 | for (int i=0; i
5 | #include
6 | #ifdef __APPLE__
7 | #include
8 | #endif
9 |
10 | // Tables and misc. globals
11 |
12 | namespace Tables
13 | {
14 | void Init();
15 |
16 | // This goes from 0 to 1, unlike real sine
17 | // which goes from 0 to 2pi
18 | inline float Sin(float x);
19 | inline float Cos(float x);
20 | inline float Noise(float x);
21 | inline float dbToAmp(float x);
22 |
23 | inline float SoftClip(float x);
24 | inline void ZeroMem(float *buf, int len);
25 |
26 | const int kSinePoints = 8192;
27 | const int kPulsePoints = 4096;
28 | const float kNoiseRate = 30000;
29 | const int kNoisePoints = kNoiseRate * 4;
30 | extern float g_sinTab[kSinePoints+1];
31 | extern float g_cosTab[kSinePoints+1];
32 | extern float g_pulseTab[kPulsePoints];
33 |
34 | // 1 entry for each 16-bit dB (interpolated when reading)
35 | const int kDbPoints = 96;
36 | extern float g_dbTab[kDbPoints+1];
37 |
38 | const int kSoftClipPoints = 256;
39 | extern float g_softClipTab[kSoftClipPoints+1];
40 | extern float g_noiseTab[kNoisePoints+1];
41 |
42 | #ifdef DIGITS_PRO
43 | const int kNumLFOs = 3;
44 | #else
45 | const int kNumLFOs = 1;
46 | #endif
47 | };
48 |
49 | inline float Tables::Noise(float x)
50 | {
51 | float dist = x - floor(x);
52 | int i = x;
53 | return g_noiseTab[i] + dist*(g_noiseTab[i+1] - g_noiseTab[i]);
54 | }
55 |
56 | inline float Tables::Sin(float x)
57 | {
58 | float fIndex = x*kSinePoints;
59 |
60 | // This profiled to be faster than fmod
61 | while (fIndex >= kSinePoints)
62 | fIndex -= kSinePoints;
63 | while (fIndex < 0)
64 | fIndex += kSinePoints;
65 |
66 | // Short circuit this function-- this is nearest neighbor. With
67 | // a 8k-entry table, there doesn't seem to be noticible noise and
68 | // it uses less CPU than, say, a 256-entry table with interpolation
69 | // below (on an Intel i5)
70 | return g_sinTab[(int)fIndex];
71 |
72 | #if 0
73 | float frac = fIndex - int(fIndex);
74 | int index = fIndex;
75 | float ret = g_sinTab[index] + ( g_sinTab[index+1] - g_sinTab[index] )*frac;
76 |
77 | return ret;
78 | #endif
79 | }
80 |
81 | inline float Tables::Cos(float x)
82 | {
83 | // Cribbed from Sin()-- go see comments there
84 | float fIndex = x*kSinePoints;
85 |
86 | // This profiled to be faster than fmod
87 | while (fIndex >= kSinePoints)
88 | fIndex -= kSinePoints;
89 | while (fIndex < 0)
90 | fIndex += kSinePoints;
91 | // if (x == NAN) { printf("NAN2 from x = %f\n", x); return 0; }
92 |
93 |
94 | return g_cosTab[(int)fIndex];
95 | }
96 |
97 | inline float Tables::SoftClip(float x)
98 | {
99 |
100 | float fIndex = ((x + 1.0f)/2.0f) * (float)kSoftClipPoints;
101 | int index = (int)fIndex;
102 | float frac = fIndex - index;
103 | return g_softClipTab[index] + (g_softClipTab[index+1] - g_softClipTab[index]) * frac;
104 | }
105 |
106 | inline void Tables::ZeroMem(float *buf, int len)
107 | {
108 | #ifdef __APPLE__
109 | vDSP_vclr(buf, 1.0, len);
110 | #else
111 | for (int i=0; i */
2 |
3 | #include "Voice.h"
4 | #include "VstCore.h"
5 |
6 | #ifdef DIGITS_MULTICORE
7 | #include // EBUSY for trylock
8 | #include
9 | #endif
10 |
11 | float Voice::kAttackRange = 1000.0f;
12 | float Voice::kAttackMinimumAmp = 1.0f;
13 | float Voice::kAttackMinimumShaper = 1.0f;
14 | float Voice::kDecayRange = 1000.0f;
15 | float Voice::kDecayMinimum = 20.0f;
16 | float Voice::kReleaseRange = 1000.0f;
17 | float Voice::kReleaseMinimum = 20.0f;
18 | float Voice::kFadeRange = 3000.0f;
19 | float Voice::kFadeMinimum = 500.0f;
20 | float Voice::kDetuneMaximum = .01f;
21 | float Voice::kLFOMinimum = .25f; //hz
22 | float Voice::kLFORange = 1000.0f; //well into audio range
23 | float Voice::kPWMMinimum = .1f;
24 | float Voice::kPWMRange = .8f;
25 |
26 | #ifdef DBGMCORE
27 | #define DEBUG_MCORE(...) { fprintf(stderr, __VA_ARGS__); }
28 | #else
29 | #define DEBUG_MCORE
30 | #endif
31 |
32 | // This is to shape parameter space so, for example, the slider for
33 | // an envelope has more "short decay" options than long ones. This
34 | // makes controls with a lot of range much easier to use.
35 | inline float ExpShape(float base, float x)
36 | {
37 | float range = base - 1;
38 | return ((pow(base, x) - 1.0f)/range);
39 | }
40 |
41 | Voice::Voice(int voiceNum) :
42 | m_pdOsc1(),
43 | m_pdOsc2(),
44 | m_pitch(0),
45 | m_detune(0),
46 | m_octave(1.0f),
47 | m_mix(.5f),
48 | m_resoVol(0),
49 | m_pulseWidth(.5f),
50 | m_delta(0),
51 | m_deltaLo(0),
52 | m_deltaHi(0),
53 | m_delta2(0),
54 | m_deltaLo2(0),
55 | m_deltaHi2(0),
56 | m_deltaBlend(0),
57 | m_glideSpeed(0),
58 | m_glideMode(kGlide_PolyNoGlide),
59 | m_bend(0),
60 | m_modWheel(0),
61 | m_aftertouch(0),
62 | m_velocity(0),
63 | m_basisWave(0),
64 | m_shpMin(0),
65 | m_shpMax(0),
66 | m_velShp(0),
67 | m_velAmp(0),
68 | m_modShp(0),
69 | m_modLFO1Amp(0),
70 | m_atouchShp(0),
71 | m_atouchLFO1Amp(0),
72 | m_nextSubVoice(0),
73 | m_needsRender(false),
74 | m_isSubVoice(false),
75 | m_lockShaperAmt(0),
76 | m_sR(0),
77 | m_voiceNumber(voiceNum),
78 | m_ampRateScale(0),
79 | m_ampLevelScale(0),
80 | m_ampAttack(0),
81 | m_ampDecay(0),
82 | m_ampRelease(0),
83 | m_shpRateScale(0),
84 | m_shpLevelScale(0),
85 | m_shpAttack(0),
86 | m_shpDecay(0),
87 | m_shpRelease(0),
88 | m_bitCrushPos(0),
89 | m_bitCrushDelta(0),
90 | m_bitCrushBlend(0),
91 | m_bitCrushDivider(0),
92 | m_bitCrushBits(0)
93 | {
94 | #ifdef DIGITS_MULTICORE
95 | pthread_mutex_init(&m_mutex, 0);
96 | #endif
97 |
98 | m_delta = m_deltaHi = m_deltaLo = 0;
99 |
100 | m_pdOsc1.SetSkew(.5);
101 | m_pdOsc2.SetSkew(.99);
102 |
103 | for (int i=0; i 1.0f) levelScale = 1.0f;
137 |
138 | // TODO: Don't pass delta in; might as well do it all at once
139 |
140 | if (reset)
141 | {
142 | ResetPhases();
143 | }
144 | m_ampEnv.GateOn(false);
145 | m_shaperEnv.GateOn(false);
146 | for (int i=0; i= 400)
171 | {
172 | // Intercept (400, 1) and (1200, 0)
173 |
174 | keyScale = 1.0 - (x - 400.0f)/6000.0f;
175 | if (keyScale < 0) keyScale = 0;
176 | }
177 | else {
178 | keyScale = 1.0f;
179 | }
180 |
181 | m_pdOsc1.SetKeyScale(keyScale*levelScale);
182 |
183 | x = m_pdOsc2.GetDelta()*m_sR;
184 | if (x >= 400)
185 | {
186 | // Intercept (400, 1) and (1200, 0)
187 |
188 | keyScale = 1.0 - (x - 400.0f)/6000.0f;
189 | if (keyScale < 0) keyScale = 0;
190 | }
191 | else {
192 | keyScale = 1.0f;
193 | }
194 |
195 | m_pdOsc2.SetKeyScale(keyScale*levelScale);
196 | }
197 |
198 | void Voice::NoteOff(int key)
199 | {
200 | if (key != m_pitch && key >= 0)
201 | return;
202 |
203 | m_ampEnv.GateOff();
204 | m_shaperEnv.GateOff();
205 | }
206 |
207 | void Voice::PitchBend(float value)
208 | {
209 | m_bend = value;
210 | CalcPitch();
211 | }
212 |
213 | void Voice::CalcPitch()
214 | {
215 | float pitch;
216 | float pitch2;
217 |
218 | if (m_bend < 0)
219 | {
220 | pitch = m_delta + ((m_delta-m_deltaLo)*m_bend);
221 | pitch2 = m_delta2 + ((m_delta2-m_deltaLo2)*m_bend);
222 | }
223 | else
224 | {
225 | pitch = m_delta + ((m_deltaHi-m_delta)*m_bend);
226 | pitch2 = m_delta2 + ((m_deltaHi2-m_delta2)*m_bend);
227 | }
228 |
229 | pitch = (1.0f-m_deltaBlend)*pitch + (m_deltaBlend)*pitch2;
230 |
231 | m_pdOsc2.SetPitch((pitch) - (pitch*m_detune));
232 | m_pdOsc1.SetPitch((pitch * m_octave) + (pitch * m_detune));
233 | m_resoGen.SetPitch(pitch);
234 | }
235 |
236 | void Voice::SetBasisWaves()
237 | {
238 | m_pdOsc1.SetBasis(m_basisWave);
239 | m_pdOsc2.SetBasis(m_basisWave);
240 |
241 | }
242 |
243 | void Voice::SetPulseWidths()
244 | {
245 | m_pdOsc1.SetPulseWidth(m_pulseWidth);
246 | m_pdOsc2.SetPulseWidth(m_pulseWidth);
247 | m_resoGen.SetPulseWidth(m_pulseWidth);
248 | }
249 |
250 | void Voice::Render(float *out, int len, Voice::voiceBuffers_t* bufs, bool doContourGens, int thread)
251 | {
252 | // If the mutex is busy, it means another thread has already grabbed
253 | // this voice and its subvoices, so skip it
254 | #ifdef DIGITS_MULTICORE
255 | if (pthread_mutex_trylock(&m_mutex) == EBUSY)
256 | {
257 | DEBUG_MCORE("%s: Lock was busy on voice %d\n", thread==0? "c" : "h", m_voiceNumber);
258 | Tables::ZeroMem(out, len);
259 | return;
260 | }
261 | #endif
262 |
263 | if (IsFree() || !m_needsRender)
264 | {
265 | Tables::ZeroMem(out, len);
266 | #ifdef DIGITS_MULTICORE
267 | pthread_mutex_unlock(&m_mutex);
268 | #endif
269 | m_needsRender = false;
270 | return;
271 | }
272 |
273 | DEBUG_MCORE("%s: processing voice %d\n", thread==0? "c": "h", m_voiceNumber);
274 | m_needsRender = false;
275 |
276 | // Initialize buffers (previously InitBuffers, pre-multicore)
277 | m_pdOsc1.SetBuffers(bufs->m_ampEnvBuf, bufs->m_shpEnvBuf, bufs->m_lfoBufs);
278 | m_pdOsc2.SetBuffers(bufs->m_ampEnvBuf, bufs->m_shpEnvBuf, bufs->m_lfoBufs);
279 | m_resoGen.SetBuffers(bufs->m_ampEnvBuf, bufs->m_shpEnvBuf, bufs->m_lfoBufs);
280 |
281 | // Lock (or unlock) shaper to the specified setting. 0 is off.
282 | m_pdOsc1.LockShaperTo(m_lockShaperAmt);
283 | m_pdOsc2.LockShaperTo(m_lockShaperAmt);
284 |
285 | if (doContourGens)
286 | {
287 | float shpMod = (1.0f-m_velocity) * m_velShp;
288 |
289 | // TODO: Do we want to just set ctlAmt to this? Maybe. Might be more consistent.
290 | m_shaperEnv.SetMaximum(m_shpMax - m_shpMax*shpMod);
291 | m_shaperEnv.SetMinimum(m_shpMin - m_shpMin*shpMod);
292 |
293 | float ctlAmt = m_modWheel*m_modShp + m_aftertouch*m_atouchShp;
294 | if (ctlAmt > 1.0f)
295 | ctlAmt = 1.0f;
296 | m_shaperEnv.SetControlInput(1.0f-ctlAmt);
297 |
298 | m_shaperEnv.Render(bufs->m_shpEnvBuf->Data(), len);
299 | m_ampEnv.Render(bufs->m_ampEnvBuf->Data(), len);
300 |
301 | // TODO: LFOs are surprisingly costly, so we should only
302 | // render this if the LFO is assigned. This should be determined
303 | // when the LFO levels are adjusted, not determined each frame!
304 | for (int i=0; im_lfoBufs[i]->Data(), len);
308 | }
309 |
310 | // Apply LFO1 attenuation if enabled
311 | // TODO: vDSP this sucker!
312 | if (m_atouchLFO1Amp || m_modLFO1Amp)
313 | {
314 | float influence = (1.0f-m_aftertouch)*m_atouchLFO1Amp + (1.0f-m_modWheel)*m_modLFO1Amp;
315 | for (int i=0; im_lfoBufs[0]->Data()[i] *= 1.0f - influence;
317 | }
318 | }
319 | //... but the noise LFO is rendered regardless
320 | else
321 | {
322 | for (int i=0; im_lfoBufs[i]->Data(), len);
326 | }
327 | }
328 |
329 | // Animate glide
330 | if (m_deltaBlend > 0)
331 | {
332 | CalcPitch();
333 | m_deltaBlend += 1.0f / m_glideSpeed;
334 | if (m_deltaBlend >= 1.0f)
335 | {
336 | m_deltaBlend = 0;
337 | m_delta = m_delta2;
338 | m_deltaHi = m_deltaHi2;
339 | m_deltaLo = m_deltaLo2;
340 | CalcPitch();
341 | }
342 | }
343 |
344 | // If doContourGens is false, we assume it's because we're rendering a subvoice
345 | if (doContourGens)
346 | Tables::ZeroMem(out, len);
347 |
348 | float pdVol = 1.0f - m_resoVol;
349 | if (pdVol > 0)
350 | {
351 | Tables::ZeroMem(bufs->m_fmScratchBuf->Data(), len);
352 |
353 | // Don't add in the volume here because it affects the FM indexing
354 | m_pdOsc1.Render(0, bufs->m_fmScratchBuf->Data(), len, 1.0f);
355 | m_pdOsc2.Render(bufs->m_fmScratchBuf->Data(), out, len, m_mix);
356 |
357 | // Scale the volume afterwards so it doesn't interfere with
358 | // the FM indexing, and also apply the envelope here since it's
359 | // a unified envelope for both oscillators
360 | // TODO: Fold this into the volume specified in the pdOsc render function
361 | // and save a mul
362 | // TODO: vDSP this stuff
363 | float osc1mix = 1.0f - m_mix;
364 | for (int i=0; im_fmScratchBuf->Data()[i] * osc1mix;
367 | out[i] *= pdVol * bufs->m_ampEnvBuf->Data()[i];
368 | }
369 | }
370 | if (pdVol < 1.0f)
371 | {
372 | m_resoGen.Render(out, len, m_resoVol);
373 | }
374 |
375 | // Render the subvoices (without contour generator)
376 | if (m_nextSubVoice)
377 | {
378 | if (m_ampEnv.IsDone())
379 | m_nextSubVoice->DisableSubVoices();
380 | m_nextSubVoice->Render(out, len, bufs, false, thread);
381 | }
382 |
383 | // TODO: Find a way to unify volumes so this can be done in the loop above
384 | // TODO: Or at least do this only once for all subvoices
385 | if (doContourGens)
386 | {
387 | // If shaper is locked, that means the filter is engaged (and is responsible
388 | // for brightness control)
389 | if (m_lockShaperAmt)
390 | {
391 | m_trueFilter.SetFrequency(18000.0f * bufs->m_shpEnvBuf->Data()[0]);
392 | m_trueFilter.Render(out, len);
393 | }
394 |
395 | for (int i=0; im_lfoBufs[0]->Data()[i]*m_lfoAmplitude[0]
399 | + bufs->m_lfoBufs[1]->Data()[i]*m_lfoAmplitude[1]
400 | + bufs->m_lfoBufs[2]->Data()[i]*m_lfoAmplitude[2];
401 | #else
402 | float lfoInfluence = bufs->m_lfoBufs[0]->Data()[i]*m_lfoAmplitude[0];
403 | #endif
404 | out[i] -= (out[i]*lfoInfluence);
405 | }
406 | }
407 |
408 | if (m_bitCrushBlend)
409 | {
410 | for (int i=0; i < len; i++)
411 | {
412 | m_bitCrushPos += m_bitCrushDelta;
413 | if (m_bitCrushPos >= 1.0f)
414 | {
415 | m_bitCrushLastSample = (int)(out[i] * m_bitCrushBits);
416 | m_bitCrushPos -= 1.0f;
417 | }
418 | out[i] = ((float)m_bitCrushLastSample / (float)m_bitCrushBits)*m_bitCrushBlend + out[i]*(1.0-m_bitCrushBlend);
419 | }
420 | }
421 |
422 | #ifdef DIGITS_MULTICORE
423 | pthread_mutex_unlock(&m_mutex);
424 | #endif
425 | }
426 |
427 | void Voice::SetParameter(int index, float value)
428 | {
429 | // Obtain Mutex
430 |
431 | VstCore::paramNums_t num = (VstCore::paramNums_t)index;
432 | int lfoSelect = -1;
433 |
434 | switch(num)
435 | {
436 | case VstCore::kO1Skew:
437 | m_pdOsc1.SetSkew(.5f + (value * .5f));
438 | break;
439 | case VstCore::kO1ShpMod:
440 | {
441 | float val;
442 | if (value < .25)
443 | val = .5f;
444 | else if (value < .5)
445 | val = 1.0f;
446 | else if (value < .75)
447 | val = 2.0f;
448 | else
449 | val = 3.0f;
450 | m_pdOsc1.SetShaperMod(val);
451 | break;
452 | }
453 | case VstCore::kO2Skew:
454 | m_pdOsc2.SetSkew(.5f + (value * .5f));
455 | break;
456 | case VstCore::kO2ShpMod:
457 | {
458 | float val;
459 | if (value < .25)
460 | val = .5f;
461 | else if (value < .5)
462 | val = 1.0f;
463 | else if (value < .75)
464 | val = 2.0f;
465 | else
466 | val = 3.0f;
467 | m_pdOsc2.SetShaperMod(val);
468 | break;
469 | }
470 | case VstCore::kO2Vol:
471 | m_mix = value;
472 | break;
473 | case VstCore::kResoVol:
474 | m_resoVol = value;
475 | break;
476 | case VstCore::kResoWave:
477 | if (value < .25)
478 | m_resoGen.SetStyle(ResoGen::kSawQuarter);
479 | else if (value < .5)
480 | m_resoGen.SetStyle(ResoGen::kSawHalf);
481 | else if (value < .75)
482 | m_resoGen.SetStyle(ResoGen::kSquareQuarter);
483 | else
484 | m_resoGen.SetStyle(ResoGen::kSquareHalf);
485 | break;
486 | case VstCore::kAmpAtt:
487 | m_ampAttack = value * kAttackRange + kAttackMinimumAmp;
488 | m_ampEnv.SetAttackExponential(m_ampAttack, m_sR);
489 | break;
490 | case VstCore::kAmpDec:
491 | m_ampDecay = value * kDecayRange + kDecayMinimum;
492 | m_ampEnv.SetDecayExponential(m_ampDecay, m_sR);
493 | break;
494 | case VstCore::kAmpRel:
495 | m_ampRelease = value * kReleaseRange + kReleaseMinimum;
496 | m_ampEnv.SetReleaseExponential(m_ampRelease, m_sR);
497 | break;
498 | case VstCore::kAmpSus:
499 | m_ampEnv.SetSustainLevel(value);
500 | break;
501 | case VstCore::kAmpFade:
502 | if (value == 1.0f)
503 | m_ampEnv.SetFadeDirect(1.0f);
504 | else if (value > 0)
505 | m_ampEnv.SetFadeExponential(value * kFadeRange + kFadeMinimum, m_sR);
506 | else
507 | m_ampEnv.SetFadeDirect(0);
508 | break;
509 | case VstCore::kShpAtt:
510 | m_shpAttack = value * kAttackRange + kAttackMinimumShaper;
511 | m_shaperEnv.SetAttackExponential(m_shpAttack, m_sR);
512 | break;
513 | case VstCore::kShpDec:
514 | m_shpDecay = value * kDecayRange + kDecayMinimum;
515 | m_shaperEnv.SetDecayExponential(m_shpDecay, m_sR);
516 | break;
517 | case VstCore::kShpRel:
518 | m_shpRelease = value * kReleaseRange + kReleaseMinimum;
519 | m_shaperEnv.SetReleaseExponential(m_shpRelease, m_sR);
520 | break;
521 | case VstCore::kShpSus:
522 | m_shaperEnv.SetSustainLevel(value);
523 | break;
524 | case VstCore::kShpFade:
525 | if (value == 1.0f)
526 | m_shaperEnv.SetFadeDirect(1.0);
527 | else if (value > 0)
528 | m_shaperEnv.SetFadeExponential(1.0f * kFadeRange + kFadeMinimum, m_sR);
529 | else
530 | m_shaperEnv.SetFadeDirect(0);
531 | break;
532 | case VstCore::kShpMin:
533 | // TODO: Shouldn't these be in the envelope section?
534 | if (value == 0)
535 | {
536 | m_shaperEnv.NoAttack();
537 | }
538 | else
539 | {
540 | m_shaperEnv.NoAttack(false);
541 | // m_shaperEnv.SetMinimum(value);
542 | }
543 |
544 | m_shpMin = value;
545 | break;
546 | case VstCore::kShpMax:
547 | m_shpMax = value;
548 | break;
549 | case VstCore::kFM:
550 | m_pdOsc2.SetFMInputAmt(4.0f * value);
551 | break;
552 | case VstCore::kDetune:
553 | m_detune = value * kDetuneMaximum;
554 | break;
555 | case VstCore::kOctave: {
556 | int oct = (int)(value*6.0f) - 1;
557 | m_octave = pow((float)2, (float)oct);
558 | /*
559 | if (value < .25)
560 | m_octave = .5;
561 | else if (value < .5)
562 | m_octave = 1.0;
563 | else if (value < .75)
564 | m_octave = 2.0;
565 | else
566 | m_octave = 4.0;*/
567 | }
568 | break;
569 | case VstCore::kBasisWave:
570 | m_basisWave = value < .5? 0 : 1;
571 | SetBasisWaves();
572 | break;
573 | case VstCore::kPulseWidth:
574 | m_pulseWidth = kPWMMinimum + (value * kPWMRange);
575 | SetPulseWidths();
576 | break;
577 | case VstCore::kVelShaper:
578 | SetVelocityShp(value);
579 | break;
580 | case VstCore::kVelVolume:
581 | SetVelocityAmp(value);
582 | break;
583 | case VstCore::kLFORate:
584 | if (lfoSelect == -1) lfoSelect = 0;
585 | #ifdef DIGITS_PRO
586 | case VstCore::kLFO2Rate:
587 | if (lfoSelect == -1) lfoSelect = 1;
588 | case VstCore::kLFO3Rate:
589 | if (lfoSelect == -1) lfoSelect = 2;
590 | #endif
591 | value = ExpShape(100.0f, value);
592 | m_lfos[lfoSelect].SetRate(kLFOMinimum + (value * kLFORange), m_sR);
593 | break;
594 | case VstCore::kLFOType:
595 | if (lfoSelect == -1) lfoSelect = 0;
596 | #ifdef DIGITS_PRO
597 | case VstCore::kLFO2Type:
598 | if (lfoSelect == -1) lfoSelect = 1;
599 | case VstCore::kLFO3Type:
600 | if (lfoSelect == -1) lfoSelect = 2;
601 | #endif
602 | if (value < .25)
603 | m_lfos[lfoSelect].SetType(LFO::kLFO_Sin);
604 | else if (value < .5)
605 | m_lfos[lfoSelect].SetType(LFO::kLFO_Noise);
606 | else if (value < .75)
607 | m_lfos[lfoSelect].SetType(LFO::kLFO_RampDn);
608 | else
609 | m_lfos[lfoSelect].SetType(LFO::kLFO_RampUp);
610 | break;
611 | case VstCore::kLFODelay:
612 | if (lfoSelect == -1) lfoSelect = 0;
613 | #ifdef DIGITS_PRO
614 | case VstCore::kLFO2Delay:
615 | if (lfoSelect == -1) lfoSelect = 1;
616 | case VstCore::kLFO3Delay:
617 | if (lfoSelect == -1) lfoSelect = 2;
618 | #endif
619 | // Up to two seconds
620 | m_lfos[lfoSelect].SetDelay(value * 2000.0f, m_sR);
621 | break;
622 | case VstCore::kLFORepeat:
623 | if (lfoSelect == -1) lfoSelect = 0;
624 | #ifdef DIGITS_PRO
625 | case VstCore::kLFO2Repeat:
626 | if (lfoSelect == -1) lfoSelect = 1;
627 | case VstCore::kLFO3Repeat:
628 | if (lfoSelect == -1) lfoSelect = 2;
629 | #endif
630 | if (value == 1.0f)
631 | m_lfos[lfoSelect].SetRepeat(-1);
632 | else
633 | m_lfos[lfoSelect].SetRepeat(1+(value*4));
634 | break;
635 | case VstCore::kLFOShp:
636 | if (lfoSelect == -1) lfoSelect = 0;
637 | #ifdef DIGITS_PRO
638 | case VstCore::kLFO2Shp:
639 | if (lfoSelect == -1) lfoSelect = 1;
640 | case VstCore::kLFO3Shp:
641 | if (lfoSelect == -1) lfoSelect = 2;
642 | #endif
643 | m_pdOsc1.SetLFOShaper(lfoSelect, value);
644 | m_pdOsc2.SetLFOShaper(lfoSelect, value);
645 | m_resoGen.SetLFOShaper(lfoSelect, value);
646 | if (value > 0)
647 | m_lfoIsAssigned[lfoSelect] |= kLFOa_toShaper;
648 | else
649 | m_lfoIsAssigned[lfoSelect] &= ~kLFOa_toShaper;
650 | break;
651 | case VstCore::kLFOAmp:
652 | if (lfoSelect == -1) lfoSelect = 0;
653 | #ifdef DIGITS_PRO
654 | case VstCore::kLFO2Amp:
655 | if (lfoSelect == -1) lfoSelect = 1;
656 | case VstCore::kLFO3Amp:
657 | if (lfoSelect == -1) lfoSelect = 2;
658 | #endif
659 | m_lfoAmplitude[lfoSelect] = value;
660 | if (value > 0)
661 | m_lfoIsAssigned[lfoSelect] |= kLFOa_toAmp;
662 | else
663 | m_lfoIsAssigned[lfoSelect] &= ~kLFOa_toAmp;
664 |
665 | break;
666 | case VstCore::kLFOFrq:
667 | if (lfoSelect == -1) lfoSelect = 0;
668 | #ifdef DIGITS_PRO
669 | case VstCore::kLFO2Frq:
670 | if (lfoSelect == -1) lfoSelect = 1;
671 | case VstCore::kLFO3Frq:
672 | if (lfoSelect == -1) lfoSelect = 2;
673 | #endif
674 | m_pdOsc1.SetLFOPitch(lfoSelect, value * .75f);
675 | m_pdOsc2.SetLFOPitch(lfoSelect, value * .75f);
676 | m_resoGen.SetLFOPitch(lfoSelect, value);
677 | if (value > 0)
678 | m_lfoIsAssigned[lfoSelect] |= kLFOa_toPitch;
679 | else
680 | m_lfoIsAssigned[lfoSelect] &= ~kLFOa_toPitch;
681 | break;
682 | case VstCore::kLFOPWM:
683 | if (lfoSelect == -1) lfoSelect = 0;
684 | #ifdef DIGITS_PRO
685 | case VstCore::kLFO2PWM:
686 | if (lfoSelect == -1) lfoSelect = 1;
687 | case VstCore::kLFO3PWM:
688 | if (lfoSelect == -1) lfoSelect = 2;
689 | #endif
690 | m_pdOsc1.SetLFOPWM(lfoSelect, value);
691 | m_pdOsc2.SetLFOPWM(lfoSelect, value);
692 | m_resoGen.SetLFOPWM(lfoSelect, value);
693 | if (value > 0)
694 | m_lfoIsAssigned[lfoSelect] |= kLFOa_toPWM;
695 | else
696 | m_lfoIsAssigned[lfoSelect] &= ~kLFOa_toPWM;
697 |
698 | break;
699 | #if DIGITS_PRO
700 | case VstCore::kLockShaperForFilter:
701 | m_lockShaperAmt = value;
702 | break;
703 | case VstCore::kFilterReso:
704 | // fudge factor for higher sampling rates-- dermined by ear
705 | if (m_sR >= 88200)
706 | value *= .93f;
707 | m_trueFilter.SetSharpness(3.5f * value);
708 | break;
709 | case VstCore::kFilterMode:
710 | if (value < .25)
711 | m_trueFilter.SetPoles(4);
712 | else if (value < .5)
713 | m_trueFilter.SetPoles(3);
714 | else if (value < .75)
715 | m_trueFilter.SetPoles(2);
716 | else
717 | m_trueFilter.SetPoles(1);
718 | break;
719 | case VstCore::kMonoMode:
720 | if (value < .25)
721 | m_glideMode = kGlide_PolyNoGlide;
722 | else if (value < .5)
723 | m_glideMode = kGlide_PolyGlideAlways;
724 | else if (value < .75)
725 | m_glideMode = kGlide_MonoGlideWhenHeld;
726 | else
727 | m_glideMode = kGlide_MonoGlideAlways;
728 | break;
729 | case VstCore::kPortaSpeed:
730 | if (value == 0)
731 | m_glideSpeed = 1.0f;
732 | else
733 | m_glideSpeed = value * 500.0f;
734 | break;
735 | #endif
736 | case VstCore::kModShaper:
737 | SetModWheelShaper(value);
738 | break;
739 | case VstCore::kModLFO1Amp:
740 | SetModWheelLFO1Amp(value);
741 | break;
742 | case VstCore::kAftertouchShaper:
743 | SetAftertouchShaper(value);
744 | break;
745 | case VstCore::kAftertouchLFO1Amp:
746 | SetAftertouchLFO1Amp(value);
747 | break;
748 | #if DIGITS_PRO
749 | case VstCore::kAmpRateScale:
750 | m_ampRateScale = value;
751 | break;
752 | case VstCore::kShpRateScale:
753 | m_shpRateScale = value;
754 | break;
755 | case VstCore::kShpLevelScale:
756 | m_shpLevelScale = value * .25f;
757 | break;
758 | case VstCore::kBitDiv:
759 | m_bitCrushPos = 0;
760 | m_bitCrushDivider = floor(value * 9.0f) + 1.0;
761 | break;
762 | case VstCore::kBitBit:
763 | m_bitCrushPos = 0;
764 | m_bitCrushBits = floor(value * 14.0f) + 2.0;
765 | break;
766 | case VstCore::kBitBlend:
767 | m_bitCrushBlend = value;
768 | break;
769 | #endif
770 | default:
771 | break;
772 | }
773 | }
774 |
775 | void Voice::InitiateGlide(float delta, float deltaHi, float deltaLo)
776 | {
777 | float unblend = 1.0f - m_deltaBlend;
778 |
779 | m_delta = m_delta*unblend + m_delta2*m_deltaBlend;
780 | m_deltaHi = m_deltaHi*unblend + m_deltaHi2*m_deltaBlend;
781 | m_deltaLo = m_deltaLo*unblend + m_deltaLo2*m_deltaBlend;
782 |
783 | m_delta2 = delta;
784 | m_deltaHi2 = deltaHi;
785 | m_deltaLo2 = deltaLo;
786 | m_deltaBlend = .001f; // Turn it on
787 | }
788 |
789 |
--------------------------------------------------------------------------------
/src/components/Voice.h:
--------------------------------------------------------------------------------
1 | /* Phase Distortion Synthesizer (c) 2011 Louis Gorenfeld */
2 |
3 | #ifndef _VOICE_H_
4 | #define _VOICE_H_
5 |
6 | #include
7 | #include "SndBuf.h"
8 | #include "PhaseDist.h"
9 | #include "ResoGen.h"
10 | #include "Contour.h"
11 | #include "FilterBank.h"
12 | #include "LFO.h"
13 |
14 | class Voice
15 | {
16 | public:
17 | struct voiceBuffers_t
18 | {
19 | SndBuf* m_voiceBuf;
20 | SndBuf* m_shpEnvBuf;
21 | SndBuf* m_ampEnvBuf;
22 | SndBuf* m_lfoBufs[Tables::kNumLFOs];
23 | SndBuf* m_fmScratchBuf;
24 | };
25 |
26 | // These probably could be moved to VstCore
27 | static float kAttackMinimumAmp;
28 | static float kAttackMinimumShaper;
29 | static float kAttackRange;
30 | static float kFadeMinimum;
31 | static float kFadeRange;
32 | static float kReleaseMinimum;
33 | static float kReleaseRange;
34 | static float kDecayMinimum;
35 | static float kDecayRange;
36 | static float kDetuneMaximum;
37 | static float kLFOMinimum;
38 | static float kLFORange;
39 | static float kPWMMinimum;
40 | static float kPWMRange;
41 |
42 | // voiceNumber = the number of the voice this is (for debug purposes)
43 | Voice(int voiceNumber);
44 | ~Voice();
45 |
46 | // Set doContourGen to false when rendering as a subvoice
47 | // Buffers must be passed in at render-time because multicore support needs separate buffers for each
48 | // helper thread
49 | // doContourGens is true if the contour generators are supposed to be renderd. False if we're intentionally
50 | // rendering a subvoice.
51 | // debugthread is the number of the thread (0=core, 1=helper 1, 2=helper 2, etc) for debug purposes
52 | void Render(float *out, int len, Voice::voiceBuffers_t* bufs, bool doContourGens, int debugthread);
53 | // BUFFER SET IS FOR: fmIn, SndBuf *shaperBuf, SndBuf *ampBuf, SndBuf **lfoBufs, bool doContourGens);
54 | void NoteOn(uint64_t timestamp, float deltaLo, float deltaHi, float delta, int midiKey, int velocity, bool reset=true);
55 | // Pass in a negative value to turn the note off regardless of pitch
56 | void NoteOff(int key);
57 | // Pass in -1.0 to 1.0
58 | void PitchBend(float value);
59 | // Pass in 0 to 1.0
60 | void SetModWheel(float value) { m_modWheel = value; }
61 | // Pass in 0 to 1.0
62 | void SetAftertouch(float value) { m_aftertouch = value; }
63 | // Notify the Voice of the current sampling rate
64 | void SetSamplingRate(float sR) { m_sR = sR; }
65 |
66 | void ResetPhases()
67 | {
68 | m_resoGen.ResetPhase();
69 | m_pdOsc1.ResetPhase();
70 | m_pdOsc2.ResetPhase();
71 | }
72 |
73 | // Return true if this voice can be stolen
74 | // or reused
75 | bool IsFree()
76 | {
77 | return m_ampEnv.IsDone();
78 | }
79 | bool IsReleased() { return m_ampEnv.IsReleased(); }
80 | int Pitch() { return m_pitch; }
81 | void SetParameter(int index, float value);
82 | inline float Clip(float x);
83 | uint64_t GetTimestamp() { return m_timestamp; }
84 |
85 | void InitiateGlide(float delta, float deltaHi, float deltaLo);
86 |
87 | // Set ties between velocity and amplitude/shaper
88 | void SetVelocityAmp(float amt) { m_velAmp = amt; }
89 | void SetVelocityShp(float amt) { m_velShp = amt; }
90 |
91 | void SetPulseWidths();
92 | void SetBasisWaves();
93 |
94 | // At the beginning of buffer processing, these are all true. As voices are rendered,
95 | // needsRender is set to false.
96 | bool NeedsRender() { return m_needsRender; }
97 | // In multicore mode, make sure this is wrapped in a mutex. It's not individually
98 | // wrapped because that's wasteful, kinda like individually-wrapped M&Ms.
99 | void SetNeedsRender(bool needsRender=true)
100 | {
101 | m_needsRender = needsRender;
102 | }
103 | void SetIsSubVoice(bool isSubVoice) { m_isSubVoice = isSubVoice; }
104 | bool IsSubVoice() { return m_isSubVoice; }
105 |
106 | // Set the subvoice pointer (for optimization of orch/phat/unison mode)
107 | void SetNextSubVoice(Voice* nextSubVoice)
108 | {
109 | fprintf(stderr, "SetNextSubVoice %p -> %p\n", this, nextSubVoice);
110 | m_nextSubVoice = nextSubVoice;
111 | if (nextSubVoice)
112 | nextSubVoice->SetIsSubVoice(true);
113 | }
114 |
115 | // Recursively go through the subvoice list and turn off all the envelopes (disable voice)
116 | void DisableSubVoices()
117 | {
118 | m_ampEnv.SetDone();
119 | if (m_nextSubVoice)
120 | m_nextSubVoice->DisableSubVoices();
121 | }
122 |
123 | // When we engage the filter, we lock the shaper at a
124 | // specific value. This is the amount it's locked to.
125 | void LockShaperTo(float val) { m_lockShaperAmt = val; }
126 |
127 | void UpdateFilterSamplingRate(float sR) { m_trueFilter.SetSamplingRate(sR); }
128 |
129 | // Set influence for aftertouch and modwheel
130 | void SetAftertouchShaper(float value) { m_atouchShp = value; }
131 | void SetAftertouchLFO1Amp(float value) { m_atouchLFO1Amp = value; }
132 | void SetModWheelShaper(float value) { m_modShp = value; }
133 | void SetModWheelLFO1Amp(float value) { m_modLFO1Amp = value; }
134 |
135 | bool ShaperLocked() { return (m_lockShaperAmt > 0); }
136 |
137 | // Divider should be in the range of 1 to 8, or 0 for off.
138 | // void SetBitCrushDivider(float div) { m_bitCrushDivider = div; }
139 | // void SetBitCrushBits(int bits) { m_bitCrushBits = pow(2, bits); }
140 |
141 | private:
142 | #ifdef DIGITS_MULTICORE
143 | // Mutex is locked when setParameter
144 | pthread_mutex_t m_mutex;
145 | #endif
146 |
147 | enum GlideMode
148 | {
149 | kGlide_PolyNoGlide,
150 | kGlide_PolyGlideAlways,
151 | kGlide_MonoGlideWhenHeld,
152 | kGlide_MonoGlideAlways
153 | };
154 |
155 | uint64_t m_timestamp;
156 |
157 | Contour m_ampEnv;
158 | Contour m_shaperEnv;
159 | PhaseDist m_pdOsc1;
160 | PhaseDist m_pdOsc2;
161 | LFO m_lfos[Tables::kNumLFOs];
162 |
163 | ResoGen m_resoGen;
164 | // MIDI pitch value used for note on/offs
165 | int m_pitch;
166 | float m_detune;
167 | float m_octave;
168 | float m_mix;
169 | float m_resoVol;
170 | float m_pulseWidth;
171 | float m_lfoAmplitude[Tables::kNumLFOs]; // How much LFO affects the amplitude
172 |
173 | // Pitch delta
174 | float m_delta;
175 | // Pitch bend down delta
176 | float m_deltaLo;
177 | // Pitch bend up delta
178 | float m_deltaHi;
179 |
180 | // The same, but for notes that we're sliding to (monophonic mode)
181 | float m_delta2;
182 | float m_deltaLo2;
183 | float m_deltaHi2;
184 | // The position from 0 to 1 between the two pitches we're at
185 | float m_deltaBlend;
186 | // How long it takes for a portamento (glide) to finish. This is in terms of control
187 | // rate frames. At the time of writing, the control rate is 1000/sec, so milliseconds.
188 | float m_glideSpeed;
189 | // The glide mode
190 | GlideMode m_glideMode;
191 |
192 | // Last pitch wheel value
193 | float m_bend;
194 | // Last mod wheel value
195 | float m_modWheel;
196 | // Last aftertouch value
197 | float m_aftertouch;
198 | // Velocity
199 | float m_velocity;
200 |
201 | int m_basisWave; // 0 = cos, 1 = sin
202 |
203 | // These are stored here because we want to set these per
204 | // note (for tying velocity to brightness)
205 | float m_shpMin;
206 | float m_shpMax;
207 | float m_velShp;
208 | float m_velAmp;
209 |
210 | float m_modShp;
211 | float m_modLFO1Amp;
212 | float m_atouchShp;
213 | float m_atouchLFO1Amp;
214 |
215 | // Calculate pitch based on frequency deltas and pitch wheel value
216 | void CalcPitch();
217 | // Recalculate envelopes (for sample rate changes)
218 | void RecalcEnvs() {} // TODO
219 |
220 | // Set to null when there's no more subvoices
221 | Voice *m_nextSubVoice;
222 | // This is so that the main render loop doesn't end up
223 | // rendering this voice twice (if it's a subvoice)
224 | bool m_needsRender;
225 | // This is a sub-voice (phat/unison/orch mode)
226 | bool m_isSubVoice;
227 |
228 | LowPassReso m_trueFilter;
229 | // When we engage the filter, we lock the shaper at a
230 | // specific value. This is the amount it's locked to.
231 | float m_lockShaperAmt;
232 |
233 | // Current sampling rate
234 | float m_sR;
235 |
236 | // The number of the voice for debugging purposes
237 | int m_voiceNumber;
238 |
239 | // Bitfield that shows the LFO assignments. When it's 0, it's
240 | // safe not to process that LFO
241 | static const int kLFOa_toShaper = 1;
242 | static const int kLFOa_toPWM = 2;
243 | static const int kLFOa_toAmp = 3;
244 | static const int kLFOa_toPitch = 4;
245 | int m_lfoIsAssigned[Tables::kNumLFOs];
246 |
247 | // Envelope settings, for rate/level scaling upon note-on
248 | // Rate and level scaling, in terms of
249 | // speedup or attenuation per octave. Ramps
250 | // based on frequency. e.g., .5 for level would
251 | // attenuate the envelope by .5 per octave. 2 for
252 | // rate would double the envelope speed each octave,
253 | // starting at 60hz.
254 | float m_ampRateScale;
255 | float m_ampLevelScale;
256 | float m_ampAttack;
257 | float m_ampDecay;
258 | float m_ampRelease;
259 | float m_shpRateScale;
260 | float m_shpLevelScale;
261 | float m_shpAttack;
262 | float m_shpDecay;
263 | float m_shpRelease;
264 |
265 | // Sample-hold for the smart bitcrush
266 | float m_bitCrushPos;
267 | float m_bitCrushDelta;
268 | int m_bitCrushLastSample;
269 | float m_bitCrushBlend;
270 | float m_bitCrushDivider;
271 | int m_bitCrushBits;
272 | };
273 |
274 | #endif
275 |
276 |
--------------------------------------------------------------------------------
/src/digits/DigitsBench.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * DigitsBench.cpp
3 | * PDVST
4 | *
5 | * Created by Louis Gorenfeld on 9/20/12.
6 | * Copyright 2012 ExtentOfTheJam. All rights reserved.
7 | *
8 | * This is a minimal class to provide a decent benchmark for
9 | * Digits outside of the host
10 | */
11 |
12 | #include "VstCore.h"
13 |
14 | int main()
15 | {
16 | static const int kBlockSize = 256;
17 | VstCore digitsCore((void*)1);
18 |
19 | digitsCore.setSampleRate(48000);
20 | digitsCore.setBlockSize(kBlockSize);
21 | digitsCore.setProgram(3 /* Flanger strings */);
22 |
23 |
24 | VstEvents *ev = (VstEvents*)new char[sizeof(VstEvents) + 2*sizeof(VstMidiEvent*)];
25 | VstMidiEvent midiEvents[4];
26 | midiEvents[0].midiData[0] = 0x90;
27 | midiEvents[0].midiData[1] = 64;
28 | midiEvents[0].midiData[2] = 0x7f;
29 | midiEvents[0].deltaFrames = 0;
30 | midiEvents[1].midiData[0] = 0x90;
31 | midiEvents[1].midiData[1] = 66;
32 | midiEvents[1].midiData[2] = 0x7f;
33 | midiEvents[1].deltaFrames = 0;
34 | midiEvents[2].midiData[0] = 0x90;
35 | midiEvents[2].midiData[1] = 68;
36 | midiEvents[2].midiData[2] = 0x7f;
37 | midiEvents[2].deltaFrames = 0;
38 | midiEvents[3].midiData[0] = 0x90;
39 | midiEvents[3].midiData[1] = 70;
40 | midiEvents[3].midiData[2] = 0x7f;
41 | midiEvents[3].deltaFrames = 0;
42 |
43 | ev->events[0] = &midiEvents[0];
44 | ev->events[1] = &midiEvents[1];
45 | ev->events[2] = &midiEvents[2];
46 | ev->events[3] = &midiEvents[3];
47 | ev->numEvents = 4;
48 |
49 | digitsCore.processEvents(ev);
50 | /*
51 | FILE *fp = fopen("DigitsBench.raw", "wb");
52 | float *outs[2];
53 | outs[0] = new float[48000];
54 | outs[1] = new float[48000];
55 | digitsCore.processReplacing(0, outs, 48000);
56 |
57 | fwrite(outs[0], sizeof(float), 48000, fp);
58 |
59 | fclose(fp);
60 | */
61 |
62 | float *outs[2];
63 | outs[0] = new float[kBlockSize];
64 | outs[1] = new float[kBlockSize];
65 |
66 | // Render 1 minute of audio at 48khz
67 | for (int i=0; i<(48000*60)/256; i++)
68 | {
69 | digitsCore.processReplacing(0, outs, kBlockSize);
70 | }
71 |
72 | delete[] outs[0];
73 | delete[] outs[1];
74 |
75 | return 0;
76 | }
77 |
78 |
--------------------------------------------------------------------------------
/src/digits/EditorWindow.h:
--------------------------------------------------------------------------------
1 | /*
2 | * EditorWindow.h
3 | * PDVST
4 | *
5 | * Created by Louis Gorenfeld on 7/29/12.
6 | * Copyright 2012 ExtentOfTheJam. All rights reserved.
7 | *
8 | */
9 |
10 | #ifndef _EDITWINDOW_H_
11 | #define _EDITWINDOW_H_
12 |
13 | #include "../vstgui/plugin-bindings/aeffguieditor.h"
14 | #include "VstCore.h" // kNumParameters
15 |
16 | class EditorWindow : public AEffGUIEditor, public IControlListener
17 | {
18 | public:
19 | EditorWindow(void *p);
20 | ~EditorWindow();
21 |
22 | // AEffGUIEditor
23 | virtual bool open (void* ptr);
24 | void close ();
25 | void setParameter (VstInt32 index, float value);
26 | void idle();
27 |
28 | // CControlListener
29 | void valueChanged (CControl* pControl);
30 |
31 | // The guts of the effect
32 | VstCore *m_me;
33 |
34 | protected:
35 | enum oscType_t
36 | {
37 | kOsc1,
38 | kOsc2,
39 | kReso
40 | };
41 |
42 | enum tripleType_t
43 | {
44 | kMix,
45 | kAmpEnv,
46 | kShpEnv
47 | };
48 |
49 | static const int kEditorWidth = 890;
50 | static const int kEditorHeight = 440;
51 | // Padding between the edge of a panel and the first
52 | // control (e.g., from left side of panel to first control)
53 | static const int kSidePadding = 20;
54 | static const int kDialPadding = 50;
55 | static const int kDialWidth = 32;
56 | static const int kDialSpacing = kDialWidth + 16;
57 |
58 | // How far beneath the dial is the text?
59 | static const int kDialTextPadding = 0;
60 | // Position text 10 pixels beneath dial
61 | static const int kTextPaddingY = 50;
62 |
63 | static const int kPulldownWidth = 64;
64 | static const int kTextboxHeight = 14;
65 | static const int kTextboxWidth = 48;
66 |
67 | static const int kBankSelectorKey = 65536;
68 | static const int kPatchSelectorKey = 65537;
69 |
70 | static const int kGUIParamsStartAt = 1000;
71 | static const int kLFOParams = 8; // 8 parameters per LFO
72 |
73 | enum
74 | {
75 | kGUIParam_LFOButton1 = kGUIParamsStartAt,
76 | kGUIParam_LFOButton2,
77 | kGUIParam_LFOButton3,
78 | kGUIParam_VelButton,
79 | kGUIParam_ModButton,
80 | kGUIParam_ATButton,
81 | kGUIParam_DelButton,
82 | kGUIParam_ChrButton,
83 | kGUIParam_BitButton,
84 | kGUIParam_SaveEnter,
85 | kGUIParam_SaveOK,
86 | kGUIParam_SaveCancel
87 | };
88 |
89 | enum velATMod_t
90 | {
91 | kVel = 0,
92 | kAT,
93 | kMod
94 | };
95 |
96 | int m_curLFO;
97 |
98 | CControl* m_controls[VstCore::kNumParams];
99 | CControl* m_LFOButtons[3];
100 | CControl* m_velButton;
101 | CControl* m_atButton;
102 | CControl* m_modButton;
103 | CControl* m_velLabels[2];
104 | CControl* m_atLabels[2];
105 | CControl* m_modLabels[2];
106 |
107 | CTextLabel* m_statusText;
108 | COptionMenu* m_patchMenu;
109 | COptionMenu* m_bankMenu;
110 | CTextEdit *m_saveFilenameField;
111 | CFrame *m_frame;
112 | CViewContainer *m_savePopup;
113 |
114 | CViewContainer *m_delayView;
115 | CViewContainer *m_chorusView;
116 | CViewContainer *m_bitcrushView;
117 | CControl *m_delayButton;
118 | CControl *m_chorusButton;
119 | CControl *m_bitcrushButton;
120 |
121 | CViewContainer *m_vuL;
122 | CViewContainer *m_vuR;
123 |
124 | std::vector m_lines;
125 |
126 | // When the status text is set, this is set to the number of idle() calls
127 | // until the status text goes blank again
128 | int m_statusTimeout;
129 |
130 | #ifdef DIGITS_PRO
131 | // Which LFO is currently shown?
132 | int m_activeLFO;
133 | #endif
134 |
135 | // Draw a panel with skew, a pulldown menu for waveshape, and a label
136 | void DrawOscPanel(CFrame* destFrame, CBitmap* dialImg, CBitmap* dialHandleImg,
137 | int x, int y, oscType_t type);
138 |
139 | void DrawEnvPanel(CFrame* destFrame, CBitmap* dialImg, CBitmap* dialHandleImg,
140 | int x, int y, bool isAmpEnv);
141 |
142 | void DrawMixPanel(CFrame* destFrame, CBitmap* dialImg, CBitmap* dialHandleImg,
143 | int x, int y);
144 |
145 | void DrawPhasePanel(CFrame* destFrame, CBitmap* dialImg, CBitmap* dialHandleImg,
146 | int x, int y);
147 |
148 | // Show one LFO panel, hide the rest. whichLFO is the LFO #, starting from 0.
149 | void ShowLFOPanel(int whichLFO);
150 |
151 | // whichLFO is the number, starting from 0, of the LFO you want drawn
152 | void DrawLFOPanel(CFrame* destFrame, CBitmap* dialImg, CBitmap* dialHandleImg,
153 | int x, int y, int whichLFO);
154 |
155 | // Show one FX panel, hide the rest.
156 | void ShowFXPanel(int which);
157 |
158 | void DrawFXPanel(CFrame* destFrame, CBitmap* dialImg, CBitmap* dialHandleImg,
159 | int x, int y);
160 |
161 | void ShowVelATModPanel(velATMod_t mode);
162 |
163 | void DrawVelocityAftertouchPanel(CFrame* destFrame, CBitmap* dialImg, CBitmap* dialHandleImg,
164 | int x, int y, velATMod_t forMode);
165 |
166 | void DrawMiscPanel(CFrame* destFrame, CBitmap* dialImg, CBitmap* dialHandleImg,
167 | int x, int y);
168 |
169 | void DrawFilterPanel(CFrame* destFrame, CBitmap* dialImg, CBitmap* dialHandleImg,
170 | int x, int y);
171 |
172 | void DrawMonoPolyPanel(CFrame* destFrame, CBitmap* dialImg, CBitmap* dialHandleImg,
173 | int x, int y);
174 |
175 | void DrawPatchPanel(CFrame *destFrame, int x, int y);
176 | // Update the guts of the patch panel, which also updates the banks and patches
177 | // cache. Set bankChanged to true if changing banks.
178 | void UpdatePatchPanel(bool bankChanged=false);
179 |
180 | // Add a dial, spit back the handle for the label (handle for dial is in m_controls)
181 | CTextLabel *AddDial(CViewContainer* destFrame, CBitmap* dialImg, CBitmap* dialHandleImg,
182 | int x, int y, int paramNum, const char* label, float defaultValue=0);
183 |
184 | // Draw our snazzy backgroud
185 | void DrawLines(CFrame *destFrame);
186 |
187 | void SavePreset(std::string &fn);
188 | };
189 |
190 | #endif
191 |
192 |
--------------------------------------------------------------------------------
/src/digits/Patches.h:
--------------------------------------------------------------------------------
1 | #ifndef _PATCHES_H_
2 | #define _PATCHES_H_
3 |
4 | #define NUMPATCHES 44
5 |
6 | extern char presetBank[32][512];
7 |
8 | //extern int s_patchLen[NUMPATCHES];
9 |
10 | char *s_patchNames[] = { "INIT:Init Tone",
11 | "PAD: Bell Brass Pad",
12 | "PAD: Dream Pad",
13 | "PAD: Flanger Strings",
14 | "PAD: Ghost Choir",
15 | "PAD: String Ens.",
16 | "PAD: String Ens. Bright",
17 | "PAD: Wintery Pad",
18 |
19 | "SWP: HiSweep",
20 | "SWP: HiSweep-Overdrive",
21 | "SWP: Howling Tube",
22 | "SWP: Mean Sweeps",
23 | "SWP: Serious",
24 |
25 | "ARP: Eastern Arp",
26 | "ARP: Future Tines",
27 | "ARP: House Stabs",
28 | "ARP: POW!",
29 | "ARP: Quack! Quack!",
30 | "ARP: Thunky Arp",
31 |
32 | "LEAD:Bell Lead",
33 | "LEAD:Brass Lead",
34 | "LEAD:Brassy Slicer",
35 | "LEAD:Darius",
36 | "LEAD:Ghosts",
37 | "LEAD:Harsh Lead",
38 | "LEAD:Hollow Tube",
39 | "LEAD:HyperFlute",
40 | "LEAD:Raving Lunatic",
41 | "LEAD:ResoLead",
42 | "LEAD:SIDLead",
43 | "LEAD:SynReed",
44 | "LEAD:The Creeps",
45 | "LEAD:Solo Violin",
46 |
47 | "CHRD:Brass Ens.",
48 | "CHRD:Elec. Organ",
49 | "CHRD:Hi-Tone",
50 | "CHRD:Toy Piano",
51 |
52 | "BASS:404",
53 | "BASS:Chorused Bass",
54 | "BASS:FM Bass",
55 | "BASS:Flanger Bass",
56 | "BASS:PWM Bass",
57 | "BASS:Rubber Band",
58 | "BASS:Thunky Bass"
59 | };
60 |
61 | #endif
62 |
--------------------------------------------------------------------------------
/src/digits/PhaseDist.cpp:
--------------------------------------------------------------------------------
1 | /* Phase Distortion Synthesizer (c) 2011 Louis Gorenfeld */
2 |
3 | #include
4 | #include "PhaseDist.h"
5 | #include "Voice.h" // PWM min/max defines
6 | #include "Tables.h"
7 |
8 | PhaseDist::PhaseDist() :
9 | m_ampBuf(0),
10 | m_shpBuf(0),
11 | m_fmInputAmt(0),
12 | m_fmInputAmt1(0),
13 | m_shaperMod(0),
14 | m_skew(0),
15 | m_delta(0),
16 | m_deltaDest(0),
17 | m_glide(0),
18 | m_glide1(0),
19 | m_pos(0),
20 | m_basisWave(0),
21 | m_pwmWidth(.5),
22 | m_keyScale(1.0f),
23 | m_lockShaperAmt(0)
24 | {
25 | m_lfoShaper[0] = m_lfoShaper[1] = m_lfoShaper[2] = 0;
26 | m_lfoPitch[0] = m_lfoPitch[1] = m_lfoPitch[2] = 0;
27 | m_lfoPWM[0] = m_lfoPWM[1] = m_lfoPWM[2] = 0;
28 | m_lfoBufs[0] = m_lfoBufs[1] = m_lfoBufs[2] = 0;
29 | }
30 |
31 | void PhaseDist::Render(float *fmIn, float *out, int len, float volume)
32 | {
33 | float *brightContour = m_shpBuf;
34 | float *ampContour = m_ampBuf;
35 |
36 | if (!ampContour || !out)
37 | return;
38 |
39 | float lastContour;
40 | if (brightContour)
41 | {
42 | // TODO: Make compatible with non-pro (see top of PhaseDist::Render)
43 | #ifdef DIGITS_PRO
44 | float lfoInfluence = ((m_lfoBufs[0][0]+1.0f)*.5f) * m_lfoShaper[0]
45 | + ((m_lfoBufs[1][0]+1.0f)*.5f) * m_lfoShaper[1]
46 | + ((m_lfoBufs[2][0]+1.0f)*.5f) * m_lfoShaper[2];
47 | #else
48 | float lfoInfluence = ((m_lfoBufs[0][0]+1.0f)*.5f) * m_lfoShaper[0];
49 | #endif
50 | float bright;
51 | if (m_lockShaperAmt)
52 | bright = m_lockShaperAmt;
53 | else
54 | bright = brightContour[0] - (brightContour[0] * lfoInfluence);
55 | lastContour = m_skew - (bright * m_skew * m_keyScale);
56 | }
57 | else
58 | lastContour = m_skew - (.90f * m_skew);
59 |
60 | float m1 = m_skew / lastContour;
61 | float m2 = (1.0f - m_skew) / (1.0f - lastContour);
62 | float b2 = 1.0f - m2;
63 | bool squareMode = m_shaperMod == .5f;
64 | if (squareMode)
65 | b2 *= .5f;
66 |
67 | // Calculate PWM shaper
68 | float lfoInfluence = m_lfoPWM[0] * m_lfoBufs[0][0]
69 | + m_lfoPWM[1] * m_lfoBufs[1][0]
70 | + m_lfoPWM[2] * m_lfoBufs[2][0];
71 | float pwmWidth = m_pwmWidth + lfoInfluence;
72 | if (pwmWidth > Voice::kPWMMinimum + Voice::kPWMRange) pwmWidth = Voice::kPWMMinimum + Voice::kPWMRange;
73 | if (pwmWidth < Voice::kPWMMinimum) pwmWidth = Voice::kPWMMinimum;
74 | float m3 = .5f / pwmWidth;
75 | float m4 = (.5f) / (1.0f - pwmWidth);
76 | float b4 = 1.0f - m4;
77 | float pwmPos;
78 | if (m_pos < pwmWidth)
79 | pwmPos = m3*m_pos;
80 | else
81 | pwmPos = m4*m_pos + b4;
82 |
83 | float fmInputAmtDelta = (m_fmInputAmt1 - m_fmInputAmt) / (float)len;
84 |
85 | // Reset detail counter so this isn't happening twice in a row. This is a poor man's
86 | // optimization: This stuff should ONLY happen when m_detailCounter hits 0! Needs some
87 | // more thought.
88 | m_detailCounter = kDetailLevel;
89 |
90 | for (int i=0; i 1.0f)
122 | index *= m_shaperMod;
123 |
124 | if (m_fmInputAmt)
125 | if (m_basisWave == 0)
126 | out[i] += Tables::Cos(index + (m_fmInputAmt * fmIn[i])) * volume * ampContour[i];
127 | else
128 | out[i] += Tables::Sin(index + (m_fmInputAmt * fmIn[i])) * volume * ampContour[i];
129 | else
130 | if (m_basisWave == 0)
131 | out[i] += Tables::Cos(index) * volume; // Apply amp contour as last step since it's unified
132 | else
133 | out[i] += Tables::Sin(index) * volume;
134 |
135 | if (m_fmInputAmt != m_fmInputAmt1)
136 | m_fmInputAmt += fmInputAmtDelta;
137 |
138 | // Wrap oscillator
139 | float lfoInfluence = 0;
140 | if (m_lfoPitch[0])
141 | lfoInfluence += m_lfoBufs[0][i] * m_lfoPitch[0];
142 | if (m_lfoPitch[1])
143 | lfoInfluence += m_lfoBufs[1][i] * m_lfoPitch[1];
144 | if (m_lfoPitch[2])
145 | lfoInfluence += m_lfoBufs[2][i] * m_lfoPitch[2];
146 | m_pos += m_delta + (m_delta * lfoInfluence);
147 | while (m_pos >= 1.0f)
148 | {
149 | m_pos -= 1.0f;
150 | }
151 |
152 | // Recalculate linear equation
153 | if (--m_detailCounter <= 0)
154 | {
155 | if (brightContour)
156 | {
157 | #ifdef DIGITS_PRO
158 | float lfoInfluence = ((m_lfoBufs[0][i]+1.0f)*.5f) * m_lfoShaper[0]
159 | + ((m_lfoBufs[1][i]+1.0f)*.5f) * m_lfoShaper[1]
160 | + ((m_lfoBufs[2][i]+1.0f)*.5f) * m_lfoShaper[2];
161 | if (lfoInfluence > 1.0f) lfoInfluence = 1.0f;
162 | #else
163 | float lfoInfluence = ((m_lfoBufs[0][i]+1.0f)*.5f) * m_lfoShaper[0];
164 | #endif
165 | float bright;
166 | if (m_lockShaperAmt)
167 | bright = m_lockShaperAmt;
168 | else
169 | bright = brightContour[i] * (1.0f - lfoInfluence);
170 |
171 | //float bright = brightContour[i] - (brightContour[i] * ((m_lfoBuf[i]+1.0f)*.5f) * m_lfoShaper);
172 | lastContour = m_skew - (bright * m_skew * m_keyScale);
173 | }
174 | else
175 | lastContour = m_skew - (.9f * m_skew);
176 | m1 = m_skew / lastContour;
177 | m2 = (1.0f - m_skew) / (1.0f - lastContour);
178 | b2 = 1.0f - m2;
179 | if (squareMode)
180 | b2 *= .5f;
181 |
182 | // Move PWM
183 | #ifdef DIGITS_PRO
184 | float lfoInfluence = m_lfoPWM[0] * m_lfoBufs[0][0]
185 | + m_lfoPWM[1] * m_lfoBufs[1][0]
186 | + m_lfoPWM[2] * m_lfoBufs[2][0];
187 | #else
188 | float lfoInfluence = m_lfoPWM[0] * m_lfoBufs[0][0];
189 | #endif
190 | float pwmWidth = m_pwmWidth + lfoInfluence;
191 | if (pwmWidth > Voice::kPWMMinimum + Voice::kPWMRange) pwmWidth = Voice::kPWMMinimum + Voice::kPWMRange;
192 | if (pwmWidth < Voice::kPWMMinimum) pwmWidth = Voice::kPWMMinimum;
193 |
194 | m_detailCounter = kDetailLevel;
195 | }
196 |
197 | // Shape position using pwm shaper
198 | if (m_pos < pwmWidth)
199 | pwmPos = m3*m_pos;
200 | else
201 | pwmPos = m4*m_pos + b4;
202 |
203 | // Animate glide
204 | // m_delta = (m_glide*m_delta) + (m_glide1*m_deltaDest);
205 | }
206 |
207 | m_fmInputAmt = m_fmInputAmt1;
208 | }
209 |
210 |
211 |
--------------------------------------------------------------------------------
/src/digits/PhaseDist.h:
--------------------------------------------------------------------------------
1 | /* Phase Distortion Synthesizer (c) 2011 Louis Gorenfeld */
2 |
3 | #ifndef _PHASEDIST_
4 | #define _PHASEDIST_
5 |
6 | #include
7 | #include "SndBuf.h"
8 | #include "BufferManager.h"
9 |
10 | class PhaseDist
11 | {
12 | public:
13 | PhaseDist();
14 | ~PhaseDist() {};
15 |
16 | // Set the pitch in hz/sR (delta)
17 | void SetPitch(float delta)
18 | {
19 | m_delta = delta;
20 | m_deltaDest = delta;
21 | }
22 |
23 | void SetGlideDest(float delta) { m_deltaDest = delta; }
24 |
25 | // Render ADDING one buffer of audio (control rate chunk)
26 | void Render(float *fmIn, float *out, int len, float volume);
27 |
28 | // Brightness of the tone (filter cutoff)
29 | // void SetBright(float bright) { m_bright = m_skew - (bright * m_skew); }
30 |
31 | // Set FM input source (affects shaper position)
32 | // 0 if unused
33 | // void SetFMInput(SndBuf* fmInput) { m_fmInput = fmInput; }
34 |
35 | // Set FM input amount (affects shaper position)
36 | void SetFMInputAmt(float amt) { m_fmInputAmt1 = amt; }
37 |
38 | // How many times per cycle the shaper runs (2x for square)
39 | void SetShaperMod(float mod) { m_shaperMod = mod; }
40 |
41 | // Set skew point (.5 is normal for most CZ waves)
42 | void SetSkew(float skew) { m_skew = skew; }
43 |
44 | // Set basis waveform
45 | void SetBasis(int basis) { m_basisWave = basis; }
46 |
47 | void ResetPhase() { m_pos = 0; m_detailCounter = 0; }
48 |
49 | void SetGlideSpeed(float ms, float sR)
50 | {
51 | float sams = (ms/1000.0)*sR;
52 | m_glide = pow((float)M_E, (float)-1.0f/sams);
53 | m_glide1 = 1.0f - m_glide;
54 | }
55 |
56 | void SetPulseWidth(float width) { m_pwmWidth = width; }
57 | void SetBuffers(SndBuf* ampBuf, SndBuf* shpBuf, SndBuf** lfoBufs)
58 | {
59 | m_ampBuf = ampBuf->Data();
60 | m_shpBuf = shpBuf->Data();
61 | m_lfoBufs[0] = lfoBufs[0]->Data();
62 | m_lfoBufs[1] = lfoBufs[1]->Data();
63 | m_lfoBufs[2] = lfoBufs[2]->Data();
64 | }
65 |
66 | void SetLFOShaper(int lfo, float value) { m_lfoShaper[lfo] = value; }
67 | void SetLFOPitch(int lfo, float value) { m_lfoPitch[lfo] = value; }
68 | void SetLFOPWM(int lfo, float value) { m_lfoPWM[lfo] = value; }
69 |
70 | // Get delta with modulation factored in (for keyscaling)
71 | float GetDelta() { return m_delta; }
72 | // Set keyscaling amount for shaper (shaper attenuation)
73 | void SetKeyScale(float x) { m_keyScale = x; }
74 | // See Voice for documentation on LockShaperTo
75 | void LockShaperTo(float val) { m_lockShaperAmt = val; }
76 |
77 | private:
78 | // Recalc slopes only every N samples
79 | static const int kDetailLevel = 16;
80 |
81 | float *m_ampBuf;
82 | float *m_shpBuf;
83 | float *m_lfoBufs[Tables::kNumLFOs];
84 |
85 | float m_fmInputAmt;
86 | float m_fmInputAmt1; // zipper noise smoothing (new value)
87 | float m_shaperMod;
88 | float m_skew;
89 |
90 | float m_delta;
91 | // Delta destination (for slides)
92 | float m_deltaDest;
93 | // Coefficients for one-pole smoother (for slides)
94 | float m_glide;
95 | float m_glide1;
96 | float m_pos;
97 | int m_basisWave;
98 | float m_pwmWidth;
99 |
100 | // LFO severtity
101 | float m_lfoShaper[Tables::kNumLFOs];
102 | float m_lfoPitch[Tables::kNumLFOs];
103 | float m_lfoPWM[Tables::kNumLFOs];
104 |
105 | // Shaper keyscaler
106 | float m_keyScale;
107 | // Lock shaper to this value (see Voice)
108 | float m_lockShaperAmt;
109 |
110 | int m_detailCounter;
111 |
112 | };
113 |
114 | #endif
115 |
--------------------------------------------------------------------------------
/src/digits/ResoGen.cpp:
--------------------------------------------------------------------------------
1 | /* Phase Distortion Synthesizer (c) 2011 Louis Gorenfeld */
2 |
3 | #include
4 | #include "Tables.h"
5 | #include "ResoGen.h"
6 |
7 | ResoGen::ResoGen() :
8 | m_ampBuf(0),
9 | m_shpBuf(0),
10 | m_style(kSawQuarter),
11 | m_delta(0),
12 | m_pos1(0),
13 | m_pos2(0),
14 | m_flip(1.0f),
15 | m_pw(.5)
16 | {
17 | m_lfoBufs[0] = m_lfoBufs[1] = m_lfoBufs[2] = 0;
18 | m_lfoShaper[0] = m_lfoShaper[1] = m_lfoShaper[2] = 0;
19 | m_lfoPWM[0] = m_lfoPWM[1] = m_lfoPWM[2] = 0;
20 | m_lfoPitch[0] = m_lfoPitch[1] = m_lfoPitch[2] = 0;
21 | }
22 |
23 | void ResoGen::ResetPhase()
24 | {
25 | m_pos1 = 0;
26 | m_pos2 = 0;
27 | m_flip = 1.0f;
28 | }
29 |
30 | void ResoGen::Render(float *out, int len, float volume)
31 | {
32 | float* ampContour = m_ampBuf;
33 | float* brightContour = m_shpBuf;
34 |
35 | // Match the volume of the normal oscillator
36 | volume *= 2.0f;
37 |
38 | if (!ampContour || !brightContour || !out)
39 | return;
40 |
41 | // Calculate PWM shaper
42 | float m3 = .5f / m_pw;
43 | float m4 = (.5f) / (1.0f - m_pw);
44 | float b4 = 1.0f - m4;
45 | float pwmPos;
46 | if (m_pos2 < m_pw)
47 | pwmPos = m3*m_pos2;
48 | else
49 | pwmPos = m4*m_pos2 + b4;
50 |
51 | float sam;
52 |
53 | for (int i=0; i= 1.0f)
89 | m_pos1 -= 1.0f;
90 | while (m_pos2 >= 1.0f)
91 | {
92 | m_pos2 -= 1.0f;
93 | if (m_style == 2 || m_style == 3)
94 | m_flip *= -1.0f;
95 | }
96 | if (m_pos2 < m_pw)
97 | pwmPos = m3*m_pos2;
98 | else
99 | pwmPos = m4*m_pos2 + b4;
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/src/digits/ResoGen.h:
--------------------------------------------------------------------------------
1 | /* Phase Distortion Synthesizer (c) 2011 Louis Gorenfeld */
2 |
3 | #ifndef _RESOGEN_H_
4 | #define _RESOGEN_H_
5 |
6 | #include "SndBuf.h"
7 |
8 | class ResoGen
9 | {
10 | public:
11 | enum resoStyle_t
12 | {
13 | kSawQuarter,
14 | kSawHalf,
15 | kSquareQuarter,
16 | kSquareHalf
17 | };
18 |
19 | ResoGen();
20 | ~ResoGen() {}
21 | void SetPitch(float delta) { m_delta = delta; }
22 |
23 | void SetStyle(resoStyle_t style) { m_style = style; }
24 |
25 | // Render ADDING one buffer of audio (control rate chunk)
26 | void Render(float *out, int len, float volume=1.0f);
27 |
28 | // Brightness of the tone (filter cutoff)
29 | // void SetBright(float bright) { m_bright = 2.0f + (bright * 14.0f); }
30 |
31 | // Reset phase of oscillators
32 | void ResetPhase();
33 |
34 | void SetPulseWidth(float width) { m_pw = width; }
35 | void SetBuffers(SndBuf *ampBuf, SndBuf *shpBuf, SndBuf **lfoBufs)
36 | {
37 | m_ampBuf = ampBuf->Data();
38 | m_shpBuf = shpBuf->Data();
39 | m_lfoBufs[0] = lfoBufs[0]->Data();
40 | m_lfoBufs[1] = lfoBufs[1]->Data();
41 | m_lfoBufs[2] = lfoBufs[2]->Data();
42 | }
43 | void SetLFOShaper(int lfo, float value) { m_lfoShaper[lfo] = value; }
44 | void SetLFOPitch(int lfo, float value) { m_lfoPitch[lfo] = value; }
45 | void SetLFOPWM(int lfo, float value) { m_lfoPWM[lfo] = value; }
46 |
47 | private:
48 | float *m_ampBuf;
49 | float *m_shpBuf;
50 | float *m_lfoBufs[Tables::kNumLFOs];
51 | float m_lfoShaper[Tables::kNumLFOs];
52 | float m_lfoPitch[Tables::kNumLFOs];
53 | float m_lfoPWM[Tables::kNumLFOs];
54 |
55 | resoStyle_t m_style;
56 | float m_delta;
57 | // Position of slave (sine)
58 | float m_pos1;
59 | // Position of master (window)
60 | float m_pos2;
61 | // Multiplier for slave frequency
62 | // float m_bright;
63 | // Wave inversion for square patterns
64 | float m_flip;
65 | float m_pw;
66 | };
67 |
68 | #endif
69 |
--------------------------------------------------------------------------------
/src/digits/VstCore.h:
--------------------------------------------------------------------------------
1 | /* Phase Distortion Synthesizer (c) 2011 Louis Gorenfeld */
2 |
3 | #ifndef _VSTCORE_H_
4 | #define _VSTCORE_H_
5 |
6 | #define VERSION_MAJ 0x1
7 | #define VERSION_MIN 0x5
8 | #define VERSION_PAT_MAJ 0x1
9 | #define VERSION_PAT_MIN 0x2
10 |
11 | #ifdef FAUX_VST_HEADER
12 | #include "FauxVST.h"
13 | #else
14 | #include "public.sdk/source/vst2.x/audioeffectx.h"
15 | #endif
16 |
17 | #include
18 | #include
19 | #include "PatchBankList.h"
20 | #include "Voice.h"
21 | #include "Chorus.h"
22 | #include "LFO.h"
23 | #include "Oversampler.h"
24 |
25 | #ifdef DIGITS_MULTICORE
26 | #include
27 | void* digits_helper(void* arg);
28 | #endif
29 |
30 | #ifdef DBGMCORE
31 | #define DEBUG_MCORE(...) { fprintf(stderr, __VA_ARGS__); }
32 | #define DEBUGFRAMESEPARATOR
33 | #else
34 | #define DEBUG_MCORE
35 | #endif
36 |
37 | class VstCore : public AudioEffectX
38 | {
39 | public:
40 | enum paramNums_t
41 | {
42 | kO1Skew = 0,
43 | kO1ShpMod,
44 | kO2Skew,
45 | kO2ShpMod,
46 | kO2Vol,
47 | #ifdef DIGITS_PRO
48 | kResetOscs,
49 | #endif
50 | kResoVol,
51 | kResoWave,
52 | kAmpAtt,
53 | kAmpDec,
54 | kAmpSus,
55 | kAmpFade,
56 | kAmpRel,
57 | kShpAtt,
58 | kShpDec,
59 | kShpSus,
60 | kShpFade,
61 | kShpRel,
62 | kShpMin,
63 | kShpMax,
64 | kFM,
65 | kDetune,
66 | kOctave,
67 | kBasisWave,
68 | kPulseWidth,
69 | kVelShaper,
70 | kVelVolume,
71 | kModShaper,
72 | kModLFO1Amp,
73 | #ifdef DIGITS_PRO
74 | kAftertouchShaper,
75 | kAftertouchLFO1Amp,
76 | #endif
77 | kLFORate,
78 | kLFOType,
79 | kLFODelay,
80 | kLFORepeat,
81 | kLFOShp,
82 | kLFOAmp,
83 | kLFOFrq,
84 | kLFOPWM,
85 | #ifdef DIGITS_PRO
86 | kLFO2Rate,
87 | kLFO2Type,
88 | kLFO2Delay,
89 | kLFO2Repeat,
90 | kLFO2Shp,
91 | kLFO2Amp,
92 | kLFO2Frq,
93 | kLFO2PWM,
94 | kLFO3Rate,
95 | kLFO3Type,
96 | kLFO3Delay,
97 | kLFO3Repeat,
98 | kLFO3Shp,
99 | kLFO3Amp,
100 | kLFO3Frq,
101 | kLFO3PWM,
102 | #endif
103 | kOrch,
104 | kDel_L,
105 | kDel_R,
106 | kDelWet,
107 | kDelFB,
108 | kDelLoss,
109 | kChrRate,
110 | kChrDepth,
111 | kChrDirtyClean,
112 | kChrTone,
113 | kChrWetDry,
114 | kChrFlang,
115 | kBitDiv,
116 | kBitBit,
117 | kBitBlend,
118 | #ifdef DIGITS_PRO
119 | kLockShaperForFilter,
120 | kFilterReso,
121 | kFilterMode,
122 | kMonoMode,
123 | kPortaSpeed,
124 | kAmpRateScale,
125 | kShpRateScale,
126 | kShpLevelScale,
127 | kPitchbendUp,
128 | kPitchbendDn,
129 | #endif
130 | kGain,
131 | kNumParams // Maximum value
132 | };
133 | static const char* s_paramNames[];
134 |
135 |
136 | #ifdef DIGITS_MULTICORE
137 | class HelperThread_t
138 | {
139 | public:
140 | // Constructor
141 | // rt_prio should be set to the priority we want the thread to be
142 | HelperThread_t(VstCore* core, Voice::voiceBuffers_t* bufs, int rt_prio);
143 | ~HelperThread_t();
144 |
145 | // Signal the helper thread to start processing a chunk. Call from core.
146 | void StartProcessChunk(int len, int forBuf)
147 | {
148 | DEBUG_MCORE("c: StartProcessChunk: get lock\n");
149 | pthread_mutex_lock(&m_beginChunkMutex);
150 | DEBUG_MCORE("c: StartProcessChunk: did processing = false, for buffer=%d\n", forBuf);
151 | m_curBuf = forBuf;
152 | m_chunkLen = len;
153 | m_didProcessing = false;
154 | pthread_mutex_unlock(&m_beginChunkMutex);
155 | DEBUG_MCORE("c: StartProcessChunk: release lock\n");
156 | pthread_cond_signal(&m_beginChunkCond);
157 | DEBUG_MCORE("c: StartProcessChunk: signal helper for %u\n", forBuf);
158 | }
159 | bool DidProcessing() { return m_didProcessing; }
160 | // Call from core
161 | void Quit()
162 | {
163 | DEBUG_MCORE("Shutting down helper\n");
164 | m_quitNow = true;
165 | StartProcessChunk(0, 0);
166 | pthread_join(m_thread, 0);
167 | DEBUG_MCORE("Done shutting down helper\n");
168 | m_quitNow = false;
169 | }
170 |
171 | pthread_mutex_t* GetMutex() { return &m_beginChunkMutex; }
172 |
173 | // Do not call directly. This is called by the thread callback.
174 | void ThreadCore();
175 | void SetOutputBuffer(float* buf) { m_outBuf = buf; }
176 |
177 | private:
178 | pthread_mutex_t m_beginChunkMutex;
179 | pthread_cond_t m_beginChunkCond;
180 | pthread_t m_thread;
181 | Voice::voiceBuffers_t* m_bufs;
182 | float* m_outBuf;
183 | int m_chunkLen;
184 | VstCore* m_vstCore;
185 | bool m_quitNow;
186 | // True if processing happened this frame
187 | bool m_didProcessing;
188 | unsigned int m_curBuf;
189 | };
190 | #endif
191 |
192 | VstCore(audioMasterCallback audioMaster);
193 | ~VstCore();
194 |
195 | // VST functions
196 | virtual VstInt32 getProgram () { return m_curProgram; }
197 | virtual void setProgram(VstInt32 program);
198 | virtual void getProgramName(char *name);
199 | virtual void setProgramName(char *name);
200 | // The non-VST SetProgramName. We use this because it's better, and Digits won't let
201 | // you permanently rename patches from solely within the DAW anyway/
202 | // SetProgram is also a non-VST variant here (notice capitalization). Both these functions
203 | // are guaranteed to be safe to call without triggering any DAW-side behavior-- they're
204 | // solely superficial and are used to keep the UI in sync.
205 | void SetProgramName(std::string name) { m_curProgramName = name; }
206 | void SetProgram(int program) { m_curProgram = program; }
207 | virtual void processReplacing(float **ins, float **outs, VstInt32 frames);
208 | virtual VstInt32 processEvents(VstEvents *events);
209 | virtual VstInt32 canDo(char *text);
210 | virtual void setParameter(VstInt32 index, float value);
211 | virtual float getParameter(VstInt32 index);
212 | virtual void getParameterLabel(VstInt32 index, char *text);
213 | virtual void getParameterDisplay(VstInt32 index, char *text);
214 | virtual void getParameterName(VstInt32 index, char *text);
215 | virtual void setSampleRate(float sR);
216 | virtual void setBlockSize(VstInt32 blockSize);
217 | virtual bool getOutputProperties(VstInt32 index, VstPinProperties* prop);
218 | virtual bool getEffectName(char *name);
219 | virtual bool getVendorString(char *text);
220 | virtual bool getProductString(char *text);
221 | virtual VstInt32 getNumMidiInputChannels() { return 1; }
222 | virtual VstInt32 getNumMidiOutputChannels() { return 0; }
223 | void HandleMidiEvent(char* midiEvent);
224 | // Set chorus for either chorus or flanger operation
225 | void SetChorusFlanger(bool isChorus);
226 |
227 | // Save/Load functions
228 | virtual VstInt32 getChunk(void** data, bool isPreset);
229 | virtual VstInt32 setChunk(void* data, VstInt32 byteSize, bool isPreset = false);
230 | bool LoadFXP(const std::string& fn);
231 | bool SaveFXP(const std::string& fn);
232 |
233 | PatchBankList& GetPatchBankList() { return m_pbList; }
234 |
235 | void NoteOn(int pitch, int velocity);
236 | void NoteOff(int pitch);
237 |
238 | bool VoiceIsFree(int voiceNum) { return m_voices[voiceNum]->IsFree(); }
239 | bool VoiceIsSubVoice(int voiceNum) { return m_voices[voiceNum]->IsSubVoice(); }
240 | void VoiceRender(int voiceNum, float *out, int len, Voice::voiceBuffers_t *bufs, int debugvoice, int debugthread)
241 | {
242 | m_voices[voiceNum]->Render(out, len, bufs, true, debugthread);
243 | }
244 |
245 | unsigned int CurBuf() { return m_curBuf; }
246 |
247 | #ifdef DIGITS_MULTICORE
248 | // Allocate a helper thread and start it. This routine is not very smart, so use
249 | // it carefully.
250 | void StartHelper(int helperIndex);
251 | #endif
252 |
253 | void AllNotesOff();
254 | void ResetPhases();
255 | void ResetEngine();
256 |
257 | private:
258 | static const int kNumVoices = 40;
259 | static const int kOctaves = 10; // Octaves that there are deltas for
260 | static const char* s_paramNamesChunk[];
261 |
262 | int m_curProgram;
263 | std::string m_curProgramName;
264 |
265 | // This is for the editor window, but must persist between
266 | // editor window allocation/reallocations
267 | PatchBankList m_pbList;
268 |
269 | Voice *m_voices[kNumVoices];
270 | Chorus m_chorus[2];
271 | // Chorus or flanger mode?
272 | bool m_chorusMode;
273 | // Oversampler m_oversampler;
274 | // int m_oversampleAmt;
275 |
276 | typedef std::vector midiEvents_t;
277 | std::vector m_midiEvents;
278 | static float s_freqDelta[kOctaves*12];
279 | // Orch (spread, supersaw, etc) mode variance amount
280 | float m_orch;
281 | // Overall gain of the sound
282 | float m_gain;
283 | // Voice is set to monophonic
284 | bool m_isMono;
285 | // Voice is set to always glide
286 | bool m_alwaysGlide;
287 |
288 | // Calculate deltas for each frequency (tied to sampling rate)
289 | void CalculateFreqDeltas();
290 | // Get delta for MIDI note number
291 | float GetDelta(VstInt32 midiNoteNum);
292 | // Find lowest key pressed (used in mono mode)
293 | int FindLowestNote();
294 |
295 | // 2 for now (dual core)
296 | Voice::voiceBuffers_t m_bufSets[2];
297 | // The helper's extra buffers
298 | // 1 for now (dual core)
299 | SndBuf* m_helperOutBufs[1];
300 |
301 | SndBuf* m_tempBuf;
302 |
303 | // Bitfield for which keys are on (mono mode)
304 | uint32_t m_keyBits[4];
305 |
306 | // Frames left to write within the control rate-sized buffer
307 | // left to write out to the host's buffer, preserved
308 | // between processReplacing calls
309 | int m_writeLeft;
310 | BufferManager m_manager;
311 |
312 | // True if this key is held down (keybits)
313 | inline bool IsNoteOn(int pitch);
314 |
315 | // Very simple store of floating point settings
316 | // for our program data
317 | float m_simpleProgram[kNumParams];
318 |
319 | // Voice allocation and stealing algorithm
320 | int NextFreeVoice();
321 |
322 | // Count up on each key press so that we can
323 | // figure out which notes are oldest
324 | uint64_t m_timestampClock;
325 | // Where does the next control period start? This is carried
326 | // over from buffer to buffer.
327 | int m_nextSpan;
328 |
329 | // Dynamically allocated space in which to save one patch.
330 | // FXBs are not supported. This is only dynamic because the
331 | // patch length varies because it's string based, but only
332 | // varies between versions. It calculates the patch len on save.
333 | char *m_patchData;
334 |
335 | // Last status byte for "running status" MIDI feature
336 | int m_lastStatus;
337 |
338 | // DC filter coefficients
339 | float m_dc_a[2];
340 | float m_dc_b[2];
341 | float m_dc_out[2];
342 | float m_dc_in[2];
343 |
344 | // Delay lines for echo
345 | float *m_delL;
346 | float *m_delR;
347 | // Read/write pointers
348 | int m_del_wL;
349 | int m_del_wR;
350 | // Wrap for pointer index in samples
351 | int m_del_wrapL;
352 | int m_del_wrapR;
353 | float m_delWet;
354 | float m_delFB;
355 | // Last sample for high frequency decay (4-pole)
356 | float m_del_lastL[4];
357 | float m_del_lastR[4];
358 | float m_del_filterA;
359 | float m_del_filterB;
360 | // Delay lines for chorus
361 |
362 |
363 | // Lite mode for phat detune
364 | bool m_phatLite;
365 |
366 | // Last note-on pitch recorded (for always-glide mode)
367 | int m_lastPitch;
368 |
369 | // Pitch bend amounts in semitones
370 | int m_bendUpAmt;
371 | int m_bendDnAmt;
372 |
373 | // True if the oscillator phases are reset upon note on
374 | bool m_resetOscs;
375 |
376 | #ifdef DIGITS_MULTICORE
377 | HelperThread_t* m_helpers[1];
378 | #endif
379 |
380 | int m_numCores;
381 |
382 | void PitchBend(float value);
383 | void ZeroPatch();
384 |
385 | void ApplyDC(float *in, int len);
386 |
387 | // Current chunk buffer's number (keep incrementing; wrap-around is OK)
388 | // This is used to prevent the helper thread from waking up too late and
389 | // performing work too early on the following frame, which knocks it out of sync
390 | unsigned int m_curBuf;
391 |
392 | SndBuf *m_chorusDryBuf;
393 | };
394 |
395 | #endif
396 |
397 |
--------------------------------------------------------------------------------
/windows/Digits.rc:
--------------------------------------------------------------------------------
1 | #define APSTUDIO_READONLY_SYMBOLS
2 |
3 | /////////////////////////////////////////////////////////////////////////////
4 | //
5 | // Bitmap
6 | //
7 |
8 | CosNoiseRockerV.png PNG DISCARDABLE "../Graphics/digits/CosNoiseRockerV.png"
9 | CosSinRockerV.png PNG DISCARDABLE "../Graphics/digits/CosSinRockerV.png"
10 | Dial_LCD.png PNG DISCARDABLE "../Graphics/digits/Dial_LCD.png"
11 | DialHandle_LCD.png PNG DISCARDABLE "../Graphics/digits/DialHandle_LCD.png"
12 | DigitsBG.png PNG DISCARDABLE "../Graphics/digits/DigitsBG.png"
13 | HSliderBG.png PNG DISCARDABLE "../Graphics/digits/HSliderBG.png"
14 | HSliderNub.png PNG DISCARDABLE "../Graphics/digits/HSliderNub.png"
15 | Logo.png PNG DISCARDABLE "../Graphics/digits/Logo.png"
16 |
17 |
18 | #ifndef _MAC
19 | /////////////////////////////////////////////////////////////////////////////
20 | //
21 | // Version
22 | //
23 | 1 VERSIONINFO
24 | FILEVERSION 1,0,0,0
25 | PRODUCTVERSION 2,1,0,0
26 | FILEFLAGSMASK 0x0L
27 | #ifdef _DEBUG
28 | FILEFLAGS 0x1L
29 | #else
30 | FILEFLAGS 0x0L
31 | #endif
32 | FILEOS 0x4L
33 | FILETYPE 0x2L
34 | FILESUBTYPE 0x0L
35 | BEGIN
36 | BLOCK "StringFileInfo"
37 | BEGIN
38 | BLOCK "000004e4"
39 | BEGIN
40 | VALUE "CompanyName", "Extent of the Jam\0"
41 | VALUE "FileDescription", "Digits VST\0"
42 | VALUE "FileVersion", "2.1.0"
43 | VALUE "InternalName", "Digits VST"
44 | VALUE "LegalCopyright", "Extent of the Jam\0"
45 | VALUE "OriginalFilename", "Digits"
46 | VALUE "ProductName", "Digits"
47 | VALUE "ProductVersion", "2.1.0.0"
48 | END
49 | END
50 | BLOCK "VarFileInfo"
51 | BEGIN
52 | VALUE "Translation", 0x0, 1252
53 | END
54 | END
55 |
56 | #endif // !_MAC
57 |
--------------------------------------------------------------------------------
/windows/DigitsVST.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Debug
10 | x64
11 |
12 |
13 | Release
14 | Win32
15 |
16 |
17 | Release
18 | x64
19 |
20 |
21 |
22 | Win32Proj
23 | {85DD9136-6EC3-A79C-BA32-4D011E0C9E82}
24 |
25 |
26 |
27 | DynamicLibrary
28 | true
29 | v140
30 |
31 |
32 | DynamicLibrary
33 | true
34 | v140
35 |
36 |
37 | DynamicLibrary
38 | false
39 | v140
40 |
41 |
42 | DynamicLibrary
43 | false
44 | v140
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 | true
64 |
65 |
66 | true
67 |
68 |
69 | true
70 |
71 |
72 | true
73 |
74 |
75 |
76 | WIN32;_DEBUG;_WINDOWS;_USRDLL;DIGITSVST_EXPORTS;DIGITS_PRO;%(PreprocessorDefinitions);_USE_MATH_DEFINES
77 | MultiThreadedDebugDLL
78 | Level3
79 | ProgramDatabase
80 | Disabled
81 | $(ProjectDir)\..\src\components;$(ProjectDir)\..\src\digits;$(ProjectDir)\..\sdks\vstsdk2.4;$(ProjectDir)\..\sdks\vstgui\plugin-bindings;..\sdks\vstsdk2.4\public.sdk\source\vst2.x;%(AdditionalIncludeDirectories)
82 |
83 |
84 | MachineX86
85 | true
86 | Windows
87 | vstplug.def
88 |
89 |
90 |
91 |
92 | WIN32;_DEBUG;_WINDOWS;_USRDLL;DIGITSVST_EXPORTS;DIGITS_PRO;%(PreprocessorDefinitions);_USE_MATH_DEFINES
93 | MultiThreadedDebugDLL
94 | Level3
95 | ProgramDatabase
96 | Disabled
97 | C:\Users\Louis\Desktop\DigitsVst\trunk\vstsdk2.4;C:\MinGW\msys\1.0\home\Louis\svnrepo\DigitsVst\vstsdk2.4;%(AdditionalIncludeDirectories)
98 |
99 |
100 | true
101 | Windows
102 | vstplug.def
103 |
104 |
105 |
106 |
107 | WIN32;_WINDOWS;_USRDLL;DIGITSVST_EXPORTS;DIGITS_PRO;%(PreprocessorDefinitions);_USE_MATH_DEFINES
108 | MultiThreadedDLL
109 | Level3
110 | ProgramDatabase
111 | $(ProjectDir)\..\src\components;$(ProjectDir)\..\src\digits;$(ProjectDir)\..\sdks\vstsdk2.4;$(ProjectDir)\..\sdks\vstgui\plugin-bindings;..\sdks\vstsdk2.4\public.sdk\source\vst2.x;%(AdditionalIncludeDirectories)
112 | MaxSpeed
113 | Default
114 |
115 |
116 | MachineX86
117 | true
118 | Windows
119 | true
120 | true
121 | vstplug.def
122 | false
123 |
124 |
125 |
126 |
127 | WIN32;_WINDOWS;_USRDLL;DIGITSVST_EXPORTS;DIGITS_PRO;%(PreprocessorDefinitions);_USE_MATH_DEFINES
128 | MultiThreadedDLL
129 | Level3
130 | ProgramDatabase
131 | C:\Users\Louis\Desktop\DigitsVst\trunk\vstsdk2.4;C:\MinGW\msys\1.0\home\Louis\svnrepo\DigitsVst\vstsdk2.4;%(AdditionalIncludeDirectories)
132 | MaxSpeed
133 | Default
134 |
135 |
136 | true
137 | Windows
138 | true
139 | true
140 | vstplug.def
141 | false
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
--------------------------------------------------------------------------------
/windows/Main.VC.opendb:
--------------------------------------------------------------------------------
1 | L o u i s L O U I S - P C
--------------------------------------------------------------------------------
/windows/Main.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Express 14 for Windows Desktop
4 | VisualStudioVersion = 14.0.24720.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DigitsVST", "DigitsVST.vcxproj", "{85DD9136-6EC3-A79C-BA32-4D011E0C9E82}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Win32 = Debug|Win32
11 | Debug|x64 = Debug|x64
12 | Release|Win32 = Release|Win32
13 | Release|x64 = Release|x64
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {85DD9136-6EC3-A79C-BA32-4D011E0C9E82}.Debug|Win32.ActiveCfg = Debug|Win32
17 | {85DD9136-6EC3-A79C-BA32-4D011E0C9E82}.Debug|Win32.Build.0 = Debug|Win32
18 | {85DD9136-6EC3-A79C-BA32-4D011E0C9E82}.Debug|x64.ActiveCfg = Debug|x64
19 | {85DD9136-6EC3-A79C-BA32-4D011E0C9E82}.Debug|x64.Build.0 = Debug|x64
20 | {85DD9136-6EC3-A79C-BA32-4D011E0C9E82}.Release|Win32.ActiveCfg = Release|Win32
21 | {85DD9136-6EC3-A79C-BA32-4D011E0C9E82}.Release|Win32.Build.0 = Release|Win32
22 | {85DD9136-6EC3-A79C-BA32-4D011E0C9E82}.Release|x64.ActiveCfg = Release|x64
23 | {85DD9136-6EC3-A79C-BA32-4D011E0C9E82}.Release|x64.Build.0 = Release|x64
24 | {930529B6-2B18-40F3-B6AB-31D87251B0E4}.Debug|Win32.ActiveCfg = Debug|Win32
25 | {930529B6-2B18-40F3-B6AB-31D87251B0E4}.Debug|Win32.Build.0 = Debug|Win32
26 | {930529B6-2B18-40F3-B6AB-31D87251B0E4}.Debug|x64.ActiveCfg = Debug|x64
27 | {930529B6-2B18-40F3-B6AB-31D87251B0E4}.Debug|x64.Build.0 = Debug|x64
28 | {930529B6-2B18-40F3-B6AB-31D87251B0E4}.Release|Win32.ActiveCfg = Release|Win32
29 | {930529B6-2B18-40F3-B6AB-31D87251B0E4}.Release|Win32.Build.0 = Release|Win32
30 | {930529B6-2B18-40F3-B6AB-31D87251B0E4}.Release|x64.ActiveCfg = Release|x64
31 | {930529B6-2B18-40F3-B6AB-31D87251B0E4}.Release|x64.Build.0 = Release|x64
32 | EndGlobalSection
33 | GlobalSection(SolutionProperties) = preSolution
34 | HideSolutionNode = FALSE
35 | EndGlobalSection
36 | EndGlobal
37 |
--------------------------------------------------------------------------------
/windows/vstplug.def:
--------------------------------------------------------------------------------
1 | EXPORTS
2 | VSTPluginMain
3 | main=VSTPluginMain
--------------------------------------------------------------------------------