diff --git a/app/src/main/java/de/moekadu/tuner/preferences/PreferenceResources.kt b/app/src/main/java/de/moekadu/tuner/preferences/PreferenceResources.kt index e58d9777..79195ac3 100644 --- a/app/src/main/java/de/moekadu/tuner/preferences/PreferenceResources.kt +++ b/app/src/main/java/de/moekadu/tuner/preferences/PreferenceResources.kt @@ -144,6 +144,8 @@ class PreferenceResources( val notationType = when(notation) { "international" -> NotationType.International "solfege" -> NotationType.Solfege + "carnatic" -> NotationType.Carnatic + "hindustani" -> NotationType.Hindustani else -> NotationType.Standard } val sharpFlatPreference = if (preferFlat) diff --git a/app/src/main/java/de/moekadu/tuner/temperaments/MusicalNote.kt b/app/src/main/java/de/moekadu/tuner/temperaments/MusicalNote.kt index a495c9dd..993c2aeb 100644 --- a/app/src/main/java/de/moekadu/tuner/temperaments/MusicalNote.kt +++ b/app/src/main/java/de/moekadu/tuner/temperaments/MusicalNote.kt @@ -63,8 +63,8 @@ data class MusicalNote(val base: BaseNote, val modifier: NoteModifier, val octav } /** Return a note, where enharmonic and base represenation are exchanged. */ - fun switchEnharmonic(): MusicalNote { - if (enharmonicBase == BaseNote.None) + fun switchEnharmonic(switchAlsoForBaseNone: Boolean = false): MusicalNote { + if (enharmonicBase == BaseNote.None && !switchAlsoForBaseNone) return this return MusicalNote(base = enharmonicBase, modifier = enharmonicModifier, octave = octave, octaveOffset = enharmonicOctaveOffset, diff --git a/app/src/main/java/de/moekadu/tuner/temperaments/NoteNamePrinter.kt b/app/src/main/java/de/moekadu/tuner/temperaments/NoteNamePrinter.kt index 93ddd80d..44f6e120 100644 --- a/app/src/main/java/de/moekadu/tuner/temperaments/NoteNamePrinter.kt +++ b/app/src/main/java/de/moekadu/tuner/temperaments/NoteNamePrinter.kt @@ -198,75 +198,85 @@ class NoteNamePrinter( } private fun resolveNoteProperties(note: MusicalNote): ResolvedNoteProperties { - // check if there is a direct note name capturing base and modifier + return if (preferEnharmonic(note)) { + resolveNotePropertiesWithoutEnharmonicCheck(note.switchEnharmonic(switchAlsoForBaseNone = true)) + } else { + resolveNotePropertiesWithoutEnharmonicCheck(note) + } + } + + private fun resolveNotePropertiesWithoutEnharmonicCheck(note: MusicalNote): ResolvedNoteProperties { + // check if we can directly resolve the note val stem = NoteNameStem.fromMusicalNote(note) - val noteNameOriginal = noteResourceIds[stem]?.let{ context.getString(it) } - if (noteNameOriginal != null && noteNameOriginal != "" && noteNameOriginal != "-") { + val noteName = noteResourceIds[stem]?.let { context.getString(it) } + if (noteName != null && noteName != "" && noteName != "-") { return ResolvedNoteProperties( - baseName = noteNameOriginal, + baseName = noteName, modifier = NoteModifier.None, octave = if (note.octave == Int.MAX_VALUE) Int.MAX_VALUE else note.octave + note.octaveOffset ) } - // check if there is a direct note name of the enharmonic capturing base and modifier - val noteEnharmonic = note.switchEnharmonic() + // check if we can directly resolve the enharmonic + val noteEnharmonic = note.switchEnharmonic(switchAlsoForBaseNone = true) val stemEnharmonic = NoteNameStem.fromMusicalNote(noteEnharmonic) - val noteNameEnharmonic = noteResourceIds[stemEnharmonic]?.let{ context.getString(it) } - if (noteNameEnharmonic != null && noteNameEnharmonic !="" && noteNameEnharmonic != "-") { + val noteNameEnharmonic = noteResourceIds[stemEnharmonic]?.let { context.getString(it) } + + if (noteNameEnharmonic != null && noteNameEnharmonic != "" && noteNameEnharmonic != "-") { return ResolvedNoteProperties( baseName = noteNameEnharmonic, modifier = NoteModifier.None, - octave = if (note.octave == Int.MAX_VALUE) Int.MAX_VALUE else note.octave + note.octaveOffset + octave = if (note.octave == Int.MAX_VALUE) Int.MAX_VALUE else noteEnharmonic.octave + noteEnharmonic.octaveOffset ) } - // construct note name based on base note and modifier -> either for enharmonic, or directly - if (preferEnharmonic(note)) { - val stemEnharmonicBase = NoteNameStem( - noteEnharmonic.base, NoteModifier.None, BaseNote.None, NoteModifier.None - ) - val noteNameEnharmonicBase = - noteResourceIds[stemEnharmonicBase]?.let { context.getString(it) } - if (noteNameEnharmonicBase != null && noteNameEnharmonicBase != "" && noteNameEnharmonicBase != "-") { - return ResolvedNoteProperties( - baseName = noteNameEnharmonicBase, - modifier = noteEnharmonic.modifier, - octave = if (noteEnharmonic.octave == Int.MAX_VALUE) Int.MAX_VALUE else noteEnharmonic.octave + noteEnharmonic.octaveOffset - ) - } - } else { - val stemBase = NoteNameStem( - note.base, NoteModifier.None, BaseNote.None, NoteModifier.None + // try to resolve note by base name + modifier + val stemBase = NoteNameStem( + note.base, NoteModifier.None, BaseNote.None, NoteModifier.None + ) + val noteNameBase = noteResourceIds[stemBase]?.let { context.getString(it) } + if (noteNameBase != null && noteNameBase != "" && noteNameBase != "-") { + return ResolvedNoteProperties( + baseName = noteNameBase, + modifier = note.modifier, + octave = if (note.octave == Int.MAX_VALUE) Int.MAX_VALUE else note.octave + note.octaveOffset ) - val noteNameBase = - noteResourceIds[stemBase]?.let { context.getString(it) } - if (noteNameBase != null && noteNameBase != "" && noteNameBase != "-") { - return ResolvedNoteProperties( - baseName = noteNameBase, - modifier = note.modifier, - octave = if (note.octave == Int.MAX_VALUE) Int.MAX_VALUE else note.octave + note.octaveOffset - ) - } } - // note able to resolve note name, print a X + // try to resolve note by enharmonic base name + modifier + val stemEnharmonicBase = NoteNameStem( + noteEnharmonic.base, NoteModifier.None, BaseNote.None, NoteModifier.None + ) + val noteNameEnharmonicBase = noteResourceIds[stemEnharmonicBase]?.let { context.getString(it) } + if (noteNameEnharmonicBase != null && noteNameEnharmonicBase != "" && noteNameEnharmonicBase != "-") { + return ResolvedNoteProperties( + baseName = noteNameEnharmonicBase, + modifier = noteEnharmonic.modifier, + octave = if (note.octave == Int.MAX_VALUE) Int.MAX_VALUE else noteEnharmonic.octave + noteEnharmonic.octaveOffset + ) + } return ResolvedNoteProperties("X", NoteModifier.None, note.octave) } private fun preferEnharmonic(note: MusicalNote): Boolean { if (note.enharmonicBase == BaseNote.None) - return false + return sharpFlatPreference == SharpFlatPreference.Flat return when (sharpFlatPreference) { SharpFlatPreference.None -> { false } SharpFlatPreference.Sharp -> { - note.enharmonicModifier.flatSharpIndex() > note.modifier.flatSharpIndex() + if (note.enharmonicModifier.flatSharpIndex() == note.modifier.flatSharpIndex()) + false + else + note.enharmonicModifier.flatSharpIndex() > note.modifier.flatSharpIndex() } SharpFlatPreference.Flat -> { - note.enharmonicModifier.flatSharpIndex() < note.modifier.flatSharpIndex() + if (note.enharmonicModifier.flatSharpIndex() == note.modifier.flatSharpIndex()) + true + else + note.enharmonicModifier.flatSharpIndex() < note.modifier.flatSharpIndex() } } } diff --git a/app/src/main/java/de/moekadu/tuner/temperaments/NoteNamePrinterFactory.kt b/app/src/main/java/de/moekadu/tuner/temperaments/NoteNamePrinterFactory.kt index 0ac8cc60..1b6e43e8 100644 --- a/app/src/main/java/de/moekadu/tuner/temperaments/NoteNamePrinterFactory.kt +++ b/app/src/main/java/de/moekadu/tuner/temperaments/NoteNamePrinterFactory.kt @@ -6,7 +6,9 @@ import de.moekadu.tuner.R enum class NotationType { Standard, International, - Solfege + Solfege, + Carnatic, + Hindustani } // if more special note names are needed, (like ashparp_bflat -> B in German), this can easily @@ -43,20 +45,43 @@ private val noteInternationalResourceIds = mapOf( NoteNameStem(BaseNote.B) to R.string.b_note_international, ) -//private val noteCarnaticResourceIds = mapOf( -// NoteNameStem(BaseNote.C) to R.string.c_carnatic, -// NoteNameStem(BaseNote.C, NoteModifier.Sharp, BaseNote.D, NoteModifier.Flat) to R.string.csharp_dflat_carnatic, -// NoteNameStem(BaseNote.D) to R.string.d_carnatic, -// NoteNameStem(BaseNote.D, NoteModifier.Sharp, BaseNote.E, NoteModifier.Flat) to R.string.dsharp_eflat_carnatic, -// NoteNameStem(BaseNote.E) to R.string.e_carnatic, -// NoteNameStem(BaseNote.F) to R.string.f_carnatic, -// NoteNameStem(BaseNote.F, NoteModifier.Sharp, BaseNote.G, NoteModifier.Flat) to R.string.fsharp_gflat_carnatic, -// NoteNameStem(BaseNote.G) to R.string.g_carnatic, -// NoteNameStem(BaseNote.G, NoteModifier.Sharp, BaseNote.A, NoteModifier.Flat) to R.string.gsharp_aflat_carnatic, -// NoteNameStem(BaseNote.A) to R.string.a_carnatic, -// NoteNameStem(BaseNote.A, NoteModifier.Sharp, BaseNote.B, NoteModifier.Flat) to R.string.asharp_bflat_carnatic, -// NoteNameStem(BaseNote.B) to R.string.b_carnatic, -//) +private val noteCarnaticResourceIds = mapOf( + NoteNameStem(BaseNote.C) to R.string.sa_carnatic, + NoteNameStem(BaseNote.C, NoteModifier.Sharp, BaseNote.D, NoteModifier.Flat) to R.string.ri1_carnatic, + NoteNameStem(BaseNote.D) to R.string.ri2_carnatic, + NoteNameStem(BaseNote.None, enharmonicBaseNote = BaseNote.D) to R.string.ga1_carnatic, + NoteNameStem(BaseNote.D, NoteModifier.Sharp, BaseNote.E, NoteModifier.Flat) to R.string.ri3_carnatic, + NoteNameStem(BaseNote.E, NoteModifier.Flat, BaseNote.D, NoteModifier.Sharp) to R.string.ga2_carnatic, + NoteNameStem(BaseNote.E) to R.string.ga3_carnatic, + NoteNameStem(BaseNote.F) to R.string.ma1_carnatic, + NoteNameStem(BaseNote.F, NoteModifier.Sharp, BaseNote.G, NoteModifier.Flat) to R.string.ma2_carnatic, + NoteNameStem(BaseNote.G) to R.string.pa_carnatic, + NoteNameStem(BaseNote.G, NoteModifier.Sharp, BaseNote.A, NoteModifier.Flat) to R.string.dha1_carnatic, + NoteNameStem(BaseNote.A) to R.string.ni1_carnatic, + NoteNameStem(BaseNote.None, enharmonicBaseNote = BaseNote.A) to R.string.dha2_carnatic, + NoteNameStem(BaseNote.A, NoteModifier.Sharp, BaseNote.B, NoteModifier.Flat) to R.string.ni2_carnatic, + NoteNameStem(BaseNote.B, NoteModifier.Flat, BaseNote.A, NoteModifier.Sharp) to R.string.dha3_carnatic, + NoteNameStem(BaseNote.B) to R.string.ni3_carnatic, +) + +private val noteHindustaniResourceIds = mapOf( + NoteNameStem(BaseNote.C) to R.string.sa_hindustani, + NoteNameStem(BaseNote.C, NoteModifier.Sharp, BaseNote.D, NoteModifier.Flat) to R.string.re1_hindustani, + NoteNameStem(BaseNote.D) to R.string.re2_hindustani, + NoteNameStem(BaseNote.None, enharmonicBaseNote = BaseNote.D) to R.string.ga1_hindustani, + NoteNameStem(BaseNote.D, NoteModifier.Sharp, BaseNote.E, NoteModifier.Flat) to R.string.re3_hindustani, + NoteNameStem(BaseNote.E, NoteModifier.Flat, BaseNote.D, NoteModifier.Sharp) to R.string.ga2_hindustani, + NoteNameStem(BaseNote.E) to R.string.ga3_hindustani, + NoteNameStem(BaseNote.F) to R.string.ma1_hindustani, + NoteNameStem(BaseNote.F, NoteModifier.Sharp, BaseNote.G, NoteModifier.Flat) to R.string.ma2_hindustani, + NoteNameStem(BaseNote.G) to R.string.pa_hindustani, + NoteNameStem(BaseNote.G, NoteModifier.Sharp, BaseNote.A, NoteModifier.Flat) to R.string.dha1_hindustani, + NoteNameStem(BaseNote.A) to R.string.ni1_hindustani, + NoteNameStem(BaseNote.None, enharmonicBaseNote = BaseNote.A) to R.string.dha2_hindustani, + NoteNameStem(BaseNote.A, NoteModifier.Sharp, BaseNote.B, NoteModifier.Flat) to R.string.ni2_hindustani, + NoteNameStem(BaseNote.B, NoteModifier.Flat, BaseNote.A, NoteModifier.Sharp) to R.string.dha3_hindustani, + NoteNameStem(BaseNote.B) to R.string.ni3_hindustani, +) fun createNoteNamePrinter( context: Context, @@ -81,5 +106,17 @@ fun createNoteNamePrinter( NoteNamePrinter.MaxNoteNameWidth.MultipleLetters ) } + NotationType.Carnatic -> { + NoteNamePrinter( + context, sharpFlatPreference, noteCarnaticResourceIds, + NoteNamePrinter.MaxNoteNameWidth.MultipleLetters + ) + } + NotationType.Hindustani -> { + NoteNamePrinter( + context, sharpFlatPreference, noteHindustaniResourceIds, + NoteNamePrinter.MaxNoteNameWidth.MultipleLetters + ) + } } } diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 4af1d317..f8516e3b 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -35,11 +35,15 @@ "standard" "solfege" "international" + "carnatic" + "hindustani" @string/notation_standard @string/notation_solfege @string/notation_international + @string/notation_carnatic + @string/notation_hindustani diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index eadd4db9..b5bb6442 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -252,4 +252,38 @@ Disable capturing Capture in scientific mode Solfège notation + Sa + Ri₁ + Ri₂ + Ga₁ + Ga₂ + Ri₃ + Ga₃ + Ma₁ + Ma₂ + Pa + Dha₁ + Dha₂ + Ni₁ + Ni₂ + Dha₃ + Ni₃ + Carnatic + Sa + Re₁ + Re₂ + Ga₁ + Ga₂ + Re₃ + Ga₃ + Ma₁ + Ma₂ + Pa + Dha₁ + Dha₂ + Ni₁ + Ni₂ + Dha₃ + Ni₃ + Hindustani