// Ringtone player v0.1
// by Al Rado
//
// Plays ringtones in RTTTL format(Ring Tone Text Transfer Language)
// More ringtones: http://syspace.ru/nokiatone/rtttf.htm
import "stringUtil"
SongParser = {}
SongParser.notesMap = {"B0":"23", "C1":"24", "C#1":"25", "D1":"26", "D#1":"27", "E1":"28", "F1":"29", "F#1":"30", "G1":"31", "G#1":"32", "A1":"33", "A#1":"34", "B1":"35", "C2":"36", "C#2":"37", "D2":"38", "D#2":"39", "E2":"40", "F2":"41", "F#2":"42", "G2":"43", "G#2":"44", "A2":"45", "A#2":"46", "B2":"47", "C3":"48", "C#3":"49", "D3":"50", "D#3":"51", "E3":"52", "F3":"53", "F#3":"54", "G3":"55", "G#3":"56","A3":"57", "A#3":"58", "B3":"59", "C4":"60", "C#4":"61","D4":"62", "D#4":"63", "E4":"64", "F4":"65", "F#4":"66", "G4":"67", "G#4":"68", "A4":"69", "A#4":"70", "B4":"71", "C5":"72", "C#5":"73", "D5":"74", "D#5":"75", "E5":"76", "F5":"77", "F#5":"78", "G5":"79", "G#5":"80", "A5":"81", "A#5":"82", "B5":"83", "C6":"84", "C#6":"85", "D6":"86", "D#6":"87", "E6":"88", "F6":"89", "F#6":"90", "G6":"91", "G#6":"92", "A6":"93", "A#6":"94", "B6":"95", "C7":"96", "C#7":"97", "D7":"98", "D#7":"99", "E7":"100", "F7":"101", "F#7":"102", "G7":"103", "G#7":"104", "A7":"105", "A#7":"106", "B7":"107", "C8":"108", "C#8":"109", "D8":"110", "D#8":"111"}
SongParser.getValue = function(keyValuePair)
return val(keyValuePair.split("=")[1])
end function
SongParser.parseNote = function(rawNote, wholeNote)
note = {}
if self.isDigit(rawNote[1]) then
note.duration = wholeNote / val(rawNote[0:2])
note.name = rawNote[2:]
else
note.duration = wholeNote / val(rawNote[0:1])
note.name = rawNote[1:]
end if
// fix dotted notes
if note.name.contains(".") then
note.name = note.name.remove(".")
note.duration = note.duration + note.duration / 2
end if
note.Frequency = self.noteFreqByName(note.name)
return note
end function
SongParser.parseSong = function(songToParse)
parts = songToParse.split(":")
song = {}
song.name = parts[0]
song.notes = []
settings = parts[1]
tones = parts[2].upper
settingParts = settings.split(",")
song.defaultDuration = self.getValue(settingParts[0])
song.defaultOctave = self.getValue(settingParts[1])
song.tempo = self.getValue(settingParts[2])
songNotes = tones.split(",")
for songNote in songNotes
rawNote = songNote.trim
if not self.isDigit(rawNote[0]) then
rawNote = song.defaultDuration + rawNote;
end if
if not self.isDigit(rawNote[-1]) then
rawNote = rawNote + song.defaultOctave
end if
note = self.parseNote(rawNote, self.getWholeNoteDuration(song.tempo))
song.notes.push note
end for
return song
end function
SongParser.getWholeNoteDuration = function(tempo)
if tempo != 0 then
return 60 * 4 / tempo
else
return 0;
end if
end function
SongParser.isDigit = function(symbol)
return val(symbol) > 0
end function
SongParser.noteFreqByName = function(noteName)
noteName = noteName.upper
if not self.notesMap.hasIndex(noteName) then
noteFreq = 0
else
noteNum = val(self.notesMap[noteName])
noteFreq = noteFreq(noteNum)
end if
return noteFreq
end function
ringtoneSound = new Sound
ringtoneSound.waveform = Sound.sineWave
ringtoneSound.envelope = 1
playNote = function(snd, freq, duration)
snd.freq = freq
snd.duration = duration
snd.play
wait duration
end function
ringtonesOnStartup = []
ringtonesOnStartup.push "Smpsns:d=4,o=5,b=160:32p,c.6,e6,f#6,8a6,g.6,e6,c6,8a,8f#,8f#,8f#,2g"
ringtonesOnStartup.push "PacMan:d=32,o=5,b=112:32p,b,p,b6,p,f#6,p,d#6,p,b6,f#6,16p,16d#6,16p,c6,p,c7,p,g6,p,e6,p,c7,g6,16p,16e6,16p,b,p,b6,p,f#6,p,d#6,p,b6,f#6,16p,16d#6,16p,d#6,e6,f6,p,f6,f#6,g6,p,g6,g#6,a6,p,b.6"
ringtonesOnStartup.push "Flinstones:d=4,o=5,b=40:32p,16f6,16a#,16a#6,32g6,16f6,16a#.,16f6,32d#6,32d6,32d6,32d#6,32f6,16a#,16c6,d6,16f6,16a#.,16a#6,32g6,16f6,16a#.,32f6,32f6,32d#6,32d6,32d6,32d#6,32f6,16a#,16c6,a#,16a6,16d.6,16a#6,32a6,32a6,32g6,32f#6,32a6,8g6,16g6,16c.6,32a6,32a6,32g6,32g6,32f6,32e6,32g6,8f6,16f6,16a#.,16a#6,32g6,16f6,16a#.,16f6,32d#6,32d6,32d6,32d#6,32f6,16a#,16c.6,32d6,32d#6,32f6,16a#,16c.6,32d6,32d#6,32f6,16a#6,16c7,8a#.6"
ringtonesOnStartup.push "Barbie girl:d=4,o=5,b=125:8g#,8e,8g#,8c#6,a,p,8f#,8d#,8f#,8b,g#,8f#,8e,p,8e,8c#,f#,c#,p,8f#,8e,g#,f# "
playRingtone = function(songStr)
song = SongParser.parseSong(songStr)
print "Song name: " + song.name
for note in song.notes
playNote ringtoneSound, note.Frequency, note.duration
end for
end function
clear
print "Example of ringtone:"
print ringtonesOnStartup[0]
print ""
playRingtone ringtonesOnStartup[ringtonesOnStartup.len * rnd]
while true
songStr = input("Paste ringtone in RTTTL format: ")
playRingtone songStr
end while