Created
November 15, 2010 02:11
-
-
Save jesstess/676329 to your computer and use it in GitHub Desktop.
Construct tones yourself and play them through /dev/dsp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
# Play music without any external files (ie you create the notes yourself) | |
# through /dev/dsp! Inspired by | |
# http://www.tldp.org/LDP/abs/html/devref1.html#MUSICSCR | |
def generate_notes(): | |
# See http://www.phy.mtu.edu/~suits/NoteFreqCalcs.html for details on | |
# calculating the frequencies | |
# 440 Hz, a4, is our reference frequency | |
a4 = 440 | |
# There are 12 half steps in the western chromatic scale | |
a = 2.0**(1.0/12) | |
# /dev/dsp has a default 8000 frames per second, 1 byte per frame. Let's | |
# make each note 2000 frames. | |
duration = 2000 | |
# Maximum volume is \xff | |
volume = '\xc0' | |
# Mute is halfway between \x00 and \xff | |
mute = '\x80' | |
base_notes = ["c", "c#", "d", "d#", "e", "f", | |
"f#", "g", "g#", "a", "a#", "b"] | |
d = dict() | |
for octave in [2, 3, 4, 5]: | |
for i in range(len(base_notes)): | |
# exponent is the distance in half steps you are from a4 | |
exponent = 12*(octave - 5) + 3 + i | |
# f_n=f_O*(a)^n | |
hertz = a4*a**(exponent) | |
# Convert Hertz to bytes | |
tone = int(8000.0 / hertz) | |
buffer = "" | |
for t in range(0, duration): | |
if t % tone == 0: | |
buffer += volume | |
else: | |
buffer += mute | |
d[base_notes[i] + str(octave)] = buffer | |
# Shorthand for the notes in the octave above middle C | |
for note in base_notes: | |
d[note] = d[note + "3"] | |
# Quarter note rest | |
d["rest"] = mute*duration | |
return d | |
def jingle_bells(): | |
song = ["e", "e", "e", "rest", | |
"e", "e", "e", "rest", | |
"e", "g", "c", "d", | |
"e", "rest", "rest", "rest", | |
"f", "f", "f", "f", | |
"f", "e", "e", "e", | |
"g", "g", "f", "d", | |
"c", "rest", "rest", "rest"] | |
return "".join([notes[elt] for elt in song]) | |
def oh_christmas_tree(): | |
song = ["c", "rest", "f", "f", | |
"f", "rest", "g", "rest", | |
"a", "a", "a", "rest", | |
"rest", "a", "g", "a", | |
"a#", "rest", "e", "rest", | |
"g", "rest", "f", "rest"] | |
return "".join([notes[elt] for elt in song]) | |
def deck_the_halls(): | |
song = ["c4", "rest", "rest", "a#", | |
"a", "rest", "g", "rest", | |
"f", "rest", "g", "rest", | |
"a", "rest", "f", "rest", | |
"g", "a", "a#", "g", | |
"a", "rest", "rest", "g", | |
"f", "rest", "e", "rest", | |
"f", "rest", "rest", "rest"] | |
return "".join([notes[elt] for elt in song]) | |
def test(): | |
""" | |
Step through the octaves. | |
""" | |
base_notes = ["c", "c#", "d", "d#", "e", "f", | |
"f#", "g", "g#", "a", "a#", "b"] | |
return "".join([notes[elt + str(i)] | |
for i in [2, 3, 4, 5] | |
for elt in base_notes]) | |
if __name__ == "__main__": | |
global notes | |
notes = generate_notes() | |
f = open("/dev/dsp", 'wb') | |
f.write(jingle_bells()) | |
f.write(oh_christmas_tree()) | |
f.write(deck_the_halls()) | |
f.close() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment