rualark / MGen

MGen: Windows PC C++ music generation and analysis laboratory, playing into MIDI port and exporting MIDI
http://arkhipenko.weebly.com
GNU Affero General Public License v3.0
45 stars 11 forks source link

CA3: Make dissonance rules #2303

Closed rualark closed 6 years ago

rualark commented 6 years ago

Sequence:

  1. Detect sus
  2. Detect basic msh (based on downbeats and leaps)
  3. Detect PDD, build msh
  4. Detect sus type and mark needed resolution in msh
  5. Detect cambiata and DNT, build msh
  6. Detect dissonances with msh (also detect if sus resolution is consonant based on msh)
  7. Detect harmony with msh
rualark commented 6 years ago

Goals:

  1. Find which voices start measure with harmonic notes (for each sus and PDD check if they are legitimate)
    • First find notes, which never can be non-harmonic
    • Downbeat long notes
    • Downbeat notes that are not surrounded by stepwise descending movement
    • Suspensions that are not followed by resolution shape (stepwise for LT, stepwise down for other notes)
    • Notes that start or end leaps >3rd (3rd leap can be a cambiata or dnt)
    • Notes that start or end leaps of a 3rd and are not part of cambiata or dnt shape
    • Downbeat notes that are not part of pdd shape
  2. Find melody shapes
  3. Find dissonant intervals
rualark commented 6 years ago

General solution:

rualark commented 6 years ago

When ambivalent notes can occur in penultimate measure:

When ambivalent notes can occur in other measures:

rualark commented 6 years ago

Full approach:

rualark commented 6 years ago

Rules updated from Shegolev:

rualark commented 6 years ago

DETECTION OF HARMONIC NOTE CONFLICT WITH HARMONY

In case of single harmony in measure: While detecting new harmonic notes, add them to cn and ccn vectors. These vectors will be used to find out if melodic shape has discord, that needs to be avoided. If melodic shape has none, it will be marked as ambiguous and will be checked again after checking all other shapes, when more notes will be collected in cn/ccn. This approach requires that note is never marked as harmonic until there is a confirmation.

For penultimate harmony this algorithm cannot work correctly, because notes in measure can belong to two different harmonies and direct notes accumulation will not work. One of approaches here is to decide how to divide measure and collect cn/ccn for each part of measure separately.

Idea: as soon as we detect first note, that cannot be part of current chord in ccn, scan all chord tones in current measure from left to right and rebuild chord ccn.

rualark commented 6 years ago

DETECTION OF DIRECT MOTION TO DISSONANCE:

This does not need harmonic notes detection in other voices, because dissonance is prohibited without regard to if it is a chord tone or not.

rualark commented 6 years ago

Algorithm structure:

rualark commented 6 years ago

When deciding which note should be part of harmony, there is no need to check for direct movement to dissonance, because it is prohibited irrelevant of if note is part of chord or not.

On the other hand, we need to check for 4th and tritones with bass, because being part of chord, they are not yet allowed. So, only checking if note can be a part of chord works only for voices except bass.

rualark commented 6 years ago

Optimization of this complex algorithm. The main problem of the algorithm is that we need to check shapes multiple times. This is not a big performance problem but this a problem with algorithm complexity. This leads to saving each problematic shape to some data structure and then iterating over it.

Another source of complexity of the algorithm is that instead of checking vertical intervals, place in chord should be checked all the time, which is much more difficult, especially considering complex 6/4 chord detection. To check if note can be harmonic, first possible dissonance (chromatic, 2nd or 7th) with chord tone should be checked. If none found, then another check should be run: making this note harmonic should not lead to 6/4 chord. This means that this note should not form 4th with any of harmonic notes in bass.

rualark commented 6 years ago

Вариант оптимизации:

  1. Найти ноты, которые точно являются гармоническими (BasicMsh)
  2. Найти все мелодические фигуры (sus, PDD, DNT, cambiata, anticipation) без учета того, какие вертикальные интервалы или аккорды они образуют. Отметить ноты как относящиеся к одному из вариантов трактовки (есть фигура - нет фигуры). Если фигур в такте несколько, то при маркировке следующей фигуры учитывать текущую маркировку.
  3. Построить аккорд из этих нот.
  4. Для каждого возможного аккорда рассмотреть все ноты фигур и определить, есть ли варианты, при которых все ноты, которые должны быть гармоническими, оказываются частью аккорда.

Таким образом, не нужно сложным образом проверять, может ли каждая нота являться частью аккорда и итерационно проходить все голоса. Алгоритм становится более простым и потенциально более быстрым.

В случае, если в голосе в одном такте больше одной фигуры, возможны следующие ситуации:

Группы нот в фигурах:

Возможные наложения:

При переборе всех возможных гармоний анализируются 7 гармоний, начинающиеся с соответствующей ступени лада. Однако, каждая гармония может существовать в альтерированном и неальтерированном виде. Обнаружение альтерированной и неальтерированной ноты в одном аккорде может обозначать неправильный аккорд. Однако, в начале сканирования тип аккорда может быть не определен, если ни альтерированная, ни неальтерированная нота не присутствует среди обязательных гармонических нот. В этом случае ноты будут добавляться в аккорд динамически, на определенном шаге создавая конфликт друг с другом. Это создает неопределенность. Например, из-за того, что наличие тритона можно будет определить только после альтерации аккорда.

Поэтому предлагается перебирать 13 гармоний (6 альтерированных и 7 неальтерированных - кроме гармонии I, в которой альтерации быть не может). При этом оба варианта, альтерированный и неальтерированный, нужно перебирать только для гармоний кроме I и только в том случае, если в обязательных нотах отсутствует альтерированная и неальтерированная нота - то есть если альтерация аккорда не определена.

При анализе аккорда достаточно сравнить новых кандидатов в аккордовые ноты с хроматическим отпечатком аккорда (cchn) на предмет точного соответствия.

rualark commented 6 years ago

Реализованный сейчас алгоритм имеет следующие недостатки:

  1. Не поддерживает разделения на несколько гармоний в такте, даже если это уже видно до анализа задержаний, PDD, DNT, cambiata, anticipation. В результате определяется неверная гармония для всего или для части такта, что в свою очередь может привести к неправильному выставлению msh. Например, PDD будет ошибочно разрешен: image На самом деле в этом примере можно определить одну гармонию в предпоследнем такте, то это будет квартсекстаккорд, что нежелательно. И поэтому более правильно определить гармонию SII, затем D. Проблема здесь в том, что место, где в такте начинается новая гармония, зависит от того, как трактовать фигурные ноты и какие выбрать предыдущие гармонии в этом такте. С другой стороны, правильных вариантов начала новой гармонии в такте всего два, а иногда и один. Однако, студенты не всегда все пишут в соответствии с правилами контрапункта, а определить гармонию придется без ошибок, даже если результат не будет соответствовать правилам контрапункта.

  2. Останавливается на первой подходящей гармонии с минимальным обращением. Таким образом, неоднозначность квинты-сексты будет разрешаться автоматически без возможности повлиять на выбор.

rualark commented 6 years ago

Ограничение текущего алгоритма, связанное с анализом только одной гармонии на каждый такт, может быть снято путем анализа всех нот, однозначно являющихся аккордовыми, на предмет того, какие гармонии они формируют - до начала анализа неоднозначных нот. В этом случае придется анализировать по нескольку аккордов на такт. Проблем такого подхода несколько:

  1. Разделение гармоний в такте все еще может отличаться от конечного, поскольку оно не учитывает неоднозначные ноты фигур (sus, PDD, DNT, cambiata, anticipation). Однако, оно становится ближе к конечному распределению. Разделить такт сразу однозначно невозможно, либо пришлось бы рассмотреть все возможные варианты разделения такта, которых очень много.
  2. Технически усложняется анализ неоднозначных аккордовых нот.
  3. Замедляется анализ, т.к. вариантов гармоний на такт становится больше.

Такой вариант является лучшим приближением, чем анализ одной гармонии на такт. Интересно, что если продолжать стратегию "анализирую только правильное", то для предпоследнего такта можно рассматривать только два разрешенных разделения на гармонии. Проблемой такого подхода будет то, что невозможно будет корректно проанализировать некоторые аккордовые ноты, что приведет к неправильным аккордам и позициям в результате. Это будет происходить только в случае, если студент нарушил правила, но это не оправдывает такой подход.

В каких случаях разделение такта на гармонии по однозначным нотам приведет к проблемам и каким? image Здесь зеленые ноты будут определены как обязательные гармонические, что приведет к определению единственной гармонии в такте GBD. В то время как красная нота будет определена как гармоническая только позже при анализе задержания. Она не попадет в единственный возможный аккорд GBD, который был определен из обязательных нот. Задержание окажется неразрешенным, что будет отмечено флагом, а красная нота будет отмечена как неаккордовая и не войдет в окончательный анализ гармонии.

Если задержание разрешается мелодически корректно, то оно перестает быть гармонической нотой в любом случае. Однако, если окончание задержания образовано неаккордовой нотой, то разрешение должно быть аккордовой нотой. Если аккордовой - то разрешение не требуется и обязательства гармоничности нот определяются формой мелодии без учета задержания. Это означает, что до тех пор, пока не будет ясно, является ли окончание задержания неаккордовой нотой, нельзя решить, должны ли разрешение и ноты между задержанием и разрешением быть аккордовыми нотами.

Таким образом, попытка определить количество гармоний в такте по обязательным нотам оказывается не точной и приводит к неправильному определению гармонии.

rualark commented 6 years ago

Now let's return to my initial algorithm and check if it is useful. It was:

The question is how obligatory shapes are detected. For example, let's talk about sus. There can be two approaches to sus:

  1. First approach: first check if sus ending is harmonic.
    • If sus ending is harmonic, do not check for resolution if there is no ornament. If there is correct ornament and resolution is harmonic, allow ornament.
    • If sus ending is not harmonic, require resolution to be correct and harmonic.
  2. Second approach: first check resolution
    • If resolution is correct and harmonic, do not require sus ending to be harmonic
    • If resolution is wrong or not harmonic, require sus ending to be harmonic

First approach is currently implemented in CP1 algorithm. It seems to be easier, because checking if resolution is harmonic can be more difficult, as it depends on chords division inside measure.

Obligatory shapes can be detected in the following situations:

All other shapes are voluntary. All combinations of them should be checked. Forming too many chords in measure (more than one or two) is not good, but it is not a reason to avoid note obligatory. Because avoiding two chords here may lead to problems later (probably?).

rualark commented 6 years ago

Новая проблема связана с тем, что задержание может возникнуть не только между тактами, но и между аккордами одного такта. Например так: image

В связи с этим возникает несколько осложнений:

В то же время все эти осложнения возникают только для нот, которые обладают определенными мелодическими характеристиками, что делает возможным их разрешение:

  1. Нота не может быть короче 3/4.
  2. Нота должна разрешаться поступенно вниз или вверх (вводный тон), при этом может быть добавлен орнамент.
  3. Разрешение (начало, середина, окончание) не должно диссонировать с другими аккордовыми нотами (с началом точно. с остальными частями - в зависимости от их возможности быть задержаниями).
  4. Начало ноты не должно образовывать диссонанса с другими нотами.
  5. Нота не может создавать задержание в следующем такте, т.к. в таком случае в данном такте нота должна быть гармонической во всех гармониях, через которые она проходит.

Внутритактовые задержания не оказывают влияния на поиск обязательных гармонических нот.

rualark commented 6 years ago

New algorithm:

rualark commented 6 years ago

There are two possible approaches to finding harmonic notes that do not need rhythm analysis:

The key question to ask before selecting a approach is: "Do we need to know which notes are harmonic before finishing shape analysis?" In the current algorithm, knowing which notes are harmonic is very important during shape analysis, because notes are being compared to harmonic tones to decide if shape is obligatory true or false. This is why second approach should be used.

rualark commented 6 years ago

Current resolution rules ensure that if resolution is found, there can be no other resolution. This is why when resolution is detected, we can always check if it is harmonic. If resolution is not harmonic, then suspension cannot be non-harmonic, which means that it is either a harmonic suspension, or a suspension error.

Now, when we are checking some particular shapes combination, if suspension is nonharmonic and it does not have resolution, it should be marked as a mistake.

rualark commented 6 years ago

Todo:

rualark commented 6 years ago

The note that is checked can form the following intervals with other harmonic notes:

The main goal of variants assessment is to try different interpretations of the same notes. Some notes may be harmonic in one variant and non-harmonic in other. Talking about sus, we have the following notes:

Possible situations with sus:

Effectively, such an approach means that suspension note and resolution note are analysed as two separate shapes. It leads to possibility of non-harmonic sus + non-harmonic resolution variant. This variant is obviously wrong, but it can lead to best harmonic results. For example, when resolution is considered harmonic, harmony can be impossible at some point or it will lead to multiple harmonies in measure.

An alternative approach will be to say "if this sus is resolved to this note, harmony will be very wrong". But this is far from harmonic analysis.

rualark commented 6 years ago

When variants are detected, they should be saved and then scanned. For this each scanned shape should have a unique id. Shape variant data:

Now all combinations of shape variants should be scanned with brute force. To apply a shape variant, notes msh should be changed. Then harmony should be detected. For each combination penalty should be calculated. Major penalty is assigned for excessive harmonies in measure, wrong second harmony position. Minor penalty is assigned for wrong harmony and dissonances (on leap, no resolution...). Combination with minimum penalty wins. It is used to show flags and detect harmony.

rualark commented 6 years ago

Currently msh has ls index, but this does not allow to mark sus, because it starts in the middle of the note. For this, additional vector susres is used. As far as we start to separate sus and sus res shapes, susres is not enough. Currently unresolved sus always means that sus is harmonic, but this is not always the case. Making sus harmonic may lead to wrong harmony detection as soon as sus is not resolved. At least, one harmony variant is missed. This can be excused because student already made a sus mistake, but this makes harmony recognition less precise.

For this reason, msh should be migrated from s to ls, so that there can be multiple msh for sus note.

rualark commented 6 years ago

Currently if sus does not have resolution, it will not be marked or added to variants. It will always be considered harmonic. This is the same situation as with dissonating resolution. In this case if sus is non-harmonic, it can spoil harmony detection. For example if two downbeat harmonic notes are C and A and sus is D. In this case sept chord D will be detected instead of Am chord with unresolved sus.

To cope with this, sus should be checked against other notes if it is definitely non-harmonic and should be always added to variants if there is no decisive interval. This actually leads to separate sus and sus res detection. The only difference between these shapes is that sus res can be detected only when sus exists.

If sus or sus preparation is too short, this should not block sus or sus res detection. Instead, both shapes should be detected. Later after msh algorithm run flag for short preparation or short sus should be fired without affecting the msh detection algorithm.

If there are not enough notes for resolution, this also should not affect detection of sus.

When resolution is marked non-harmonic, while sus is also non-harmonic, this is definitely a mistake and should lead to minor penalty, but this is a feasible solution for harmony detection.

Talking about intrabar suspension, situation is different. All possible isus are detected before any shape is analysed. But they are not added to variants. If isus is unresolved, it is never analysed and is considered harmonic in all chords. If isus is resolved, it is analysed after all other shapes. Actually, only the following combinations of isus are possible:

rualark commented 6 years ago

When detecting interval that is formed by checked note with harmonic notes that are sounding at the same time, detected dissonance has precedence. Only if note does not form dissonance with harmonic notes, then detected octave or unison with harmonic note will lead to "definitely harmonic tone".

rualark commented 6 years ago

The problem with current approach is that when we discard some of variants due to sus or sus resolution forming dissonance with leaping or downbeat notes, this does not mean that these leaping or downbeat notes are definitely harmonic and correct, while sus is wrong. This is why intervals between notes do not mean that some variants should be discarded. If in a melody shape looks legal, it should be checked for all variants. So due to possible student mistakes, correct harmony detection requires that all shape variants are analysed.

If correct harmony detection is not important while generating, other algorithms can be used - from one harmony in measure algorithm - to intervals detection between voices.

Isus can happen even if it starts with non-harmonic tone, but there will be a mistake. Moreover, isus can happen even if it is too short and is not resolved at all (at the end of measure). As far as intervals between voices are not analysed when exact harmony needs to be detected, isus does not need to be detected before other shapes. It was needed when each note required isus property to know if only note start can be checked for harmonic intervals.

rualark commented 6 years ago

To sum it up, currently I have ideas of the following algorithms:

rualark commented 6 years ago

As harmony is not needed in case of harmonic note mistake, I stop developing algorithm 2 at this commit: https://github.com/rualark/MGen/commit/095895d4afb7b98f58aee1f4b90818b3de93abc6

Here is the last commit with algorithm 1 implementation: https://github.com/rualark/MGen/commit/bc02af67de702750ee3a0b2300657bb40534a40b

rualark commented 6 years ago

TODO:

rualark commented 6 years ago

Solutions:

Separate algorithm for penultimate measure:

Scanning separate parts is impossible because in different parts shape must be in the same state. Alternative solution to this is to scan harmony combination. In worst case, when only one definitely harmonic note exists in both parts, there will be 9 combinations. A problem with this approach: cchnv should be separate for each step or there should be two cchnv vectors, while there should be mapping vector from step to part.

This approach looks bulky, but there seems to be no other way to check multiple harmonies in one measure.

Problems with sus:

To make minimum changes to sus and pdd detection functions, they can act inside part of measure, not inside measure. Because both pdd and sus have to be enclosed in measure part. As for dnt and cambiata, they can go through parts, but have to be enclosed in a measure.

rualark commented 6 years ago

Approaches to implementation of 2 harmonies per measure scan:

rualark commented 6 years ago

Новая проблема связана с тем, что алгоритм не различает квартсекстаккорд при сканировании вариантов аккордов. Кроме этого, при оценке PDD не анализируются консонансы, образованные с другими аккордовыми звуками. В результате выбираются не оптимальные аккорды: image

Возможные решения:

  1. При сканировании квартсекстаккорда добавлять штраф. Такой подход требует переключения на сохранение штрафа для каждой комбинации и выбор лучшего варианта из отсканированных. Подход довольно гибкий, но требует дополнительных структур хранения данных и приведет к снижению производительности.
  2. Сканировать варианты в другом порядке. Такой подход быстрее и не снижает производительность, но теоретически имеет ограничения по возможности масштабирования.

1 1 1 2 2 1 2 2 3 1 3 2 3 3 1 3 2 3 3 3

rualark commented 6 years ago

Implemented