Play provides various functions to play musical material stored in Note, Phrase, Part, and Score objects.
Play.audio() uses one or more AudioSamples (i.e., external audio files) as instruments to play musical material stored in Note, Phrase, Part, and Score objects.
| Function | Description |
| Play.audio(material, audioSamples) | Play musical material using AudioSamples as instruments. Parameter material may be a Note, Phrase, Part, or Score. Parameter audioSamples is a list of AudioSamples. |
| Play.audio(material, audioSamples, loopFlags) | Same as above. Additional parameter loopFlags is a list of booleans (True, False) indicating which AudioSamples to loop, if a note is longer than the corresponding AudioSample (a parallel list – all False by default). |
| Play.audio(material, audioSamples, loopFlags, envelopes) | Same as above. Additional parameter envelopes is a list of Envelopes to apply to corresponding AudioSamples (a parallel list). |
NOTE: You need to provide an audio sample for each channel used in the musical material. For example, if only one channel is being used (i.e., channel 0), you only need to provide one audio sample. See example below.
It is OK to reuse the same audio sample for more than one channel. If so, simply include it more than once in the audio sample list.
Order matters – channel 0 is associated with the first audio sample provided (i.e., all notes with channel 0 will be played using this audio sample); channel 1 is associated with the second audio sample, and so on.
Envelopes (a more advanced topic) are optional. For more information, see Envelope.
The following Play audio functions are also available:
| Function | Description |
| Play.audioNote(pitch, start, duration, audioSample, velocity, panning, loopFlag, envelope) | Plays a note with pitch (0-127 or float frequency in Hz) to be sounded after start milliseconds, lasting duration milliseconds, using an audioSample. Optional parameters are velocity (0-127 – default is 127), panning (0-127 – default is -1 indicating global panning), loopAudioSample indicating whether to loop audio sample if too short (default is False), and envelope. |
| Play.audioOn(pitch, audioSample, velocity, panning, loopAudioSample, envelope) | Starts pitch sounding immediately, using the given audioSample, at given pitch (0-127 or float frequency in Hz). Optional parameters are velocity (0-127 – default is 127), panning (0-127 – default is -1 indicating global panning), loopAudioSample indicating whether to loop audio sample if too short (default is False), and envelope. |
| Play.audioOff(pitch, audioSample, envelope) | Stops pitch from sounding. If the pitch is not sounding via this audioSample, this has no effect. Optional envelope should be the same as the one provided in corresponding Play.audioOn(). |
| Play.allAudioNotesOff() | Stops all notes from sounding on all audio samples. |
For example, here is a variation on furElise.py in Ch. 3:
# furElise.py
# Generates the theme from Beethoven's Fur Elise...
# using Moondog's "Bird's Lament" audio sample as instrument
# for rendering sound.
from music import *
instrument = AudioSample("moondog.Bird_sLament.wav", G4) # load an audio file
# create musical material...
# theme has some repetition, so break it up to maximize economy
# (also notice how we line up corresponding pitches and durations)
pitches1 = [E5, DS5, E5, DS5, E5, B4, D5, C5]
durations1 = [SN, SN, SN, SN, SN, SN, SN, SN]
pitches2 = [A4, REST, C4, E4, A4, B4, REST, E4]
durations2 = [EN, SN, SN, SN, SN, EN, SN, SN]
pitches3 = [GS4, B4, C5, REST, E4]
durations3 = [SN, SN, EN, SN, SN]
pitches4 = [C5, B4, A4]
durations4 = [SN, SN, EN]
# create an empty phrase, and construct theme from the above motifs
theme = Phrase()
theme.addNoteList(pitches1, durations1)
theme.addNoteList(pitches2, durations2)
theme.addNoteList(pitches3, durations3)
theme.addNoteList(pitches1, durations1) # again
theme.addNoteList(pitches2, durations2)
theme.addNoteList(pitches4, durations4)
# play it using audio file as instrument
Play.audio(theme, [instrument])
# More advanced using envelope to shape instrument sound
# Loop audio file, if too short for a note
#Play.audio(theme, [instrument], [True])
# Now, create an envelope to soften the audio instrument sound
#envelope = Envelope(attackTimes = [5, 10, 30], attackVolumes = [0.1, 0.2, 0.3], delayTime = 25, sustainVolume = 0.7, releaseTime = 200)
#Play.audio(theme, [instrument], [True], [envelope]) # and play it
Another example is this variation on creating a custom MIDI synthesizer, this time using an AudioSample (instead of MIDI), which essentially creates a regular synthesizer:
# audioSynthesizer.py
#
# Create a simple AudioSample synthesizer which plays notes originating
# on a external MIDI controller. More functionality may be easily
# added.
#
from midi import *
from music import *
# select input MIDI controller
midiIn = MidiIn()
# load sound
audio = AudioSample("strings - A4.wav", A4)
# create a nice envelope
env = Envelope([0, 20, 10], [0.0, 0.8, 1.0], 30, 0.6, 1200)
#env = Envelope() # default
# create callback function to start notes
def beginNote(eventType, channel, data1, data2):
# start this note, and loop it!!
Play.audioOn(data1, audio, data2, 64, True, env)
#print "pitch =", data1, "volume =", data2
# and register it
midiIn.onNoteOn(beginNote)
# create callback function to stop notes
def endNote(eventType, channel, data1, data2):
# stop this note
Play.audioOff(data1, audio, env)
#print "pitch =", data1, "volume =", data2
# and register it
midiIn.onNoteOff(endNote)
This allows to experiment with different sounds – to explore how they sound in polyphony… among other possibilities.