-
Notifications
You must be signed in to change notification settings - Fork 0
/
realize_song.rb
81 lines (67 loc) · 1.92 KB
/
realize_song.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
require 'midilib/io/seqreader'
require 'midilib/io/seqwriter'
require 'midilib'
require 'json'
require_relative "bass"
require_relative "piano"
require_relative "lead"
def add_drum_track(json,seq)
# Create a track to hold the notes. Add it to the sequence.
track = MIDI::Track.new(seq)
seq.tracks << track
fname = Dir.entries("drum_loops/").delete_if{|e| e == "." || e == ".."}.sample
seq2 = MIDI::Sequence.new()
File.open("drum_loops/"+ fname, 'rb') { | file |
seq2.read(file) { | track2, num_tracks, i |
next if !track2
16.times do |n|
track2.each do |e|
track.events << e
end
end
}
}
end
=begin
Acoustic Grand Piano
2 Bright Acoustic Piano
3 Electric Grand Piano
5 Electric Piano 1
6 Electric Piano 2
57 Trumpet
58 Trombone
60 Muted Trumpet
66 Alto Sax
67 Tenor Sax
=end
def lead_instr_rand_param
{
"rhythm_bias" => -2 + rand(5),
"noise_ratio" => 0.6 + rand(0.3),
"patch" => [57,58,66,67,0].sample
}
end
def create_song(chart_json)
# set up midi file.
seq = MIDI::Sequence.new()
#$key = 0#-12 + rand(24)
# Create a first track for the sequence. This holds tempo events and stuff
# like that.
track = MIDI::Track.new(seq)
seq.tracks << track
track.events << MIDI::Tempo.new(MIDI::Tempo.bpm_to_mpq(chart_json["tempo"]))
track.events << MIDI::MetaEvent.new(MIDI::META_SEQ_NAME, 'Sequence Name')
add_piano_track(chart_json,seq)
add_bass_track(chart_json,seq)
add_lead_track(chart_json,seq,2,lead_instr_rand_param)
#add_drum_track(chart_json,seq)
# Calling recalc_times is not necessary, because that only sets the events'
# start times, which are not written out to the MIDI file. The delta times are
# what get written out.
File.open("realized_songs/#{chart_json["name"]}.mid", 'wb') { |file| seq.write(file) }
end
Dir.entries("generated_songs/").each do |e|
next if e == "." || e == ".."
next if File.exists?("realized_songs/#{e}")
create_song(JSON::parse(File.read("generated_songs/#{e}")))
end