예제 #1
0
    private List <int> GetModifiedMelody(List <int> melody, Interval notes)
    {
        List <int> modifiedMelody      = new List <int>(melody);
        int        numberNotesModified = RandomGenerator.Next(NumberNotesModifiedInMelody.Min, NumberNotesModifiedInMelody.Max);

        for (int i = 0; i < numberNotesModified; i++)
        {
            int        index      = RandomGenerator.Next(0, melody.Count);
            List <int> jointNotes = MusicCreator2.GetJointNotes(modifiedMelody[index], notes.Min, notes.Max);
            modifiedMelody[index] = RandomGenerator.Next(0, jointNotes.Count);
        }
        return(modifiedMelody);
    }
예제 #2
0
    private List <int> GenerateMelody(int beatsPerTab)
    {
        // Create a probability array
        const int             joint = 1; const int withinTierce = 2; const int outsideTierce = 3; const int repeat = 4;
        Dictionary <int, int> cases = new Dictionary <int, int>();

        cases.Add(joint, JointNoteProb);
        cases.Add(withinTierce, NoteWithinTierceProb);
        cases.Add(outsideTierce, NoteOutsideTierceProb);
        cases.Add(repeat, RepeatNoteProb);
        int[] probArray = Probability.CreateProbabilityArray(cases);

        // Creating the melody by adding a first random note
        int        firstNote = RandomGenerator.Next(MelodyNotes.Min, MelodyNotes.Max);
        List <int> melody    = new List <int>();

        melody.Add(firstNote);

        // Add notes to all beats using given probabilities
        for (int i = 1; i < NumberTabMelody * beatsPerTab; i++)
        {
            int choice   = probArray[RandomGenerator.Next(0, 100)];
            int note     = -1;
            int lastNote = melody[i - 1];
            switch (choice)
            {
            case joint:
                List <int> jointNotes = MusicCreator2.GetJointNotes(lastNote, MelodyNotes.Min, MelodyNotes.Max);
                note = jointNotes[RandomGenerator.Next(0, jointNotes.Count)];
                break;

            case withinTierce:
                List <int> withinTierceNotes = MusicCreator2.GetNotesWithinInterval(lastNote, 3, MelodyNotes.Min, MelodyNotes.Max);
                List <int> withinOneNote     = MusicCreator2.GetNotesWithinInterval(lastNote, 1, MelodyNotes.Min, MelodyNotes.Max);
                withinTierceNotes.RemoveAll(n => withinOneNote.Contains(n));
                note = withinTierceNotes[RandomGenerator.Next(0, withinTierceNotes.Count)];
                break;

            case outsideTierce:
                List <int> withinTierceN = MusicCreator2.GetNotesWithinInterval(lastNote, 3, MelodyNotes.Min, MelodyNotes.Max);
                List <int> withinOctave  = MusicCreator2.GetNotesWithinInterval(lastNote, 7, MelodyNotes.Min, MelodyNotes.Max);
                withinOctave.RemoveAll(n => withinTierceN.Contains(n));
                note = withinOctave[RandomGenerator.Next(0, withinOctave.Count)];
                break;

            case repeat:
                note = lastNote;
                break;

            default:
                Debug.LogError("Problem with the choice : " + choice);
                break;
            }
            melody.Add(note);
        }

        // TODO add silences and continue by avoiding making too large silence or too large notes

        // Add some silences randomly by replacing notes
        int numberSilence = RandomGenerator.Next(NumberSilenceInMelody.Min, NumberSilenceInMelody.Max);

        PutNoteRandomlyIn(MusicPlayer.SILENCE, melody, numberSilence);

        // Add some continue randomly by replacing notes
        int numberContinues = RandomGenerator.Next(NumberContinueInMelody.Min, NumberContinueInMelody.Max);

        PutNoteRandomlyIn(MusicPlayer.CONTINUE, melody, numberContinues);

        return(melody);
    }
예제 #3
0
    /// <summary>
    /// Generate a support for the given melody.
    /// Will take the most played note of the melody, and choose this note - 1 * octave chord as base chord.
    /// For each tab of the melody, will choose a different chord, based on the base chord. (see quintes cycles)
    /// https://composer-sa-musique.fr/comment-creer-une-musique-en-5-minutes-le-cycle-des-quintes/
    /// Notes of the chosen chord will be used to make de melody of the support.
    /// </summary>
    /// <param name="beatsPerTab"></param>
    /// <param name="melodyToSupport"></param>
    /// <returns></returns>
    private List <int> GenerateSupport(int beatsPerTab, List <int> melodyToSupport)
    {
        List <int> melodyToSupportCopy = new List <int>(melodyToSupport);

        melodyToSupportCopy.RemoveAll(note => note < 0);
        int                mostPlayedNote = melodyToSupportCopy.GroupBy(note => note).OrderByDescending(x => x.Count()).First().Key;
        int                checkInBounds  = (mostPlayedNote - 7 > SupportNotes.Min) ? mostPlayedNote - 7 : mostPlayedNote;
        List <int>         basedChord     = MusicCreator2.GetChord(checkInBounds, SupportNotes.Max);
        List <List <int> > chordsToUse    = new List <List <int> >();

        chordsToUse.Add(basedChord);
        int lastChord = mostPlayedNote;

        for (int i = 1; i < NumberTabMelody; i++)
        {
            List <int> goodChords     = new List <int>();
            int        minusChord     = lastChord - 4;
            int        plusChord      = lastChord + 4;
            int        minorChordLow  = lastChord - 12;
            int        minorChordHigh = lastChord + 12;
            goodChords.Add(checkInBounds);
            if (minusChord >= SupportNotes.Min)
            {
                goodChords.Add(minusChord);
            }
            if (plusChord + 4 <= SupportNotes.Max)
            {
                goodChords.Add(plusChord);
            }
            if (minorChordLow >= SupportNotes.Min)
            {
                goodChords.Add(minorChordLow);
            }
            if (minorChordHigh + 4 <= SupportNotes.Max)
            {
                goodChords.Add(minorChordHigh);
            }
            int chosenChord = goodChords[RandomGenerator.Next(0, goodChords.Count)];
            Debug.Assert(chosenChord >= SupportNotes.Min && chosenChord <= SupportNotes.Max, "Out of bound note : " + minusChord + ", " + plusChord + ", " + minorChordLow + ", " + minorChordHigh + ", " + SupportNotes.Max + ", ");
            chordsToUse.Add(MusicCreator2.GetChord(chosenChord, SupportNotes.Max));
        }

        // Create the rythm pattern of the support
        List <int> supportRythmPattern = new List <int>();

        for (int i = 0; i < beatsPerTab; i++)
        {
            int randomChordIndex = RandomGenerator.Next(0, 3);
            supportRythmPattern.Add(randomChordIndex);
        }

        // Add some silences randomly by replacing notes
        int numberSilence = RandomGenerator.Next(NumberSilenceInSupportPattern.Min, NumberSilenceInSupportPattern.Max);

        PutNoteRandomlyIn(MusicPlayer.SILENCE, supportRythmPattern, numberSilence);

        // Add some continue randomly by replacing notes
        int numberContinues = RandomGenerator.Next(NumberContinueInSupportPattern.Min, NumberContinueInSupportPattern.Max);

        PutNoteRandomlyIn(MusicPlayer.CONTINUE, supportRythmPattern, numberContinues);

        List <int> supportMelody = new List <int>();

        // Create each tab using the pattern
        for (int i = 0; i < melodyToSupport.Count / beatsPerTab; i++)
        {
            List <int> chordToUse = chordsToUse[i];
            for (int j = 0; j < beatsPerTab; j++)
            {
                if (supportRythmPattern[j] != MusicPlayer.SILENCE && supportRythmPattern[j] != MusicPlayer.CONTINUE)
                {
                    supportMelody.Add(chordToUse[supportRythmPattern[j]]);
                }
                else
                {
                    supportMelody.Add(supportRythmPattern[j]);
                }
            }
        }
        Debug.Assert(supportMelody.Count == melodyToSupport.Count, supportMelody.Count + " but" + melodyToSupport.Count);
        return(supportMelody);
    }