diff --git a/composeApp/src/commonMain/kotlin/mg/dot/feufaro/solfa/Solfa.kt b/composeApp/src/commonMain/kotlin/mg/dot/feufaro/solfa/Solfa.kt index fddcd5f..2866936 100644 --- a/composeApp/src/commonMain/kotlin/mg/dot/feufaro/solfa/Solfa.kt +++ b/composeApp/src/commonMain/kotlin/mg/dot/feufaro/solfa/Solfa.kt @@ -105,7 +105,7 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository } val templateCharArray = pTemplate.template.toCharArray() var nextMarker: Char = '0' - templateCharArray.forEach { // D.-R + templateCharArray.forEachIndexed { index, it -> // D.-R when (it) { 'D', 'R', 'M', 'F', 'S', 'L', 'T', 'd', 'r', 'm', 'f', 's', 'l', 't', @@ -128,7 +128,22 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository '.', ',' -> unitObject.addMarker(it) - '-', 'Z', 'z', 'w' -> + '-' -> { + val prevChar = templateCharArray.getOrNull(index - 1) + val nextChar = templateCharArray.getOrNull(index + 1) + + val charToInsert = if (prevChar == '.' && nextChar == ',') { + ' ' + } else { + '-' + } + + N.indices.forEach { voiceNumber -> + unitObject.addBlank(voiceNumber, charToInsert) + } + } + + 'Z', 'z', 'w' -> N.indices.forEach { voiceNumber -> unitObject.addBlank(voiceNumber, it) } @@ -1038,7 +1053,7 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository var actionTaken = "Keep" if (rawBlockText.trim().isEmpty()) { - rawBlockText = if(isT0) "" else "z" + rawBlockText = if(isT0) "" else "-" actionTaken = if(isT0) "EMPTY->\"\"" else "EMPTY->z" } @@ -1777,6 +1792,8 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository val finalLines = (prefix + cleanedBlocks.joinToString("")) .replace("2z11", "y") + .replace("31", "y") + .replace("3-", "y") .replace(Regex("""\$\{.*?\}|/""")) { match -> if (match.value == "/") "/ " else match.value } @@ -1894,7 +1911,7 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository .replace(",'", "") .replace("',", "") - val noteCharIterator = noteChar2.replace("/", "").toCharArray().iterator() + val noteCharIterator = noteChar2.replace("/", "").replace(".", "").toCharArray().iterator() var result = "" var firstInLoop = true var replacement: Char = 'x' @@ -2060,8 +2077,9 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository var midiDuration = 0 var nextDuration = 0 var lastNoteString = "" + var lastPhysicalNote = "" val midiPitch = MidiPitch(voiceNumber) - var nextComment: MutableList = mutableListOf() + val nextComment = mutableListOf() var trioletCount = -1 var nextTrioletDuration = 0 fun pushMidi(typeBlock: String = "note") { @@ -2097,7 +2115,7 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository midiPitch.duration = 0 lastNoteString = "" midiDuration = 0 - nextComment = mutableListOf() + nextComment.clear() } midiPitch.currentVoiceNumber(voiceNumber) @@ -2115,6 +2133,7 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository } } var lastIt = ' ' + var lastSignificantIt = ' ' val newN = POneVoiceNote() val lineRepeated = REGEX_REPETITION.replace(line) { matchResult -> val (charIterated, iteration) = matchResult.destructured @@ -2124,15 +2143,16 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository var commentNumber = -1 var inSplit = false var expectSplitBrace = false - val lineChar = lineRepeated.toCharArray() - lineChar.forEach { + + var i = 0 + while (i < lineRepeated.length) { + val it = lineRepeated[i] when (it) { '|', ':', '!', '/' -> { - if (it == '|' && lastIt == '[') { - // le séparateur split - } else if (lastIt == '|' || lastIt == ':' || lastIt == '!' || lastIt == '/') { - } else { - midiDuration += nextDuration + if (!(it == '|' && lastIt == '[') && lastIt !in "|:!/") { + if (nextDuration > 0 && lastIt != '-') { + midiDuration += nextDuration + } nextDuration = 60 } } @@ -2152,29 +2172,60 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository } '.' -> { - if (lastIt == ';') { + if (lastIt == ';' || lastSignificantIt == ';') { pushMidi() lastNoteString = "z" midiDuration = 15 nextDuration = 30 } - midiDuration += nextDuration - 30 - nextDuration = 30 + if (lastSignificantIt == '-') { + midiDuration += 30 - nextDuration + nextDuration = 30 + } else { + if (nextDuration == 0) { + if (midiDuration == 0) { + midiDuration = 30 + } else { + midiDuration -= 30 + } + nextDuration = 30 + } else if (nextDuration <= 30) { + midiDuration += nextDuration + } else { + midiDuration += nextDuration - 30 + nextDuration = 30 + } + } } ';' -> { - if (lastIt == '.') { + if ((lastIt == '.' || lastSignificantIt == '.') && lastNoteString == "z" && midiDuration == 0) { pushMidi() lastNoteString = "z" midiDuration = 15 nextDuration = 15 } - if (nextDuration >= 45) { - midiDuration += nextDuration - 45 - nextDuration = 45 - } else { - midiDuration += nextDuration - 15 + if (lastSignificantIt == '-') { + midiDuration += 15 - nextDuration nextDuration = 15 + } else { + if (nextDuration == 0) { + if (midiDuration == 0) { + midiDuration = 15 + } else { + midiDuration -= 45 + } + nextDuration = 15 + } else if (nextDuration <= 15) { + midiDuration += nextDuration + nextDuration = 0 + } else if (nextDuration >= 45) { + midiDuration += nextDuration - 45 + nextDuration = 15 + } else { + midiDuration += nextDuration - 15 + nextDuration = 15 + } } } @@ -2182,6 +2233,9 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository if(!inSplit ){ newN.appendLastNote(it) lastNoteString += it + if (lastPhysicalNote.isNotEmpty() && lastPhysicalNote != "z") { + lastPhysicalNote += it + } } else { newN.appendLastSplitNoteSuffix(it) } @@ -2202,12 +2256,14 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository nextDuration = 60 } } - var noteString = it.toString().lowercase() - if (it == 'D' || it == 'R' || it == 'F' || it == 'S') { - noteString += "i" - } - if (it == 'T') { - noteString += "a" + + val noteString = when (it) { + 'D' -> "di" + 'R' -> "ri" + 'F' -> "fi" + 'S' -> "si" + 'T' -> "ta" + else -> it.lowercaseChar().toString() } if(inSplit) { newN.appendLastSplitNote(noteString) @@ -2215,58 +2271,91 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository newN.addItem(noteString) when (noteString) { "-" -> { - midiDuration += if (nextDuration > 0) nextDuration else 20 - nextDuration = 0 + if (lastNoteString == "z") { + pushMidi() + val targetNote = if (lastPhysicalNote.isNotEmpty() && lastPhysicalNote != "z") lastPhysicalNote else "s" + lastNoteString = targetNote + } + midiDuration += if (nextDuration > 0) nextDuration else 60 + if (nextDuration == 0) nextDuration = 60 } - "z", "@" -> { + "z" -> { if (lastNoteString == "z") { - midiDuration += nextDuration + midiDuration += if (nextDuration > 0) nextDuration else 60 nextDuration = 0 } else { pushMidi() - //noteString = } lastNoteString = "z" + lastPhysicalNote = "z" } "'", "(", ")", "{", "}", "," -> {} else -> { pushMidi() lastNoteString = noteString + lastPhysicalNote = noteString } } } } '@' -> { - if(!inSplit) { - if (lastNoteString == "z") { - midiDuration += nextDuration - nextDuration = 0 - } else { - pushMidi() + if (!inSplit) { + if (lastNoteString != "z") { + var isProlongation = false + var k = i + 1 + while (k < lineRepeated.length) { + val nextC = lineRepeated[k] + if (nextC == '-') { + isProlongation = true + break + } + if (nextC in "drmfsltDRFSTzZ|:!/") { + break + } + k++ + } + + if (!isProlongation) { + pushMidi() + lastNoteString = "z" + } else { + + } } - lastNoteString = "z" } } - 'i', 'a' -> + 'i', 'a' -> { lastNoteString += it + if (lastPhysicalNote.isNotEmpty() && lastPhysicalNote != "z") { + lastPhysicalNote += it + } + } '&' -> { commentNumber++ - nextComment.add(templateComments[commentNumber]) - if (templateComments[commentNumber] == "\$T") { - nextTrioletDuration = 2 * nextDuration / 3 - trioletCount = 2 - nextDuration = nextDuration - nextTrioletDuration } + val comment = templateComments.getOrNull(commentNumber) + if (comment != null) { + nextComment.add(comment) + if (comment == "\$T") { + nextTrioletDuration = 2 * nextDuration / 3 + trioletCount = 2 + nextDuration -= nextTrioletDuration + } + } } else -> { expectSplitBrace = false } } + if (it != '~') { + lastSignificantIt = it + } lastIt = it + i++ } pushMidi() /*if (voiceNumber == 1) {