Skip to content

Commit

Permalink
allow setting range manually, randomize notes better
Browse files Browse the repository at this point in the history
  • Loading branch information
TeemuKoivisto committed Jan 18, 2024
1 parent ce0f7f4 commit 8044a80
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 7 deletions.
55 changes: 51 additions & 4 deletions packages/client/src/components/MidiInfo.svelte
Original file line number Diff line number Diff line change
@@ -1,14 +1,39 @@
<script lang="ts">
import { midiActions, midiInput, midiRange } from '$stores/midi'
import { getNote } from '$utils/midi'
import { getNote, parseNote } from '$utils/midi'
let rangeMin = getNote($midiRange[0]).absolute
let rangeMax = getNote($midiRange[1]).absolute
let rangeError = ''
function handleSetRange() {
// prompt -> press the lowest note in your MIDI device
// press the highest note in your MIDI device
}
function handleRangeChanged(
rang: 'min' | 'max',
e: Event & {
currentTarget: EventTarget & HTMLInputElement
}
) {
const parsed = parseNote(e.currentTarget.value)
if ('data' in parsed) {
const old = $midiRange
const range = [
rang === 'min' ? parsed.data : old[0],
rang === 'max' ? parsed.data : old[1]
] as [number, number]
midiActions.setMidiRange(range)
rangeError = ''
} else {
rangeError = parsed.err
if (rang === 'min') {
rangeMin = getNote($midiRange[0]).absolute
} else {
rangeMax = getNote($midiRange[1]).absolute
}
}
}
</script>

<div class={`${$$props.class || ''}`}>
Expand All @@ -25,14 +50,33 @@
<div class="flex flex-col">
<label class="font-bold" for="range_min">Range</label>
<div class="my-1 flex">
<input class="w-10" id="range_min" bind:value={rangeMin} />
<input
class="w-10"
id="range_min"
bind:value={rangeMin}
on:change={e => handleRangeChanged('min', e)}
/>
<span class="mx-2">-</span>
<input class="w-10" id="range_max" bind:value={rangeMax} />
<input
class="w-10"
id="range_max"
bind:value={rangeMax}
on:change={e => handleRangeChanged('max', e)}
/>
</div>
<div>
{#if rangeError}
<div class="error">{rangeError}</div>
{/if}
<button class="btn primary" on:click={handleSetRange}>Use MIDI</button>
</div>
</div>
<div class="flex flex-col h-full">
<label class="font-bold" for="sound">Sound</label>
<div class="my-1 flex">
<input class="w-10" id="sound" type="checkbox" value="false" />
</div>
</div>
</div>
</fieldset>
</div>
Expand All @@ -41,8 +85,11 @@
.midi-body {
display: grid;
gap: 0.5rem;
grid-template-columns: 25% 25%;
grid-template-columns: 25% 25% 25%;
grid-template-rows: auto;
align-items: center;
}
.error {
@apply text-xs text-red-500;
}
</style>
2 changes: 1 addition & 1 deletion packages/client/src/routes/(site)/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
</script>

<div class="flex-col items-center justify-center">
<main class="flex-col items-center justify-center h-full min-h-screen max-w-[800px] mx-[auto]">
<main class="flex-col items-center justify-center h-full min-h-screen max-w-[732px] mx-[auto]">
<slot />
</main>
</div>
12 changes: 11 additions & 1 deletion packages/client/src/stores/game.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,17 @@ export const gameActions = {
const range = get(midiRange)
console.log('range', range)
for (let i = 0; i < amount; i += 1) {
notes.push(range[0] + Math.floor(Math.random() * (range[1] - range[0])))
let attempts = 0,
val: number = range[1]
// Try having all values unique
while (attempts < 5) {
attempts += 1
val = range[0] + Math.floor(Math.random() * (range[1] - range[0]))
if (!notes.includes(val)) {
attempts = 5
}
}
notes.push(val)
}
const game = new GuessGame(notes)
console.log('new game ', notes)
Expand Down
4 changes: 3 additions & 1 deletion packages/client/src/stores/midi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,7 @@ export const midiActions = {
})
.catch(err => ({ err: err.toString(), code: 403 }))
},
setMidiRange() {}
setMidiRange(range: [number, number]) {
midiRange.set(range)
}
}
21 changes: 21 additions & 0 deletions packages/client/src/utils/midi.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { Result } from '@/types'

export const C_MAJOR_NOTES = {
0: { note: 'C', steps: 0, sharp: false, flat: false },
1: { note: 'C♯', steps: 0, sharp: true, flat: false },
Expand All @@ -22,3 +24,22 @@ export function getNote(value: number) {
const note = C_MAJOR_NOTES[(semitonesFromC0 % 12) as keyof typeof C_MAJOR_NOTES]
return { ...note, absolute: `${note.note}${octave}` }
}

export function parseNote(val: string): Result<number> {
if (val.length === 2 || val.length === 3) {
const note = val.slice(0, val.length - 1).toUpperCase()
let octave: number | undefined
try {
octave = parseInt(val[val.length - 1])
} catch (err) {
return { err: `Couldn't parse note "${val}" octave`, code: 400 }
}
const found = Object.values(C_MAJOR_NOTES).find(n => n.note === note)
if (!found) {
return { err: `Note "${val}" not found in scale`, code: 400 }
}
return { data: 12 + octave * 7 + found.steps }
} else {
return { err: `Unrecognized note "${val}"`, code: 400 }
}
}

0 comments on commit 8044a80

Please sign in to comment.