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

353 lines
8.8 KiB
Python

from midiutil.MidiFile3 import MIDIFile
import random
import sys
import os
#--Variables--
#MIDI Variables
Selected_channel = 0
Selected_track = 0
Time_Constant = 0
Miditrack = MIDIFile(0)
#notes variables. these are pitches of the notes, add 12 to them for every octave you wanna go up
DictOfNotes = {'C' : 0, 'Do' : 0, 'Do#' : 1, 'C#' : 1, 'Reb' : 1, 'Db' : 1, 'Re' : 2, 'D' : 2, 'D#' : 3, 'Re#' : 3, 'Mib' : 3, 'Eb' : 3, 'Mi' : 4, 'E' : 4, 'F' : 5, 'Fa' : 5, 'F#' : 6,'Fa#' : 6, 'Solb':6, 'Gb' : 6, 'Sol':7, 'G' : 7, 'Sol#' : 8, 'G#' : 8, 'Lab' : 8, 'Ab' : 8,'La':9, 'A' : 9,'La#' : 10, 'A#' : 10, 'Bb' : 10,'Sib': 10, 'Tib': 10, 'B' : 11, 'Si':11, 'Ti':11}
C = 0
Db = 1
D = 2
Eb = 3
E = 4
F = 5
Gb = 6
G = 7
Ab = 8
A = 9
Bb = 10
B = 11
#Instrument Variables
DictOfInstruments = {'Piano' : 1, 'Bright_Piano' : 2,'Electric_Grand_Piano' : 3,'Honkytonk_Piano' : 4,'Electric_Piano' : 5,'Electric_Piano_2' : 6,'Harpsichord' : 7,'Clavinet' : 8,'Celesta' : 9,'Glockenspiel' : 10,'Music_Box' : 11,'Vibraphone' : 12,'Marimba' : 13,'Xylophone' : 14,'Tubular_Bells' : 15,'Dulcimer' : 16,'Drawbar_Organ' : 17,'Percussive_Organ' : 18,'Rock_Organ' : 19,'Church_Organ' : 20,'Reed_Organ' : 21,'Accordion' : 22,'Harmonica' : 23,'Tango_Accordion' : 24,'Acoustic_Guitar_nylon' : 25,'Acoustic_Guitar_steel' : 26,'Electric_Guitar_jazz' : 27,'Electric_Guitar_clean' : 28,'Electric_Guitar_muted' : 29,'Overdriven_Guitar' : 30,'Distortion_Guitar' : 31,'Guitar_Harmonics' : 49,'Acoustic_Bass' : 33,'Electric_Bass_finger' : 34,'Electric_Bass_pick' : 35,'Fretless_Bass' : 36,'Slap_Bass' : 37,'Slap_Bass_2' : 38,'Synth_Bass' : 39,'Synth_Bass_2' : 40,'Violin' : 41,'Viola' : 42,'Cello' : 43,'Contrabass' : 44,'Tremolo_Strings' : 45,'Pizzicato_Strings' : 46,'Orchestral_Harp' : 47,'Timpani' : 48,'String_Ensemble' : 49,'String_Ensemble_2' : 50,'Synth_Strings' : 51,'Synth_Strings_2' : 52,'Choir_Aahs' : 53,'Voice_Oohs' : 54,'Synth_Choir' : 55,'Orchestra_Hit' : 56,'Trumpet' : 57,'Trombone' : 58,'Tuba' : 59,'Muted_Trumpet' : 60,'French_Horn' : 61,'Brass_Section' : 62,'Synth_Brass' : 63,'Synth_Brass_2' : 64,'Soprano_Sax' : 65,'Alto_Sax' : 66,'Tenor_Sax' : 67,'Baritone_Sax' : 68,'Oboe' : 69,'English_Horn' : 70,'Bassoon' : 71,'Clarinet' : 72,'Piccolo' : 73,'Flute' : 74,'Recorder' : 75,'Pan_Flute' : 76,'Blown_bottle' : 77,'Shakuhachi' : 78,'Whistle' : 79,'Ocarina' : 80,'Synth_Lead_square' : 81,'Synth_Lead_sawtooth' : 82,'Synth_Lead_calliope' : 83,'Synth_Lead_chiff' : 84,'Synth_Lead_charang' : 85,'Synth_Lead_voice' : 86,'Synth_Lead_fifths' : 87,'Synth_Lead_bass_and_lead' : 88,'Synth_Pad_new_age' : 89,'Synth_Pad_warm' : 90,'Synth_Pad_polysynth' : 91,'Synth_Pad_choir' : 92,'Synth_Pad_bowed' : 93,'Synth_Pad_metallic' : 94,'Synth_Pad_halo' : 95,'Synth_Pad_sweep' : 96,'Synth_FX_rain' : 97,'Synth_FX_soundtrack' : 98,'Synth_FX_crystal' : 99,'Synth_FX_atmosphere' : 100,'Synth_FX_brightness' : 101,'Synth_FX_goblins' : 102,'Synth_FX_echoes' : 103,'Synth_FX_scifi' : 104,'Sitar' : 105,'Banjo' : 106,'Shamisen' : 107,'Koto' : 108,'Kalimba' : 109,'Bagpipe' : 110,'Fiddle' : 111,'Shanai' : 112,'Tinkle_Bell' : 113,'Agogo' : 114,'Steel_Drums' : 115,'Woodblock' : 116,'Taiko_Drum' : 117,'Melodic_Tom' : 118,'Synth_Drum' : 119,'Reverse_Cymbal' : 120,'Guitar_Fret_Noise' : 121,'Breath_Noise' : 122,'Seashore' : 123,'Bird_Tweet' : 124,'Telephone_Ring' : 125,'Helicopter' : 126,'Applause' : 127,'Gunshot' : 128}
#Pianos
Piano = 1
Bright_Piano = 2
Electric_Grand_Piano = 3
Honkytonk_Piano = 4
Electric_Piano = 5
Electric_Piano_2 = 6
Harpsichord = 7
Clavinet = 8
#Chromatic_Percussion
Celesta = 9
Glockenspiel = 10
Music_Box = 11
Vibraphone = 12
Marimba = 13
Xylophone = 14
Tubular_Bells = 15
Dulcimer = 16
#Organ
Drawbar_Organ = 17
Percussive_Organ = 18
Rock_Organ = 19
Church_Organ = 20
Reed_Organ = 21
Accordion = 22
Harmonica = 23
Tango_Accordion = 24
#Guitar
Acoustic_Guitar_nylon = 25
Acoustic_Guitar_steel = 26
Electric_Guitar_jazz = 27
Electric_Guitar_clean = 28
Electric_Guitar_muted = 29
Overdriven_Guitar = 30
Distortion_Guitar = 31
Guitar_Harmonics = 49
#Bass
Acoustic_Bass = 33
Electric_Bass_finger = 34
Electric_Bass_pick = 35
Fretless_Bass = 36
Slap_Bass = 37
Slap_Bass_2 = 38
Synth_Bass = 39
Synth_Bass_2 = 40
#Strings
Violin = 41
Viola = 42
Cello = 43
Contrabass = 44
Tremolo_Strings = 45
Pizzicato_Strings = 46
Orchestral_Harp = 47
Timpani = 48
#Ensemble
String_Ensemble = 49
String_Ensemble_2 = 50
Synth_Strings = 51
Synth_Strings_2 = 52
Choir_Aahs = 53
Voice_Oohs = 54
Synth_Choir = 55
Orchestra_Hit = 56
#Brass
Trumpet = 57
Trombone = 58
Tuba = 59
Muted_Trumpet = 60
French_Horn = 61
Brass_Section = 62
Synth_Brass = 63
Synth_Brass_2 = 64
#Reed
Soprano_Sax = 65
Alto_Sax = 66
Tenor_Sax = 67
Baritone_Sax = 68
Oboe = 69
English_Horn = 70
Bassoon = 71
Clarinet = 72
#Pipe
Piccolo = 73
Flute = 74
Recorder = 75
Pan_Flute = 76
Blown_bottle = 77
Shakuhachi = 78
Whistle = 79
Ocarina = 80
#Synth_Lead
Synth_Lead_square = 81
Synth_Lead_sawtooth = 82
Synth_Lead_calliope = 83
Synth_Lead_chiff = 84
Synth_Lead_charang = 85
Synth_Lead_voice = 86
Synth_Lead_fifths = 87
Synth_Lead_bass_and_lead = 88
#Synth_Pad
Synth_Pad_new_age = 89
Synth_Pad_warm = 90
Synth_Pad_polysynth = 91
Synth_Pad_choir = 92
Synth_Pad_bowed = 93
Synth_Pad_metallic = 94
Synth_Pad_halo = 95
Synth_Pad_sweep = 96
#Synth_Effects
Synth_FX_rain = 97
Synth_FX_soundtrack = 98
Synth_FX_crystal = 99
Synth_FX_atmosphere = 100
Synth_FX_brightness = 101
Synth_FX_goblins = 102
Synth_FX_echoes = 103
Synth_FX_scifi = 104
#Ethnic
Sitar = 105
Banjo = 106
Shamisen = 107
Koto = 108
Kalimba = 109
Bagpipe = 110
Fiddle = 111
Shanai = 112
#Percussive
Tinkle_Bell = 113
Agogo = 114
Steel_Drums = 115
Woodblock = 116
Taiko_Drum = 117
Melodic_Tom = 118
Synth_Drum = 119
Reverse_Cymbal = 120
#Sound_effects
Guitar_Fret_Noise = 121
Breath_Noise = 122
Seashore = 123
Bird_Tweet = 124
Telephone_Ring = 125
Helicopter = 126
Applause = 127
Gunshot = 128
#--Functions--
#creates a midi file with the wanted amount of tracks, at the tempo and wanted amount of channels.
#these will always be in 4/4ths, since like 90% of music is in 4/4ths anyway it doesn't matter, and if we want, we can make it any multiple of the 4/4ths time since we can just increase the tempo, or take multiple bars and emulate them being one bar.
def MakeMidiFile(Tempo, Channels, Tracks = 16):
global Selected_channel
global Selected_track
global Time_Constant
global Miditrack
Time_Constant = 0
Selected_track = 0
Selected_channel = 0
Miditrack = MIDIFile(Tracks)
for x in range(0,Tracks):
trcknm = "track " + str(x)
Miditrack.addTrackName(x, Time_Constant, trcknm)
Miditrack.addTempo(x, Time_Constant, Tempo)
return
#changes note to the octave you want
def No( note, octave ):
temp = note + (12 * octave)
return int(note + (12 * octave))
def NoPrs( string ):
if len(string) > 3:
octNr = string[-1]
noteNr = DictOfNotes[string[0:-1]]
elif len(string) > 2 :
octNr = string[-1]
noteNr = DictOfNotes[string[0:-1]]
else:
octNr = string[-1]
noteNr = DictOfNotes[string[0]]
return No(noteNr, int(octNr))
#adds a single note to the track and sets the time_constant further
def AddNote( note, duration, volume ):
global Selected_channel
global Selected_track
global Time_Constant
global Miditrack
Miditrack.addNote(Selected_track, Selected_channel, NoPrs(note), Time_Constant, duration, volume)
Time_Constant += duration
return
#adds multiple notes to the track and sets the time_constant further
def AddChord( notes, duration, volume ):
global Selected_channel
global Selected_track
global Time_Constant
global Miditrack
for note in notes:
nr = NoPrs(note)
Miditrack.addNote(Selected_track, Selected_channel, nr, Time_Constant, duration, volume)
Time_Constant += duration
return
#adds a pause in the track
def AddPause( times, duration ):
if (is_number(times)):
for x in range (0, int(times)):
AddNote('C0', duration, 0)
else:
AddNote('C0', duration, 0)
return
#generates the .mid and writes it to given name
def ExportMidi(FileName):
global Miditrack
binfile = open(FileName+".mid", 'wb')
Miditrack.writeFile(binfile)
binfile.close()
return
def ChangeInstrument(InstrumentNr = 1, Channel = None, Track = None):
global Selected_channel
global Selected_track
global Time_Constant
global Miditrack
if Channel is None:
Channel = Selected_channel
if Track == None:
Track = Selected_track
if InstrumentNr in DictOfInstruments:
InstrumentNr = DictOfInstruments[InstrumentNr]
elif is_number(InstrumentNr):
InstrumentNr = int(InstrumentNr)
else:
InstrumentNr = 1
Miditrack.addProgramChange(Track, Channel, Time_Constant, InstrumentNr)
return
def ChangeTrack(tracknr):
global Selected_channel
global Selected_track
global Time_Constant
global Miditrack
Time_Constant = 0
Selected_track = tracknr
if Selected_track == None or Selected_track < 1:
Selected_track = 1
return
def is_number(s):
try:
int(s)
return True
except ValueError:
return False