Skip to content

Commit

Permalink
Add Melodic & Natural minor scales
Browse files Browse the repository at this point in the history
  • Loading branch information
ZaneH committed Jul 5, 2022
1 parent 858d1d8 commit 3a8cde5
Show file tree
Hide file tree
Showing 6 changed files with 316 additions and 30 deletions.
14 changes: 8 additions & 6 deletions src/components/Trainer/TrainerDisplay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Select from 'react-select'
import styled from 'styled-components'
import {
AvailablePracticeModesType,
AvailableScalesType,
AvailableMajorScalesType,
AVAILABLE_MODES,
AVAILABLE_SCALES,
} from '../../utils'
Expand Down Expand Up @@ -61,8 +61,8 @@ const TrainerDisplay = () => {
} = useContext(TrainerContext)

const scaleOptions = Object.keys(AVAILABLE_SCALES).map((s: string) => ({
label: AVAILABLE_SCALES[s as AvailableScalesType].label,
value: AVAILABLE_SCALES[s as AvailableScalesType].value,
label: AVAILABLE_SCALES[s as AvailableMajorScalesType].label,
value: AVAILABLE_SCALES[s as AvailableMajorScalesType].value,
}))

const modeOptions = Object.keys(AVAILABLE_MODES).map((s: string) => ({
Expand Down Expand Up @@ -93,11 +93,13 @@ const TrainerDisplay = () => {
<Select
options={scaleOptions}
value={{
label: AVAILABLE_SCALES[scale?.value as AvailableScalesType].label,
value: AVAILABLE_SCALES[scale?.value as AvailableScalesType].value,
label:
AVAILABLE_SCALES[scale?.value as AvailableMajorScalesType].label,
value:
AVAILABLE_SCALES[scale?.value as AvailableMajorScalesType].value,
}}
onChange={(e) => {
setScale?.(AVAILABLE_SCALES[e?.value as AvailableScalesType])
setScale?.(AVAILABLE_SCALES[e?.value as AvailableMajorScalesType])
}}
/>
</TrainerSection>
Expand Down
1 change: 1 addition & 0 deletions src/components/Trainer/TrainerPiano.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ const TrainerPiano = () => {
return <InKeyMarker>{midiNumber}</InKeyMarker>
} else {
if (isHardModeEnabled) {
// only add the first marker in hard mode
if (midiNumber % 12 === 0) {
return (
<InKeyMarker>{modScale.keys[midiNumber % 12]}</InKeyMarker>
Expand Down
39 changes: 37 additions & 2 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,20 @@
import { AvailableScalesType } from './scales/majors'
import {
AvailableMajorScalesType,
AVAILABLE_MAJOR_SCALES,
} from './scales/major'
import {
AvailableMinorMelodicScalesType,
AVAILABLE_MINOR_MELODIC_SCALES,
} from './scales/minor.melodic'
import {
AvailableMinorNaturalScalesType,
AVAILABLE_MINOR_NATURAL_SCALES,
} from './scales/minor.natural'

type AvailableScalesType =
| AvailableMajorScalesType
| AvailableMinorNaturalScalesType
| AvailableMinorMelodicScalesType

export type ScaleType = {
label?: string
Expand All @@ -8,5 +24,24 @@ export type ScaleType = {
}
}

export * from './scales/majors'
export const AVAILABLE_SCALES: {
[key in AvailableScalesType]: ScaleType
} = {
...AVAILABLE_MAJOR_SCALES,
...AVAILABLE_MINOR_NATURAL_SCALES,
...AVAILABLE_MINOR_MELODIC_SCALES,
}

export const ignoreOctave = (scale: ScaleType): ScaleType => {
const scaleKeys: string[] = Object.keys(scale.keys || {})
const modKeys: ScaleType = { keys: {} }

for (const k of scaleKeys) {
modKeys.keys[Number(k) % 12] = scale!.keys![Number(k)]
}

return modKeys
}

export * from './scales/major'
export * from './modes/practice'
34 changes: 12 additions & 22 deletions src/utils/scales/Majors.ts → src/utils/scales/major.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,18 +105,7 @@ const BMajor: ScaleType = {
},
} as const

const ignoreOctave = (scale: ScaleType): ScaleType => {
const scaleKeys: string[] = Object.keys(scale.keys || {})
const modKeys: ScaleType = { keys: {} }

for (const k of scaleKeys) {
modKeys.keys[Number(k) % 12] = scale!.keys![Number(k)]
}

return modKeys
}

export type AvailableScalesType =
export type AvailableMajorScalesType =
| 'c-major'
| 'd-major'
| 'e-major'
Expand All @@ -125,14 +114,15 @@ export type AvailableScalesType =
| 'a-major'
| 'b-major'

const AVAILABLE_SCALES: { [key in AvailableScalesType]: ScaleType } = {
'c-major': CMajor,
'd-major': DMajor,
'e-major': EMajor,
'f-major': FMajor,
'g-major': GMajor,
'a-major': AMajor,
'b-major': BMajor,
} as const
const AVAILABLE_MAJOR_SCALES: { [key in AvailableMajorScalesType]: ScaleType } =
{
'c-major': CMajor,
'd-major': DMajor,
'e-major': EMajor,
'f-major': FMajor,
'g-major': GMajor,
'a-major': AMajor,
'b-major': BMajor,
} as const

export { AVAILABLE_SCALES, ignoreOctave }
export { AVAILABLE_MAJOR_SCALES }
129 changes: 129 additions & 0 deletions src/utils/scales/minor.melodic.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import { ScaleType } from '..'

const CMinorMelodic: ScaleType = {
label: 'C Minor (Melodic)',
value: 'c-minor-melodic',
keys: {
48: 'i',
50: 'iiº',
51: 'III+',
53: 'IV',
55: 'V',
57: 'viº',
59: 'viiº',
60: 'i',
},
} as const

const DMinorMelodic: ScaleType = {
label: 'D Minor (Melodic)',
value: 'd-minor-melodic',
keys: {
50: 'i',
52: 'iiº',
53: 'III+',
55: 'IV',
57: 'V',
59: 'viº',
61: 'viiº',
62: 'i',
},
} as const

const EMinorMelodic: ScaleType = {
label: 'E Minor (Melodic)',
value: 'e-minor-melodic',
keys: {
52: 'i',
54: 'iiº',
55: 'III+',
57: 'IV',
59: 'V',
61: 'viº',
63: 'viiº',
64: 'i',
},
} as const

const FMinorMelodic: ScaleType = {
label: 'F Minor (Melodic)',
value: 'f-minor-melodic',
keys: {
53: 'i',
55: 'iiº',
56: 'III+',
58: 'IV',
60: 'V',
62: 'viº',
64: 'viiº',
65: 'i',
},
} as const

const GMinorMelodic: ScaleType = {
label: 'G Minor (Melodic)',
value: 'g-minor-melodic',
keys: {
55: 'i',
57: 'iiº',
58: 'III+',
60: 'IV',
62: 'V',
64: 'viº',
66: 'viiº',
67: 'i',
},
} as const

const AMinorMelodic: ScaleType = {
label: 'A Minor (Melodic)',
value: 'a-minor-melodic',
keys: {
57: 'i',
59: 'iiº',
60: 'III+',
62: 'IV',
64: 'V',
66: 'viº',
68: 'viiº',
69: 'i',
},
} as const

const BMinorMelodic: ScaleType = {
label: 'B Minor (Melodic)',
value: 'b-minor-melodic',
keys: {
59: 'i',
61: 'iiº',
62: 'III+',
64: 'IV',
66: 'V',
68: 'viº',
70: 'viiº',
71: 'i',
},
} as const

export type AvailableMinorMelodicScalesType =
| 'c-minor-melodic'
| 'd-minor-melodic'
| 'e-minor-melodic'
| 'f-minor-melodic'
| 'g-minor-melodic'
| 'a-minor-melodic'
| 'b-minor-melodic'

const AVAILABLE_MINOR_MELODIC_SCALES: {
[key in AvailableMinorMelodicScalesType]: ScaleType
} = {
'c-minor-melodic': CMinorMelodic,
'd-minor-melodic': DMinorMelodic,
'e-minor-melodic': EMinorMelodic,
'f-minor-melodic': FMinorMelodic,
'g-minor-melodic': GMinorMelodic,
'a-minor-melodic': AMinorMelodic,
'b-minor-melodic': BMinorMelodic,
} as const

export { AVAILABLE_MINOR_MELODIC_SCALES }
129 changes: 129 additions & 0 deletions src/utils/scales/minor.natural.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import { ScaleType } from '..'

const CMinorNatural: ScaleType = {
label: 'C Minor (Natural)',
value: 'c-minor-natural',
keys: {
48: 'i',
50: 'iiº',
51: 'III',
53: 'iv',
55: 'v',
56: 'VI',
58: 'VII',
60: 'i',
},
} as const

const DMinorNatural: ScaleType = {
label: 'D Minor (Natural)',
value: 'd-minor-natural',
keys: {
50: 'i',
52: 'iiº',
53: 'III',
55: 'iv',
57: 'v',
58: 'VI',
60: 'VII',
62: 'i',
},
} as const

const EMinorNatural: ScaleType = {
label: 'E Minor (Natural)',
value: 'e-minor-natural',
keys: {
52: 'i',
54: 'iiº',
55: 'III',
57: 'iv',
59: 'v',
60: 'VI',
62: 'VII',
64: 'i',
},
} as const

const FMinorNatural: ScaleType = {
label: 'F Minor (Natural)',
value: 'f-minor-natural',
keys: {
53: 'i',
55: 'iiº',
56: 'III',
58: 'iv',
60: 'v',
61: 'VI',
63: 'VII',
65: 'i',
},
} as const

const GMinorNatural: ScaleType = {
label: 'G Minor (Natural)',
value: 'g-minor-natural',
keys: {
55: 'i',
57: 'iiº',
58: 'III',
60: 'iv',
62: 'v',
63: 'VI',
65: 'VII',
67: 'i',
},
} as const

const AMinorNatural: ScaleType = {
label: 'A Minor (Natural)',
value: 'a-minor-natural',
keys: {
57: 'i',
59: 'iiº',
60: 'III',
62: 'iv',
64: 'v',
65: 'VI',
67: 'VII',
69: 'i',
},
} as const

const BMinorNatural: ScaleType = {
label: 'B Minor (Natural)',
value: 'b-minor-natural',
keys: {
59: 'i',
61: 'iiº',
62: 'III',
64: 'iv',
66: 'v',
67: 'VI',
69: 'VII',
71: 'i',
},
} as const

export type AvailableMinorNaturalScalesType =
| 'c-minor-natural'
| 'd-minor-natural'
| 'e-minor-natural'
| 'f-minor-natural'
| 'g-minor-natural'
| 'a-minor-natural'
| 'b-minor-natural'

const AVAILABLE_MINOR_NATURAL_SCALES: {
[key in AvailableMinorNaturalScalesType]: ScaleType
} = {
'c-minor-natural': CMinorNatural,
'd-minor-natural': DMinorNatural,
'e-minor-natural': EMinorNatural,
'f-minor-natural': FMinorNatural,
'g-minor-natural': GMinorNatural,
'a-minor-natural': AMinorNatural,
'b-minor-natural': BMinorNatural,
} as const

export { AVAILABLE_MINOR_NATURAL_SCALES }

0 comments on commit 3a8cde5

Please sign in to comment.