diff --git a/src/features/helpers/Helpers.js b/src/features/helpers/Helpers.js index 42e8d63..93206d7 100644 --- a/src/features/helpers/Helpers.js +++ b/src/features/helpers/Helpers.js @@ -6,48 +6,52 @@ import './rcSelectTheme.css'; const SliderWithToolTip = createSliderWithTooltip(RCSlider); const SelectStyle = { - control: (provided) => ({ - ...provided, - width: '100%', - }), + control: (provided) => ({ + ...provided, + width: '100%', + }), }; const Slider = (props) => { - return ( - `${v}`} - min={props.min} - max={props.max} - value={props.parameter} - onChange={(v) => props.onChange(v)} - /> - ); + return ( + `${v}`} + min={props.min} + max={props.max} + value={props.parameter} + onChange={(v) => props.onChange(v)} + /> + ); }; const SelectList = (props) => { - return ( - `${option.value}` + } + onChange={(e) => props.onChange(e.value)} + styles={SelectStyle} + /> + ); }; const Checkbox = (props) => { - return ( -
- {`${props.name}:`} - props.onChange(e.target.checked)} - /> -
- ); + return ( +
+ {`${props.name}:`} + props.onChange(e.target.checked)} + /> +
+ ); }; export { Slider, SelectList, Checkbox }; diff --git a/src/features/timbre/Effects.js b/src/features/timbre/Effects.js index e69de29..9fa0346 100644 --- a/src/features/timbre/Effects.js +++ b/src/features/timbre/Effects.js @@ -0,0 +1,16 @@ +import React from 'react'; +import { useSelector } from 'react-redux'; +import { ModFX, Delay, EQ } from './parameters/ModFX'; +import { selectById } from './timbreSlice.js'; +import styles from './Timbre.module.css'; + +export default function Effects(props) { + const ids = useSelector((state) => selectById(state, props.id)); + return ( +
+ + + +
+ ); +} diff --git a/src/features/timbre/Timbre.js b/src/features/timbre/Timbre.js index 7d4885d..64fe8a7 100644 --- a/src/features/timbre/Timbre.js +++ b/src/features/timbre/Timbre.js @@ -12,134 +12,134 @@ import { selectById } from './timbreSlice.js'; import styles from './Timbre.module.css'; export default function Timbre(props) { - const ids = useSelector((state) => selectById(state, props.id)); - return ( -
- - - - - - -
- - - - - -
- ); + const ids = useSelector((state) => selectById(state, props.id)); + return ( +
+ + + + + + +
+ + + + + +
+ ); } diff --git a/src/features/timbre/Timbre.module.css b/src/features/timbre/Timbre.module.css index 54e02a6..0452f06 100644 --- a/src/features/timbre/Timbre.module.css +++ b/src/features/timbre/Timbre.module.css @@ -1,112 +1,110 @@ .timbreStyle { - display: inline-flex; - flex-wrap: wrap; - flex-direction: row; - justify-content: center; - + display: flex; + flex-wrap: wrap; + flex-direction: row; + justify-content: center; } @media screen and (min-width: 1824) { - .lineBreak { - width: 100%; - } + .lineBreak { + width: 100%; + } } .buttonContainer { - position: fixed; - top: 0; - left: 25%; + position: fixed; + top: 0; + left: 25%; } .buttonContainer > button:hover { - background: white; - color: slateblue; - border: 2px solid slateblue; + background: white; + color: slateblue; + border: 2px solid slateblue; } .buttonContainer > button:focus { - background: slateblue; - color: white; - border: 2px solid slateblue; + background: slateblue; + color: white; + border: 2px solid slateblue; } .tabs { - height: 100vh; - display: flex; - flex-direction: column; + height: 100vh; + display: flex; + flex-direction: column; } .tabList { - border-bottom: 1px solid black; - display: inline-flex; - flex-direction: row; - list-style-type: none; - justify-content: center; - top: 0; - padding: 0; - margin: 0; - width: 100vw; + border-bottom: 1px solid black; + display: inline-flex; + flex-direction: row; + list-style-type: none; + justify-content: center; + top: 0; + padding: 0; + margin: 0; + width: 100vw; - background: white; + background: white; } .tab { - width: 78px; - background: white; - color: slategrey; - font-size: 0.75em; - margin: 0.75em 1em; - padding: 0.25em 1em; - border: 2px solid slategrey; - border-radius: 3px; - outline: none; - -webkit-touch-callout: none; /* iOS Safari */ - -webkit-user-select: none; /* Safari */ - -khtml-user-select: none; /* Konqueror HTML */ - -moz-user-select: none; /* Old versions of Firefox */ - -ms-user-select: none; /* Internet Explorer/Edge */ - user-select: none; + width: 78px; + background: white; + color: slategrey; + font-size: 0.75em; + margin: 0.75em 1em; + padding: 0.25em 1em; + border: 2px solid slategrey; + border-radius: 3px; + outline: none; + -webkit-touch-callout: none; /* iOS Safari */ + -webkit-user-select: none; /* Safari */ + -khtml-user-select: none; /* Konqueror HTML */ + -moz-user-select: none; /* Old versions of Firefox */ + -ms-user-select: none; /* Internet Explorer/Edge */ + user-select: none; } .tab:hover { - background: white; - color: slateblue; - border: 2px solid slateblue; + background: white; + color: slateblue; + border: 2px solid slateblue; } .selected, .selected:hover { - background: slateblue; - color: white; - border: 2px solid slateblue; - transition: 0.2s ease-in-out; + background: slateblue; + color: white; + border: 2px solid slateblue; + transition: 0.2s ease-in-out; } @keyframes slideeffect { - 0% { - opacity: 0.5; - } - 100% { - opacity: 1; - } + 0% { + opacity: 0.5; + } + 100% { + opacity: 1; + } } .tabPanel { - - padding: 1em 0; - height: 100%; - animation: slideeffect 0.6s ease-in-out; - opacity: 1; - overflow-y: scroll; + padding: 1em 0; + height: 100%; + animation: slideeffect 0.6s ease-in-out; + opacity: 1; + overflow-y: scroll; } .tabPanel::-webkit-scrollbar { - width: 0.25em; + width: 0.25em; } - -.tabPanel::-webkit-scrollbar-track, .tabPanel::-webkit-scrollbar-thumb { - background-color: transparent; - + +.tabPanel::-webkit-scrollbar-track, +.tabPanel::-webkit-scrollbar-thumb { + background-color: transparent; } .tabPanel:hover::-webkit-scrollbar-track { - background-color: lightgray; + background-color: lightgray; } - + .tabPanel:hover::-webkit-scrollbar-thumb { - background-color: slateblue; - border-radius: 6px; -} \ No newline at end of file + background-color: slateblue; + border-radius: 6px; +} diff --git a/src/features/timbre/parameters/ModFX.js b/src/features/timbre/parameters/ModFX.js index af56815..ad6fe4c 100644 --- a/src/features/timbre/parameters/ModFX.js +++ b/src/features/timbre/parameters/ModFX.js @@ -1,8 +1,8 @@ -import React from "react"; -import { useSelector, useDispatch } from "react-redux"; -import { selectById, parameterUpdated } from "./parameterSlice.js"; -import { Slider, SelectList } from "../../helpers/Helpers"; -import styles from "./Parameters.module.css"; +import React from 'react'; +import { useSelector, useDispatch } from 'react-redux'; +import { selectById, parameterUpdated } from './parameterSlice.js'; +import { Slider, SelectList, Checkbox } from '../../helpers/Helpers'; +import styles from './Parameters.module.css'; const ModFX = (props) => { const parameters = useSelector((state) => selectById(state, props.id)); @@ -10,13 +10,15 @@ const ModFX = (props) => { return (
+ Mod FX + Mod Type dispatch( parameterUpdated({ @@ -26,6 +28,7 @@ const ModFX = (props) => { ) } /> + LFO Speed { ) } /> + Mod FX Depth {
); }; + +const Delay = (props) => { + const parameters = useSelector((state) => selectById(state, props.id)); + const dispatch = useDispatch(); + + return ( +
+ Delay + Delay Type + + dispatch( + parameterUpdated({ + id: props.id, + changes: { type: value }, + }) + ) + } + /> + + dispatch( + parameterUpdated({ + id: props.id, + changes: { tempoSync: value }, + }) + ) + } + /> + {parameters.tempoSync ? ( +
+ Sync Note + + dispatch( + parameterUpdated({ + id: props.id, + changes: { syncNote: value }, + }) + ) + } + /> +
+ ) : ( +
+ Delay Time + + dispatch( + parameterUpdated({ + id: props.id, + changes: { delayTime: value }, + }) + ) + } + /> +
+ )} + Delay Depth + + dispatch( + parameterUpdated({ + id: props.id, + changes: { delayDepth: value }, + }) + ) + } + /> +
+ ); +}; + +const EQ = (props) => { + const parameters = useSelector((state) => selectById(state, props.id)); + const dispatch = useDispatch(); + + return ( +
+ EQ + Low EQ Frequency + `${e.value}kHz`} + value={parameters.lowFrequency} + list={[ + { value: 40 }, + { value: 50 }, + { value: 60 }, + { value: 80 }, + { value: 100 }, + { value: 120 }, + { value: 140 }, + { value: 160 }, + { value: 180 }, + { value: 200 }, + { value: 220 }, + { value: 240 }, + { value: 260 }, + { value: 280 }, + { value: 300 }, + { value: 320 }, + { value: 340 }, + { value: 360 }, + { value: 380 }, + { value: 400 }, + { value: 420 }, + { value: 440 }, + { value: 460 }, + { value: 480 }, + { value: 500 }, + { value: 600 }, + { value: 700 }, + { value: 800 }, + { value: 900 }, + { value: 1000 }, + ]} + onChange={(value) => + dispatch( + parameterUpdated({ + id: props.id, + changes: { lowFrequency: value }, + }) + ) + } + /> + Low EQ Gain + + dispatch( + parameterUpdated({ + id: props.id, + changes: { lowGain: value }, + }) + ) + } + /> + High EQ Frequency + `${e.value}kHz`} + value={parameters.highFrequency} + list={[ + { value: 1.0 }, + { value: 1.25 }, + { value: 1.5 }, + { value: 1.75 }, + { value: 2.0 }, + { value: 2.25 }, + { value: 2.5 }, + { value: 2.75 }, + { value: 3.0 }, + { value: 3.25 }, + { value: 3.5 }, + { value: 3.75 }, + { value: 4.0 }, + { value: 4.25 }, + { value: 4.5 }, + { value: 4.75 }, + { value: 5.0 }, + { value: 5.25 }, + { value: 5.5 }, + { value: 5.75 }, + { value: 6.0 }, + { value: 7.0 }, + { value: 8.0 }, + { value: 9.0 }, + { value: 10.0 }, + { value: 11.0 }, + { value: 12.0 }, + { value: 14.0 }, + { value: 16.0 }, + { value: 18.0 }, + ]} + onChange={(value) => + dispatch( + parameterUpdated({ + id: props.id, + changes: { highFrequency: value }, + }) + ) + } + /> + High EQ Gain + + dispatch( + parameterUpdated({ + id: props.id, + changes: { highGain: value }, + }) + ) + } + /> +
+ ); +}; + +export { ModFX, Delay, EQ }; diff --git a/src/features/timbre/parameters/Parameters.module.css b/src/features/timbre/parameters/Parameters.module.css index 3edf14b..5abbe6f 100644 --- a/src/features/timbre/parameters/Parameters.module.css +++ b/src/features/timbre/parameters/Parameters.module.css @@ -1,88 +1,89 @@ -.container, .horizontalContainer, .patchesContainer { - border: solid 1pt slategrey; - border-radius: 6px; +.container, +.horizontalContainer, +.patchesContainer { + border: solid 1pt slategrey; + border-radius: 6px; } .container { - position: relative; - font-size: small; - display: inline-flex; - flex-direction: column; - justify-content: center; - padding: 16pt; - margin: 10pt; - width: 15%; - height: 214px; - line-height: 1.5em; + position: relative; + font-size: small; + display: inline-flex; + flex-direction: column; + justify-content: center; + padding: 16pt; + margin: 10pt; + min-width: 15%; + height: 214px; + line-height: 1.5em; } .container > * { - margin: 3pt 0; + margin: 3pt 0; } .header { - font-size: 1.5em; - line-height: 1.25em; - text-align: center; - background-color: white; - padding: 0 .25em 0.075em; - border-left: 1px solid slategrey; - border-right: 1px solid slategrey; - box-sizing: border-box; + font-size: 1.5em; + line-height: 1.25em; + text-align: center; + background-color: white; + padding: 0 0.25em 0.075em; + border-left: 1px solid slategrey; + border-right: 1px solid slategrey; + box-sizing: border-box; } .container > .header { - position: absolute; - top: -7.5%; - left: 12%; + position: absolute; + top: -7.5%; + left: 12%; } -.horizontalContainer > .header, .patchesContainer > .header { - position: absolute; - top: -5.25%; - left: 6%; +.horizontalContainer > .header, +.patchesContainer > .header { + position: absolute; + top: -5.25%; + left: 6%; } .horizontalContainer { - position: relative; - font-size: small; - display: inline-flex; - flex-direction: row; - justify-content: center; - align-items: center; - padding: 16pt 8pt 16pt 8pt; - margin: 10pt; - width: 448px; - height: 214px; - + position: relative; + font-size: small; + display: inline-flex; + flex-direction: row; + justify-content: center; + align-items: center; + padding: 16pt 8pt 16pt 8pt; + margin: 10pt; + width: 448px; + height: 214px; } .patchesContainer { - position: relative; - font-size: small; - display: inline-flex; - flex-direction: row; - justify-content: center; - align-items: center; - padding: 16pt 8pt 16pt 8pt; - margin: 10pt; - width: 680px; - height: 214px; + position: relative; + font-size: small; + display: inline-flex; + flex-direction: row; + justify-content: center; + align-items: center; + padding: 16pt 8pt 16pt 8pt; + margin: 10pt; + width: 680px; + height: 214px; } .horizontalContainer > .container, .patchesContainer > .container { - padding: 0 16pt; - width: 100%; - margin: 10pt 0; - border: none; + padding: 0 16pt; + width: 100%; + margin: 10pt 0; + border: none; } .divider { - height: 214px; - width: 2px; - background-color:slategrey; - margin: 0 8pt; + height: 214px; + width: 2px; + background-color: slategrey; + margin: 0 8pt; } .patchesContainer > .divider { - width: 4px; + width: 4px; } - diff --git a/src/features/timbre/parameters/parameterSlice.js b/src/features/timbre/parameters/parameterSlice.js index 7f628cc..ff252d1 100644 --- a/src/features/timbre/parameters/parameterSlice.js +++ b/src/features/timbre/parameters/parameterSlice.js @@ -3,349 +3,373 @@ import { createSlice, createEntityAdapter } from '@reduxjs/toolkit'; const parametersAdapter = createEntityAdapter({}); const parametersSlice = createSlice({ - name: 'parameters', - initialState: parametersAdapter.getInitialState({ - ids: [ - 'vco1', - 'vco2', - 'mixer1', - 'pitch1', - 'filter1', - 'eg1', - 'amp1', - 'eg2', - 'lfo1', - 'lfo2', - 'patches1', - 'vco3', - 'vco4', - 'mixer2', - 'pitch2', - 'filter2', - 'eg3', - 'amp2', - 'eg4', - 'lfo3', - 'lfo4', - 'patches2', - 'vco5', - 'audioIn', - 'mixer3', - 'pitch3', - 'filter3', - 'fcMod', - 'eg4', - 'amp3', - 'lfo5', - 'lfo6', - 'levels', - 'pans', - ], - entities: { - 'vco1': { - id: 'vco1', - waveform: 'Saw', - dwgsOrModType: 'SynWave1', - waveMod: 0, - lfoMod: 0, - }, - 'vco2': { - id: 'vco2', - waveform: 'Saw', - dwgsOrModType: 'Off', - waveMod: 0, - lfoMod: 0, - }, - 'vco3': { - id: 'vco3', - waveform: 'Saw', - dwgsOrModType: 'SynWave1', - waveMod: 0, - lfoMod: 0, - }, - 'vco4': { - id: 'vco4', - waveform: 'Saw', - dwgsOrModType: 'Off', - waveMod: 0, - lfoMod: 0, - }, - 'vco5': { - id: 'vco5', - waveform: 'Saw', - dwgsOrModType: 'SynWave1', - waveMod: 0, - lfoMod: 0, - }, - 'audioIn': { - id: 'audioIn', - gate: 0, - threshold: 0, - hpfLevel: 0, - hpfGate: false, - }, - 'mixer1': { - id: 'mixer1', - vol1: 127, - vol2: 0, - vol3: 0, - }, - 'mixer2': { - id: 'mixer2', - vol1: 127, - vol2: 0, - vol3: 0, - }, - 'mixer3': { - id: 'mixer3', - vol1: 127, - vol2: 0, - vol3: 0, - }, - 'pitch1': { - id: 'pitch1', - voiceAssign: 'Mono', - triggerMode: 'Single', - transpose: 0, - tune: 0, - unisonDetune: 0, - portamento: 0, - bendRange: 0, - vibratoIntensity: 0, - }, - 'pitch2': { - id: 'pitch2', - voiceAssign: 'Mono', - triggerMode: 'Single', - transpose: 0, - tune: 0, - unisonDetune: 0, - portamento: 0, - bendRange: 0, - vibratoIntensity: 0, - }, - 'pitch3': { - id: 'pitch3', - voiceAssign: 'Mono', - triggerMode: 'Single', - transpose: 0, - tune: 0, - unisonDetune: 0, - portamento: 0, - bendRange: 0, - vibratoIntensity: 0, - }, - 'filter1': { - id: 'filter1', - filterType: '-24db Low Pass', - cutoff: 0, - resonance: 0, - egIntensity: 0, - keyboardTrack: 0, - }, - 'filter2': { - id: 'filter2', - filterType: '-24db Low Pass', - cutoff: 0, - resonance: 0, - egIntensity: 0, - keyboardTrack: 0, - }, - 'filter3': { - id: 'filter3', - cutoff: 0, - resonance: 0, - efSense: 0, - }, - 'fcMod': { - id: 'fcMod', - source: 'Amp EG', - intensity: 0, - }, - 'eg1': { - id: 'eg1', - attack: 0, - decay: 0, - sustain: 127, - release: 0, - egReset: false, - }, - 'amp1': { - id: 'amp1', - ampLevel: 127, - panpot: 0, - ampTrack: 0, - distortion: false, - }, - 'eg2': { - id: 'eg2', - attack: 0, - decay: 0, - sustain: 127, - release: 0, - egReset: false, - }, - 'eg3': { - id: 'eg3', - attack: 0, - decay: 0, - sustain: 127, - release: 0, - egReset: false, - }, - 'amp2': { - id: 'amp2', - ampLevel: 127, - panpot: 0, - ampTrack: 0, - distortion: false, - }, - 'eg4': { - id: 'eg4', - attack: 0, - decay: 0, - sustain: 127, - release: 0, - egReset: false, - }, - 'eg5': { - id: 'eg5', - attack: 0, - decay: 0, - sustain: 127, - release: 0, - egReset: false, - }, - 'amp3': { - id: 'amp3', - ampLevel: 127, - directLevel: 0, - ampTrack: 0, - distortion: false, - }, - 'lfo1': { - id: 'lfo1', - waveform: 'Saw', - keySync: 'Off', - tempoSync: false, - frequency: 0, - }, - 'lfo2': { - id: 'lfo2', - waveform: 'Saw', - keySync: 'Off', - tempoSync: false, - frequency: 0, - }, - 'lfo3': { - id: 'lfo3', - waveform: 'Saw', - keySync: 'Off', - tempoSync: false, - frequency: 0, - }, - 'lfo4': { - id: 'lfo4', - waveform: 'Saw', - keySync: 'Off', - tempoSync: false, - frequency: 0, - }, - 'lfo5': { - id: 'lfo5', - waveform: 'Saw', - keySync: 'Off', - tempoSync: false, - frequency: 0, - }, - 'lfo6': { - id: 'lfo6', - waveform: 'Saw', - keySync: 'Off', - tempoSync: false, - frequency: 0, - }, - 'patches1': { - id: 'patches1', - patch1: { - source: 'Filter EG', - destination: 'Pitch', - modIntensity: 0, - }, - patch2: { - source: 'Filter EG', - destination: 'Pitch', - modIntensity: 0, - }, - patch3: { - source: 'LFO 1', - destination: 'Pitch', - modIntensity: 0, - }, - patch4: { - source: 'LFO 2', - destination: 'Pitch', - modIntensity: 0, - }, - }, - 'patches2': { - id: 'patches2', - patch1: { - source: 'Filter EG', - destination: 'Pitch', - modIntensity: 0, - }, - patch2: { - source: 'Filter EG', - destination: 'Pitch', - modIntensity: 0, - }, - patch3: { - source: 'LFO 1', - destination: 'Pitch', - modIntensity: 0, - }, - patch4: { - source: 'LFO 2', - destination: 'Pitch', - modIntensity: 0, - }, - }, - 'levels': { - id: 'levels', - level1: 0, - level2: 0, - level3: 0, - level4: 0, - level5: 0, - level6: 0, - level7: 0, - level8: 0 - }, - 'pans': { - id: 'pans', - pan1: 0, - pan2: 0, - pan3: 0, - pan4: 0, - pan5: 0, - pan6: 0, - pan7: 0, - pan8: 0 - } + name: 'parameters', + initialState: parametersAdapter.getInitialState({ + ids: [ + 'vco1', + 'vco2', + 'mixer1', + 'pitch1', + 'filter1', + 'eg1', + 'amp1', + 'eg2', + 'lfo1', + 'lfo2', + 'patches1', + 'vco3', + 'vco4', + 'mixer2', + 'pitch2', + 'filter2', + 'eg3', + 'amp2', + 'eg4', + 'lfo3', + 'lfo4', + 'patches2', + 'vco5', + 'audioIn', + 'mixer3', + 'pitch3', + 'filter3', + 'fcMod', + 'eg4', + 'amp3', + 'lfo5', + 'lfo6', + 'levels', + 'pans', + 'modfx', + 'delay', + 'eq', + ], + entities: { + vco1: { + id: 'vco1', + waveform: 'Saw', + dwgsOrModType: 'SynWave1', + waveMod: 0, + lfoMod: 0, + }, + vco2: { + id: 'vco2', + waveform: 'Saw', + dwgsOrModType: 'Off', + waveMod: 0, + lfoMod: 0, + }, + vco3: { + id: 'vco3', + waveform: 'Saw', + dwgsOrModType: 'SynWave1', + waveMod: 0, + lfoMod: 0, + }, + vco4: { + id: 'vco4', + waveform: 'Saw', + dwgsOrModType: 'Off', + waveMod: 0, + lfoMod: 0, + }, + vco5: { + id: 'vco5', + waveform: 'Saw', + dwgsOrModType: 'SynWave1', + waveMod: 0, + lfoMod: 0, + }, + audioIn: { + id: 'audioIn', + gate: 0, + threshold: 0, + hpfLevel: 0, + hpfGate: false, + }, + mixer1: { + id: 'mixer1', + vol1: 127, + vol2: 0, + vol3: 0, + }, + mixer2: { + id: 'mixer2', + vol1: 127, + vol2: 0, + vol3: 0, + }, + mixer3: { + id: 'mixer3', + vol1: 127, + vol2: 0, + vol3: 0, + }, + pitch1: { + id: 'pitch1', + voiceAssign: 'Mono', + triggerMode: 'Single', + transpose: 0, + tune: 0, + unisonDetune: 0, + portamento: 0, + bendRange: 0, + vibratoIntensity: 0, + }, + pitch2: { + id: 'pitch2', + voiceAssign: 'Mono', + triggerMode: 'Single', + transpose: 0, + tune: 0, + unisonDetune: 0, + portamento: 0, + bendRange: 0, + vibratoIntensity: 0, + }, + pitch3: { + id: 'pitch3', + voiceAssign: 'Mono', + triggerMode: 'Single', + transpose: 0, + tune: 0, + unisonDetune: 0, + portamento: 0, + bendRange: 0, + vibratoIntensity: 0, + }, + filter1: { + id: 'filter1', + filterType: '-24db Low Pass', + cutoff: 0, + resonance: 0, + egIntensity: 0, + keyboardTrack: 0, + }, + filter2: { + id: 'filter2', + filterType: '-24db Low Pass', + cutoff: 0, + resonance: 0, + egIntensity: 0, + keyboardTrack: 0, + }, + filter3: { + id: 'filter3', + cutoff: 0, + resonance: 0, + efSense: 0, + }, + fcMod: { + id: 'fcMod', + source: 'Amp EG', + intensity: 0, + }, + eg1: { + id: 'eg1', + attack: 0, + decay: 0, + sustain: 127, + release: 0, + egReset: false, + }, + amp1: { + id: 'amp1', + ampLevel: 127, + panpot: 0, + ampTrack: 0, + distortion: false, + }, + eg2: { + id: 'eg2', + attack: 0, + decay: 0, + sustain: 127, + release: 0, + egReset: false, + }, + eg3: { + id: 'eg3', + attack: 0, + decay: 0, + sustain: 127, + release: 0, + egReset: false, + }, + amp2: { + id: 'amp2', + ampLevel: 127, + panpot: 0, + ampTrack: 0, + distortion: false, + }, + eg4: { + id: 'eg4', + attack: 0, + decay: 0, + sustain: 127, + release: 0, + egReset: false, + }, + eg5: { + id: 'eg5', + attack: 0, + decay: 0, + sustain: 127, + release: 0, + egReset: false, + }, + amp3: { + id: 'amp3', + ampLevel: 127, + directLevel: 0, + ampTrack: 0, + distortion: false, + }, + lfo1: { + id: 'lfo1', + waveform: 'Saw', + keySync: 'Off', + tempoSync: false, + frequency: 0, + }, + lfo2: { + id: 'lfo2', + waveform: 'Saw', + keySync: 'Off', + tempoSync: false, + frequency: 0, + }, + lfo3: { + id: 'lfo3', + waveform: 'Saw', + keySync: 'Off', + tempoSync: false, + frequency: 0, + }, + lfo4: { + id: 'lfo4', + waveform: 'Saw', + keySync: 'Off', + tempoSync: false, + frequency: 0, + }, + lfo5: { + id: 'lfo5', + waveform: 'Saw', + keySync: 'Off', + tempoSync: false, + frequency: 0, + }, + lfo6: { + id: 'lfo6', + waveform: 'Saw', + keySync: 'Off', + tempoSync: false, + frequency: 0, + }, + patches1: { + id: 'patches1', + patch1: { + source: 'Filter EG', + destination: 'Pitch', + modIntensity: 0, }, - }), - reducers: { - parameterAdded: parametersAdapter.addOne, - parameterUpdated: parametersAdapter.updateOne, + patch2: { + source: 'Filter EG', + destination: 'Pitch', + modIntensity: 0, + }, + patch3: { + source: 'LFO 1', + destination: 'Pitch', + modIntensity: 0, + }, + patch4: { + source: 'LFO 2', + destination: 'Pitch', + modIntensity: 0, + }, + }, + patches2: { + id: 'patches2', + patch1: { + source: 'Filter EG', + destination: 'Pitch', + modIntensity: 0, + }, + patch2: { + source: 'Filter EG', + destination: 'Pitch', + modIntensity: 0, + }, + patch3: { + source: 'LFO 1', + destination: 'Pitch', + modIntensity: 0, + }, + patch4: { + source: 'LFO 2', + destination: 'Pitch', + modIntensity: 0, + }, + }, + levels: { + id: 'levels', + level1: 0, + level2: 0, + level3: 0, + level4: 0, + level5: 0, + level6: 0, + level7: 0, + level8: 0, + }, + pans: { + id: 'pans', + pan1: 0, + pan2: 0, + pan3: 0, + pan4: 0, + pan5: 0, + pan6: 0, + pan7: 0, + pan8: 0, + }, + modfx: { + id: 'modfx', + type: 'Flanger/Chorus', + lfoSpeed: 0, + effectDepth: 0, + }, + delay: { + id: 'delay', + type: 'Stereo Delay', + tempoSync: false, + syncNote: '1/32', + delayTime: 0, + delayDepth: 0, + }, + eq: { + id: 'eq', + lowFrequency: 40, + lowGain: 0, + highFrequency: 1.0, + highGain: 0, + }, }, + }), + reducers: { + parameterAdded: parametersAdapter.addOne, + parameterUpdated: parametersAdapter.updateOne, + }, }); export const { - selectById, - selectAll, - selectEntities, - selectIds, + selectById, + selectAll, + selectEntities, + selectIds, } = parametersAdapter.getSelectors((state) => state.parameters); export const { parameterAdded, parameterUpdated } = parametersSlice.actions; diff --git a/src/features/timbre/timbreSlice.js b/src/features/timbre/timbreSlice.js index 28b02c6..48722d9 100644 --- a/src/features/timbre/timbreSlice.js +++ b/src/features/timbre/timbreSlice.js @@ -3,76 +3,82 @@ import { createSlice, createEntityAdapter } from '@reduxjs/toolkit'; const timbreAdapter = createEntityAdapter({}); const timbreSlice = createSlice({ - name: 'timbre', - initialState: timbreAdapter.getInitialState({ - ids: ['timbre1', 'timbre2', 'vocoder', 'effects', 'arpeggiator'], - entities: { - 'timbre1': { - id: 'timbre1', - vco1: 'vco1', - vco2: 'vco2', - mixer: 'mixer1', - pitch: 'pitch1', - filter: 'filter1', - eg1: 'eg1', - amp: 'amp1', - eg2: 'eg2', - lfo1: 'lfo1', - lfo2: 'lfo2', - patches: 'patches1', - }, - 'timbre2': { - id: 'timbre2', - vco1: 'vco3', - vco2: 'vco4', - mixer: 'mixer2', - pitch: 'pitch2', - filter: 'filter2', - eg1: 'eg3', - amp: 'amp2', - eg2: 'eg4', - lfo1: 'lfo3', - lfo2: 'lfo4', - patches: 'patches2', - }, - 'vocoder': { - id: 'vocoder', - vco: 'vco5', - audioIn: 'audioIn', - mixer: 'mixer3', - pitch: 'pitch3', - filter: 'filter3', - fcMod: 'fcMod', - eg: 'eg5', - amp: 'amp3', - lfo1: 'lfo5', - lfo2: 'lfo6', - levels: 'levels', - pans: 'pans' - }, - }, - currentTimbre: 'timbre1', - }), - reducers: { - timbreCurrentUpdate(state, action) { - state.currentTimbre = action.payload; - }, - timbreAdded: timbreAdapter.addOne, - timbreUpdated: timbreAdapter.updateOne, + name: 'timbre', + initialState: timbreAdapter.getInitialState({ + ids: ['timbre1', 'timbre2', 'vocoder', 'effects', 'arpeggiator'], + entities: { + timbre1: { + id: 'timbre1', + vco1: 'vco1', + vco2: 'vco2', + mixer: 'mixer1', + pitch: 'pitch1', + filter: 'filter1', + eg1: 'eg1', + amp: 'amp1', + eg2: 'eg2', + lfo1: 'lfo1', + lfo2: 'lfo2', + patches: 'patches1', + }, + timbre2: { + id: 'timbre2', + vco1: 'vco3', + vco2: 'vco4', + mixer: 'mixer2', + pitch: 'pitch2', + filter: 'filter2', + eg1: 'eg3', + amp: 'amp2', + eg2: 'eg4', + lfo1: 'lfo3', + lfo2: 'lfo4', + patches: 'patches2', + }, + vocoder: { + id: 'vocoder', + vco: 'vco5', + audioIn: 'audioIn', + mixer: 'mixer3', + pitch: 'pitch3', + filter: 'filter3', + fcMod: 'fcMod', + eg: 'eg5', + amp: 'amp3', + lfo1: 'lfo5', + lfo2: 'lfo6', + levels: 'levels', + pans: 'pans', + }, + effects: { + id: 'effects', + modfx: 'modfx', + delay: 'delay', + eq: 'eq', + }, }, + currentTimbre: 'timbre1', + }), + reducers: { + timbreCurrentUpdate(state, action) { + state.currentTimbre = action.payload; + }, + timbreAdded: timbreAdapter.addOne, + timbreUpdated: timbreAdapter.updateOne, + }, }); export const { - selectById, - selectAll, - selectEntities, - selectIds, + selectById, + selectAll, + selectEntities, + selectIds, } = timbreAdapter.getSelectors((state) => state.timbres); export const { - timbreCurrentUpdate, - timbreAdded, - timbreUpdated, + timbreCurrentUpdate, + timbreAdded, + timbreUpdated, } = timbreSlice.actions; export default timbreSlice.reducer; diff --git a/src/features/timbre/timbreSwitcher.js b/src/features/timbre/timbreSwitcher.js index 181e248..8e9b55b 100644 --- a/src/features/timbre/timbreSwitcher.js +++ b/src/features/timbre/timbreSwitcher.js @@ -1,35 +1,40 @@ import React from 'react'; import Timbre from './Timbre'; import Vocoder from './Vocoder'; +import Effects from './Effects'; import { Tab, Tabs, TabList, TabPanel } from 'react-tabs'; import styles from './Timbre.module.css'; export default function TimbreSwitcher(props) { - return ( -
- - - Timbre 1 - Timbre 2 - Vocoder - Effects - Arpeggio - + return ( +
+ + + Timbre 1 + Timbre 2 + Vocoder + Effects + Arpeggio + - - - - - - - - - - -
- ); + + + + + + + + + + + + +
+
+ ); }