BlottoBeats.Client.Generator.composeMelody C# (CSharp) Method

composeMelody() public method

public composeMelody ( Song thisSection, Random randomizer, String key, int mode, String timeSigPattern, int timeSigQuant ) : void
thisSection BlottoBeats.Library.SongData.Song
randomizer System.Random
key String
mode int
timeSigPattern String
timeSigQuant int
return void
        void composeMelody(Song.SongSegment thisSection, Random randomizer, String key, int mode, String timeSigPattern, int timeSigQuant)
        {
            //TODO check for bad input
            int indexer = thisSection.melodies.Count;
            int chordLength;
            int currentSum = 0;
            String prevNoteVal = "";
            String noteVal = "";
            int noteRhythm = 0;
            String[] notes = { "A", "A#", "B", "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#" };
            String[] keySig = new String[7];
            String[] notearray = new String[14];
            int keynum = Array.IndexOf(notes, key);
            thisSection.melodies.Add(new Song.Melody());

            if (mode == 0)
            {
                keySig[0] = notes[keynum];
                keySig[1] = notes[(keynum + 2) % 12];
                keySig[2] = notes[(keynum + 4) % 12];
                keySig[3] = notes[(keynum + 5) % 12];
                keySig[4] = notes[(keynum + 7) % 12];
                keySig[5] = notes[(keynum + 9) % 12];
                keySig[6] = notes[(keynum + 11) % 12];

            }
            if (mode == 1)
            {
                keySig[0] = notes[keynum];
                keySig[1] = notes[(keynum + 2) % 12];
                keySig[2] = notes[(keynum + 3) % 12];
                keySig[3] = notes[(keynum + 5) % 12];
                keySig[4] = notes[(keynum + 7) % 12];
                keySig[5] = notes[(keynum + 8) % 12];
                keySig[6] = notes[(keynum + 10) % 12];

            }

            int octave = 4;
            String lastNote = "";
            String nextNote = "";
            int thisChord = 0;
            int nextChord = 0;
            for (int i = 0; i < 14; i++)
            {
                nextNote = keySig[i % 7];
                if (!lastNote.Equals("") && !nextNote.Equals("") && lastNote[0] < 'C' && nextNote[0] >= 'C')
                {
                    octave++;
                }
                notearray[i] = nextNote + octave.ToString();
                lastNote = nextNote;
            }
            int totalSectionSum = 0;
            int measureLen = 0;
            if (timeSigPattern.Equals("Simple"))
            {
                measureLen += 4;
            }
            else
                measureLen += 6;
            measureLen *= timeSigQuant;
            for (int i = 0; i < thisSection.chordPattern.Count; i++)
            {
                chordLength = thisSection.chordPattern[i].chordVoice.First().length;
                currentSum = 0;
                while (currentSum < chordLength)
                {

                    //Randomly pick a length within the current measure that doesn't overlap chords
                    int maxVal = Math.Min(measureLen - (totalSectionSum % measureLen), chordLength - currentSum);
                    //If a melody falls onto the last chord of a segment just make the rhythm of note #1 the length of the chord
                    if (i == thisSection.chordPattern.Count - 1)
                    {
                        noteRhythm = chordLength;
                    }
                    else
                    {
                        int[] rhythmWeight = new int[maxVal];
                        for (int j = 0; j < maxVal; j++)
                        {
                            int beatSize = measureLen / timeSigQuant;
                            if (j > beatSize)
                            {
                                rhythmWeight[j] = 4;

                            }
                            else
                            {
                                rhythmWeight[j] = 1;

                            }
                            if (maxVal < beatSize)
                            {
                                rhythmWeight[maxVal - 1] = 10;

                            }
                            if (j + 1 % beatSize == 0)
                            {
                                rhythmWeight[j] *= 4;

                            }
                            if (j + 1 == beatSize)
                            {
                                rhythmWeight[j] *= 4;

                            }

                        }
                        int sumRythWeights = 0;
                        for (int k = 0; k < maxVal; k++)
                        {
                            sumRythWeights += rhythmWeight[k];
                        }

                        int randOutput = randomizer.Next(sumRythWeights);
                        sumRythWeights = 0;
                        for (int k = 0; k < maxVal; k++)
                        {
                            sumRythWeights += rhythmWeight[k];
                            if (randOutput < sumRythWeights)
                            {
                                noteRhythm = k + 1;
                                break;
                            }

                        }
                    }

                    //Define noteValue for each note
                    int[] noteWeights = new int[14];
                    if (prevNoteVal.Equals(""))
                    {
                        for (int j = 0; j < 14; j++)
                        {
                            noteWeights[j] = 1;

                        }

                    }
                    else
                    {
                        int index = Array.IndexOf(notearray, prevNoteVal);
                        int difference = 0;
                        for (int j = 0; j < 14; j++)
                        {
                            difference = index - j;
                            difference = Math.Abs(difference);
                            switch (difference)
                            {
                                case 0:
                                    noteWeights[j] = 16;
                                    break;
                                case 1:
                                    noteWeights[j] = 14;
                                    break;
                                case 2:
                                    noteWeights[j] = 10;
                                    break;
                                case 3:
                                    noteWeights[j] = 3;
                                    break;
                                case 4:
                                    noteWeights[j] = 4;
                                    break;
                                case 5:
                                    noteWeights[j] = 3;
                                    break;
                                case 6:
                                    noteWeights[j] = 2;
                                    break;
                                case 7:
                                    noteWeights[j] = 4;
                                    break;
                                case 8:
                                    noteWeights[j] = 1;
                                    break;
                                case 9:
                                    noteWeights[j] = 2;
                                    break;
                                case 10:
                                    noteWeights[j] = 1;
                                    break;
                                case 11:
                                    noteWeights[j] = 1;
                                    break;
                                case 12:
                                    noteWeights[j] = 1;
                                    break;
                                case 13:
                                    noteWeights[j] = 1;
                                    break;

                            }

                        }

                    }

                    //Defines the current chord and the upcoming chord for usage below
                    thisChord = thisSection.chordPattern[i].chordVal;
                    if (i < thisSection.chordPattern.Count - 1)
                    {
                        nextChord = thisSection.chordPattern[i + 1].chordVal;

                    }
                    else
                    {
                        nextChord = 0;

                    }

                    if (currentSum == 0)
                    {
                        //If first and last note of the chord
                        if (currentSum + noteRhythm == chordLength)
                        {
                            //if chord is last chord weight towards chord
                            if (nextChord == 0)
                            {
                                int indexerForChordVals = thisChord - 1;
                                for (int j = 0; j < 6; j++)
                                {
                                    noteWeights[indexerForChordVals] *= 2;
                                    if (j == 2)
                                        indexerForChordVals += 3;
                                    else
                                        indexerForChordVals += 2;
                                    indexerForChordVals %= 14;
                                }

                            }
                            //Otherwise weight towards notes that lead into the next chord
                            if (nextChord == 1)
                            {
                                noteWeights[1] *= 3;
                                noteWeights[3] *= 3;
                                noteWeights[6] *= 3;
                                noteWeights[8] *= 3;
                                noteWeights[10] *= 3;
                                noteWeights[13] *= 3;
                            }
                            if (nextChord == 2)
                            {
                                noteWeights[0] *= 3;
                                noteWeights[2] *= 3;
                                noteWeights[4] *= 3;
                                noteWeights[7] *= 3;
                                noteWeights[9] *= 3;
                                noteWeights[11] *= 3;
                            }
                            if (nextChord == 3)
                            {
                                noteWeights[1] *= 3;
                                noteWeights[3] *= 3;
                                noteWeights[5] *= 3;
                                noteWeights[8] *= 3;
                                noteWeights[10] *= 3;
                                noteWeights[12] *= 3;
                                noteWeights[0] *= 3;
                                noteWeights[7] *= 3;
                            }
                            if (nextChord == 4)
                            {
                                noteWeights[1] *= 3;
                                noteWeights[2] *= 3;
                                noteWeights[4] *= 3;
                                noteWeights[8] *= 3;
                                noteWeights[9] *= 3;
                                noteWeights[11] *= 3;
                            }
                            if (nextChord == 5)
                            {
                                noteWeights[0] *= 3;
                                noteWeights[3] *= 3;
                                noteWeights[5] *= 3;
                                noteWeights[7] *= 3;
                                noteWeights[10] *= 3;
                                noteWeights[12] *= 3;
                            }
                            if (nextChord == 6)
                            {
                                noteWeights[1] *= 3;
                                noteWeights[3] *= 3;
                                noteWeights[6] *= 3;
                                noteWeights[8] *= 3;
                                noteWeights[10] *= 3;
                                noteWeights[13] *= 3;
                            }
                            if (nextChord == 7)
                            {
                                noteWeights[0] *= 3;
                                noteWeights[2] *= 3;
                                noteWeights[5] *= 3;
                                noteWeights[7] *= 3;
                                noteWeights[9] *= 3;
                                noteWeights[12] *= 3;
                            }

                        }
                        if (thisChord == 1)
                        {
                            noteWeights[0] *= 3;
                            noteWeights[2] *= 2;
                            noteWeights[4] *= 1;
                            noteWeights[7] *= 3;
                            noteWeights[9] *= 2;
                            noteWeights[11] *= 1;
                        }
                        if (thisChord == 2)
                        {
                            noteWeights[1] *= 3;
                            noteWeights[3] *= 1;
                            noteWeights[5] *= 2;
                            noteWeights[8] *= 3;
                            noteWeights[10] *= 1;
                            noteWeights[12] *= 2;
                        }
                        if (thisChord == 3)
                        {
                            noteWeights[2] *= 3;
                            noteWeights[4] *= 2;
                            noteWeights[6] *= 1;
                            noteWeights[9] *= 3;
                            noteWeights[11] *= 2;
                            noteWeights[13] *= 1;
                        }
                        if (thisChord == 4)
                        {
                            noteWeights[3] *= 3;
                            noteWeights[5] *= 1;
                            noteWeights[7] *= 2;
                            noteWeights[10] *= 3;
                            noteWeights[12] *= 1;
                            noteWeights[0] *= 2;
                        }
                        if (thisChord == 5)
                        {
                            noteWeights[4] *= 1;
                            noteWeights[6] *= 2;
                            noteWeights[8] *= 3;
                            noteWeights[11] *= 1;
                            noteWeights[13] *= 2;
                            noteWeights[1] *= 3;
                        }
                        if (thisChord == 6)
                        {
                            noteWeights[5] *= 2;
                            noteWeights[7] *= 1;
                            noteWeights[9] *= 3;
                            noteWeights[12] *= 2;
                            noteWeights[0] *= 1;
                            noteWeights[2] *= 3;
                        }
                        if (thisChord == 7)
                        {
                            noteWeights[6] *= 2;
                            noteWeights[8] *= 3;
                            noteWeights[10] *= 1;
                            noteWeights[13] *= 2;
                            noteWeights[1] *= 3;
                            noteWeights[3] *= 1;
                        }
                        //if the note is not a chord tone, set the weight to be 0
                        for (int j = 0; j < 14; j++)
                        {
                            int thisChordIndex = thisChord - 1;
                            if (j != thisChordIndex && j != thisChordIndex + 2 && j != thisChordIndex + 4 && j != thisChordIndex + 7 && j != (thisChordIndex + 9) % 13 && j != (thisChordIndex + 11) % 13)
                            {
                                noteWeights[j] = 0;
                            }
                        }

                    }
                    else if (currentSum + noteRhythm == chordLength)
                    {

                        //weight towards notes that lead into the next chord
                        if (nextChord == 1)
                        {
                            noteWeights[1] *= 3;
                            noteWeights[3] *= 3;
                            noteWeights[6] *= 3;
                            noteWeights[8] *= 3;
                            noteWeights[10] *= 3;
                            noteWeights[13] *= 3;
                        }
                        if (nextChord == 2)
                        {
                            noteWeights[0] *= 3;
                            noteWeights[2] *= 3;
                            noteWeights[4] *= 3;
                            noteWeights[7] *= 3;
                            noteWeights[9] *= 3;
                            noteWeights[11] *= 3;
                        }
                        if (nextChord == 3)
                        {
                            noteWeights[1] *= 3;
                            noteWeights[3] *= 3;
                            noteWeights[5] *= 3;
                            noteWeights[8] *= 3;
                            noteWeights[10] *= 3;
                            noteWeights[12] *= 3;
                            noteWeights[0] *= 3;
                            noteWeights[7] *= 3;
                        }
                        if (nextChord == 4)
                        {
                            noteWeights[1] *= 3;
                            noteWeights[2] *= 3;
                            noteWeights[4] *= 3;
                            noteWeights[8] *= 3;
                            noteWeights[9] *= 3;
                            noteWeights[11] *= 3;
                        }
                        if (nextChord == 5)
                        {
                            noteWeights[0] *= 3;
                            noteWeights[3] *= 3;
                            noteWeights[5] *= 3;
                            noteWeights[7] *= 3;
                            noteWeights[10] *= 3;
                            noteWeights[12] *= 3;
                        }
                        if (nextChord == 6)
                        {
                            noteWeights[1] *= 3;
                            noteWeights[3] *= 3;
                            noteWeights[6] *= 3;
                            noteWeights[8] *= 3;
                            noteWeights[10] *= 3;
                            noteWeights[13] *= 3;
                        }
                        if (nextChord == 7)
                        {
                            noteWeights[0] *= 3;
                            noteWeights[2] *= 3;
                            noteWeights[5] *= 3;
                            noteWeights[7] *= 3;
                            noteWeights[9] *= 3;
                            noteWeights[12] *= 3;
                        }
                    }
                    //If a note isn't first or last of a chord. Double it's weighting towards chord tones.
                    else
                    {
                        int indexerForChordVals = thisChord - 1;
                        for (int j = 0; j < 6; j++)
                        {
                            noteWeights[indexerForChordVals] *= 2;
                            if (j == 2)
                                indexerForChordVals += 3;
                            else
                                indexerForChordVals += 2;
                            indexerForChordVals %= 14;
                        }

                    }
                    //Selects a note randomly based upon weighting
                    int sumWeights = 0;
                    for (int j = 0; j < 14; j++)
                    {
                        sumWeights += noteWeights[j];
                    }

                    int randOut = randomizer.Next(sumWeights);
                    sumWeights = 0;
                    for (int j = 0; j < 14; j++)
                    {
                        sumWeights += noteWeights[j];
                        if (randOut < sumWeights)
                        {
                            noteVal = notearray[j];
                            break;
                        }

                    }
                    //Raise and lower leading tones in dominant functions of minor modes in melodic lines
                    if (mode == 1)
                    {
                        if (thisChord == 5 || thisChord == 7)
                        {
                            if (noteVal.Equals(notearray[6]) || noteVal.Equals(notearray[13]))
                            {
                                if (noteVal[1] == '#')
                                {
                                    octave = int.Parse(noteVal[2].ToString());
                                    String sub = noteVal.Substring(0, 2);
                                    int index = Array.IndexOf(notes, sub);
                                    noteVal = notes[(index + 1)%12] + octave.ToString();
                                }
                                else
                                {
                                    octave = int.Parse(noteVal[1].ToString());
                                    String sub = noteVal.Substring(0, 1);
                                    int index = Array.IndexOf(notes, sub);
                                    if (sub.Equals("B"))
                                    {
                                        octave++;
                                    }
                                    noteVal = notes[(index + 1) % 12] + octave.ToString();
                                }
                            }
                        }

                    }
                    thisSection.melodies[indexer].melodicLine.Add(new Song.Note(noteVal, noteRhythm));
                    currentSum += noteRhythm;
                    totalSectionSum += noteRhythm;
                    prevNoteVal = noteVal;
                }
            }
        }