Implement Mod FX, Delay and EQ

This commit is contained in:
Aoife
2020-11-21 00:02:19 -05:00
parent c08fb8ea50
commit 67744f59c7
9 changed files with 1027 additions and 734 deletions
+5 -1
View File
@@ -29,7 +29,11 @@ const SelectList = (props) => {
<Select <Select
value={{ value: props.value }} value={{ value: props.value }}
options={props.list} options={props.list}
getOptionLabel={(option) => `${option.value}`} getOptionLabel={
props.labelFunction
? props.labelFunction
: (option) => `${option.value}`
}
onChange={(e) => props.onChange(e.value)} onChange={(e) => props.onChange(e.value)}
styles={SelectStyle} styles={SelectStyle}
/> />
+16
View File
@@ -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 (
<div className={styles.timbreStyle}>
<ModFX id={ids.modfx} />
<Delay id={ids.delay} />
<EQ id={ids.eq} />
</div>
);
}
+1 -1
View File
@@ -115,7 +115,7 @@ export default function Timbre(props) {
<Mixer name="Mixer" id={ids.mixer} /> <Mixer name="Mixer" id={ids.mixer} />
<Pitch name="Pitch" id={ids.pitch} /> <Pitch name="Pitch" id={ids.pitch} />
<Filter name="Filter" id={ids.filter} /> <Filter name="Filter" id={ids.filter} />
<Amp name="Amp"id={ids.amp} /> <Amp name="Amp" id={ids.amp} />
<div className={styles.lineBreak} /> <div className={styles.lineBreak} />
<EG name="EG 1" id={ids.eg1} /> <EG name="EG 1" id={ids.eg1} />
<EG name="EG 2" id={ids.eg2} /> <EG name="EG 2" id={ids.eg2} />
+3 -5
View File
@@ -1,9 +1,8 @@
.timbreStyle { .timbreStyle {
display: inline-flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
flex-direction: row; flex-direction: row;
justify-content: center; justify-content: center;
} }
@media screen and (min-width: 1824) { @media screen and (min-width: 1824) {
@@ -87,7 +86,6 @@
} }
} }
.tabPanel { .tabPanel {
padding: 1em 0; padding: 1em 0;
height: 100%; height: 100%;
animation: slideeffect 0.6s ease-in-out; animation: slideeffect 0.6s ease-in-out;
@@ -98,9 +96,9 @@
width: 0.25em; width: 0.25em;
} }
.tabPanel::-webkit-scrollbar-track, .tabPanel::-webkit-scrollbar-thumb { .tabPanel::-webkit-scrollbar-track,
.tabPanel::-webkit-scrollbar-thumb {
background-color: transparent; background-color: transparent;
} }
.tabPanel:hover::-webkit-scrollbar-track { .tabPanel:hover::-webkit-scrollbar-track {
background-color: lightgray; background-color: lightgray;
+249 -10
View File
@@ -1,8 +1,8 @@
import React from "react"; import React from 'react';
import { useSelector, useDispatch } from "react-redux"; import { useSelector, useDispatch } from 'react-redux';
import { selectById, parameterUpdated } from "./parameterSlice.js"; import { selectById, parameterUpdated } from './parameterSlice.js';
import { Slider, SelectList } from "../../helpers/Helpers"; import { Slider, SelectList, Checkbox } from '../../helpers/Helpers';
import styles from "./Parameters.module.css"; import styles from './Parameters.module.css';
const ModFX = (props) => { const ModFX = (props) => {
const parameters = useSelector((state) => selectById(state, props.id)); const parameters = useSelector((state) => selectById(state, props.id));
@@ -10,13 +10,15 @@ const ModFX = (props) => {
return ( return (
<div className={styles.container}> <div className={styles.container}>
<span className={styles.header}>Mod FX</span>
Mod Type
<SelectList <SelectList
value={parameters.type} value={parameters.type}
list={ list={[
({ value: "Flanger/Chorus" }, { value: 'Flanger/Chorus' },
{ value: "Ensemble" }, { value: 'Ensemble' },
{ value: "Phaser" }) { value: 'Phaser' },
} ]}
onChange={(value) => onChange={(value) =>
dispatch( dispatch(
parameterUpdated({ parameterUpdated({
@@ -26,6 +28,7 @@ const ModFX = (props) => {
) )
} }
/> />
LFO Speed
<Slider <Slider
min={0} min={0}
max={127} max={127}
@@ -39,6 +42,7 @@ const ModFX = (props) => {
) )
} }
/> />
Mod FX Depth
<Slider <Slider
min={0} min={0}
max={127} max={127}
@@ -55,3 +59,238 @@ const ModFX = (props) => {
</div> </div>
); );
}; };
const Delay = (props) => {
const parameters = useSelector((state) => selectById(state, props.id));
const dispatch = useDispatch();
return (
<div className={styles.container}>
<span className={styles.header}>Delay</span>
Delay Type
<SelectList
value={parameters.type}
list={[
{ value: 'Stereo Delay' },
{ value: 'Cross Delay' },
{ value: 'L/R Delay' },
]}
onChange={(value) =>
dispatch(
parameterUpdated({
id: props.id,
changes: { type: value },
})
)
}
/>
<Checkbox
name="Tempo Sync"
parameter={parameters.tempoSync}
onChange={(value) =>
dispatch(
parameterUpdated({
id: props.id,
changes: { tempoSync: value },
})
)
}
/>
{parameters.tempoSync ? (
<div>
Sync Note
<SelectList
value={parameters.syncNote}
list={[
{ value: '1/32' },
{ value: '1/24' },
{ value: '1/16' },
{ value: '1/12' },
{ value: '3/32' },
{ value: '1/8' },
{ value: '1/6' },
{ value: '3/16' },
{ value: '1/4' },
{ value: '1/3' },
{ value: '3/8' },
{ value: '1/2' },
{ value: '2/3' },
{ value: '3/4' },
{ value: '1/1' },
]}
onChange={(value) =>
dispatch(
parameterUpdated({
id: props.id,
changes: { syncNote: value },
})
)
}
/>
</div>
) : (
<div>
Delay Time
<Slider
min={0}
max={127}
parameter={parameters.delayTime}
onChange={(value) =>
dispatch(
parameterUpdated({
id: props.id,
changes: { delayTime: value },
})
)
}
/>
</div>
)}
Delay Depth
<Slider
min={0}
max={127}
parameter={parameters.delayDepth}
onChange={(value) =>
dispatch(
parameterUpdated({
id: props.id,
changes: { delayDepth: value },
})
)
}
/>
</div>
);
};
const EQ = (props) => {
const parameters = useSelector((state) => selectById(state, props.id));
const dispatch = useDispatch();
return (
<div className={styles.container}>
<span className={styles.header}>EQ</span>
Low EQ Frequency
<SelectList
labelFunction={(e) => `${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
<Slider
min={-12}
max={12}
parameter={parameters.lowGain}
onChange={(value) =>
dispatch(
parameterUpdated({
id: props.id,
changes: { lowGain: value },
})
)
}
/>
High EQ Frequency
<SelectList
labelFunction={(e) => `${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
<Slider
min={-12}
max={12}
parameter={parameters.highGain}
onChange={(value) =>
dispatch(
parameterUpdated({
id: props.id,
changes: { highGain: value },
})
)
}
/>
</div>
);
};
export { ModFX, Delay, EQ };
@@ -1,4 +1,6 @@
.container, .horizontalContainer, .patchesContainer { .container,
.horizontalContainer,
.patchesContainer {
border: solid 1pt slategrey; border: solid 1pt slategrey;
border-radius: 6px; border-radius: 6px;
} }
@@ -11,7 +13,7 @@
justify-content: center; justify-content: center;
padding: 16pt; padding: 16pt;
margin: 10pt; margin: 10pt;
width: 15%; min-width: 15%;
height: 214px; height: 214px;
line-height: 1.5em; line-height: 1.5em;
} }
@@ -24,7 +26,7 @@
line-height: 1.25em; line-height: 1.25em;
text-align: center; text-align: center;
background-color: white; background-color: white;
padding: 0 .25em 0.075em; padding: 0 0.25em 0.075em;
border-left: 1px solid slategrey; border-left: 1px solid slategrey;
border-right: 1px solid slategrey; border-right: 1px solid slategrey;
box-sizing: border-box; box-sizing: border-box;
@@ -34,7 +36,8 @@
top: -7.5%; top: -7.5%;
left: 12%; left: 12%;
} }
.horizontalContainer > .header, .patchesContainer > .header { .horizontalContainer > .header,
.patchesContainer > .header {
position: absolute; position: absolute;
top: -5.25%; top: -5.25%;
left: 6%; left: 6%;
@@ -51,7 +54,6 @@
margin: 10pt; margin: 10pt;
width: 448px; width: 448px;
height: 214px; height: 214px;
} }
.patchesContainer { .patchesContainer {
@@ -78,11 +80,10 @@
.divider { .divider {
height: 214px; height: 214px;
width: 2px; width: 2px;
background-color:slategrey; background-color: slategrey;
margin: 0 8pt; margin: 0 8pt;
} }
.patchesContainer > .divider { .patchesContainer > .divider {
width: 4px; width: 4px;
} }
@@ -40,69 +40,72 @@ const parametersSlice = createSlice({
'lfo6', 'lfo6',
'levels', 'levels',
'pans', 'pans',
'modfx',
'delay',
'eq',
], ],
entities: { entities: {
'vco1': { vco1: {
id: 'vco1', id: 'vco1',
waveform: 'Saw', waveform: 'Saw',
dwgsOrModType: 'SynWave1', dwgsOrModType: 'SynWave1',
waveMod: 0, waveMod: 0,
lfoMod: 0, lfoMod: 0,
}, },
'vco2': { vco2: {
id: 'vco2', id: 'vco2',
waveform: 'Saw', waveform: 'Saw',
dwgsOrModType: 'Off', dwgsOrModType: 'Off',
waveMod: 0, waveMod: 0,
lfoMod: 0, lfoMod: 0,
}, },
'vco3': { vco3: {
id: 'vco3', id: 'vco3',
waveform: 'Saw', waveform: 'Saw',
dwgsOrModType: 'SynWave1', dwgsOrModType: 'SynWave1',
waveMod: 0, waveMod: 0,
lfoMod: 0, lfoMod: 0,
}, },
'vco4': { vco4: {
id: 'vco4', id: 'vco4',
waveform: 'Saw', waveform: 'Saw',
dwgsOrModType: 'Off', dwgsOrModType: 'Off',
waveMod: 0, waveMod: 0,
lfoMod: 0, lfoMod: 0,
}, },
'vco5': { vco5: {
id: 'vco5', id: 'vco5',
waveform: 'Saw', waveform: 'Saw',
dwgsOrModType: 'SynWave1', dwgsOrModType: 'SynWave1',
waveMod: 0, waveMod: 0,
lfoMod: 0, lfoMod: 0,
}, },
'audioIn': { audioIn: {
id: 'audioIn', id: 'audioIn',
gate: 0, gate: 0,
threshold: 0, threshold: 0,
hpfLevel: 0, hpfLevel: 0,
hpfGate: false, hpfGate: false,
}, },
'mixer1': { mixer1: {
id: 'mixer1', id: 'mixer1',
vol1: 127, vol1: 127,
vol2: 0, vol2: 0,
vol3: 0, vol3: 0,
}, },
'mixer2': { mixer2: {
id: 'mixer2', id: 'mixer2',
vol1: 127, vol1: 127,
vol2: 0, vol2: 0,
vol3: 0, vol3: 0,
}, },
'mixer3': { mixer3: {
id: 'mixer3', id: 'mixer3',
vol1: 127, vol1: 127,
vol2: 0, vol2: 0,
vol3: 0, vol3: 0,
}, },
'pitch1': { pitch1: {
id: 'pitch1', id: 'pitch1',
voiceAssign: 'Mono', voiceAssign: 'Mono',
triggerMode: 'Single', triggerMode: 'Single',
@@ -113,7 +116,7 @@ const parametersSlice = createSlice({
bendRange: 0, bendRange: 0,
vibratoIntensity: 0, vibratoIntensity: 0,
}, },
'pitch2': { pitch2: {
id: 'pitch2', id: 'pitch2',
voiceAssign: 'Mono', voiceAssign: 'Mono',
triggerMode: 'Single', triggerMode: 'Single',
@@ -124,7 +127,7 @@ const parametersSlice = createSlice({
bendRange: 0, bendRange: 0,
vibratoIntensity: 0, vibratoIntensity: 0,
}, },
'pitch3': { pitch3: {
id: 'pitch3', id: 'pitch3',
voiceAssign: 'Mono', voiceAssign: 'Mono',
triggerMode: 'Single', triggerMode: 'Single',
@@ -135,7 +138,7 @@ const parametersSlice = createSlice({
bendRange: 0, bendRange: 0,
vibratoIntensity: 0, vibratoIntensity: 0,
}, },
'filter1': { filter1: {
id: 'filter1', id: 'filter1',
filterType: '-24db Low Pass', filterType: '-24db Low Pass',
cutoff: 0, cutoff: 0,
@@ -143,7 +146,7 @@ const parametersSlice = createSlice({
egIntensity: 0, egIntensity: 0,
keyboardTrack: 0, keyboardTrack: 0,
}, },
'filter2': { filter2: {
id: 'filter2', id: 'filter2',
filterType: '-24db Low Pass', filterType: '-24db Low Pass',
cutoff: 0, cutoff: 0,
@@ -151,18 +154,18 @@ const parametersSlice = createSlice({
egIntensity: 0, egIntensity: 0,
keyboardTrack: 0, keyboardTrack: 0,
}, },
'filter3': { filter3: {
id: 'filter3', id: 'filter3',
cutoff: 0, cutoff: 0,
resonance: 0, resonance: 0,
efSense: 0, efSense: 0,
}, },
'fcMod': { fcMod: {
id: 'fcMod', id: 'fcMod',
source: 'Amp EG', source: 'Amp EG',
intensity: 0, intensity: 0,
}, },
'eg1': { eg1: {
id: 'eg1', id: 'eg1',
attack: 0, attack: 0,
decay: 0, decay: 0,
@@ -170,14 +173,14 @@ const parametersSlice = createSlice({
release: 0, release: 0,
egReset: false, egReset: false,
}, },
'amp1': { amp1: {
id: 'amp1', id: 'amp1',
ampLevel: 127, ampLevel: 127,
panpot: 0, panpot: 0,
ampTrack: 0, ampTrack: 0,
distortion: false, distortion: false,
}, },
'eg2': { eg2: {
id: 'eg2', id: 'eg2',
attack: 0, attack: 0,
decay: 0, decay: 0,
@@ -185,7 +188,7 @@ const parametersSlice = createSlice({
release: 0, release: 0,
egReset: false, egReset: false,
}, },
'eg3': { eg3: {
id: 'eg3', id: 'eg3',
attack: 0, attack: 0,
decay: 0, decay: 0,
@@ -193,14 +196,14 @@ const parametersSlice = createSlice({
release: 0, release: 0,
egReset: false, egReset: false,
}, },
'amp2': { amp2: {
id: 'amp2', id: 'amp2',
ampLevel: 127, ampLevel: 127,
panpot: 0, panpot: 0,
ampTrack: 0, ampTrack: 0,
distortion: false, distortion: false,
}, },
'eg4': { eg4: {
id: 'eg4', id: 'eg4',
attack: 0, attack: 0,
decay: 0, decay: 0,
@@ -208,7 +211,7 @@ const parametersSlice = createSlice({
release: 0, release: 0,
egReset: false, egReset: false,
}, },
'eg5': { eg5: {
id: 'eg5', id: 'eg5',
attack: 0, attack: 0,
decay: 0, decay: 0,
@@ -216,56 +219,56 @@ const parametersSlice = createSlice({
release: 0, release: 0,
egReset: false, egReset: false,
}, },
'amp3': { amp3: {
id: 'amp3', id: 'amp3',
ampLevel: 127, ampLevel: 127,
directLevel: 0, directLevel: 0,
ampTrack: 0, ampTrack: 0,
distortion: false, distortion: false,
}, },
'lfo1': { lfo1: {
id: 'lfo1', id: 'lfo1',
waveform: 'Saw', waveform: 'Saw',
keySync: 'Off', keySync: 'Off',
tempoSync: false, tempoSync: false,
frequency: 0, frequency: 0,
}, },
'lfo2': { lfo2: {
id: 'lfo2', id: 'lfo2',
waveform: 'Saw', waveform: 'Saw',
keySync: 'Off', keySync: 'Off',
tempoSync: false, tempoSync: false,
frequency: 0, frequency: 0,
}, },
'lfo3': { lfo3: {
id: 'lfo3', id: 'lfo3',
waveform: 'Saw', waveform: 'Saw',
keySync: 'Off', keySync: 'Off',
tempoSync: false, tempoSync: false,
frequency: 0, frequency: 0,
}, },
'lfo4': { lfo4: {
id: 'lfo4', id: 'lfo4',
waveform: 'Saw', waveform: 'Saw',
keySync: 'Off', keySync: 'Off',
tempoSync: false, tempoSync: false,
frequency: 0, frequency: 0,
}, },
'lfo5': { lfo5: {
id: 'lfo5', id: 'lfo5',
waveform: 'Saw', waveform: 'Saw',
keySync: 'Off', keySync: 'Off',
tempoSync: false, tempoSync: false,
frequency: 0, frequency: 0,
}, },
'lfo6': { lfo6: {
id: 'lfo6', id: 'lfo6',
waveform: 'Saw', waveform: 'Saw',
keySync: 'Off', keySync: 'Off',
tempoSync: false, tempoSync: false,
frequency: 0, frequency: 0,
}, },
'patches1': { patches1: {
id: 'patches1', id: 'patches1',
patch1: { patch1: {
source: 'Filter EG', source: 'Filter EG',
@@ -288,7 +291,7 @@ const parametersSlice = createSlice({
modIntensity: 0, modIntensity: 0,
}, },
}, },
'patches2': { patches2: {
id: 'patches2', id: 'patches2',
patch1: { patch1: {
source: 'Filter EG', source: 'Filter EG',
@@ -311,7 +314,7 @@ const parametersSlice = createSlice({
modIntensity: 0, modIntensity: 0,
}, },
}, },
'levels': { levels: {
id: 'levels', id: 'levels',
level1: 0, level1: 0,
level2: 0, level2: 0,
@@ -320,9 +323,9 @@ const parametersSlice = createSlice({
level5: 0, level5: 0,
level6: 0, level6: 0,
level7: 0, level7: 0,
level8: 0 level8: 0,
}, },
'pans': { pans: {
id: 'pans', id: 'pans',
pan1: 0, pan1: 0,
pan2: 0, pan2: 0,
@@ -331,8 +334,29 @@ const parametersSlice = createSlice({
pan5: 0, pan5: 0,
pan6: 0, pan6: 0,
pan7: 0, pan7: 0,
pan8: 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: { reducers: {
+10 -4
View File
@@ -7,7 +7,7 @@ const timbreSlice = createSlice({
initialState: timbreAdapter.getInitialState({ initialState: timbreAdapter.getInitialState({
ids: ['timbre1', 'timbre2', 'vocoder', 'effects', 'arpeggiator'], ids: ['timbre1', 'timbre2', 'vocoder', 'effects', 'arpeggiator'],
entities: { entities: {
'timbre1': { timbre1: {
id: 'timbre1', id: 'timbre1',
vco1: 'vco1', vco1: 'vco1',
vco2: 'vco2', vco2: 'vco2',
@@ -21,7 +21,7 @@ const timbreSlice = createSlice({
lfo2: 'lfo2', lfo2: 'lfo2',
patches: 'patches1', patches: 'patches1',
}, },
'timbre2': { timbre2: {
id: 'timbre2', id: 'timbre2',
vco1: 'vco3', vco1: 'vco3',
vco2: 'vco4', vco2: 'vco4',
@@ -35,7 +35,7 @@ const timbreSlice = createSlice({
lfo2: 'lfo4', lfo2: 'lfo4',
patches: 'patches2', patches: 'patches2',
}, },
'vocoder': { vocoder: {
id: 'vocoder', id: 'vocoder',
vco: 'vco5', vco: 'vco5',
audioIn: 'audioIn', audioIn: 'audioIn',
@@ -48,7 +48,13 @@ const timbreSlice = createSlice({
lfo1: 'lfo5', lfo1: 'lfo5',
lfo2: 'lfo6', lfo2: 'lfo6',
levels: 'levels', levels: 'levels',
pans: 'pans' pans: 'pans',
},
effects: {
id: 'effects',
modfx: 'modfx',
delay: 'delay',
eq: 'eq',
}, },
}, },
currentTimbre: 'timbre1', currentTimbre: 'timbre1',
+6 -1
View File
@@ -1,6 +1,7 @@
import React from 'react'; import React from 'react';
import Timbre from './Timbre'; import Timbre from './Timbre';
import Vocoder from './Vocoder'; import Vocoder from './Vocoder';
import Effects from './Effects';
import { Tab, Tabs, TabList, TabPanel } from 'react-tabs'; import { Tab, Tabs, TabList, TabPanel } from 'react-tabs';
import styles from './Timbre.module.css'; import styles from './Timbre.module.css';
@@ -11,7 +12,8 @@ export default function TimbreSwitcher(props) {
className={styles.tabs} className={styles.tabs}
defaultIndex="0" defaultIndex="0"
selectedTabClassName={styles.selected} selectedTabClassName={styles.selected}
selectedTabPanelClassName={styles.tabPanel}> selectedTabPanelClassName={styles.tabPanel}
>
<TabList className={styles.tabList}> <TabList className={styles.tabList}>
<Tab className={styles.tab}>Timbre 1</Tab> <Tab className={styles.tab}>Timbre 1</Tab>
<Tab className={styles.tab}>Timbre 2</Tab> <Tab className={styles.tab}>Timbre 2</Tab>
@@ -29,6 +31,9 @@ export default function TimbreSwitcher(props) {
<TabPanel> <TabPanel>
<Vocoder id="vocoder" /> <Vocoder id="vocoder" />
</TabPanel> </TabPanel>
<TabPanel>
<Effects id="effects" />
</TabPanel>
</Tabs> </Tabs>
</div> </div>
); );