From 4c36ca7f1355a2c3fba06c1e6272d5a5e3d77697 Mon Sep 17 00:00:00 2001 From: Lumi Pakkanen Date: Tue, 2 May 2023 11:47:56 +0300 Subject: [PATCH 1/2] Make A4 the default reference pitch Use the English standard for 69 = A4 by default. Add configuration to recover the old French behavior 69 = A5. ref #401 --- src/App.vue | 9 +++++++++ src/components/ScaleBuilder.vue | 6 +++++- src/utils.ts | 11 ++++++++--- src/views/PreferencesView.vue | 16 ++++++++++++++++ src/views/ScaleView.vue | 3 +++ 5 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/App.vue b/src/App.vue index 8d8cfc46..07620c04 100644 --- a/src/App.vue +++ b/src/App.vue @@ -106,6 +106,7 @@ const colorScheme = ref<"light" | "dark">("light"); const centsFractionDigits = ref(3); const decimalFractionDigits = ref(5); const showVirtualQwerty = ref(false); +const midiOctaveOffset = ref(-1); // Special keyboard codes also from local storage. const deactivationCode = ref("Backquote"); @@ -748,6 +749,9 @@ onMounted(() => { if ("showVirtualQwerty" in storage) { showVirtualQwerty.value = storage.getItem("showVirtualQwerty") === "true"; } + if ("midiOctaveOffset" in storage) { + midiOctaveOffset.value = parseInt(storage.getItem("midiOctaveOffset")!); + } // Fetch special key map if ("deactivationCode" in storage) { @@ -897,6 +901,9 @@ watch(decimalFractionDigits, (newValue) => watch(showVirtualQwerty, (newValue) => window.localStorage.setItem("showVirtualQwerty", newValue.toString()) ); +watch(midiOctaveOffset, (newValue) => + window.localStorage.setItem("midiOctaveOffset", newValue.toString()) +); // Store keymaps watch(deactivationCode, (newValue) => window.localStorage.setItem("deactivationCode", newValue) @@ -993,6 +1000,7 @@ watch(degreeDownCode, (newValue) => :typingKeyboard="typingKeyboard" :keyboardMapping="keyboardMapping" :showVirtualQwerty="showVirtualQwerty" + :midiOctaveOffset="midiOctaveOffset" @update:audioDelay="audioDelay = $event" @update:mainVolume="mainVolume = $event" @update:scaleName="scaleName = $event" @@ -1018,6 +1026,7 @@ watch(degreeDownCode, (newValue) => @update:centsFractionDigits="centsFractionDigits = $event" @update:decimalFractionDigits="decimalFractionDigits = $event" @update:showVirtualQwerty="showVirtualQwerty = $event" + @update:midiOctaveOffset="midiOctaveOffset = $event" @update:deactivationCode="deactivationCode = $event" @update:equaveUpCode="equaveUpCode = $event" @update:equaveDownCode="equaveDownCode = $event" diff --git a/src/components/ScaleBuilder.vue b/src/components/ScaleBuilder.vue index cac46af5..ea64b6b6 100644 --- a/src/components/ScaleBuilder.vue +++ b/src/components/ScaleBuilder.vue @@ -50,6 +50,8 @@ const props = defineProps<{ centsFractionDigits: number; decimalFractionDigits: number; newline: string; + + midiOctaveOffset: number; }>(); const emit = defineEmits([ @@ -373,7 +375,9 @@ function copyToClipboard() { step="1" v-model="baseMidiNote" /> - {{ midiNoteNumberToName(baseMidiNote) }} + {{ + midiNoteNumberToName(baseMidiNote, props.midiOctaveOffset) + }} diff --git a/src/utils.ts b/src/utils.ts index 8d6e469c..98d77ef3 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -33,10 +33,15 @@ const MIDI_NOTE_NAMES = [ "B", ]; -// Find MIDI note name from MIDI note number -export function midiNoteNumberToName(noteNumber: number) { +/** + * Convert an integer MIDI note number to a name such as A4. + * @param noteNumber MIDI note number to convert. + * @param octaveOffset Defaults to the English standard: 69 = A4. An offset of zero results in the French standard 69 = A5. + * @returns String representation of the MIDI note number. + */ +export function midiNoteNumberToName(noteNumber: number, octaveOffset = -1) { const remainder = mmod(noteNumber, 12); - const quotient = (noteNumber - remainder) / 12; + const quotient = (noteNumber - remainder) / 12 + octaveOffset; return MIDI_NOTE_NAMES[remainder] + quotient.toString(); } diff --git a/src/views/PreferencesView.vue b/src/views/PreferencesView.vue index 6c59dbac..6a83e9f3 100644 --- a/src/views/PreferencesView.vue +++ b/src/views/PreferencesView.vue @@ -8,6 +8,7 @@ const props = defineProps<{ centsFractionDigits: number; decimalFractionDigits: number; showVirtualQwerty: boolean; + midiOctaveOffset: number; }>(); const emit = defineEmits([ @@ -17,6 +18,7 @@ const emit = defineEmits([ "update:decimalFractionDigits", "update:virtualKeyboardMode", "update:showVirtualQwerty", + "update:midiOctaveOffset", ]); const newline = computed({ @@ -39,6 +41,10 @@ const showVirtualQwerty = computed({ get: () => props.showVirtualQwerty, set: (newValue: boolean) => emit("update:showVirtualQwerty", newValue), }); +const midiOctaveOffset = computed({ + get: () => props.midiOctaveOffset, + set: (newValue: number) => emit("update:midiOctaveOffset", newValue), +});