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) {
+
+
+
);