Files
rpiRadio/ProjectBefore/NodeServer/PythonCode/Midi/Interpreter.py
2018-05-19 02:20:19 +02:00

393 lines
9.6 KiB
Python

import sys
import schedule
import os
import MidiGenerator as m
import time
import json
from os import listdir
from os.path import isfile, join
#vars
#notes first letters
nts = {"D", "R", "M", "F", "S", "L", "S", "T", "C", "E", "G", "A", "B"}
times = {"O", "o", "q", "t", "s"}
Modifiers = {"(", ")", "|", ":"}
speshNts = {"D", "F"}
eu = {"R", "M", "S", "L", "T", "S"}
us = {"C", "E", "G", "A", "B"}
times = {'O' : 4, 'o' : 2, 'q' : 1, 't' : .5, 's' : .25}
channels = {'0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9,'A':10,'B':11,'C':12,'D':13,'E':14,'F':15}
noteMods = {"b", "#"}
filetype = None
'| B2t E3t (B3 F4)q pt D4t D3t A3t D4t E4t E3t B4t pt D5t |'
song = '| E4q G#4q B4q pq | ( E4 G#4 B4 )o po |'
ConvertionNotPossible = False
bpm = 140
#/home/beppe/Documents/Python/proj/1718JrpiRadio/PythonCode/Midi/
songPath = "songs/"
nonExistantNotes = {"D#", "Cb", "E#", "Fb", "Si#", "Ti#", "Dob", "Mi#", "Fab"}
#Methods
instrument = 0
def GetNextCharThing(pos, strg):
global ConvertionNotPossible
temp = strg[pos]
if temp in nts:
note = GetNoteStr(pos, strg)
timing = strg[pos+len(note)]
try:
m.AddNote(note, times[timing], 100)
except:
ConvertionNotPossible = True
print(str(sys.exc_info()[0]) + " ERROR HAPPENED AT ADDNOTE, ConvertionNotPossible = " + str(ConvertionNotPossible))
return pos+len(note)+1
elif temp in Modifiers:
if temp == "|":
return pos+1
elif temp == ":":
chan = strg[pos+1]
if chan in channels:
try:
m.Selected_channel = channels[chan]
m.ChangeInstrument(instrument)
except:
ConvertionNotPossible = True
print(str(sys.exc_info()[0]) + " ERROR HAPPENED AT CHANGEINSTRUMENT, ConvertionNotPossible = " + str(ConvertionNotPossible))
return pos+2
elif temp == "(":
charNr = pos +1
notes = []
while True:
if strg[charNr] in nts:
tempNote = GetNoteStr(charNr, strg)
notes.append(tempNote)
charNr = charNr + len(tempNote)
elif strg[charNr] == ")":
timing = strg[charNr+1]
try:
m.AddChord(notes, times[timing], 100)
except:
ConvertionNotPossible = True
print(str(sys.exc_info()[0]) + " ERROR HAPPENED AT ADDCHORD, ConvertionNotPossible = " + str(ConvertionNotPossible))
return charNr+1
break
elif strg[charNr] == "|":
charNr = charNr+1
elif temp in times:
return pos+1
elif temp == 'p':
amount = strg[pos+1]
timing = strg[pos+2]
try:
m.AddPause(amount, times[timing])
except:
ConvertionNotPossible = True
print(str(sys.exc_info()[0]) + " ERROR HAPPENED AT PAUSES, ConvertionNotPossible = " + str(ConvertionNotPossible))
return pos+2
else:
ConvertionNotPossible = True
return pos+1
def GetNoteStr(pos, strg):
temp = strg[pos]
if temp in nts:
if temp in speshNts:
if temp == "D":
if strg[pos+1] == "o":
if strg[pos+2] in noteMods:
note = strg[pos:pos+3]
octv = strg[pos+3]
return note+octv
else:
note = strg[pos:pos+2]
octv = strg[pos+2]
return note+octv
else:
if strg[pos+1] in noteMods:
note = strg[pos:pos+2]
octv = strg[pos+2]
return note+octv
else:
note = strg[pos]
octv = strg[pos+1]
return note+octv
else:
if strg[pos+1] == "a":
if strg[pos+2] in noteMods:
note = strg[pos:pos+3]
octv = strg[pos+3]
return note+octv
else:
note = strg[pos:pos+2]
octv = strg[pos+2]
return note+octv
else:
if strg[pos+1] in noteMods:
note = strg[pos:pos+2]
octv = strg[pos+2]
return note+octv
else:
note = strg[pos]
octv = strg[pos+1]
return note+octv
elif temp in eu:
if temp == "S":
if strg[pos+1] == "o":
if strg[pos+3] in noteMods:
note = strg[pos:pos+4]
octv = strg[pos+4]
return note+octv
else:
note = strg[pos:pos+3]
octv = strg[pos+3]
return note+octv
else:
if strg[pos+2] in noteMods:
note = strg[pos:pos+3]
octv = strg[pos+3]
return note+octv
else:
note = strg[pos:pos+2]
octv = strg[pos+2]
return note+octv
else:
if strg[pos+2] in noteMods:
note = strg[pos:pos+3]
octv = strg[pos+3]
return note+octv
else:
note = strg[pos:pos+2]
octv = strg[pos+2]
return note+octv
elif temp in us:
if strg[pos+1] in noteMods:
note = strg[pos:pos+2]
octv = strg[pos+2]
return note+octv
else:
note = strg[pos]
octv = strg[pos+1]
return note+octv
else:
return None
else:
return None
def writeSong(sng, title, bpm = 140, inst=1):
global songPath
m.MakeMidiFile(bpm, 16, 1)
currentpos = sng.find('|')
global instrument
global ConvertionNotPossible
if (instrument > 0):
m.ChangeInstrument(instrument)
else:
instrument = 1
while currentpos < len(sng):
currentpos = GetNextCharThing(currentpos, sng)
if ConvertionNotPossible:
break
if not ConvertionNotPossible:
m.ExportMidi(songPath + title)
else:
print("NOTABLETOWRITETRACK")
return True
def writeSongTracked(sngTracks, title, bpm=140, inst=1):
m.MakeMidiFile(bpm, 16, len(sngTracks)+1)
tracknr = 1
global ConvertionNotPossible, songPath
for track in sngTracks:
currentpos = track.find('|')
m.ChangeTrack(tracknr)
global instrument
InstrumentChk(track)
if (instrument > 0):
m.ChangeInstrument(instrument)
else:
instrument = 1
m.ChangeInstrument(instrument)
while currentpos < len(track):
currentpos = GetNextCharThing(currentpos, track)
if ConvertionNotPossible:
break
print (ConvertionNotPossible)
tracknr = tracknr +1
print (ConvertionNotPossible)
print (ConvertionNotPossible)
if not ConvertionNotPossible:
m.ExportMidi(songPath + title)
else:
print("NOTABLETOWRITETRACK")
m.ExportMidi(songPath + title)
return
def checkText(txt):
if txt.find('|') == -1:
return True
if any(Noot in txt for Noot in nonExistantNotes):
return True
return False
def ConvertFile(CONVERTABLEFILE):
title = ""
song = ""
global ConvertionNotPossible
ConvertionNotPossible = False
file = str(CONVERTABLEFILE)
file_extension = file[len(file)-5:]
if file_extension == '.json':
content = ""
with open(CONVERTABLEFILE, 'r') as contentfile:
content = contentfile.read()
print(content)
temp = json.loads(content)
for tweet in temp['tweets']:
song = tweet['text']
song = song.replace(" ", "")
ConvertionNotPossible = checkText(song)
title = tweet['UserName'] + " id_" + str(tweet['id'])
if ConvertionNotPossible == False:
writeSong(song, title)
tweet['location'] = 'songs/' + title + '.mid'
tweet['success'] = "yes"
with open('tweets.json', "w") as outfile:
json.dump(temp, outfile)
return
else:
title = os.path.basename(file)
with open(file, 'r') as files:
song = files.readline()
song = song.replace(" ", "")
firstBar = song.find('|')
checkText(song)
writeSong(song, title)
if ConvertionNotPossible:
with open(Directory+"/FailedLog", "a") as files:
files.write("song " + title + " has failed to initialise.... \n")
def is_number(s):
try:
int(s)
return True
except ValueError:
return False
def checkItems(path):
items = os.path.listdir(path)
for item in items:
ConvertFile(item)
return True
def checkTempo(strb):
global bpm
if strb.find("Bpm(") > -1:
temp = strb[strb.find("Bpm(")+4:strb.find(")")]
if is_number(temp):
bpm = int(temp)
else:
bpm = 140
return
def ConvertText(txt, ttl=time.strftime("%d_%m_%y_%H_%M_%S")):
song = txt
title = ttl
tracked = False
song = song.replace(" ", "")
checkTempo(song)
global ConvertionNotPossible
if "[" in song:
song = song.split("[")
tracked = True
if tracked:
songs = []
for track in song:
checkText(track)
if "Inst(" in track:
instStr = track[track.find("Inst("):track.find(")")+1]
else:
instStr = ""
testnaam = track[track.find("]")+3:len(track)-1]
temptrs = track[track.find("|"):track.find("]")]
if is_number(testnaam):
songs.append(instStr + temptrs*int(testnaam))
writeSongTracked(songs, title, bpm)
else:
InstrumentChk(song)
checkText(song)
writeSong(song, title, bpm)
if ConvertionNotPossible:
print('failed to export as song')
else:
print('normally it\'s exported now under the title of ' + title+'.mid')
return True
def InstrumentChk(txt):
global instrument
Inst = txt
if "Inst" in txt:
Inst = Inst[Inst.find("Inst(")+5:Inst.find(")")]
if is_number(Inst):
if int(Inst) < 129:
instrument = int(Inst)
else:
instrument = 0
else:
if Inst in m.DictOfInstruments:
instrument = m.DictOfInstruments[Inst]
else:
instrument = 0
def is_convertabletxt(txt):
if txt.find("|") > -1:
return True
return False
def startupRoutine():
if len(sys.argv) > 1:
if os.path.isdir(sys.argv[1]):
checkItems(sys.argv[1])
else:
if is_convertabletxt(sys.argv[1]):
if len(sys.argv) > 2:
ConvertText(sys.argv[1], sys.argv[2])
else:
ConvertText(sys.argv[1])
sys.exit()
if os.path.isfile(sys.argv[1]):
ConvertFile(sys.argv[1])
sys.exit()
print("no valid argument was found\nDo you want to continue? (y/n)")
char = input()
if char == 'y':
print('\nPlease enter the title of the string you want to convert,\nif you don\'t want to give it a name, then leave it blank and it will get a timestamp as the title.')
title = input()
print('\nPlease enter the content of the string you want to convert')
content = input()
print('\nConverting')
if(is_convertabletxt(content)):
if(title==""):
ConvertText(content)
else:
ConvertText(content, title)
else:
print('\nthe text you entered is non convertable\nPress enter to continue...')
input()
sys.exit()
else:
sys.exit()
startupRoutine()