def main(): parser = argparse.ArgumentParser(description='Provide parameters!') parser.add_argument('tempo', help="Provide tempo of the song!", type=int) parser.add_argument('key', help="Provide key of the song!", type=int) parser.add_argument('scale', help="Provide scale of the song!", type=int) parser.add_argument('number_of_bars', help="Provide number of bars!", type=int) parser.add_argument('meter', help="Provide the meter of the song!", type=int) parser.add_argument('octaves_range', help="Provide the range of octaves", type=int) parser.add_argument('song_name', help="Provide song name", type=str) args = parser.parse_args() tempo = args.tempo key = args.key scale = args.scale number_of_bars = args.number_of_bars meter = args.meter octaves_range = args.octaves_range song_name = "resources/" + args.song_name + ".mid" with open('resources/scales.txt', 'r') as f: x = f.readlines() # scales are in scales.txt file if scale > len(x): print("Scale number is out of range") sys.exit() if key > 11 or key < 0: print("Key number should be between 0 - 11") sys.exit() if meter < 1 or meter > 7: print("Meter should be between 1 - 7") sys.exit() if tempo < 1 or tempo > 300: print("Tempo should be between 1 - 300") sys.exit() if number_of_bars < 1 or number_of_bars > 50: print("Number of bars should be between 1 - 50") sys.exit() if octaves_range < 1 or octaves_range > 3: print("Number of octaves should be between 1 - 3") sys.exit() scale_list = x[scale-1].replace('\n', '') scale_list = scale_list.split(", ") tempo *= 4 meter *= 4 song = Song(number_of_bars, scale_list, tempo, key, meter, octaves_range) song.generate_song() midi = MIDITime(tempo, song_name) song_notes = song.notes midi.add_track(song_notes) midi.save_midi()
class Music: def parser(self, args): self.filename = args.filename + '.mid' self.repeats = args.repeats self.long = 10 + args.long * 10 self.tempo = 72 + args.speed * 12 self.pitch_max = 68 + args.speed * 4 self.pitch_min = 33 + args.speed * 4 self.duration_max = 2.7 - args.speed * 0.3 self.duration_min = 1.8 - args.speed * 0.2 self.mymidi = MIDITime(self.tempo, self.filename) self.midinotes = [] def rand(self): for i in range(0, self.long): self.midinotes.append([ i * 0.53, randint(self.pitch_min, self.pitch_max), randint(70, 130), random.uniform(self.duration_min, self.duration_max) ]) j = 0 for j in range(1, self.repeats): for i in range(0, self.long): self.midinotes.append([ j * self.long * 0.53 + i * 0.53, self.midinotes[i][1], self.midinotes[i][2], self.midinotes[i][3] ]) self.mymidi.add_track(self.midinotes) def saveAndLaunch(self): self.mymidi.save_midi() os.startfile(self.filename)
def generate(self, lenght, path_in, path_out, bmp, nutes_max): mymidi = MIDITime(bmp, path_out) midinotes = self.algorithm.compose(lenght, path_in, nutes_max) mymidi.add_track(midinotes) mymidi.save_midi()
def main(): args = args_parser.parse_args() vel = 127 scale = MINOR if args.scale == "MINOR" else MAJOR # opens file with poem to parse with open(args.poem, 'r', encoding="UTF-8") as poem: poem_lines = poem.readlines() letter_notes = letter_notes_dict(args.lang, args.gama, scale) # sometimes there is strange utf sig in the first spot if poem_lines[0][0].lower() not in letter_notes.keys(): poem_lines[0] = poem_lines[0][1:] # lowers all notes if necessary if args.l: for letter, note in letter_notes.items(): letter_notes[letter] = note - 12 rhythm_maker = RhythmMaker(args.rhythm) chord_maker = ChordMaker(scale, vel // 2, args.chords) song = Song(vel, letter_notes, chord_maker, rhythm_maker) for line in poem_lines: for word in line.split(): song.add_tact(word) mymidi = MIDITime(90, args.o) mymidi.add_track(song.print()) mymidi.save_midi()
def csv_to_miditime(self, infile, outfile, octave): raw_data = list(self.read_csv(infile)) mymidi = MIDITime(self.tempo, outfile, self.seconds_per_year, self.base_octave, self.octave_range, self.epoch) note_list = [] for r in raw_data: began_date = datetime.strptime(r["began_date"], "%Y-%m-%d %H:%M:%S+00:00") # 2009-01-15 16:15:00+00:00 ended_date = datetime.strptime(r["ended_date"], "%Y-%m-%d %H:%M:%S+00:00") began_days_since_epoch = mymidi.days_since_epoch(began_date) ended_days_since_epoch = mymidi.days_since_epoch(ended_date) start_beat = mymidi.beat(began_days_since_epoch) end_beat = mymidi.beat(ended_days_since_epoch) duration_in_beats = end_beat - start_beat if duration_in_beats < 3: duration_in_beats = 3 # print start_beat, duration_in_beats note_list = note_list + self.bigger_boat(round(start_beat), duration_in_beats, mymidi, octave) # Add a track with those notes mymidi.add_track(note_list) # Output the .mid file mymidi.save_midi()
def test_sequencer_simple(out="out.mid", bpm=120, beats_per_bar=5): mt = MIDITime(bpm, out) seq = Sequencer(beats_per_bar=beats_per_bar, perturb_velocity_cap=20) start = 0 end = 120 pi = [BassDrum1, S, AcousticSnare, ClosedHiHat, BassDrum1] pv = [H, 0, M, M, H] pd = [1, 1, 1, 1, 1] pattern = Pattern("drum", 1, pi, pv, pd, repeatable=True) seq.time = start seq.channel = CHANNEL_DRUMS if not seq.compatible(pattern): print("Pattern incompatible") return while seq.time < end: if not seq.append(pattern): print("Couldn't append") # print(seq.notes()) mt.add_track(seq.notes) save_midi(mt)
def create_midi_file(fileName, bpm = 120, data = [], outputRange=2, songBeatLength=60): # first normalize data by deviation magnitudeMean = sum([d[1] for d in data]) / len([d[1] for d in data]) deviations = [(d[1] - magnitudeMean) for d in data] magnitudeMin = min(deviations) magnitudeMax = max(deviations) # (bpm, filename, sec per year, base octave,octave range) mymidi = MIDITime(bpm, fileName, 5, 4, outputRange) # add {'event_date': , 'magnitude': } note_list = [] # tie everything to 60 beats # [time, pitch, velocity, duration] beatsPerDataPoint = float(songBeatLength) / len(deviations) i = 0 for d in deviations: note_list.append([ i * beatsPerDataPoint, # beat mag_to_pitch_tuned(d, mymidi, magnitudeMin, magnitudeMax), 100, # velocity beatsPerDataPoint # duration, in beats ]) i=i+1 # Add a track with those notes mymidi.add_track(note_list) mymidi.save_midi()
def test_drums_simple(out="out.mid", bpm=120, beats_per_bar=5): mt = MIDITime(bpm, out) start = 0 end = 120 drums = [] d = 1 v = 127 for t in range(start, end): step = t % beats_per_bar if step == 0: n = BassDrum1 drums.append([[t, n, v, d], CHANNEL_DRUMS]) elif step == 2: n = AcousticSnare drums.append([[t, n, v, d], CHANNEL_DRUMS]) elif step == 3: n = ClosedHiHat drums.append([[t, n, v, d], CHANNEL_DRUMS]) elif step == 4: n = BassDrum1 drums.append([[t, n, v, d], CHANNEL_DRUMS]) mt.add_track(drums) save_midi(mt)
def just_jaws(self, outfile): # Just play the whole song mymidi = MIDITime(self.tempo, outfile, self.seconds_per_year, self.base_octave, self.octave_range, self.epoch) note_list = self.bigger_boat(0, 70, mymidi, 3) # Add a track with those notes mymidi.add_track(note_list) # Output the .mid file mymidi.save_midi()
def just_jaws(self, outfile): # Just play the whole song mymidi = MIDITime(self.tempo, outfile, self.seconds_per_year, self.base_octave, self.octave_range, self.epoch) note_list = self.bigger_boat(0, 70, mymidi, self.base_octave) # Add a track with those notes mymidi.add_track(note_list) # Output the .mid file mymidi.save_midi()
def test_hi_ride_sounds(out="out.mid", bpm=180, beats_per_bar=5): mt = MIDITime(bpm, out) seq = Sequencer(beats_per_bar=beats_per_bar, perturb_velocity_cap=30) start = 0 end = 120 pi = [] # length, character, ability to be looped # drummer - main pi = [] pi.append(ClosedHiHat) # very short tss, repeat pi.append(SILENCE) pi.append(PedalHiHat) # very short tss 2, repeat pi.append(SILENCE) pi.append(ClosedHiHat) # very short tss, repeat pi.append(SILENCE) pi.append(PedalHiHat) # very short tss 2, repeat pi.append(OpenHiHat) # long tss, single pi.append(RideCymbal2) # long, repeat pi.append(SILENCE) pi.append(RideCymbal2) # long, repeat pi.append(SILENCE) pi.append(RideCymbal2) # long, repeat pi.append(SILENCE) pi.append(RideBell) # long bell, repeat pi.append(CrashCymbal1) # long crash, single # pi = [val for val in pi for _ in range(0, 4)] pv = [] pd = [] pattern = Pattern("drums", int(ceil(len(pi) / beats_per_bar)), pi, pv, pd, repeatable=True) seq.channel = CHANNEL_DRUMS seq.time = start if not seq.compatible(pattern): print("Pattern incompatible") return while seq.time < end: if not seq.append(pattern): print("Couldn't append") mt.add_track(seq.notes) save_midi(mt)
def generate(self): filename = self.generate_filename() mymidi = MIDITime(self.tempo, self.location + filename) if self.mode == 0: midinotes = self.mode0() elif self.mode == 1: midinotes = self.mode1() else: midinotes = self.mode2() mymidi.add_track(midinotes) mymidi.save_midi()
def generate(self, pace, duration, probability): midi = MIDITime(tempo=pace, outfile=self.filename) notes_count = int(duration * pace / 60) notes = [] x = get_max_probability(probability) for i in range(0, notes_count): x = get_random(probability, x)[0] if x < 128: notes.append([i, x, 127, randint(3, 5)]) midi.add_track(notes) midi.save_midi()
def test_generator(out="out.mid", bpm=120, beats_per_bar=5): mt = MIDITime(bpm, out) seq = Sequencer(beats_per_bar=beats_per_bar, perturb_velocity_cap=10) prng = RandomState(75123481) start = 0 end = 120 scale = [A, C, D, E, G] # create the pattern as directions for a walk within a scale pi = [STAY, -1, UP, -1, UP, DOWN, ROOT_DOWN, -1, -1, NEXT_ROOT] pv = [H, 0, M, 0, H, H, M, 0, 0, M] pd = [2, 1, 1, 3, 1, 1, 3, 0, 0, 1] pattern0 = Pattern("piano1", 2, pi, pv, pd, repeatable=True) patterns = [ pattern0.walk_from_these_directions(len(scale), prng) for _ in range(1, 10) ] patterns = [p for p in patterns if p] print("available: ", len(patterns)) if not patterns: print("Couldn't generate any patterns from these directions.") return for (i, p) in enumerate(patterns): print(i, ": ", p.indices) pattern = patterns[0] # convert to sounds walker = ScaleWalker(Scale(ScaleBlueprint(scale), E)) pattern = pattern.sound_pattern_from_this_walk(walker) seq.time = start if not seq.compatible(pattern): print("Pattern incompatible") return while seq.time < end: if not seq.append(pattern): print("Couldn't append") print(seq.notes) mt.add_track(seq.notes) save_midi(mt)
def main(): args = return_args() dates = getDateRange(args.days) getRequest(dates, args.minmag) myLocation=getLocation() domains = parseQuakes(myLocation) #domains = {'distance': (33.69, 11845.77), 'depth': (0.42, 599.18), 'magnitude': (2.5, 7.2)} quake_midi = MIDITime(outfile=args.outfile, tempo=args.tempo, base_octave=args.base, octave_range=args.range) track_list = create_track_list(quake_midi, domains, args.key, args.patches) for note_list in track_list: quake_midi.add_track(note_list) print args.patches quake_midi.save_midi()
def playMusic(long, tempo, pitch, velocity, duration): global mymidi, midinotes, i mymidi = MIDITime(tempo, filename) midinotes = [] for i in range(0, long): midinotes.append([ i * 0.5, randint(48, pitch), randint(70, velocity), randint(1, duration) ]) mymidi.add_track(midinotes) mymidi.save_midi() os.startfile(filename)
def notes_to_midi_file(note_list, filename, tempo=_default_tempo): """Creates a midi file from a list of notes.""" midifile = MIDITime(_default_tempo, filename) time = 0 midi_event_list = [] note_list = flatten(note_list) #flatten the note list for note in note_list: midi_event_list.append([time, note, 200, 1]) time += 1 midifile.add_track(midi_event_list) midifile.save_midi()
class SongGenerator: def __init__(self, file_name, song_speed, song_mode, tones_range, notes): self.song = MIDITime(song_speed, file_name) #song self.song_mode = song_mode #if curvy or slight self.tones_range = tones_range # (60 - range ... 60 ... 60 + range) self.notes = notes #list with notes def generate_song(self): bit = 0 #start bit counter notes = [] #cut notes main_note = 60 #begin with 60 (C0) prev_note = 0 #previous note (needed to slighty style) for note in self.notes: note_details = [] #list to put in main notes list note_details.append(bit) # at n bit bit += 1 main_note = self.generate_single_note(self.song_mode, note, prev_note, main_note) #generate note note_details.append(main_note) prev_note = note #set previous as current note_details.append(127) #velocity note_details.append(randint(0, 10)) #duration of note notes.append(note_details) #add note details do main notes list print("Notes details:") self.song.add_track(notes) #add list to song self.song.save_midi() #save song print("Song succesfully saved!") def generate_single_note(self, mode, current_note, prev_note, main_note): #generate note using a note list start_note = 60 #begin with c0 if mode == 0: #if curvy then return note parsed to [60 - tones_range ... 60 ... 60 + tones_range] return current_note % (self.tones_range * 2) + (start_note - self.tones_range) else: #if slightly then main note depends on previous note if (prev_note > current_note > (start_note - self.tones_range)): return main_note - 1 elif (prev_note < current_note < (start_note + self.tones_range)): return main_note + 1 return main_note
def midify(sumsinearray): counter = 0 global mymidi for i in range(len(sumsinearray)): name = str(sumsinearray[i][1]) +'.mid' mymidi = MIDITime(120, name, 4, 5, 1) my_data = dictify(sumsinearray[i][0]) my_data_timed = [{'beat': mymidi.beat(d['datapoint']), 'magnitude': d['magnitude']} for d in my_data] start_time = my_data_timed[0]['beat'] note_list = builtnotelist(my_data_timed, start_time) # Add a track with those notes mymidi.add_track(note_list) # Output the .mid file mymidi.save_midi() counter += 1
def generate_file(filepath, time, option, bpm): directory = path.dirname(filepath) # if path is not created, makes one if directory != '' and not path.exists(directory): makedirs(directory) mymidi = MIDITime(bpm, filepath) # Create a list of notes. Each note is a list: [time, pitch, velocity, duration] # notes as an object sounds = musicnotes.Notes(time, 0, option) midinotes = sounds.notes magicnotes = [ [0, 61, 127, 3], [2, 66, 127, 2], [5, 69, 127, 1], [6, 68, 127, 2], [8, 66, 127, 2], [11, 73, 127, 2], [13, 71, 127, 4], [18, 68, 107, 2], [22, 66, 100, 2], [25, 69, 127, 1], [26, 68, 127, 1], [28, 64, 117, 2], [31, 66, 100, 2], [33, 61, 90, 3], ] if filepath.endswith('magic.mid'): mymidi = MIDITime(240, filepath) mymidi.add_track(magicnotes) mymidi.save_midi() exit(0) # Add a track with those notes mymidi.add_track(midinotes) # Output the .mid file mymidi.save_midi()
def list_to_miditime(self, raw_data, outfile, octave): mymidi = MIDITime(self.tempo, outfile, self.seconds_per_mile, self.base_octave, self.octave_range, self.epoch) note_list = [] start_note_index = 0 border_full_length = self.border_full_length() print border_full_length for r in raw_data: segment_start_meters = r['start_pct'] * border_full_length segment_start_beat = self.nearest_nth_beat( self.beat_meters(segment_start_meters), 16) segment_end_beat = self.nearest_nth_beat( self.beat_meters(segment_start_meters + r['length_m']), 16) duration_in_beats = segment_end_beat - segment_start_beat if duration_in_beats == 0: duration_in_beats = float(1) / float( 16) # Minimum duration of 1/16 if r['type'] == 'pedestrian': pitch = 'E5' elif r['type'] == 'vehicle': pitch = 'F6' # I've left a few other options commented out here. The live version just plays one long note for the duration of the fence segment, but the othres play through a melody. We ended up doing all of our melodic stuff in Live once we had a raw midi file. # new_notes, start_note_index = self.bigger_boat_2(segment_start_beat, start_note_index, duration_in_beats, mymidi, octave) # new_notes = self.bigger_boat(segment_start_beat, duration_in_beats, mymidi, octave) new_notes = self.just_one_note(segment_start_beat, duration_in_beats, pitch, mymidi, octave) note_list = note_list + new_notes # Add a track with those notes mymidi.add_track(note_list) # Output the .mid file mymidi.save_midi()
class MIDIFile(object): def __init__(self, BPM=120, filename='example.mid'): self.pattern = MIDITime(BPM, filename) self.step_counter = 0 self.filename = filename def create(self, notes): midinotes = [] offset = 60 attack = 200 beats = 1 for note in notes: pitch = (note - 1) + offset midinote = [self.step_counter, pitch, attack, beats] midinotes.append(midinote) self.step_counter = self.step_counter + 1 # Add a track with those notes self.pattern.add_track(midinotes) # Output the .mid file self.pattern.save_midi()
class Composer: def __init__(self, out_file: str = "out.mid"): self.__mt = MIDITime(StyleManager().style.bpm, out_file) self.drummer = Drummer() self.player = PianoPlayer() def compose(self, bar_groups: int = 4): self.drummer.play(bar_groups) self.player.play(bar_groups) def save(self): tracks = self.drummer.tracks + self.player.tracks for notes in tracks: self.__mt.add_track(notes) if tracks: save_midi(self.__mt, StyleManager().style.instruments_per_channel) else: save_midi(self.__mt) # empty
def test_sequencer_relative(out="out.mid", bpm=120, beats_per_bar=10): mt = MIDITime(bpm, out) seq = Sequencer(beats_per_bar=beats_per_bar, perturb_velocity_cap=10) start = 0 end = 120 # create the pattern as indices within a scale pi = [0, S, 1, S, 2] pv = [H, 0, M, 0, H] pd = [1, 1, 1, 1, 1] pattern = Pattern("piano", 1, pi, pv, pd, repeatable=True) # convert to sounds walker = ScaleWalker(Scale(ScaleBlueprint([A, C, D, E, G]), E)) print(pattern.indices) pattern = pattern.sound_pattern_from_this_walk(walker) print(pattern.indices) seq.time = start if not seq.compatible(pattern): print("Pattern incompatible") return while seq.time < end: if not seq.append(pattern): print("Couldn't append") print(seq.notes) mt.add_track(seq.notes) save_midi(mt)
def csv_to_miditime(self, infile, outfile, octave): raw_data = list(self.read_csv(infile)) mymidi = MIDITime(self.tempo, outfile, self.seconds_per_year, self.base_octave, self.octave_range, self.epoch) note_list = [] start_note_index = 0 for r in raw_data: began_date = datetime.strptime( r["began_date"], "%Y-%m-%d %H:%M:%S+00:00") # 2009-01-15 16:15:00+00:00 ended_date = datetime.strptime(r["ended_date"], "%Y-%m-%d %H:%M:%S+00:00") began_days_since_epoch = mymidi.days_since_epoch(began_date) ended_days_since_epoch = mymidi.days_since_epoch(ended_date) start_beat = mymidi.beat(began_days_since_epoch) end_beat = mymidi.beat(ended_days_since_epoch) duration_in_beats = end_beat - start_beat # if duration_in_beats < 3: # duration_in_beats = 3 # print start_beat, duration_in_beats new_notes, start_note_index = self.bigger_boat_2( start_beat, start_note_index, duration_in_beats, mymidi, octave) note_list = note_list + new_notes # Add a track with those notes mymidi.add_track(note_list) # Output the .mid file mymidi.save_midi()
notes.extend(note) return notes if debug: NotesGenerator.set_debug_mode() gen_random_notes = print_arg(gen_random_notes) if args.seqoff: sequence = NotesGenerator(key_string=output, base_duration=1 / 4, segments_number=args.number, max_difference=args.difference, segment_length=args.length) notes = sequence.give_notes() mymidi.add_track(notes) # last note from list of notes and first element -> end time of sound max_time = notes[-1][0] else: max_time = args.length * args.number for i in range(random): # duration <- [1/2,2] dur = (i + 1) / 2 notes = gen_random_notes(key_string=output, start=48 + i * 5, num=int(max_time / dur), offset=0, duration=dur) mymidi.add_track(notes) output = [chr(ord(c) - 1) for c in output]
def save_midi_file(data, name, bpm): mymidi = MIDITime(bpm, name) mymidi.add_track(data) mymidi.save_midi()
class bomb2midi(object): ''' Submitted by Jennifer LaFleur. ''' epoch = datetime( 1945, 1, 1) # Not actually necessary, but optional to specify your own mymidi = None min_value = 0 max_value = 5.7 tempo = 120 min_attack = 30 max_attack = 255 min_duration = 1 max_duration = 5 seconds_per_year = 3 c_major = ['C', 'D', 'E', 'F', 'G', 'A', 'B'] c_minor = ['C', 'D', 'Eb', 'F', 'G', 'Ab', 'Bb'] a_minor = ['A', 'B', 'C', 'D', 'E', 'F', 'F#', 'G', 'G#'] c_blues_minor = ['C', 'Eb', 'F', 'F#', 'G', 'Bb'] d_minor = ['D', 'E', 'F', 'G', 'A', 'Bb', 'C'] c_gregorian = ['C', 'D', 'Eb', 'F', 'G', 'Ab', 'A', 'Bb'] current_key = c_major base_octave = 2 octave_range = 5 def __init__(self): self.csv_to_miditime() def read_csv(self, filepath): csv_file = open(filepath, 'rU') return csv.DictReader(csv_file, delimiter=',', quotechar='"') def remove_weeks(self, csv_obj): return [r for r in csv_obj if r['Date'] not in ['']] def round_to_quarter_beat(self, input): return round(input * 4) / 4 def make_notes(self, data_timed, data_key): note_list = [] start_time = data_timed[0]['beat'] for d in data_timed: note_list.append([ self.round_to_quarter_beat(d['beat'] - start_time), self.data_to_pitch_tuned(d[data_key]), 100, #mag_to_attack(d['magnitude']), # attack 1 # duration, in beats ]) return note_list def csv_to_miditime(self): raw_data = list(self.read_csv('data/bombs.csv')) filtered_data = self.remove_weeks(raw_data) self.mymidi = MIDITime(self.tempo, 'bombtest_log.mid', self.seconds_per_year, self.base_octave, self.octave_range, self.epoch) self.minimum = self.mymidi.get_data_range(filtered_data, 'Yieldnum')[0] self.maximum = self.mymidi.get_data_range(filtered_data, 'Yieldnum')[1] timed_data = [] for r in filtered_data: python_date = datetime.strptime(r["Date"], "%m/%d/%Y") days_since_epoch = self.mymidi.days_since_epoch(python_date) beat = self.mymidi.beat(days_since_epoch) timed_data.append({ 'days_since_epoch': days_since_epoch, 'beat': beat, 'BombYieldMillions': float(r['Yieldnum']) }) note_list = self.make_notes(timed_data, 'BombYieldMillions') # Add a track with those notes self.mymidi.add_track(note_list) # Output the .mid file self.mymidi.save_midi() def data_to_pitch_tuned(self, datapoint): # Where does this data point sit in the domain of your data? (I.E. the min magnitude is 3, the max in 5.6). In this case the optional 'True' means the scale is reversed, so the highest value will return the lowest percentage. #scale_pct = self.mymidi.linear_scale_pct(0, self.maximum, datapoint) # Another option: Linear scale, reverse order # scale_pct = self.mymidi.linear_scale_pct(0, self.maximum, datapoint, True) # print 10**self.maximum # Another option: Logarithmic scale, reverse order scale_pct = self.mymidi.log_scale_pct(0, self.maximum, datapoint, True, 'log') # Pick a range of notes. This allows you to play in a key. mode = self.current_key #Find the note that matches your data point note = self.mymidi.scale_to_note(scale_pct, mode) #Translate that note to a MIDI pitch midi_pitch = self.mymidi.note_to_midi_pitch(note) print scale_pct, note return midi_pitch def mag_to_attack(self, datapoint): # Where does this data point sit in the domain of your data? (I.E. the min magnitude is 3, the max in 5.6). In this case the optional 'True' means the scale is reversed, so the highest value will return the lowest percentage. scale_pct = self.mymidi.linear_scale_pct(0, self.maximum, datapoint) #max_attack = 10 adj_attack = (1 - scale_pct) * max_attack + 70 #adj_attack = 100 return adj_attack
class Coal2Midi(object): ''' Adapted from Jordan Wirfs-Brock's awesome coal production sonification. Post here: http://insideenergy.org/2016/05/03/listen-to-u-s-coal-production-fall-off-a-cliff/ Code and data here: https://github.com/InsideEnergy/Data-for-stories/tree/master/20160503-coal-production-sonification ''' epoch = datetime(1970, 1, 1) # TODO: Allow this to override the midtime epoch mymidi = None tempo = 120 min_attack = 30 max_attack = 255 min_duration = 1 max_duration = 5 seconds_per_year = 26 c_major = ['C', 'D', 'E', 'F', 'G', 'A', 'B'] c_minor = ['C', 'D', 'Eb', 'F', 'G', 'Ab', 'Bb'] a_minor = ['A', 'B', 'C', 'D', 'E', 'F', 'F#', 'G', 'G#'] c_blues_minor = ['C', 'Eb', 'F', 'F#', 'G', 'Bb'] d_minor = ['D', 'E', 'F', 'G', 'A', 'Bb', 'C'] c_gregorian = ['C', 'D', 'Eb', 'F', 'G', 'Ab', 'A', 'Bb'] current_key = c_major base_octave = 4 octave_range = 3 def __init__(self): self.csv_to_miditime() def read_csv(self, filepath): csv_file = open(filepath, 'rU') return csv.DictReader(csv_file, delimiter=',', quotechar='"') def remove_weeks(self, csv_obj): return [r for r in csv_obj if int(r['Week']) not in [53]] def round_to_quarter_beat(self, input): return round(input * 4) / 4 def round_to_half_beat(self, input): return round(input * 2) / 2 def make_notes(self, data_timed, data_key): note_list = [] start_time = data_timed[0]['beat'] for d in data_timed: note_list.append([ # self.round_to_half_beat(d['beat'] - start_time), round(d['beat'] - start_time), self.data_to_pitch_tuned(d[data_key]), 100, #mag_to_attack(d['magnitude']), # attack 1 # duration, in beats ]) return note_list def data_to_pitch_tuned(self, datapoint): # Where does this data point sit in the domain of your data? (I.E. the min magnitude is 3, the max in 5.6). In this case the optional 'True' means the scale is reversed, so the highest value will return the lowest percentage. scale_pct = self.mymidi.linear_scale_pct(0, self.maximum, datapoint) # Another option: Linear scale, reverse order # scale_pct = mymidi.linear_scale_pct(0, self.maximum, datapoint, True) # Another option: Logarithmic scale, reverse order # scale_pct = mymidi.log_scale_pct(0, self.maximum, datapoint, True) # Pick a range of notes. This allows you to play in a key. mode = self.current_key #Find the note that matches your data point note = self.mymidi.scale_to_note(scale_pct, mode) #Translate that note to a MIDI pitch midi_pitch = self.mymidi.note_to_midi_pitch(note) return midi_pitch def mag_to_attack(self, datapoint): # Where does this data point sit in the domain of your data? (I.E. the min magnitude is 3, the max in 5.6). In this case the optional 'True' means the scale is reversed, so the highest value will return the lowest percentage. scale_pct = self.mymidi.linear_scale_pct(0, self.maximum, datapoint) #max_attack = 10 adj_attack = (1 - scale_pct) * max_attack + 70 #adj_attack = 100 return adj_attack def csv_to_miditime(self): self.mymidi = MIDITime(self.tempo, 'coaltest.mid', self.seconds_per_year, self.base_octave, self.octave_range) raw_data = self.read_csv('data/coal_prod_1984_2016_weeks_summed.csv') filtered_data = self.remove_weeks(raw_data) self.minimum = self.mymidi.get_data_range(filtered_data, 'CoalProd')[0] / 1000000.0 self.maximum = self.mymidi.get_data_range(filtered_data, 'CoalProd')[1] / 1000000.0 timed_data = [] # Get the first day in the dataset, so we can use it's day of the week to anchor our other weekly data. first_day = self.mymidi.map_week_to_day(filtered_data[0]['Year'], filtered_data[0]['Week']) for r in filtered_data: # Convert the week to a date in that week week_start_date = self.mymidi.map_week_to_day(r['Year'], r['Week'], first_day.weekday()) # To get your date into an integer format, convert that date into the number of days since Jan. 1, 1970 days_since_epoch = self.mymidi.days_since_epoch(week_start_date) # Convert that integer date into a beat beat = self.mymidi.beat(days_since_epoch) timed_data.append({ 'days_since_epoch': days_since_epoch, 'beat': beat, 'CoalProdMillions': float(r['CoalProd']) / 1000000.0 }) note_list = self.make_notes(timed_data, 'CoalProdMillions') # Add a track with those notes self.mymidi.add_track(note_list) # Output the .mid file self.mymidi.save_midi()
class Coal2Midi(object): ''' Adapted from Jordan Wirfs-Brock's awesome coal production sonification. Post here: http://insideenergy.org/2016/05/03/listen-to-u-s-coal-production-fall-off-a-cliff/ Code and data here: https://github.com/InsideEnergy/Data-for-stories/tree/master/20160503-coal-production-sonification ''' epoch = datetime(1970, 1, 1) # TODO: Allow this to override the midtime epoch mymidi = None tempo = 120 min_attack = 30 max_attack = 255 min_duration = 1 max_duration = 5 seconds_per_year = 26 c_major = ['C', 'D', 'E', 'F', 'G', 'A', 'B'] c_minor = ['C', 'D', 'Eb', 'F', 'G', 'Ab', 'Bb'] a_minor = ['A', 'B', 'C', 'D', 'E', 'F', 'F#', 'G', 'G#'] c_blues_minor = ['C', 'Eb', 'F', 'F#', 'G', 'Bb'] d_minor = ['D', 'E', 'F', 'G', 'A', 'Bb', 'C'] c_gregorian = ['C', 'D', 'Eb', 'F', 'G', 'Ab', 'A', 'Bb'] current_key = c_major base_octave = 4 octave_range = 3 def __init__(self): self.csv_to_miditime() def read_csv(self, filepath): csv_file = open(filepath, 'rU') return csv.DictReader(csv_file, delimiter=',', quotechar='"') def remove_weeks(self, csv_obj): return [r for r in csv_obj if int(r['Week']) not in [53]] def round_to_quarter_beat(self, input): return round(input * 4) / 4 def round_to_half_beat(self, input): return round(input * 2) / 2 def make_notes(self, data_timed, data_key): note_list = [] start_time = data_timed[0]['beat'] for d in data_timed: note_list.append([ # self.round_to_half_beat(d['beat'] - start_time), round(d['beat'] - start_time), self.data_to_pitch_tuned(d[data_key]), 100, #mag_to_attack(d['magnitude']), # attack 1 # duration, in beats ]) return note_list def data_to_pitch_tuned(self, datapoint): # Where does this data point sit in the domain of your data? (I.E. the min magnitude is 3, the max in 5.6). In this case the optional 'True' means the scale is reversed, so the highest value will return the lowest percentage. scale_pct = self.mymidi.linear_scale_pct(0, self.maximum, datapoint) # Another option: Linear scale, reverse order # scale_pct = mymidi.linear_scale_pct(0, self.maximum, datapoint, True) # Another option: Logarithmic scale, reverse order # scale_pct = mymidi.log_scale_pct(0, self.maximum, datapoint, True) # Pick a range of notes. This allows you to play in a key. mode = self.current_key #Find the note that matches your data point note = self.mymidi.scale_to_note(scale_pct, mode) #Translate that note to a MIDI pitch midi_pitch = self.mymidi.note_to_midi_pitch(note) return midi_pitch def mag_to_attack(self, datapoint): # Where does this data point sit in the domain of your data? (I.E. the min magnitude is 3, the max in 5.6). In this case the optional 'True' means the scale is reversed, so the highest value will return the lowest percentage. scale_pct = self.mymidi.linear_scale_pct(0, self.maximum, datapoint) #max_attack = 10 adj_attack = (1 - scale_pct) * max_attack + 70 #adj_attack = 100 return adj_attack def csv_to_miditime(self): self.mymidi = MIDITime(self.tempo, 'coaltest.mid', self.seconds_per_year, self.base_octave, self.octave_range) raw_data = self.read_csv('data/coal_prod_1984_2016_weeks_summed.csv') filtered_data = self.remove_weeks(raw_data) self.minimum = self.mymidi.get_data_range(filtered_data, 'CoalProd')[0] / 1000000.0 self.maximum = self.mymidi.get_data_range(filtered_data, 'CoalProd')[1] / 1000000.0 timed_data = [] # Get the first day in the dataset, so we can use it's day of the week to anchor our other weekly data. first_day = self.mymidi.map_week_to_day(filtered_data[0]['Year'], filtered_data[0]['Week']) for r in filtered_data: # Convert the week to a date in that week week_start_date = self.mymidi.map_week_to_day( r['Year'], r['Week'], first_day.weekday()) # To get your date into an integer format, convert that date into the number of days since Jan. 1, 1970 days_since_epoch = self.mymidi.days_since_epoch(week_start_date) # Convert that integer date into a beat beat = self.mymidi.beat(days_since_epoch) timed_data.append({ 'days_since_epoch': days_since_epoch, 'beat': beat, 'CoalProdMillions': float(r['CoalProd']) / 1000000.0 }) note_list = self.make_notes(timed_data, 'CoalProdMillions') # Add a track with those notes self.mymidi.add_track(note_list) # Output the .mid file self.mymidi.save_midi()
class bomb2midi(object): ''' Submitted by Jennifer LaFleur. ''' epoch = datetime(1945, 1, 1) # Not actually necessary, but optional to specify your own mymidi = None min_value = 0 max_value = 5.7 tempo = 120 min_attack = 30 max_attack = 255 min_duration = 1 max_duration = 5 seconds_per_year = 3 c_major = ['C', 'D', 'E', 'F', 'G', 'A', 'B'] c_minor = ['C', 'D', 'Eb', 'F', 'G', 'Ab', 'Bb'] a_minor = ['A', 'B', 'C', 'D', 'E', 'F', 'F#', 'G', 'G#'] c_blues_minor = ['C', 'Eb', 'F', 'F#', 'G', 'Bb'] d_minor = ['D', 'E', 'F', 'G', 'A', 'Bb', 'C'] c_gregorian = ['C', 'D', 'Eb', 'F', 'G', 'Ab', 'A', 'Bb'] current_key = c_major base_octave = 2 octave_range = 5 def __init__(self): self.csv_to_miditime() def read_csv(self, filepath): csv_file = open(filepath, 'rU') return csv.DictReader(csv_file, delimiter=',', quotechar='"') def remove_weeks(self, csv_obj): return [r for r in csv_obj if r['Date'] not in ['']] def round_to_quarter_beat(self, input): return round(input * 4) / 4 def make_notes(self, data_timed, data_key): note_list = [] start_time = data_timed[0]['beat'] for d in data_timed: note_list.append([ self.round_to_quarter_beat(d['beat'] - start_time), self.data_to_pitch_tuned(d[data_key]), 100, #mag_to_attack(d['magnitude']), # attack 1 # duration, in beats ]) return note_list def csv_to_miditime(self): raw_data = list(self.read_csv('data/bombs.csv')) filtered_data = self.remove_weeks(raw_data) self.mymidi = MIDITime(self.tempo, 'bombtest_log.mid', self.seconds_per_year, self.base_octave, self.octave_range, self.epoch) self.minimum = self.mymidi.get_data_range(filtered_data, 'Yieldnum')[0] self.maximum = self.mymidi.get_data_range(filtered_data, 'Yieldnum')[1] timed_data = [] for r in filtered_data: python_date = datetime.strptime(r["Date"], "%m/%d/%Y") days_since_epoch = self.mymidi.days_since_epoch(python_date) beat = self.mymidi.beat(days_since_epoch) timed_data.append({ 'days_since_epoch': days_since_epoch, 'beat': beat, 'BombYieldMillions': float(r['Yieldnum']) }) note_list = self.make_notes(timed_data, 'BombYieldMillions') # Add a track with those notes self.mymidi.add_track(note_list) # Output the .mid file self.mymidi.save_midi() def data_to_pitch_tuned(self, datapoint): # Where does this data point sit in the domain of your data? (I.E. the min magnitude is 3, the max in 5.6). In this case the optional 'True' means the scale is reversed, so the highest value will return the lowest percentage. #scale_pct = self.mymidi.linear_scale_pct(0, self.maximum, datapoint) # Another option: Linear scale, reverse order # scale_pct = self.mymidi.linear_scale_pct(0, self.maximum, datapoint, True) # print 10**self.maximum # Another option: Logarithmic scale, reverse order scale_pct = self.mymidi.log_scale_pct(0, self.maximum, datapoint, True, 'log') # Pick a range of notes. This allows you to play in a key. mode = self.current_key #Find the note that matches your data point note = self.mymidi.scale_to_note(scale_pct, mode) #Translate that note to a MIDI pitch midi_pitch = self.mymidi.note_to_midi_pitch(note) print scale_pct, note return midi_pitch def mag_to_attack(self, datapoint): # Where does this data point sit in the domain of your data? (I.E. the min magnitude is 3, the max in 5.6). In this case the optional 'True' means the scale is reversed, so the highest value will return the lowest percentage. scale_pct = self.mymidi.linear_scale_pct(0, self.maximum, datapoint) #max_attack = 10 adj_attack = (1 - scale_pct) * max_attack + 70 #adj_attack = 100 return adj_attack
#Translate that note to a MIDI pitch midi_pitch = mymidi.note_to_midi_pitch(note) return midi_pitch note_list = [] z_scores = stats.zscore(data_list) exp_score = [math.ceil(math.exp(x) * 4) / 4 for x in z_scores] i = 0 for d in my_data_timed: note_list.append([ d['beat'] - start_time, mag_to_pitch_tuned(d['magnitude_change']), 100, # velocity exp_score[i] # duration, in beats ]) i += 1 # Add a track with those notes mymidi.add_track(note_list) # Output the .mid file mymidi.save_midi() #sum = sum(exp_score) #softmax_score = [x / sum for x in exp_score] print(exp_score)
set_note_array(notes_arp, 2) def set_note_array(arrai, PROTOCOL): j = 0 # loop to go through all the available notes for i in arrai: rnd = random.randint(0, 2) #append notes to the note's array midinotes.append([j + rnd, i, 127, PROTOCOL]) j = j + 1 + rnd # Inicialize song song = MIDITime(BPM, output) song.add_track(midinotes) # main # Output of the MIDI data to a file.mid clean_listas() #binary streams kek f_udp = f_arp = f_dhcp = f_tcp = "" for i in range(len(udp)): f_udp += udp[i] for i in range(len(tcp)): f_tcp += tcp[i] for i in range(len(arp)): f_arp += arp[i] #start the program
def process(self): logging.info("Generating MIDI...") bpm = self.bpm bar_bpm = 8 bar_time = self.results.default_bar_size / bar_bpm midi = MIDITime(bpm, self.output_file) midi_data = [] midi_tone_data = [] curr_beat = 0 for bar in self.results.bars: tone_beat = curr_beat for note_ndx, note in bar.notes.items(): note_midi_length = bar_time * (note.length / bar.bar_size) if not note.silent: midi_data.append([ curr_beat, note.pitch + (12 if self.rich_mode else 0), 127, note_midi_length ]) curr_beat += note_midi_length if not self.rich_mode: tone_length = self.results.default_bar_size // len( bar.tones.items()) for tone_ndx, tone in bar.tones.items(): tone_midi_length = bar_time * (tone_length / bar.bar_size) midi_tone_data.append([ tone_beat, tone.get_note_index_by_octave(3), 90, tone_midi_length ]) midi_tone_data.append([ tone_beat, tone.get_note_index_by_octave(4) + 7, 90, tone_midi_length ]) if tone.type == ToneType.Dur: midi_tone_data.append([ tone_beat, tone.get_note_index_by_octave(4) + 4, 90, tone_midi_length ]) if tone.type == ToneType.Mol: midi_tone_data.append([ tone_beat, tone.get_note_index_by_octave(4) + 3, 90, tone_midi_length ]) tone_beat += tone_midi_length else: rich_tone_length = self.results.default_bar_size // 8 rich_tone_real_length = bar_time * (rich_tone_length / bar.bar_size) tone_accomp_curr = 0 rich_tone_seq_ndx = 0 while tone_accomp_curr < bar.bar_size: rich_tone = bar.get_tone_for_note_index(tone_accomp_curr) rich_tone_seq = [ rich_tone.get_note_index_by_octave(3), rich_tone.get_note_index_by_octave(4), rich_tone.get_note_index_by_octave(4) + 4 if rich_tone.type == ToneType.Dur else rich_tone.get_note_index_by_octave(4) + 3, rich_tone.get_note_index_by_octave(4) + 7, ] midi_tone_data.append([ tone_beat, rich_tone_seq[rich_tone_seq_ndx], 90, rich_tone_real_length * (len(rich_tone_seq) - rich_tone_seq_ndx) ]) rich_tone_seq_ndx = 0 if rich_tone_seq_ndx >= len( rich_tone_seq) - 1 else rich_tone_seq_ndx + 1 tone_beat += rich_tone_real_length tone_accomp_curr += rich_tone_length midi.add_track(midi_data) midi.add_track(midi_tone_data) midi.save_midi()
from miditime.miditime import MIDITime import argparse from soundParametersCreator import soundParametersCreator parser = argparse.ArgumentParser() parameters = [] creator = soundParametersCreator() args = [] # parametres of the sound are made using some strings as keys parser.add_argument('answ1', type=str) parser.add_argument('answ2', type=str) parser.add_argument('answ3', type=str) parser.add_argument('answ4', type=str) parser.add_argument('answ5', type=str) parser.add_argument('answ6', type=str) parser.add_argument('path', type=str) parser.add_argument('levelOfNarcoticness', type=int) args = parser.parse_args() parameters += creator.createParameter(args.answ1, args.levelOfNarcoticness) parameters += creator.createParameter(args.answ2, args.levelOfNarcoticness) parameters += creator.createParameter(args.answ3, args.levelOfNarcoticness) parameters += creator.createParameter(args.answ4, args.levelOfNarcoticness) parameters += creator.createParameter(args.answ5, args.levelOfNarcoticness) parameters += creator.createParameter(args.answ6, args.levelOfNarcoticness) mymidi = MIDITime(100, args.path) mymidi.add_track(parameters) mymidi.save_midi()