A python music player
Posted: Fri Jul 13, 2007 9:23 pm
Hello, I've been working on this for a while now. It serves no purpose other than to give me something to do and to make my knowledge of python better, but I would like to 1) Have my code reviewed and if anybody is willing 2) have a helping (and skilled) hand at finishing this.
Basically, it parses a string and converts the instructions to music that is played via the winsound module.
Keep in mind that this is by no means done yet, but here it is:
If you are willing to help me finish this, you don't have to worry about musical knowledge. That's my part 
At the very least, please review my code and give me a few pointers. Thanks much, smudge
Basically, it parses a string and converts the instructions to music that is played via the winsound module.
Keep in mind that this is by no means done yet, but here it is:
Code: Select all
""" Name/ToDo list
Music Maker
by smudge
#Add support for repeats, something like |: ... : |x (repeat x times, if no x, 1 time)
#Staccato & Legato (*X and ^X)?
#Add support for dotting notes: A-8.
#Add support for reading from files
"""
import winsound
''' Usage instructions
A- -> G for notes
R for rest
- = flat
+ = sharp
L1=whole note default
L2/4/8/16=half/quarter/eighth/sixteenth...
A-8 plays an A flat eighth note
> = octave up perm
< = octave down perm
<X = X played down an octave
>>X = X played up 2 octaves
each note should be space separated
'''
#Crazy Train test music :D
music="L8 D D >A D >B- D >A D G F E F G F E C4"
print "Playing:",music
#settings
tempo=138.
played_in=4.
noteLen=4.
octave=0.
tempo=tempo/60./1000.#beats/ms
scale="A- A B- B C D- D E- E F G- G"
#Some shortcut functions
def findNote(baseF,hsteps):
return int(baseF * 2**(float(hsteps)/float(12)))
def playN(note,len):
if note != 'R':
if octave<0:
oct=1/(abs(octave)*2.)
elif octave==0:
oct=1
else:
oct=octave*2
else:
oct=1
beats=played_in/len
winsound.Beep(int(dict[note]*oct),int(beats/tempo))
def noteChecks(n):
global music,tempo,played_in,octave,scale,repeatLevel,repeatArr,noteLen
if 'L' in n:#If we are defining a default note length
#print " Found a length definition of",n[1:],"in",n
noteLen=int(n[1:])
elif 'O' in n:#If we are setting the default octave
octave=float(n[1:])
elif 'T' in n:#if we are setting the tempo
tempo=float(n[1:])/60./1000.
elif '>' in n:#shifting octave up
notNote=True
for x in scale.split(' '):
if n.find(x)!=-1: notNote=False
if notNote==True:#if we are shifting up permanently
octs=n.count('>')
octave+=octs
else:#or on a note to note basis
octs=n.count('>')
n=n[octs:]
octave+=octs
noteChecks(n)
octave-=octs
elif '<' in n:#shifting octave down
notNote=True
for x in scale.split(' '):
if n.find(x)!=-1: notNote=False
if notNote==True:#if we are shifting down permanently
octs=n.count('<')
octave-=octs
else:#or on a note to note basis
octs=n.count('<')
n=n[octs:]
octave-=octs
noteChecks(n)
octave+=octs
else:#if we are playing a note
if ('-' in n) or ('+' in n):#if we have a sharp or flat
if n[2:]=='':#if no length is defined
playN(n[0:2],noteLen)
else:
playN(n[0:2],int(n[2:]))
else:
if n[1:]=='':#if no length is defined
playN(n[0],noteLen)
else:
playN(n[0],int(n[1:]))
#Dictionary of notes and freqs
dict={}
i=-1
for n in scale.split(" "):
dict[n]=findNote(440,i)
#print "Loaded freq of",n,":",dict[n]
i=i+1
#Fakes resting by playing an inaudible pitch
dict['R']=30000
#Read the music
for n in music.split(' '):
noteChecks(n)
print "Done"
At the very least, please review my code and give me a few pointers. Thanks much, smudge