├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── TODO.md ├── docs ├── manual │ ├── CoreUML.pdf │ ├── CurveDown.pdf │ ├── CurveUp.pdf │ ├── Curves.nb │ ├── GUIUML.pdf │ ├── ModulationSourcesAndShapers.png │ ├── Other.png │ ├── Saw1.pdf │ ├── Saw2.pdf │ ├── Threads.pdf │ ├── UML.graffle │ ├── UML.pdf │ ├── UnitShapers1.png │ ├── UnitShapers2.png │ ├── UnitShapers3.png │ ├── UnitSources1.png │ ├── UnitSources2.png │ ├── adsr.png │ ├── constrain.png │ ├── display.png │ ├── flow.tex │ ├── loopbackaudio.pdf │ ├── loopbackmidi.pdf │ ├── oscilloscope.png │ ├── partials.pdf │ ├── phases.pdf │ ├── screenshot.png │ ├── simple.png │ ├── simplepatch.png │ ├── sinewaves.nb │ ├── sinewaves.pdf │ └── subpatches.png └── web │ ├── Banner.png │ └── HelloWorldDemo.png ├── flow ├── AudioInput.java ├── Constant.java ├── Flow.java ├── Group.java ├── Input.java ├── Manufacturers.txt ├── MicroTuning.java ├── Midi.java ├── MidiClock.java ├── Miscellaneous.java ├── ModSource.java ├── Modulation.java ├── Nil.java ├── Output.java ├── Prefs.java ├── Presetable.java ├── Sound.java ├── Unit.java ├── UnitSource.java ├── Utility.java ├── XORShift32.java ├── gui │ ├── About.png │ ├── AppMenu.java │ ├── BellyButton.png │ ├── BellyButtonPressed.png │ ├── ConstraintsChooser.java │ ├── DisclosurePanel.java │ ├── Display.java │ ├── InputOutput.java │ ├── Joystick.java │ ├── KeyDisplay.java │ ├── Mac.java │ ├── ModulationInput.java │ ├── ModulationOutput.java │ ├── ModulationWire.java │ ├── ModulePanel.java │ ├── OptionsChooser.java │ ├── Oscilloscope.java │ ├── Playing.png │ ├── Presets.java │ ├── PushButton.java │ ├── Rack.java │ ├── Rebuildable.java │ ├── Stretch.java │ ├── Strut.java │ ├── Style.java │ ├── SubpatchPanel.java │ ├── Test.java │ ├── UnitInput.java │ ├── UnitOutput.java │ ├── UnitWire.java │ └── WidgetList.java ├── modules │ ├── AHR.java │ ├── AKWF.java │ ├── Alias.java │ ├── All.java │ ├── AmpMath.java │ ├── AudioIn.java │ ├── BellyButton.png │ ├── BellyButtonPressed.png │ ├── Buffer.java │ ├── Choice.java │ ├── Chord.java │ ├── Combine.java │ ├── Compress.java │ ├── Constraints.java │ ├── ConvertWav.java │ ├── DADSR.java │ ├── Delay.java │ ├── Dilate.java │ ├── Dissolve.java │ ├── Draw.java │ ├── Drawbars.java │ ├── EitherOr.java │ ├── Envelope.java │ ├── Fatten.java │ ├── Fill.java │ ├── Filter.java │ ├── Fix.java │ ├── FlangeFilter.java │ ├── FormantFilter.java │ ├── Geiger.java │ ├── HarmonicLab.java │ ├── Harmonics.java │ ├── In.java │ ├── Jitter.java │ ├── Joy.java │ ├── KHarmonics.java │ ├── LFO.java │ ├── LadderFilter.java │ ├── Latch.java │ ├── LeftArrow.png │ ├── LeftArrowPressed.png │ ├── LinearFilter.java │ ├── MIDIIn.java │ ├── MPE.java │ ├── Macro.java │ ├── Map.java │ ├── Mapping.nb │ ├── Mix.java │ ├── ModMath.java │ ├── Modules.java │ ├── Morph.java │ ├── NRPN.java │ ├── Noise.java │ ├── Normalize.java │ ├── Note.java │ ├── Out.java │ ├── PartialFilter.java │ ├── Partials.java │ ├── Patch.java │ ├── RandMod.java │ ├── Rectified.java │ ├── RightArrow.png │ ├── RightArrowPressed.png │ ├── Rotate.java │ ├── SampleAndHold.java │ ├── Sawtooth.java │ ├── Scale.java │ ├── Seq.java │ ├── Shift.java │ ├── Sine.java │ ├── Skeletonize.java │ ├── Smooth.java │ ├── Soften.java │ ├── Square.java │ ├── Stretch.java │ ├── Sub.java │ ├── Subharmonics.java │ ├── Swap.java │ ├── Switch.java │ ├── Tinkle.java │ ├── Triangle.java │ ├── User.java │ ├── VCA.java │ ├── WaveTable.java │ ├── Waves.java │ ├── help │ │ ├── AHR.html │ │ ├── AKWF.html │ │ ├── All.html │ │ ├── AmpMath.html │ │ ├── AudioIn.html │ │ ├── Buffer.html │ │ ├── Choice.html │ │ ├── Chord.html │ │ ├── Combine.html │ │ ├── Compress.html │ │ ├── Constraints.html │ │ ├── DADSR.html │ │ ├── Delay.html │ │ ├── Dilate.html │ │ ├── Dissolve.html │ │ ├── Draw.html │ │ ├── Drawbars.html │ │ ├── EitherOr.html │ │ ├── Envelope.html │ │ ├── Fatten.html │ │ ├── Fill.html │ │ ├── Filter.html │ │ ├── Fix.html │ │ ├── FlangeFilter.html │ │ ├── FormantFilter.html │ │ ├── Geiger.html │ │ ├── HarmonicLab.html │ │ ├── Harmonics.html │ │ ├── In.html │ │ ├── Jitter.html │ │ ├── Joy.html │ │ ├── KHarmonics.html │ │ ├── LFO.html │ │ ├── LadderFilter.html │ │ ├── Latch.html │ │ ├── LinearFilter.html │ │ ├── MIDIIn.html │ │ ├── MPE.html │ │ ├── Macro.html │ │ ├── Map.html │ │ ├── Mix.html │ │ ├── ModMath.html │ │ ├── Morph.html │ │ ├── NRPN.html │ │ ├── Noise.html │ │ ├── Normalize.html │ │ ├── Note.html │ │ ├── Out.html │ │ ├── PartialFilter.html │ │ ├── Partials.html │ │ ├── Patch.html │ │ ├── RandMod.html │ │ ├── Rectified.html │ │ ├── Rotate.html │ │ ├── SampleAndHold.html │ │ ├── Sawtooth.html │ │ ├── Scale.html │ │ ├── Seq.html │ │ ├── Shift.html │ │ ├── Sine.html │ │ ├── Skeletonize.html │ │ ├── Smooth.html │ │ ├── Soften.html │ │ ├── Square.html │ │ ├── Stretch.html │ │ ├── Sub.html │ │ ├── Subharmonics.html │ │ ├── Swap.html │ │ ├── Switch.html │ │ ├── Tinkle.html │ │ ├── Triangle.html │ │ ├── User.html │ │ ├── VCA.html │ │ ├── WaveTable.html │ │ └── Waves.html │ └── waves │ │ ├── LICENSE.txt │ │ ├── akwf.out │ │ ├── kharmonics.out │ │ ├── waves.out │ │ ├── wavesources.tar.gz │ │ └── wavesources │ │ └── CZ │ │ └── ConvertWave.java ├── patches │ ├── Apparition.flow │ ├── Astronomical.flow │ ├── Atlantean.flow │ ├── Ayahh.flow │ ├── Bedevilment.flow │ ├── BlockChime.flow │ ├── Borealis.flow │ ├── Chime.flow │ ├── Collision.flow │ ├── Convergence.flow │ ├── Detuned.flow │ ├── Drawbars.flow │ ├── Droid.flow │ ├── Droplets.flow │ ├── Effervescence.flow │ ├── ElasticBass.flow │ ├── Energize.flow │ ├── Enrichment.flow │ ├── Fascination.flow │ ├── Fatness.flow │ ├── Footsteps.flow │ ├── Giacomo.flow │ ├── Glitter.flow │ ├── Harm.flow │ ├── Herald.flow │ ├── IComeInPeace.flow │ ├── Idemnification.flow │ ├── Instability.flow │ ├── Jawa.flow │ ├── JerkedAround.flow │ ├── Juice.flow │ ├── Kotobell.flow │ ├── Linearity.flow │ ├── LowDrone.flow │ ├── Marimba.flow │ ├── Melancholy.flow │ ├── NoisyBass.flow │ ├── OctaveChime.flow │ ├── Order.flow │ ├── Owwee.flow │ ├── PeacefulPlanet.flow │ ├── Percolation.flow │ ├── PewPewPew.flow │ ├── Phantasm.flow │ ├── PianoSparks.flow │ ├── Pizzicato.flow │ ├── Plop.flow │ ├── Plucky.flow │ ├── PopBass.flow │ ├── PopcornInTheTunnel.flow │ ├── Pwaaaah.flow │ ├── README.md │ ├── RandomK5.flow │ ├── ScaleBass.flow │ ├── Sequentialism.flow │ ├── ShimmerBells.flow │ ├── SpringMallet.flow │ ├── Starlight.flow │ ├── Steel.flow │ ├── Sunshine.flow │ ├── SuperSawStab.flow │ ├── SuperSquare.flow │ ├── Swirls.flow │ ├── Synchronization.flow │ ├── Templar.flow │ ├── ThirdRail.flow │ ├── Tinklepad.flow │ ├── Tremble.flow │ ├── Trinkets.flow │ ├── TubularBell.flow │ ├── Turbulence.flow │ ├── Undercurrent.flow │ ├── Undulation.flow │ ├── Vacillation.flow │ ├── Vigor.flow │ ├── WarmOrganPad.flow │ ├── Whiplash.flow │ ├── Whoa.flow │ ├── Zephyr.flow │ ├── experiments │ │ ├── Aliasing.flow │ │ ├── Bell.flow │ │ ├── Formant Test.flow │ │ ├── README.md │ │ └── ShepardTone.flow │ ├── macros │ │ ├── AhOoh.flow │ │ ├── AhOohDemo.flow │ │ ├── Bass Filter.flow │ │ ├── BrickWallFilter.flow │ │ ├── CCHarmonics.flow │ │ ├── CCHarmonics.old.flow │ │ ├── Drift.flow │ │ ├── README.md │ │ ├── RandomFatten.flow │ │ ├── SuperSaw.flow │ │ ├── Tamp.flow │ │ └── Waver.flow │ └── percussion │ │ ├── Aftershock.flow │ │ ├── Blaster.flow │ │ ├── Clang.flow │ │ ├── Click.flow │ │ ├── Crack.flow │ │ ├── DetunedTom.flow │ │ ├── DissolveToNoise.flow │ │ ├── Handclap.flow │ │ ├── HeavySpring.flow │ │ ├── HighHat.flow │ │ ├── Kick.flow │ │ ├── MetalKick.flow │ │ ├── MoreCowbell.flow │ │ ├── Pop.flow │ │ ├── Snap.flow │ │ ├── Snip.flow │ │ ├── Thump.flow │ │ └── Thwang.flow └── utilities │ ├── FFT.java │ ├── FreeVerb.java │ ├── StringUtilities.java │ ├── WavFile.java │ ├── WavFileException.java │ └── WindowedSinc.java └── libraries ├── README.md ├── coremidi4j-1.5.jar └── json.jar /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: jar install 2 | 3 | all: 4 | javac -cp libraries/coremidi4j-1.5.jar:libraries/json.jar:. $$(find flow -name '*.java') 5 | 6 | run: DUMMY 7 | java -cp libraries/coremidi4j-1.5.jar:libraries/json.jar flow.Flow 8 | 9 | indent: 10 | touch ${HOME}/.emacs 11 | find . -name "*.java" -print -exec emacs --batch --load ~/.emacs --eval='(progn (find-file "{}") (mark-whole-buffer) (setq indent-tabs-mode nil) (untabify (point-min) (point-max)) (indent-region (point-min) (point-max) nil) (save-buffer))' \; 12 | 13 | jar: 14 | rm -rf install/flow.jar uk META-INF 15 | javac flow/*.java flow/*/*.java 16 | touch /tmp/manifest.add 17 | rm /tmp/manifest.add 18 | echo "Main-Class: flow.Flow" > /tmp/manifest.add 19 | cd libraries ; jar -xvf coremidi4j-1.5.jar 20 | mv libraries/META-INF . ; mv libraries/uk . 21 | cd libraries ; jar -xvf json.jar 22 | mv libraries/org . 23 | jar -cvfm install/flow.jar /tmp/manifest.add `find flow -name "*.class"` `find flow -name "*.init"` `find flow -name "*.html"` `find flow -name "*.png"` `find flow -name "*.jpg"` `find flow -name "*.out"` `find flow -name "Manufacturers.txt"` org/ uk/ META-INF/ 24 | rm -rf uk META-INF org 25 | 26 | install8: jar 27 | rm -rf install/Flow.app install/bundles install/Flow.dmg.html install/Flow.dmg.jnlp 28 | - javapackager -deploy -Bruntime= -native dmg -srcfiles install/flow.jar -appclass flow.Flow -name Flow -outdir install -outfile Flow.dmg -v 29 | - mv install/bundles/Flow-0.0.dmg install/Flow.dmg 30 | rm -rf install/bundles install/Flow.dmg.html install/Flow.dmg.jnlp 31 | 32 | install: jar 33 | rm -rf install/Flow.app install/bundles install/Flow.dmg.html install/Flow.dmg.jnlp 34 | - jpackage --input install --name Flow --main-jar flow.jar --main-class flow.Flow --type dmg --mac-package-name "Flow" --verbose --java-options '-XX:+UseZGC -XX:MaxGCPauseMillis=1' 35 | open Flow-1.0.dmg 36 | # - mv install/bundles/Flow-0.0.dmg install/Flow.dmg 37 | # rm -rf install/bundles install/Flow.dmg.html install/Flow.dmg.jnlp 38 | 39 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | To Do 2 | ===== 3 | 4 | This is a list of stuff that's not done yet. Pick something and work on it! 5 | 6 | 7 | System 8 | ------ 9 | 10 | * Midi Devices may have the same name in Linux; for example, the two incoming 11 | MIDI devices from the Korg Microsampler. We need to detect this and use other 12 | info (version etc.) to distinguish them. 13 | 14 | * The software has not been tested on Windows at all, and only in limited form on 15 | Linux. 16 | 17 | * MIDI clock is flakey and inaccurate. Also, we ignore clock pulses while stopped, 18 | when in fact we should be using them to estimate our upcoming tempo. 19 | 20 | * At present we're using java.util.Random, which is (1) multithreaded and thus 21 | unneccessarily slow, and (2) very bad quality. The quality doesn't really 22 | matter for our purposes, and I'm keeping it to make it easier for people 23 | unused to other generators. But I've included a rudimentary XORShift32 24 | implementation which should be fine for our purposes and is also much faster 25 | and somewhat better quality. Perhaps we should move to it? 26 | 27 | * **Overall: we need compelling patches.** I think right now the modules have a lot 28 | of promise but they still feel meh. It's fun to experiment in additive, but 29 | we need patches that are nontrivial to do in some other way and are useful. 30 | 31 | Modules 32 | ------- 33 | 34 | * Alias 35 | * All 36 | * AHR 37 | * AmpMath 38 | * Average 39 | * Buffer 40 | * Choice 41 | * Combine 42 | * Compress 43 | - This doesn't feel like a very useful module. Perhaps it should be eliminated. 44 | - Or maybe merge it in with AmpMath 45 | - We need to consider what to do with amplitudes >= 1.0 46 | * DADSR 47 | * Delay 48 | * Dilate 49 | * Draw 50 | * Drawbars 51 | * EitherOr 52 | * Envelope 53 | * Fatten 54 | * Fill 55 | * Filter 56 | * Fix 57 | * FlangeFilter 58 | * Geiger 59 | * Harmonics 60 | - Need to better organize the existing harmonics and weed out the dumb ones 61 | * In 62 | * Jitter 63 | * LFO 64 | * LinearFilter 65 | - Frequencies may be too sensitive. 66 | * Macro 67 | * Map 68 | * MIDIIn 69 | * Mix 70 | * ModMath 71 | * Morph 72 | * MPE 73 | * Noise 74 | * Normalize 75 | * Note 76 | * NRPN 77 | * Out 78 | * PartialMod 79 | - Seems not to be working right. 80 | * PartialFilter 81 | * PartialsLab 82 | - We could extend this to make it more useful. 83 | * PartialMod 84 | * Partials 85 | * Rand 86 | - Is this a useful module? Should we delete or merge it? 87 | * Rectified 88 | * Rotate 89 | * Sample and Hold 90 | * Sawtooth 91 | * Scale 92 | * Seq 93 | - This is incomplete and not working properly. Curve has no purpose. 94 | * Shift 95 | * Sine 96 | - This could be made more useful perhaps 97 | * Skeletonize 98 | * Smooth 99 | * Soften 100 | * Square 101 | * Squish 102 | * Stretch 103 | * Sub 104 | * Swap 105 | * Tinkle 106 | * Triangle 107 | * User 108 | * VCA 109 | * Waves 110 | - What other synths should we include? 111 | * Wavetable 112 | 113 | 114 | Uncompleted Modules 115 | ------------------- 116 | 117 | * Bell 118 | - I'm working on a bell module with independent envelopes and proper harmonics. It's not close to done yet. 119 | 120 | * Constrained 121 | - This module does not exist. The idea should be to have a module which does more 122 | advanced combinations of constraints than you'd have in the standard constraint 123 | facility. Should we make one? 124 | 125 | -------------------------------------------------------------------------------- /docs/manual/CoreUML.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/docs/manual/CoreUML.pdf -------------------------------------------------------------------------------- /docs/manual/CurveDown.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/docs/manual/CurveDown.pdf -------------------------------------------------------------------------------- /docs/manual/CurveUp.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/docs/manual/CurveUp.pdf -------------------------------------------------------------------------------- /docs/manual/GUIUML.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/docs/manual/GUIUML.pdf -------------------------------------------------------------------------------- /docs/manual/ModulationSourcesAndShapers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/docs/manual/ModulationSourcesAndShapers.png -------------------------------------------------------------------------------- /docs/manual/Other.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/docs/manual/Other.png -------------------------------------------------------------------------------- /docs/manual/Saw1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/docs/manual/Saw1.pdf -------------------------------------------------------------------------------- /docs/manual/Saw2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/docs/manual/Saw2.pdf -------------------------------------------------------------------------------- /docs/manual/Threads.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/docs/manual/Threads.pdf -------------------------------------------------------------------------------- /docs/manual/UML.graffle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/docs/manual/UML.graffle -------------------------------------------------------------------------------- /docs/manual/UML.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/docs/manual/UML.pdf -------------------------------------------------------------------------------- /docs/manual/UnitShapers1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/docs/manual/UnitShapers1.png -------------------------------------------------------------------------------- /docs/manual/UnitShapers2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/docs/manual/UnitShapers2.png -------------------------------------------------------------------------------- /docs/manual/UnitShapers3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/docs/manual/UnitShapers3.png -------------------------------------------------------------------------------- /docs/manual/UnitSources1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/docs/manual/UnitSources1.png -------------------------------------------------------------------------------- /docs/manual/UnitSources2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/docs/manual/UnitSources2.png -------------------------------------------------------------------------------- /docs/manual/adsr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/docs/manual/adsr.png -------------------------------------------------------------------------------- /docs/manual/constrain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/docs/manual/constrain.png -------------------------------------------------------------------------------- /docs/manual/display.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/docs/manual/display.png -------------------------------------------------------------------------------- /docs/manual/loopbackaudio.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/docs/manual/loopbackaudio.pdf -------------------------------------------------------------------------------- /docs/manual/loopbackmidi.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/docs/manual/loopbackmidi.pdf -------------------------------------------------------------------------------- /docs/manual/oscilloscope.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/docs/manual/oscilloscope.png -------------------------------------------------------------------------------- /docs/manual/partials.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/docs/manual/partials.pdf -------------------------------------------------------------------------------- /docs/manual/phases.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/docs/manual/phases.pdf -------------------------------------------------------------------------------- /docs/manual/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/docs/manual/screenshot.png -------------------------------------------------------------------------------- /docs/manual/simple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/docs/manual/simple.png -------------------------------------------------------------------------------- /docs/manual/simplepatch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/docs/manual/simplepatch.png -------------------------------------------------------------------------------- /docs/manual/sinewaves.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/docs/manual/sinewaves.pdf -------------------------------------------------------------------------------- /docs/manual/subpatches.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/docs/manual/subpatches.png -------------------------------------------------------------------------------- /docs/web/Banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/docs/web/Banner.png -------------------------------------------------------------------------------- /docs/web/HelloWorldDemo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/docs/web/HelloWorldDemo.png -------------------------------------------------------------------------------- /flow/Constant.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 by George Mason University 2 | // Licensed under the Apache 2.0 License 3 | 4 | 5 | package flow; 6 | 7 | /** 8 | Constant is a Modulation which provides a single value. The class name is actually 9 | a misnomer, as you can change the value of a Constant via its setValue(...) method. 10 | Constants are the typical default elements which fill the incoming Modulation slots 11 | of Modulation and Unit objects. 12 | 13 |

Constants do not register themselves with Sounds. You will never see a 14 | ModPanel which represents a Constant. 15 | 16 |

Constants do not provide triggers. 17 | 18 |

There are three useful Constant objects: Modulation.ZERO, Modulation.HALF, and 19 | Modulation.ONE. 20 | **/ 21 | 22 | public class Constant extends Modulation 23 | { 24 | private static final long serialVersionUID = 1; 25 | 26 | public static final Constant ZERO = new Constant(0); 27 | public static final Constant QUARTER = new Constant(0.25); 28 | public static final Constant HALF = new Constant(0.5); 29 | public static final Constant ONE = new Constant(1); 30 | 31 | public Constant(double val) 32 | { 33 | super(null); // don't register me 34 | setValue(val); 35 | } 36 | 37 | /** Returns the Constant's value, between 0...1. This method is the same as modulate(). */ 38 | public double getValue() 39 | { 40 | return getModulationOutput(0); 41 | } 42 | 43 | /** Sets the Constant's value, bounded to between 0...1. */ 44 | public void setValue(double val) 45 | { 46 | if (val < 0) val = 0; 47 | else if (val > 1) val = 1; 48 | setModulationOutput(0, val); 49 | } 50 | 51 | public String toString() { return "<" + getValue() + ">"; } 52 | } 53 | -------------------------------------------------------------------------------- /flow/Flow.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 by George Mason University 2 | // Licensed under the Apache 2.0 License 3 | 4 | 5 | package flow; 6 | 7 | import flow.gui.*; 8 | import flow.modules.*; 9 | import java.awt.*; 10 | import java.awt.geom.*; 11 | import javax.swing.border.*; 12 | import javax.swing.*; 13 | import java.awt.event.*; 14 | import java.util.*; 15 | import org.json.*; 16 | import java.io.*; 17 | import java.util.zip.*; 18 | 19 | 20 | public class Flow 21 | { 22 | // Flow Version 23 | public static int VERSION = 12; 24 | 25 | public static void main(String[] args) 26 | { 27 | Output output = new Output(); 28 | 29 | Sound sound0 = null; 30 | for(int i = 0; i < Output.getNumVoices(); i++) 31 | { 32 | Sound sound = new Sound(output); 33 | if (i == 0) sound0 = sound; 34 | Out out = new Out(sound); // findBugs thinks this is a dead store. It isn't. 35 | sound.reset(); 36 | } 37 | 38 | final Rack rack = new Rack(output); 39 | rack.smallerOkay = true; 40 | for (Modulation mod : sound0.getRegistered()) 41 | { 42 | // there will be only one: Out 43 | if (!(mod instanceof Constant) && !(mod instanceof Nil)) 44 | rack.addModulation(mod); 45 | } 46 | rack.smallerOkay = false; 47 | rack.rebuild(); 48 | 49 | Dimension d = rack.getScrollPane().getPreferredSize(); 50 | d.height *= 1.6; 51 | rack.getScrollPane().setPreferredSize(d); 52 | 53 | rack.sprout(); 54 | 55 | output.startPrimaryVoiceThread(); 56 | 57 | if (args.length == 1) 58 | { 59 | SwingUtilities.invokeLater(new Runnable() 60 | { 61 | public void run() 62 | { 63 | try 64 | { 65 | File f = new File(args[0]); 66 | AppMenu.doLoad(rack, new JSONObject(new JSONTokener(new GZIPInputStream(new FileInputStream(f)))), true); 67 | AppMenu.setLastFile(f); 68 | rack.setPatchFile(f); 69 | rack.setPatchName(rack.getPatchName()); 70 | } 71 | catch(Exception ex) { System.err.println("Couldn't load file " + args[0]); System.err.println(ex); } 72 | } 73 | }); 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /flow/Miscellaneous.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 by George Mason University 2 | // Licensed under the Apache 2.0 License 3 | 4 | 5 | package flow; 6 | 7 | /** 8 | Modules implement this empty interface to hint to the GUI that they are "unusual" 9 | and so deserve to have black title bars. Examples include In, Out, etc. 10 | **/ 11 | 12 | public interface Miscellaneous 13 | { 14 | } 15 | -------------------------------------------------------------------------------- /flow/ModSource.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 by George Mason University 2 | // Licensed under the Apache 2.0 License 3 | 4 | 5 | package flow; 6 | 7 | /** 8 | Modulations implement this empty interface to hint to the GUI that they are primarily 9 | initial sources of modulation values rather than piping or filtering them from some other source. 10 | **/ 11 | 12 | public interface ModSource 13 | { 14 | } 15 | -------------------------------------------------------------------------------- /flow/Nil.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 by George Mason University 2 | // Licensed under the Apache 2.0 License 3 | 4 | 5 | package flow; 6 | 7 | /** 8 | Nil is a Unit which does nothing. Its frequencies and amplitudes are all zero. 9 | The sole purpose of Nil objects is to indicate that the input to a Unit has not 10 | been filled by another Unit (Nil basically serves the purpose of null). 11 | 12 |

Nil instances do not register themselves with Sounds. You will never see a 13 | ModPanel which represents Nil. 14 | 15 |

There is a canonical Nil object available: Unit.NIL. However other Nil 16 | instances can and will be created, and they should all be treated as equivalent. 17 | **/ 18 | 19 | public class Nil extends Unit 20 | { 21 | private static final long serialVersionUID = 1; 22 | 23 | public Nil() 24 | { 25 | super(null); 26 | } 27 | 28 | public String toString() { return ""; } 29 | } 30 | -------------------------------------------------------------------------------- /flow/Presetable.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 by George Mason University 2 | // Licensed under the Apache 2.0 License 3 | 4 | 5 | package flow; 6 | 7 | /** Implement this interface to enable presets in your module. */ 8 | 9 | public interface Presetable 10 | { 11 | public String[] getPresets(); 12 | public void setPreset(int preset); 13 | } 14 | -------------------------------------------------------------------------------- /flow/UnitSource.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 by George Mason University 2 | // Licensed under the Apache 2.0 License 3 | 4 | 5 | package flow; 6 | 7 | /** 8 | Units implement this empty interface to hint to the GUI that they are primarily 9 | initial sources of harmonics rather than piping or filtering them from some other source. 10 | **/ 11 | 12 | public interface UnitSource 13 | { 14 | } 15 | -------------------------------------------------------------------------------- /flow/XORShift32.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 by George Mason University 2 | // Licensed under the Apache 2.0 License 3 | 4 | 5 | package flow; 6 | 7 | 8 | public class XORShift32 9 | { 10 | int seed; 11 | 12 | public XORShift32(int val) 13 | { 14 | reseed(val); 15 | } 16 | 17 | public void reseed(int val) 18 | { 19 | if (val == 0) val = -1; 20 | seed = val; 21 | } 22 | 23 | public int next() 24 | { 25 | seed ^= (seed << 13); 26 | seed ^= (seed >>> 17); 27 | seed ^= (seed << 5); 28 | return seed; 29 | } 30 | 31 | public int nextInt(int n) 32 | { 33 | if (n<=0) 34 | throw new IllegalArgumentException("n must be positive, got: " + n); 35 | 36 | if ((n & -n) == n) 37 | return (int)((n * (long)(next() & 0x7FFFFFFF)) >> 31); 38 | 39 | int bits, val; 40 | do 41 | { 42 | bits = (next() & 0x7FFFFFFF); 43 | val = bits % n; 44 | } 45 | while(bits - val + (n-1) < 0); 46 | return val; 47 | } 48 | 49 | public float nextFloat() 50 | { 51 | return (next() & 0x00FFFFFF) / ((float)(1 << 24)); 52 | } 53 | 54 | public boolean nextBoolean (float probability) 55 | { 56 | if (probability < 0.0f || probability > 1.0f) 57 | throw new IllegalArgumentException ("probability must be between 0.0 and 1.0 inclusive."); 58 | if (probability==0.0f) return false; // fix half-open issues 59 | else if (probability==1.0f) return true; // fix half-open issues 60 | return nextFloat() < probability; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /flow/gui/About.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/gui/About.png -------------------------------------------------------------------------------- /flow/gui/BellyButton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/gui/BellyButton.png -------------------------------------------------------------------------------- /flow/gui/BellyButtonPressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/gui/BellyButtonPressed.png -------------------------------------------------------------------------------- /flow/gui/Mac.java: -------------------------------------------------------------------------------- 1 | /*** 2 | Copyright 2017 by Sean Luke 3 | Licensed under the Apache License version 2.0 4 | */ 5 | 6 | package flow.gui; 7 | 8 | import java.lang.reflect.*; 9 | 10 | // Code for handling MacOS X specific About Menus. Maybe also we'll handle Preferences later. 11 | // 12 | // Inspired by https://stackoverflow.com/questions/7256230/in-order-to-macify-a-java-app-to-catch-the-about-event-do-i-have-to-implement 13 | // 14 | // I used the reflection version so it compiles cleanly on linux and windows as well. 15 | 16 | public class Mac 17 | { 18 | public static void setup(Rack rack) 19 | { 20 | if (System.getProperty("os.name").contains("Mac")) 21 | { 22 | System.setProperty("apple.awt.graphics.EnableQ2DX", "true"); 23 | System.setProperty("apple.laf.useScreenMenuBar", "true"); 24 | try 25 | { 26 | java.awt.Desktop.getDesktop().setAboutHandler(new java.awt.desktop.AboutHandler() 27 | { 28 | public void handleAbout(java.awt.desktop.AboutEvent e) 29 | { 30 | AppMenu.doAbout(); 31 | } 32 | }); 33 | } 34 | catch (Exception e) 35 | { 36 | //fail quietly 37 | } 38 | 39 | try 40 | { 41 | Object app = Class.forName("com.apple.eawt.Application").getMethod("getApplication").invoke(null); 42 | 43 | Object al = Proxy.newProxyInstance( 44 | Class.forName("com.apple.eawt.AboutHandler").getClassLoader(), 45 | new Class[]{Class.forName("com.apple.eawt.AboutHandler")}, 46 | new AboutListener(rack)); 47 | 48 | app.getClass().getMethod("setAboutHandler", Class.forName("com.apple.eawt.AboutHandler")).invoke(app, al); 49 | 50 | al = Proxy.newProxyInstance( 51 | Class.forName("com.apple.eawt.QuitHandler").getClassLoader(), 52 | new Class[]{Class.forName("com.apple.eawt.QuitHandler")}, 53 | new QuitListener(rack)); 54 | 55 | app.getClass().getMethod("setQuitHandler", Class.forName("com.apple.eawt.QuitHandler")).invoke(app, al); 56 | } 57 | catch (Exception e) 58 | { 59 | //fail quietly 60 | } 61 | } 62 | } 63 | } 64 | 65 | class AboutListener implements InvocationHandler 66 | { 67 | Rack rack; 68 | public AboutListener(Rack rack) { this.rack = rack; } 69 | public Object invoke(Object proxy, Method method, Object[] args) 70 | { 71 | AppMenu.doAbout(); 72 | return null; 73 | } 74 | } 75 | 76 | class QuitListener implements InvocationHandler 77 | { 78 | Rack rack; 79 | public QuitListener(Rack rack) { this.rack = rack; } 80 | public Object invoke(Object proxy, Method method, Object[] args) 81 | { 82 | rack.doQuit(); 83 | return null; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /flow/gui/ModulationWire.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 by George Mason University 2 | // Licensed under the Apache 2.0 License 3 | 4 | 5 | package flow.gui; 6 | import java.util.*; 7 | 8 | import flow.*; 9 | import java.awt.*; 10 | import java.awt.geom.*; 11 | import javax.swing.border.*; 12 | import javax.swing.*; 13 | import java.awt.event.*; 14 | 15 | /** 16 | Draws the lines which represent wires attaching ModulationOutput jacks to ModulationInput jacks. 17 | */ 18 | 19 | public class ModulationWire 20 | { 21 | ModulationOutput start = null; 22 | ModulationInput end = null; 23 | Rack rack; 24 | 25 | Stroke stroke = new BasicStroke(2.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL, 0, new float[] {2, 2}, 0); 26 | Color color; 27 | 28 | public void setStart(ModulationOutput p) { start = p; } 29 | public ModulationOutput getStart() { return start; } 30 | public void setEnd(ModulationInput p) { end = p; } 31 | public ModulationInput getEnd() { return end; } 32 | 33 | public void chooseColor() 34 | { 35 | color = new Color((int)(Math.random() * 220), (int)(Math.random() * 220), (int)(Math.random() * 220), 175); 36 | } 37 | 38 | public ModulationWire(Rack rack) 39 | { 40 | this.rack = rack; 41 | chooseColor(); 42 | } 43 | 44 | public void draw(Graphics2D g) 45 | { 46 | if (start == null) {System.err.println("ModulationWire: Null Start"); return; } 47 | if (start.jack == null) {System.err.println("ModulationWire: Null StartJack"); return; } 48 | 49 | Rectangle bounds = start.jack.getBounds(); 50 | Point start_p = new Point(bounds.width/2, bounds.height/2); 51 | start_p = SwingUtilities.convertPoint(start.jack, start_p, rack.getWirePaintComponent()); 52 | 53 | Point end_p = null; 54 | if (end == null) 55 | { 56 | end_p = MouseInfo.getPointerInfo().getLocation(); 57 | SwingUtilities.convertPointFromScreen(end_p, start.jack); 58 | } 59 | else 60 | { 61 | bounds = end.dial.getBounds(); 62 | end_p = new Point(bounds.width/2, bounds.height/2); 63 | end_p = SwingUtilities.convertPoint(end.dial, end_p, start.jack); 64 | } 65 | 66 | end_p = SwingUtilities.convertPoint(start.jack, end_p, rack.getWirePaintComponent()); 67 | 68 | g.setStroke(stroke); 69 | g.setColor(color); 70 | Path2D.Double path = new Path2D.Double(); 71 | path.moveTo(start_p.getX(), start_p.getY()); 72 | double diff = Math.abs(start_p.getX() - end_p.getX()); 73 | double midx = (start_p.getX() + end_p.getX()) / 2; 74 | double midY = (start_p.getY() + end_p.getY()) / 2; 75 | path.curveTo(midx, midY + diff / 4, 76 | midx,midY + diff / 4, end_p.getX(), end_p.getY()); 77 | g.draw(path); 78 | 79 | } 80 | 81 | public String toString() { return "ModWire [from=" + start + ", to=" + end + "]"; } 82 | } 83 | -------------------------------------------------------------------------------- /flow/gui/Playing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/gui/Playing.png -------------------------------------------------------------------------------- /flow/gui/Rebuildable.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 by George Mason University 2 | // Licensed under the Apache 2.0 License 3 | 4 | 5 | package flow.gui; 6 | 7 | /** 8 | Indicates a widget which can rebuild itself to reflect underlying changes 9 | in its Modulation or Unit. 10 | */ 11 | 12 | public interface Rebuildable 13 | { 14 | /** Resets the component to reflect the underlying of the synthesizer. */ 15 | public void rebuild(); 16 | } 17 | -------------------------------------------------------------------------------- /flow/gui/Stretch.java: -------------------------------------------------------------------------------- 1 | /*** 2 | Copyright 2017 by Sean Luke 3 | Licensed under the Apache License version 2.0 4 | */ 5 | 6 | package flow.gui; 7 | 8 | import flow.*; 9 | import java.awt.*; 10 | import java.awt.geom.*; 11 | import javax.swing.border.*; 12 | import javax.swing.*; 13 | import java.awt.event.*; 14 | 15 | 16 | /** 17 | A utility class for making simple variable-height or variable-width blobs 18 | 19 | @author Sean Luke 20 | */ 21 | 22 | public class Stretch 23 | { 24 | public static JComponent makeHorizontalStretch() 25 | { 26 | return _makeStretch(Integer.MAX_VALUE, 0); 27 | } 28 | 29 | public static JComponent makeVerticalStretch() 30 | { 31 | return _makeStretch(0, Integer.MAX_VALUE); 32 | } 33 | 34 | public static JComponent makeStretch() 35 | { 36 | return _makeStretch(Integer.MAX_VALUE, Integer.MAX_VALUE); 37 | } 38 | 39 | static JComponent _makeStretch(int horizontal, int vertical) 40 | { 41 | JPanel panel = new JPanel() 42 | { 43 | public Dimension getMinimumSize() { return new Dimension(0, 0); } 44 | public Dimension getPreferredSize() { return new Dimension(0, 0); } 45 | public Dimension getMaximumSize() { return new Dimension(horizontal, vertical); } 46 | }; 47 | panel.setOpaque(false); 48 | return panel; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /flow/gui/Strut.java: -------------------------------------------------------------------------------- 1 | /*** 2 | Copyright 2023 by Sean Luke 3 | Licensed under the Apache License version 2.0 4 | */ 5 | 6 | package flow.gui; 7 | 8 | import flow.*; 9 | import java.awt.*; 10 | import java.awt.geom.*; 11 | import javax.swing.border.*; 12 | import javax.swing.*; 13 | import java.awt.event.*; 14 | 15 | 16 | /** 17 | A utility class for making simple fixed-height or fixed-width blobs 18 | 19 | @author Sean Luke 20 | */ 21 | 22 | public class Strut 23 | { 24 | public static JComponent makeHorizontalStrut(final int space) 25 | { 26 | return makeStrut(space, 0); 27 | } 28 | 29 | public static JComponent makeVerticalStrut(final int space) 30 | { 31 | return makeStrut(0, space); 32 | } 33 | 34 | public static JComponent makeHorizontalStrut(final int space, boolean setBackground) 35 | { 36 | return makeStrut(space, 0, setBackground); 37 | } 38 | 39 | public static JComponent makeVerticalStrut(final int space, boolean setBackground) 40 | { 41 | return makeStrut(0, space, setBackground); 42 | } 43 | 44 | public static JComponent makeStrut(final int width, final int height, boolean setBackground) 45 | { 46 | JPanel panel = new JPanel() 47 | { 48 | public Dimension getMinimumSize() { return new Dimension(width, height); } 49 | public Dimension getPreferredSize() { return new Dimension(width, height); } 50 | public Dimension getMaximumSize() { return new Dimension(width, height); } 51 | }; 52 | if (setBackground) panel.setBackground(Style.BACKGROUND_COLOR()); 53 | return panel; 54 | } 55 | 56 | public static JComponent makeStrut(final int width, final int height) 57 | { 58 | return makeStrut(width, height, true); 59 | } 60 | 61 | public static JComponent makeStrut(Component[] components) 62 | { 63 | return makeStrut(components, false, false); 64 | } 65 | 66 | public static JComponent makeStrut(Component[] components, boolean zeroWidth, boolean zeroHeight) 67 | { 68 | int maxWidth = 0; 69 | int maxHeight = 0; 70 | for(int i = 0; i < components.length; i++) 71 | { 72 | components[i].validate(); 73 | Dimension size = components[i].getPreferredSize(); 74 | if (maxWidth < size.width) 75 | maxWidth = size.width; 76 | if (maxHeight < size.height) 77 | maxHeight = size.height; 78 | } 79 | return makeStrut((zeroWidth ? 0 : maxWidth), (zeroHeight ? 0 : maxHeight)); 80 | } 81 | 82 | public static JComponent makeStrut(Component[] components, boolean zeroWidth) 83 | { 84 | return makeStrut(components, zeroWidth, !zeroWidth); 85 | } 86 | 87 | public static JComponent makeStrut(Component component, boolean zeroWidth, boolean zeroHeight) 88 | { 89 | return makeStrut(new Component[] { component }, zeroWidth, zeroHeight); 90 | } 91 | 92 | public static JComponent makeStrut(Component component, boolean zeroWidth) 93 | { 94 | return makeStrut(new Component[] { component }, zeroWidth, !zeroWidth); 95 | } 96 | 97 | public static JComponent makeStrut(Component component) 98 | { 99 | return makeStrut(new Component[] { component }); 100 | } 101 | 102 | public static JComponent makeHorizontalStrut(Component component) 103 | { 104 | return makeStrut(new Component[] { component }, false, true); 105 | } 106 | 107 | public static JComponent makeVerticalStrut(Component component) 108 | { 109 | return makeStrut(new Component[] { component }, true, false); 110 | } 111 | 112 | } 113 | -------------------------------------------------------------------------------- /flow/gui/Style.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 by George Mason University 2 | // Licensed under the Apache 2.0 License 3 | 4 | 5 | package flow.gui; 6 | 7 | import flow.*; 8 | import java.awt.*; 9 | import java.awt.geom.*; 10 | import javax.swing.border.*; 11 | import javax.swing.*; 12 | 13 | /** 14 | A collection of GUI style constants. 15 | */ 16 | 17 | public class Style 18 | { 19 | public final static Color UNIT_COLOR = Color.BLUE; 20 | public final static Color MOD_COLOR = Color.BLACK; 21 | 22 | /////// GLOBAL CONSTANTS 23 | 24 | /** Background color */ 25 | public final static Color DEFAULT_BACKGROUND_COLOR = Color.BLACK; 26 | static Color BACKGROUND_COLOR = DEFAULT_BACKGROUND_COLOR; 27 | public static Color BACKGROUND_COLOR() { return BACKGROUND_COLOR; } 28 | /** Text color */ 29 | public final static Color DEFAULT_TEXT_COLOR = Color.WHITE; 30 | static Color TEXT_COLOR = DEFAULT_TEXT_COLOR; 31 | public static Color TEXT_COLOR() { return TEXT_COLOR; } 32 | /** Small font, primarily for labels, button and combo box text. */ 33 | public static Font SMALL_FONT() { return new Font(Font.SANS_SERIF, Font.PLAIN, isUnix() ? 9 : 10); } 34 | public static Color DEFAULT_DYNAMIC_COLOR = Color.RED; 35 | static Color DYNAMIC_COLOR = DEFAULT_DYNAMIC_COLOR; 36 | public static Color DYNAMIC_COLOR() { return DYNAMIC_COLOR; } 37 | 38 | /** Width of the set region in Dials etc. Should be a multiple of 2, ideally 4*/ 39 | public static float DIAL_STROKE_WIDTH() { return 4.0f; } 40 | /** Width of the dial **/ 41 | public static int LABELLED_DIAL_WIDTH() { return 20; } 42 | /** Color of the set region in Dials etc. when being updated. */ 43 | public static Color DIAL_DYNAMIC_COLOR() { return DYNAMIC_COLOR(); } 44 | /** The stroke for the set region in Dials etc. */ 45 | public static BasicStroke DIAL_THIN_STROKE() { return new BasicStroke(DIAL_STROKE_WIDTH() / 2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL); } 46 | /** The stroke for the unset region in Dials etc. */ 47 | public static BasicStroke DIAL_THICK_STROKE() { return new BasicStroke(DIAL_STROKE_WIDTH(), BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL); } 48 | 49 | /////// KEYBOARD CONSTANTS 50 | public static Color KEYBOARD_WHITE_COLOR() { return Color.WHITE; } 51 | public static Color KEYBOARD_BLACK_COLOR() { return Color.BLACK; } 52 | public static Color KEYBOARD_DYNAMIC_COLOR() { return DYNAMIC_COLOR(); } 53 | public static int KEYBOARD_DEFAULT_WHITE_KEY_WIDTH() { return 12; } 54 | public static int KEYBOARD_DEFAULT_WHITE_KEY_HEIGHT() { return 48; } 55 | 56 | 57 | /////// GRAPHICS PREPARATION 58 | 59 | /** Updates the graphics rendering hints before drawing. Called by a few widgets. */ 60 | public static void prepareGraphics(Graphics g) 61 | { 62 | Graphics2D graphics = (Graphics2D) g; 63 | graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 64 | graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); 65 | graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); 66 | } 67 | 68 | 69 | /////// OS DISTINGUISHING PROCEDURES 70 | 71 | private static String OS() { return System.getProperty("os.name").toLowerCase(); } 72 | 73 | public static boolean isWindows() 74 | { 75 | return (OS().indexOf("win") >= 0); 76 | } 77 | 78 | public static boolean isMac() 79 | { 80 | return (OS().indexOf("mac") >= 0 || System.getProperty("mrj.version") != null); 81 | } 82 | 83 | public static boolean isUnix() 84 | { 85 | return (OS().indexOf("nix") >= 0 || OS().indexOf("nux") >= 0 || OS().indexOf("aix") > 0 ); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /flow/gui/UnitWire.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 by George Mason University 2 | // Licensed under the Apache 2.0 License 3 | 4 | 5 | package flow.gui; 6 | import java.util.*; 7 | 8 | import flow.*; 9 | import java.awt.*; 10 | import java.awt.geom.*; 11 | import javax.swing.border.*; 12 | import javax.swing.*; 13 | import java.awt.event.*; 14 | 15 | 16 | /** 17 | Draws the lines which represent wires attaching UnitOutput jacks to UnitInput jacks. 18 | */ 19 | 20 | public class UnitWire 21 | { 22 | UnitOutput start = null; 23 | UnitInput end = null; 24 | Rack rack; 25 | 26 | Stroke stroke = new BasicStroke(4.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL, 0, new float[] { 1 }, 0); 27 | Color color; 28 | 29 | public void setStart(UnitOutput p) { start = p; } 30 | public UnitOutput getStart() { return start; } 31 | public void setEnd(UnitInput p) { end = p; } 32 | public UnitInput getEnd() { return end; } 33 | 34 | public void chooseColor() 35 | { 36 | color = new Color((int)(Math.random() * 220), (int)(Math.random() * 220), (int)(Math.random() * 220), 175); 37 | } 38 | 39 | public UnitWire(Rack rack) 40 | { 41 | this.rack = rack; 42 | chooseColor(); 43 | } 44 | 45 | public void draw(Graphics2D g) 46 | { 47 | if (start == null) {System.err.println("UnitWire: Null Start"); return; } 48 | if (start.jack == null) {System.err.println("UnitWire: Null StartJack"); return; } 49 | 50 | Rectangle bounds = start.jack.getBounds(); 51 | Point start_p = new Point(bounds.width/2, bounds.height/2); 52 | start_p = SwingUtilities.convertPoint(start.jack, start_p, rack.getWirePaintComponent()); 53 | 54 | Point end_p = null; 55 | if (end == null) 56 | { 57 | end_p = MouseInfo.getPointerInfo().getLocation(); 58 | SwingUtilities.convertPointFromScreen(end_p, start.jack); 59 | } 60 | else 61 | { 62 | bounds = end.jack.getBounds(); 63 | end_p = new Point(bounds.width/2, bounds.height/2); 64 | end_p = SwingUtilities.convertPoint(end.jack, end_p, start.jack); 65 | } 66 | 67 | end_p = SwingUtilities.convertPoint(start.jack, end_p, rack.getWirePaintComponent()); 68 | 69 | g.setStroke(stroke); 70 | g.setColor(color); 71 | Path2D.Double path = new Path2D.Double(); 72 | path.moveTo(start_p.getX(), start_p.getY()); 73 | double diff = Math.abs(start_p.getX() - end_p.getX()); 74 | double midx = (start_p.getX() + end_p.getX()) / 2; 75 | double midY = (start_p.getY() + end_p.getY()) / 2; 76 | path.curveTo(midx, midY + diff / 4, 77 | midx,midY + diff / 4, end_p.getX(), end_p.getY()); 78 | g.draw(path); 79 | } 80 | 81 | public String toString() { return "UnitWire [from=" + start + ", to=" + end + "]"; } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /flow/gui/WidgetList.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 by George Mason University 2 | // Licensed under the Apache 2.0 License 3 | 4 | 5 | package flow.gui; 6 | import java.awt.*; 7 | import javax.swing.*; 8 | 9 | /** 10 | A simple JComponent which holds a collection of JComponents (the widgets) 11 | and displays them with associated labels. 12 | */ 13 | 14 | public class WidgetList extends JPanel 15 | { 16 | public WidgetList(String[] labels, JComponent[] widgets) 17 | { 18 | int max = 0; 19 | JLabel[] jlabels = new JLabel[labels.length]; 20 | for(int i = 0; i < labels.length; i++) 21 | { 22 | jlabels[i] = new JLabel(labels[i] + " ", SwingConstants.RIGHT); 23 | int width = (int)(jlabels[i].getPreferredSize().getWidth()); 24 | if (width > max) max = width; 25 | } 26 | 27 | Box vbox = new Box(BoxLayout.Y_AXIS); 28 | for(int i = 0; i < labels.length; i++) 29 | { 30 | jlabels[i].setPreferredSize(new Dimension( 31 | max, (int)(jlabels[i].getPreferredSize().getHeight()))); 32 | jlabels[i].setMinimumSize(jlabels[i].getPreferredSize()); 33 | // for some reason this has to be set as well 34 | jlabels[i].setMaximumSize(jlabels[i].getPreferredSize()); 35 | Box hbox = new Box(BoxLayout.X_AXIS); 36 | hbox.add(jlabels[i]); 37 | hbox.add(widgets[i]); 38 | vbox.add(hbox); 39 | } 40 | 41 | setLayout(new BorderLayout()); 42 | add(vbox, BorderLayout.SOUTH); 43 | } 44 | } 45 | 46 | -------------------------------------------------------------------------------- /flow/modules/Alias.java: -------------------------------------------------------------------------------- 1 | // Copyright 2021 by George Mason University 2 | // Licensed under the Apache 2.0 License 3 | 4 | 5 | package flow.modules; 6 | import flow.gui.*; 7 | import java.awt.*; 8 | import javax.swing.*; 9 | 10 | import flow.*; 11 | 12 | /** 13 | An Alias or Foldover generator. 14 | */ 15 | 16 | public class Alias extends Unit 17 | { 18 | private static final long serialVersionUID = 1; 19 | 20 | public static final int MOD_CUTOFF = 0; 21 | public static final double MINIMUM_FREQUENCY = 0.000001; // seems reasonable 22 | 23 | public Alias(Sound sound) 24 | { 25 | super(sound); 26 | defineInputs( new Unit[] { Unit.NIL }, new String[] { "Input" }); 27 | defineModulations(new Constant[] { Constant.ONE }, new String[] { "Cutoff" }); 28 | } 29 | 30 | public double fold(double val, double cutoff) 31 | { 32 | double v = val / cutoff; 33 | int times = (int)v; 34 | double frac = v - times; 35 | if (times % 2 == 1) frac = 1.0 - frac; 36 | return frac * cutoff; 37 | } 38 | 39 | public void go() 40 | { 41 | super.go(); 42 | 43 | pushAmplitudes(0); 44 | copyFrequencies(0); 45 | 46 | double[] amplitudes = getAmplitudes(0); 47 | double[] frequencies = getFrequencies(0); 48 | double pitch = sound.getPitch(); 49 | 50 | double cutoff = modToFrequency(makeVeryInsensitive(modulate(MOD_CUTOFF))); // Note that this is in angular frequency, but we don't divide by 2 PI to get Hertz because that's done at the end of the day when we add up the sine waves 51 | if (cutoff < MINIMUM_FREQUENCY) cutoff = MINIMUM_FREQUENCY; // so we're never 0 52 | 53 | for(int i = 0; i < frequencies.length; i++) 54 | { 55 | frequencies[i] = fold(frequencies[i] * pitch, cutoff) / pitch; 56 | } 57 | 58 | constrain(); 59 | } 60 | 61 | 62 | public String getModulationValueDescription(int modulation, double value, boolean isConstant) 63 | { 64 | if (isConstant) 65 | { 66 | if (modulation == MOD_CUTOFF) 67 | { 68 | return String.format("%.4f", modToFrequency(makeVeryInsensitive(value))); 69 | } 70 | else return ""; 71 | } 72 | else return ""; 73 | } 74 | 75 | public static String getName() { return "Alias"; } 76 | } 77 | -------------------------------------------------------------------------------- /flow/modules/All.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 by George Mason University 2 | // Licensed under the Apache 2.0 License 3 | 4 | 5 | package flow.modules; 6 | 7 | import flow.*; 8 | 9 | /** 10 | A Unit which provides all partials at 1.0 amplitude, 11 | with standardized frequencies. 12 | */ 13 | 14 | public class All extends Unit implements UnitSource 15 | { 16 | private static final long serialVersionUID = 1; 17 | 18 | public All(Sound sound) 19 | { 20 | super(sound); 21 | 22 | double[] amplitudes = getAmplitudes(0); 23 | 24 | setClearOnReset(false); 25 | for(int i = 0; i < amplitudes.length; i++) 26 | { 27 | amplitudes[i] = 0.25; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /flow/modules/AudioIn.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 by George Mason University 2 | // Licensed under the Apache 2.0 License 3 | 4 | 5 | package flow.modules; 6 | 7 | import flow.*; 8 | 9 | /** 10 | A Unit which provides partials for a Sawtooth Wave. 11 | */ 12 | 13 | public class AudioIn extends Unit implements UnitSource 14 | { 15 | private static final long serialVersionUID = 1; 16 | 17 | public static final double MAX_GAIN = 4; 18 | public static final int MOD_GAIN = 0; 19 | 20 | public AudioIn(Sound sound) 21 | { 22 | super(sound); 23 | defineModulations(new Constant[] { new Constant(1.0 / MAX_GAIN) }, new String[] { "Gain" }); 24 | } 25 | 26 | public void go() 27 | { 28 | super.go(); 29 | double[] amplitudes = getAmplitudes(0); 30 | sound.getOutput().getAudioInput().getAmplitudes(amplitudes); 31 | double mod = modulate(MOD_GAIN) * MAX_GAIN; 32 | for(int i = 0; i < amplitudes.length; i++) 33 | amplitudes[i] *= mod; 34 | } 35 | 36 | public static String getName() { return "Audio In"; } 37 | 38 | public String getModulationValueDescription(int modulation, double value, boolean isConstant) 39 | { 40 | if (isConstant) 41 | { 42 | if (modulation == MOD_GAIN) 43 | { 44 | return String.format("%.4f", (value * MAX_GAIN)); 45 | } 46 | else return super.getModulationValueDescription(modulation, value, isConstant); 47 | } 48 | else return ""; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /flow/modules/BellyButton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/modules/BellyButton.png -------------------------------------------------------------------------------- /flow/modules/BellyButtonPressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/modules/BellyButtonPressed.png -------------------------------------------------------------------------------- /flow/modules/Buffer.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 by George Mason University 2 | // Licensed under the Apache 2.0 License 3 | 4 | 5 | package flow.modules; 6 | 7 | import flow.*; 8 | 9 | /** 10 | A Unit which does a kind of sample-and-hold on an incoming set of partials. Specifically 11 | when it receives a TRIGGER, it samples the partials from its input source and only 12 | outputs those partials. If FREE is FALSE, then it also samples on gate. It always samples 13 | on reset. You can kind of think of Buffer as the counterpart to Smooth: it's an unsmoother. 14 | */ 15 | 16 | public class Buffer extends Unit 17 | { 18 | private static final long serialVersionUID = 1; 19 | 20 | public static final int MOD_TRIGGER = 0; 21 | 22 | boolean free; 23 | boolean start; 24 | boolean reset; 25 | double[] bufferedAmplitudes = new double[NUM_PARTIALS]; 26 | double[] bufferedFrequencies = new double[NUM_PARTIALS]; 27 | 28 | public static final int OPTION_FREE = 0; 29 | 30 | public int getOptionValue(int option) 31 | { 32 | switch(option) 33 | { 34 | case OPTION_FREE: return getFree() ? 1 : 0; 35 | default: throw new RuntimeException("No such option " + option); 36 | } 37 | } 38 | 39 | public void setOptionValue(int option, int value) 40 | { 41 | switch(option) 42 | { 43 | case OPTION_FREE: setFree(value != 0); return; 44 | default: throw new RuntimeException("No such option " + option); 45 | } 46 | } 47 | 48 | 49 | public boolean getFree() { return free; } 50 | public void setFree(boolean free) { this.free = free; } 51 | 52 | public Object clone() 53 | { 54 | Buffer obj = (Buffer)(super.clone()); 55 | obj.bufferedAmplitudes = (double[])(obj.bufferedAmplitudes.clone()); 56 | obj.bufferedFrequencies = (double[])(obj.bufferedFrequencies.clone()); 57 | return obj; 58 | } 59 | 60 | public Buffer(Sound sound) 61 | { 62 | super(sound); 63 | defineInputs( new Unit[] { Unit.NIL }, new String[] { "Input" }); 64 | defineModulations(new Constant[] { Constant.ONE }, new String[] { "Trigger" }); 65 | defineOptions(new String[] { "Free" }, new String[][] { { "Free" } } ); 66 | setFree(false); 67 | start = true; 68 | } 69 | 70 | public void reset() 71 | { 72 | super.reset(); 73 | start = true; 74 | } 75 | 76 | public void gate() 77 | { 78 | super.gate(); 79 | if (!free) start = true; 80 | } 81 | 82 | public void go() 83 | { 84 | super.go(); 85 | 86 | double[] amplitudesIn = getAmplitudesIn(0); 87 | double[] frequenciesIn = getFrequenciesIn(0); 88 | 89 | modulate(MOD_TRIGGER); 90 | if (start || isTriggered(MOD_TRIGGER)) 91 | { 92 | System.arraycopy(amplitudesIn, 0, bufferedAmplitudes, 0, amplitudesIn.length); 93 | System.arraycopy(frequenciesIn, 0, bufferedFrequencies, 0, frequenciesIn.length); 94 | start = false; 95 | reset = true; 96 | } 97 | 98 | if (reset) 99 | { 100 | System.arraycopy(bufferedAmplitudes, 0, getAmplitudes(0), 0, bufferedAmplitudes.length); 101 | System.arraycopy(bufferedFrequencies, 0, getFrequencies(0), 0, bufferedFrequencies.length); 102 | } 103 | 104 | reset = constrain(); 105 | if (reset) simpleSort(0, false); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /flow/modules/Compress.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 by George Mason University 2 | // Licensed under the Apache 2.0 License 3 | 4 | 5 | package flow.modules; 6 | 7 | import flow.*; 8 | 9 | /** 10 | A Unit which compresses or expands its input -- that is, either squeezes its amplitudes all towards 1.0 11 | or pushes them all away from 1.0. The squeezing/expanding is exponential, and the degree is 12 | specified by SCALE. Compression occurs when SCALE is greater than 0.5; expansion occurs when SCALE 13 | is less than 0.5. 14 | */ 15 | 16 | 17 | public class Compress extends Unit 18 | { 19 | private static final long serialVersionUID = 1; 20 | 21 | double lastModulation = Double.NaN; 22 | double[] lastAmps; 23 | 24 | public static final int MOD_SCALE = 0; 25 | 26 | public Object clone() 27 | { 28 | Compress obj = (Compress)(super.clone()); 29 | obj.lastAmps = (double[])(obj.lastAmps.clone()); 30 | return obj; 31 | } 32 | 33 | public Compress(Sound sound) 34 | { 35 | super(sound); 36 | defineInputs( new Unit[] { Unit.NIL }, new String[] { "Input" }); 37 | defineModulations(new Constant[] { Constant.HALF }, new String[] { "Scale" }); 38 | lastAmps = new double[NUM_PARTIALS]; 39 | } 40 | 41 | public void go() 42 | { 43 | super.gate(); 44 | 45 | // we don't copy the amplitudes 46 | pushFrequencies(0); 47 | 48 | double[] amplitudes = getAmplitudes(0); 49 | 50 | double mod = 1.0 - modulate(MOD_SCALE); 51 | if (mod >= 0.5) mod = (mod - 0.5) * 8 + 1; 52 | else mod = 1.0 / ((0.5 - mod) * 8 + 1); 53 | 54 | // mod now ranges from 0.2 to 1.0 to 5.0 55 | 56 | double[] amps = getAmplitudesIn(0); 57 | 58 | for(int i = 0; i < amplitudes.length; i++) 59 | { 60 | if (lastModulation != mod || amps[i] != lastAmps[i]) 61 | { 62 | amplitudes[i] = Utility.hybridpow(amps[i], mod); 63 | lastAmps[i] = amplitudes[i]; 64 | } 65 | else 66 | amplitudes[i] = lastAmps[i]; 67 | } 68 | lastModulation = mod; 69 | 70 | constrain(); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /flow/modules/ConvertWav.java: -------------------------------------------------------------------------------- 1 | package flow.modules; 2 | import flow.utilities.*; 3 | import java.io.*; 4 | 5 | public class ConvertWav 6 | { 7 | public static final int MAXIMUM_SAMPLES = 4096; 8 | public static final int WINDOW_SIZE = 65; 9 | public static final double MINIMUM_AMPLITUDE = 0.001; 10 | 11 | public static void main(String[] args) throws Exception 12 | { 13 | 14 | double[] waves = null; 15 | double[] buffer = new double[256]; 16 | int count = 0; 17 | 18 | File file = new File(args[0]); 19 | WavFile wavFile = null; 20 | double[] _waves = new double[MAXIMUM_SAMPLES]; 21 | wavFile = WavFile.openWavFile(file); 22 | 23 | while(true) 24 | { 25 | // Read frames into buffer 26 | int framesRead = wavFile.readFrames(buffer, buffer.length); 27 | if (count + framesRead > MAXIMUM_SAMPLES) 28 | { 29 | System.err.println("File Too Large"); 30 | System.exit(1); 31 | } 32 | System.arraycopy(buffer, 0, _waves, count, framesRead); 33 | count += framesRead; 34 | if (framesRead < buffer.length) 35 | break; 36 | } 37 | waves = new double[count]; 38 | System.arraycopy(_waves, 0, waves, 0, count); 39 | wavFile.close(); 40 | 41 | int desiredSampleSize = 512; // because we have up to 256 samples 42 | int currentSampleSize = waves.length; 43 | 44 | /// Resample to Flow's sampling rate 45 | double[] newvals = WindowedSinc.interpolate( 46 | waves, 47 | currentSampleSize, 48 | desiredSampleSize, // notice desired and current are swapped -- because these are SIZES, not RATES 49 | WINDOW_SIZE, 50 | true); 51 | 52 | // Note no window. Should still be okay (I think?) 53 | double[] harmonics = FFT.getHarmonics(newvals); 54 | double[] finished = new double[harmonics.length / 2]; // must be 256 55 | for (int s=1 ; s < harmonics.length / 2; s++) // we skip the DC offset (0) and set the Nyquist frequency bin (harmonics.length / 2) to 0 56 | { 57 | finished[s - 1] = (harmonics[s] >= MINIMUM_AMPLITUDE ? harmonics[s] : 0 ); 58 | } 59 | 60 | double max = 0; 61 | for(int i = 0; i < finished.length; i++) 62 | { 63 | if (max < finished[i]) 64 | max = finished[i]; 65 | } 66 | 67 | if (max > 0) 68 | { 69 | for(int i = 0; i < finished.length; i++) 70 | { 71 | finished[i] /= max; 72 | } 73 | } 74 | String name = file.getName(); 75 | name = name.substring(0, name.length() - 4); // .wav 76 | System.out.println(name); 77 | for(int i = 0; i < finished.length; i++) 78 | { 79 | int val = (int)(finished[i] * (999 + 10) - 10); 80 | if (val < 0) val = 0; 81 | System.out.print("" + val + " "); 82 | } 83 | System.out.println(); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /flow/modules/EitherOr.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 by George Mason University 2 | // Licensed under the Apache 2.0 License 3 | 4 | 5 | package flow.modules; 6 | 7 | import flow.*; 8 | import flow.gui.*; 9 | 10 | public class EitherOr extends Modulation 11 | { 12 | private static final long serialVersionUID = 1; 13 | 14 | public static String getName() { return "Either/Or"; } 15 | 16 | public static final int MAX_OPTIONS = 4; 17 | 18 | public static final int MOD_INPUT = 0; 19 | public static final int MOD_YES = 1; 20 | public static final int MOD_NO = 2; 21 | public static final int MOD_NUM_OPTIONS = 3; 22 | 23 | int choice = -1; 24 | int numOptions = -1; 25 | 26 | public EitherOr(Sound sound) 27 | { 28 | super(sound); 29 | defineModulations(new Constant[] { Constant.ZERO, Constant.ONE, Constant.ZERO, Constant.ZERO }, new String[] { "Choice", "Yes", "No", "Options" }); 30 | defineModulationOutputs(new String[] { "1", "2", "3", "4" }); 31 | } 32 | 33 | int discretize(double val, int num) 34 | { 35 | int v = (int)(val * num); 36 | if (val == 1.0) return v - 1; 37 | else return v; 38 | } 39 | 40 | public void go() 41 | { 42 | super.go(); 43 | 44 | int _numOptions = discretize(modulate(MOD_NUM_OPTIONS), MAX_OPTIONS - 1) + 2; 45 | if (_numOptions != numOptions) 46 | { 47 | numOptions = _numOptions; 48 | double noMod = modulate(MOD_NO); 49 | for(int i = 0; i < getNumModulationOutputs(); i++) 50 | { 51 | setModulationOutput(i, noMod); 52 | } 53 | choice = -1; // need to reset it all 54 | } 55 | 56 | int _choice = discretize(modulate(MOD_INPUT), numOptions); 57 | 58 | if (_choice != choice) 59 | { 60 | choice = _choice; 61 | double yesMod = modulate(MOD_YES); 62 | double noMod = modulate(MOD_NO); 63 | 64 | for(int i = 0; i < getNumModulationOutputs(); i++) 65 | { 66 | setModulationOutput(i, noMod); 67 | } 68 | setModulationOutput(_choice, yesMod); 69 | } 70 | 71 | } 72 | 73 | public String getModulationValueDescription(int modulation, double value, boolean isConstant) 74 | { 75 | if (isConstant) 76 | { 77 | if (modulation == MOD_NUM_OPTIONS) 78 | { 79 | return "" + (discretize(value, MAX_OPTIONS - 1) + 2); 80 | } 81 | else if (modulation == MOD_INPUT) 82 | { 83 | return "" + (discretize(value, numOptions) + 1); 84 | } 85 | else return super.getModulationValueDescription(modulation, value, isConstant); 86 | } 87 | else return ""; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /flow/modules/Fill.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 by George Mason University 2 | // Licensed under the Apache 2.0 License 3 | 4 | 5 | package flow.modules; 6 | 7 | import flow.*; 8 | 9 | /** 10 | A Unit which takes two incoming sources, A and B, and produces a mixed source by including all 11 | non-zero amplitude partials from A, and then replacing the zero-amplitude partials with the 12 | lowest non-zero partials from B. 13 | */ 14 | 15 | public class Fill extends Unit 16 | { 17 | private static final long serialVersionUID = 1; 18 | 19 | public static final int UNIT_INPUT_A = 0; 20 | public static final int UNIT_INPUT_B = 1; 21 | 22 | public static final int MOD_SCALE_A = 0; 23 | public static final int MOD_SCALE_B = 1; 24 | 25 | // Mixes the harmonics of up to four units, using the frequencies of the first unit 26 | 27 | public Fill(Sound sound) 28 | { 29 | super(sound); 30 | defineInputs( new Unit[] { Unit.NIL, Unit.NIL }, new String[] { "Input A", "Input B" }); 31 | defineModulations(new Constant[] { Constant.ONE, Constant.ONE }, new String[] { "Scale A", "Scale B" }); 32 | } 33 | 34 | public void go() 35 | { 36 | super.go(); 37 | 38 | copyFrequencies(0); 39 | copyAmplitudes(0); 40 | 41 | double[] amplitudes = getAmplitudes(0); // INPUT_A was copied over 42 | double[] frequencies = getFrequencies(0); // INPUT_A was copied over 43 | double[] amp2 = getAmplitudesIn(UNIT_INPUT_B); 44 | double[] freq2 = getFrequenciesIn(UNIT_INPUT_B); 45 | double scaleA = modulate(MOD_SCALE_A); 46 | double scaleB = modulate(MOD_SCALE_B); 47 | 48 | 49 | int i2 = 0; 50 | for(int i = 0; i < amplitudes.length; i++) 51 | { 52 | if (amplitudes[i] == 0) // fill it 53 | { 54 | for( ; i2 < amplitudes.length; i2++) 55 | { 56 | if (amp2[i2] != 0) 57 | { 58 | amplitudes[i] = amp2[i2] * scaleB; 59 | frequencies[i] = freq2[i2]; 60 | break; 61 | } 62 | } 63 | i2++; 64 | } 65 | else 66 | { 67 | amplitudes[i] *= scaleA; 68 | } 69 | } 70 | 71 | simpleSort(0, false); 72 | } 73 | 74 | public boolean isConstrainable() { return false; } 75 | } 76 | -------------------------------------------------------------------------------- /flow/modules/Fix.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 by George Mason University 2 | // Licensed under the Apache 2.0 License 3 | 4 | 5 | package flow.modules; 6 | 7 | import flow.*; 8 | import flow.gui.*; 9 | import org.json.*; 10 | 11 | /** 12 | A module which works with the Macro facility to route 13 | higher-level partials and modulations to your patch as 14 | unit and modulation outputs. All eight unit and modulation 15 | outputs can be custom named by clicking on their labels. 16 | */ 17 | 18 | 19 | public class Fix extends Modulation implements Miscellaneous 20 | { 21 | private static final long serialVersionUID = 1; 22 | 23 | public static final int MOD_NOTE = 0; 24 | public static final int MOD_VELOCTY = 1; 25 | 26 | boolean started = false; 27 | 28 | public Fix(Sound sound) 29 | { 30 | super(sound); 31 | defineModulationOutputs(new String[] { }); 32 | defineModulations(new Constant[] { Constant.HALF, Constant.ONE }, 33 | new String[] { "Note", "Velocity" }); 34 | } 35 | 36 | int lastNoteCounter = -1; 37 | int lastNote = -1; 38 | public void go() 39 | { 40 | super.go(); 41 | int note = (int)(modulate(MOD_NOTE) * 128) - 1; 42 | if (note > -1) // off 43 | { 44 | int nc = sound.getNoteCounter(); 45 | if (lastNote != note || lastNoteCounter != nc) 46 | { 47 | sound.setNote(Math.pow(2.0, (double) (note - 69) / 12.0) * 440.0); 48 | lastNote = note; 49 | lastNoteCounter = nc; 50 | } 51 | } 52 | 53 | double vel = modulate(MOD_VELOCTY); 54 | if (vel > 0) 55 | { 56 | sound.setVelocity(vel); 57 | } 58 | } 59 | 60 | public static final String[] notes = new String[] { "C", "Db", "D", "Eb", "E", "F", "Gb", "G", "Ab", "A", "Bb", "B" }; 61 | public String getModulationValueDescription(int modulation, double value, boolean isConstant) 62 | { 63 | if (isConstant) 64 | { 65 | if (modulation == MOD_NOTE) // rate 66 | { 67 | int note = (int)(value * 128) - 1; 68 | if (note == -1) 69 | return "Free"; 70 | else 71 | { 72 | return notes[note % 12] + (note / 12); 73 | } 74 | } 75 | else if (modulation == MOD_VELOCTY) // rate 76 | { 77 | if (value == 0.0) 78 | return "Free"; 79 | else 80 | return String.format("%.4f", value); 81 | } 82 | } 83 | return ""; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /flow/modules/Latch.java: -------------------------------------------------------------------------------- 1 | // Copyright 2024 by Sean Luke 2 | // Licensed under the Apache 2.0 License 3 | 4 | 5 | package flow.modules; 6 | import flow.gui.*; 7 | import java.awt.*; 8 | import javax.swing.*; 9 | 10 | import flow.*; 11 | 12 | public class Latch extends Unit 13 | { 14 | private static final long serialVersionUID = 1; 15 | 16 | public static final int MOD_TRIGGER = 0; 17 | public static final int MOD_SELECT_INITIAL = 1; 18 | public static final int MOD_SELECT_IN = 2; 19 | public static final int NUM_INITIALS = 4; 20 | public static final int NUM_INS = 4; 21 | 22 | boolean trigger = false; 23 | 24 | public Latch(Sound sound) 25 | { 26 | super(sound); 27 | defineInputs( new Unit[] { Unit.NIL, Unit.NIL, Unit.NIL, Unit.NIL, Unit.NIL, Unit.NIL, Unit.NIL, Unit.NIL }, new String[] { "Initial 1", "Initial 2", "Initial 3", "Initial 4", "Later 1", "Later 2", "Later 3", "Later 4" }); 28 | defineModulations(new Constant[] { Constant.ZERO, Constant.ZERO, Constant.ZERO }, new String[] { "Trigger", "Sel Initial", "Sel Later" }); 29 | } 30 | 31 | public void gate() 32 | { 33 | super.gate(); 34 | if (isModulationConstant(MOD_TRIGGER)) 35 | { 36 | trigger = true; 37 | } 38 | } 39 | 40 | public void go() 41 | { 42 | super.go(); 43 | 44 | if (trigger || isTriggered(MOD_TRIGGER)) 45 | { 46 | int val = (int)(modulate(MOD_SELECT_INITIAL) * NUM_INITIALS); // 0...4 47 | if (val == NUM_INITIALS) val = NUM_INITIALS - 1; // 0...3 48 | copyFrequencies(val); 49 | copyAmplitudes(val); 50 | trigger = false; 51 | } 52 | else 53 | { 54 | int val = (int)(modulate(MOD_SELECT_IN) * NUM_INS + NUM_INITIALS); // 4...8 55 | if (val == NUM_INITIALS + NUM_INS) val = NUM_INITIALS + NUM_INS - 1; // 4...7 56 | copyFrequencies(val); 57 | copyAmplitudes(val); 58 | } 59 | constrain(); // is this useful? 60 | } 61 | 62 | public static String getName() { return "Latch"; } 63 | 64 | public String getModulationValueDescription(int modulation, double value, boolean isConstant) 65 | { 66 | if (isConstant) 67 | { 68 | if (modulation == MOD_TRIGGER) 69 | { 70 | return super.getModulationValueDescription(modulation, value, isConstant); 71 | } 72 | else 73 | { 74 | int d = (int)(value * NUM_INS); 75 | if (d == NUM_INS) d = NUM_INS - 1; 76 | d += 1; 77 | return String.valueOf(d); 78 | } 79 | } 80 | else return ""; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /flow/modules/LeftArrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/modules/LeftArrow.png -------------------------------------------------------------------------------- /flow/modules/LeftArrowPressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/modules/LeftArrowPressed.png -------------------------------------------------------------------------------- /flow/modules/Patch.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 by George Mason University 2 | // Licensed under the Apache 2.0 License 3 | 4 | 5 | package flow.modules; 6 | 7 | import flow.*; 8 | import flow.gui.*; 9 | import java.awt.*; 10 | import javax.swing.*; 11 | 12 | /** 13 | */ 14 | 15 | public class Patch extends Unit implements Miscellaneous 16 | { 17 | private static final long serialVersionUID = 1; 18 | 19 | public static final int NUM_MODULATIONS = 8; 20 | public static final int NUM_UNITS = 8; 21 | 22 | public Patch(Sound sound) 23 | { 24 | super(sound); 25 | defineInputs( new Unit[] { Unit.NIL, Unit.NIL, Unit.NIL, Unit.NIL, Unit.NIL, Unit.NIL, Unit.NIL, Unit.NIL }, new String[] { "A", "B", "C", "D", "E", "F", "G", "H" }); 26 | defineModulations(new Constant[] { Constant.ZERO, Constant.ZERO, Constant.ZERO, Constant.ZERO, Constant.ZERO, Constant.ZERO, Constant.ZERO, Constant.ZERO }, new String[] { "1", "2", "3", "4", "5", "6", "7", "8" }); 27 | defineOutputs(new String[] { "A", "B", "C", "D", "E", "F", "G", "H" }); 28 | defineModulationOutputs(new String[] { "1", "2", "3", "4", "5", "6", "7", "8" }); 29 | } 30 | 31 | public void go() 32 | { 33 | super.go(); 34 | 35 | for(int i = 0; i < NUM_UNITS; i++) 36 | { 37 | pushFrequencies(i, i); 38 | pushAmplitudes(i, i); 39 | } 40 | 41 | for(int i = 0; i < NUM_MODULATIONS; i++) 42 | { 43 | setModulationOutput(i, modulate(i)); 44 | } 45 | } 46 | 47 | public boolean isConstrainable() { return false; } 48 | 49 | public ModulePanel getPanel() 50 | { 51 | return new ModulePanel(Patch.this) 52 | { 53 | public JComponent buildPanel() 54 | { 55 | Modulation mod = getModulation(); 56 | 57 | Box box = new Box(BoxLayout.Y_AXIS); 58 | 59 | for(int i = 0; i < NUM_UNITS; i++) 60 | { 61 | final int _i = i; 62 | 63 | Box hbox = new Box(BoxLayout.X_AXIS); 64 | UnitOutput output = new UnitOutput((Unit)mod, i, this); 65 | output.setTitleText("", false); 66 | UnitInput input = new UnitInput((Unit)mod, i, this); 67 | hbox.add(input); 68 | hbox.add(output); 69 | box.add(hbox); 70 | } 71 | 72 | for(int i = 0; i < NUM_MODULATIONS; i++) 73 | { 74 | final int _i = i; 75 | 76 | Box hbox = new Box(BoxLayout.X_AXIS); 77 | ModulationOutput output = new ModulationOutput(mod, i, this); 78 | output.setTitleText("", false); 79 | ModulationInput input = new ModulationInput(mod, i, this, false); 80 | hbox.add(input); 81 | hbox.add(output); 82 | box.add(hbox); 83 | } 84 | return box; 85 | } 86 | }; 87 | } 88 | 89 | 90 | 91 | } 92 | -------------------------------------------------------------------------------- /flow/modules/RandMod.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 by George Mason University 2 | // Licensed under the Apache 2.0 License 3 | 4 | 5 | package flow.modules; 6 | 7 | import flow.*; 8 | import flow.gui.*; 9 | import java.util.*; 10 | 11 | public class RandMod extends Modulation implements ModSource 12 | { 13 | private static final long serialVersionUID = 1; 14 | 15 | public static String getName() { return "Random"; } 16 | 17 | public static final int MOD_HIGH = 0; 18 | public static final int MOD_LOW = 1; 19 | public static final int MOD_TRIGGER = 2; 20 | public static final int MOD_SEED = 3; 21 | 22 | double current = 0; 23 | public Random random = null; 24 | 25 | void initializeRandom() 26 | { 27 | // first reseed 28 | double mod = modulate(MOD_SEED); 29 | 30 | if (mod == 0) 31 | { 32 | random = null; 33 | } 34 | else 35 | { 36 | long seed = Double.doubleToLongBits(mod); 37 | if (random == null) random = new Random(seed); 38 | else random.setSeed(seed); 39 | } 40 | } 41 | 42 | boolean onGate = true; 43 | public boolean isOnGate() { return onGate; } 44 | public void setOnGate(boolean val) { onGate = val; } 45 | 46 | public static final int OPTION_GATE = 0; 47 | 48 | public int getOptionValue(int option) 49 | { 50 | switch(option) 51 | { 52 | case OPTION_GATE: return isOnGate() ? 1 : 0; 53 | default: throw new RuntimeException("No such option " + option); 54 | } 55 | } 56 | 57 | public void setOptionValue(int option, int value) 58 | { 59 | switch(option) 60 | { 61 | case OPTION_GATE: setOnGate(value != 0); return; 62 | default: throw new RuntimeException("No such option " + option); 63 | } 64 | } 65 | 66 | 67 | 68 | public RandMod(Sound sound) 69 | { 70 | super(sound); 71 | defineModulations(new Constant[] { Constant.ONE, Constant.ZERO, Constant.ZERO, Constant.ZERO }, new String[] { "High", "Low", "Trigger", "Seed" }); 72 | defineOptions(new String[] { "Note On" }, new String[][] { { "Note On" } } ); 73 | } 74 | 75 | public void randomize() 76 | { 77 | Random rand = (random == null ? getSound().getRandom() : random); 78 | double val = rand.nextDouble(); 79 | double high = modulate(MOD_HIGH); 80 | double low = modulate(MOD_LOW); 81 | if (high < low) // swap if the boundaries are bad 82 | { 83 | double tmp = high; 84 | high = low; 85 | low = tmp; 86 | } 87 | current = (val * (high - low)) + low; 88 | } 89 | 90 | public void gate() 91 | { 92 | super.gate(); 93 | if (onGate) 94 | randomize(); 95 | } 96 | 97 | public void reset() 98 | { 99 | super.reset(); 100 | initializeRandom(); 101 | randomize(); 102 | } 103 | 104 | public void go() 105 | { 106 | super.go(); 107 | if (isTriggered(MOD_TRIGGER)) 108 | randomize(); 109 | setModulationOutput(0, current); 110 | } 111 | 112 | public String getModulationValueDescription(int modulation, double value, boolean isConstant) 113 | { 114 | if (isConstant) 115 | { 116 | if (modulation == MOD_SEED) 117 | { 118 | return (value == 0.0 ? "Free" : String.format("%.4f" , value)); 119 | } 120 | else return super.getModulationValueDescription(modulation, value, isConstant); 121 | } 122 | else return ""; 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /flow/modules/Rectified.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 by George Mason University 2 | // Licensed under the Apache 2.0 License 3 | 4 | 5 | package flow.modules; 6 | 7 | import flow.*; 8 | 9 | /** 10 | A Unit which outputs the partials corresponding to a Rectified Sine wave, 11 | that is, a wave of the form Abs(Sin(x)). 12 | */ 13 | 14 | public class Rectified extends Unit implements UnitSource 15 | { 16 | private static final long serialVersionUID = 1; 17 | 18 | public static final double NORMALIZED_GAIN = 0.6679687500000003; 19 | public static final double GAIN_MULTIPLIER = 8.0; // twice that of triangle! 20 | public static final int MOD_GAIN = 0; 21 | double oldGain = NORMALIZED_GAIN; 22 | 23 | void buildAmplitudes(double gain) 24 | { 25 | // From http://www.dspguide.com/ch13/4.htm 26 | // We ignore the negative sign, since that's 27 | // eliminated in the Sqrt(a^2 + b^2). We 28 | // ignore the 4/pi since that's normalized away. 29 | 30 | double[] amplitudes = getAmplitudes(0); 31 | for(int i = 0; i < amplitudes.length; i++) 32 | { 33 | amplitudes[i] = gain * 1.0 / (4 * (i + 1) * (i + 1) - 1); 34 | } 35 | 36 | } 37 | 38 | // A rectified Sine Wave, that is, Abs(Sin(x)) 39 | public Rectified(Sound sound) 40 | { 41 | super(sound); 42 | defineModulations(new Constant[] { new Constant(NORMALIZED_GAIN / GAIN_MULTIPLIER) }, 43 | new String[] { "Gain" }); 44 | 45 | setClearOnReset(false); 46 | 47 | buildAmplitudes(NORMALIZED_GAIN); 48 | // normalizeAmplitudes(); 49 | //double[] amplitudes = getAmplitudes(0); 50 | //System.err.println(amplitudes[0]); 51 | } 52 | 53 | public void go() 54 | { 55 | super.go(); 56 | double gain = modulate(MOD_GAIN); 57 | if (oldGain != gain) // Need to change values 58 | { 59 | buildAmplitudes(gain * GAIN_MULTIPLIER); 60 | oldGain = gain; 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /flow/modules/RightArrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/modules/RightArrow.png -------------------------------------------------------------------------------- /flow/modules/RightArrowPressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/modules/RightArrowPressed.png -------------------------------------------------------------------------------- /flow/modules/SampleAndHold.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 by George Mason University 2 | // Licensed under the Apache 2.0 License 3 | 4 | 5 | package flow.modules; 6 | 7 | import flow.*; 8 | 9 | /** 10 | A Modulation which performs a classic Sample and Hold on its incoming modulation 11 | Signal. When it receives a Trigger, it performs another sample, then only outputs 12 | that sample until the next Trigger. 13 | */ 14 | 15 | public class SampleAndHold extends Modulation 16 | { 17 | private static final long serialVersionUID = 1; 18 | 19 | public static final int MOD_SIGNAL = 0; 20 | public static final int MOD_TRIGGER = 1; 21 | 22 | public static final int TYPE_SAMPLE_AND_HOLD = 0; 23 | public static final int TYPE_TRACK_AND_HOLD = 1; 24 | public static final int TYPE_TRACK_AND_HOLD_ALT = 2; 25 | 26 | int type; 27 | public int getType() { return type; } 28 | public void setType(int val) { type = val; } 29 | 30 | public static final int OPTION_TYPE = 0; 31 | 32 | public int getOptionValue(int option) 33 | { 34 | switch(option) 35 | { 36 | case OPTION_TYPE: return getType(); 37 | default: throw new RuntimeException("No such option " + option); 38 | } 39 | } 40 | 41 | public void setOptionValue(int option, int value) 42 | { 43 | switch(option) 44 | { 45 | case OPTION_TYPE: setType(value); return; 46 | default: throw new RuntimeException("No such option " + option); 47 | } 48 | } 49 | 50 | 51 | public static String getName() { return "S & H"; } 52 | 53 | boolean sampling = false; 54 | 55 | public SampleAndHold(Sound sound) 56 | { 57 | super(sound); 58 | defineModulations(new Constant[] { Constant.ZERO, Constant.ZERO }, new String[] { "Signal", "Trigger", }); 59 | defineOptions(new String[] { "Type" }, new String[][] { { "S & H", "T & H", "T & H 2" } }); 60 | } 61 | 62 | public void reset() 63 | { 64 | super.reset(); 65 | setModulationOutput(0, modulate(MOD_SIGNAL)); 66 | if (getType() == TYPE_TRACK_AND_HOLD) 67 | { 68 | sampling = true; 69 | } 70 | else 71 | { 72 | sampling = false; 73 | } 74 | } 75 | 76 | public void gate() 77 | { 78 | super.gate(); 79 | setModulationOutput(0, modulate(MOD_SIGNAL)); 80 | if (getType() == TYPE_TRACK_AND_HOLD) 81 | { 82 | sampling = true; 83 | } 84 | else 85 | { 86 | sampling = false; 87 | } 88 | } 89 | 90 | public void go() 91 | { 92 | super.go(); 93 | 94 | if (getType() == TYPE_SAMPLE_AND_HOLD) 95 | { 96 | if (isTriggered(MOD_TRIGGER)) 97 | { 98 | setModulationOutput(0, modulate(MOD_SIGNAL)); 99 | } 100 | } 101 | else 102 | { 103 | if (isTriggered(MOD_TRIGGER)) 104 | { 105 | if (sampling) 106 | { 107 | setModulationOutput(0, modulate(MOD_SIGNAL)); 108 | } 109 | sampling = !sampling; 110 | } 111 | else if (!sampling) 112 | { 113 | setModulationOutput(0, modulate(MOD_SIGNAL)); 114 | } 115 | } 116 | 117 | // pass through trigger 118 | if (isTriggered(MOD_SIGNAL)) 119 | { 120 | updateTrigger(0); 121 | } 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /flow/modules/Sawtooth.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 by George Mason University 2 | // Licensed under the Apache 2.0 License 3 | 4 | 5 | package flow.modules; 6 | 7 | import flow.*; 8 | 9 | /** 10 | A Unit which provides partials for a Sawtooth Wave. 11 | */ 12 | 13 | public class Sawtooth extends Unit implements UnitSource 14 | { 15 | private static final long serialVersionUID = 1; 16 | 17 | public static final double NORMALIZED_GAIN = 0.1632827683729929; 18 | public static final double GAIN_MULTIPLIER = 4.0; 19 | 20 | public static final int MOD_GAIN = 0; 21 | double oldGain = NORMALIZED_GAIN; 22 | 23 | 24 | void buildAmplitudes(double gain) 25 | { 26 | double[] amplitudes = getAmplitudes(0); 27 | for(int i = 0; i < amplitudes.length; i++) 28 | { 29 | amplitudes[i] = gain * (double)(1.0 / (i+1)); 30 | } 31 | } 32 | 33 | public Sawtooth(Sound sound) 34 | { 35 | super(sound); 36 | defineModulations(new Constant[] { new Constant(NORMALIZED_GAIN / GAIN_MULTIPLIER) }, 37 | new String[] { "Gain" }); 38 | 39 | double[] amplitudes = getAmplitudes(0); 40 | 41 | setClearOnReset(false); 42 | buildAmplitudes(NORMALIZED_GAIN); 43 | // normalizeAmplitudes(); 44 | } 45 | 46 | public void go() 47 | { 48 | super.go(); 49 | double gain = modulate(MOD_GAIN); 50 | if (oldGain != gain) // Need to change values 51 | { 52 | buildAmplitudes(gain * GAIN_MULTIPLIER); 53 | oldGain = gain; 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /flow/modules/Scale.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 by George Mason University 2 | // Licensed under the Apache 2.0 License 3 | 4 | 5 | package flow.modules; 6 | 7 | import flow.*; 8 | 9 | /** 10 | A Unit which scales all the partials towards or away from the minimum partial. 11 | The degree of scaling depends on the Modulation SCALE. The maximum scaling is 3.0. 12 | */ 13 | 14 | public class Scale extends Unit 15 | { 16 | private static final long serialVersionUID = 1; 17 | 18 | public static final int MOD_SCALE = 0; 19 | 20 | public Scale(Sound sound) 21 | { 22 | super(sound); 23 | defineInputs( new Unit[] { Unit.NIL }, new String[] { "Input" }); 24 | defineModulations(new Constant[] { Constant.HALF }, new String[] { "Scale" }); 25 | } 26 | 27 | public static final double MAX_BOUND = 3.0; 28 | 29 | public void go() 30 | { 31 | super.go(); 32 | 33 | copyFrequencies(0); 34 | pushAmplitudes(0); 35 | 36 | double[] frequencies = getFrequencies(0); 37 | 38 | double mod = modulate(MOD_SCALE); 39 | if (mod == 0.5) mod = 1.0; 40 | else if (mod > 0.5) mod = ((mod - 0.5) * 2) * MAX_BOUND + 1.0; 41 | else mod = (mod * 2); 42 | double lowest = frequencies[getLowestPartial(0)]; 43 | 44 | for(int i = 0; i < frequencies.length; i++) 45 | { 46 | frequencies[i] = (frequencies[i] - lowest) * mod + lowest; 47 | } 48 | 49 | if (constrain()) simpleSort(0, true); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /flow/modules/Sine.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 by George Mason University 2 | // Licensed under the Apache 2.0 License 3 | 4 | 5 | package flow.modules; 6 | 7 | import flow.*; 8 | 9 | /** 10 | A Unit which provides a single partial at 1.0, whose 11 | frequency is determined by the "Frequency" modulation. 12 | */ 13 | 14 | public class Sine extends Unit implements UnitSource 15 | { 16 | private static final long serialVersionUID = 1; 17 | 18 | public static final int MOD_PARTIALS = 0; 19 | 20 | public static final double NORMALIZED_GAIN = 1.0; 21 | public static final double GAIN_MULTIPLIER = 4.0; 22 | public static final int MOD_GAIN = 1; 23 | double oldGain = NORMALIZED_GAIN; 24 | 25 | void buildAmplitudes(double mod, double gain) 26 | { 27 | double[] amplitudes = getAmplitudes(0); 28 | int p = (int)(mod * (Unit.NUM_PARTIALS - 1.0)); 29 | for(int i = 0; i < Unit.NUM_PARTIALS; i++) 30 | { 31 | if (i == p) amplitudes[i] = GAIN_MULTIPLIER * gain; 32 | else amplitudes[i] = 0.0; 33 | } 34 | } 35 | 36 | public Sine(Sound sound) 37 | { 38 | super(sound); 39 | defineModulations(new Constant[] { Constant.ZERO, new Constant(NORMALIZED_GAIN / GAIN_MULTIPLIER) }, 40 | new String[] { "Partial", "Gain" }); 41 | 42 | // double[] amplitudes = getAmplitudes(0); 43 | 44 | setClearOnReset(false); 45 | // sine = 0; 46 | // amplitudes[0] = 1; 47 | } 48 | 49 | double lastMod = Double.NaN; 50 | int sine = 0; 51 | 52 | public void go() 53 | { 54 | super.go(); 55 | 56 | //double[] frequencies = getFrequencies(0); 57 | double mod = modulate(MOD_PARTIALS); 58 | double gain = modulate(MOD_GAIN); 59 | 60 | if (lastMod != mod || gain != oldGain) 61 | { 62 | /* 63 | frequencies[sine] = mod * ((double)Unit.NUM_PARTIALS - 1.0) + 1; 64 | simpleSort(0, false); 65 | 66 | for(int i = 0; i < Unit.NUM_PARTIALS; i++) 67 | if (amplitudes[i] > 0) // found it 68 | { 69 | sine = i; 70 | break; 71 | } 72 | */ 73 | buildAmplitudes(mod, gain); 74 | lastMod = mod; 75 | oldGain = gain; 76 | } 77 | } 78 | 79 | public String getModulationValueDescription(int modulation, double value, boolean isConstant) 80 | { 81 | if (isConstant) 82 | { 83 | if (modulation == MOD_PARTIALS) 84 | { 85 | return "" + (int)(value * (Unit.NUM_PARTIALS - 1.0)); 86 | } 87 | else return super.getModulationValueDescription(modulation, value, isConstant); 88 | } 89 | else return ""; 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /flow/modules/Soften.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 by George Mason University 2 | // Licensed under the Apache 2.0 License 3 | 4 | 5 | package flow.modules; 6 | 7 | import flow.*; 8 | 9 | /** 10 | A Modulation which smooths over a modulation signal. The degree of smoothing is specified by Amount. 11 | You can choose to keep the softening free, or reset it on gate. 12 | */ 13 | 14 | public class Soften extends Modulation 15 | { 16 | private static final long serialVersionUID = 1; 17 | 18 | public static final int MOD_SIGNAL = 0; 19 | public static final int MOD_AMOUNT = 1; 20 | public static final int MOD_SCALE = 2; 21 | 22 | public static String getName() { return "Soften"; } 23 | 24 | public static final double SCALE_MAXIMUM = 10; 25 | 26 | double current; 27 | 28 | boolean free; 29 | public void setFree(boolean val) { free = val; } 30 | public boolean getFree() { return free; } 31 | 32 | public static final int OPTION_FREE = 0; 33 | 34 | public int getOptionValue(int option) 35 | { 36 | switch(option) 37 | { 38 | case OPTION_FREE: return getFree() ? 1 : 0; 39 | default: throw new RuntimeException("No such option " + option); 40 | } 41 | } 42 | 43 | public void setOptionValue(int option, int value) 44 | { 45 | switch(option) 46 | { 47 | case OPTION_FREE: setFree(value != 0); return; 48 | default: throw new RuntimeException("No such option " + option); 49 | } 50 | } 51 | 52 | public Soften(Sound sound) 53 | { 54 | super(sound); 55 | defineModulations(new Constant[] { Constant.ZERO, Constant.ZERO, Constant.ZERO }, 56 | new String[] { "Input", "Amount", "Scale" }); 57 | } 58 | 59 | public void reset() 60 | { 61 | super.reset(); 62 | current = Double.NaN; 63 | } 64 | 65 | public void gate() 66 | { 67 | super.gate(); 68 | if (!free) current = Double.NaN; 69 | } 70 | 71 | public void go() 72 | { 73 | super.go(); 74 | double signal = modulate(MOD_SIGNAL); 75 | if (current != current) // NaN 76 | current = signal; 77 | else 78 | { 79 | double alpha = makeInsensitive(modulate(MOD_AMOUNT)); 80 | current = alpha * current + (1 - alpha) * signal; 81 | } 82 | 83 | double scale = modulate(MOD_SCALE); 84 | double val = (current - 0.5) * (scale * (SCALE_MAXIMUM - 1) + 1) + 0.5; 85 | if (val < 0) val = 0; 86 | if (val > 1) val = 1; 87 | setModulationOutput(0, val); 88 | if (isTriggered(MOD_SIGNAL)) 89 | updateTrigger(0); 90 | } 91 | 92 | public String getModulationValueDescription(int modulation, double value, boolean isConstant) 93 | { 94 | if (modulation == 2 && isConstant) 95 | return String.format("%.4f", value * (SCALE_MAXIMUM - 1) + 1); 96 | else return super.getModulationValueDescription(modulation, value, isConstant); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /flow/modules/Square.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 by George Mason University 2 | // Licensed under the Apache 2.0 License 3 | 4 | 5 | package flow.modules; 6 | 7 | import flow.*; 8 | 9 | /** 10 | A Unit which provides partials for a Square Wave, or with a given 11 | pulse width. Pulse width is modulated by the Modulation "Pulse Width", 12 | with a standard square wave at 0.5. 13 | */ 14 | 15 | public class Square extends Unit implements UnitSource //, Parameterizable 16 | { 17 | private static final long serialVersionUID = 1; 18 | 19 | public static final int MOD_PULSE_WIDTH = 0; 20 | public static final int MOD_GAIN = 1; 21 | 22 | double lastMod = -1; 23 | 24 | public static final double NORMALIZED_GAIN = 0.29344691229918385; 25 | public static final double GAIN_MULTIPLIER = 4.0; 26 | 27 | double oldGain = -1; 28 | 29 | public Square(Sound sound) 30 | { 31 | super(sound); 32 | defineModulations(new Constant[] { Constant.HALF, new Constant(NORMALIZED_GAIN / GAIN_MULTIPLIER) }, 33 | new String[] { "Pulse Width", "Gain" }); 34 | setClearOnReset(false); 35 | buildPWM(); 36 | } 37 | 38 | public void go() 39 | { 40 | super.go(); 41 | 42 | buildPWM(); 43 | } 44 | 45 | public void buildPWM() 46 | { 47 | double mod = modulate(MOD_PULSE_WIDTH); 48 | double gain = modulate(MOD_GAIN) * GAIN_MULTIPLIER; 49 | if (lastMod != mod || gain != oldGain) 50 | { 51 | double[] amplitudes = getAmplitudes(0); 52 | 53 | if (mod == 0.5) // easy case! 54 | { 55 | for(int i = 1; i < amplitudes.length; i+=2) 56 | { 57 | amplitudes[i] = 0; 58 | } 59 | 60 | for(int i = 0; i < amplitudes.length; i+=2) 61 | { 62 | amplitudes[i] = gain * (double)(1.0 / (i+1)); 63 | } 64 | } 65 | else 66 | { 67 | // From here: http://www.dspguide.com/ch13/4.htm 68 | // I presume I don't do a0 69 | // The 'a' component of Harmonic n is 2/(pi n) sin(pi n d) 70 | // where d is the pulse width (0...1) 71 | // The 'b' component is 0 72 | // The magnitude, I believe, is Sqrt(a^2 + b^2), so 73 | // this means that we just do Math.abs(a). 74 | // The outer 2.0 / Math.PI is gonna get normalized away anyway... 75 | 76 | for(int i = 0; i < amplitudes.length; i++) 77 | { 78 | amplitudes[i] = (mod == 0 || mod == 1 ? 0 : Math.abs(1.0 / (i+1) * Utility.fastSin(Math.PI * (i + 1) * mod))); 79 | } 80 | } 81 | 82 | //normalizeAmplitudes(); 83 | lastMod = mod; 84 | oldGain = gain; 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /flow/modules/Sub.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 by George Mason University 2 | // Licensed under the Apache 2.0 License 3 | 4 | 5 | package flow.modules; 6 | 7 | import flow.*; 8 | 9 | /** 10 | A Unit which shifts the frequency of all partials. There are three 11 | options: 12 | 13 |

    14 |
  1. Pitch. Shift all partials by a certain pitch (for example, up an octave). 15 | This multiplies their frequencies by a certain amount. 16 |
  2. Frequency. Add a certain amount to the frequency of all partials. 17 | partials based on their distance from the nearest 18 |
  3. Partials. Move all partials towards the frequency of the next partial. 19 |
20 | 21 | The degree of shifting depends on the SHIFT modulation, bounded by the 22 | BOUND modulation. 23 | */ 24 | 25 | public class Sub extends Unit 26 | { 27 | private static final long serialVersionUID = 1; 28 | 29 | public static final double BOUND = 4; 30 | public static final int NUM_SUBS = 4; 31 | public static final double[] SUB_FREQUENCIES = new double[] { 0.5, 0.25, 0.125, .0625 }; 32 | 33 | public Sub(Sound sound) 34 | { 35 | super(sound); 36 | defineInputs( new Unit[] { Unit.NIL }, new String[] { "Input" }); 37 | defineModulations(new Constant[] { new Constant(1.0 / BOUND), Constant.ZERO, Constant.ZERO, Constant.ZERO }, 38 | new String[] { "-1 Oct", "-2 Oct", "-3 Oct", "-4 Oct" }); 39 | setPushOrders(false); 40 | } 41 | 42 | public boolean isConstrainable() { return false; } 43 | 44 | public void go() 45 | { 46 | super.go(); 47 | 48 | copyFrequencies(0); 49 | copyAmplitudes(0); 50 | copyOrders(0); 51 | 52 | double[] frequencies = getFrequencies(0); 53 | double[] amplitudes = getAmplitudes(0); 54 | byte[] orders = getOrders(0); 55 | byte[] topOrders = new byte[NUM_SUBS]; 56 | 57 | // make room at the bottom so we don't have to sort 58 | for(int j = 0; j < NUM_SUBS; j++) 59 | { 60 | topOrders[j] = orders[orders.length - 1 - j]; 61 | } 62 | 63 | for(int j = frequencies.length - 1; j >= NUM_SUBS; j--) 64 | { 65 | frequencies[j] = frequencies[j - NUM_SUBS]; 66 | amplitudes[j] = amplitudes[j - NUM_SUBS]; 67 | orders[j] = orders[j - NUM_SUBS]; 68 | } 69 | 70 | for(int i = 0; i < NUM_SUBS; i++) 71 | { 72 | // the sub frequencies are flipped in freqency order (-1 oct, -2 oct, -3 oct, -4 oct) 73 | // so we flip them back here 74 | frequencies[NUM_SUBS - i - 1] = SUB_FREQUENCIES[i]; 75 | amplitudes[NUM_SUBS - i - 1] = modulate(i) * amplitudes[NUM_SUBS] * BOUND; 76 | orders[NUM_SUBS - i - 1] = topOrders[i]; // reuse the ones we just deleted 77 | } 78 | } 79 | 80 | public String getModulationValueDescription(int modulation, double value, boolean isConstant) 81 | { 82 | if (isConstant) 83 | { 84 | return super.getModulationValueDescription(modulation, value * 4, isConstant); 85 | } 86 | else return ""; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /flow/modules/Triangle.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 by George Mason University 2 | // Licensed under the Apache 2.0 License 3 | 4 | 5 | package flow.modules; 6 | 7 | import flow.*; 8 | 9 | /** 10 | A Unit which provides positive partials for a Triangle wave. 11 | Traditionally triangle waves have some negative partials 12 | (that is, ones with a phase offset of Pi), but this one does 13 | not: it relies on us not being able to distinguish phase. 14 | */ 15 | 16 | public class Triangle extends Unit implements UnitSource 17 | { 18 | private static final long serialVersionUID = 1; 19 | 20 | public static final double NORMALIZED_GAIN = 0.8118547451597639; 21 | public static final double GAIN_MULTIPLIER = 4.0; 22 | public static final int MOD_GAIN = 0; 23 | double oldGain = NORMALIZED_GAIN; 24 | 25 | void buildAmplitudes(double gain) 26 | { 27 | double[] amplitudes = getAmplitudes(0); 28 | for(int i = 0; i < amplitudes.length; i += 2) 29 | { 30 | amplitudes[i] = gain * (double)(1.0 / ((i+1) * (i+1))); 31 | } 32 | 33 | } 34 | 35 | public Triangle(Sound sound) 36 | { 37 | super(sound); 38 | defineModulations(new Constant[] { new Constant(NORMALIZED_GAIN / GAIN_MULTIPLIER) }, 39 | new String[] { "Gain" }); 40 | 41 | setClearOnReset(false); 42 | 43 | buildAmplitudes(NORMALIZED_GAIN); 44 | //normalizeAmplitudes(); 45 | //System.err.println(amplitudes[0]); 46 | } 47 | 48 | public void go() 49 | { 50 | super.go(); 51 | double gain = modulate(MOD_GAIN); 52 | if (oldGain != gain) // Need to change values 53 | { 54 | buildAmplitudes(gain * GAIN_MULTIPLIER); 55 | oldGain = gain; 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /flow/modules/VCA.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 by George Mason University 2 | // Licensed under the Apache 2.0 License 3 | 4 | 5 | package flow.modules; 6 | 7 | import flow.*; 8 | 9 | /** 10 | A Unit which provides an amplifier. It takes a single input Unit, multiplies all its 11 | amplitudes by a given value, and ouptuts the result. The multiplier is defined by 12 | the modulation "Mod", which goes from 0...1, which is then multiplied against "Scale", 13 | which goes from 0...8 with 1.0 at its midpoint. "Mod" is linear, so you should 14 | use that to modulate via an envelope or LFO. "Scale" ought to be dialed in by hand. 15 | */ 16 | 17 | public class VCA extends Unit 18 | { 19 | private static final long serialVersionUID = 1; 20 | 21 | public static final int MOD_MOD = 0; 22 | public static final int MOD_SCALE = 1; 23 | 24 | public static final double MAX_SCALE = 8.0; 25 | 26 | public VCA(Sound sound) 27 | { 28 | super(sound); 29 | defineInputs( new Unit[] { Unit.NIL }, new String[] { "Input" }); 30 | defineModulations(new Constant[] { Constant.ONE, Constant.HALF }, new String[] { "Mod", "Scale" }); 31 | } 32 | 33 | public void go() 34 | { 35 | super.go(); 36 | 37 | pushFrequencies(0); 38 | copyAmplitudes(0); 39 | 40 | double[] amplitudes = getAmplitudes(0); 41 | 42 | double mod = modulate(MOD_MOD); 43 | double scale = modulate(MOD_SCALE); 44 | if (scale == 0.5) 45 | scale = 1.0; 46 | else if (scale > 0.5) 47 | scale = (scale - 0.5) * 2 * (MAX_SCALE - 1) + 1; 48 | else 49 | scale = scale * 2.0; 50 | 51 | for(int i = 0; i < amplitudes.length; i++) 52 | amplitudes[i] = amplitudes[i] * mod * scale; 53 | 54 | constrain(); 55 | boundAmplitudes(); // we can make the amplitudes go high, so we need to bound them 56 | } 57 | 58 | public String[] getPopupOptions(int modulation) 59 | { 60 | if (modulation == MOD_SCALE) 61 | { 62 | return new String[] { "0", "1/4", "1/2", "1", "2", "4", "8" }; 63 | } 64 | else return super.getPopupOptions(modulation); 65 | } 66 | 67 | public static final double[] POPUP_CONVERSIONS = new double[] 68 | { 69 | // <= 0.5 70 | 0, 0.125, 0.25, 0.5, 71 | // > 0.5 72 | (6 + 2.0) / 14.0, 73 | (6 + 4.0) / 14.0, 74 | (6 + 8.0) / 14.0 75 | }; 76 | 77 | public double getPopupConversion(int modulation, int index) 78 | { 79 | // when > 0.5, mod = (6 + scale) / 14 80 | if (modulation == MOD_SCALE) 81 | { 82 | return POPUP_CONVERSIONS[index]; 83 | } 84 | else return super.getPopupConversion(modulation, index); 85 | } 86 | 87 | public String getModulationValueDescription(int modulation, double value, boolean isConstant) 88 | { 89 | if (isConstant) 90 | { 91 | if (modulation == MOD_SCALE) 92 | { 93 | if (value >= 0.5) 94 | value = (value - 0.5) * 2 * (MAX_SCALE - 1) + 1; 95 | else 96 | value = value * 2.0; 97 | return String.format("%.4f", value); 98 | } 99 | else return super.getModulationValueDescription(modulation, value, isConstant); 100 | } 101 | else return ""; 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /flow/modules/help/AHR.html: -------------------------------------------------------------------------------- 1 | An Attack-Hold-Release envelope. 2 | 3 |
4 |
Start Level 5 |
The level at which the envelope begins on trigger, and also the level at which the release ends. 6 |
Attack Time 7 |
Time taken during the attack period. 8 |
Attack Level 9 |
Level reached at the end of the attack period. 10 |
Hold Time 11 |
Time taken duing the hold period. The level stays the same. 12 |
Release Time 13 |
Time take during the release period. 14 |
On Tr 15 |
Triggers the Note-On trigger. Otherwise, a NOTE ON event performs this trigger. 16 |
Off Tr 17 |
Triggers the Note-Off trigger. Otherwise, a NOTE OFF event performs this trigger. 18 |
Attack Curve 19 |
The curve taken by the attack. See the manual for a description of the available curves. 20 |
Release Curve 21 |
The curve taken by the attack. See the manual for a de 22 | scription of the available curves. 23 |
One Shot 24 |
If the Note Off trigger is received, it is ignored: the release will only occur after the attack and hold times have expired. 25 |
MIDI Sync 26 |
Attack, Hold, and Release times assume that we are playing at 120 BPM. If MIDI sync is faster (or slower), these times will be correspondingly faster (or slower). 27 |
Ramp 28 |
The envelope only attacks: it does not release. 29 |
H, R, E 30 |
Trigger outputs which fire when the envelope reaches its Hold and Release stages, or Ends. 31 |
32 | -------------------------------------------------------------------------------- /flow/modules/help/AKWF.html: -------------------------------------------------------------------------------- 1 | A source of harmonics drawn from the Adventure Kid Waveform (AKWF) collection, a large set of single-cycle waveforms. You can blend two harmonics sources to produce a final output. 2 | 3 |

The waves in the collection are grouped into categories. Select a category, then choose a wave from the category. The AKWF collection is available for free at https://www.adventurekid.se 4 | 5 |

6 |
Mix 7 |
The degree of the first source versus the second source. 8 |
Category 9 |
The first category. 10 |
Sound 11 |
The first source, a wave from the first category. 12 |
Category 2 13 |
The second category. 14 |
Sound 15 |
The second source, a wave from the second category. 16 |
Normalize 17 |
The result should be normalized prior to output. 18 |
19 | 20 | -------------------------------------------------------------------------------- /flow/modules/help/All.html: -------------------------------------------------------------------------------- 1 | Outputs a signal with all harmonics at equal volume (an impulse train). 2 | 3 |

This is particularly useful for visualizing the effects of filters applied to a signal 4 | -------------------------------------------------------------------------------- /flow/modules/help/AmpMath.html: -------------------------------------------------------------------------------- 1 | Bulk amplitude manipulation of partials, by combining the amplitudes of two incoming partial sources. 2 | 3 |

4 |
Input A 5 |
The first partial source. 6 |
Input B 7 |
The second partial source. 8 |
Scale 9 |
A scalar value S. 10 |
Operation 11 |
The manipulation to perform: 12 |
13 |
14 |
+ 15 |
A + B + S 16 |
- 17 |
max(A - B - B, 0) 18 |
x 19 |
A x B 20 |
inv x 21 |
A x (1 - B) 22 |
compress 23 |
1 - (1 - A) x (1 - B) 24 |
average 25 |
S x A + (1 - S) x B 26 |
min 27 |
min(A x (1 - S), B) 28 |
max 29 |
max(A, (1 - S), B) 30 |
filter 31 |
If B < S then 0 else A 32 |
filternot 33 |
If B >= S then 0 else A 34 |
fill 35 |
If A > S then A else B 36 |
threshold 37 |
If A > S then 1 else 0 38 |
scaledown 39 |
A x S + B, (Scales A in the range 0...1) 40 |
scaleup 41 |
A x (S + 1) + B (Scales A in the range 1...2) 42 |
scalefar 43 |
A x (S + 9) + B (Scales A in the range 1...10) 44 |
clampdown 45 |
min(A, S) + B 46 |
clampup 47 |
max(A, S) + B 48 |
49 |
Normalize 50 |
Normalizes the result after the operation. 51 |
52 | -------------------------------------------------------------------------------- /flow/modules/help/AudioIn.html: -------------------------------------------------------------------------------- 1 | Produces partials in real time through a vocoder process on the current audio input. 2 | 3 |

You can set the audio input device under "Options -> MIDI and Audio Options". 4 | 5 |

6 |
Gain 7 |
The input signal gain. 8 |
9 | 10 | -------------------------------------------------------------------------------- /flow/modules/help/Buffer.html: -------------------------------------------------------------------------------- 1 | Takes an incoming partials and a trigger, and samples the partials when triggered, or when the user begins a note; thereafter outputting only that sample. This is the partials equivalent of sample and hold. 2 | 3 |
4 |
Input 5 |
The incoming partials to sample. 6 |
Trigger 7 |
When a trigger is received here, the sample is taken. 8 |
Free 9 |
Should NOTE ON be ignored when sampling? That is, only sample on a trigger? 10 |
11 | -------------------------------------------------------------------------------- /flow/modules/help/Choice.html: -------------------------------------------------------------------------------- 1 | This module makes it possible to control a combobox or checkbox on some target module via modulation. 2 | 3 |
    4 |
  1. Connect any output of the target module (either modulation or partials) into a Target input on the Choice module. Doing so informs Choice which target module you would like to manipulate. 5 | 6 |

  2. Next, choose the combobox or checkbox of interest via the Option dial. 7 | 8 |

  3. Finally, change or modulate the Value dial. 9 |
10 | 11 |
12 |
The Target Inputs 13 |
A modulation input and a partials input to connect to any output of your target module. 14 |
Option 15 |
The combobox or checkbox to manipulate. 16 |
Value 17 |
The setting of the combobox or checkbox. 18 |
19 | -------------------------------------------------------------------------------- /flow/modules/help/Chord.html: -------------------------------------------------------------------------------- 1 | Converts a sound into an interval or chord, by reassigning high partials as necessary. 2 | 3 |
4 |
Input 5 |
The partials source. 6 |
Gain 7 |
How loud the additional chord notes are (up to the same volume of the root note). 8 |
Chord 9 |
The interval or chord to produce: 10 |
11 |
12 |
13 |
None 14 |
Do nothing (just pass the sound through) 15 |
16 |
Intervals 17 |
m2 18 |
Minor Second 19 |
M2 20 |
Major Second 21 |
m3 22 |
Minor Third 23 |
M3 24 |
Major Third 25 |
4 26 |
Perfect Fourth 27 |
TT 28 |
Tri Tone 29 |
5 30 |
Perfect Fifth 31 |
m6 32 |
Minor Sixth 33 |
M6 34 |
Major Sixth 35 |
m7 36 |
Minor Seventh 37 |
M7 38 |
Major Seventh 39 |
Oct 40 |
Octave 41 |
Oct+m3 42 |
Minor Third above an Octave 43 |
Oct+M3 44 |
Major Third above an Octave 45 |
Oct+5 46 |
Perfect Fifth above an Octave 47 |
2 Oct 48 |
2 Octaves 49 |
50 |
3-Note Chords 51 |
min 52 |
Minor Triad 53 |
min-1 54 |
Minor Triad (First Inversion) 55 |
min-2 56 |
Minor Triad (Second Inversion) 57 |
Maj 58 |
Major Triad 59 |
Maj-1 60 |
Major Triad (First Inversion) 61 |
Maj-2 62 |
Major Triad (Second Inversion) 63 |
64 |
4-Note Chords 65 |
7 66 |
Dominant 7 67 |
min7 68 |
Minor 7 69 |
Maj7 70 |
Major 7 71 |
dim7 72 |
Diminished 7 73 |
min+Oct 74 |
Minor Triad plus Octave 75 |
Maj+Oct 76 |
Major Triad plus Octave 77 |
78 |
79 | -------------------------------------------------------------------------------- /flow/modules/help/Combine.html: -------------------------------------------------------------------------------- 1 | Combines the partials of two input sources. 2 | 3 |

This throws all the partials together and removes the highest frequency half of them, leaving the remainder. 4 | 5 |

This module has a constraints facility (at its bottom): this facility constrains to the first input only. 6 | 7 |

8 |
Input A and Input B 9 |
The two inputs 10 |
Scale A and Scale B 11 |
Scales the amplitudes of the two inputs prior to combining them. 12 |
Merge 13 |
If two partials have identical frequencies, they are treated as a single partial whose amplitude is their sum. This allows more unique partials to be included but can create pops if partials move about and merge into one another. 14 |
Half 15 |
Half of the partials of each source are guaranteed to be in the final result. This is done by eliminating the highest frequency partials of each input first, then combining them. 16 |
17 | -------------------------------------------------------------------------------- /flow/modules/help/Compress.html: -------------------------------------------------------------------------------- 1 | Compresses (or Expands) the partial amplitudes. Compression squeezes the amplitudes exponentially towards 1.0. Expansion pushes them exponentially away from 1.0. 2 | 3 |
4 |
Input 5 |
The partials source 6 |
Scale 7 |
If this is > 0.5, then the partials are compressed more and more. If this is < 0.5, then the partials are expanded more and more. At 0.5 this module does nothing. 8 |
9 | -------------------------------------------------------------------------------- /flow/modules/help/Constraints.html: -------------------------------------------------------------------------------- 1 | Provides constraints useful to feed into the constraints sections of various modules. 2 | 3 |

There are four groupings similar to modules' constraint sections: Include, Also Include..., Also Include..., and Reduce To.... The constraints from the first three are all added together (OR or UNION). Then the results are whittled down to only include partials which also appear in the last one (AND or INTERSECTION). 4 | 5 |

In set notation, this is (X1 v X2 v X3) ^ X4. 6 | 7 |

The final partials can be fed into the Only souce of any module's constraint section to constrain to just those partials. 8 | 9 | Each grouping has: 10 | 11 |

12 |
"Include...", "Also Include...", or "Reduce To..." 13 |
Specify partials to constrain. If Only (below) was attached to, its partials take precedence and these are not used. 14 |
Only 15 |
Feed partials into here to constrain to just those partials. 16 |
Not 17 |
Constrain to those partials not included in the above. 18 |
19 | -------------------------------------------------------------------------------- /flow/modules/help/DADSR.html: -------------------------------------------------------------------------------- 1 | A Decay-Attack-Delay-Sustain-Release envelope. 2 | 3 |
4 |
Delay Time 5 |
The amount of time taken to delay before starting the attack. 6 |
Delay Level 7 |
The level reached at the end of the Delay stage. 8 |
Attack Time 9 |
Time taken during the attack stage. 10 |
Attack Level 11 |
Level reached at the end of the attack stage. 12 |
Decay Time 13 |
Time taken duing the decay stage. 14 |
Sustain Level 15 |
Level to which the envelope decays. The envelope then holds at the sustain level until a NOTE OFF occurs or a Note-Off trigger fires. 16 |
Release Time 17 |
Time take during the release stage. 18 |
Release Level 19 |
Level to which release decays. 20 |
On Tr 21 |
Triggers the Note-On trigger. Otherwise, a NOTE ON event performs this trigger. 22 |
Off Tr 23 |
Triggers the Note-Off trigger. Otherwise, a NOTE OFF event performs this trigger. 24 |
Curve 25 |
The curve taken by the attack, decay, and release. See the manual for a description of the available curves. 26 |
One Shot 27 |
If the Note Off trigger is received, it is ignored: the envelope will attack, then decay to sustain, then immediately release on its own. 28 |
Gate Reset 29 |
When a Note On occurs, the envelope immediately resets to the Release level. Otherwise the envelope starts from whatever level it is currently at (the default). 30 |
MIDI Sync 31 |
Delay, Attack, Decay, and Release times assume that we are playing at 120 BPM. If MIDI sync is faster (or slower), these times will be correspondingly faster (or slower). 32 |
Fast Release 33 |
If during the Decay stage a Note Off trigger occurs, the release stage is entered immediately. Otherwise it is entered when the Decay stage has completed (the default). 34 |
D, A, D, S, R, E 35 |
Trigger outputs which fire when the envelope reaches its Delay, Attack, Decay, Sustain, or Release stages, or Ends. 36 | 37 |
38 | -------------------------------------------------------------------------------- /flow/modules/help/Delay.html: -------------------------------------------------------------------------------- 1 | An initial delay, followed by a repeated delay. 2 | 3 |
4 |
Input 5 |
The input partials to delay. 6 |
Wet 7 |
The wetness of the delay (how much delay is passed through versus the original partials signal). 8 |
Initial Delay 9 |
The initial delay time 10 |
Later Delays 11 |
The delay time for each of the repeated later delays 12 |
Initial Cut 13 |
The cut in amplitude of the initial delay relative to the original signal. 14 |
Later Cuts 15 |
The cut in amplitude of the later delays relative to the amplitude of each previous delay. 16 |
17 | -------------------------------------------------------------------------------- /flow/modules/help/Dilate.html: -------------------------------------------------------------------------------- 1 | Boosts the amplitude of partials on either side of the locally highest-amplitude partials in a sound. 2 | 3 |
4 |
Input 5 |
The input partials to delay. 6 |
Boost 7 |
The degree to which the partials are increased to approach the amplitude of their higher neighbors. 8 |
Direction 9 |
10 |
11 |
Lower 12 |
Only partials lower in frequency than a higher-amplitude neighbor are boosted. 13 |
Higher 14 |
Only partials higher in frequency than a higher-amplitude neighbor are boosted. 15 |
Both 16 |
Partials on both sides of a higher-amplitude neighbor are boosted. 17 |
18 |
19 | -------------------------------------------------------------------------------- /flow/modules/help/Dissolve.html: -------------------------------------------------------------------------------- 1 | Gradually replaces the partials, one by one, from input A with those in input B. 2 | 3 |
4 |
A, B 5 |
The two inputs 6 |
Dissolve 7 |
The number of partials in A which have been replaced with those in B. 8 |
Seed 9 |
The random number seed determining the order in which partials are replaced. If the seed is 0 (Free), then a new seed is chosen each note, so the order changes each note. 10 |
11 | -------------------------------------------------------------------------------- /flow/modules/help/Draw.html: -------------------------------------------------------------------------------- 1 | A tool for manually modifying (through drawing) the amplitudes, but not frequencies, of a set of partials. 2 |
3 |
Show 4 |
Reveals the drawing surface, plus various menu options. 5 |
Source 6 |
The input for capturing partials (see Menu below) 7 |
Menu 8 |
9 |
10 |
Undo / Redo 11 |
Undo or redo of the last drawing operation. 12 |
Capture 13 |
Load current partials from the input attached to the Source. 14 |
Standardize Frequencies 15 |
Make all the partials into harmonics. 16 |
Normalize Amplitudes 17 |
Make the partials' amplitudes sum to 1 18 |
Maximize Amplitudes 19 |
Scale the amplitudes so that the largest is equal to 1. 20 |
Clear Amplitudes 21 |
Set all the amplitudes to zero 22 |
Save Partials As... 23 |
Write all the partials out as a text file 24 |
Load Partials... 25 |
Load the partials from a text file 26 |
Load Wave... 27 |
Extract the partials from a sound in a WAV file. 28 |
29 |
Constrain 30 |
Constrains the effects of drawing to only partials matching the given constraint. 31 |
32 | -------------------------------------------------------------------------------- /flow/modules/help/Drawbars.html: -------------------------------------------------------------------------------- 1 | A drawbar and tonewheel organ simulator. 2 | 3 |
4 |
1 (16') ... 9 (1') 5 |
The classic nine drawbars, each with their pitch setting. Each drawbar corresponds to one harmonic. The drawbar amplitude can be set to a value from 0.0 to 8.0. 6 |
10 and 11 7 |
The common two additional drawbars, corresponding to two harmonics each. The drawbar amplitude can be set to a value from 0.0 to 8.0. 8 |
Perc Decay 9 |
The decay setting for percussion. 10 |
Perc Volume 11 |
The volume setting for percussion. 12 |
Percussion 13 |
Off, or either of the two standard settings ("1st" and "2nd"). 14 |
Tuning 15 |
Classic tuning found on drawbar organs, Equal Temperment tuning to which the classic tuning was an approximation, and true harmonic tuning (integer hrmonics). 16 |
Presets... 17 |
A set of presets for classic settings of the first nine drawbars. Choosing a preset will set the drawbars accordingly. 18 |
19 | -------------------------------------------------------------------------------- /flow/modules/help/EitherOr.html: -------------------------------------------------------------------------------- 1 | A multiplexer for up to four modulation outputs. Based on the given Choice value, one of the Output values will be assiged the Yes value, and the others will be assigned the No value. 2 | 3 |
4 |
Choice 5 |
Selects the current output 6 |
Yes 7 |
The value the current output... outputs. 8 |
No 9 |
The value output by all other outputs other than the current. 10 |
Options 11 |
The number of outputs 12 |
13 | -------------------------------------------------------------------------------- /flow/modules/help/Envelope.html: -------------------------------------------------------------------------------- 1 | A general-purpose envelope with many stages. Envelope contains stages in three regions: the Pre-Sustain region, the Sustain region, and the Release (or Post-Sustain) region. When the envelope is triggered, it moves through its pre-sustain stages, then it optionally loops through its sustain stages until Note Off occurs, at which point it moves through its Release stages. 2 | 3 |
4 |
Start 5 |
The initial level to start at 6 |
Pre n ... Level 7 |
The time to progress through stage n, and the level reached at the end of the stage. If the time is off, the stage is skipped. 8 |
Sus n ... Level 9 |
The time to progress through stage n, and the level reached at the end of the stage. If the time is off, the stage is skipped. 10 |
Rel n ... Level 11 |
The time to progress through stage n, and the level reached at the end of the stage. If the time is off, the stage is skipped. 12 |
On Tr 13 |
Triggers the Note-On trigger. Otherwise, a NOTE ON event performs this trigger. 14 |
Off Tr 15 |
Triggers the Note-Off trigger. Otherwise, a NOTE OFF event performs this trigger. 16 |
Curve 17 |
The curve taken by all stages. See the manual for a description of the available curves. 18 |
Type 19 |
20 |
21 |
Sustain 22 |
The sustain region works through the sustain stages, then stays at the end of the final one. 23 |
Sustain Loop 24 |
The sustain region loops through its stages. 25 |
One Shot 26 |
The envelope works its way through all stages, with no looping, regardless of any Note Off event. 27 |
Play Through 28 |
The envelope works its way through all stages, with no looping, but on Note Off it skips forward to the release stages if it has not reached them yet. 29 |
Loop w/Rel (Loop with Release) 30 |
The envelope loops through all stages, and stops looping on Note Off 31 |
Loop 32 |
The envelope loops through all stages forever. It resets to the first stage on Note On. 33 |
34 |
Gate Reset 35 |
When a Note On occurs, the envelope immediately resets to the Start level. Otherwise the envelope starts from whatever level it is currently at (the default). 36 |
MIDI Sync 37 |
Delay, Attack, Decay, and Release times assume that we are playing at 120 BPM. If MIDI sync is faster (or slower), these times will be correspondingly faster (or slower). 38 |
Pre 1, 2, 3, Sus 1, 2, 3, Rel 1, 2, E 39 |
Trigger outputs which fire when the envelope reaches its Pre 1 ... 3, Sus 1 ... 3, or Rel 1 ... 2 stages, or Ends. 40 |
41 | -------------------------------------------------------------------------------- /flow/modules/help/Fatten.html: -------------------------------------------------------------------------------- 1 | A thickener via detuning. This module works by taking highest frequency half of the partials and reassigning them the same frequencies as the lowest half. It then detunes the reassigned partials by some degree and sets the amplitudes to some fraction of the lower ones. 2 | 3 |
4 |
Input 5 |
The input partials 6 |
Wet 7 |
The volume of the detuned partials relative to the originals. 8 |
Detune 9 |
The degree of detuning in cents. 10 |
11 | -------------------------------------------------------------------------------- /flow/modules/help/Fill.html: -------------------------------------------------------------------------------- 1 | Combines two input sources by replacing zero-amplitude partials in Source A with the lowest-frequency non-zero-amplitude partials of Source B. 2 |
3 |
Input A and B 4 |
The two sources respectively 5 |
Scale A and B 6 |
Pre-combination amplitude scaling of the two sources. 7 |
8 | -------------------------------------------------------------------------------- /flow/modules/help/Filter.html: -------------------------------------------------------------------------------- 1 | A state-variable 2- or 4-pole filter. 2 | 3 |
4 |
Input 5 |
The partials input source. 6 |
Cutoff 7 |
The cutoff frequency. 8 |
State 9 |
The type of filter. The filter state can range from High Pass through Notch, through Low Pass, through Band Pass, and then to High Pass again. 10 |
Resonance 11 |
The degree of resonance. 12 |
4-Pole 13 |
The filter is normally a 2-pole filter. This changes to a 4-pole (by doing two 2-pole filters in series). 14 |
Relative 15 |
Is the cutoff frequency shifted relative to the base pitch of the note? 16 |
Taper 17 |
Should we gradually taper off the amplitude so that it reaches 0 at the Nyquist limit? Tapering more closely approximates a digital filter; not tapering (the default) more closely approximates an analog filter. 18 |
19 | -------------------------------------------------------------------------------- /flow/modules/help/Fix.html: -------------------------------------------------------------------------------- 1 | A mechanism for locking the pitch and/or velocity of a voice. This works if Fix is in the top-level patch, and ideally is the first module in the patch. It will have no effect if Fix is in a macro. 2 | 3 |
4 |
Note 5 |
The note to fix to, or Free, indicating no pitch locking. 6 |
Velocity 7 |
The velocity to fix to, or Free, indicating no velocity locking. 8 |
9 | -------------------------------------------------------------------------------- /flow/modules/help/FlangeFilter.html: -------------------------------------------------------------------------------- 1 | A filter producing flanger and phaser effects. 2 | 3 |
4 |
Input 5 |
The partials input source. 6 |
Wet 7 |
The degree of effect of the flanging on the original signal. 8 |
OffsetMod 9 |
The phase offset of the flange humps, typically modulated by an LFO. 10 |
Stretch 11 |
The base size of the flange humps. 12 |
StretchMod 13 |
The additional modulated size of the flange humps, typically via an LFO. 14 |
Style 15 |
16 |
17 |
Linear 18 |
The humps are triangle-shaped up-down lines. 19 |
Spike Up 20 |
The humps are rounded on the bottom and spiked on the top, like a feedback comb filter. 21 |
Spike Down 22 |
The humps are rouned on the top and spiked on the bottom, like a forward comb filter. 23 |
Curvy 24 |
The humps are S-shaped in the middle and round both at top and bottom. 25 |
Spikey 26 |
The humps are S-shaped in the middle and spiked both at the top and bottom. 27 |
28 |
Fixed 29 |
The base flange filter frequency does not shift with the pitch of the note. 30 |
Fundamental 31 |
The fundamental is included in the flanging. 32 |
33 | -------------------------------------------------------------------------------- /flow/modules/help/FormantFilter.html: -------------------------------------------------------------------------------- 1 | A multi-vowel morphing format filter. As the interpolation value changes, the filter shifts through a sequence of vowels. 2 | 3 |
4 |
Input 5 |
The partials input source. 6 |
Interpolation 7 |
The current position of the filter in the sequence of vowels. 8 |
Num Vowels 9 |
The number of vowels in the sequence. 10 |
Gain 11 |
A post-filtering increase in amplitude for the partials. 12 |
Num Formants 13 |
The number of formants used in producing the vowel. 14 |
Resonance 15 |
The strength of each formant. A higher resonance makes formants peakier and narrower. 16 |
Vowel n 17 |
The vowels available are A, E, I, and U for bass, tenor, contra tenor, alto, and soprano voices. 18 |
Four Pole 19 |
Sets the bandpass filters in the formant filter to be four pole rather than two-pole 20 |
21 | -------------------------------------------------------------------------------- /flow/modules/help/Geiger.html: -------------------------------------------------------------------------------- 1 | A source of randomly-timed pulses. A pulse is a square wave pulse plus a trigger. 2 | 3 |

As incoming pulses arrive, with some probability a counter is increased. When the counter reaches a certain value, it is reset to 0 and Geiger changes from 0 to 1 or vice versa, and issues a pulse. 4 | 5 |

6 |
Trials 7 |
The size of the counter. If 1, then Geiger just outputs a pulse with the given probability every time it receives a pulse. If >= 1, then pulses are more regular (the variance is decreased) but also corresponsingly slower in rate. 8 |
Prob 9 |
The probability that the counter will be increased on an incoming pulse. 10 |
Trigger 11 |
The incoming pulses 12 |
Seed 13 |
The random number seed, to guarantee determinism in the pulses. If Free, then Geiger is nondeterministic. 14 |
Pulsing 15 |
After raising from 0 to 1, Geiger will always drop back to 0 on the next incoming pulse; and when dropping it will not issue a trigger. This produces an up/down effect rather than changing from 0 to 1 or vice versa. 16 |
17 | -------------------------------------------------------------------------------- /flow/modules/help/HarmonicLab.html: -------------------------------------------------------------------------------- 1 | A programmmable, modulatable harmonics generator. 2 | 3 |

Adds up to three kinds of waves. Each wave has a particular low pass filtering function and is constrained to a set of harmonics. If an earlier wave uses a given harmonic, it takes precedence over later waves. 4 | 5 |

6 |
Amt 1 ... 3 7 |
The strength of the filtering of the given wave. 8 |
Gain 1 ... 3 9 |
The amplitude of the partials in the given wave. 10 |
Type 1 ... 3 11 |
The filter shape. The shapes are given by their equation. 12 |
Constraint 1 ... 3 13 |
The harmonics to which the wave is constrained. 14 |
15 | 16 | -------------------------------------------------------------------------------- /flow/modules/help/Harmonics.html: -------------------------------------------------------------------------------- 1 | Outputs a set of harmonics with varying amplitudes. 2 | 3 |
4 |
Amp 1 ... 32 5 |
The amplitudes of the first 32 harmonics. Harmonic 1 is the fundamental. 6 |
Get 7 |
Loads the amplitudes from the provided source 8 |
Source 9 |
The incoming harmonics to load from 10 |
Get 11 |
Extracts the first 32 harmonics from the given source. 12 |
Compress 13 |
Rearranges the harmonics so that all non-zero-amplitude harmonics come first. 14 |
Mutate 15 |
Randomly mutates the amplitudes of all harmonics by the given amount. 16 |
17 | -------------------------------------------------------------------------------- /flow/modules/help/In.html: -------------------------------------------------------------------------------- 1 | Feeds in inputs to a Macro from its parent. 2 | 3 |

A Macro can have up to 8 partials inputs and up to 8 modulation signal inputs. the partials inputs are named A...H and the modulation signal inputs are named 1..8, but you can rename any of them by clicking on their underlined labels. Unused inputs are trimmed out when the Macro is displayed. 4 | 5 |

6 |
A ... D 7 |
The partials inputs 8 |
1 ... 8 9 |
The modulation signal inputs 10 |
1 ... 8 (dials) 11 |
The default values for the signal inputs if the parent does not connect a signal to them. 12 |
13 | -------------------------------------------------------------------------------- /flow/modules/help/Jitter.html: -------------------------------------------------------------------------------- 1 | Adds random jitter noise to the frequencies and amplitudes of partials. 2 | 3 |

Jitter only adds noise when receiving a trigger and on NOTE ON. Each time it receives a trigger it changes the noise provided. 4 | 5 |

6 |
Input 7 |
The partials input 8 |
Freq Var 9 |
The degree of jitter noise applied to the frequencies of the partials. 10 |
Amp Var 11 |
The degree of jitter noise applied to the amplitudes of the partials. 12 |
Trigger 13 |
Tiggers the module to change its jitter noise 14 |
Seed 15 |
The random number seed for the jitter. This allows the jitter pattern to be exactly the same (deterministic) each time you press a note. Alternatively you can set the seed to Free, which makes the pattern nondeterministic. Free is particularly useful if you want new jitter every time you press a note. 16 |
Non-Zero 17 |
Jitter is only applied to non-zero amplitude partials. This is useful when combining Jitter with Fill. 18 |
Amp Ratio 19 |
The amplitude jitter should be proportional to the current amplitude value, as opposed to just fixed random noise. 20 |
21 | -------------------------------------------------------------------------------- /flow/modules/help/Joy.html: -------------------------------------------------------------------------------- 1 | A joystick for simultaneously modifying four modulation outputs, plus recorded joystick movement trajectories. 2 |
3 |
↖↗↙↘ 4 |
The four modulation outputs, corresponding to (and highest in) the various corners of the joystick. 5 |
On Tr 6 |
Starts or restarts playback of a recorded trajectory (normally this is done at Note On). 7 |
Loop 8 |
Indicates that a recorded trajectory should loop forever. 9 |
Show 10 |
Reveals the joystick and record button. 11 |
Record 12 |
A button for recording the a joystick movement trajectory, which is then played back whenever a note is played. This button has four states: 13 |
14 |
Record 15 |
Arms the recording. The joystick turns green. Drag the joystick to begin recording. A point labelled "Start" will show where the trajectory started: thisis useful to close things up if you're looping. 16 |
Cancel 17 |
Disarms and cancels the recording. The joystick turns blue. 18 |
Recording 19 |
Indicates that recording is taking place. 20 |
Clear 21 |
Erases the last recording 22 |
23 |
24 | Note that when you are moving the joystick manually, all voices are affected. When the joystick is controlled by a prerecording, it affects each note independently and starts when the note is pressed. 25 | -------------------------------------------------------------------------------- /flow/modules/help/KHarmonics.html: -------------------------------------------------------------------------------- 1 | A source of harmonics drawn from patches in the Kawai K5 synthesizer. You can blend two harmonics sources to produce a final output. 2 | 3 |

These harmonics are extracted from K5 patches. The patches are drawn from the public domain and from Kawai's own factory patches (with permission). 4 | 5 |

6 |
Mix 7 |
The degree of the first source versus the second source. 8 |
Sound 9 |
The first source. 10 |
Sound 2 11 |
The second source 12 |
Normalize 13 |
The result should be normalized prior to output. 14 |
15 | -------------------------------------------------------------------------------- /flow/modules/help/LFO.html: -------------------------------------------------------------------------------- 1 | A Low Frequency Oscillator. When the oscillator completes one period, it issues a trigger. 2 | 3 |
4 |
Rate 5 |
The speed of the oscillator (the length of its period). 6 | If you double-click on the rate, the menu that pops up will tell you the proper rate to set for different notes when under MIDI Sync. 7 |
Phase 8 |
The phase of the oscillator, from 0 (0.0) to 2 Pi (1.0) 9 |
Scale 10 |
The wave amplitude. 11 |
Shift 12 |
The wave's DC offset. The LFO does not exceed 0.0 or 1.0, so it is clipped if the offset causes it to exceed those bounds. 13 |
Variance 14 |
The size of the random jumps made by the oscillator when the oscillator type is set to Random or to Rnd S&H. 15 |
Seed 16 |
The random seed used for the random jumps when the oscillator type is set to Random or to Rnd S&H. The seed guarantees that the random sequence is the same each time you press a new note. If you want it to be different every time, set the seed to Free. 17 |
On Tr 18 |
Replaces the Note On trigger with one provided by this input. 19 |
Type 20 |
21 |
22 |
Sine 23 |
Sine wave 24 |
Triangle 25 |
Triangle wave 26 |
Square 27 |
Square wave 28 |
Saw Up 29 |
Ramp wave 30 |
Random 31 |
A random wave. When the wave concludes its period, a new random target value is selected. Then during the next period the wave moves linearly to that new target value. This target value is chosen from within the range defined by the Scale, centered at the Shift position. The Variance defines the degree to which the target value will deviate from the current value. A small variance makes a smooth random oscillator; a large variance causes more disruptive jumps. 32 |
Rnd S&H 33 |
A random wave. This is the same as Random, except that when a new random target value is selected, the wave immediately adopts it, rather than moving to it smoothly. 34 |
35 |
36 |
Free 37 |
The LFO is not reset on a Note On event. 38 |
Invert 39 |
The LFO wave is flipped. 40 |
Half Trigger 41 |
The LFO issues a trigger both at the end of a period and half-way in the period. 42 |
Linear Rate 43 |
When an incoming modulation signal is attached to the Rate dial, it changes the Rate value linearly rather than (as is normal) exponentially. This does not effect manual changes to the dial, which are always exponential. 44 |
MIDI Sync 45 |
The period rate assumes that we are playing at 120 BPM. If MIDI sync is faster (or slower), this rate will be correspondingly faster (or slower). The Rate dial's pop-up menu has useful note speeds when under MIDI Sync. 46 |
Init Trigger 47 |
When a Note on event occurs, or the synthesizer is reset, a Trigger is issued at the start of the very first wave. 48 |
49 | 50 | -------------------------------------------------------------------------------- /flow/modules/help/LadderFilter.html: -------------------------------------------------------------------------------- 1 | Various low-pass ladder filters. 2 | 3 |
4 |
Input 5 |
The partials input source. 6 |
Cutoff 7 |
The cutoff frequency. 8 |
Resonance 9 |
The degree of resonance. Note that a 1-pole (6dB) filter cannot resonate. 10 |
Poles 11 |
The number of poles in the filter. 12 | 13 |
14 |
1 (6dB) 15 |
A 1-pole, 6dB filter. Note that this filter is not technically a ladder filter, but ladder filters are built from strings of such filters. 1-pole filters have no resonance. 16 |
3 (18dB) 17 |
A 3-pole, 18dB filter. 18 |
4 (24dB) 19 |
A 4-pole, 24dB filter. This is the classic ladder filter confguration. 20 |
6 (36dB) 21 |
A 6-pole, 36dB filter. 22 |
8 (48dB) 23 |
An 8-pole, 48dB filter. 24 |
25 | 26 |
Relative 27 |
Is the cutoff frequency shifted relative to the base pitch of the note? 28 |
Taper 29 |
Should we gradually taper off the amplitude so that it reaches 0 at the Nyquist limit? Tapering more closely approximates a digital filter; not tapering (the default) more closely approximates an analog filter. 30 |
31 | -------------------------------------------------------------------------------- /flow/modules/help/Latch.html: -------------------------------------------------------------------------------- 1 | A latch for recurrent sound flows. 2 | 3 | When triggered (or Note On gate), Latch allows sound to flow from one of its INITIAL partials input sources. Immediately thereafter, it only allows sound to flow from one of its LATER partials input sources. The primary use of Latch is to attach its output to one of its LATER inputs recursively, so that it starts with an initial impulse and then recursively modifies it as time goes on. 4 | 5 |
6 |
Initial 1 ... 4 7 |
The initial partials input sources, selectable with Sel Initial. 8 |
Later 1 ... 4 9 |
The later partials input sources, selectable with Sel Later. 10 |
Trigger 11 |
When triggered, Latch will output sound from one Initial source (depending on Sel Initial). Otherwise will output sound from one Later source (depending on Sel Later). If you do not connect the trigger to anything, Latch will be automatically triggered by a Note On (a gate). 12 |
Sel Initial 13 |
Selects which of the Initial sources will be used. 14 |
Sel Later 15 |
Selects which of the Later sources will be used. 16 |
17 | -------------------------------------------------------------------------------- /flow/modules/help/LinearFilter.html: -------------------------------------------------------------------------------- 1 | A multi-peak filter. You specify the gain and frequency of up to 8 peaks and valleys, and the filter interpolates linearly between them. 2 | 3 |
4 |
Input 5 |
The partials input source. 6 |
Nodes 7 |
The number of peaks and valleys 8 |
Base 9 |
This frequency value is added to the frequencies of all the nodes to shift them positively or negatively. 10 |
Freq n 11 |
The frequency of node n 12 |
Gain n 13 |
The gain of node n 14 |
Relative 15 |
The filter frequencies are shifted with pitch. 16 |
17 | -------------------------------------------------------------------------------- /flow/modules/help/MIDIIn.html: -------------------------------------------------------------------------------- 1 | Auxiliary MIDI input information. 2 | 3 |
4 |
Gate 5 |
0 when Note Off, 1 when Note On. Trigger occurs on Note On. 6 |
Note 7 |
The pitch of the most recent MIDI Note. 0.0 ... 1.0 maps to MIDI note 0...127. Trigger occurs on Note On. 8 |
Velocity 9 |
The most recent attack (Note On) velocity value. 0.0 ... 1.0 maps to MIDI velocity 0...127. Trigger occurs on Note On 10 |
Release 11 |
The most recent release (Note Off) velocity value. 0.0 ... 1.0 maps to MIDI velocity 0...127. Trigger occurs on Note Off 12 |
Pressure 13 |
The current pressure (aftertouch) value. This responds to both channel and poly pressure. 0.0 ... 1.0 maps to MIDI velocity 0...127. 14 |
Clock 15 |
MIDI Clock. This triggers every single MIDI clock pulse. When the clock is running, the value is 1.0, else 0.0. When a MIDI START message is received, the clock will also go to 0.0 prior to the first pulse (at which point the clock is considered running, so it goes to 1.0). You will probably need to divide the MIDI clock pulse to something more useful for your purposes: for example getting a trigger every beat (every 24 pulses). To do something like this, try using the Trigger 2A through Trigger 192A options in the Mod Math module. 16 |
Bend 17 |
Current pitch bend information. 0.0 ... 1.0 maps to extreme bend low (-8192) to extreme bend high (8191). No bend is 0.5. 18 |
CC n (eight of them) 19 |
The dial sets the CC parameter. The output is the current value at that parameter, with 0...127 mapped to 0.0 ... 1.0. Trigger occurs when the CC value changes. CC values 6, 38, 98, 99, 100, and 101 are invalid: they are used by Flow for NRPN. If you need more than 8 CCs, just use a second MIDIIn module. 20 |
21 | -------------------------------------------------------------------------------- /flow/modules/help/MPE.html: -------------------------------------------------------------------------------- 1 | Multidimensional Polyphonic Expression (MPE) input information. 2 | 3 |
4 |
Velocity 5 |
The most recent attack (Note On) velocity value. 0.0 ... 1.0 maps to MIDI velocity 0...127. Trigger occurs on Note On 6 |
Release 7 |
The most recent release (Note Off) velocity value. 0.0 ... 1.0 maps to MIDI velocity 0...127. Trigger occurs on Note Off 8 |
Current pitch bend information. 0.0 ... 1.0 ma 9 | ps to extreme bend low (-8192) to extreme bend high 10 | (8191). No bend is 0.5. 11 |
Pressure 12 |
The current pressure (aftertouch) value, mapped from 0...127 to 0.0...1.0, then modified by the offset and variance below, then bounded to between 0.0 and 1.0. This responds to both channel and polyphonic pressure. 13 |
(Pressure) Offset 14 |
This value is added to the pressure. 15 |
(Pressure) Variance 16 |
This value is multiplied by the pressure (prior to offset). Also, if the variance is negative, the final pressure value is inverted (subtracted from 1.0). 17 |
Y (CC 74) 18 |
The current "Y controller" (CC 74) value, mapped from 0...127 to 0.0...1.0, then modified by the offset and variance below, then bounded to between 0.0 and 1.0. 19 |
(Y) Offset 20 |
This value is added to the pressure. 21 |
(Y) Variance 22 |
This value is multiplied by the pressure (prior to offset). Also, if the variance is negative, the final pressure value is inverted (subtracted from 1.0) 23 |
24 | -------------------------------------------------------------------------------- /flow/modules/help/Macro.html: -------------------------------------------------------------------------------- 1 | This is a Macro. A Macro is a patch that you have loaded as a module. 2 | 3 | 7 | 8 |
9 |
Pause 10 |
If this is set, then On Tr has another feature: as long as On Tr's value is set to zero (0.0), then the Macro's underlying modules will be paused: they won't recieve any steps. This can save computational power when used in combination with Switch or Morph, whose output triggers also go to zero. Be careful using this feature: see the manual. 11 |
On Tr 12 |
If you send a trigger here, the Macro's underlying modules will receive a Gate (Note On) message, effectively resetting them. 13 |
Off Tr 14 |
If you send a trigger here, the Macro's underlying modules will receieve a Release (Note Off) message. 15 |
Info 16 |
Provides the version, author, date, and information of the patch loaded as a Macro. 17 |
18 | -------------------------------------------------------------------------------- /flow/modules/help/Map.html: -------------------------------------------------------------------------------- 1 | Maps a signal to between a set of bounds. 2 | 3 |

In normal configuration, the incoming signal is mapped so that 0.0 ... 1.0 maps to A ... B and is then output. That is, for a given input x, the output y = A + (B - A) * x. 4 | 5 |

6 |
Signal 7 |
The original input. 8 |
Bound A 9 |
The first bound. 10 |
Bound B 11 |
The second bound. 12 |
Inverse 13 |
Instead of mapping 0.0 ... 1.0 -> A ... B, the converse is true: A ... B is mapped to 0.0 ... 1.0.You can use Inverse to un-map a value mapped by an earlier Map. 14 |
Flip 15 |
The input signal is flipped (subtracted from 1.0) prior to mapping. 16 |
Center 17 |
Instead of defining A and B directly, we define a Center and a Variance (and the dials change accordingly). Thus A = min(0, Center - Variance) and B = max(Center + Variance) 18 |
19 | -------------------------------------------------------------------------------- /flow/modules/help/Mix.html: -------------------------------------------------------------------------------- 1 | Mix (add) the amplitudes of up to four sets of partials. The frequencies of the partials in all four sets are reset to the frequencies of the first set of partials. 2 | 3 | 4 |
5 |
Input A ... D 6 |
The four original inputs 7 |
Gain A ... D 8 |
The amplitudes of inputs A...D will be multiplied against these prior to mixing. 9 |
Type 10 |
11 |
12 |
Sum 13 |
Mix the amplitudes by adding them. 14 |
Max 15 |
Mix the amplitudes by taking the maximum over the four. 16 |
17 |
18 | -------------------------------------------------------------------------------- /flow/modules/help/ModMath.html: -------------------------------------------------------------------------------- 1 | Functions on two modulation signals, as well as functions on their triggers. 2 | 3 |
4 |
Signal A and B 5 |
The two input signals 6 |
Operation 7 |
This is the output function of A and B's signals. 8 |
9 |
+ 10 |
min(A + B, 1) 11 |
- 12 |
max(A - B, 0). By setting A = 0, you can use this to negate B. 13 |
x 14 |
A x B 15 |
min 16 |
min(A, B) 17 |
max 18 |
max(A, B) 19 |
square 20 |
min(A x A + B, 1) 21 |
sqrt 22 |
min(sqrt(A) + B, 1) 23 |
cube 24 |
min(A x A x A + B, 1) 25 |
discretize 26 |
Discretizes A, using B to set the amount of discretization (from 1 to 128 chunks). 27 |
map hi 28 |
A x (1 - B) + B 29 |
average 30 |
(A + B) / 2 31 |
threshold 32 |
If A >= B, 1 else 0 33 |
switch 34 |
If B was more recently triggered than A, then B else A 35 | 36 |
37 |
Trigger On 38 |
This indicates how the output should trigger wh 39 | en receiving triggers from A and/or B. 40 |
41 |
A 42 |
Triggers on A's trigger only 43 |
A or B 44 |
Triggers on A's trigger or B's trigger 45 |
A and B 46 |
Trigger only when A and B trigger simultaneously 47 |
A and not B 48 |
Trigger only when A is triggering but not B 49 |
2 A ... 192 A 50 |
A rate divider. Triggers every n triggers of A. This is particularly useful in conjunction with MIDI Clock information from the MIDI In module. 51 |
dir 52 |
Triggers when A's value changes direction. 53 |
center 54 |
Triggers when A's value crosses the center line (0.5). 55 |
56 | 57 |

Dividing a Clock Pulse

58 | 59 | If you're dividing the trigger, the following table might be useful: 60 | 61 |
62 |
1 63 |
Eighth Triplet (Triplet 64th Note) 64 |
2 65 |
Quarter Triplet (Triplet 32nd Note) 66 |
3 67 |
Thirty-Second Note 68 |
4 69 |
Half Triplet (Triplet 16th Note) 70 |
6 71 |
Sixteenth Note 72 |
8 73 |
Triplet 74 |
12 75 |
Eighth Note 76 |
16 77 |
Quarter Note Triplet 78 |
18 79 |
Dotted Eighth Note 80 |
24 81 |
Quarter Note 82 |
32 83 |
Half Note Triplet 84 |
36 85 |
Dotted Quarter Note 86 |
48 87 |
Half Note 88 |
64 89 |
Whole Note Triplet 90 |
72 91 |
Dotted Half Note 92 |
96 93 |
Whole Note 94 |
144 95 |
Dotted Whole Note 96 |
192 97 |
Double Whole Note 98 |
99 | 100 | 101 | 102 | 103 |
104 | 105 | -------------------------------------------------------------------------------- /flow/modules/help/Morph.html: -------------------------------------------------------------------------------- 1 | Interpolates the amplitudes and frequencies of partials from among four different sources in turn. 2 | 3 |

When there are only two inputs, the Interpolation knob interpolates between the two of them. 4 | 5 |

When there are more than two inputs, the Interpolation knob starts by interpolating between the first two: but when it reaches 1.0, it begins interpolating between the second and third. When it reaches 0.0 it begins interpolating between the third and fourth, and so on. 6 | 7 |

Morph's interpolation is computed as follows. We take the first partial from both active sources, and produce a partial which is a weighted average of the two both in terms of frequency and amplitude. Then we do this for the second partial, and so on. 8 | 9 |

Morph doesn't just pair up the #1 partials and then the #2 partials, etc. It can also map the partials to each other in complex ways. 10 | 11 |

12 |
Input A ... D 13 |
The four input partials sources 14 |
Trig A ... D 15 |
Triggers fired when Morph begins using the partials source in question. This can be used to inform another module that a new sound is beginning. 16 |
Interpolation 17 |
The current interpolation weight value. 18 |
Variance. 19 |
The randomness in mapping when the Type is Random. 20 |
Seed 21 |
Random number seed used when the Type is Random. This seed guarantees that the randomness is deterministic: it's the same order every time a note is played. If you set the Seed to Free, then it will be completely nondeterministic. 22 |
Type 23 |
Morph can pair up partials in complex ways rather than just line #1 up with #1 and #2 up with #2 etc. 24 |
25 |
Normal 26 |
Partial #1 is paired with #1, #2 is paired with #2, and so on. 27 |
Random 28 |
The ordering of the partials is shuffled randomly in one source relative to the other. 29 |
2-Pair 30 |
Reversed groups of 2. Partial #1 is paired with #2, #2 with #1, #3 with #4, #4 with #3, and so on. 31 |
4-Pair 32 |
Reversed groups of 4. Partial #1 is paired with #4, #2 with #3, #3 with #2, #4 with #1, and so on. 33 |
8-Pair 34 |
Reversed groups of 8 35 |
Increasing 36 |
The first pair is a 2-pair. The next pair is a 4-pair. The next pair is an 8-pair. The next pair is a 16-pair. And so on. 37 |
38 |
Fundamental 39 |
The fundamental is included in the pairing mapping. If not the fundamentals are mapped to one another. 40 |
Frequency 41 |
Interpolate the partial frequencies 42 |
Amplitude 43 |
Interpolate the partial amplitudes 44 |
Free 45 |
When a Note On occurs, Morph does not reset to the first two inputs used, but instead starts right where it had left off. 46 |
Random 47 |
Instead of iterating sequentially through the sources, Morph will select its new source at random each time. The random seed is determined by Seed. 48 |
49 | -------------------------------------------------------------------------------- /flow/modules/help/NRPN.html: -------------------------------------------------------------------------------- 1 | Modulation sources arriving by external NRPN signals. 2 | 3 |

Flow responds to NRPN, and you can use it for any purpose you like. If you need more than eight incoming NRPN signals, just add an additional NRPN module. 4 | 5 |

Each NRPN parameter has three ports: an MSB dial, an LSB dial, and an output port (to the right of the MSB). You specify the parameter number as a combination of the MSB and LSB, and the most recent value is output at the port. 6 | 7 |

8 |
MSB 9 |
Specifies the MSB of an NRPN parameter number. The parameter number is equal to 128 * MSB + LSB. This value is shown to the right of the LSB. 10 |
LSB 11 |
Specifies the LSB of an NRPN parameter number. The parameter number is equal to 128 * MSB + LSB. This value is shown to the right of the LSB. 12 |
[Output] (to right of MSB) 13 |
This provides the most recent value arriving on the given parameter. 14 |
15 | -------------------------------------------------------------------------------- /flow/modules/help/Noise.html: -------------------------------------------------------------------------------- 1 | Different colors of random noise. 2 | 3 |

Noise is generated by rapidly creating and destroying partials at random frequencies and (possibly) amplitudes. 4 | 5 |

6 |
High 7 |
The upper bound for partial frequencies. If Hi 8 | gh < Low, then the two bounds are swapped. 9 |
Low 10 |
The lower bound for partial frequencies. If High < Low, then the two bounds are swapped. 11 |
Partials 12 |
The number of partials created at any one time. Low numbers of partials create a kind of dribbly effect. 13 |
Amp Var 14 |
The degree of randomness in the partial amplitudes. 15 |
Ramp 16 |
The ramp in partial amplitudes. This produces different colored noise. At 0.0, amplitude partials are maximal at the lower bound and drop linearly until they are zero at the higher bound. At 1.0 it is the opposite. And at 0.5, amplitude partials are all the same value. 17 |
Gain 18 |
The noise volume. 19 |
Seed 20 |
The random number seed for the noise generator. This sees to it that the noise is the same from note to note. If you would like nondeterministic noise, set the seed to Free. 21 |
Top 22 |
The partials used to generate the noise are set to the top n partials in the partials list: the remainder are set to 0 frequency and 0 amplitude. (When unchecked, they are set to the bottom partials, and the remainder are set to a high frequency and 0 amplitude). This can have impacts on modules like Combine, where the partials discarded are the highest frequency. 23 |
24 | 25 |

If you want more sophisticated coloration to your sound, set the ramp to 0.5 (producing white noise) and run the sound through a high pass, low pass, or band pass filter. 26 | -------------------------------------------------------------------------------- /flow/modules/help/Normalize.html: -------------------------------------------------------------------------------- 1 | Normalizes, Maximizes, and/or Standardizes an input. 2 | 3 |

4 |
Input 5 |
The input partials 6 |
Scaling 7 |
How to scale the partial amplitudes 8 |
9 |
Off 10 |
Don't scale the amplitudes 11 |
Normalize 12 |
Scale the partials so that their amplitudes sum to 1. 13 |
Maximize 14 |
Scale the partials so that their high 15 |
16 |
Standardize 17 |
Set all the partials to harmonics. The lowest partial is harmonic 1, the second is harmonic 2, and so on. 18 |
19 | -------------------------------------------------------------------------------- /flow/modules/help/Note.html: -------------------------------------------------------------------------------- 1 | A note pad. 2 | 3 |

You can widen or narrow the notepad by pressing on the appropriate arrow buttons at the bottom. 4 | 5 |

The notepad supports cut and paste, and drag and drop, but no formatting. 6 | -------------------------------------------------------------------------------- /flow/modules/help/Out.html: -------------------------------------------------------------------------------- 1 | If this is a top-level patch, outputs sound as audio and displays sound and signals. If this is a macro, provides the sound and signals to the parent. 2 | 3 | Macros can provide up to four audio outputs and four modulation signal outputs to their parents. The default names for these are A, B, C, D and 1, 2, 3, 4 respectively. You can change the names of these outputs by clicking on the title (the underlined portion). Unused outputs are trimmed out when a Macro is displayed. 4 | 5 |

6 |
 Clip  7 |
Indicates that Flow is producing sound louder than the maximum amplitude of your machine, resulting in clipping. 8 |
 Glitch  9 |
Indicates that Flow cannot run fast enough to keep the audio buffer filled, resulting in glitches as the buffer gets filled with 0. 10 |
A (Audio) 11 |
If this is a top-level patch, then this outputs the partials as audio, and also displays it in the left partials display. If this is a macro, then this routes to partials output A in the parent. 12 |
B (Aux) 13 |
If this is a top-level patch, then this displays the partials in the right partials display. If this is a macro, then this routes to partials output B in the parent. 14 |
C, D 15 |
If this is a macro, then these route to partials outputs C and D in the parent. 16 |
1 (Scope) 17 |
If this is a top-level patch, then this displays the modulation signal in the left oscilloscope. If this is a macro, then this routes to modulation output 1 in the parent. 18 |
2 (Aux) 19 |
If this is a top-level patch, then this displays the modulation signal in the right oscilloscope. If this is a macro, then this routes to modulation output 2 in the parent. 20 |
3, 4 21 |
If this is a macro, then these route to modulation signal outputs 3 and 4 in the parent. 22 |
Gain 23 |
If this is a top-level patch, then this modifies the final volume of the sound. 24 |
Wet 25 |
If this is a top-level patch, then this sets the wetness of the reverb. 26 |
Damp 27 |
If this is a top-level patch, then this sets the dampening of the reverb. 28 |
Size 29 |
If this is a top-level patch, then this sets the room size of the reverb. 30 |
Pan 31 |
If this is a top-level patch, then this sets the panning of the sound. 32 |
Dephase 33 |
If this is a top-level patch, then this sets whether the partials are in phase or randomly dephased. 34 |
Edit 35 |
Lets you set the Name, Version, Author, Date, and Information regarding the patch. 36 |
37 | -------------------------------------------------------------------------------- /flow/modules/help/PartialFilter.html: -------------------------------------------------------------------------------- 1 | A filter based on linear interpolation among another set of partials. 2 | 3 |

The idea is that each partial in the Partials port represents a peak or valley of a filter function: you can think of these partials as frequency value sliders in an equalizer, with their amplitudes being the gains. 4 | 5 |

6 |
Input 7 |
The partials to be filtered. 8 |
Partials 9 |
The partials to do the filtering. 10 |
Frequencies 11 |
How the partials are positioned in frequency. 12 |
13 |
Relative 14 |
The partials are at the frequency expected given the current pitch. 15 |
Fixed 16 |
The partials are spaced so that the fundamental represents 0Hz, the next harmonic would be 100Hz, the next would be 200Hz, and so on. Partials less than the fundamental are ignored. 17 |
Double 18 |
The partials are spaced so that the fundamental 19 | represents 0Hz, the next harmonic would be 200Hz, 20 | the next would be 400Hz, and so on. Partials less 21 | than the fundamental are ignored. 22 |
23 |
24 | -------------------------------------------------------------------------------- /flow/modules/help/Partials.html: -------------------------------------------------------------------------------- 1 | Outputs a set of partials with varying frequencies and amplitudes. 2 | 3 |
4 |
Freq 1 ... 16 5 |
The frequencies of 16 partials. 6 |
Amp 1 ... 16 7 |
The amplitudes of the same 16 partials. 8 |
Source 9 |
The incoming partials to load from 10 |
Get 11 |
Extracts the first 16 partials from the given source. 12 |
Compress 13 |
Rearranges the partials so that all non-zero-amplitude partials come first. 14 |
Mutate 15 |
Randomly mutates either the frequencies or the amplitudes of all partials by the given amount. 16 |
17 | -------------------------------------------------------------------------------- /flow/modules/help/Patch.html: -------------------------------------------------------------------------------- 1 | A simple thru patchbay. This is useful for breaking up long connections between two modules, or for attaching many inputs to a single output which you want to change here and there. 2 | 3 |
4 |
Units A ... H 5 |
Each input is routed directly to the corresponding output. 6 |
Modulations 1 ... 8 7 |
Each input is routed directly to the corresponding output. 8 |
9 | -------------------------------------------------------------------------------- /flow/modules/help/RandMod.html: -------------------------------------------------------------------------------- 1 | Emits random values within a range and which change on reset, trigger, or optionally note on. 2 | 3 |
4 |
High 5 |
The high end of the random range 6 |
Low 7 |
The low end of the random range 8 |
Trigger 9 |
Changes the random value in the output on receiving a trigger event 10 |
Seed 11 |
The random number seed. This seed is deterministic. If you would like nondeterministic random values, set the seed to Free. 12 |
Note On 13 |
Changes to a new random value when on a note on event occurs, in addition to incoming triggers and on reset. 14 |
15 | -------------------------------------------------------------------------------- /flow/modules/help/Rectified.html: -------------------------------------------------------------------------------- 1 | Outputs the normalized partials of a fully rectified sine wave. 2 | 3 |

A fully rectified sine wave is the function Abs(sin(x)). It has a distinctive harmonic signature. 4 | -------------------------------------------------------------------------------- /flow/modules/help/Rotate.html: -------------------------------------------------------------------------------- 1 | Shifts a set of partials up or down, wrapping partials beyond a certain boundary to the other side. This creates a barber-pole effect. 2 | 3 |

4 |
Input 5 |
The input partials source. 6 |
Rotate 7 |
Degree of rotation from 0.0 to 1.0 (a full period). 8 |
Upper 9 |
The upper boundary: the highest frequency. If t 10 | he upper boundary is less than the lower boundary, 11 | the two are swapped. 12 |
Lower 13 |
The lower boundary: the lowest frequency. If the upper boundary is less than the lower boundary, the two are swapped. 14 |
Thin 15 |
Thins out partials from the source. 16 |
Stretch 17 |
Stretches the frequencies of the partials prior to rotation. 18 |
Window 19 |
Windows the amplitudes of the partials prior to rotation. 20 |
Center 21 |
Place the peak of the stretching in the center (and symmetric) as opposed to the lower boundary. 22 |
Solo 23 |
Mute all partials outside the boundaries. 24 |
25 | -------------------------------------------------------------------------------- /flow/modules/help/SampleAndHold.html: -------------------------------------------------------------------------------- 1 | Takes an incoming modulation signal and a trigger, and samples the signal when triggered, outputting only that sample. 2 | 3 |
4 |
Signal 5 |
The incoming signal to sample. 6 |
Trigger 7 |
When a trigger is received here, the sample is taken. 8 |
Type 9 |
10 |
11 |
S & H 12 |
Sample and Hold mode only. On receiving a trigger, samples the signal and outputs that value until the next trigger, when it resamples etc. 13 |
T & H 14 |
Track and Hold mode. The trigger toggles between Sample and Hold Mode, or letting it pass through normally. When a gate is received, we start in Sample and Hold Mode. 15 |
T & H 2 16 |
Track and Hold mode #2. The trigger toggles between Sample and Hold Mode, or letting it pass through normally. When a gate is received, we start passing through normally. 17 |
18 | -------------------------------------------------------------------------------- /flow/modules/help/Sawtooth.html: -------------------------------------------------------------------------------- 1 | Outputs the normalized partials of a sawtooth wave. 2 | 3 | -------------------------------------------------------------------------------- /flow/modules/help/Scale.html: -------------------------------------------------------------------------------- 1 | Scales the partial frequencies to or away from the fundamental. 2 | 3 |
4 |
Input 5 |
The input partials source. 6 |
Scale 7 |
The scaling. 0.5 are the orginal frequencies. Less than 0.5 squishes the partials towards the fundamental. Greater than 0.5 stretches them further away from the fundamental. 8 |
9 | -------------------------------------------------------------------------------- /flow/modules/help/Seq.html: -------------------------------------------------------------------------------- 1 | A step sequencer. 2 | 3 |

Seq outputs a different modulation value every step. Steps are advanced when it receives a trigger. Seq's output can be attached to Shift's shift input, and when Shift is set to Pitch, Seq can be used to change note values as well. 4 | 5 |

6 |
1 ... 32 7 |
The value to output when the trigger reaches the given step. When connecting to Shift, you can select the right modulation output to correspond to a note by double-clicking on the step dial and selecting a note. 8 |
Steps 9 |
The number of steps. Steps beyond this number are ignored. 10 |
Trigger 11 |
When a trigger is received here, Seq advances to the next step. A good source of triggers would be an LFO. 12 |
Change 13 |
How the step shifts from one sequence to the next. See the manual for a description of the various curves. The modulation signal provided to the Trigger specifies where in this curve Seq should be at any time. To do this right, attach an LFO to the Trigger and set the LFO to Saw Up. If you're outputting notes, it'd be best also to turn off Free on the LFO. 14 |
Free 15 |
The sequencer ignores both Note On and Note Off. Otherwise it resets on Note Off and obeys Stop on Release. 16 |
Stop on Release 17 |
The sequencer stops on Note Off. 18 |
Sample 19 |
The sequencer samples the current step value and immediately transitions to it (as opposed to constantly adjusting if the step value is modified in real-time). The Trigger value is ignored, and so is Change. 20 |
Guided 21 |
The incoming value to Trigger doesn't specify the Change curve, but rather specifies which step to move to. 22 |
Display 23 |
A little red dot is displayed to show which step is being played. This is computationally costly, so turn it off when it's not needed. 24 |
25 | -------------------------------------------------------------------------------- /flow/modules/help/Shift.html: -------------------------------------------------------------------------------- 1 | Shifts the pitch, frequency, or partial position of a set of partials. 2 | 3 |
4 |
Input 5 |
The input partials to shift. 6 |
Shift 7 |
Shifts the pitch, frequency, or partial position. Shift can be positive or negative. 8 |
Bound 9 |
The maximum range of the shift modulation. 10 |
Type 11 |
12 |
13 |
Pitch 14 |
Shift by pitch. This changes the frequency of the partials exponentially. You can shift by up to several octaves. This can be used in combination with the Seq module to change note pitches: see the Help panel of the Seq module. 15 |
Frequency 16 |
Shift by pitch. This simply adds a constant value to the frequency of all the partials. 17 |
Partials 18 |
Shift by partials. This moves each partial frequency up (or down) to the frequency value occupied by the neighboring partial 19 |
Vibrato 20 |
Shift by pitch, but by a much smaller amount (at most a half step in each direction). This can be used with an LFO to provide a small amount of vibrato. 21 |
22 |
23 | -------------------------------------------------------------------------------- /flow/modules/help/Sine.html: -------------------------------------------------------------------------------- 1 | Outputs a Sine wave. 2 | 3 |
4 |
Frequency 5 |
The harmonic shift of the sine wave relative to the pitch. 6 |
7 | -------------------------------------------------------------------------------- /flow/modules/help/Skeletonize.html: -------------------------------------------------------------------------------- 1 | Thin out a sound by reducing the amplitude of partials if their neighbors have a higher amplitude to start with. 2 | 3 |
4 |
Input 5 |
The input partials source. 6 |
Cut 7 |
The degree to cut down the amplitudes. 8 |
9 | -------------------------------------------------------------------------------- /flow/modules/help/Smooth.html: -------------------------------------------------------------------------------- 1 | Smooths out sudden changes in frequency and amplitude among partials. 2 | 3 |
4 |
Input 5 |
The input partials source. 6 |
Amount 7 |
The degree to smooth. 8 |
Free 9 |
Never reset on Note On. (Normally Smooth resets, which creates a sudden non-smooth jump which may or may not be desirable). 10 |
11 | -------------------------------------------------------------------------------- /flow/modules/help/Soften.html: -------------------------------------------------------------------------------- 1 | Smooths out sudden changes in modulation. 2 | 3 |
4 |
Input 5 |
The input partials source. 6 |
Amount 7 |
The degree to smooth. 8 |
Scale 9 |
Scales the amplitude of the resulting signal. This is useful because high degrees of smoothing can reduce the amplitude. 10 |
11 | -------------------------------------------------------------------------------- /flow/modules/help/Square.html: -------------------------------------------------------------------------------- 1 | Outputs a Pulse wave. 2 | 3 |
4 |
Pulse Width 5 |
The wave's pulse width. At 0.5 the wave is a Square wave. 6 |
7 | -------------------------------------------------------------------------------- /flow/modules/help/Stretch.html: -------------------------------------------------------------------------------- 1 | Stretches the partials either away from or toward a specific target partial. 2 | 3 | 4 |

When there are more than two inputs, the Interpolation knob starts by interpolating between the first two: but when it reaches 1.0, it begins interpolating between the second and third. When it reaches 0.0 it begins interpolating between the third and fourth, and so on. 5 | 6 |

Morph's interpolation is computed as follows. We take the first partial from both active sources, and produce a partial which is a weighted average of the two both in terms of frequency and amplitude. Then we do this for the second partial, and so on. 7 | 8 |

Morph doesn't just pair up the #1 partials and then the #2 partials, etc. It can also map the partials to each other in complex ways. 9 | 10 |

11 |
Input 12 |
The input source to stretch. 13 |
Amount 14 |
The degree of stretching. 15 |
Max Amount 16 |
The maximum amount of stretching (away only). 17 |
Partial 18 |
The partial to stretch towards or away from. 19 |
Style 20 |
How stretching occurs. Stretching can be linear (x), squared (x^2), or cubed (x^3), where x is the distance between a partial and the target partial. In the "free" versions, partials may freely stretch to/away from the target partial. In the "non-free" versions, partials are constrained so that they are "attached" to the partial bounds, like a spring. 21 |
Largest 22 |
The target is the largest possible partial, not one specified by the Partial dial. 23 |
Squish 24 |
Stretch towards the target partial rather than away. 25 |
26 | -------------------------------------------------------------------------------- /flow/modules/help/Sub.html: -------------------------------------------------------------------------------- 1 | Adds sub-harmonics. 2 | 3 |
4 |
Input 5 |
The input source to add sub-harmonics to. 6 |
-1 Oct ... -4 Oct 7 |
Amplitude of various sub-harmonics. These range from -1 Oct (one octave below the fundamental) to -4 Oct (four octaves below the fundamental). 8 |
9 | -------------------------------------------------------------------------------- /flow/modules/help/Subharmonics.html: -------------------------------------------------------------------------------- 1 | Outputs a set of harmonics below the fundamental with varying amplitudes. 2 | 3 |
4 |
Amp 1, Amp 1/2, ... Amp 1/32 5 |
The amplitudes of the fundamental (Amp 1) and the first 31 subharmonics. A subharmonic 1/n is 1/n the frequency of the fundamental. 6 |
Mutate 7 |
Randomly mutates the amplitudes of all subharmonics by the given amount. 8 |
9 | -------------------------------------------------------------------------------- /flow/modules/help/Swap.html: -------------------------------------------------------------------------------- 1 | Pairs up partials, then swaps the amplitudes among the pairs. 2 | 3 |
4 |
Input 5 |
The partials input source. 6 |
Distance 7 |
The distance between pairs of partials. When this is small, then nearby partials are grouped and swapped 8 |
Fundamental 9 |
Whether to include the fundamental in the pairing and swapping. 10 |
11 | -------------------------------------------------------------------------------- /flow/modules/help/Switch.html: -------------------------------------------------------------------------------- 1 | Switches between up to eight different sources. 2 | 3 |

You select the new sound to play by sending a trigger the corresponding modulation input. Select will then interpolate the frequencies and amplitudes between the old sound and the newly chosen sound until old sound is entirely faded out. You can use this in combination with the individual modulation outputs of an envelope to select one sound, then another, then a final sound, for example. 4 | 5 |

If you instead send a trigger to next, this will cause the next sound to trigger, wrapping around. 6 | 7 |

The first selected sound is always A. 8 | 9 |

10 |
Input A ... H 11 |
The eight input partials sources 12 |
Trig A ... H [Input] 13 |
When triggered, selects the corresponding input. 14 |
Next 15 |
When trigered, selects the next input. 16 |
Rate 17 |
The rate at which the sounds are faded in/out. This is useful for preventing pops when a new sound is suddenly selected. 18 |
Free 19 |
When a Note On occurs, Select does not reset to input A, but instead starts right where it had left off. 20 |
21 | -------------------------------------------------------------------------------- /flow/modules/help/Tinkle.html: -------------------------------------------------------------------------------- 1 | When triggered, drops random partials into its output sound, creating a tinkling effect. 2 | 3 |
4 |
Trigger 5 |
Triggers Tinkle to drop some partials. 6 |
Decay 7 |
How quickly a partial's amplitude decays away. 8 |
Volume 9 |
Initial amplitude of a new dropped partial. 10 |
Number 11 |
The number of partials to create each trigger. 12 |
Probability 13 |
The probability that a trigger will create any partials at all. 14 |
Seed 15 |
The random number seed. This allows the tinkle pattern to be exactly the same (deterministic) each time you press a note. Alternatively you can set the seed to Free, which makes the pattern nondeterministic. Free is particularly useful if you want new jitter every time you press a note. 16 |
17 | -------------------------------------------------------------------------------- /flow/modules/help/Triangle.html: -------------------------------------------------------------------------------- 1 | Outputs the normalized partials of a triangle wave. 2 | 3 | -------------------------------------------------------------------------------- /flow/modules/help/User.html: -------------------------------------------------------------------------------- 1 | A set of tools to allow you to manually trigger or set modulations. This could be used for testing purposes or for live performance. 2 | 3 |
4 |
A ... D 5 |
Setting the input dial value in turn outputs the exact same value in the corresponding output modulation. This is useful if you need to manually change several dials simultaneously to the same value. For example, if you have three LFOs and you need to change all of their rates at the same time, you could hook them all up to the provided output here, then change them all by modifying the corresponding input dial. 6 | 7 |
Tr A ... D 8 |
Pressing a button sends a trigger along the previously mentioned outputs A ... D 9 |
10 | -------------------------------------------------------------------------------- /flow/modules/help/VCA.html: -------------------------------------------------------------------------------- 1 | Amplifies all of the partials by a given amount. 2 | 3 |

Partials are amplified by multiplying their amplitudes first against Mod, and then against Scale. 4 | 5 |

6 |
Input 7 |
The input partials to amplify 8 |
Mod 9 |
Ranges from 0...1, and used to modulate the VCA amplitude. 10 |
Scale 11 |
Ranged from 0...8, and normally used to manually set the maximum amplitude modulation. 12 |
13 | -------------------------------------------------------------------------------- /flow/modules/help/WaveTable.html: -------------------------------------------------------------------------------- 1 | Outputs partials from wavetable. 2 | 3 |

Traditionaly a wavetable is a list of single-cycle waves, and you can modulate which wave is being outputted. Flow doesn't have waves: instead Flow's wavetable is a list of sets of partials: the effect is the same. 4 | 5 |

The Wavetable module can load the following wavetables: 6 | 7 |

    8 |
  • Sysex files for Waldorf Blofeld wavetables. These files end end in .syx or .SYX. See the About pane for information about where to find them. 9 | 10 |

  • WAV files from waveeditoneline.com. These files are a concatenation of 128 waves, each of which is 256 samples. The WAV files must be 16-bit signed integer PCM, Mono only, and end in .wav or .WAV 11 | 12 |

  • WAV files representing an arbitrary raw sound sample. he WAV files must be 16-bit signed integer PCM, Mono only, and end in .wav or .WAV 13 |
14 | 15 |
16 |
Position 17 |
Where in the wavetable we should select the wave to output. 18 |
Interpolate 19 |
If the position specified is in between two waves, should we output a wave that is the interpolation (average) of the two, or should we just output the wave that is nearest? 20 |
Wavetable... 21 |
Loads the wavetable either from WAV or from Blofeld sysex 22 |
Sample... 23 |
Loads a sample as if it were wavetable. This does some additional smoothing on the sample to convert it appropriately. 24 |
25 | -------------------------------------------------------------------------------- /flow/modules/help/Waves.html: -------------------------------------------------------------------------------- 1 | A collection of harmonics drawn from the single-cycle waves of several classic synthesizers 2 | . 3 | 4 |

You can select harmonics for two sound sources, which are mixed. The harmonics are drawn from single-cycle waves of the Kawai K3, Ensoniq SQ-80, Prophet VS, and Casio CZ series. See the manual for more details. 5 | 6 |

7 |
Mix 8 |
The degree of the first source versus the second source. 9 |
Sound 10 |
The first source. 11 |
Sound 2 12 |
The second source 13 |
Normalize 14 |
The result should be normalized prior to output. 15 |
16 | -------------------------------------------------------------------------------- /flow/modules/waves/LICENSE.txt: -------------------------------------------------------------------------------- 1 | The harmonics in this collection are licensed under 2 | https://creativecommons.org/licenses/by/4.0/ 3 | 4 | See the manual and the wavesources file for information 5 | about the location and sources of the sound files from 6 | which these harmonics were originally extracted. 7 | -------------------------------------------------------------------------------- /flow/modules/waves/wavesources.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/modules/waves/wavesources.tar.gz -------------------------------------------------------------------------------- /flow/patches/Apparition.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Apparition.flow -------------------------------------------------------------------------------- /flow/patches/Astronomical.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Astronomical.flow -------------------------------------------------------------------------------- /flow/patches/Atlantean.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Atlantean.flow -------------------------------------------------------------------------------- /flow/patches/Ayahh.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Ayahh.flow -------------------------------------------------------------------------------- /flow/patches/Bedevilment.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Bedevilment.flow -------------------------------------------------------------------------------- /flow/patches/BlockChime.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/BlockChime.flow -------------------------------------------------------------------------------- /flow/patches/Borealis.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Borealis.flow -------------------------------------------------------------------------------- /flow/patches/Chime.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Chime.flow -------------------------------------------------------------------------------- /flow/patches/Collision.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Collision.flow -------------------------------------------------------------------------------- /flow/patches/Convergence.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Convergence.flow -------------------------------------------------------------------------------- /flow/patches/Detuned.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Detuned.flow -------------------------------------------------------------------------------- /flow/patches/Drawbars.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Drawbars.flow -------------------------------------------------------------------------------- /flow/patches/Droid.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Droid.flow -------------------------------------------------------------------------------- /flow/patches/Droplets.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Droplets.flow -------------------------------------------------------------------------------- /flow/patches/Effervescence.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Effervescence.flow -------------------------------------------------------------------------------- /flow/patches/ElasticBass.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/ElasticBass.flow -------------------------------------------------------------------------------- /flow/patches/Energize.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Energize.flow -------------------------------------------------------------------------------- /flow/patches/Enrichment.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Enrichment.flow -------------------------------------------------------------------------------- /flow/patches/Fascination.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Fascination.flow -------------------------------------------------------------------------------- /flow/patches/Fatness.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Fatness.flow -------------------------------------------------------------------------------- /flow/patches/Footsteps.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Footsteps.flow -------------------------------------------------------------------------------- /flow/patches/Giacomo.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Giacomo.flow -------------------------------------------------------------------------------- /flow/patches/Glitter.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Glitter.flow -------------------------------------------------------------------------------- /flow/patches/Harm.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Harm.flow -------------------------------------------------------------------------------- /flow/patches/Herald.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Herald.flow -------------------------------------------------------------------------------- /flow/patches/IComeInPeace.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/IComeInPeace.flow -------------------------------------------------------------------------------- /flow/patches/Idemnification.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Idemnification.flow -------------------------------------------------------------------------------- /flow/patches/Instability.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Instability.flow -------------------------------------------------------------------------------- /flow/patches/Jawa.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Jawa.flow -------------------------------------------------------------------------------- /flow/patches/JerkedAround.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/JerkedAround.flow -------------------------------------------------------------------------------- /flow/patches/Juice.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Juice.flow -------------------------------------------------------------------------------- /flow/patches/Kotobell.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Kotobell.flow -------------------------------------------------------------------------------- /flow/patches/Linearity.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Linearity.flow -------------------------------------------------------------------------------- /flow/patches/LowDrone.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/LowDrone.flow -------------------------------------------------------------------------------- /flow/patches/Marimba.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Marimba.flow -------------------------------------------------------------------------------- /flow/patches/Melancholy.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Melancholy.flow -------------------------------------------------------------------------------- /flow/patches/NoisyBass.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/NoisyBass.flow -------------------------------------------------------------------------------- /flow/patches/OctaveChime.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/OctaveChime.flow -------------------------------------------------------------------------------- /flow/patches/Order.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Order.flow -------------------------------------------------------------------------------- /flow/patches/Owwee.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Owwee.flow -------------------------------------------------------------------------------- /flow/patches/PeacefulPlanet.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/PeacefulPlanet.flow -------------------------------------------------------------------------------- /flow/patches/Percolation.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Percolation.flow -------------------------------------------------------------------------------- /flow/patches/PewPewPew.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/PewPewPew.flow -------------------------------------------------------------------------------- /flow/patches/Phantasm.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Phantasm.flow -------------------------------------------------------------------------------- /flow/patches/PianoSparks.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/PianoSparks.flow -------------------------------------------------------------------------------- /flow/patches/Pizzicato.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Pizzicato.flow -------------------------------------------------------------------------------- /flow/patches/Plop.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Plop.flow -------------------------------------------------------------------------------- /flow/patches/Plucky.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Plucky.flow -------------------------------------------------------------------------------- /flow/patches/PopBass.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/PopBass.flow -------------------------------------------------------------------------------- /flow/patches/PopcornInTheTunnel.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/PopcornInTheTunnel.flow -------------------------------------------------------------------------------- /flow/patches/Pwaaaah.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Pwaaaah.flow -------------------------------------------------------------------------------- /flow/patches/README.md: -------------------------------------------------------------------------------- 1 | # Flow Patches 2 | 3 | A collection of patches made with Flow. 4 | 5 | * **This Directory** 6 | Primary patches 7 | 8 | * **Experiments** 9 | Experimental patches you might find helpful or interesting 10 | 11 | * **Macros** 12 | Utility patches useful as modules loaded into other patches 13 | 14 | * **Percussion** 15 | Drum sounds 16 | -------------------------------------------------------------------------------- /flow/patches/RandomK5.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/RandomK5.flow -------------------------------------------------------------------------------- /flow/patches/ScaleBass.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/ScaleBass.flow -------------------------------------------------------------------------------- /flow/patches/Sequentialism.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Sequentialism.flow -------------------------------------------------------------------------------- /flow/patches/ShimmerBells.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/ShimmerBells.flow -------------------------------------------------------------------------------- /flow/patches/SpringMallet.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/SpringMallet.flow -------------------------------------------------------------------------------- /flow/patches/Starlight.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Starlight.flow -------------------------------------------------------------------------------- /flow/patches/Steel.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Steel.flow -------------------------------------------------------------------------------- /flow/patches/Sunshine.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Sunshine.flow -------------------------------------------------------------------------------- /flow/patches/SuperSawStab.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/SuperSawStab.flow -------------------------------------------------------------------------------- /flow/patches/SuperSquare.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/SuperSquare.flow -------------------------------------------------------------------------------- /flow/patches/Swirls.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Swirls.flow -------------------------------------------------------------------------------- /flow/patches/Synchronization.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Synchronization.flow -------------------------------------------------------------------------------- /flow/patches/Templar.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Templar.flow -------------------------------------------------------------------------------- /flow/patches/ThirdRail.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/ThirdRail.flow -------------------------------------------------------------------------------- /flow/patches/Tinklepad.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Tinklepad.flow -------------------------------------------------------------------------------- /flow/patches/Tremble.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Tremble.flow -------------------------------------------------------------------------------- /flow/patches/Trinkets.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Trinkets.flow -------------------------------------------------------------------------------- /flow/patches/TubularBell.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/TubularBell.flow -------------------------------------------------------------------------------- /flow/patches/Turbulence.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Turbulence.flow -------------------------------------------------------------------------------- /flow/patches/Undercurrent.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Undercurrent.flow -------------------------------------------------------------------------------- /flow/patches/Undulation.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Undulation.flow -------------------------------------------------------------------------------- /flow/patches/Vacillation.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Vacillation.flow -------------------------------------------------------------------------------- /flow/patches/Vigor.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Vigor.flow -------------------------------------------------------------------------------- /flow/patches/WarmOrganPad.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/WarmOrganPad.flow -------------------------------------------------------------------------------- /flow/patches/Whiplash.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Whiplash.flow -------------------------------------------------------------------------------- /flow/patches/Whoa.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Whoa.flow -------------------------------------------------------------------------------- /flow/patches/Zephyr.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/Zephyr.flow -------------------------------------------------------------------------------- /flow/patches/experiments/Aliasing.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/experiments/Aliasing.flow -------------------------------------------------------------------------------- /flow/patches/experiments/Bell.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/experiments/Bell.flow -------------------------------------------------------------------------------- /flow/patches/experiments/Formant Test.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/experiments/Formant Test.flow -------------------------------------------------------------------------------- /flow/patches/experiments/README.md: -------------------------------------------------------------------------------- 1 | # Flow Experimental Patches 2 | 3 | This is a small collection of interesting experimental patches. 4 | 5 | * **Aliasing** 6 | A demonstration of use of the Alias module to show the effect of aliasing (foldback). 7 | 8 | * **Bell** 9 | A church bell simulation. This uses individual envelopes to control the prime, tierce, etc. harmonics of a church bell. 10 | 11 | * **Formant Test** 12 | A test of the Formant module. 13 | 14 | * **Shepard Tone** 15 | A Shepard Tone is the "barber shop pole" of sounds -- a patch which presents a sound that feels like it's forever going up by introducing low frequencies and slowly tamping out the high oes. 16 | -------------------------------------------------------------------------------- /flow/patches/experiments/ShepardTone.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/experiments/ShepardTone.flow -------------------------------------------------------------------------------- /flow/patches/macros/AhOoh.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/macros/AhOoh.flow -------------------------------------------------------------------------------- /flow/patches/macros/AhOohDemo.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/macros/AhOohDemo.flow -------------------------------------------------------------------------------- /flow/patches/macros/Bass Filter.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/macros/Bass Filter.flow -------------------------------------------------------------------------------- /flow/patches/macros/BrickWallFilter.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/macros/BrickWallFilter.flow -------------------------------------------------------------------------------- /flow/patches/macros/CCHarmonics.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/macros/CCHarmonics.flow -------------------------------------------------------------------------------- /flow/patches/macros/CCHarmonics.old.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/macros/CCHarmonics.old.flow -------------------------------------------------------------------------------- /flow/patches/macros/Drift.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/macros/Drift.flow -------------------------------------------------------------------------------- /flow/patches/macros/README.md: -------------------------------------------------------------------------------- 1 | # Flow Macros 2 | 3 | Flow macros are patches meant to be loaded as modules inside other patches. This collection of macros may prove useful to you as modules. 4 | 5 | * **Bass Filter** 6 | Boosts the bass in a sound below a certain cutoff frequency 7 | 8 | * **Brick Wall Filter** 9 | Eliminates all partials above a certain cutoff frequency 10 | 11 | * **CC Harmonics** 12 | Controls the amplitudes of harmonics 1 ... 96 independently via CC values sent from a MIDI controller. You can use this patch to generate sounds from scratch, or use it in combination with AmpMath (using "multiply") to modify the amplitudes of harmonics from an existing sound. 13 | 14 | * **Drift** 15 | Slightly randomizes the partial frequencies of a sound each Note On, creating a VCO drift kind of thing. Also randomizes the pan position of the voice, creating a pan spread kind of thing. 16 | 17 | * **Random Fatten** 18 | Fattens a sound but randomly changes the degree of fattening 19 | 20 | * **Super Saw** 21 | A bad attempt at a super saw oscillator 22 | 23 | * **Tamp** 24 | Starting at some cutoff frequency, linearly cuts down the amplitude of high harmonics until they reach 0 at around 22 KHz. 25 | 26 | * **Waver** 27 | Adds random noise to an existing modulation signal, perhaps to humanise it. 28 | -------------------------------------------------------------------------------- /flow/patches/macros/RandomFatten.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/macros/RandomFatten.flow -------------------------------------------------------------------------------- /flow/patches/macros/SuperSaw.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/macros/SuperSaw.flow -------------------------------------------------------------------------------- /flow/patches/macros/Tamp.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/macros/Tamp.flow -------------------------------------------------------------------------------- /flow/patches/macros/Waver.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/macros/Waver.flow -------------------------------------------------------------------------------- /flow/patches/percussion/Aftershock.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/percussion/Aftershock.flow -------------------------------------------------------------------------------- /flow/patches/percussion/Blaster.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/percussion/Blaster.flow -------------------------------------------------------------------------------- /flow/patches/percussion/Clang.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/percussion/Clang.flow -------------------------------------------------------------------------------- /flow/patches/percussion/Click.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/percussion/Click.flow -------------------------------------------------------------------------------- /flow/patches/percussion/Crack.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/percussion/Crack.flow -------------------------------------------------------------------------------- /flow/patches/percussion/DetunedTom.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/percussion/DetunedTom.flow -------------------------------------------------------------------------------- /flow/patches/percussion/DissolveToNoise.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/percussion/DissolveToNoise.flow -------------------------------------------------------------------------------- /flow/patches/percussion/Handclap.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/percussion/Handclap.flow -------------------------------------------------------------------------------- /flow/patches/percussion/HeavySpring.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/percussion/HeavySpring.flow -------------------------------------------------------------------------------- /flow/patches/percussion/HighHat.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/percussion/HighHat.flow -------------------------------------------------------------------------------- /flow/patches/percussion/Kick.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/percussion/Kick.flow -------------------------------------------------------------------------------- /flow/patches/percussion/MetalKick.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/percussion/MetalKick.flow -------------------------------------------------------------------------------- /flow/patches/percussion/MoreCowbell.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/percussion/MoreCowbell.flow -------------------------------------------------------------------------------- /flow/patches/percussion/Pop.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/percussion/Pop.flow -------------------------------------------------------------------------------- /flow/patches/percussion/Snap.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/percussion/Snap.flow -------------------------------------------------------------------------------- /flow/patches/percussion/Snip.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/percussion/Snip.flow -------------------------------------------------------------------------------- /flow/patches/percussion/Thump.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/percussion/Thump.flow -------------------------------------------------------------------------------- /flow/patches/percussion/Thwang.flow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/flow/patches/percussion/Thwang.flow -------------------------------------------------------------------------------- /flow/utilities/StringUtilities.java: -------------------------------------------------------------------------------- 1 | /*** 2 | Copyright 2020 by Sean Luke 3 | Licensed under the Apache License version 2.0 4 | */ 5 | 6 | package flow.utilities; 7 | import java.io.*; 8 | import java.util.*; 9 | 10 | public class StringUtilities 11 | { 12 | public static String read(File file) 13 | { 14 | try 15 | { 16 | return read(new FileInputStream(file)); 17 | } 18 | catch (Exception ex) 19 | { 20 | ex.printStackTrace(); 21 | return null; 22 | } 23 | } 24 | 25 | public static String read(InputStream stream) 26 | { 27 | try 28 | { 29 | BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); 30 | StringBuilder build = new StringBuilder(); 31 | char[] buf = new char[1024]; 32 | 33 | while(true) 34 | { 35 | int val = reader.read(buf, 0, buf.length); 36 | if (val < 0) break; 37 | build.append(buf, 0, val); 38 | } 39 | return build.toString(); 40 | } 41 | catch (Exception ex) 42 | { 43 | ex.printStackTrace(); 44 | return null; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /flow/utilities/WavFileException.java: -------------------------------------------------------------------------------- 1 | package flow.utilities; 2 | 3 | /** 4 | * Wav file Exception class 5 | * A.Greensted 6 | * http://www.labbookpages.co.uk 7 | * 8 | * File format is based on the information from 9 | * http://www.sonicspot.com/guide/wavefiles.html 10 | * http://www.blitter.com/~russtopia/MIDI/~jglatt/tech/wave.htm 11 | * 12 | * Version 1.0 13 | */ 14 | 15 | public class WavFileException extends Exception 16 | { 17 | public WavFileException() 18 | { 19 | super(); 20 | } 21 | 22 | public WavFileException(String message) 23 | { 24 | super(message); 25 | } 26 | 27 | public WavFileException(String message, Throwable cause) 28 | { 29 | super(message, cause); 30 | } 31 | 32 | public WavFileException(Throwable cause) 33 | { 34 | super(cause); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /libraries/README.md: -------------------------------------------------------------------------------- 1 | INSTALLATION 2 | 3 | Flow uses coremidi4j. You don't need to install it, it's part of Flow's jar file and executable. 4 | 5 | Flow also uses org.json in order to save and load patches. 6 | 7 | 8 | 9 | DISTRIBUTION 10 | 11 | The Jar File coremidi4j-1.1.jar is distributed under the Eclipse Common License. 12 | Edisyn does not modify or extend it, but just links against it. If you would like 13 | the source code to this jar file, you're in luck! It's embedded within the jar 14 | file itself, in a subdirectory called "source". 15 | 16 | The CoreMidi4J distribution is maintained here: 17 | https://github.com/DerekCook/CoreMidi4J 18 | 19 | I'd go there for the most recent copies. 20 | 21 | The Jar File json.jar is distributed under the JSON License. 22 | 23 | -------------------------------------------------------------------------------- /libraries/coremidi4j-1.5.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/libraries/coremidi4j-1.5.jar -------------------------------------------------------------------------------- /libraries/json.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclab/flow/f6c970850408ee4eb0f526492994a4aecd449c35/libraries/json.jar --------------------------------------------------------------------------------