CMPM-147-01
    Assignment 5: Music with Markov Chains
    Skip To Content
    Dashboard
    • Login
    • Dashboard
    • Calendar
    • Inbox
    • Help
    Close
    • My Dashboard
    • CMPM-147-01
    • Assignments
    • Assignment 5: Music with Markov Chains
    2019 Summer Quarter
    • Home
    • Assignments
    • Files
    • Syllabus
    • Quizzes
    • Collaborations
    • Google Drive
    • Zoom
    • Student Experience of Teaching

    Assignment 5: Music with Markov Chains

    • Due Aug 3, 2019 by 11:59pm
    • Points 10
    • Submitting a file upload
    • Available Jul 27, 2019 at 12am - Aug 10, 2019 at 11:59pm 15 days
    This assignment was locked Aug 10, 2019 at 11:59pm.

    Objectives

    Learn how to generate polyphonic music with Markov Chains.

    Description

    Jul-27-2019 17-55-36.gif

    A Markov Chain is a statistical model of a system that changes stochastically from one state to another. It can be applied to generate random sequences  that follow a probability distribution learned from a dataset. In this assignment, you will use a Markov Chain to generate polyphonic music.

    For this assignment, you will use a base code to load and parse MIDI files to create your own dataset. To load a list of midi files using this base code, you have to create a .json file that defines a list of MIDI filepaths as follows:

    data/midi_files.json:
    {"file0": "data/midis/Super_Mario_Bros_Underworld.mid",
    "file1": "data/midis/Super_Mario_Bros_MainTheme.mid",
    "file2": "data/midis/Super_Mario_Bros_Underwater.mid"}

    The base code provides a python script that can generate this list given a directory with MIDI files in it:

    python3 midiPlayer/py/load_midi.py --dat data/midis/ --out data/midi_files.json 

    Once your create your .json file, you can load all the MIDI files describe inside it using the following code:

    let midiPlayer = new MidiPlayer();
    midiPlayer.loadMidis("data/midi_files.json", onMIDIsLoaded);

    Where the first argument is the path of your .json file and the second is a callback function that is called when all the MIDI files have been loaded. This function passes the list of MIDI files as piano rolls as argument so you can parse them, for example:

    function onMIDIsLoaded(pianoRolls) {
    let pianoRoll = pianoRolls[0];
    let midiText = midiPlayer.pianoRoll2Text(pianoRoll);
    }

    In this example, "midiText" contains a string representation of the first MIDI file in your .json file. In this assignment, a MIDI file is encoded as a string where each time step of MIDI's piano roll is separated by the character "." and every note is represented by a symbol of the form [pitch]_[duration], where pitch is a integer from 0 to 127 and duration can be any integer. In this encoding scheme, space is a separator of symbols. For example, consider the piano roll below:

    Screen Shot 2019-07-27 at 5.12.16 PM.png

    The first 20 time steps of this piano roll are encoded by the following string:

    62_4 . . . . . 61_4 64_4 . . . . . 60_4 66_4 . . . . . 59_4 67_4 . . . . .

    The provided base code can also be used to play and visualize your generated music pieces as shown in the example above.  Once you have a generated piece as a string  you can play and visualize it as follows:

    let midi = midiPlayer.text2Midi(midiText);

    let midiData = midiPlayer.parseMidi(midi);
    let pianoRoll = midiPlayer.notes2PianoRoll(midiData.duration, midiData.notes);

    midiPlayer.setPianoRoll(pianoRoll, tsCallback);

    To accomplish this assignment:

    1. Clone the base code  from your class GitHub.
    2. Download from the internet a large number (e.g. 500) of MIDI files of piano music from the same music style (e.g. classical music, jazz,  video game soundtracks, etc).
    3. Create a .json file with all these download MIDIs using the load_midi.py script.
    4. Load (in sketch.js) all these files and parse them as strings.
    5. Implement (in "markov.js") a Markov Chain class which supports training a markov chain on a given dataset and sampling from it to generate new pieces on the style of the dataset.
    6. Use (in "sketch.js")  your Markov Chain to generate a new piece every time one reloads your sketch.  User should be able to play this piece and visualized it as a piano roll on the canvas.
    7. Using your Markov Chain class, generate 5 different pieces using different amounts of data (e.g. 100, 200, 300, 400, 500). 

    Resources

    • Classical Piano MIDI files
    • The MAESTRO dataset
    • Video Game Music MIDI

    Submission

    Host your source code on Github and upload the following on Canvas:

    1. A zip file with the final version of your code.
    2. A zip file with the 5 different music pieces generated using different amounts of data.
    3. A link (as a comment to your submission) to this assignment's github page. This page should have examples (.png or .gif) of outputs of your Markov Chain with a brief explanation (1 paragraph) of  how this Markov Chain generates music.
    1564901999 08/03/2019 11:59pm
    Additional Comments:
    Rating max score to > pts

    Rubric

     
     
     
     
     
     
     
         
    Can't change a rubric once you've started using it.  
    Find a Rubric
    Find Rubric
    Title
    You've already rated students with this rubric. Any major changes could affect their assessment results.
    Title
    Criteria Ratings Pts
    Edit criterion description Delete criterion row
    This criterion is linked to a Learning Outcome Description of criterion
    threshold: 5 pts
    Edit rating Delete rating
    5 to >0 pts
    Full Marks
    blank
    Edit rating Delete rating
    0 to >0 pts
    No Marks
    blank_2
    This area will be used by the assessor to leave comments related to this criterion.
    pts
      / 5 pts
    --
    Additional Comments
    Total Points: 5 out of 5