Instructions for recursiveScales

(produced at 00:54 a.m. UTC on 2024-11-13)

This task is part of project10 which is due at 23:00 EST on 2024-11-19.

You have the option to work with a partner on this task if you wish. Working with a partner requires more work to coordinate schedules, but if you work together and make sure that you are both understanding the code you write, you will make progress faster and learn more.

You can download the starter code for this task using this link.

You can submit this task using this link.

Put all of your work for this task into the file recursiveScales.py
(you will create this file from scratch)

This task and the recursiveCircles task are very similar. This task is based on audio using the wavesynth library, while the recursive circles task is based on turtle graphics instead. You may choose to do either task, but you do not need to do both.

In this task, you will create a file named recursiveScales.py and write functions scale, unevenScale, and rungsListMelody within it, the first two of which which are similar to the functions with the same names from the earlier "scales" task. However, for this task, you are not allowed to use any loops, and must use recursion instead.

If you didn't do the scale task before, you should review that material before starting this task, and you may need to familiarize yourself with the wavesynth library. It may be easier to do the recursiveCircles task instead of this one in that case.

Part A: scale

This function works like the scale function from the earlier task of the same name, and takes equivalent parameters:

  • scaleDuration determines the duration of the entire scale.
  • notesUp determines the number of notes in the scale.

It should behave exactly like scale from the earlier task: it must add a number of notes to the current track, each one step above the last. climbUp must be used to increase the pitch. The number of notes added is determined by the second parameter, and the duration of each note is the same, so the total scale duration is split evenly between the notes. For example, if there are 4 notes and the total duration is 1 second, each note will be 1/4 second long.

Whereas in the previous task this problem was solved using a loop, in this task, you may not use any loops and you must use recursion. As an extra goal, you should only include a single call to addNote and you should only include a single recursive call.

Hint: Each recursive function call frame needs to add just one note.

These scale examples demonstrate what it should print and what the results should sound like.

Part B: unevenScale

This function works exactly like unevenScale from the non-recursive scale task, taking equivalent parameters:

  • notesUp determines the number of notes in the scale.
  • startLength determines the length of the first note in the scale, and every odd-numbered note after that.
  • otherLength determines the length of the even-numbered notes in the scale (every other note starting from the second one).

As before, notes are added stepping up one step at a time using climbUp, but now every other note has a different duration.

Just like in the previous function, you may not use any loops and you must use recursion. Also as above, as extra goals, you should use addNote in only one place, and you should also only include a single recursive call.

These unevenScale examples demonstrate what the printed output and audio should be.

Part C: rungsListMelody

This function is a new function: given a total duration and a list of rung values, it must add notes to the current track which follow the pattern of climbing up and/or down that is provided. Specifically, it will add one note at the current pitch, even if the rungs list is empty. If the rungs list is not empty, it will contain positive and negative integers, and subsequent notes should be added climbing up or down that many rungs in pitch. Note that it must use the climbUp function, which can accept an argument to specify how many steps to take, and negative values will cause it to climb down, so you can simply pass the numbers from the rungs list directly to the climbUp function. As a concrete example, if the rungs list is [3, -2, 1] then the notes added would be:

  • One note at the starting pitch.
  • One note 3 rungs above the starting pitch.
  • One note one rung above the starting pitch (i.e., two rungs below the pitch of the note before).
  • One note two rungs above the starting pitch (i.e., one rung above the previous note).

Just like turtle keeps track of the current drawing position, wavesynth keeps track of the "current pitch" which is what climbUp changes and what addNote uses to determine the pitch of the note it creates.

As with the other functions in this task, you may not use loops and you must use recursion. Also as before, as extra goals, you should call addNote in only one place and you should include only one recursive call.

Hint: The total number of notes in the melody is always one more than the number of intervals in the rungs list, because the rungs represent pitch changes in between notes.

These rungsListMelody examples demonstrate what the printed output and audio should be.

Notes

Examples

scale examples

These examples demonstrate what the printed output and audio results of the scale function should be. Note that you must call saveTrack and then open the specified file with an audio player to hear the notes added, and if you call multiple functions that add notes without calling eraseTrack in between, the notes will all pile into the same track. You can also call playTrack to have Python play the sound directly, but you will need to use the package manager to install the simpleaudio package for that to work. Note that each example below uses setPitch before calling scale, since scale starts from whatever the current pitch happens to be.

In []:
setPitch(C4) scale(2, 8) printTrack()
Prints
a 0.25s keyboard note at C4 (60% vol) and a 0.25s keyboard note at D4 (60% vol) and a 0.25s keyboard note at E4 (60% vol) and a 0.25s keyboard note at F4 (60% vol) and a 0.25s keyboard note at G4 (60% vol) and a 0.25s keyboard note at A4 (60% vol) and a 0.25s keyboard note at B4 (60% vol) and a 0.25s keyboard note at C5 (60% vol)
Audio In []:
setPitch(C4) scale(1.2, 5) printTrack()
Prints
a 0.24s keyboard note at C4 (60% vol) and a 0.24s keyboard note at D4 (60% vol) and a 0.24s keyboard note at E4 (60% vol) and a 0.24s keyboard note at F4 (60% vol) and a 0.24s keyboard note at G4 (60% vol)
Audio In []:
setPitch(A3) scale(1.6, 4) printTrack()
Prints
a 0.4s keyboard note at A3 (60% vol) and a 0.4s keyboard note at B3 (60% vol) and a 0.4s keyboard note at C4 (60% vol) and a 0.4s keyboard note at D4 (60% vol)
Audio