Skip to content

Commit

Permalink
General code improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
ZaneH committed Jul 17, 2022
1 parent 44ca9e2 commit 910e2dc
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 17 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# Piano Trainer

Learn to play the piano at your own pace through various modes of practice. [Watch video](https://vimeo.com/730642802)
Learn to play the piano at your own pace through various modes of practice. [Watch the video](https://vimeo.com/730642802)

<p align="center">
<img alt="Piano Trainer screenshot" src="https://i.imgur.com/k2y1Gr5.png" height="250px" />
Expand Down
11 changes: 7 additions & 4 deletions src/components/Keyboard/Keyboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import { KeyboardShortcuts, MidiNumbers, Piano } from 'react-piano'
import 'react-piano/dist/styles.css'
import styled, { css } from 'styled-components'
import {
getFifthFromMidiNote,
getTriadChordFromMidiNote,
getFifthFromMidiNumber,
getTriadChordFromMidiNumber,
MidiDevice,
midiNumberToNote,
} from '../../utils'
Expand Down Expand Up @@ -116,7 +116,7 @@ const Keyboard = () => {
}))
setChordStack?.([])
} else if (practiceMode === 'chords') {
const targetChord = getTriadChordFromMidiNote(
const targetChord = getTriadChordFromMidiNumber(
noteTracker?.nextTargetMidiNumber!,
scale!
)
Expand All @@ -139,7 +139,10 @@ const Keyboard = () => {
// turn the target numbers into target letters to ignore octave for matching
const targetFifths = [
noteTracker?.nextTargetMidiNumber!,
getFifthFromMidiNote(noteTracker?.nextTargetMidiNumber!, scale?.value!),
getFifthFromMidiNumber(
noteTracker?.nextTargetMidiNumber!,
scale?.value!
),
]

const targetFifthNotes = targetFifths.map((f) => midiNumberToNote(f))
Expand Down
4 changes: 2 additions & 2 deletions src/components/Quiz/Quiz.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import styled from 'styled-components'
import {
CIRCLE_OF_FIFTHS,
convertKeyToScalesKey,
getBothFifthsFromMidiNote,
getBothFifthsFromMidiNumber,
getRandomFifth,
getRandomKey,
isAdjacentFifth,
Expand Down Expand Up @@ -174,7 +174,7 @@ const Quiz = () => {

const currentValidMidi = useMemo<number[]>(() => {
if (currentQuestion.type === 'fifth') {
return getBothFifthsFromMidiNote(
return getBothFifthsFromMidiNumber(
MidiNumbers.fromNote(
`${swapNoteWithSynonym(currentQuestionKey, currentQuestion.majMin)}3`
),
Expand Down
12 changes: 6 additions & 6 deletions src/components/Trainer/TrainerPiano.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import styled from 'styled-components'
import {
AvailableAllScalesType,
AVAILABLE_MAJOR_SCALES,
getFifthFromMidiNote,
getTriadChordFromMidiNote,
getFifthFromMidiNumber,
getTriadChordFromMidiNumber,
ignoreOctave,
OCTAVE_LENGTH,
} from '../../utils'
Expand Down Expand Up @@ -50,23 +50,23 @@ const TrainerPiano = () => {
}
} else if (practiceMode === 'chords') {
if (isHardModeEnabled) {
return getTriadChordFromMidiNote(noteTracker!.prevNote!, scale)
return getTriadChordFromMidiNumber(noteTracker!.prevNote!, scale)
} else {
return getTriadChordFromMidiNote(nextNote, scale)
return getTriadChordFromMidiNumber(nextNote, scale)
}
} else if (practiceMode === 'fifths') {
if (isHardModeEnabled) {
return [
noteTracker!.prevNote!,
getFifthFromMidiNote(
getFifthFromMidiNumber(
noteTracker!.prevNote!,
scale.value as AvailableAllScalesType
),
]
} else {
return [
nextNote,
getFifthFromMidiNote(
getFifthFromMidiNumber(
nextNote,
scale.value as AvailableAllScalesType
),
Expand Down
46 changes: 42 additions & 4 deletions src/utils/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import { MidiNumbers } from 'react-piano'

/**
* Returns the keys for a given `ScaleType` starting at c0 in midi numbers.
* @param scale A `ScaleType` including the keys to ignore the octave of
* @returns An array of objects with midi numbers as key and their roman numerals as value
*/
export const ignoreOctave = (scale: ScaleType): ScaleKeyType[] => {
const scaleKeys: string[] = Object.keys(scale.keys || {})
Expand All @@ -29,7 +31,13 @@ export const ignoreOctave = (scale: ScaleType): ScaleKeyType[] => {
return moduloKeys
}

export const getFifthFromMidiNote = (
/**
* Given a midi number, return another midi number that's a fifth away.
* @param midiNumber A midi number to get the fifth of
* @param scale The scale to follow for this fifth (unnecessary?)
* @returns A single midi number that is a fifth from the given midi number
*/
export const getFifthFromMidiNumber = (
midiNumber: number,
scale: AvailableAllScalesType
): number => {
Expand Down Expand Up @@ -61,7 +69,7 @@ export const getFifthFromMidiNote = (
* @param scale The fifths will fall in this key
* @returns An array with 2 fifths as midi numbers
*/
export const getBothFifthsFromMidiNote = (
export const getBothFifthsFromMidiNumber = (
midiNumber: number,
scale: AvailableAllScalesType
): number[] => {
Expand Down Expand Up @@ -184,7 +192,14 @@ export const swapNoteWithSynonym = (
}
}

export const getTriadChordFromMidiNote = (
/**
* Given a midi number, return three midi numbers that make up a chord with the
* provided scale.
* @param midiNumber A midi number to start the triad from
* @param scale The scale to follow for this chord
* @returns 3 midi numbers in an array that make up a triad starting from midiNumber
*/
export const getTriadChordFromMidiNumber = (
midiNumber: number,
scale: ScaleType
): number[] => {
Expand Down Expand Up @@ -216,7 +231,11 @@ export const getTriadChordFromMidiNote = (
return triadChordMidi
}

export const getRandomKey = () => {
/**
* Returns a random piano note as a string.
* @returns A random note (ex. C#, Db, F#, Gb)
*/
export const getRandomKey = (): string => {
const allKeys = 'ABCDEFG'
const allMods = ['', '#', 'b']
let potentialKey = ''
Expand All @@ -235,16 +254,30 @@ export const getRandomKey = () => {
return potentialKey
}

/**
* Helper function to generate a random `MajorMinorType` value.
* @returns Either 'Major' or 'Minor'
*/
export const getRandomMajMin = (): MajorMinorType => {
const options: MajorMinorType[] = ['Minor', 'Major']
return options[Math.floor(Math.random() * options.length)]
}

/**
* Helper function to generate a random note that will be on the Circle of Fifths.
* @param majMin Which scale to use to generate a random fifth note (unnecessary?)
* @returns A random note that's on the Circle of Fifths (ex. C, A, E, F#, etc.)
*/
export const getRandomFifth = (majMin: MajorMinorType) => {
const fifths = CIRCLE_OF_FIFTHS[majMin]
return fifths[Math.floor(Math.random() * fifths.length)]
}

/**
* Helper function to shuffle an array.
* @param array An array to shuffle
* @returns A shuffled array
*/
export function shuffle<T>(array: T[]): T[] {
let currentIndex = array.length,
randomIndex
Expand All @@ -265,6 +298,11 @@ export function shuffle<T>(array: T[]): T[] {
return array
}

/**
* Converts a given midi number to it's corresponding letter form. (ex. 48 = C)
* @param midiNumber A midi number to convert to a note
* @returns A note represented as a string without the octave.
*/
export const midiNumberToNote = (midiNumber: number): string => {
return MidiNumbers.getAttributes(midiNumber)
.note.toLowerCase()
Expand Down

0 comments on commit 910e2dc

Please sign in to comment.