diff --git a/src/features/timbre/Arpeggio.js b/src/features/timbre/Arpeggio.js index e69de29..6808558 100644 --- a/src/features/timbre/Arpeggio.js +++ b/src/features/timbre/Arpeggio.js @@ -0,0 +1,15 @@ +import React from 'react'; +import { useSelector } from 'react-redux'; +import { selectById } from './timbreSlice.js'; +import { ArpeggA, ArpeggB } from './parameters/Arpeggios'; +import styles from './Timbre.module.css'; + +export default function Arpeggio(props) { + const ids = useSelector((state) => selectById(state, props.id)); + return ( +
+ + +
+ ); +} diff --git a/src/features/timbre/parameters/Arpeggios.js b/src/features/timbre/parameters/Arpeggios.js new file mode 100644 index 0000000..13af710 --- /dev/null +++ b/src/features/timbre/parameters/Arpeggios.js @@ -0,0 +1,199 @@ +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 ArpeggA = (props) => { + const parameters = useSelector((state) => selectById(state, props.id)); + const dispatch = useDispatch(); + + return ( +
+ Arpeggio A. +
+ Tempo + + dispatch( + parameterUpdated({ + id: props.id, + changes: { tempo: value }, + }) + ) + } + /> + Resolution + + dispatch( + parameterUpdated({ + id: props.id, + changes: { resolution: value }, + }) + ) + } + /> + Gate + + dispatch( + parameterUpdated({ + id: props.id, + changes: { gate: value }, + }) + ) + } + /> +
+
+
+ Type + + dispatch( + parameterUpdated({ + id: props.id, + changes: { type: value }, + }) + ) + } + /> + Range + `${v.value} Oct`} + value={parameters.range} + list={[{ value: 1 }, { value: 2 }, { value: 3 }, { value: 4 }]} + onChange={(value) => + dispatch( + parameterUpdated({ + id: props.id, + changes: { range: value }, + }) + ) + } + /> +
+
+ ); +}; + +const ArpeggB = (props) => { + const parameters = useSelector((state) => selectById(state, props.id)); + const dispatch = useDispatch(); + + return ( +
+ Arpeggio B. +
+ + dispatch( + parameterUpdated({ + id: props.id, + changes: { latch: value }, + }) + ) + } + /> + Swing + + dispatch( + parameterUpdated({ + id: props.id, + changes: { swing: value }, + }) + ) + } + /> + + dispatch( + parameterUpdated({ + id: props.id, + changes: { keySync: value }, + }) + ) + } + /> +
+
+
+ Last Step + `Step ${v.value}`} + value={parameters.lastStep} + list={[ + { value: 1 }, + { value: 2 }, + { value: 3 }, + { value: 4 }, + { value: 5 }, + { value: 6 }, + { value: 7 }, + { value: 8 }, + ]} + onChange={(value) => + dispatch( + parameterUpdated({ + id: props.id, + changes: { lastStep: value }, + }) + ) + } + /> + Target Timbre + + dispatch( + parameterUpdated({ + id: props.id, + changes: { target: value }, + }) + ) + } + /> +
+
+ ); +}; + +export { ArpeggA, ArpeggB }; diff --git a/src/features/timbre/parameters/parameterSlice.js b/src/features/timbre/parameters/parameterSlice.js index ff252d1..d8a68d3 100644 --- a/src/features/timbre/parameters/parameterSlice.js +++ b/src/features/timbre/parameters/parameterSlice.js @@ -43,6 +43,8 @@ const parametersSlice = createSlice({ 'modfx', 'delay', 'eq', + 'arpeggA', + 'arpeggB', ], entities: { vco1: { @@ -357,6 +359,22 @@ const parametersSlice = createSlice({ highFrequency: 1.0, highGain: 0, }, + arpeggA: { + id: 'arpeggA', + tempo: 20, + resolution: '1/24', + gate: 0, + type: 'Up', + range: 1, + }, + arpeggB: { + id: 'arpeggB', + latch: false, + swing: 0, + keySync: false, + lastStep: 1, + target: 'Both', + }, }, }), reducers: { diff --git a/src/features/timbre/timbreSlice.js b/src/features/timbre/timbreSlice.js index 48722d9..fe2937f 100644 --- a/src/features/timbre/timbreSlice.js +++ b/src/features/timbre/timbreSlice.js @@ -5,7 +5,7 @@ const timbreAdapter = createEntityAdapter({}); const timbreSlice = createSlice({ name: 'timbre', initialState: timbreAdapter.getInitialState({ - ids: ['timbre1', 'timbre2', 'vocoder', 'effects', 'arpeggiator'], + ids: ['timbre1', 'timbre2', 'vocoder', 'effects', 'arpeggio'], entities: { timbre1: { id: 'timbre1', @@ -56,6 +56,10 @@ const timbreSlice = createSlice({ delay: 'delay', eq: 'eq', }, + arpeggio: { + arpeggA: 'arpeggA', + arpeggB: 'arpeggB', + }, }, currentTimbre: 'timbre1', }), diff --git a/src/features/timbre/timbreSwitcher.js b/src/features/timbre/timbreSwitcher.js index 8e9b55b..ed2d18e 100644 --- a/src/features/timbre/timbreSwitcher.js +++ b/src/features/timbre/timbreSwitcher.js @@ -2,6 +2,7 @@ import React from 'react'; import Timbre from './Timbre'; import Vocoder from './Vocoder'; import Effects from './Effects'; +import Arpeggio from './Arpeggio'; import { Tab, Tabs, TabList, TabPanel } from 'react-tabs'; import styles from './Timbre.module.css'; @@ -34,6 +35,9 @@ export default function TimbreSwitcher(props) { + + +
);