private void CheckClosingFormula(VoiceLine cantusFirmus, VoiceLine voiceLine, CounterpointSpecie specie)
        {
            List <List <int> > allowedClosingFormulas = AllowedClosingFormula(cantusFirmus, voiceLine, specie);

            foreach (var allowedClosingFormula in allowedClosingFormulas)
            {
                int i = cantusFirmus.NotesUngrouped.Count - 2;
                int k = allowedClosingFormula.Count - 1;

                while (k >= 0 && i >= 0)
                {
                    if (cantusFirmus.HorizontalIntervals[i] == Math.Abs(allowedClosingFormula[k]))
                    {
                        k--;
                        i--;
                    }
                    else
                    {
                        return;
                    }
                }
                if (k > 0)
                {
                    CounterpointCommentsLog.Add("Invalid closing formula. Proper closing formula consists of:");
                    string proper = "";
                    foreach (var a in allowedClosingFormula)
                    {
                        proper += GetNamedInterval(a) + ", ";
                    }
                    proper  = proper.Substring(0, proper.Length - 2);
                    proper += ".";
                }
            }
        }
 /// <summary>
 /// checks for skips larger/smaller than given interval.
 /// </summary>
 /// <param name="cantusFirmus">cantusFirmus</param>
 /// <param name="voiceLine">voiceLine</param>
 /// <param name="specie">specie</param>
 /// <param name="interval">checked interval</param>
 /// <param name="skipDirection">pass 1 for upward motion, -1 for downward</param>
 /// <param name="NoteDistance">distane between 2 checked notes</param>
 /// <param name="inequalityType">pass -1 for smaller than relation, 1 for larger than relation</param>
 private void CheckSkipInequality(VoiceLine voiceLine, CounterpointSpecie specie,
                                  int interval, int skipDirection, int NoteDistance, int inequalityType)
 {
     for (int i = 0; Math.Max(i, i + NoteDistance) < voiceLine.NotesUngrouped.Count; i++)
     {
         if (inequalityType * skipDirection * (voiceLine.NotesUngrouped[i].NoteNumber - voiceLine.NotesUngrouped[i + NoteDistance].NoteNumber)
             > inequalityType * interval)
         {
             CounterpointCommentsLog.Add("Forbidden interval ("
                                         + GetNamedInterval(interval)
                                         + ") between notes "
                                         + i.ToString() + ", " + (i + NoteDistance).ToString());
         }
     }
 }
        private void CheckForNotesOutOfMode(VoiceLine cantusFirmus, VoiceLine voiceLine, CounterpointSpecie specie)
        {
            int i = 1;

            foreach (var interval in cantusFirmus.VerticalIntervals[voiceLine.VoiceId])
            {
                int index = Scale.BinarySearch(interval);

                if (index >= 0 && Scale[index] != interval)
                {
                    CounterpointCommentsLog.Add("Note " + (i).ToString() + " is out of selected scale");
                }

                i++;
            }
        }
 /// <summary>
 /// Function checking voice line for given interval skip
 /// </summary>
 /// <param name="cantusFirmus">cantusFirmus</param>
 /// <param name="voiceLine">voiceLine</param>
 /// <param name="specie">specie</param>
 /// <param name="skip">checked interval</param>
 /// <param name="skipDirection">pass 1 for upward motion, -1 for downward</param>
 /// <param name="NoteDistance">distane between 2 checked notes</param>
 private void CheckSkip(VoiceLine voiceLine, CounterpointSpecie specie,
                        int interval, int skipDirection, int NoteDistance, string optionalErrorComment = "")
 {
     for (int i = 0; Math.Max(i, i + NoteDistance) < voiceLine.NotesUngrouped.Count; i++)
     {
         if (skipDirection * (voiceLine.NotesUngrouped[i].NoteNumber - voiceLine.NotesUngrouped[i + NoteDistance].NoteNumber)
             == interval)
         {
             CounterpointCommentsLog.Add("Forbidden interval in voice " + (voiceLine.VoiceId + 1).ToString() + " ("
                                         + GetNamedInterval(interval)
                                         + ") between notes "
                                         + (i + 1).ToString() + " (" + voiceLine.NotesUngrouped[i].ToString() + "), "
                                         + (i + 1 + NoteDistance).ToString()
                                         + " (" + voiceLine.NotesUngrouped[i + NoteDistance].ToString() + ")"
                                         + optionalErrorComment);
         }
     }
 }
 private void CheckPerfectConsonanceEntrance(VoiceLine cantusFirmus, VoiceLine voiceLine, CounterpointSpecie specie)
 {
     for (int i = 0; i > 0 && i + 1 < cantusFirmus.NotesUngrouped.Count; i++)
     {
         var interval = cantusFirmus.VerticalIntervals[voiceLine.VoiceId][i];
         if (interval == 0 || interval == 7 || interval == 12)
         {
             if (cantusFirmus.HorizontalIntervals[i - 1] * voiceLine.HorizontalIntervals[i - 1] <= 0)
             {
             }
             else
             {
                 CounterpointCommentsLog.Add("You entered a perfect consonance (a " + GetNamedInterval(interval)
                                             + ") by means of direct motion at note " + (i + 1) + ".");
             }
         }
     }
 }
        private void CheckForStepsInSameDirection(VoiceLine voiceLine, CounterpointSpecie specie, int numberOfSkips)
        {
            int currentNumberOfSteps = 1;

            for (int i = 0; (i + 1) < voiceLine.NotesUngrouped.Count - 1; i++)
            {
                if (voiceLine.HorizontalIntervals[i] * voiceLine.HorizontalIntervals[i + 1] > 0)
                {
                    currentNumberOfSteps++;
                    if (currentNumberOfSteps >= numberOfSkips)
                    {
                        CounterpointCommentsLog.Add("Warning: " + currentNumberOfSteps + " steps in the same direction starting at note "
                                                    + i.ToString() + ".");
                    }
                }
                else
                {
                    currentNumberOfSteps = 1;
                }
            }
        }
        private void CheckCounterpointMode(VoiceLine cantusFirmus, VoiceLine voiceLine, CounterpointSpecie specie)
        {
            //checking for higher voice line

            //c.f. is the higher voice
            if (cantusFirmus.VerticalIntervals[voiceLine.VoiceId].Any(x => x < 0))
            {
                if (cantusFirmus.VerticalIntervals[voiceLine.VoiceId][0] == 12 ||
                    cantusFirmus.VerticalIntervals[voiceLine.VoiceId][0] == 0)
                {
                }
                else
                {
                    CounterpointCommentsLog
                    .Add("Mode has been changed- first interval should be octave or unison.");
                }
            }
            //c.f. is the lower voice
            else
            {
                if (cantusFirmus.VerticalIntervals[voiceLine.VoiceId].Count > 0)
                {
                    if (cantusFirmus.VerticalIntervals[voiceLine.VoiceId][0] % 13 == 12 ||
                        cantusFirmus.VerticalIntervals[voiceLine.VoiceId][0] % 13 == 0 ||
                        cantusFirmus.VerticalIntervals[voiceLine.VoiceId][0] % 13 == 7)
                    {
                    }
                    else
                    {
                        CounterpointCommentsLog
                        .Add("Mode has been changed- first interval should be octave, fifth or unison."
                             + "Current interval: " + cantusFirmus.VerticalIntervals[voiceLine.VoiceId][0].ToString());
                    }
                }
            }
        }
        private void RunCounterpointAnalysis(Piece piece, CounterpointSpecie specie)
        {
            //na razie zakladamy ze wszystko to 3 specie xddd
            var cantusFirmus = piece.VoiceLines[CantusFirmusId];

            for (int i = 0; i < piece.VoiceLines.Count && piece.VoiceLines[i].VoiceId != cantusFirmus.VoiceId; i++)
            {
                VoiceLine voiceLine = piece.VoiceLines[i];
                CheckExposedTritones(voiceLine, specie);
                // CheckExposedFifths(voiceLine, specie);

                //check forbidden skips:
                // aug fourth, seventh, octave+, descending minor sixths, major sixths.

                //aug fourth
                CheckSkip(voiceLine, specie, 6, 1, 1);
                CheckSkip(voiceLine, specie, 6, -1, 1);

                // seventh
                CheckSkip(voiceLine, specie, 10, 1, 1);
                CheckSkip(voiceLine, specie, 10, -1, 1);

                CheckSkip(voiceLine, specie, 11, 1, 1);
                CheckSkip(voiceLine, specie, 11, -1, 1);

                //sixth
                CheckSkip(voiceLine, specie, 9, 1, 1);
                CheckSkip(voiceLine, specie, 9, -1, 1);
                CheckSkip(voiceLine, specie, 8, -1, 1);

                //Leaps bigger than octave
                CheckSkipInequality(voiceLine, specie, 12, 1, 1, 1);
                CheckSkipInequality(voiceLine, specie, 12, -1, 1, 1);

                //check for repeated notes
                CheckSkip(voiceLine, specie, 0, 1, 1, ". Repeated notes are not strictly forbidden, but should be avoided.");

                //Tcheck for 2+ skips in the same direction
                CheckForStepsInSameDirection(voiceLine, specie, 3);

                CheckCounterpointMode(cantusFirmus, voiceLine, specie);

                CheckForNotesOutOfMode(cantusFirmus, voiceLine, specie);

                //check closing formula
                //allowed for upper cf:3m-5-4-3m-1
                //allowed for upper cf:5-3m-1
                //allowed for lower cf:8-7-5-6w-8
                //allowed for lower cf:3-4-5-6w-8
                CheckClosingFormula(cantusFirmus, voiceLine, specie);

                // check perfect consonance(unison, fifth, octave) entrance
                CheckPerfectConsonanceEntrance(cantusFirmus, voiceLine, specie);

                //TODO check dissonnance (allowed in 2+ species)
                CheckForDissonnance(cantusFirmus, voiceLine, specie);

                //CheckForNotesOutOfMode(cantusFirmus,voiceLine,specie);

                //TODO check for parallel fifths/octaves

                //TODO check for cambiata
            }
        }
        private List <List <int> > AllowedClosingFormula(VoiceLine cantusFirmus, VoiceLine voiceLine, CounterpointSpecie specie)
        {
            bool CantusFirmusIsHigherVoice = false;

            if (cantusFirmus.VerticalIntervals[voiceLine.VoiceId].Any(x => x < 0))
            {
                CantusFirmusIsHigherVoice = true;
            }
            else
            {
                CantusFirmusIsHigherVoice = false;
            }

            if (CantusFirmusIsHigherVoice)
            {
                switch ((int)specie)
                {
                case 1:
                    return(new List <List <int> > {
                        new List <int> {
                            3, 0
                        }
                    });

                case 2:
                    return(new List <List <int> > {
                        new List <int> {
                            7, 3, 0
                        }
                    });

                case 3:
                    return(new List <List <int> > {
                        new List <int> {
                            3, 7, 5, 3, 0
                        }
                    });

                case 4:
                    return(new List <List <int> > {
                        new List <int> {
                            2, 3, 0
                        }
                    });

                case 5:
                    return(new List <List <int> > {
                        new List <int> {
                            2, 3, 0
                        }
                    });

                default:
                    return(null);
                }
            }
            else
            {
                switch ((int)specie)
                {
                case 1:
                    return(new List <List <int> > {
                        new List <int> {
                            9, 12
                        }
                    });

                case 2:
                    return(new List <List <int> > {
                        new List <int> {
                            7, 9, 12
                        }
                    });

                case 3:
                    return(new List <List <int> > {
                        new List <int> {
                            3, 5, 7, 9, 12
                        }, new List <int> {
                            12, 10, 7, 9, 12
                        }
                    });

                case 4:
                    return(new List <List <int> > {
                        new List <int> {
                            2, 3, 0
                        }
                    });

                case 5:
                    return(new List <List <int> > {
                        new List <int> {
                            2, 3, 0
                        }
                    });

                default:
                    return(null);
                }
            }
        }
 private void CheckExposedFifths(VoiceLine cantusFirmus, CounterpointSpecie specie)
 {
     CheckSkip(cantusFirmus, specie, 7, 1, 2, " (Exposed fifth)");
     CheckSkip(cantusFirmus, specie, 7, -1, 2, " (Exposed fifth)");
 }
 private void CheckExposedTritones(VoiceLine cantusFirmus, CounterpointSpecie specie)
 {
     CheckSkip(cantusFirmus, specie, 6, 1, 2, " (Exposed tritone)");
     CheckSkip(cantusFirmus, specie, 6, -1, 2, " (Exposed tritone)");
 }
        private void CheckForDissonnance(VoiceLine cantusFirmus, VoiceLine voiceLine, CounterpointSpecie specie)
        {
            var intervals = cantusFirmus.VerticalIntervals[voiceLine.VoiceId];

            for (int i = 0; i < intervals.Count - 1; i++)
            {
                var interval  = intervals[i];
                var firstNote = cantusFirmus.NotesUngrouped[0];

                var intervalFromFirstNote = (GetIntervalInSemitones(firstNote, voiceLine.NotesUngrouped[i]));

                if (intervalFromFirstNote % 12 == 0)
                {
                    continue;
                }

                if (Scale.Contains(intervalFromFirstNote % 12))
                {
                    int noteIndex = Scale.IndexOf(intervalFromFirstNote % 12);
                    if (!IsConsonance(interval))
                    {
                        //Druga czesc koniunkcji to sprawdzenie czy i to przejsciowy dzwiek w skali
                        if ((IsConsonance(intervals[i - 1]) && IsConsonance(intervals[i + 1])) &&
                            (Math.Abs(voiceLine.NotesUngrouped[i - 1].NoteNumber - firstNote.NoteNumber) % 12
                             == Scale[(noteIndex - 1) > 0? (noteIndex - 1) % 7: 0] &&
                             Math.Abs(voiceLine.NotesUngrouped[i + 1].NoteNumber - firstNote.NoteNumber) % 12
                             == Scale[(noteIndex + 1) % 7]) ||
                            (Math.Abs(voiceLine.NotesUngrouped[i - 1].NoteNumber - firstNote.NoteNumber) % 12
                             == Scale[(noteIndex + 1) % 7] &&
                             Math.Abs(voiceLine.NotesUngrouped[i + 1].NoteNumber - firstNote.NoteNumber) % 12
                             == Scale[(noteIndex - 1) > 0 ? (noteIndex - 1) % 7 : 0]))
                        {
                        }
                        else
                        {   //Cambiata
                            if (specie == CounterpointSpecie.Third || specie == CounterpointSpecie.Fifth)
                            {
                                if (i - 1 > 0 && i + 2 < intervals.Count)
                                {
                                    if (cantusFirmus.VoiceId > voiceLine.VoiceId)
                                    {
                                        if (intervals[i - 1] % 12 == 12 && (intervals[i] == 11 || intervals[i] == 10) &&
                                            intervals[i + 1] == 7 && (intervals[i + 2] == 8 || intervals[i + 2] == 9))
                                        {
                                        }
                                    }
                                    else
                                    {
                                        if (intervals[i - 1] == 12 && (intervals[i] == 11 || intervals[i] == 10) &&
                                            intervals[i + 1] == 7 && (intervals[i + 2] == 12 || intervals[i + 2] == 11))
                                        {
                                        }
                                    }
                                }
                            }
                            CounterpointCommentsLog.Add("Improperly resolved disonance at note " + (i + 1).ToString() + ".");
                        }
                    }
                }
                else
                {
                    CounterpointCommentsLog.Add("Note " + (i + 1).ToString() + " is out of mode!");
                }
            }
        }
예제 #13
0
        private void SetVerticalIntervals(VoiceLine firstVoice, VoiceLine secondVoice, int voiceNumber)
        {
            long currentPositionInBar1 = 0;
            long currentPositionInBar2 = 0;

            firstVoice.VerticalIntervals.Add(new List <int>());

            TextFileLog log = new TextFileLog();


            for (int i = 0; i < firstVoice.Bars.Count; i++)
            {
                if (i < secondVoice.Bars.Count)
                {
                    int j = 0; // iterates over fist voices notes
                    int k = 0; // itarates over second voices notes

                    //variables keeping record of last value of j and k
                    int lastJ = -1;
                    int lastK = -1;


                    while (j < firstVoice[i].notes.Count && k < secondVoice[i].notes.Count)
                    {
                        firstVoice.VerticalIntervals[voiceNumber]
                        .Add(CounterpointAnalysis.GetIntervalInSemitones(firstVoice[i][j], secondVoice[i][k]));



                        if (lastJ != j)
                        {
                            var a = firstVoice[i][j].LengthAs <MusicalTimeSpan>(tempoMap);
                            currentPositionInBar1 += a.Numerator % 2 == 0 ? a.Numerator : a.Numerator + 1;
                        }
                        if (lastK != k)
                        {
                            var b = secondVoice[i][k].LengthAs <MusicalTimeSpan>(tempoMap);
                            currentPositionInBar2 += b.Numerator % 2 == 0 ? b.Numerator : b.Numerator + 1;
                        }

                        lastJ = j;
                        lastK = k;

                        if (currentPositionInBar1 < currentPositionInBar2)
                        {
                            j++;
                        }
                        else if (currentPositionInBar1 > currentPositionInBar2)

                        {
                            k++;
                        }
                        else
                        {
                            k++;
                            j++;
                        }
                    }
                }
            }
        }