Skip to content

Commit 22006fa

Browse files
committed
reverb and delay channels, useRotaryKnob
1 parent cc14151 commit 22006fa

File tree

17 files changed

+265
-82
lines changed

17 files changed

+265
-82
lines changed

src/App/App.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { ChangeKit } from './Sequencer/MainSection/ChangeKit/ChangeKit';
1212
import { LoadSave } from './Sequencer/LoadSave/LoadSave';
1313
import { LoginPage } from './Login/LoginPage';
1414
import { PATHS } from 'hooks/useGoTo';
15-
import { Mixer } from './Sequencer/MainSection/Mixer/Mixer';
15+
import { FX } from './Sequencer/MainSection/FX/FX';
1616

1717
export default function App() {
1818
return (
@@ -33,7 +33,7 @@ const AppContent = () => {
3333
<Route path='/' exact render={() => <Redirect to={PATHS.BASE} />} />
3434
<Route path='/sequencer/:shared' component={SequencerPage} />
3535
<Route path={PATHS.CHANGE_KIT} component={ChangeKit} />
36-
<Route path={PATHS.MIXER} component={Mixer}/>
36+
<Route path={PATHS.FX} component={FX}/>
3737
<Route path={PATHS.LOAD} render={() => <LoadSave tab='load' />} />
3838
<Route path={PATHS.SAVE} render={() => <LoadSave tab='save' />} />
3939
<Route path={PATHS.LOGIN} component={LoginPage} />
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
import cuid from 'cuid';
2+
import React, { useEffect, useRef, useState } from 'react';
3+
import { Portal } from 'App/shared/Portal';
4+
import { getGrid } from 'utils/getGrid';
5+
import { Button } from 'App/shared/Button';
6+
import { useTouchAndMouse } from 'hooks/useTouchAndMouse';
7+
import { Knob } from './Knob';
8+
import { useSelector } from 'react-redux';
9+
import { Kit } from 'App/Tone';
10+
11+
export const FX = () => {
12+
const grid = getGrid(9);
13+
return (
14+
<Portal targetId='overGridPortal'>
15+
<div id='mixer' className='mixer'>
16+
<div className='fxSamples'>
17+
{grid.map((i) => {
18+
return <FXSample key={cuid.slug()} i={i} />;
19+
})}
20+
</div>
21+
</div>
22+
</Portal>
23+
);
24+
};
25+
26+
const FXSample = ({ i }) => {
27+
// const kitName = useSelector((state) => state.sequence.present.kit);
28+
// const sample = useSelector((state) => state.assets.kits[kitName].samples[i]);
29+
const sample = Kit.samples[i];
30+
console.log(sample);
31+
32+
const [edit, setEdit] = useState('filter');
33+
const { value, startFunc, moveFunc, endFunc } = useRotaryKnob();
34+
const touchAndMouse = useTouchAndMouse(startFunc, moveFunc, endFunc);
35+
useApplyFX(i, value);
36+
37+
const onClick = (type) => setEdit(type);
38+
39+
const id = `fxSample${i}`;
40+
return (
41+
<div id={id} className='fxSample'>
42+
<p>{sample.name}</p>
43+
<div className='knob-wrapper'>
44+
<div className='knob' id='length-knob' {...touchAndMouse}>
45+
<label htmlFor='length-knob'>{edit}</label>
46+
<Knob value={value} />
47+
</div>
48+
</div>
49+
<div className='smallBtns'>
50+
<FXButton type='delay' edit={edit} onClick={() => onClick('delay')}>
51+
delay
52+
</FXButton>
53+
<FXButton type='reverb' edit={edit} onClick={() => onClick('reverb')}>
54+
reverb
55+
</FXButton>
56+
</div>
57+
<div className={`fxSampleBorder border${i}`} />
58+
</div>
59+
);
60+
};
61+
62+
const useApplyFX = (i, value) => {
63+
useEffect(() => {
64+
Kit.samples[i].filter.set({ frequency: (20000 * value) / 100 });
65+
}, [i, value]);
66+
};
67+
68+
const useRotaryKnob = () => {
69+
const [value, setValue] = useState(100);
70+
71+
const prevYRef = useRef(null);
72+
73+
const startFunc = (e) => {
74+
prevYRef.current = getY(e);
75+
};
76+
const moveFunc = (e) => {
77+
const newY = getY(e);
78+
let amount = getKnobAmount(newY, prevYRef.current);
79+
prevYRef.current = newY;
80+
setValue((value) => {
81+
let newVal = value + amount;
82+
if (newVal < 0) newVal = 0;
83+
if (newVal > 100) newVal = 100;
84+
return newVal;
85+
});
86+
};
87+
const endFunc = () => {
88+
prevYRef.current = null;
89+
};
90+
91+
return { value, startFunc, moveFunc, endFunc };
92+
};
93+
94+
const FXButton = ({ type, edit, onClick }) => {
95+
const id = `fx${type}`;
96+
const classes = edit === type ? 'active' : '';
97+
return (
98+
<Button id={id} classes={classes} edit={type} onClick={onClick}>
99+
<label htmlFor={id}>{type.substr(0, 1)}</label>
100+
</Button>
101+
);
102+
};
103+
104+
const getY = (e) => {
105+
let y;
106+
if (e.touches) y = e.touches[0].clientY;
107+
else y = e.clientY;
108+
return y;
109+
};
110+
111+
const getKnobAmount = (newY, prevY) => {
112+
let amount = prevY - newY;
113+
return amount;
114+
};
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import React from 'react';
2+
3+
export const Knob = ({ value = 50 }) => (
4+
<svg viewBox='0 0 100 50' xmlns='http://www.w3.org/2000/svg'>
5+
<path
6+
className='arc'
7+
d='M10 3 A20 20, 0, 1 0, 90 3'
8+
stroke='currentColor'
9+
strokeLinecap='round'
10+
strokeDashoffset={126 - value * 1.25}
11+
strokeWidth='2'
12+
fill='none'
13+
/>
14+
<path
15+
className='arc-hide'
16+
d='M5 2 A20 20, 0, 0 0, 95 2'
17+
stroke='currentColor'
18+
strokeWidth='1'
19+
fill='none'
20+
/>
21+
</svg>
22+
);

src/App/Sequencer/MainSection/Mixer/_mixer.scss renamed to src/App/Sequencer/MainSection/FX/_fx.scss

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,31 +7,51 @@
77
@extend %fullAbs;
88
@extend %bg90;
99

10-
.mixSamples {
10+
.fxSamples {
1111
@extend %full;
1212
@include grid(3, 3, 5px);
1313
padding: 0.25rem;
1414

15-
.mixSample {
15+
.fxSample {
1616
padding: 0.5rem;
1717
@extend %full;
18-
@include flex(column);
1918
@extend %borderHalf;
2019
@extend %color;
20+
@include flex(column, space-evenly);
2121

22-
.mixSampleBorder {
23-
@extend %fullAbs;
22+
* {
23+
// border: 1px solid red;
24+
}
25+
26+
.fxSampleBorder {
27+
@extend %noEventsLayerAbs;
28+
top: 0;
29+
left: 0;
2430
opacity: 0;
2531
transition: 400ms;
2632
}
2733

2834
&.flash,
2935
&.pulse {
30-
.mixSampleBorder {
36+
.fxSampleBorder {
3137
transition: none;
3238
opacity: 1;
3339
}
3440
}
3541
}
42+
43+
.smallBtns {
44+
padding: 1rem;
45+
width: 100%;
46+
bottom: 0;
47+
@include flex(row, space-evenly);
48+
}
49+
.btn {
50+
@extend %btn;
51+
52+
&.active {
53+
@extend %bgBtnFull;
54+
}
55+
}
3656
}
3757
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
@use 'styles/mixins' as *;
2+
@use 'styles/placeholders' as *;
3+
@use 'styles/colors' as *;
4+
5+
.knob-wrapper {
6+
cursor: pointer;
7+
@include flex(column);
8+
9+
.knob {
10+
position: relative;
11+
12+
label {
13+
position: absolute;
14+
top: 25%;
15+
left: 50%;
16+
transform: translate(-50%);
17+
@extend %colorKnob;
18+
}
19+
20+
svg {
21+
width: 100%;
22+
height: 100%;
23+
}
24+
}
25+
26+
.arc {
27+
stroke-dasharray: 126px;
28+
@extend %colorKnob;
29+
}
30+
31+
.arc-hide {
32+
/* display: none; */
33+
}
34+
}

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

Lines changed: 0 additions & 30 deletions
This file was deleted.

src/App/Sequencer/MenuBar/MenuBar.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { TransportPanel } from './MenuItems/Transport/TransportPanel';
33
import { UndoRedoBtn } from './MenuItems/UndoRedoBtn';
44
import { EraseBtn } from './MenuItems/EraseBtn';
55
import { FileBtn } from './MenuItems/FileBtn';
6-
import { KitBtn, MixerBtn } from './MenuItems/OpenPathBtn';
6+
import { KitBtn, FXBtn } from './MenuItems/OpenPathBtn';
77
import { TapMenu } from './MenuItems/TapMenu';
88
import { DisplayMenu } from './MenuItems/DisplayMenu/DisplayMenu';
99
import { useSelector } from 'react-redux';
@@ -22,7 +22,7 @@ export const MenuBar = () => {
2222
<DisplayMenu />
2323
<FileBtn />
2424
<KitBtn />
25-
<MixerBtn />
25+
<FXBtn />
2626
</div>
2727
<TransportPanel />
2828
<div className='menuItems'>

src/App/Sequencer/MenuBar/MenuItems/OpenPathBtn.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ export const KitBtn = () => {
4343
return <OpenPathBtn active={selectingKit} path='changeKit' label='kit' Icon={KitIcon} />;
4444
};
4545

46-
export const MixerBtn = () => {
47-
const { mixing } = useCurrentPath();
48-
return <OpenPathBtn active={mixing} path='mixer' label='mixer' Icon={MixerIcon} />;
46+
export const FXBtn = () => {
47+
const { fx } = useCurrentPath();
48+
return <OpenPathBtn active={fx} path='fx' label='fx' Icon={MixerIcon} />;
4949
};

src/App/Sequencer/SamplePanel/SampleBtns/useSampleBtns.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export const useSampleBtn = (selectSample, selected, i) => {
3535
// flash mix panel
3636
useEffect(() => {
3737
if (!flash || !mixing) return;
38-
vanillaShowAndHideClass(`mixSample${i}`, 'flash', 100);
38+
vanillaShowAndHideClass(`fxSample${i}`, 'flash', 100);
3939
}, [flash, i, mixing]);
4040

4141
const startFunc = (e) => {

src/App/Tone/index.js

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,29 @@ document.addEventListener('touchstart', initialClick);
1313
document.addEventListener('mousedown', initialClick);
1414

1515
const mainBus = Tone.getDestination();
16-
mainBus.volume.value = -6;
16+
mainBus.volume.value = -12;
1717

1818
export const fft = new Tone.FFT({
1919
size: 32,
2020
normalRange: true,
2121
});
2222

23-
export const limiter = new Tone.Limiter(-20);
24-
mainBus.chain(limiter, fft);
23+
export const filter = new Tone.Filter(20000, 'lowpass', -24);
24+
export const pitchShift = new Tone.PitchShift();
25+
export const envelope = new Tone.AmplitudeEnvelope();
26+
27+
// export const limiter = new Tone.Limiter(-18);
28+
//
29+
export const delay = new Tone.PingPongDelay({
30+
delayTime: '8d',
31+
feedback: 0.2,
32+
wet: 0,
33+
}).connect(mainBus);
34+
export const reverb = new Tone.Reverb({ decay: 1.5, wet: 0.2 }).connect(mainBus);
35+
36+
export const kitBus = new Tone.Channel({ volume: 0, pan: 0, channelCount: 2 });
37+
kitBus.fan(delay, reverb);
38+
kitBus.chain(filter, pitchShift, envelope, fft, mainBus);
2539

2640
export const Kit = { name: 'init', samples: [{}] };
2741

0 commit comments

Comments
 (0)