diff --git a/src/controls/adsr2/ConfigureRampControlPanel.svelte b/src/controls/adsr2/ConfigureRampControlPanel.svelte index b4ec4150..f6606ac8 100644 --- a/src/controls/adsr2/ConfigureRampControlPanel.svelte +++ b/src/controls/adsr2/ConfigureRampControlPanel.svelte @@ -35,7 +35,12 @@ const handleChange = (key: string, val: any) => state.update(s => ({ ...s, [key]: val })); -
+ +
e.preventDefault()} +> -
+ +
e.preventDefault()} +> = ({ }, [synth] )} - adsrs={synth.getAdsrs()} + adsrs={dbg(synth.getAdsrs())} onAdsrChange={useCallback( (adsrIx: number, newAdsr: AdsrParams) => synth.handleAdsrChange(adsrIx, newAdsr), [synth] diff --git a/src/index.tsx b/src/index.tsx index 81de2372..f4dbf004 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -66,7 +66,7 @@ const createGlobalUI = (engine: typeof import('./engine')) => { } }; -if (typeof AudioWorkletNode === 'undefined') { +if (typeof WebAssembly === 'undefined' || typeof AudioWorkletNode === 'undefined') { createBrowserNotSupportedMessage(); } else { initSentry(); diff --git a/src/init-composition.json b/src/init-composition.json index 2a991bb9..33c4935a 100644 --- a/src/init-composition.json +++ b/src/init-composition.json @@ -1 +1 @@ -{"globalTempo":"120.0","graphEditor_eeec5678-29c3-39d6-7b03-7284211e1b55":"{\"last_node_id\":\"da2f5629-e246-5d19-9f99-8907354a427b\",\"last_link_id\":25,\"nodes\":[{\"id\":\"eda73024-8e6a-eecb-ac64-a3581fc1d886\",\"type\":\"audio/audioConnectables\",\"pos\":[100,130],\"size\":{\"0\":140,\"1\":26},\"flags\":{},\"order\":0,\"mode\":0,\"outputs\":[{\"name\":\"midi out\",\"type\":\"midi\",\"links\":[1]}],\"title\":\"MIDI Keyboard\",\"properties\":{}},{\"id\":\"0a9d84e5-03d9-0194-01c4-3504c93eea1e\",\"type\":\"audio/audioConnectables\",\"pos\":[340,130],\"size\":{\"0\":140,\"1\":26},\"flags\":{},\"order\":2,\"mode\":0,\"inputs\":[{\"name\":\"midi_in\",\"type\":\"midi\",\"link\":1}],\"outputs\":[{\"name\":\"midi_out\",\"type\":\"midi\",\"links\":[14]}],\"title\":\"MIDI Editor\",\"properties\":{}},{\"id\":\"1\",\"type\":\"customAudio/destination\",\"pos\":[1315,143],\"size\":{\"0\":140,\"1\":26},\"flags\":{},\"order\":9,\"mode\":0,\"inputs\":[{\"name\":\"input\",\"type\":\"customAudio\",\"link\":25}],\"title\":\"Destination\",\"properties\":{}},{\"id\":\"d427ee12-b908-85ba-0c63-dc481ac33df2\",\"type\":\"audio/audioConnectables\",\"pos\":[1128,133],\"size\":{\"0\":140,\"1\":126},\"flags\":{},\"order\":8,\"mode\":0,\"inputs\":[{\"name\":\"input\",\"type\":\"customAudio\",\"link\":24},{\"name\":\"roomSize\",\"type\":\"number\",\"link\":null},{\"name\":\"damping\",\"type\":\"number\",\"link\":null},{\"name\":\"wetLevel\",\"type\":\"number\",\"link\":null},{\"name\":\"dryLevel\",\"type\":\"number\",\"link\":null},{\"name\":\"width\",\"type\":\"number\",\"link\":null}],\"outputs\":[{\"name\":\"output\",\"type\":\"customAudio\",\"links\":[25]}],\"title\":\"Reverb\",\"properties\":{}},{\"id\":\"2\",\"type\":\"customAudio/compressor\",\"pos\":[938,134],\"size\":{\"0\":140,\"1\":26},\"flags\":{\"collapsed\":false},\"order\":7,\"mode\":0,\"inputs\":[{\"name\":\"input\",\"type\":\"customAudio\",\"link\":23}],\"outputs\":[{\"name\":\"output\",\"type\":\"customAudio\",\"links\":[24]}],\"title\":\"Compressor\",\"properties\":{}},{\"id\":\"3\",\"type\":\"customAudio/LFO\",\"pos\":[148,309],\"size\":{\"0\":140,\"1\":26},\"flags\":{},\"order\":4,\"mode\":0,\"inputs\":[{\"name\":\"frequency\",\"type\":\"number\",\"link\":4}],\"outputs\":[{\"name\":\"signal\",\"type\":\"number\",\"links\":[2]}],\"title\":\"LFO\",\"properties\":{}},{\"id\":\"6\",\"type\":\"customAudio/scaleAndShift\",\"pos\":[-102,325],\"size\":{\"0\":194.8,\"1\":86},\"flags\":{},\"order\":3,\"mode\":0,\"inputs\":[{\"name\":\"input\",\"type\":\"number\",\"link\":3},{\"name\":\"scale\",\"type\":\"number\",\"link\":null},{\"name\":\"pre_scale_shift\",\"type\":\"number\",\"link\":null},{\"name\":\"post_scale_shift\",\"type\":\"number\",\"link\":null}],\"outputs\":[{\"name\":\"output\",\"type\":\"number\",\"links\":[4]}],\"title\":\"Scale + Shift\",\"properties\":{\"input\":{}}},{\"id\":\"5\",\"type\":\"customAudio/LFO\",\"pos\":[-289,325],\"size\":{\"0\":140,\"1\":26},\"flags\":{},\"order\":1,\"mode\":0,\"inputs\":[{\"name\":\"frequency\",\"type\":\"number\",\"link\":null}],\"outputs\":[{\"name\":\"signal\",\"type\":\"number\",\"links\":[3]}],\"title\":\"LFO\",\"properties\":{}},{\"id\":\"91a95325-22b2-efa2-7c60-20badc2809f2\",\"type\":\"audio/audioConnectables\",\"pos\":[580,130],\"size\":{\"0\":312.4,\"1\":246},\"flags\":{},\"order\":6,\"mode\":0,\"inputs\":[{\"name\":\"midi\",\"type\":\"midi\",\"link\":14},{\"name\":\"synth_0_filter_frequency\",\"type\":\"number\",\"link\":null},{\"name\":\"synth_0_filter_detune\",\"type\":\"number\",\"link\":null},{\"name\":\"synth_0_fm_input_0\",\"type\":\"number\",\"link\":15},{\"name\":\"synth_0_fm_input_1\",\"type\":\"number\",\"link\":null},{\"name\":\"synth_0_fm_input_2\",\"type\":\"number\",\"link\":null},{\"name\":\"synth_0_fm_input_3\",\"type\":\"number\",\"link\":null},{\"name\":\"synth_0_fm_input_4\",\"type\":\"number\",\"link\":null},{\"name\":\"synth_0_fm_input_5\",\"type\":\"number\",\"link\":null},{\"name\":\"synth_0_fm_input_6\",\"type\":\"number\",\"link\":null},{\"name\":\"synth_0_fm_input_7\",\"type\":\"number\",\"link\":null},{\"name\":\"synth_0_filter_q\",\"type\":\"number\",\"link\":null}],\"outputs\":[{\"name\":\"masterOutput\",\"type\":\"customAudio\",\"links\":[23]}],\"title\":\"Synth Designer\",\"properties\":{\"synth_0_fm_input_0\":{},\"synth_0_fm_input_1\":{},\"synth_0_fm_input_2\":{},\"synth_0_fm_input_3\":{},\"synth_0_fm_input_4\":{},\"synth_0_fm_input_5\":{},\"synth_0_fm_input_6\":{},\"synth_0_fm_infput_7\":{}}},{\"id\":\"4\",\"type\":\"customAudio/scaleAndShift\",\"pos\":[326,288],\"size\":{\"0\":194.8,\"1\":86},\"flags\":{},\"order\":5,\"mode\":0,\"inputs\":[{\"name\":\"input\",\"type\":\"number\",\"link\":2},{\"name\":\"scale\",\"type\":\"number\",\"link\":null},{\"name\":\"pre_scale_shift\",\"type\":\"number\",\"link\":null},{\"name\":\"post_scale_shift\",\"type\":\"number\",\"link\":null}],\"outputs\":[{\"name\":\"output\",\"type\":\"number\",\"links\":[15]}],\"title\":\"Scale + Shift\",\"properties\":{\"input\":{}}}],\"links\":[[1,\"eda73024-8e6a-eecb-ac64-a3581fc1d886\",0,\"0a9d84e5-03d9-0194-01c4-3504c93eea1e\",0,\"midi\"],[2,\"3\",0,\"4\",0,\"number\"],[3,\"5\",0,\"6\",0,\"number\"],[4,\"6\",0,\"3\",0,\"number\"],[14,\"0a9d84e5-03d9-0194-01c4-3504c93eea1e\",0,\"91a95325-22b2-efa2-7c60-20badc2809f2\",0,\"midi\"],[15,\"4\",0,\"91a95325-22b2-efa2-7c60-20badc2809f2\",3,\"number\"],[23,\"91a95325-22b2-efa2-7c60-20badc2809f2\",0,\"2\",0,\"customAudio\"],[24,\"2\",0,\"d427ee12-b908-85ba-0c63-dc481ac33df2\",0,\"customAudio\"],[25,\"d427ee12-b908-85ba-0c63-dc481ac33df2\",0,\"1\",0,\"customAudio\"]],\"groups\":[],\"config\":{},\"extra\":{},\"version\":0.4,\"selectedNodeVcId\":\"4\"}","vcmState":"{\"view_context_ids\":[\"cef722d2-1eac-f009-c499-4a24c2166d7d\",\"eeec5678-29c3-39d6-7b03-7284211e1b55\",\"eda73024-8e6a-eecb-ac64-a3581fc1d886\",\"0a9d84e5-03d9-0194-01c4-3504c93eea1e\",\"91a95325-22b2-efa2-7c60-20badc2809f2\",\"d427ee12-b908-85ba-0c63-dc481ac33df2\"],\"active_view_ix\":0,\"patch_network_connections\":[[{\"vcId\":\"eda73024-8e6a-eecb-ac64-a3581fc1d886\",\"name\":\"midi out\"},{\"vcId\":\"0a9d84e5-03d9-0194-01c4-3504c93eea1e\",\"name\":\"midi_in\"}],[{\"vcId\":\"3\",\"name\":\"signal\"},{\"vcId\":\"4\",\"name\":\"input\"}],[{\"vcId\":\"5\",\"name\":\"signal\"},{\"vcId\":\"6\",\"name\":\"input\"}],[{\"vcId\":\"6\",\"name\":\"output\"},{\"vcId\":\"3\",\"name\":\"frequency\"}],[{\"vcId\":\"0a9d84e5-03d9-0194-01c4-3504c93eea1e\",\"name\":\"midi_out\"},{\"vcId\":\"91a95325-22b2-efa2-7c60-20badc2809f2\",\"name\":\"midi\"}],[{\"vcId\":\"4\",\"name\":\"output\"},{\"vcId\":\"91a95325-22b2-efa2-7c60-20badc2809f2\",\"name\":\"synth_0_fm_input_0\"}],[{\"vcId\":\"91a95325-22b2-efa2-7c60-20badc2809f2\",\"name\":\"masterOutput\"},{\"vcId\":\"2\",\"name\":\"input\"}],[{\"vcId\":\"d427ee12-b908-85ba-0c63-dc481ac33df2\",\"name\":\"output\"},{\"vcId\":\"1\",\"name\":\"input\"}],[{\"vcId\":\"2\",\"name\":\"output\"},{\"vcId\":\"d427ee12-b908-85ba-0c63-dc481ac33df2\",\"name\":\"input\"}]],\"foreign_connectables\":[{\"type\":\"customAudio/destination\",\"id\":\"1\",\"serializedState\":{}},{\"type\":\"customAudio/compressor\",\"id\":\"2\",\"serializedState\":{\"bottomRatio\":0.2,\"bypass\":false,\"detectionMode\":\"peak\",\"high\":{\"attack_ms\":3,\"bottom_ratio\":1,\"bottom_threshold\":-40.8,\"gain\":1,\"mix\":1,\"release_ms\":250,\"top_ratio\":66.7,\"top_threshold\":-33.8},\"knee\":30,\"lookaheadMs\":1.2,\"low\":{\"attack_ms\":3,\"bottom_ratio\":1,\"bottom_threshold\":-40.8,\"gain\":1,\"mix\":1,\"release_ms\":250,\"top_ratio\":444,\"top_threshold\":-24.4105},\"mid\":{\"attack_ms\":3,\"bottom_ratio\":1,\"bottom_threshold\":-41.8,\"gain\":1,\"mix\":1,\"release_ms\":250,\"top_ratio\":66.7,\"top_threshold\":-30.2},\"mix\":1,\"postGain\":1,\"preGain\":1,\"sab\":null,\"topRatio\":12}},{\"type\":\"customAudio/LFO\",\"id\":\"3\",\"serializedState\":{\"frequency\":1.303166747093201,\"gain\":1,\"offset\":0,\"waveform\":\"sine\"}},{\"type\":\"customAudio/scaleAndShift\",\"id\":\"4\",\"serializedState\":{\"input_min_max\":[-1,1],\"input_range\":[-1,1],\"output_min_max\":[0,1.5],\"output_range\":[0,1.2]}},{\"type\":\"customAudio/LFO\",\"id\":\"5\",\"serializedState\":{\"frequency\":0.342,\"gain\":1,\"offset\":0,\"waveform\":\"triangle\"}},{\"type\":\"customAudio/scaleAndShift\",\"id\":\"6\",\"serializedState\":{\"input_min_max\":[-1,1],\"input_range\":[-1,1],\"output_min_max\":[0,2],\"output_range\":[0,1.2]}}]}","vc_cef722d2-1eac-f009-c499-4a24c2166d7d":"{\"minimal_def\":{\"name\":\"welcome_page\",\"uuid\":\"cef722d2-1eac-f009-c499-4a24c2166d7d\",\"title\":\"Welcome Page\"}}","vc_eda73024-8e6a-eecb-ac64-a3581fc1d886":"{\"minimal_def\":{\"name\":\"midi_keyboard\",\"uuid\":\"eda73024-8e6a-eecb-ac64-a3581fc1d886\",\"title\":\"MIDI Keyboard\"}}","vc_eeec5678-29c3-39d6-7b03-7284211e1b55":"{\"minimal_def\":{\"name\":\"graph_editor\",\"uuid\":\"eeec5678-29c3-39d6-7b03-7284211e1b55\",\"title\":\"Graph Editor\"}}","MIDIKeyboard_eda73024-8e6a-eecb-ac64-a3581fc1d886":"{\"mode\":1,\"octaveOffset\":1,\"mappedOutputs\":[],\"lastSeenModWheel\":0,\"lastSeenPitchBend\":0,\"lastSeenRawMIDIControlValuesByControlIndex\":{}}","synthDesigner_91a95325-22b2-efa2-7c60-20badc2809f2":"{\"synths\":[{\"fmSynthConfig\":{\"useLegacyWavetableControls\":false,\"modulationMatrix\":[[{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0}],[{\"type\":\"param buffer\",\"value\":-0.1,\"buffer index\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0}],[{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0}],[{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0}],[{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0}],[{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0}],[{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0}],[{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0}]],\"outputWeights\":[{\"type\":\"constant\",\"value\":0.71},{\"type\":\"constant\",\"value\":0.05},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0}],\"operatorConfigs\":[{\"frequency\":{\"multiplier\":1,\"type\":\"base frequency multiplier\"},\"type\":\"sawtooth oscillator\",\"unison\":16,\"unisonDetune\":{\"type\":\"constant\",\"value\":28.923},\"unisonPhaseRandomization\":{\"enabled\":false}},{\"frequency\":{\"adsr index\":0,\"multiplier\":0.5,\"scale\":20000,\"shift\":0,\"type\":\"base frequency multiplier\"},\"type\":\"sine oscillator\",\"unison\":1,\"unisonDetune\":{\"type\":\"constant\",\"value\":1},\"unisonPhaseRandomization\":{\"enabled\":false}},{\"frequency\":{\"multiplier\":1,\"type\":\"base frequency multiplier\"},\"type\":\"sine oscillator\",\"unison\":1,\"unisonDetune\":{\"type\":\"constant\",\"value\":1},\"unisonPhaseRandomization\":{\"enabled\":false}},{\"frequency\":{\"multiplier\":1,\"type\":\"base frequency multiplier\"},\"type\":\"sine oscillator\",\"unison\":1,\"unisonDetune\":{\"type\":\"constant\",\"value\":1},\"unisonPhaseRandomization\":{\"enabled\":false}},{\"frequency\":{\"multiplier\":1,\"type\":\"base frequency multiplier\"},\"type\":\"sine oscillator\",\"unison\":1,\"unisonDetune\":{\"type\":\"constant\",\"value\":1},\"unisonPhaseRandomization\":{\"enabled\":false}},{\"frequency\":{\"multiplier\":1,\"type\":\"base frequency multiplier\"},\"type\":\"sine oscillator\",\"unison\":1,\"unisonDetune\":{\"type\":\"constant\",\"value\":1},\"unisonPhaseRandomization\":{\"enabled\":false}},{\"frequency\":{\"multiplier\":1,\"type\":\"base frequency multiplier\"},\"type\":\"sine oscillator\",\"unison\":1,\"unisonDetune\":{\"type\":\"constant\",\"value\":1},\"unisonPhaseRandomization\":{\"enabled\":false}},{\"frequency\":{\"multiplier\":1,\"type\":\"base frequency multiplier\"},\"type\":\"sine oscillator\",\"unison\":1,\"unisonDetune\":{\"type\":\"constant\",\"value\":1},\"unisonPhaseRandomization\":{\"enabled\":false}}],\"operatorEffects\":[[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null]],\"selectedUI\":{\"type\":\"modulationIndex\",\"srcOperatorIx\":1,\"dstOperatorIx\":0},\"mainEffectChain\":[{\"algorithm\":\"2\",\"isBypassed\":false,\"isCollapsed\":false,\"postGain\":{\"type\":\"constant\",\"value\":2.423},\"preGain\":{\"type\":\"constant\",\"value\":1.63},\"type\":\"soft clipper\"},{\"cutoffFrequency\":{\"adsr index\":0,\"scale\":18499,\"shift\":1,\"type\":\"adsr\",\"value\":797.4},\"drive\":{\"type\":\"constant\",\"value\":4.15},\"resonance\":{\"type\":\"constant\",\"value\":0.342},\"type\":\"moog filter\"},null,null,null,null,null,null,null,null,null,null,null,null,null,null],\"adsrs\":[{\"lenSamples\":{\"type\":\"beats to samples\",\"value\":1.5},\"logScale\":true,\"loopPoint\":null,\"outputRange\":[1,18500],\"releasePoint\":1,\"steps\":[{\"ramper\":{\"type\":\"linear\"},\"x\":0,\"y\":0.85},{\"ramper\":{\"exponent\":0.679,\"type\":\"exponential\"},\"x\":0.195,\"y\":0.81},{\"ramper\":{\"exponent\":0.85,\"type\":\"exponential\"},\"x\":0.4386,\"y\":0.8867},{\"ramper\":{\"exponent\":1.052,\"type\":\"exponential\"},\"x\":0.71,\"y\":0.873},{\"ramper\":{\"exponent\":2.1768,\"type\":\"exponential\"},\"x\":1,\"y\":0.77}],\"audioThreadData\":{\"phaseIndex\":0}}],\"detune\":{\"type\":\"constant\",\"value\":0},\"lastSeenMIDIControlValues\":{},\"wavetableState\":{\"wavetableBanks\":[]},\"gainEnvelope\":{\"audioThreadData\":{\"phaseIndex\":255},\"lenSamples\":{\"type\":\"constant\",\"value\":22050},\"loopPoint\":null,\"releasePoint\":0.996,\"steps\":[{\"ramper\":{\"type\":\"instant\"},\"x\":0,\"y\":0},{\"ramper\":{\"exponent\":1,\"type\":\"exponential\"},\"x\":0.006,\"y\":0.65},{\"ramper\":{\"exponent\":1,\"type\":\"exponential\"},\"x\":0.09,\"y\":0.6},{\"ramper\":{\"exponent\":1,\"type\":\"exponential\"},\"x\":0.996,\"y\":0.6},{\"ramper\":{\"exponent\":1,\"type\":\"exponential\"},\"x\":1,\"y\":0}]},\"sampleMappingState\":{\"stateByOperatorIx\":{}}},\"filter\":{\"type\":\"order 8 lowpass\",\"frequency\":728.2467,\"Q\":3.116,\"gain\":0,\"detune\":0},\"masterGain\":-0.656,\"filterEnvelope\":{\"steps\":[{\"x\":0,\"y\":0.2,\"ramper\":{\"type\":\"exponential\",\"exponent\":0.5}},{\"x\":0.5,\"y\":0.8,\"ramper\":{\"type\":\"exponential\",\"exponent\":0.5}},{\"x\":1,\"y\":0.2,\"ramper\":{\"type\":\"exponential\",\"exponent\":0.5}}],\"lenSamples\":44100,\"loopPoint\":0,\"releasePoint\":0.7,\"audioThreadData\":{\"buffer\":{\"0\":1},\"phaseIndex\":0},\"lengthMode\":0,\"logScale\":false},\"filterADSRLength\":1000,\"pitchMultiplier\":1,\"filterBypassed\":true,\"filterEnvelopeEnabled\":false}]}","vc_91a95325-22b2-efa2-7c60-20badc2809f2":"{\"minimal_def\":{\"name\":\"synth_designer\",\"uuid\":\"91a95325-22b2-efa2-7c60-20badc2809f2\",\"title\":\"Synth Designer\"}}","midiEditor_0a9d84e5-03d9-0194-01c4-3504c93eea1e":"{\"lines\":[{\"midiNumber\":90,\"notes\":[]},{\"midiNumber\":89,\"notes\":[]},{\"midiNumber\":88,\"notes\":[]},{\"midiNumber\":87,\"notes\":[]},{\"midiNumber\":86,\"notes\":[]},{\"midiNumber\":85,\"notes\":[]},{\"midiNumber\":84,\"notes\":[]},{\"midiNumber\":83,\"notes\":[]},{\"midiNumber\":82,\"notes\":[]},{\"midiNumber\":81,\"notes\":[]},{\"midiNumber\":80,\"notes\":[]},{\"midiNumber\":79,\"notes\":[]},{\"midiNumber\":78,\"notes\":[]},{\"midiNumber\":77,\"notes\":[]},{\"midiNumber\":76,\"notes\":[]},{\"midiNumber\":75,\"notes\":[]},{\"midiNumber\":74,\"notes\":[]},{\"midiNumber\":73,\"notes\":[]},{\"midiNumber\":72,\"notes\":[]},{\"midiNumber\":71,\"notes\":[]},{\"midiNumber\":70,\"notes\":[]},{\"midiNumber\":69,\"notes\":[]},{\"midiNumber\":68,\"notes\":[]},{\"midiNumber\":67,\"notes\":[]},{\"midiNumber\":66,\"notes\":[]},{\"midiNumber\":65,\"notes\":[]},{\"midiNumber\":64,\"notes\":[]},{\"midiNumber\":63,\"notes\":[]},{\"midiNumber\":62,\"notes\":[]},{\"midiNumber\":61,\"notes\":[]},{\"midiNumber\":60,\"notes\":[]},{\"midiNumber\":59,\"notes\":[]},{\"midiNumber\":58,\"notes\":[]},{\"midiNumber\":57,\"notes\":[]},{\"midiNumber\":56,\"notes\":[]},{\"midiNumber\":55,\"notes\":[]},{\"midiNumber\":54,\"notes\":[]},{\"midiNumber\":53,\"notes\":[]},{\"midiNumber\":52,\"notes\":[]},{\"midiNumber\":51,\"notes\":[]},{\"midiNumber\":50,\"notes\":[]},{\"midiNumber\":49,\"notes\":[]},{\"midiNumber\":48,\"notes\":[]},{\"midiNumber\":47,\"notes\":[]},{\"midiNumber\":46,\"notes\":[]},{\"midiNumber\":45,\"notes\":[]},{\"midiNumber\":44,\"notes\":[]},{\"midiNumber\":43,\"notes\":[]},{\"midiNumber\":42,\"notes\":[]},{\"midiNumber\":41,\"notes\":[]},{\"midiNumber\":40,\"notes\":[]},{\"midiNumber\":39,\"notes\":[]},{\"midiNumber\":38,\"notes\":[]},{\"midiNumber\":37,\"notes\":[]},{\"midiNumber\":36,\"notes\":[]},{\"midiNumber\":35,\"notes\":[]},{\"midiNumber\":34,\"notes\":[]},{\"midiNumber\":33,\"notes\":[]},{\"midiNumber\":32,\"notes\":[]},{\"midiNumber\":31,\"notes\":[]},{\"midiNumber\":30,\"notes\":[]},{\"midiNumber\":29,\"notes\":[]},{\"midiNumber\":28,\"notes\":[]},{\"midiNumber\":27,\"notes\":[]},{\"midiNumber\":26,\"notes\":[]},{\"midiNumber\":25,\"notes\":[]},{\"midiNumber\":24,\"notes\":[]},{\"midiNumber\":23,\"notes\":[]},{\"midiNumber\":22,\"notes\":[]},{\"midiNumber\":21,\"notes\":[]},{\"midiNumber\":20,\"notes\":[]},{\"midiNumber\":19,\"notes\":[]},{\"midiNumber\":18,\"notes\":[]},{\"midiNumber\":17,\"notes\":[]},{\"midiNumber\":16,\"notes\":[]},{\"midiNumber\":15,\"notes\":[]},{\"midiNumber\":14,\"notes\":[]},{\"midiNumber\":13,\"notes\":[]},{\"midiNumber\":12,\"notes\":[]},{\"midiNumber\":11,\"notes\":[]},{\"midiNumber\":10,\"notes\":[]},{\"midiNumber\":9,\"notes\":[]},{\"midiNumber\":8,\"notes\":[]},{\"midiNumber\":7,\"notes\":[]},{\"midiNumber\":6,\"notes\":[]},{\"midiNumber\":5,\"notes\":[]},{\"midiNumber\":4,\"notes\":[]},{\"midiNumber\":3,\"notes\":[]},{\"midiNumber\":2,\"notes\":[]},{\"midiNumber\":1,\"notes\":[]}],\"view\":{\"pxPerBeat\":32,\"scrollVerticalPx\":0,\"scrollHorizontalBeats\":0,\"beatsPerMeasure\":4},\"beatSnapInterval\":1,\"cursorPosBeats\":0,\"localBPM\":120,\"loopPoint\":null,\"metronomeEnabled\":true}","globalVolume":"20","vc_0a9d84e5-03d9-0194-01c4-3504c93eea1e":"{\"minimal_def\":{\"name\":\"midi_editor\",\"uuid\":\"0a9d84e5-03d9-0194-01c4-3504c93eea1e\",\"title\":\"MIDI Editor\"}}","vc_d427ee12-b908-85ba-0c63-dc481ac33df2":"{\"minimal_def\":{\"name\":\"faust_editor\",\"uuid\":\"d427ee12-b908-85ba-0c63-dc481ac33df2\",\"title\":\"Reverb\"}}","faustEditor_d427ee12-b908-85ba-0c63-dc481ac33df2":"{\"editorContent\":\"/*\\n == SOUL example code ==\\n == Author: Jules via the class Freeverb algorithm ==\\n*/\\n\\n/// Title: An implementation of the classic Freeverb reverb algorithm.\\n\\ngraph Reverb [[ main ]]\\n{\\n input stream float audioIn;\\n output stream float<2> audioOut;\\n\\n input\\n {\\n ReverbParameterProcessorParam.roomSize [[ name: \\\"Room Size\\\", min: 0, max: 100, init: 80, text: \\\"tiny|small|medium|large|hall\\\" ]];\\n ReverbParameterProcessorParam.damping [[ name: \\\"Damping Factor\\\", min: 0, max: 100, init: 50, unit: \\\"%\\\", step: 1 ]];\\n ReverbParameterProcessorParam.wetLevel [[ name: \\\"Wet Level\\\", min: 0, max: 100, init: 33, unit: \\\"%\\\", step: 1 ]];\\n ReverbParameterProcessorParam.dryLevel [[ name: \\\"Dry Level\\\", min: 0, max: 100, init: 40, unit: \\\"%\\\", step: 1 ]];\\n ReverbParameterProcessorParam.width [[ name: \\\"Width\\\", min: 0, max: 100, init: 100, unit: \\\"%\\\", step: 1 ]];\\n }\\n\\n let\\n {\\n dryGainParameterRamp = ParameterRamp (20.0f);\\n wetGain1ParameterRamp = ParameterRamp (20.0f);\\n wetGain2ParameterRamp = ParameterRamp (20.0f);\\n dampingParameterRamp = ParameterRamp (20.0f);\\n feedbackParameterRamp = ParameterRamp (20.0f);\\n\\n reverbChannelLeft = ReverbChannel (0);\\n reverbChannelRight = ReverbChannel (23);\\n }\\n\\n connection\\n {\\n // Parameter outputs to smoothing processors\\n ReverbParameterProcessorParam.dryGainOut -> dryGainParameterRamp.updateParameter;\\n ReverbParameterProcessorParam.wetGain1Out -> wetGain1ParameterRamp.updateParameter;\\n ReverbParameterProcessorParam.wetGain2Out -> wetGain2ParameterRamp.updateParameter;\\n ReverbParameterProcessorParam.dampingOut -> dampingParameterRamp.updateParameter;\\n ReverbParameterProcessorParam.feedbackOut -> feedbackParameterRamp.updateParameter;\\n\\n // Sum the audio\\n audioIn -> Mixer.audioInDry;\\n\\n // Left channel\\n audioIn -> reverbChannelLeft.audioIn;\\n dampingParameterRamp.parameterOut -> reverbChannelLeft.damping;\\n feedbackParameterRamp.parameterOut -> reverbChannelLeft.feedback;\\n reverbChannelLeft -> Mixer.audioInLeftWet;\\n\\n // Right channel\\n audioIn -> reverbChannelRight.audioIn;\\n dampingParameterRamp.parameterOut -> reverbChannelRight.damping;\\n feedbackParameterRamp.parameterOut -> reverbChannelRight.feedback;\\n reverbChannelRight.audioOut -> Mixer.audioInRightWet;\\n\\n // Mix parameters to the mixer\\n dryGainParameterRamp.parameterOut -> Mixer.dryIn;\\n wetGain1ParameterRamp.parameterOut -> Mixer.wet1In;\\n wetGain2ParameterRamp.parameterOut -> Mixer.wet2In;\\n\\n // Write the mixed values to the output\\n Mixer -> audioOut;\\n }\\n}\\n\\n//==============================================================================\\nprocessor AllpassFilter (int bufferSize)\\n{\\n output stream float audioOut;\\n input stream float audioIn;\\n\\n float[bufferSize] buffer;\\n\\n void run()\\n {\\n wrap bufferIndex = 0;\\n\\n loop\\n {\\n let in = audioIn;\\n let bufferedValue = buffer[bufferIndex];\\n\\n buffer[bufferIndex] = in + (bufferedValue * 0.5f);\\n\\n bufferIndex++;\\n audioOut << bufferedValue - in;\\n\\n advance();\\n }\\n }\\n}\\n\\n//==============================================================================\\nprocessor CombFilter (int bufferSize)\\n{\\n output stream float audioOut;\\n input stream float audioIn, dampingIn, feedbackLevelIn;\\n\\n float[bufferSize] buffer;\\n\\n void run()\\n {\\n wrap bufferIndex = 0;\\n\\n let gain = 0.015f;\\n float last = 0.0f;\\n\\n loop\\n {\\n let out = buffer[bufferIndex];\\n audioOut << out;\\n\\n last = (out * (1.0f - dampingIn)) + (last * dampingIn);\\n\\n buffer[bufferIndex] = (gain * audioIn) + (last * feedbackLevelIn);\\n ++bufferIndex;\\n\\n advance();\\n }\\n }\\n}\\n\\n//==============================================================================\\nprocessor Mixer\\n{\\n input stream float audioInDry;\\n input stream float dryIn, wet1In, wet2In,\\n audioInLeftWet, audioInRightWet;\\n\\n output stream float<2> audioOut;\\n\\n void run()\\n {\\n loop\\n {\\n let left = (audioInLeftWet * wet1In) + (audioInRightWet * wet2In);\\n let right = (audioInRightWet * wet1In) + (audioInLeftWet * wet2In);\\n\\n audioOut << float<2> (left, right) + audioInDry * dryIn;\\n advance();\\n }\\n }\\n}\\n\\n\\n//==============================================================================\\n// Converts an input value into a stream (limited to the given slewRate)\\nprocessor ParameterRamp (float slewRate)\\n{\\n input event float updateParameter;\\n output stream float parameterOut;\\n\\n event updateParameter (float newTarget)\\n {\\n targetValue = newTarget;\\n\\n let diff = targetValue - currentValue;\\n let rampSeconds = abs (diff) / slewRate;\\n\\n rampSamples = int (processor.frequency * rampSeconds);\\n rampIncrement = diff / float (rampSamples);\\n }\\n\\n float targetValue;\\n float currentValue;\\n float rampIncrement;\\n int rampSamples;\\n\\n void run()\\n {\\n loop\\n {\\n if (rampSamples > 0)\\n {\\n currentValue += rampIncrement;\\n --rampSamples;\\n }\\n\\n parameterOut << currentValue;\\n advance();\\n }\\n }\\n}\\n\\n//==============================================================================\\n// Correctly applies parameter changes to the streams of input to the algorithm\\nprocessor ReverbParameterProcessorParam\\n{\\n input event float roomSize,\\n damping,\\n wetLevel,\\n dryLevel,\\n width;\\n\\n output event float dryGainOut,\\n wetGain1Out,\\n wetGain2Out,\\n dampingOut,\\n feedbackOut;\\n\\n event roomSize (float newValue) { roomSizeScaled = newValue / 100.0f; onUpdate(); }\\n event damping (float newValue) { dampingScaled = newValue / 100.0f; onUpdate(); }\\n event wetLevel (float newValue) { wetLevelScaled = newValue / 100.0f; onUpdate(); }\\n event dryLevel (float newValue) { dryLevelScaled = newValue / 100.0f; onUpdate(); }\\n event width (float newValue) { widthScaled = newValue / 100.0f; onUpdate(); }\\n\\n float roomSizeScaled = 0.5f;\\n float dampingScaled = 0.5f;\\n float wetLevelScaled = 0.33f;\\n float dryLevelScaled = 0.4f;\\n float widthScaled = 1.0f;\\n\\n void onUpdate()\\n {\\n // Various tuning factors for the reverb\\n let wetScaleFactor = 3.0f;\\n let dryScaleFactor = 2.0f;\\n\\n let roomScaleFactor = 0.28f;\\n let roomOffset = 0.7f;\\n let dampScaleFactor = 0.4f;\\n\\n // Write updated values\\n dryGainOut << dryLevelScaled * dryScaleFactor;\\n wetGain1Out << 0.5f * wetLevelScaled * wetScaleFactor * (1.0f + widthScaled);\\n wetGain2Out << 0.5f * wetLevelScaled * wetScaleFactor * (1.0f - widthScaled);\\n dampingOut << dampingScaled * dampScaleFactor;\\n feedbackOut << roomSizeScaled * roomScaleFactor + roomOffset;\\n }\\n}\\n\\n//==============================================================================\\n// Mono freeverb implementation\\ngraph ReverbChannel (int offset)\\n{\\n input stream float audioIn, damping, feedback;\\n output stream float audioOut;\\n\\n let\\n {\\n allpass_1 = AllpassFilter(225 + offset);\\n allpass_2 = AllpassFilter(341 + offset);\\n allpass_3 = AllpassFilter(441 + offset);\\n allpass_4 = AllpassFilter(556 + offset);\\n\\n comb_1 = CombFilter(1116 + offset);\\n comb_2 = CombFilter(1188 + offset);\\n comb_3 = CombFilter(1277 + offset);\\n comb_4 = CombFilter(1356 + offset);\\n comb_5 = CombFilter(1422 + offset);\\n comb_6 = CombFilter(1491 + offset);\\n comb_7 = CombFilter(1557 + offset);\\n comb_8 = CombFilter(1617 + offset);\\n }\\n\\n connection\\n {\\n damping -> comb_1.dampingIn,\\n comb_2.dampingIn,\\n comb_3.dampingIn,\\n comb_4.dampingIn,\\n comb_5.dampingIn,\\n comb_6.dampingIn,\\n comb_7.dampingIn,\\n comb_8.dampingIn;\\n\\n feedback -> comb_1.feedbackLevelIn,\\n comb_2.feedbackLevelIn,\\n comb_3.feedbackLevelIn,\\n comb_4.feedbackLevelIn,\\n comb_5.feedbackLevelIn,\\n comb_6.feedbackLevelIn,\\n comb_7.feedbackLevelIn,\\n comb_8.feedbackLevelIn;\\n\\n audioIn -> comb_1.audioIn,\\n comb_2.audioIn,\\n comb_3.audioIn,\\n comb_4.audioIn,\\n comb_5.audioIn,\\n comb_6.audioIn,\\n comb_7.audioIn,\\n comb_8.audioIn;\\n\\n comb_1,\\n comb_2,\\n comb_3,\\n comb_4,\\n comb_5,\\n comb_6,\\n comb_7,\\n comb_8 -> allpass_1 -> allpass_2 -> allpass_3 -> allpass_4 -> audioOut;\\n }\\n}\\n\",\"cachedInputNames\":[\"roomSize\",\"damping\",\"wetLevel\",\"dryLevel\",\"width\"],\"polyphonyState\":{\"polyphonyEnabled\":false,\"frequencyInputName\":null,\"gateInputName\":null,\"voiceCount\":8},\"paramDefaultValues\":{\"roomSize\":80,\"damping\":86,\"wetLevel\":33,\"dryLevel\":57,\"width\":100},\"isRunning\":true,\"language\":\"soul\",\"optimize\":true}"} +{"globalTempo":"120.0","graphEditor_eeec5678-29c3-39d6-7b03-7284211e1b55":"{\"last_node_id\":\"da2f5629-e246-5d19-9f99-8907354a427b\",\"last_link_id\":25,\"nodes\":[{\"id\":\"eda73024-8e6a-eecb-ac64-a3581fc1d886\",\"type\":\"audio/audioConnectables\",\"pos\":[100,130],\"size\":{\"0\":140,\"1\":26},\"flags\":{},\"order\":0,\"mode\":0,\"outputs\":[{\"name\":\"midi out\",\"type\":\"midi\",\"links\":[1]}],\"title\":\"MIDI Keyboard\",\"properties\":{}},{\"id\":\"0a9d84e5-03d9-0194-01c4-3504c93eea1e\",\"type\":\"audio/audioConnectables\",\"pos\":[340,130],\"size\":{\"0\":140,\"1\":26},\"flags\":{},\"order\":2,\"mode\":0,\"inputs\":[{\"name\":\"midi_in\",\"type\":\"midi\",\"link\":1}],\"outputs\":[{\"name\":\"midi_out\",\"type\":\"midi\",\"links\":[14]}],\"title\":\"MIDI Editor\",\"properties\":{}},{\"id\":\"1\",\"type\":\"customAudio/destination\",\"pos\":[1315,143],\"size\":{\"0\":140,\"1\":26},\"flags\":{},\"order\":9,\"mode\":0,\"inputs\":[{\"name\":\"input\",\"type\":\"customAudio\",\"link\":25}],\"title\":\"Destination\",\"properties\":{}},{\"id\":\"d427ee12-b908-85ba-0c63-dc481ac33df2\",\"type\":\"audio/audioConnectables\",\"pos\":[1128,133],\"size\":{\"0\":140,\"1\":126},\"flags\":{},\"order\":8,\"mode\":0,\"inputs\":[{\"name\":\"input\",\"type\":\"customAudio\",\"link\":24},{\"name\":\"roomSize\",\"type\":\"number\",\"link\":null},{\"name\":\"damping\",\"type\":\"number\",\"link\":null},{\"name\":\"wetLevel\",\"type\":\"number\",\"link\":null},{\"name\":\"dryLevel\",\"type\":\"number\",\"link\":null},{\"name\":\"width\",\"type\":\"number\",\"link\":null}],\"outputs\":[{\"name\":\"output\",\"type\":\"customAudio\",\"links\":[25]}],\"title\":\"Reverb\",\"properties\":{}},{\"id\":\"2\",\"type\":\"customAudio/compressor\",\"pos\":[938,134],\"size\":{\"0\":140,\"1\":26},\"flags\":{\"collapsed\":false},\"order\":7,\"mode\":0,\"inputs\":[{\"name\":\"input\",\"type\":\"customAudio\",\"link\":23}],\"outputs\":[{\"name\":\"output\",\"type\":\"customAudio\",\"links\":[24]}],\"title\":\"Compressor\",\"properties\":{}},{\"id\":\"3\",\"type\":\"customAudio/LFO\",\"pos\":[148,309],\"size\":{\"0\":140,\"1\":26},\"flags\":{},\"order\":4,\"mode\":0,\"inputs\":[{\"name\":\"frequency\",\"type\":\"number\",\"link\":4}],\"outputs\":[{\"name\":\"signal\",\"type\":\"number\",\"links\":[2]}],\"title\":\"LFO\",\"properties\":{}},{\"id\":\"6\",\"type\":\"customAudio/scaleAndShift\",\"pos\":[-102,325],\"size\":{\"0\":194.8,\"1\":86},\"flags\":{},\"order\":3,\"mode\":0,\"inputs\":[{\"name\":\"input\",\"type\":\"number\",\"link\":3},{\"name\":\"scale\",\"type\":\"number\",\"link\":null},{\"name\":\"pre_scale_shift\",\"type\":\"number\",\"link\":null},{\"name\":\"post_scale_shift\",\"type\":\"number\",\"link\":null}],\"outputs\":[{\"name\":\"output\",\"type\":\"number\",\"links\":[4]}],\"title\":\"Scale + Shift\",\"properties\":{\"input\":{}}},{\"id\":\"5\",\"type\":\"customAudio/LFO\",\"pos\":[-289,325],\"size\":{\"0\":140,\"1\":26},\"flags\":{},\"order\":1,\"mode\":0,\"inputs\":[{\"name\":\"frequency\",\"type\":\"number\",\"link\":null}],\"outputs\":[{\"name\":\"signal\",\"type\":\"number\",\"links\":[3]}],\"title\":\"LFO\",\"properties\":{}},{\"id\":\"91a95325-22b2-efa2-7c60-20badc2809f2\",\"type\":\"audio/audioConnectables\",\"pos\":[580,130],\"size\":{\"0\":312.4,\"1\":246},\"flags\":{},\"order\":6,\"mode\":0,\"inputs\":[{\"name\":\"midi\",\"type\":\"midi\",\"link\":14},{\"name\":\"synth_0_filter_frequency\",\"type\":\"number\",\"link\":null},{\"name\":\"synth_0_filter_detune\",\"type\":\"number\",\"link\":null},{\"name\":\"synth_0_fm_input_0\",\"type\":\"number\",\"link\":15},{\"name\":\"synth_0_fm_input_1\",\"type\":\"number\",\"link\":null},{\"name\":\"synth_0_fm_input_2\",\"type\":\"number\",\"link\":null},{\"name\":\"synth_0_fm_input_3\",\"type\":\"number\",\"link\":null},{\"name\":\"synth_0_fm_input_4\",\"type\":\"number\",\"link\":null},{\"name\":\"synth_0_fm_input_5\",\"type\":\"number\",\"link\":null},{\"name\":\"synth_0_fm_input_6\",\"type\":\"number\",\"link\":null},{\"name\":\"synth_0_fm_input_7\",\"type\":\"number\",\"link\":null},{\"name\":\"synth_0_filter_q\",\"type\":\"number\",\"link\":null}],\"outputs\":[{\"name\":\"masterOutput\",\"type\":\"customAudio\",\"links\":[23]}],\"title\":\"Synth Designer\",\"properties\":{\"synth_0_fm_input_0\":{},\"synth_0_fm_input_1\":{},\"synth_0_fm_input_2\":{},\"synth_0_fm_input_3\":{},\"synth_0_fm_input_4\":{},\"synth_0_fm_input_5\":{},\"synth_0_fm_input_6\":{},\"synth_0_fm_infput_7\":{}}},{\"id\":\"4\",\"type\":\"customAudio/scaleAndShift\",\"pos\":[326,288],\"size\":{\"0\":194.8,\"1\":86},\"flags\":{},\"order\":5,\"mode\":0,\"inputs\":[{\"name\":\"input\",\"type\":\"number\",\"link\":2},{\"name\":\"scale\",\"type\":\"number\",\"link\":null},{\"name\":\"pre_scale_shift\",\"type\":\"number\",\"link\":null},{\"name\":\"post_scale_shift\",\"type\":\"number\",\"link\":null}],\"outputs\":[{\"name\":\"output\",\"type\":\"number\",\"links\":[15]}],\"title\":\"Scale + Shift\",\"properties\":{\"input\":{}}}],\"links\":[[1,\"eda73024-8e6a-eecb-ac64-a3581fc1d886\",0,\"0a9d84e5-03d9-0194-01c4-3504c93eea1e\",0,\"midi\"],[2,\"3\",0,\"4\",0,\"number\"],[3,\"5\",0,\"6\",0,\"number\"],[4,\"6\",0,\"3\",0,\"number\"],[14,\"0a9d84e5-03d9-0194-01c4-3504c93eea1e\",0,\"91a95325-22b2-efa2-7c60-20badc2809f2\",0,\"midi\"],[15,\"4\",0,\"91a95325-22b2-efa2-7c60-20badc2809f2\",3,\"number\"],[23,\"91a95325-22b2-efa2-7c60-20badc2809f2\",0,\"2\",0,\"customAudio\"],[24,\"2\",0,\"d427ee12-b908-85ba-0c63-dc481ac33df2\",0,\"customAudio\"],[25,\"d427ee12-b908-85ba-0c63-dc481ac33df2\",0,\"1\",0,\"customAudio\"]],\"groups\":[],\"config\":{},\"extra\":{},\"version\":0.4,\"selectedNodeVcId\":\"4\"}","vcmState":"{\"view_context_ids\":[\"cef722d2-1eac-f009-c499-4a24c2166d7d\",\"eeec5678-29c3-39d6-7b03-7284211e1b55\",\"eda73024-8e6a-eecb-ac64-a3581fc1d886\",\"0a9d84e5-03d9-0194-01c4-3504c93eea1e\",\"91a95325-22b2-efa2-7c60-20badc2809f2\",\"d427ee12-b908-85ba-0c63-dc481ac33df2\"],\"active_view_ix\":0,\"patch_network_connections\":[[{\"vcId\":\"eda73024-8e6a-eecb-ac64-a3581fc1d886\",\"name\":\"midi out\"},{\"vcId\":\"0a9d84e5-03d9-0194-01c4-3504c93eea1e\",\"name\":\"midi_in\"}],[{\"vcId\":\"3\",\"name\":\"signal\"},{\"vcId\":\"4\",\"name\":\"input\"}],[{\"vcId\":\"5\",\"name\":\"signal\"},{\"vcId\":\"6\",\"name\":\"input\"}],[{\"vcId\":\"6\",\"name\":\"output\"},{\"vcId\":\"3\",\"name\":\"frequency\"}],[{\"vcId\":\"0a9d84e5-03d9-0194-01c4-3504c93eea1e\",\"name\":\"midi_out\"},{\"vcId\":\"91a95325-22b2-efa2-7c60-20badc2809f2\",\"name\":\"midi\"}],[{\"vcId\":\"4\",\"name\":\"output\"},{\"vcId\":\"91a95325-22b2-efa2-7c60-20badc2809f2\",\"name\":\"synth_0_fm_input_0\"}],[{\"vcId\":\"91a95325-22b2-efa2-7c60-20badc2809f2\",\"name\":\"masterOutput\"},{\"vcId\":\"2\",\"name\":\"input\"}],[{\"vcId\":\"d427ee12-b908-85ba-0c63-dc481ac33df2\",\"name\":\"output\"},{\"vcId\":\"1\",\"name\":\"input\"}],[{\"vcId\":\"2\",\"name\":\"output\"},{\"vcId\":\"d427ee12-b908-85ba-0c63-dc481ac33df2\",\"name\":\"input\"}]],\"foreign_connectables\":[{\"type\":\"customAudio/destination\",\"id\":\"1\",\"serializedState\":{}},{\"type\":\"customAudio/compressor\",\"id\":\"2\",\"serializedState\":{\"bottomRatio\":0.2,\"bypass\":false,\"detectionMode\":\"peak\",\"high\":{\"attack_ms\":3,\"bottom_ratio\":1,\"bottom_threshold\":-40.8,\"gain\":1,\"mix\":1,\"release_ms\":250,\"top_ratio\":66.7,\"top_threshold\":-33.8},\"knee\":30,\"lookaheadMs\":1.2,\"low\":{\"attack_ms\":3,\"bottom_ratio\":1,\"bottom_threshold\":-40.8,\"gain\":1,\"mix\":1,\"release_ms\":250,\"top_ratio\":444,\"top_threshold\":-24.4105},\"mid\":{\"attack_ms\":3,\"bottom_ratio\":1,\"bottom_threshold\":-41.8,\"gain\":1,\"mix\":1,\"release_ms\":250,\"top_ratio\":66.7,\"top_threshold\":-30.2},\"mix\":1,\"postGain\":1,\"preGain\":1,\"sab\":null,\"topRatio\":12}},{\"type\":\"customAudio/LFO\",\"id\":\"3\",\"serializedState\":{\"frequency\":1.303166747093201,\"gain\":1,\"offset\":0,\"waveform\":\"sine\"}},{\"type\":\"customAudio/scaleAndShift\",\"id\":\"4\",\"serializedState\":{\"input_min_max\":[-1,1],\"input_range\":[-1,1],\"output_min_max\":[0,1.5],\"output_range\":[0,1.2]}},{\"type\":\"customAudio/LFO\",\"id\":\"5\",\"serializedState\":{\"frequency\":0.342,\"gain\":1,\"offset\":0,\"waveform\":\"triangle\"}},{\"type\":\"customAudio/scaleAndShift\",\"id\":\"6\",\"serializedState\":{\"input_min_max\":[-1,1],\"input_range\":[-1,1],\"output_min_max\":[0,2],\"output_range\":[0,1.2]}}]}","vc_cef722d2-1eac-f009-c499-4a24c2166d7d":"{\"minimal_def\":{\"name\":\"welcome_page\",\"uuid\":\"cef722d2-1eac-f009-c499-4a24c2166d7d\",\"title\":\"Welcome Page\"}}","vc_eda73024-8e6a-eecb-ac64-a3581fc1d886":"{\"minimal_def\":{\"name\":\"midi_keyboard\",\"uuid\":\"eda73024-8e6a-eecb-ac64-a3581fc1d886\",\"title\":\"MIDI Keyboard\"}}","vc_eeec5678-29c3-39d6-7b03-7284211e1b55":"{\"minimal_def\":{\"name\":\"graph_editor\",\"uuid\":\"eeec5678-29c3-39d6-7b03-7284211e1b55\",\"title\":\"Graph Editor\"}}","MIDIKeyboard_eda73024-8e6a-eecb-ac64-a3581fc1d886":"{\"mode\":1,\"octaveOffset\":1,\"mappedOutputs\":[],\"lastSeenModWheel\":0,\"lastSeenPitchBend\":0,\"lastSeenRawMIDIControlValuesByControlIndex\":{}}","synthDesigner_91a95325-22b2-efa2-7c60-20badc2809f2":"{\"synths\":[{\"fmSynthConfig\":{\"modulationMatrix\":[[{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0}],[{\"type\":\"param buffer\",\"value\":-0.1,\"buffer index\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0}],[{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0}],[{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0}],[{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0}],[{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0}],[{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0}],[{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0}]],\"outputWeights\":[{\"type\":\"constant\",\"value\":0.71},{\"type\":\"constant\",\"value\":0.05},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0},{\"type\":\"constant\",\"value\":0}],\"operatorConfigs\":[{\"frequency\":{\"multiplier\":1,\"type\":\"base frequency multiplier\"},\"type\":\"sawtooth oscillator\",\"unison\":16,\"unisonDetune\":{\"type\":\"constant\",\"value\":28.923},\"unisonPhaseRandomization\":{\"enabled\":false}},{\"frequency\":{\"adsr index\":0,\"multiplier\":0.5,\"scale\":20000,\"shift\":0,\"type\":\"base frequency multiplier\"},\"type\":\"sine oscillator\",\"unison\":1,\"unisonDetune\":{\"type\":\"constant\",\"value\":1},\"unisonPhaseRandomization\":{\"enabled\":false}},{\"frequency\":{\"multiplier\":1,\"type\":\"base frequency multiplier\"},\"type\":\"sine oscillator\",\"unison\":1,\"unisonDetune\":{\"type\":\"constant\",\"value\":1},\"unisonPhaseRandomization\":{\"enabled\":false}},{\"frequency\":{\"multiplier\":1,\"type\":\"base frequency multiplier\"},\"type\":\"sine oscillator\",\"unison\":1,\"unisonDetune\":{\"type\":\"constant\",\"value\":1},\"unisonPhaseRandomization\":{\"enabled\":false}},{\"frequency\":{\"multiplier\":1,\"type\":\"base frequency multiplier\"},\"type\":\"sine oscillator\",\"unison\":1,\"unisonDetune\":{\"type\":\"constant\",\"value\":1},\"unisonPhaseRandomization\":{\"enabled\":false}},{\"frequency\":{\"multiplier\":1,\"type\":\"base frequency multiplier\"},\"type\":\"sine oscillator\",\"unison\":1,\"unisonDetune\":{\"type\":\"constant\",\"value\":1},\"unisonPhaseRandomization\":{\"enabled\":false}},{\"frequency\":{\"multiplier\":1,\"type\":\"base frequency multiplier\"},\"type\":\"sine oscillator\",\"unison\":1,\"unisonDetune\":{\"type\":\"constant\",\"value\":1},\"unisonPhaseRandomization\":{\"enabled\":false}},{\"frequency\":{\"multiplier\":1,\"type\":\"base frequency multiplier\"},\"type\":\"sine oscillator\",\"unison\":1,\"unisonDetune\":{\"type\":\"constant\",\"value\":1},\"unisonPhaseRandomization\":{\"enabled\":false}}],\"operatorEffects\":[[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null]],\"selectedUI\":{\"type\":\"modulationIndex\",\"srcOperatorIx\":2,\"dstOperatorIx\":0},\"mainEffectChain\":[{\"algorithm\":\"2\",\"isBypassed\":false,\"isCollapsed\":false,\"postGain\":{\"type\":\"constant\",\"value\":2.423},\"preGain\":{\"type\":\"constant\",\"value\":1.63},\"type\":\"soft clipper\"},{\"cutoffFrequency\":{\"adsr index\":0,\"scale\":18499,\"shift\":1,\"type\":\"adsr\",\"value\":797.4},\"drive\":{\"type\":\"constant\",\"value\":4.15},\"resonance\":{\"type\":\"constant\",\"value\":0.342},\"type\":\"moog filter\"},null,null,null,null,null,null,null,null,null,null,null,null,null,null],\"adsrs\":[{\"steps\":[{\"ramper\":{\"type\":\"linear\"},\"x\":0,\"y\":0.85},{\"ramper\":{\"exponent\":0.679,\"type\":\"bezier\",\"controlPoints\":[{\"x\":0.5,\"y\":0.8233547699825767},{\"x\":0.5,\"y\":0.8233547699825767}]},\"x\":0.195,\"y\":0.81},{\"ramper\":{\"exponent\":0.85,\"type\":\"bezier\",\"controlPoints\":[{\"x\":0.5000000000000001,\"y\":0.8539526523384027},{\"x\":0.5000000000000001,\"y\":0.8539526523384027}]},\"x\":0.4386,\"y\":0.8867},{\"ramper\":{\"exponent\":1.052,\"type\":\"bezier\",\"controlPoints\":[{\"x\":0.5000000000000007,\"y\":0.8801733365807982},{\"x\":0.5000000000000007,\"y\":0.8801733365807982}]},\"x\":0.71,\"y\":0.873},{\"ramper\":{\"exponent\":2.1768,\"type\":\"exponential\"},\"x\":1,\"y\":0.77}],\"lenSamples\":{\"type\":\"beats to samples\",\"value\":1.5},\"loopPoint\":null,\"releasePoint\":1,\"audioThreadData\":{\"phaseIndex\":0,\"debugName\":\"serializeAdsr\"},\"outputRange\":[-30,30],\"logScale\":true}],\"detune\":{\"type\":\"constant\",\"value\":0},\"lastSeenMIDIControlValues\":{},\"wavetableState\":{\"wavetableBanks\":[]},\"gainEnvelope\":{\"steps\":[{\"ramper\":{\"type\":\"instant\"},\"x\":0,\"y\":0},{\"ramper\":{\"exponent\":1,\"type\":\"bezier\",\"controlPoints\":[{\"x\":0.5,\"y\":0.425},{\"x\":0.5,\"y\":0.425}]},\"x\":0.006,\"y\":0.75},{\"x\":0.15,\"y\":0.72,\"ramper\":{\"type\":\"bezier\",\"controlPoints\":[{\"x\":0.5270819952900878,\"y\":0.7327777777777779},{\"x\":0.5270819952900878,\"y\":0.7327777777777779}]}},{\"ramper\":{\"exponent\":1,\"type\":\"bezier\",\"controlPoints\":[{\"x\":0.6536961878863242,\"y\":0.704074074074074},{\"x\":0.6536961878863242,\"y\":0.704074074074074}]},\"x\":0.996,\"y\":0.7},{\"ramper\":{\"exponent\":1,\"type\":\"bezier\",\"controlPoints\":[{\"x\":0.5000000000000278,\"y\":0.35},{\"x\":0.5000000000000278,\"y\":0.35}]},\"x\":1,\"y\":0}],\"lenSamples\":{\"type\":\"constant\",\"value\":22050},\"loopPoint\":null,\"releasePoint\":0.996,\"audioThreadData\":{\"phaseIndex\":255},\"outputRange\":[0,1],\"logScale\":false},\"filterEnvelope\":{\"steps\":[{\"x\":0,\"y\":0.1266666666666667,\"ramper\":{\"type\":\"exponential\",\"exponent\":0.5}},{\"x\":0.5236051502145923,\"y\":0.8166666666666667,\"ramper\":{\"type\":\"bezier\",\"exponent\":0.5,\"controlPoints\":[{\"x\":0.6688125894134478,\"y\":0.29555555555555557},{\"x\":0.6688125894134478,\"y\":0.29555555555555557}]}},{\"x\":1,\"y\":0.2,\"ramper\":{\"type\":\"bezier\",\"exponent\":0.5,\"controlPoints\":[{\"x\":0.7822822822822824,\"y\":0.6349999999999999},{\"x\":0.7822822822822824,\"y\":0.6349999999999999}]}}],\"lenSamples\":{\"type\":\"constant\",\"value\":16327.931847514868},\"loopPoint\":0,\"releasePoint\":0.7424892703862661,\"audioThreadData\":{\"phaseIndex\":254},\"outputRange\":[20,20000],\"logScale\":true,\"lengthMode\":0},\"sampleMappingState\":{\"stateByOperatorIx\":{}},\"useLegacyWavetableControls\":false,\"filterParamControlSources\":{\"Q\":0,\"frequency\":1,\"gain\":0},\"masterGain\":-0.656},\"filter\":{\"type\":\"order 8 lowpass\",\"frequency\":728.2467,\"Q\":3.116,\"gain\":0,\"detune\":0,\"enable envelope\":true,\"bypass\":true},\"masterGain\":-0.656,\"filterEnvelope\":{\"steps\":[{\"x\":0,\"y\":0.1266666666666667,\"ramper\":{\"type\":\"exponential\",\"exponent\":0.5}},{\"x\":0.5236051502145923,\"y\":0.8166666666666667,\"ramper\":{\"type\":\"bezier\",\"exponent\":0.5,\"controlPoints\":[{\"x\":0.6688125894134478,\"y\":0.29555555555555557},{\"x\":0.6688125894134478,\"y\":0.29555555555555557}]}},{\"x\":1,\"y\":0.2,\"ramper\":{\"type\":\"bezier\",\"exponent\":0.5,\"controlPoints\":[{\"x\":0.7822822822822824,\"y\":0.6349999999999999},{\"x\":0.7822822822822824,\"y\":0.6349999999999999}]}}],\"lenSamples\":370.2478876987498,\"loopPoint\":0,\"releasePoint\":0.7424892703862661,\"audioThreadData\":{\"phaseIndex\":254},\"outputRange\":[20,20000],\"logScale\":true,\"lengthMode\":0},\"filterADSRLength\":370.2478876987498,\"pitchMultiplier\":1,\"filterBypassed\":true,\"filterEnvelopeEnabled\":true}]}","vc_91a95325-22b2-efa2-7c60-20badc2809f2":"{\"minimal_def\":{\"name\":\"synth_designer\",\"uuid\":\"91a95325-22b2-efa2-7c60-20badc2809f2\",\"title\":\"Synth Designer\"}}","midiEditor_0a9d84e5-03d9-0194-01c4-3504c93eea1e":"{\"lines\":[{\"midiNumber\":90,\"notes\":[]},{\"midiNumber\":89,\"notes\":[]},{\"midiNumber\":88,\"notes\":[]},{\"midiNumber\":87,\"notes\":[]},{\"midiNumber\":86,\"notes\":[]},{\"midiNumber\":85,\"notes\":[]},{\"midiNumber\":84,\"notes\":[]},{\"midiNumber\":83,\"notes\":[]},{\"midiNumber\":82,\"notes\":[]},{\"midiNumber\":81,\"notes\":[]},{\"midiNumber\":80,\"notes\":[]},{\"midiNumber\":79,\"notes\":[]},{\"midiNumber\":78,\"notes\":[]},{\"midiNumber\":77,\"notes\":[]},{\"midiNumber\":76,\"notes\":[]},{\"midiNumber\":75,\"notes\":[]},{\"midiNumber\":74,\"notes\":[]},{\"midiNumber\":73,\"notes\":[]},{\"midiNumber\":72,\"notes\":[]},{\"midiNumber\":71,\"notes\":[]},{\"midiNumber\":70,\"notes\":[]},{\"midiNumber\":69,\"notes\":[]},{\"midiNumber\":68,\"notes\":[]},{\"midiNumber\":67,\"notes\":[]},{\"midiNumber\":66,\"notes\":[]},{\"midiNumber\":65,\"notes\":[]},{\"midiNumber\":64,\"notes\":[]},{\"midiNumber\":63,\"notes\":[]},{\"midiNumber\":62,\"notes\":[]},{\"midiNumber\":61,\"notes\":[]},{\"midiNumber\":60,\"notes\":[]},{\"midiNumber\":59,\"notes\":[]},{\"midiNumber\":58,\"notes\":[]},{\"midiNumber\":57,\"notes\":[]},{\"midiNumber\":56,\"notes\":[]},{\"midiNumber\":55,\"notes\":[]},{\"midiNumber\":54,\"notes\":[]},{\"midiNumber\":53,\"notes\":[]},{\"midiNumber\":52,\"notes\":[]},{\"midiNumber\":51,\"notes\":[]},{\"midiNumber\":50,\"notes\":[]},{\"midiNumber\":49,\"notes\":[]},{\"midiNumber\":48,\"notes\":[]},{\"midiNumber\":47,\"notes\":[]},{\"midiNumber\":46,\"notes\":[]},{\"midiNumber\":45,\"notes\":[]},{\"midiNumber\":44,\"notes\":[]},{\"midiNumber\":43,\"notes\":[]},{\"midiNumber\":42,\"notes\":[]},{\"midiNumber\":41,\"notes\":[]},{\"midiNumber\":40,\"notes\":[]},{\"midiNumber\":39,\"notes\":[]},{\"midiNumber\":38,\"notes\":[]},{\"midiNumber\":37,\"notes\":[]},{\"midiNumber\":36,\"notes\":[]},{\"midiNumber\":35,\"notes\":[]},{\"midiNumber\":34,\"notes\":[]},{\"midiNumber\":33,\"notes\":[]},{\"midiNumber\":32,\"notes\":[]},{\"midiNumber\":31,\"notes\":[]},{\"midiNumber\":30,\"notes\":[]},{\"midiNumber\":29,\"notes\":[]},{\"midiNumber\":28,\"notes\":[]},{\"midiNumber\":27,\"notes\":[]},{\"midiNumber\":26,\"notes\":[]},{\"midiNumber\":25,\"notes\":[]},{\"midiNumber\":24,\"notes\":[]},{\"midiNumber\":23,\"notes\":[]},{\"midiNumber\":22,\"notes\":[]},{\"midiNumber\":21,\"notes\":[]},{\"midiNumber\":20,\"notes\":[]},{\"midiNumber\":19,\"notes\":[]},{\"midiNumber\":18,\"notes\":[]},{\"midiNumber\":17,\"notes\":[]},{\"midiNumber\":16,\"notes\":[]},{\"midiNumber\":15,\"notes\":[]},{\"midiNumber\":14,\"notes\":[]},{\"midiNumber\":13,\"notes\":[]},{\"midiNumber\":12,\"notes\":[]},{\"midiNumber\":11,\"notes\":[]},{\"midiNumber\":10,\"notes\":[]},{\"midiNumber\":9,\"notes\":[]},{\"midiNumber\":8,\"notes\":[]},{\"midiNumber\":7,\"notes\":[]},{\"midiNumber\":6,\"notes\":[]},{\"midiNumber\":5,\"notes\":[]},{\"midiNumber\":4,\"notes\":[]},{\"midiNumber\":3,\"notes\":[]},{\"midiNumber\":2,\"notes\":[]},{\"midiNumber\":1,\"notes\":[]}],\"view\":{\"pxPerBeat\":32,\"scrollVerticalPx\":0,\"scrollHorizontalBeats\":0,\"beatsPerMeasure\":4},\"beatSnapInterval\":1,\"cursorPosBeats\":0,\"localBPM\":120,\"loopPoint\":null,\"metronomeEnabled\":true}","globalVolume":"20","vc_0a9d84e5-03d9-0194-01c4-3504c93eea1e":"{\"minimal_def\":{\"name\":\"midi_editor\",\"uuid\":\"0a9d84e5-03d9-0194-01c4-3504c93eea1e\",\"title\":\"MIDI Editor\"}}","vc_d427ee12-b908-85ba-0c63-dc481ac33df2":"{\"minimal_def\":{\"name\":\"faust_editor\",\"uuid\":\"d427ee12-b908-85ba-0c63-dc481ac33df2\",\"title\":\"Reverb\"}}","faustEditor_d427ee12-b908-85ba-0c63-dc481ac33df2":"{\"editorContent\":\"/*\\n == SOUL example code ==\\n == Author: Jules via the class Freeverb algorithm ==\\n*/\\n\\n/// Title: An implementation of the classic Freeverb reverb algorithm.\\n\\ngraph Reverb [[ main ]]\\n{\\n input stream float audioIn;\\n output stream float<2> audioOut;\\n\\n input\\n {\\n ReverbParameterProcessorParam.roomSize [[ name: \\\"Room Size\\\", min: 0, max: 100, init: 80, text: \\\"tiny|small|medium|large|hall\\\" ]];\\n ReverbParameterProcessorParam.damping [[ name: \\\"Damping Factor\\\", min: 0, max: 100, init: 50, unit: \\\"%\\\", step: 1 ]];\\n ReverbParameterProcessorParam.wetLevel [[ name: \\\"Wet Level\\\", min: 0, max: 100, init: 33, unit: \\\"%\\\", step: 1 ]];\\n ReverbParameterProcessorParam.dryLevel [[ name: \\\"Dry Level\\\", min: 0, max: 100, init: 40, unit: \\\"%\\\", step: 1 ]];\\n ReverbParameterProcessorParam.width [[ name: \\\"Width\\\", min: 0, max: 100, init: 100, unit: \\\"%\\\", step: 1 ]];\\n }\\n\\n let\\n {\\n dryGainParameterRamp = ParameterRamp (20.0f);\\n wetGain1ParameterRamp = ParameterRamp (20.0f);\\n wetGain2ParameterRamp = ParameterRamp (20.0f);\\n dampingParameterRamp = ParameterRamp (20.0f);\\n feedbackParameterRamp = ParameterRamp (20.0f);\\n\\n reverbChannelLeft = ReverbChannel (0);\\n reverbChannelRight = ReverbChannel (23);\\n }\\n\\n connection\\n {\\n // Parameter outputs to smoothing processors\\n ReverbParameterProcessorParam.dryGainOut -> dryGainParameterRamp.updateParameter;\\n ReverbParameterProcessorParam.wetGain1Out -> wetGain1ParameterRamp.updateParameter;\\n ReverbParameterProcessorParam.wetGain2Out -> wetGain2ParameterRamp.updateParameter;\\n ReverbParameterProcessorParam.dampingOut -> dampingParameterRamp.updateParameter;\\n ReverbParameterProcessorParam.feedbackOut -> feedbackParameterRamp.updateParameter;\\n\\n // Sum the audio\\n audioIn -> Mixer.audioInDry;\\n\\n // Left channel\\n audioIn -> reverbChannelLeft.audioIn;\\n dampingParameterRamp.parameterOut -> reverbChannelLeft.damping;\\n feedbackParameterRamp.parameterOut -> reverbChannelLeft.feedback;\\n reverbChannelLeft -> Mixer.audioInLeftWet;\\n\\n // Right channel\\n audioIn -> reverbChannelRight.audioIn;\\n dampingParameterRamp.parameterOut -> reverbChannelRight.damping;\\n feedbackParameterRamp.parameterOut -> reverbChannelRight.feedback;\\n reverbChannelRight.audioOut -> Mixer.audioInRightWet;\\n\\n // Mix parameters to the mixer\\n dryGainParameterRamp.parameterOut -> Mixer.dryIn;\\n wetGain1ParameterRamp.parameterOut -> Mixer.wet1In;\\n wetGain2ParameterRamp.parameterOut -> Mixer.wet2In;\\n\\n // Write the mixed values to the output\\n Mixer -> audioOut;\\n }\\n}\\n\\n//==============================================================================\\nprocessor AllpassFilter (int bufferSize)\\n{\\n output stream float audioOut;\\n input stream float audioIn;\\n\\n float[bufferSize] buffer;\\n\\n void run()\\n {\\n wrap bufferIndex = 0;\\n\\n loop\\n {\\n let in = audioIn;\\n let bufferedValue = buffer[bufferIndex];\\n\\n buffer[bufferIndex] = in + (bufferedValue * 0.5f);\\n\\n bufferIndex++;\\n audioOut << bufferedValue - in;\\n\\n advance();\\n }\\n }\\n}\\n\\n//==============================================================================\\nprocessor CombFilter (int bufferSize)\\n{\\n output stream float audioOut;\\n input stream float audioIn, dampingIn, feedbackLevelIn;\\n\\n float[bufferSize] buffer;\\n\\n void run()\\n {\\n wrap bufferIndex = 0;\\n\\n let gain = 0.015f;\\n float last = 0.0f;\\n\\n loop\\n {\\n let out = buffer[bufferIndex];\\n audioOut << out;\\n\\n last = (out * (1.0f - dampingIn)) + (last * dampingIn);\\n\\n buffer[bufferIndex] = (gain * audioIn) + (last * feedbackLevelIn);\\n ++bufferIndex;\\n\\n advance();\\n }\\n }\\n}\\n\\n//==============================================================================\\nprocessor Mixer\\n{\\n input stream float audioInDry;\\n input stream float dryIn, wet1In, wet2In,\\n audioInLeftWet, audioInRightWet;\\n\\n output stream float<2> audioOut;\\n\\n void run()\\n {\\n loop\\n {\\n let left = (audioInLeftWet * wet1In) + (audioInRightWet * wet2In);\\n let right = (audioInRightWet * wet1In) + (audioInLeftWet * wet2In);\\n\\n audioOut << float<2> (left, right) + audioInDry * dryIn;\\n advance();\\n }\\n }\\n}\\n\\n\\n//==============================================================================\\n// Converts an input value into a stream (limited to the given slewRate)\\nprocessor ParameterRamp (float slewRate)\\n{\\n input event float updateParameter;\\n output stream float parameterOut;\\n\\n event updateParameter (float newTarget)\\n {\\n targetValue = newTarget;\\n\\n let diff = targetValue - currentValue;\\n let rampSeconds = abs (diff) / slewRate;\\n\\n rampSamples = int (processor.frequency * rampSeconds);\\n rampIncrement = diff / float (rampSamples);\\n }\\n\\n float targetValue;\\n float currentValue;\\n float rampIncrement;\\n int rampSamples;\\n\\n void run()\\n {\\n loop\\n {\\n if (rampSamples > 0)\\n {\\n currentValue += rampIncrement;\\n --rampSamples;\\n }\\n\\n parameterOut << currentValue;\\n advance();\\n }\\n }\\n}\\n\\n//==============================================================================\\n// Correctly applies parameter changes to the streams of input to the algorithm\\nprocessor ReverbParameterProcessorParam\\n{\\n input event float roomSize,\\n damping,\\n wetLevel,\\n dryLevel,\\n width;\\n\\n output event float dryGainOut,\\n wetGain1Out,\\n wetGain2Out,\\n dampingOut,\\n feedbackOut;\\n\\n event roomSize (float newValue) { roomSizeScaled = newValue / 100.0f; onUpdate(); }\\n event damping (float newValue) { dampingScaled = newValue / 100.0f; onUpdate(); }\\n event wetLevel (float newValue) { wetLevelScaled = newValue / 100.0f; onUpdate(); }\\n event dryLevel (float newValue) { dryLevelScaled = newValue / 100.0f; onUpdate(); }\\n event width (float newValue) { widthScaled = newValue / 100.0f; onUpdate(); }\\n\\n float roomSizeScaled = 0.5f;\\n float dampingScaled = 0.5f;\\n float wetLevelScaled = 0.33f;\\n float dryLevelScaled = 0.4f;\\n float widthScaled = 1.0f;\\n\\n void onUpdate()\\n {\\n // Various tuning factors for the reverb\\n let wetScaleFactor = 3.0f;\\n let dryScaleFactor = 2.0f;\\n\\n let roomScaleFactor = 0.28f;\\n let roomOffset = 0.7f;\\n let dampScaleFactor = 0.4f;\\n\\n // Write updated values\\n dryGainOut << dryLevelScaled * dryScaleFactor;\\n wetGain1Out << 0.5f * wetLevelScaled * wetScaleFactor * (1.0f + widthScaled);\\n wetGain2Out << 0.5f * wetLevelScaled * wetScaleFactor * (1.0f - widthScaled);\\n dampingOut << dampingScaled * dampScaleFactor;\\n feedbackOut << roomSizeScaled * roomScaleFactor + roomOffset;\\n }\\n}\\n\\n//==============================================================================\\n// Mono freeverb implementation\\ngraph ReverbChannel (int offset)\\n{\\n input stream float audioIn, damping, feedback;\\n output stream float audioOut;\\n\\n let\\n {\\n allpass_1 = AllpassFilter(225 + offset);\\n allpass_2 = AllpassFilter(341 + offset);\\n allpass_3 = AllpassFilter(441 + offset);\\n allpass_4 = AllpassFilter(556 + offset);\\n\\n comb_1 = CombFilter(1116 + offset);\\n comb_2 = CombFilter(1188 + offset);\\n comb_3 = CombFilter(1277 + offset);\\n comb_4 = CombFilter(1356 + offset);\\n comb_5 = CombFilter(1422 + offset);\\n comb_6 = CombFilter(1491 + offset);\\n comb_7 = CombFilter(1557 + offset);\\n comb_8 = CombFilter(1617 + offset);\\n }\\n\\n connection\\n {\\n damping -> comb_1.dampingIn,\\n comb_2.dampingIn,\\n comb_3.dampingIn,\\n comb_4.dampingIn,\\n comb_5.dampingIn,\\n comb_6.dampingIn,\\n comb_7.dampingIn,\\n comb_8.dampingIn;\\n\\n feedback -> comb_1.feedbackLevelIn,\\n comb_2.feedbackLevelIn,\\n comb_3.feedbackLevelIn,\\n comb_4.feedbackLevelIn,\\n comb_5.feedbackLevelIn,\\n comb_6.feedbackLevelIn,\\n comb_7.feedbackLevelIn,\\n comb_8.feedbackLevelIn;\\n\\n audioIn -> comb_1.audioIn,\\n comb_2.audioIn,\\n comb_3.audioIn,\\n comb_4.audioIn,\\n comb_5.audioIn,\\n comb_6.audioIn,\\n comb_7.audioIn,\\n comb_8.audioIn;\\n\\n comb_1,\\n comb_2,\\n comb_3,\\n comb_4,\\n comb_5,\\n comb_6,\\n comb_7,\\n comb_8 -> allpass_1 -> allpass_2 -> allpass_3 -> allpass_4 -> audioOut;\\n }\\n}\\n\",\"cachedInputNames\":[\"roomSize\",\"damping\",\"wetLevel\",\"dryLevel\",\"width\"],\"polyphonyState\":{\"polyphonyEnabled\":false,\"frequencyInputName\":null,\"gateInputName\":null,\"voiceCount\":8},\"paramDefaultValues\":{\"roomSize\":80,\"damping\":86,\"wetLevel\":33,\"dryLevel\":57,\"width\":100},\"isRunning\":true,\"language\":\"soul\",\"optimize\":true}"}