mirror of
https://github.com/bvanroll/rpiRadio.git
synced 2025-08-29 12:02:42 +00:00
353 lines
8.8 KiB
Python
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
|