This task is part of project02 which is due at 23:00 EDT on 2024-09-17.
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
mixedUpMelodies.py
(which is provided among the starter files)
This task is based on 18th-century dice-based music composition, such as Motzart's "Musicalisches Würfenspiel." which involves rolling dice to randomly determine different segments of music to fit together.
Your goal in this task is to write functions that use the wavesynth
library to create short melodic segments:
intros, refrains, and endings. These functions will be combined with each
other to create a mixed-up melody.
The focus of this task is on modularity, so we want to write functions which will add audio to the current track while being able to be mixed together with other functions to make a song. All of our melodies will make sure that they return to the original pitch and volume settings by the end of the function. They don't necessarily have to include a note that uses the original pitch, but they must return to it, allowing us to mix multiple melodies together without interference.
You should not just use setPitch
or setVolume
to fix the pitch or
volume in any of these functions: they need to be able to return to the
starting pitch/volume no matter what those values are to start with. To
achieve this, balance out calls to climbUp
/climbDown
and louder
/quieter
within the function, OR use
currentPitch
/currentVolume
to measure the pitch/volume at the start
of the function so you can return to those values.
You must write three functions for this part of the task:
melodyIntro
,
melodyRefrain
, and
melodyEnding
.
In each function, you must:
addNote
and/or addBeat
in at least two
places (it's okay if
these are called indirectly within a custom function, but there must
be at least two separate places that such function calls appear in
your code).Beyond those requirements, melodyRefrain
has two extra requirements:
you must use some kind of custom function within melodyRefrain
,
and that function must add at least one note or beat to the composition
using addNote
or addBeat
. Furthermore, in either melodyRefrain
or the custom function used within it, you must use rewind
somewhere.
Of course, these requirements are pretty open-ended, and it's up to you
to decide what kind of melodies you want to create. You can reference the
cheeryMelody.py
and drumsMelody.py
starter files (and associated test
files) for examples of how to fulfil these goals, but of course, your own
code has to be different from the starter files.
Note: none of these three required functions may have any parameters, although your custom function(s) can have whatever parameters they like.
To complete this task, you have to define a mixedMelody
function which
has no parameters and which mixes
together some of the melody segments you created with one or more of the
provided melody segments from the cheeryMelody.py
and drumsMelody.py
files.
These melody function examples provide a demonstration of what your melody functions could sound like, although the exact pitches, volumes, and instruments used are up to you.
Specifically:
You must call at least one
Intro
, at least
two Refrain
, and
at least one
Ending
function,
and you must call at least two different Refrain
functions. You may
of course call other functions, and if you want you can get creative with
the use of functions like rewind
so that the segments overlap instead
of just playing in sequence.
This mixedMelody
example demonstrates what the
melody could sound like by mixing together some of the provided segments
with some novel segments.
As usual, there are a few rules you must follow throughout:
None
) in a variable (a.k.a., box).Demonstration of melodyIntro
, melodyRefrain
, and melodyEnding
These examples illustrate how the different melody part functions might sound (the specifics are up to you!). Note that we print the pitch and volume before and after each to show that they are the same. The last example demonstrates how things sound when multiple functions are called one after the other.
In []:Printsprint("Starting pitch is:", round(currentPitch(), 2)) print("Starting volume is:", str(round(100 * currentVolume())) + '%') melodyIntro() printTrack() playTrack() print("Ending pitch is:", round(currentPitch(), 2)) print("Ending volume is:", str(round(100 * currentVolume())) + '%')
Starting pitch is: 261.63 Starting volume is: 60% a 0.5s keyboard note at C4 (60% vol) and a 0.25s rest at 0.75s a 0.5s keyboard note at C4 (60% vol) at 0.75s a 0.5s keyboard note at G4 (27% vol) at 1.25s a 0.25s rest at 1.5s a 0.5s keyboard note at C4 (60% vol) at 1.5s a 0.5s keyboard note at E4 (27% vol) Ending pitch is: 261.63 Ending volume is: 60%Audio In []:Prints# Set up a higher pitch and quieter volume to start with setPitch(G4) setVolume(0.4) print("Starting pitch is:", round(currentPitch(), 2)) print("Starting volume is:", str(round(100 * currentVolume())) + '%') melodyRefrain() printTrack() playTrack() print("Ending pitch is:", round(currentPitch(), 2)) print("Ending volume is:", str(round(100 * currentVolume())) + '%')
Starting pitch is: 392.01 Starting volume is: 40% at 0s a 0.5s keyboard note at F4 (40% vol) at 0s a 0.5s keyboard note at A4 (18% vol) at 0.5s a 0.25s rest at 0.75s a 0.5s keyboard note at Eb4 (40% vol) at 0.75s a 0.5s keyboard note at Bb4 (18% vol) at 1.25s a 0.25s rest at 1.5s a 0.5s keyboard note at G4 (40% vol) at 1.5s a 0.5s keyboard note at Bb4 (18% vol) Ending pitch is: 392.01 Ending volume is: 40%Audio In []:Printsprint("Starting pitch is:", round(currentPitch(), 2)) print("Starting volume is:", str(round(100 * currentVolume())) + '%') melodyEnding() printTrack() playTrack() print("Ending pitch is:", round(currentPitch(), 2)) print("Ending volume is:", str(round(100 * currentVolume())) + '%')
Starting pitch is: 261.63 Starting volume is: 60% at 0s a 0.5s keyboard note at C4 (60% vol) at 0s a 0.5s keyboard note at G4 (27% vol) at 0.5s a 0.25s rest at 0.75s a 0.5s keyboard note at C4 (60% vol) at 0.75s a 0.5s keyboard note at Eb4 (27% vol) at 1.25s a 0.25s rest at 1.5s a 0.5s keyboard note at C4 (60% vol) at 1.5s a 0.5s keyboard note at E4 (27% vol) Ending pitch is: 261.63 Ending volume is: 60%Audio In []:Printsprint("Starting pitch is:", round(currentPitch(), 2)) print("Starting volume is:", str(round(100 * currentVolume())) + '%') melodyIntro() melodyRefrain() melodyEnding() printTrack() playTrack() print("Ending pitch is:", round(currentPitch(), 2)) print("Ending volume is:", str(round(100 * currentVolume())) + '%')
Starting pitch is: 261.63 Starting volume is: 60% a 0.5s keyboard note at C4 (60% vol) and a 0.25s rest at 0.75s a 0.5s keyboard note at C4 (60% vol) at 0.75s a 0.5s keyboard note at G4 (27% vol) at 1.25s a 0.25s rest at 1.5s a 0.5s keyboard note at C4 (60% vol) at 1.5s a 0.5s keyboard note at E4 (27% vol) at 2s a 0.5s keyboard note at Bb3 (60% vol) at 2s a 0.5s keyboard note at D4 (27% vol) at 2.5s a 0.25s rest at 2.75s a 0.5s keyboard note at Ab3 (60% vol) at 2.75s a 0.5s keyboard note at Eb4 (27% vol) at 3.25s a 0.25s rest at 3.5s a 0.5s keyboard note at C4 (60% vol) at 3.5s a 0.5s keyboard note at Eb4 (27% vol) at 4s a 0.5s keyboard note at C4 (60% vol) at 4s a 0.5s keyboard note at G4 (27% vol) at 4.5s a 0.25s rest at 4.75s a 0.5s keyboard note at C4 (60% vol) at 4.75s a 0.5s keyboard note at Eb4 (27% vol) at 5.25s a 0.25s rest at 5.5s a 0.5s keyboard note at C4 (60% vol) at 5.5s a 0.5s keyboard note at E4 (27% vol) Ending pitch is: 261.63 Ending volume is: 60%Audio
Demonstration of the mixedMelody
function
This example shows what mixedMelody
could sound like. Note from the
printed messages that the pitch and volume do not change from beginning
to end, even though they do change during the melody.
In []:Printsprint("Starting pitch is:", round(currentPitch(), 2)) print("Starting volume is:", str(round(100 * currentVolume())) + '%') mixedMelody() printTrack() playTrack() print("Ending pitch is:", round(currentPitch(), 2)) print("Ending volume is:", str(round(100 * currentVolume())) + '%')
Starting pitch is: 261.63 Starting volume is: 60% a 0.25s keyboard note at C4 (27% vol) and a 0.25s rest and a 0.25s keyboard note at C4 (27% vol) and a 0.25s rest and a 0.25s keyboard note at C4 (40% vol) and a 0.25s keyboard note at D4 (60% vol) at 1.5s a 0.5s keyboard note at C4 (60% vol) at 1.5s a 0.5s keyboard note at E4 (18% vol) at 2s a 0.5s keyboard note at Bb3 (60% vol) at 2s a 0.5s keyboard note at D4 (27% vol) at 2.5s a 0.25s rest at 2.75s a 0.5s keyboard note at Ab3 (60% vol) at 2.75s a 0.5s keyboard note at Eb4 (27% vol) at 3.25s a 0.25s rest at 3.5s a 0.5s keyboard note at C4 (60% vol) at 3.5s a 0.5s keyboard note at Eb4 (27% vol) at 4s a 0.25s keyboard note at C4 (60% vol) at 4s a 0.125s snare beat (18% vol) at 4.25s a 0.25s keyboard note at A3 (60% vol) at 4.25s a 0.125s snare beat (18% vol) at 4.5s a 0.25s keyboard note at F3 (60% vol) at 4.5s a 0.125s snare beat (18% vol) at 4.75s a 0.25s keyboard note at C4 (60% vol) at 4.75s a 0.125s snare beat (18% vol) at 5s a 0.25s keyboard note at C4 (60% vol) and a 0.25s keyboard note at E4 (60% vol) and a 0.25s keyboard note at G4 (60% vol) and a 0.25s keyboard note at E4 (60% vol) and a 0.25s keyboard note at C4 (60% vol) and a 0.25s keyboard note at E4 (60% vol) at 6.5s a 0.5s keyboard note at D4 (60% vol) at 6.5s a 0.5s keyboard note at A4 (18% vol) at 7s a 0.5s keyboard note at C4 (60% vol) at 7s a 0.5s keyboard note at G4 (27% vol) at 7.5s a 0.25s rest at 7.75s a 0.5s keyboard note at C4 (60% vol) at 7.75s a 0.5s keyboard note at Eb4 (27% vol) at 8.25s a 0.25s rest at 8.5s a 0.5s keyboard note at C4 (60% vol) at 8.5s a 0.5s keyboard note at E4 (27% vol) Ending pitch is: 261.63 Ending volume is: 60%Audio
=
or by defining a parameter for a function) you must also later use that variable as part of another expression. If you need to create a variable that you won't use, it must have the name _
, but you should only do this if absolutely necessary.melodyIntro
returns to original pitch and volume (test 1/1)
melodyIntro
returns to original pitch and volume (test 1/2)
melodyIntro
returns to original pitch and volume (test 2/2)
melodyRefrain
returns to original pitch and volume (test 1/1)
melodyRefrain
returns to original pitch and volume (test 1/2)
melodyRefrain
returns to original pitch and volume (test 2/2)
melodyEnding
returns to original pitch and volume (test 1/1)
melodyEnding
returns to original pitch and volume (test 1/2)
melodyEnding
returns to original pitch and volume (test 2/2)
melodyIntro
with 0 parameters
def
to define melodyIntro
with 0 parameterssynth
module.
melodyIntro
with 0 parameters, use at least two different pitch- or volume-changing functions from the following list: climbUp
, climbDown
, halfStepUp
, halfStepDown
, quieter
, louder
addNote
or addBeat
melodyIntro
with 0 parameters, call addBeat
or addNote
in at least 2 places.melodyRefrain
with 0 parameters
def
to define melodyRefrain
with 0 parameterssynth
module.
melodyRefrain
with 0 parameters, use at least two different pitch- or volume-changing functions from the following list: climbUp
, climbDown
, halfStepUp
, halfStepDown
, quieter
, louder
addNote
or addBeat
melodyRefrain
with 0 parameters, call addBeat
or addNote
in at least 2 places.melodyRefrain
with 0 parameters
def
to define melodyRefrain
with 0 parametersmelodyRefrain
with 0 parameters, your code must call a custom function, and that function must add at least one beat or note.addNote
or addBeat
melodyRefrain
with 0 parameters, call addBeat
or addNote
in at least one place.rewind
melodyRefrain
with 0 parameters, either melodyRefrain
or a custom function that it calls must use rewind
in at least one place.melodyEnding
with 0 parameters
def
to define melodyEnding
with 0 parameterssynth
module.
melodyEnding
with 0 parameters, use at least two different pitch- or volume-changing functions from the following list: climbUp
, climbDown
, halfStepUp
, halfStepDown
, quieter
, louder
addNote
or addBeat
melodyEnding
with 0 parameters, call addBeat
or addNote
in at least 2 places.mixedMelody
with 0 parameters
def
to define mixedMelody
with 0 parametersmixedMelody
with 0 parameters, use at least one of melodyIntro
, cheeryIntro
, or drumsIntro
.mixedMelody
with 0 parameters, use at least two of melodyRefrain
, cheeryRefrain
, or drumsRefrain
.mixedMelody
with 0 parameters, use at least one of melodyEnding
, cheeryEnding
, or drumsEnding
.