From b40bdc256a2742ac182bc5aa58caee0cf0aa1c3a Mon Sep 17 00:00:00 2001 From: Tim Stirrat Date: Sun, 1 Sep 2024 20:28:34 +1000 Subject: [PATCH] Allow choosing from all the mGB built-in waves --- src/App.tsx | 31 +++++--- src/components/Field.tsx | 15 ++++ src/components/SendSysex.tsx | 86 ++++++++++---------- src/components/SysexDownloadButton.tsx | 41 ++++++++++ src/components/SysexPreview.tsx | 55 +++---------- src/components/WaveformEditor.tsx | 36 ++++++--- src/components/WaveformSelector.tsx | 44 ++++++++++ src/lib/globals.ts | 106 +++++++++++++++++++++++++ src/lib/sysex.ts | 26 ++++-- src/types.ts | 6 -- 10 files changed, 325 insertions(+), 121 deletions(-) create mode 100644 src/components/Field.tsx create mode 100644 src/components/SysexDownloadButton.tsx create mode 100644 src/components/WaveformSelector.tsx create mode 100644 src/lib/globals.ts diff --git a/src/App.tsx b/src/App.tsx index 93d12db..161d0ed 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,25 +1,34 @@ import { useState } from "react"; import { SendSysex } from "./components/SendSysex"; import { WaveformEditor } from "./components/WaveformEditor"; -import { Waveform } from "./types"; -import { SysexPreview } from "./components/SysexPreview"; +import { Callback, Waveform } from "./types"; +import { MGB_WAVEFORMS } from "./lib/globals"; import { Flex } from "./components/Flex"; - -const INITIAL_WAVEFORM: number[] = [ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - // - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -]; +import { fromBytes } from "./lib/sysex"; +import { WaveformSelector } from "./components/WaveformSelector"; function App() { - const [waveform, setWaveform] = useState(INITIAL_WAVEFORM); + // deep clone the mGB default set (bytes) into samples + const [waveforms, setWaveforms] = useState( + MGB_WAVEFORMS.map((bytes) => [...fromBytes(bytes)]) + ); + const [waveIndex, setWaveIndex] = useState(0); + + const waveform = waveforms[waveIndex]; + + const setCurrentWaveform: Callback = (waveform) => + setWaveforms((prev) => { + const newWaveforms = [...prev]; + newWaveforms[waveIndex] = waveform; + return newWaveforms; + }); return ( - + + - ); diff --git a/src/components/Field.tsx b/src/components/Field.tsx new file mode 100644 index 0000000..6621c39 --- /dev/null +++ b/src/components/Field.tsx @@ -0,0 +1,15 @@ +import { useId } from "react"; +import { Flex } from "./Flex"; + +export const Field: React.FC<{ + label: string; + children: (id: string) => React.ReactNode; +}> = ({ label, children }) => { + const id = useId(); + return ( + + + {children(id)} + + ); +}; diff --git a/src/components/SendSysex.tsx b/src/components/SendSysex.tsx index ae6e547..314ec3a 100644 --- a/src/components/SendSysex.tsx +++ b/src/components/SendSysex.tsx @@ -1,12 +1,15 @@ import { Dropdown } from "primereact/dropdown"; import { useMidiAccess, useMidiPermission } from "../hooks/use_midi"; import { Flex } from "./Flex"; -import { FormEventHandler, useId, useState } from "react"; +import { FormEventHandler, useState } from "react"; import { Button } from "primereact/button"; import { PrimeIcons } from "primereact/api"; import { Waveform } from "../types"; -import { Fieldset } from "primereact/fieldset"; import { sendWaveformSysex } from "../lib/sysex"; +import { Field } from "./Field"; +import { Card } from "primereact/card"; +import { SysexPreview } from "./SysexPreview"; +import { SysexDownloadButton } from "./SysexDownloadButton"; export const SendSysex: React.FC<{ readonly waveform: Waveform }> = ({ waveform, @@ -40,48 +43,43 @@ export const SendSysex: React.FC<{ readonly waveform: Waveform }> = ({ } return ( -
- - - {(id) => ( - {option?.name ?? placeholder}} - onChange={(e) => setPortId(e.value)} - placeholder="MIDI Port" - /> - )} - -
- ); -}; + + + + + {(id) => ( + {option?.name ?? placeholder}} + onChange={(e) => setPortId(e.value)} + placeholder="MIDI Port" + /> + )} + -const Field: React.FC<{ - label: string; - children: (id: string) => React.ReactNode; -}> = ({ label, children }) => { - const id = useId(); - return ( - - - {children(id)} - +