Money doesn’t grow on trees, but music does! Musical Trees is an original project for students in a data structures class that covers trees, recursion, and memory management. In the project, students build a general tree where each node holds a musical motif (5 notes). Students then write code to evolve and prune the tree across multiple generations to elaborate and extend the original motif. Finally, students traverse the tree to produce a unique melody.
Musical Trees is an engaging project that allows students to hear the results of their code. It provides an opportunity to include students with musical backgrounds, while requiring no prior musical knowledge. The project is fully autogradable, yet still allows meaningful design freedom. It was tested and loved by a course of 80 students, many of whom extended the project to incorporate their own music theory ideas. Musical Trees combines the challenges of programming with the creativity of music generation.
Musical Trees was the last project of the semester given to students in their second computer science course. They had already learned the basics of C++, pointers, memory management, and linked lists. To prepare them for the project, two lectures were given on trees. The first on general trees, and the other on binary and binary search trees. These lectures included active learning and were followed with short homework assignments.
The students had two weeks for the full project, with part 1 due after week one. The first part involved implementing the MotifNode class, and the MusicalTree constructor, copy constructor, assignment operator, destructor, and the function MusicalTree::PruneNodes(). The second part involved completing the rest of the MusicalTree class to run the full genetic algorithm and produce the final output.
The project’s difficulty is adjustable by changing the amount of starter code. The instructor provided a lot of structure for the MotifNode class to set them up for success for the open ended MusicalTrees class. The instructor provided little to no structure for the MusicalTrees class. For my students, this was a good level of structure and freedom across two weeks.
To make the project more challenging, you could remove the structure and guidance for the MotifNode class. To make it easier and shorter, you could add more structure to the MusicalTrees class by providing the function declarations and descriptions. Another way to make the project easier would be to change the requirements for MusicalTrees::PruneNodes().
As an optional extension, the instructor also gave students the option of adjusting the function that calculates the fitness score for each node. What sounds better or worse, aka which node has a higher or lower fitness score, is subjective! The instructor provided an implementation based on some simple music theory ideas but there is lots of room for students to play and explore.
For a more open-ended and reflective assessment the instructor has included a worksheet, "reflection.pdf." It focuses on the process students followed to create their program and their reflections on its output. The second page of the worksheet asks students to read an article from Carnegie Mellon University, "As AI-Generated Music Advances, Humans Still Lead in Creativity, CMU Research Finds", which accessibly discusses the considerations surrounding AI-generated music. The worksheet then poses three questions about the article, each requiring a progressively deeper level of engagement.
One of the biggest strengths of the Musical Trees project is its interdisciplinary connection to music. The project lets students to listen to the results of their code and encourages creative application of music theory. Making interdisciplinary connections has been shown to help students see computing in varied contexts and connect it to their own interests and experiences, which can increase motivation and persistence in computing courses. This approach engages a population of students who may feel less interested in more traditional CS projects, while still remaining accessible to all learners.
The project provides opportunities to incorporate student choice. The relevant music theory related code is provided in the starter files, but students are encouraged to expand, adjust, and experiment with it to change the final musical outcome. Incorporating student choice is a recommended practice for engaging learners by connecting coursework to their goals and passions.
Additionally, the project introduces ethical and societal implications for students to reflect on. The code they write will produce unique musical melodies, but what role should technology play in music generation? To ensure the project is inclusive, no music theory knowledge is required. Additionally, students do not need to listen to the audio output in order to successfully complete the project. The starter files include support for running the project either with music as the output or with a vector of note pitch and duration values. This inclusive design reflects principles from culturally responsive and sustaining computing education, which emphasize valuing students’ identities, experiences, and cultural assets while removing unnecessary barriers to participation.