Skip to content

Commit 9e11b04

Browse files
author
Oskar Widmark
committed
feat: sound options
1 parent 569242d commit 9e11b04

File tree

7 files changed

+132
-102
lines changed

7 files changed

+132
-102
lines changed

src/App.tsx

Lines changed: 70 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
import React, { MouseEvent } from 'react';
22
import './App.css';
3-
import { SelectChangeEvent, Tab, Tabs } from '@mui/material';
3+
import {
4+
SelectChangeEvent,
5+
Slider,
6+
Tab,
7+
Tabs,
8+
Typography,
9+
} from '@mui/material';
410
import {
511
SortValue,
612
SortName,
@@ -25,21 +31,25 @@ import {
2531
RAINBOW_BACKGROUND_COLOR,
2632
INIT_STATE,
2733
INIT_SETTINGS,
34+
SOUND_TYPE_OPTIONS,
2835
} from './constants';
2936
import { SortAppBar } from './AppBar';
3037
import { CanvasController } from './canvas-controller';
3138
import { Colors } from './Colors';
3239
import { ColumnSlider } from './ColumnSlider';
3340
import { Options } from './Options';
34-
import { ResetPresetSelect } from './ResetPresetSelect';
35-
import { SortingAlgorithmSelect } from './SortingAlgorithmSelect';
3641
import { TimeSlider } from './TimeSlider';
3742
import { Audiotrack, BarChart, Palette } from '@mui/icons-material';
3843
import { TabPanel } from './TabPanel';
44+
import { NonCustomOscillatorType } from 'tone/build/esm/source/oscillator/OscillatorInterface';
45+
import { TitledSelect } from './TitledSelect';
3946

4047
type Props = {
4148
playSound: (params: { frequency: number; duration?: string }) => void;
4249
stopSounds: () => void;
50+
soundType: NonCustomOscillatorType;
51+
setSoundType: (type: NonCustomOscillatorType) => void;
52+
setVolume: (volume: number) => void;
4353
};
4454

4555
class App extends React.Component<Props> {
@@ -68,6 +78,8 @@ class App extends React.Component<Props> {
6878
columnColor2: string;
6979
backgroundColor: string;
7080
highlightColor: string;
81+
soundType: NonCustomOscillatorType;
82+
soundVolume: number;
7183
};
7284
};
7385
canvasController: CanvasController;
@@ -109,6 +121,9 @@ class App extends React.Component<Props> {
109121
this.state.settings.columnColor2,
110122
this.state.settings.highlightColor,
111123
);
124+
125+
this.props.setVolume(this.state.settings.soundVolume);
126+
this.props.setSoundType(this.state.settings.soundType);
112127
}
113128

114129
setSettings = (
@@ -288,13 +303,13 @@ class App extends React.Component<Props> {
288303
this.setState({ areSettingsOpen: false });
289304
};
290305

291-
chooseSortAlg = (event: SelectChangeEvent<SortName>) => {
306+
chooseSortAlg = (event: SelectChangeEvent<string>) => {
292307
this.stopSorting();
293308

294309
this.setSettings({ chosenSortAlg: event.target.value as SortName });
295310
};
296311

297-
chooseResetPreset = (event: SelectChangeEvent<ResetPreset>) => {
312+
chooseResetPreset = (event: SelectChangeEvent<string>) => {
298313
this.setSettings({ resetPreset: event.target.value as ResetPreset });
299314
};
300315

@@ -418,6 +433,18 @@ class App extends React.Component<Props> {
418433
});
419434
};
420435

436+
setSoundType = (event: SelectChangeEvent<string>) => {
437+
const soundType = event.target.value as NonCustomOscillatorType;
438+
this.props.setSoundType(soundType);
439+
this.setSettings({ soundType });
440+
};
441+
442+
setVolume = (_: unknown, value: number | number[]) => {
443+
const volume = value instanceof Array ? value[0] : value;
444+
this.props.setVolume(volume);
445+
this.setSettings({ soundVolume: volume });
446+
};
447+
421448
render() {
422449
return (
423450
<div
@@ -470,9 +497,11 @@ class App extends React.Component<Props> {
470497
<Tab icon={<Audiotrack />} sx={{ minWidth: 0 }} />
471498
</Tabs>
472499
<TabPanel value={this.state.tabIndex} index={0}>
473-
<SortingAlgorithmSelect
474-
chosenSortAlg={this.state.settings.chosenSortAlg}
475-
chooseSortAlg={this.chooseSortAlg}
500+
<TitledSelect
501+
title="Sorting Algorithm"
502+
value={this.state.settings.chosenSortAlg}
503+
onChange={this.chooseSortAlg}
504+
options={Object.values(SortName)}
476505
/>
477506
<Options
478507
chosenSortAlg={this.state.settings.chosenSortAlg}
@@ -495,9 +524,11 @@ class App extends React.Component<Props> {
495524
time={this.state.settings.compareTime}
496525
changeTime={this.changeCompareTime}
497526
/>
498-
<ResetPresetSelect
499-
resetPreset={this.state.settings.resetPreset}
500-
chooseResetPreset={this.chooseResetPreset}
527+
<TitledSelect
528+
title="Reset Preset"
529+
value={this.state.settings.resetPreset}
530+
onChange={this.chooseResetPreset}
531+
options={Object.values(ResetPreset)}
501532
/>
502533
</TabPanel>
503534
<TabPanel value={this.state.tabIndex} index={1}>
@@ -514,7 +545,34 @@ class App extends React.Component<Props> {
514545
setHighlightColor={this.setHighlightColor}
515546
/>
516547
</TabPanel>
517-
<TabPanel value={this.state.tabIndex} index={2}></TabPanel>
548+
<TabPanel value={this.state.tabIndex} index={2}>
549+
<TitledSelect
550+
title="Sound type"
551+
value={this.props.soundType}
552+
onChange={this.setSoundType}
553+
options={SOUND_TYPE_OPTIONS}
554+
/>
555+
<div>
556+
<Typography
557+
align="left"
558+
variant="subtitle1"
559+
color="textSecondary"
560+
>
561+
Volume
562+
</Typography>
563+
<div className="col-slider">
564+
<Slider
565+
defaultValue={this.state.settings.soundVolume}
566+
aria-labelledby="discrete-slider"
567+
valueLabelDisplay="auto"
568+
min={0}
569+
step={1}
570+
max={100}
571+
onChangeCommitted={this.setVolume}
572+
/>
573+
</div>
574+
</div>
575+
</TabPanel>
518576
</SideDrawer>
519577
</div>
520578
</div>

src/AppWithSound.tsx

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,28 @@
11
import React from 'react';
22
import App from './App';
33
import { useSoundPlayer } from './useSoundPlayer';
4+
import { NonCustomOscillatorType } from 'tone/build/esm/source/oscillator/OscillatorInterface';
5+
import { gainToDb } from 'tone';
6+
import { DEFAULT_SOUND_TYPE, DEFAULT_SOUND_VOLUME } from './constants';
47

58
export function AppWithSound(): React.ReactElement {
9+
const [soundType, setSoundType] =
10+
React.useState<NonCustomOscillatorType>(DEFAULT_SOUND_TYPE);
11+
12+
const [volume, setVolume] = React.useState(DEFAULT_SOUND_VOLUME);
13+
614
const { play, stop } = useSoundPlayer({
7-
type: 'triangle',
15+
type: soundType,
16+
volume: gainToDb(volume / 100), // Convert volume percentage to decibels
817
});
918

10-
return <App playSound={play} stopSounds={stop} />;
19+
return (
20+
<App
21+
playSound={play}
22+
stopSounds={stop}
23+
soundType={soundType}
24+
setSoundType={setSoundType}
25+
setVolume={setVolume}
26+
/>
27+
);
1128
}

src/Colors.tsx

Lines changed: 6 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,6 @@
1-
import {
2-
FormControl,
3-
Typography,
4-
Stack,
5-
TextField,
6-
MenuItem,
7-
Grid2,
8-
} from '@mui/material';
1+
import { FormControl, Stack, TextField, Grid2 } from '@mui/material';
92
import { ColorPreset } from './types';
3+
import { TitledSelect } from './TitledSelect';
104

115
export function Colors(props: {
126
colorPreset: ColorPreset;
@@ -36,30 +30,13 @@ export function Colors(props: {
3630
return (
3731
<div className="select-wrapper">
3832
<FormControl component="fieldset">
39-
<Typography
40-
align="left"
41-
variant="subtitle1"
42-
color="textSecondary"
43-
gutterBottom
44-
>
45-
Colors
46-
</Typography>
4733
<Stack direction="column" spacing={2} alignItems="left">
48-
<TextField
34+
<TitledSelect
35+
title="Sort Algorithm"
4936
value={colorPreset}
50-
label="Preset"
51-
size="small"
52-
select
5337
onChange={(e) => setColorPreset(e.target.value as ColorPreset)}
54-
>
55-
{Object.values(ColorPreset).map((v) => (
56-
<MenuItem value={v} key={v}>
57-
<Typography align="left" variant="body2" color="textSecondary">
58-
{v}
59-
</Typography>
60-
</MenuItem>
61-
))}
62-
</TextField>
38+
options={Object.values(ColorPreset)}
39+
/>
6340
{(colorPreset === ColorPreset.Custom ||
6441
colorPreset === ColorPreset.CustomGradient) && (
6542
<Grid2 container spacing={2}>

src/ResetPresetSelect.tsx

Lines changed: 0 additions & 43 deletions
This file was deleted.
Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,22 @@
11
import {
2-
SelectChangeEvent,
32
FormControl,
43
Typography,
54
Select,
65
MenuItem,
6+
SelectChangeEvent,
77
} from '@mui/material';
8-
import { SortName } from './types';
9-
10-
export function SortingAlgorithmSelect(props: {
11-
chosenSortAlg: SortName;
12-
chooseSortAlg: (event: SelectChangeEvent<SortName>) => void;
13-
}) {
14-
const { chosenSortAlg, chooseSortAlg } = props;
158

9+
export const TitledSelect = ({
10+
title,
11+
value,
12+
onChange,
13+
options,
14+
}: {
15+
title: string;
16+
value: string;
17+
onChange: (event: SelectChangeEvent<string>) => void;
18+
options: string[];
19+
}) => {
1620
return (
1721
<div className="select-wrapper">
1822
<FormControl component="fieldset">
@@ -22,18 +26,18 @@ export function SortingAlgorithmSelect(props: {
2226
color="textSecondary"
2327
gutterBottom
2428
>
25-
Sorting Algorithm
29+
{title}
2630
</Typography>
27-
<Select value={chosenSortAlg} onChange={chooseSortAlg} size="small">
28-
{Object.values(SortName).map((v) => (
31+
<Select value={value} onChange={onChange} size="small">
32+
{options.map((v) => (
2933
<MenuItem value={v} key={v}>
3034
<Typography align="left" variant="body2" color="textSecondary">
31-
{v}
35+
{v.charAt(0).toUpperCase() + v.slice(1)}
3236
</Typography>
3337
</MenuItem>
3438
))}
3539
</Select>
3640
</FormControl>
3741
</div>
3842
);
39-
}
43+
};

src/constants.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { NonCustomOscillatorType } from 'tone/build/esm/source/oscillator/OscillatorInterface';
12
import { AlgorithmOptions, ColorPreset, ResetPreset, SortName } from './types';
23

34
export const INIT_SWAP_TIME = 1;
@@ -14,6 +15,15 @@ export const DEFAULT_ALGORITHM_OPTIONS: AlgorithmOptions = {
1415
base: 4,
1516
shrinkFactor: 1.3,
1617
};
18+
export const DEFAULT_SOUND_VOLUME = 50;
19+
export const DEFAULT_SOUND_TYPE = 'triangle';
20+
export const SOUND_TYPE_OPTIONS = [
21+
'sine',
22+
'square',
23+
'triangle',
24+
'sawtooth',
25+
] as NonCustomOscillatorType[];
26+
1727
export const INIT_STATE = {
1828
isSorting: false,
1929
areSettingsOpen: false,
@@ -36,4 +46,6 @@ export const INIT_SETTINGS = {
3646
columnColor2: DEFAULT_COLUMN_COLOR_2,
3747
backgroundColor: DEFAULT_BACKGROUND_COLOR,
3848
highlightColor: DEFAULT_HIGHLIGHT_COLOR,
49+
soundVolume: DEFAULT_SOUND_VOLUME,
50+
soundType: DEFAULT_SOUND_TYPE,
3951
};

0 commit comments

Comments
 (0)