Skip to content

Instantly share code, notes, and snippets.

@jesstess
Created November 15, 2010 02:11
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jesstess/676329 to your computer and use it in GitHub Desktop.
Save jesstess/676329 to your computer and use it in GitHub Desktop.
Construct tones yourself and play them through /dev/dsp
#!/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