Skip to content

Commit 14d1702

Browse files
committed
main mixer finally makes sense
1 parent ec9d5fd commit 14d1702

File tree

13 files changed

+506
-113
lines changed

13 files changed

+506
-113
lines changed
Lines changed: 64 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,31 @@
1-
import { mainBus } from 'App/Tone';
21
import { Portal } from 'App/shared/Portal';
32
import { useTouchAndMouse } from 'hooks/useTouchAndMouse';
43
import { Knob } from './Knob';
5-
import { useRotaryKnob } from 'hooks/useRotaryKnob';
6-
import { useEffect, useState } from 'react';
4+
import { useCallback, useRef, useState } from 'react';
75
import { Button } from 'App/shared/Button';
6+
import { useDispatch, useSelector } from 'react-redux';
7+
import {
8+
MAIN_MIXER_PROPERTIES,
9+
adjustMainMixer,
10+
adjustMainMixerWarp,
11+
resetMainMixerProperty,
12+
resetMainMixerWarp,
13+
} from 'App/reducers/sequenceSlice';
814

915
export const MainMixer = () => {
16+
const mainMixer = useSelector((state) => state.sequence.present.mainMixer);
1017
return (
1118
<Portal targetId='overGridPortal'>
1219
<div id='mixer' className='mixer'>
1320
<div className='mixItemWrapper main'>
14-
{Object.entries(mainBus.mixer).map(([property, node], i) => {
15-
const currentVal = node.getVal();
21+
{Object.entries(mainMixer).map(([property, value]) => {
22+
const properties = MAIN_MIXER_PROPERTIES[property];
1623
return (
1724
<RotaryKnob
18-
key={`rotaryKnob${i}`}
25+
key={`${property}mainMixer`}
1926
property={property}
20-
node={node}
21-
currentVal={currentVal}
27+
value={value}
28+
properties={properties}
2229
/>
2330
);
2431
})}
@@ -28,25 +35,45 @@ export const MainMixer = () => {
2835
);
2936
};
3037

31-
const RotaryKnob = ({ property, node, currentVal }) => {
32-
const { value, reset, startFunc, moveFunc, endFunc } = useRotaryKnob(currentVal, node);
38+
const RotaryKnob = ({ property, value, properties }) => {
39+
const dispatch = useDispatch();
40+
41+
const adjustMixer = useCallback(
42+
(amount) => {
43+
if (property === 'warp') dispatch(adjustMainMixerWarp(amount));
44+
else dispatch(adjustMainMixer({ property, amount }));
45+
},
46+
[dispatch, property]
47+
);
48+
3349
const [editing, setEditing] = useState(false);
3450

35-
const handleStart = (e) => {
51+
const prevYRef = useRef(null);
52+
53+
const startFunc = useCallback((e) => {
3654
setEditing(true);
37-
startFunc(e);
38-
};
55+
prevYRef.current = getY(e);
56+
}, []);
3957

40-
const handleEnd = (e) => {
41-
setEditing(false);
42-
endFunc(e);
58+
const moveFunc = (e) => {
59+
const newY = getY(e);
60+
let amount = getKnobAmount(newY, prevYRef.current);
61+
adjustMixer(amount);
62+
prevYRef.current = newY;
4363
};
4464

45-
const touchAndMouse = useTouchAndMouse(handleStart, moveFunc, handleEnd);
65+
const reset = useCallback(() => {
66+
if (property === 'warp') dispatch(resetMainMixerWarp());
67+
else dispatch(resetMainMixerProperty(property));
68+
}, [dispatch, property]);
4669

47-
useEffect(() => {
48-
node.setVal(value);
49-
}, [node, value]);
70+
const endFunc = useCallback(() => {
71+
setEditing(false);
72+
if (properties.snapback) setTimeout(reset, 0);
73+
prevYRef.current = null;
74+
}, [properties.snapback, reset]);
75+
76+
const touchAndMouse = useTouchAndMouse(startFunc, moveFunc, endFunc);
5077

5178
const id = `mainMixItem${property}`;
5279
const knobId = `${id}Knob`;
@@ -57,10 +84,26 @@ const RotaryKnob = ({ property, node, currentVal }) => {
5784
<p className='mixItemName'>{property}</p>
5885
<div className='mixProperties main'>
5986
<Knob value={value} id={knobId} {...touchAndMouse} onDoubleClick={reset} />
60-
<Button disabled={node.snapback} classes='reset' onClick={reset}>
87+
<Button
88+
disabled={properties.snapback || value === properties.initialValue}
89+
classes='reset'
90+
onClick={reset}
91+
>
6192
reset
6293
</Button>
6394
</div>
6495
</div>
6596
);
6697
};
98+
99+
const getY = (e) => {
100+
let y;
101+
if (e.touches) y = e.touches[0].clientY;
102+
else y = e.clientY;
103+
return y;
104+
};
105+
106+
const getKnobAmount = (newY, prevY) => {
107+
let amount = prevY - newY;
108+
return amount;
109+
};
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import { mainBus } from 'App/Tone';
2+
import { Portal } from 'App/shared/Portal';
3+
import { useTouchAndMouse } from 'hooks/useTouchAndMouse';
4+
import { Knob } from './Knob';
5+
import { useRotaryKnob } from 'hooks/useRotaryKnob';
6+
import { useEffect, useState } from 'react';
7+
import { Button } from 'App/shared/Button';
8+
9+
export const MainMixer = () => {
10+
return (
11+
<Portal targetId='overGridPortal'>
12+
<div id='mixer' className='mixer'>
13+
<div className='mixItemWrapper main'>
14+
{Object.entries(mainBus.mixer).map(([property, node], i) => {
15+
const currentVal = node.getRotaryVal();
16+
return (
17+
<RotaryKnob
18+
key={`rotaryKnob${i}`}
19+
property={property}
20+
node={node}
21+
currentVal={currentVal}
22+
/>
23+
);
24+
})}
25+
</div>
26+
</div>
27+
</Portal>
28+
);
29+
};
30+
31+
const RotaryKnob = ({ property, node, currentVal }) => {
32+
const { value, reset, startFunc, moveFunc, endFunc } = useRotaryKnob(currentVal, node);
33+
const [editing, setEditing] = useState(false);
34+
35+
const handleStart = (e) => {
36+
setEditing(true);
37+
startFunc(e);
38+
};
39+
40+
const handleEnd = (e) => {
41+
setEditing(false);
42+
endFunc(e);
43+
};
44+
45+
const touchAndMouse = useTouchAndMouse(handleStart, moveFunc, handleEnd);
46+
47+
useEffect(() => {
48+
node.setValFromRotary(value);
49+
}, [node, value]);
50+
51+
const id = `mainMixItem${property}`;
52+
const knobId = `${id}Knob`;
53+
let containerClass = 'mixItem';
54+
if (editing) containerClass += ' editing';
55+
return (
56+
<div id={id} className={containerClass}>
57+
<p className='mixItemName'>{property}</p>
58+
<div className='mixProperties main'>
59+
<Knob value={value} id={knobId} {...touchAndMouse} onDoubleClick={reset} />
60+
<Button disabled={node.snapback} classes='reset' onClick={reset}>
61+
reset
62+
</Button>
63+
</div>
64+
</div>
65+
);
66+
};

src/App/Sequencer/MainSection/Mixer/SampleMixer.js

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,16 @@ const MixSample = ({ i }) => {
2828
<div className='mixItem'>
2929
<p className='mixItemName'>{sample.name}</p>
3030
<div id={id} className='mixProperties'>
31-
<MixItemProperty property='vol' sample={sample} currentVal={sample.vol.getVal()} />
32-
<MixItemProperty property='pan' sample={sample} currentVal={sample.pan.getVal()} />
31+
<MixItemProperty
32+
property='vol'
33+
sample={sample}
34+
currentVal={sample.vol.getRotaryVal()}
35+
/>
36+
<MixItemProperty
37+
property='pan'
38+
sample={sample}
39+
currentVal={sample.pan.getRotaryVal()}
40+
/>
3341
<div className={`mixItemBorder border${i}`} />
3442
</div>
3543
</div>
@@ -41,7 +49,7 @@ const MixItemProperty = ({ property, sample, currentVal }) => {
4149
const touchAndMouse = useTouchAndMouse(startFunc, moveFunc, endFunc);
4250

4351
useEffect(() => {
44-
sample[property].setVal(value);
52+
sample[property].setValFromRotary(value);
4553
}, [property, sample, value]);
4654

4755
let formattedValue = property === 'pan' ? formatPan(value) : parseInt(value);

src/App/Subscriptions/Mixer.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { mainBus } from 'App/Tone';
2+
import { useEffect } from 'react';
3+
import { useSelector } from 'react-redux';
4+
5+
export const Mixer = () => {
6+
const mainVolume = useSelector((state) => state.sequence.present.mainMixer.volume);
7+
useEffect(() => {
8+
mainBus.mixer.volume.setValFromRotary(mainVolume);
9+
}, [mainVolume]);
10+
11+
const reverb = useSelector((state) => state.sequence.present.mainMixer.reverb);
12+
useEffect(() => {
13+
mainBus.mixer.reverb.setValFromRotary(reverb);
14+
}, [reverb]);
15+
16+
const filter = useSelector((state) => state.sequence.present.mainMixer.filter);
17+
useEffect(() => {
18+
mainBus.mixer.filter.setValFromRotary(filter);
19+
}, [filter]);
20+
21+
const warp = useSelector((state) => state.sequence.present.mainMixer.warp);
22+
useEffect(() => {
23+
mainBus.mixer.warp.setValFromRotary(warp);
24+
}, [warp]);
25+
26+
const crush = useSelector((state) => state.sequence.present.mainMixer.crush);
27+
useEffect(() => {
28+
mainBus.mixer.crush.setValFromRotary(crush);
29+
}, [crush]);
30+
31+
const distort = useSelector((state) => state.sequence.present.mainMixer.distort);
32+
useEffect(() => {
33+
mainBus.mixer.distort.setValFromRotary(distort);
34+
}, [distort]);
35+
36+
return null;
37+
};

src/App/Subscriptions/Storage.js

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,28 +19,36 @@ export const Storage = () => {
1919
const sequence = useSelector((state) => state.sequence.present);
2020

2121
useEffect(() => {
22-
setLS('sequenceId', sequence._id);
22+
setSS('sequenceId', sequence._id);
2323
}, [sequence._id]);
2424

2525
useEffect(() => {
26-
setLS('sequenceName', sequence.name);
26+
setSS('sequenceName', sequence.name);
2727
}, [sequence.name]);
2828

2929
useEffect(() => {
30-
setLS('sequenceBpm', sequence.bpm);
30+
setSS('sequenceBpm', sequence.bpm);
3131
}, [sequence.bpm]);
3232

3333
useEffect(() => {
34-
setLS('sequenceLength', sequence.length);
34+
setSS('sequenceLength', sequence.length);
3535
}, [sequence.length]);
3636

3737
useEffect(() => {
38-
setLS('sequencePattern', sequence.pattern);
38+
setSS('sequencePattern', sequence.pattern);
3939
}, [sequence.pattern]);
4040

4141
useEffect(() => {
42-
setLS('sequenceKitName', sequence.kit);
42+
setSS('sequenceKitName', sequence.kit);
4343
}, [sequence.kit]);
4444

45+
useEffect(() => {
46+
setSS('mainMixer', sequence.mainMixer);
47+
}, [sequence.mainMixer]);
48+
49+
useEffect(() => {
50+
setSS('sampleMixer', sequence.sampleMixer);
51+
}, [sequence.sampleMixer]);
52+
4553
return null;
4654
};

src/App/Subscriptions/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { GetUser } from './GetUser';
33
import { Storage } from './Storage';
44
import { Display } from './Display';
55
import { Transport } from './Transport';
6+
import { Mixer } from './Mixer';
67

78
export const Subscriptions = () => {
89
return (
@@ -12,6 +13,7 @@ export const Subscriptions = () => {
1213
<Storage />
1314
<Transport />
1415
<Display />
16+
<Mixer />
1517
</>
1618
);
1719
};

0 commit comments

Comments
 (0)