This task is part of project06 which is due at 23:00 EDT on 2024-10-22.
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
scales.py
(you will create this file from scratch)
This project is very similar the circles task which uses
turtle
to generate images instead of wavesynth
to generate audio. You
only have to do one of the two (but you must do audioToolkit
).
For this task, you will use for
loops with the wavesynth.py
library
to create musical scales: sequences of notes with ascending pitches.
For this task, you will only need the
addNote
,
halfStepUp
,
and climbUp
functions from wavesynth
.
For testing, you will also need to use at least one of
printTrack
,
saveTrack
, and/or
playTrack
, although we've supplied
testing code for you. To use playTrack
, you will have to install the
simpleaudio
module (in the Thonny "Tools" menu select "Manage Packages"
and then search for simpleaudio
and click "Install.")
If you are on Windows and you're unable to install simpleaudio
, see the
audioToolkit task instructions which include one
possible fix. But note that simpleaudio
is not required: you can always
just open saved .wav files manually to hear what is being produced.
For this task, you will create a new Python file named scales.py
.
Your file should begin with this header, which you should fill out (note
that as usual you must document each function you
create):
"""
Authors:
Consulted:
Date:
Purpose: scales task: create runs of ascending notes.
"""
You will needs to import wavesynth
by putting the following line at the
beginning of your code:
from wavesynth import *
You will use functions from wavesynth.py
to modify pitch values in
order to construct sequences of notes with rising pitches. There are four
parts to this task:
In Part A you will create a variable-length scale that uses
climbUp
.
In Part B you will create a variable-length scale using
climbUp
in which every other note is half as long as the others.
In Part C you will create a variable-length arpeggio, in which there are a different number of half-steps between subsequent notes, specified using a list of integers.
In Part D you will create your own custom pattern of notes by using one of the previous functions inside of a loop.
In this task, you will create multiple functions, and you should test
each of them. We've included a test_scales.py
testing file that you can
run to test your functions (it will skip functions you haven't defined
yet). We've also created a play_scales.py
file that you can use to play
your scales to hear them; in that file you should comment in additional
tests as you go.
scale
The scale
function accepts two
parameters: the first controls the total duration of the scale, and the
second controls the number of notes in the scale. It must add an
ascending sequence of notes to the current
track, starting at the current pitch, and
increasing by one rung (using the climbUp
function) with each note
added. The provided duration for the whole scale must be evenly divided
among the notes in the scale. So for example, if the scale duration is 1
second and there are 4 notes, each note's duration will be 0.25 seconds.
These scale
examples demonstrate how it should work.
unevenScale
The unevenScale
function must work
like scale
, but it has 3 parameters: a number of notes, a start
duration, and an 'other' duration. Instead of creating notes that all
have the same duration, every other note in the scale sequence uses the
other duration value. The starting
note of the scale always uses the start duration, which means that
depending on the number of notes, the top note may use either that value
or the other duration.
These unevenScale
examples demonstrate how it
should work.
arpeggio
For this last part, you'll create a more flexible function that creates
ascending note sequences with variable pitch differences between the
notes. The arpeggio
function must
accept 3 arguments: the first specifies the note duration, the second is
a list of pitch differences (integers), and the third specifies the
number of cycles, which indicates how many times the pattern of pitch
differences should repeat.
arpeggio
will add an ascending sequence of
notes where the first note starts at the
current pitch, the next note is a number of half-steps above that pitch
specified by the first value from the list of pitch differences, the
third note is a number of half-steps above that pitch specified by the
second pitch-difference-list value, and so on. The steps in the
pitch-differences list will be repeated as specified by the cycle count
(which will always be a positive integer). The total number of notes
will be one plus the cycle count times the length of the
pitch-differences list.
As shown in the arpeggio
examples, if the pitch
differences are [3, 4, 5]
and the cycle count is 2, the following notes
will be added (specified in terms of half-steps above the starting
pitch):
+0, +3, +7, +12, +15, +19, +24
Note that the total number of notes in this case is 1 + (2 * 3) = 7.
Notes:
halfStepUp
function to change pitches; note that it accepts a
parameter that determines the
number of steps up to take, and that it will accept negative numbers
to step down, so you can simply pass the pitch difference values
directly to halfStepUp
to change pitches.arpeggio
directly determines the length of each note it adds, so you don't
need to compute a note length based on a total duration.scalesDesign
Now that you've created functions for several different kinds of note
sequences, your final task is to create some more complicated pattern
using these functions. This example demonstrates
one such pattern that could be created, using a loop and the rewind
function to create multiple overlapping scales. But there are no
restrictions on the pattern that your function creates. The only
requirements for your scalesDesign
function are:
scalesDesign
, you must use at least one
loop, and in that loop, you
must call at least one of the scale
, unevenScale
, or arpeggio
functions.scale
examples
These examples show what should be printed and what audio should be
produced when scale
is called, followed by printTrack
and
playTrack
. Note that the exact pitches used depend on the current
pitch when the function is called.
In []:PrintssetPitch(C4) scale(0.75, 3) printTrack() playTrack()
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)Audio In []:PrintssetPitch(B2) scale(0.64, 8) printTrack() playTrack()
a 0.08s keyboard note at B2 (60% vol) and a 0.08s keyboard note at C3 (60% vol) and a 0.08s keyboard note at D3 (60% vol) and a 0.08s keyboard note at E3 (60% vol) and a 0.08s keyboard note at F3 (60% vol) and a 0.08s keyboard note at G3 (60% vol) and a 0.08s keyboard note at A3 (60% vol) and a 0.08s keyboard note at B3 (60% vol)Audio
unevenScale
examples
These examples show what should be printed and what audio should be
produced when unevenScale
is called, followed by printTrack
and
playTrack
. Note that the exact pitches used depend on the current pitch
when the function is called.
In []:PrintssetPitch(C4) unevenScale(3, 0.75, 0.25) printTrack() playTrack()
a 0.75s keyboard note at C4 (60% vol) and a 0.25s keyboard note at D4 (60% vol) and a 0.75s keyboard note at E4 (60% vol)Audio In []:PrintssetPitch(E2) unevenScale(8, 0.4, 0.5) printTrack() playTrack()
a 0.4s keyboard note at E2 (60% vol) and a 0.5s keyboard note at F2 (60% vol) and a 0.4s keyboard note at G2 (60% vol) and a 0.5s keyboard note at A2 (60% vol) and a 0.4s keyboard note at B2 (60% vol) and a 0.5s keyboard note at C3 (60% vol) and a 0.4s keyboard note at D3 (60% vol) and a 0.5s keyboard note at E3 (60% vol)Audio