Skip to content

Commit

Permalink
Break creation into steps
Browse files Browse the repository at this point in the history
  • Loading branch information
wrenhawth committed Jul 5, 2024
1 parent 6cd8b03 commit 2a02cda
Show file tree
Hide file tree
Showing 15 changed files with 854 additions and 266 deletions.
101 changes: 94 additions & 7 deletions src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ sl-button:hover>sl-icon {
font-weight: bold;
font-size: 18px;
}

.preset-select::part(display-input) {
text-align: center;
}
Expand All @@ -118,7 +119,7 @@ sl-button:hover>sl-icon {

sl-select::part(base) {
color: white
}
}

.main {
background-color: hsla(220, 100%, 30%, .9);
Expand All @@ -135,8 +136,15 @@ sl-select::part(base) {
}

.curve-arrow {
font-size: 32px;;
font-size: 32px;
;
}

.octo {
font-size: 72px;
line-height: 72px;
}

.octopus {
margin: 0;
/* writing-mode: vertical-lr;
Expand All @@ -146,11 +154,7 @@ sl-select::part(base) {
align-items: center;
justify-content: center;

.octo {
font-size: 72px;
line-height: 72px;
;
}


.arrow {
font-size: 48px;
Expand Down Expand Up @@ -192,4 +196,87 @@ sl-select::part(base) {
align-items: center;
display: flex;
;
}

.label-on-left {
--label-width: 3.75rem;
--gap-width: 1rem;
}

.label-on-left+.label-on-left {
margin-top: var(--sl-spacing-medium);
}

.label-on-left::part(form-control) {
display: grid;
grid: auto / 1fr 1fr;
gap: var(--sl-spacing-3x-small) var(--gap-width);
align-items: center;
}

.label-on-left::part(form-control-label) {
text-align: center;
}

.label-on-left::part(form-control-help-text) {
grid-column-start: 2;
}

.top-tabs::part(tabs) {
justify-content: center;
gap: 12px;
border-top: 0;
}

.tab::part(base) {
color: white;
/* background-color: var(--sl-color-green-500); */
border-top-left-radius: 0;
border-top-right-radius: 0;
border: 1px solid white;
border-top: 0;
padding-top: 8px;
padding-bottom: 8px;
}

.start-tab::part(base) {
background-color: var(--sl-color-lime-500);
}

.drums-tab::part(base) {
background-color: var(--sl-color-green-500);
}

.chords-tab::part(base) {
background-color: var(--sl-color-emerald-500);
}

sl-tab[active]::part(base) {
font-weight: bolder;
text-decoration: underline;
}

.beat-select {
display: flex;
justify-content: space-between;
width: 100%;
flex-direction: row;
padding: 16px;
align-items: center;
}

.tempo-selector {
flex-direction: column;
display: flex;
align-items: center;
padding: 16px;
}

.step-header {
font-weight: bold;
margin: 8px;
.step-num {
font-weight: bolder;
text-decoration: underline;
}
}
158 changes: 21 additions & 137 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,149 +1,33 @@
import React, { useEffect } from 'react';

import './App.css'

import { DEFAULT_SCALE_OPTIONS, scaleToTriads } from './utils/chords';
import { Part } from 'tone';
import { CHORD_TO_INDEX, ChordSymbol } from './utils/basicChords';
import _ from 'lodash';
import { SingleChord } from './components/SingleChord';
import { Octopus } from './components/Octopus';
import { DRUM_PRESETS, DRUM_PRESETS_LOOPS, DrumEvent, DrumPreset } from './utils/drumPresets';
import { RhythmSelector } from './components/RhythmSelector';
import { fillDrumPreset } from './utils/rhythms';
import { ChordEvent, ChordPattern, fillChordPattern } from './utils/chordPatterns';
import { ChordPatternSelector } from './components/ChordPatternSelector';
import { OctoStage } from './components/canvas/OctoStage';
import { useChordSynth } from './hooks/useChordSynth';
import { useDrumSampler } from './hooks/useDrumSampler';

const updateChordPart = (part: ChordPart, i: number, chordNumeral: ChordSymbol, chordPattern: ChordPattern) => {
part.clear()
const triads = scaleToTriads(DEFAULT_SCALE_OPTIONS)
const chord = triads[CHORD_TO_INDEX[chordNumeral]]?.notes || ['C4']
const newValue = fillChordPattern(i, chord, chordPattern)
newValue.forEach((v) => {
part.at(v.time, v)
})
}
import { WorkflowProvider } from './components/WorkflowContext';
import { AllSteps } from './components/AllSteps';

const updateRhythmPart = (part: DrumPart, drumPreset: DrumPreset) => {
const newValue = fillDrumPreset(drumPreset)
console.log(newValue)
newValue.forEach((v) => {
const { time } = v
part.at(time, v)
})
}

type ChordPart = Part<ChordEvent>
type ChordParts = Array<{
part: ChordPart
chord: ChordSymbol
}>
function App() {

type DrumPart = Part<DrumEvent>

const INITIAL_CHORD_LIST: ChordSymbol[] = ['I', 'I', 'I', 'I']


function App() {
const [isStarted, setIsStarted] = React.useState(false)

const chordSynth = useChordSynth(isStarted)
const drumSampler = useDrumSampler(isStarted)
const [chordList, setChordList] = React.useState<ChordSymbol[]>(INITIAL_CHORD_LIST)
const [chordPattern, setChordPattern] = React.useState<ChordPattern>('DDDD')

const chordPartRefs = React.useRef<ChordParts | null>(null)

const [drumPreset, setDrumPreset] = React.useState<DrumPreset>(DRUM_PRESETS.BOOTS_AND_CATS)
const drumPartRef = React.useRef<Part | null>(null)

useEffect(() => {
const drumPart = new Part<DrumEvent>((time, value) => {
drumSampler.current?.triggerAttackRelease(value.notes, 1, time, value.velocity)
},
DRUM_PRESETS_LOOPS.BOOTS_AND_CATS
).start('0:0')
drumPart.loop = true;
drumPart.loopStart = '0:0'
drumPart.loopEnd = '1m'
drumPartRef.current = drumPart
}, [drumSampler, isStarted])


useEffect(() => {
if (isStarted) {
if (chordPartRefs.current == null) {
const initialTriads = scaleToTriads(DEFAULT_SCALE_OPTIONS)
// chordPartRefs.current = []
_.times(4, (i) => {
if (chordPartRefs.current == null) {
chordPartRefs.current = []
}

const initialRomanNumeral = INITIAL_CHORD_LIST[i]

const initialChord = initialTriads[CHORD_TO_INDEX[initialRomanNumeral]]?.notes || ['C5']

const initialPartValue = fillChordPattern(i, initialChord, 'DDDD')

const part = new Part((time, value) => {
chordSynth.current?.triggerAttackRelease(value.notes || ['C4'], '8n', time, value.velocity)
},
initialPartValue
).start(0)

part.loop = true
part.humanize = true
part.loopStart = '0:0'
part.loopEnd = '4m'
chordPartRefs.current.push({
part,
chord: initialRomanNumeral
})
})
}
}
}, [chordSynth, isStarted])

useEffect(() => {
chordList.forEach((c, i) => {
if (chordPartRefs.current) { // && chordPartRefs.current[i].chord !== c) {
updateChordPart(chordPartRefs.current[i].part, i, c, chordPattern)
chordPartRefs.current[i].chord = c
return
}
})
}, [chordList, chordPattern])

useEffect(() => {
console.log(drumPreset)
if (isStarted && drumPartRef.current) {
updateRhythmPart(drumPartRef.current, drumPreset)
}
}, [drumPreset, isStarted])

const getUpdateChordInListFunction = (i: number) => {
return (c: ChordSymbol) => {
setChordList((prevList) => {
const newList = [...prevList]
newList[i] = c
return newList
})
}
}
// const getUpdateChordInListFunction = (i: number) => {
// return (c: ChordSymbol) => {
// setChordList((prevList) => {
// const newList = [...prevList]
// newList[i] = c
// return newList
// })
// }
// }

return (
<>
<OctoStage />
<WorkflowProvider>
<header className='app-header'>
<h1 style={{ margin: 0 }}>OctoLooper</h1>
<RhythmSelector setSelectedRhythm={setDrumPreset} selectedRhythm={drumPreset} />
</header>
<main className="main">
<div className='top'>


{/* <main className="main"> */}
<AllSteps />
{/* <div className='top'>
<h3 style={{ margin: 0 }}>
<span className='curve-arrow'> ⤹ </span> Mix It Up <span className='curve-arrow'> ⤸ </span>
Expand All @@ -168,9 +52,9 @@ function App() {
<ChordPatternSelector setSelectedPattern={setChordPattern} selectedPattern={chordPattern} />
</div>

</main >
</>
*/}
{/* </main > */}
</WorkflowProvider>
)
}

Expand Down
Loading

0 comments on commit 2a02cda

Please sign in to comment.