from wave import open as waveOpen
from ossaudiodev import open as ossOpen
import sys, tty, termios
import random
ver = "1.1"
def playTone(myToneFile):
# http://stackoverflow.com/questions/307305/play-a-sound-with-python
s = waveOpen(myToneFile,'rb')
(nc,sw,fr,nf,comptype, compname) = s.getparams( )
dsp = ossOpen('/dev/dsp','w')
try:
from ossaudiodev import AFMT_S16_NE
except ImportError:
if byteorder == "little":
AFMT_S16_NE = ossaudiodev.AFMT_S16_LE
else:
AFMT_S16_NE = ossaudiodev.AFMT_S16_BE
dsp.setparameters(AFMT_S16_NE, nc, fr)
data = s.readframes(nf)
s.close()
dsp.write(data)
dsp.close()
def _getch():
# http://stackoverflow.com/questions/1052107/reading-a-single-character-getch-style-in-python-is-not-working-in-unix
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setraw(sys.stdin.fileno())
ch = sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return ch
def getNextRand(currentRand, randRangeMax):
newRand = random.randrange(0,randRangeMax)
while (newRand == currentRand):
newRand = random.randrange(0,randRangeMax)
return newRand
# Setup dictionary of tones here
# Full range of tones:
fullRange = (
("Low Bb", "low_Bb.wav"),
("Low B", "low_B.wav"),
("Low C", "low_C.wav"),
("Low C#", "low_C#.wav"),
("Low D", "low_D.wav"),
("Low D#", "low_D#.wav"),
("Low E", "low_E.wav"),
("Low F", "low_F.wav"),
("Low F#", "low_F#.wav"),
("Low G", "low_G.wav"),
("Low G#", "low_G#.wav"),
("Low A", "low_A.wav"),
("Low A#", "low_A#.wav"),
("Middle B", "middle_B.wav"),
("Middle C", "middle_C.wav"),
("Middle C#", "middle_C#.wav"),
("Middle D", "middle_D.wav"),
("Middle D#", "middle_D#.wav"),
("Middle E", "middle_E.wav"),
("Middle F", "middle_F.wav"),
("Middle F#", "middle_F#.wav"),
("Middle G", "middle_G.wav"),
("Middle G#", "middle_G#.wav"),
("Middle A", "middle_A.wav"),
("Middle A#", "middle_A#.wav"),
("High B", "high_B.wav"),
("High C", "high_C.wav"),
("High C#", "high_C#.wav"),
("High D", "high_D.wav"),
("High D#", "high_D#.wav"),
("High E", "high_E.wav"),
("High F", "high_F.wav"),
("High F#", "high_F#.wav"))
middleRange = fullRange[7:21]
lowMiddleRange = fullRange[0:21]
soundDictionary = middleRange
print "Intonation/Transcription Ear Developer " + ver
print "\nSpace to play tone, 0 for answer, Enter for next tone, q to quit"
kbValue = ord(_getch())
# set a random note at start
random.seed()
currentRand = random.randrange(0,len(soundDictionary))
currentSound = soundDictionary[currentRand-1]
while 1:
if kbValue == 32:
print "Playing tone."
playTone(currentSound[1])
playTone(currentSound[1])
elif kbValue == 13:
currentRand = getNextRand(currentRand, len(soundDictionary))
currentSound = soundDictionary[currentRand-1]
print "Switched to another tone."
elif kbValue == 48:
print "The answer is: " + currentSound[0]
elif kbValue == 113:
break
kbValue = ord(_getch())
So basically what it does is very simple, play back a specific sound sample, which I will try to use my ears and saxophone to match. In essence this will achieve two things.First, figuring out a particular note will aid recognition of the particular note, and that will aid transcription. Secondly, with the playback, assuming I can figure out the note, if I can harmonize with the note should help with my intonation.
Hope it works :)
Edit: 27th September 2011
After some real world use, I found that randrange kept giving very close values for the small range I'm using, so additional code was used to ensure the previous tone would not be the next one as well.



