musicality 0.8.0 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ChangeLog.md +27 -1
- data/README.md +153 -10
- data/bin/collidify +102 -0
- data/bin/lilify +57 -29
- data/bin/midify +64 -24
- data/bin/musicality +39 -0
- data/examples/composition/auto_counterpoint.rb +4 -5
- data/examples/composition/part_generator.rb +8 -2
- data/examples/composition/scale_exercise.rb +1 -1
- data/examples/notation/notes.rb +27 -0
- data/examples/notation/parts.rb +51 -0
- data/examples/notation/scores.rb +38 -0
- data/examples/notation/twinkle.rb +34 -0
- data/examples/notation/twinkle.score +33 -0
- data/lib/musicality.rb +46 -11
- data/lib/musicality/composition/dsl/score_dsl.rb +2 -2
- data/lib/musicality/composition/dsl/score_methods.rb +10 -7
- data/lib/musicality/notation/conversion/change_conversion.rb +1 -1
- data/lib/musicality/notation/conversion/note_time_converter.rb +6 -23
- data/lib/musicality/notation/conversion/score_conversion.rb +15 -15
- data/lib/musicality/notation/conversion/score_converter.rb +50 -67
- data/lib/musicality/notation/model/articulations.rb +3 -2
- data/lib/musicality/notation/model/change.rb +15 -6
- data/lib/musicality/notation/model/dynamics.rb +11 -8
- data/lib/musicality/notation/model/instrument.rb +61 -0
- data/lib/musicality/notation/model/instruments.rb +111 -0
- data/lib/musicality/notation/model/key.rb +137 -0
- data/lib/musicality/notation/model/keys.rb +37 -0
- data/lib/musicality/notation/model/link.rb +6 -19
- data/lib/musicality/notation/model/mark.rb +43 -0
- data/lib/musicality/notation/model/marks.rb +11 -0
- data/lib/musicality/notation/model/meter.rb +4 -0
- data/lib/musicality/notation/model/note.rb +42 -28
- data/lib/musicality/notation/model/part.rb +18 -5
- data/lib/musicality/notation/model/pitch.rb +13 -4
- data/lib/musicality/notation/model/score.rb +104 -66
- data/lib/musicality/notation/model/symbols.rb +16 -11
- data/lib/musicality/notation/parsing/articulation_parsing.rb +38 -38
- data/lib/musicality/notation/parsing/articulation_parsing.treetop +14 -14
- data/lib/musicality/notation/parsing/link_parsing.rb +6 -6
- data/lib/musicality/notation/parsing/link_parsing.treetop +3 -3
- data/lib/musicality/notation/parsing/mark_parsing.rb +138 -0
- data/lib/musicality/notation/parsing/mark_parsing.treetop +31 -0
- data/lib/musicality/notation/parsing/note_node.rb +19 -12
- data/lib/musicality/notation/parsing/note_parsing.rb +218 -87
- data/lib/musicality/notation/parsing/note_parsing.treetop +9 -5
- data/lib/musicality/notation/parsing/numbers/nonnegative_integer_parsing.rb +7 -2
- data/lib/musicality/notation/parsing/numbers/nonnegative_integer_parsing.treetop +1 -1
- data/lib/musicality/notation/parsing/numbers/positive_integer_parsing.rb +6 -4
- data/lib/musicality/notation/parsing/numbers/positive_integer_parsing.treetop +1 -1
- data/lib/musicality/notation/util/function.rb +41 -18
- data/lib/musicality/packable.rb +156 -0
- data/lib/musicality/performance/conversion/glissando_converter.rb +2 -2
- data/lib/musicality/performance/conversion/note_sequence_extractor.rb +223 -70
- data/lib/musicality/performance/conversion/portamento_converter.rb +5 -2
- data/lib/musicality/performance/conversion/score_collator.rb +70 -64
- data/lib/musicality/performance/midi/midi_events.rb +3 -3
- data/lib/musicality/performance/midi/midi_settings.rb +127 -0
- data/lib/musicality/performance/midi/midi_util.rb +8 -2
- data/lib/musicality/performance/midi/part_sequencer.rb +19 -18
- data/lib/musicality/performance/midi/score_sequencer.rb +13 -9
- data/lib/musicality/performance/midi/score_sequencing.rb +5 -5
- data/lib/musicality/performance/model/attack.rb +8 -0
- data/lib/musicality/performance/model/duration_functions.rb +23 -0
- data/lib/musicality/performance/model/note_sequence.rb +52 -95
- data/lib/musicality/performance/model/separation.rb +10 -0
- data/lib/musicality/performance/supercollider/add_actions.rb +13 -0
- data/lib/musicality/performance/supercollider/bundle.rb +18 -0
- data/lib/musicality/performance/supercollider/conductor.rb +125 -0
- data/lib/musicality/performance/supercollider/group.rb +71 -0
- data/lib/musicality/performance/supercollider/message.rb +26 -0
- data/lib/musicality/performance/supercollider/node.rb +122 -0
- data/lib/musicality/performance/supercollider/performer.rb +123 -0
- data/lib/musicality/performance/supercollider/score_conducting.rb +17 -0
- data/lib/musicality/performance/supercollider/server.rb +8 -0
- data/lib/musicality/performance/supercollider/synth.rb +43 -0
- data/lib/musicality/performance/supercollider/synthdef.rb +57 -0
- data/lib/musicality/performance/supercollider/synthdef_settings.rb +23 -0
- data/lib/musicality/performance/supercollider/synthdefs.rb +1654 -0
- data/lib/musicality/{composition/model/pitch_class.rb → pitch_class.rb} +1 -1
- data/lib/musicality/{composition/model/pitch_classes.rb → pitch_classes.rb} +9 -9
- data/lib/musicality/printing/lilypond/clef.rb +12 -0
- data/lib/musicality/printing/lilypond/key_engraving.rb +9 -0
- data/lib/musicality/printing/lilypond/lilypond_settings.rb +105 -0
- data/lib/musicality/printing/lilypond/meter_engraving.rb +1 -1
- data/lib/musicality/printing/lilypond/note_engraving.rb +112 -30
- data/lib/musicality/printing/lilypond/part_engraver.rb +114 -3
- data/lib/musicality/printing/lilypond/pitch_class_engraving.rb +22 -0
- data/lib/musicality/printing/lilypond/pitch_engraving.rb +2 -15
- data/lib/musicality/printing/lilypond/score_engraver.rb +44 -73
- data/lib/musicality/printing/lilypond/score_engraving.rb +3 -3
- data/lib/musicality/project/create_tasks.rb +31 -0
- data/lib/musicality/project/file_cleaner.rb +19 -0
- data/lib/musicality/project/file_raker.rb +107 -0
- data/lib/musicality/project/load_config.rb +43 -0
- data/lib/musicality/project/project.rb +64 -0
- data/lib/musicality/version.rb +1 -1
- data/musicality.gemspec +3 -0
- data/spec/composition/util/random_sampler_spec.rb +1 -1
- data/spec/notation/conversion/measure_note_map_spec.rb +1 -1
- data/spec/notation/conversion/note_time_converter_spec.rb +5 -85
- data/spec/notation/conversion/score_conversion_spec.rb +6 -41
- data/spec/notation/conversion/score_converter_spec.rb +19 -137
- data/spec/notation/model/change_spec.rb +55 -0
- data/spec/notation/model/key_spec.rb +171 -0
- data/spec/notation/model/link_spec.rb +34 -5
- data/spec/notation/model/meter_spec.rb +15 -0
- data/spec/notation/model/note_spec.rb +33 -27
- data/spec/notation/model/part_spec.rb +53 -4
- data/spec/notation/model/pitch_spec.rb +15 -0
- data/spec/notation/model/score_spec.rb +64 -72
- data/spec/notation/parsing/link_nodes_spec.rb +3 -3
- data/spec/notation/parsing/link_parsing_spec.rb +6 -6
- data/spec/notation/parsing/note_node_spec.rb +34 -9
- data/spec/notation/parsing/note_parsing_spec.rb +11 -9
- data/spec/notation/parsing/numbers/nonnegative_integer_spec.rb +4 -0
- data/spec/notation/parsing/pitch_node_spec.rb +0 -1
- data/spec/notation/util/value_computer_spec.rb +2 -2
- data/spec/performance/conversion/glissando_converter_spec.rb +9 -9
- data/spec/performance/conversion/note_sequence_extractor_spec.rb +48 -53
- data/spec/performance/conversion/portamento_converter_spec.rb +11 -9
- data/spec/performance/conversion/score_collator_spec.rb +59 -63
- data/spec/performance/midi/midi_util_spec.rb +22 -8
- data/spec/performance/midi/part_sequencer_spec.rb +2 -2
- data/spec/performance/midi/score_sequencer_spec.rb +12 -10
- data/spec/performance/midi/score_sequencing_spec.rb +2 -2
- data/spec/performance/model/note_sequence_spec.rb +41 -134
- data/spec/printing/note_engraving_spec.rb +204 -0
- data/spec/printing/score_engraver_spec.rb +40 -0
- data/spec/spec_helper.rb +1 -0
- metadata +69 -23
- data/examples/notation/hip.rb +0 -32
- data/examples/notation/missed_connection.rb +0 -26
- data/examples/notation/song1.rb +0 -33
- data/examples/notation/song2.rb +0 -32
- data/lib/musicality/notation/model/links.rb +0 -11
- data/lib/musicality/notation/packing/change_packing.rb +0 -56
- data/lib/musicality/notation/packing/part_packing.rb +0 -31
- data/lib/musicality/notation/packing/score_packing.rb +0 -123
- data/lib/musicality/performance/model/note_attacks.rb +0 -19
- data/lib/musicality/performance/util/note_linker.rb +0 -28
- data/spec/notation/packing/change_packing_spec.rb +0 -304
- data/spec/notation/packing/part_packing_spec.rb +0 -66
- data/spec/notation/packing/score_packing_spec.rb +0 -255
- data/spec/performance/util/note_linker_spec.rb +0 -68
data/bin/midify
CHANGED
@@ -3,25 +3,29 @@
|
|
3
3
|
exe_name = File.basename(__FILE__)
|
4
4
|
|
5
5
|
doc = <<DOCOPT
|
6
|
-
Loads a musicality score from YAML file, and converts it to
|
6
|
+
Loads a musicality score from YAML file, and converts it to one or more MIDI
|
7
|
+
files. If no part names are given, all score parts are selected for MIDI
|
8
|
+
sequencing. Otherwise, only the given parts names will be selected. By default,
|
9
|
+
a single engraving file will be produced. If the --split flag is used, a file
|
10
|
+
will be produced for each part. If --outdir is not given, files will be put in
|
11
|
+
the same directory as the score file.
|
7
12
|
|
8
13
|
Usage:
|
9
|
-
#{exe_name}
|
14
|
+
#{exe_name} SCORE [PART]... [options]
|
10
15
|
#{exe_name} -h | --help
|
11
16
|
#{exe_name} --version
|
12
17
|
|
13
18
|
Arguments:
|
14
|
-
|
15
|
-
PART name of a part in the score
|
16
|
-
|
17
|
-
|
19
|
+
SCORE A musicality score file (may be packed as a hash) in a YAML file
|
20
|
+
PART name of a part in the score (e.g. "lhand")
|
21
|
+
|
18
22
|
Options:
|
23
|
+
--split Make separate files for each part
|
24
|
+
--outdir=OUTD Dir where files will be put (defaults to same dir as score file)
|
19
25
|
--srate=SRATE sampling rate for converting tempo-based score to time-based
|
20
26
|
score, and for sampling dynamic change values [default: 200]
|
21
27
|
-h --help Show this screen.
|
22
28
|
--version Show version.
|
23
|
-
--outfile=OUTF Name of output MIDI file
|
24
|
-
|
25
29
|
DOCOPT
|
26
30
|
|
27
31
|
require 'docopt'
|
@@ -40,16 +44,34 @@ if args["--version"]
|
|
40
44
|
exit
|
41
45
|
end
|
42
46
|
|
47
|
+
SCORE_FILE = args["SCORE"]
|
48
|
+
unless File.exists? SCORE_FILE
|
49
|
+
puts "Score file #{SCORE_FILE} does not exist. Aborting."
|
50
|
+
exit
|
51
|
+
end
|
52
|
+
|
53
|
+
if args["--outdir"]
|
54
|
+
OUTDIR = args["--outdir"]
|
55
|
+
unless Dir.exists? OUTDIR
|
56
|
+
puts "Output directory #{OUTDIR} does not exist. Aborting."
|
57
|
+
exit
|
58
|
+
end
|
59
|
+
else
|
60
|
+
OUTDIR = File.dirname(SCORE_FILE)
|
61
|
+
end
|
62
|
+
|
63
|
+
PARTS = args["PART"]
|
64
|
+
SPLIT = args["--split"]
|
65
|
+
|
43
66
|
require 'yaml'
|
44
67
|
include Musicality
|
45
68
|
|
46
|
-
|
47
|
-
|
48
|
-
print "Reading file '#{fin_name}'..."
|
69
|
+
File.open(SCORE_FILE) do |fin|
|
70
|
+
print "Reading file '#{SCORE_FILE}'..."
|
49
71
|
score = YAML.load(fin.read)
|
50
72
|
|
51
73
|
if score.is_a? Hash
|
52
|
-
score =
|
74
|
+
score = score.unpack
|
53
75
|
end
|
54
76
|
puts "done"
|
55
77
|
|
@@ -60,22 +82,40 @@ File.open(fin_name) do |fin|
|
|
60
82
|
end
|
61
83
|
|
62
84
|
if score.valid?
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
85
|
+
if PARTS.any?
|
86
|
+
selected_parts = PARTS
|
87
|
+
else
|
88
|
+
selected_parts = score.parts.keys
|
89
|
+
end
|
90
|
+
|
67
91
|
print "Making MIDI sequence..."
|
68
92
|
sequencer = ScoreSequencer.new(score)
|
69
|
-
|
93
|
+
outfiles = {}
|
94
|
+
|
95
|
+
if SPLIT
|
96
|
+
selected_parts.each do |selected_part|
|
97
|
+
outfiles[selected_part] = sequencer.make_midi_seq([selected_part])
|
98
|
+
end
|
99
|
+
else
|
100
|
+
outfiles[""] = sequencer.make_midi_seq(selected_parts)
|
101
|
+
end
|
70
102
|
puts "done"
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
103
|
+
|
104
|
+
# part_names = args["PART"]
|
105
|
+
# program_nums = args["PROGRAM"].map {|str| str.to_i }
|
106
|
+
# instr_map = Hash[[part_names,program_nums].transpose]
|
107
|
+
|
108
|
+
base_fout_name = "#{OUTDIR}/#{File.basename(SCORE_FILE,File.extname(SCORE_FILE))}"
|
109
|
+
outfiles.each do |outfile, seq|
|
110
|
+
if outfile.empty?
|
111
|
+
fout_name = "#{base_fout_name}.mid"
|
112
|
+
else
|
113
|
+
fout_name = "#{base_fout_name}_#{outfile}.mid"
|
114
|
+
end
|
115
|
+
print "Writing MIDI file '#{fout_name}'..."
|
116
|
+
File.open(fout_name, 'wb'){ |fout| seq.write(fout) }
|
117
|
+
puts "done"
|
75
118
|
end
|
76
|
-
print "Writing MIDI file '#{fout_name}'..."
|
77
|
-
File.open(fout_name, 'wb'){ |fout| seq.write(fout) }
|
78
|
-
puts "done"
|
79
119
|
else
|
80
120
|
puts "Score is not valid. See errors:"
|
81
121
|
puts score.errors.join("\n")
|
data/bin/musicality
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
exe_name = File.basename(__FILE__)
|
4
|
+
|
5
|
+
doc = <<DOCOPT
|
6
|
+
The 'new' subcommand wll create a new musicality project.
|
7
|
+
|
8
|
+
Usage:
|
9
|
+
#{exe_name} new PROJECT_DIR [options]
|
10
|
+
#{exe_name} -h | --help
|
11
|
+
#{exe_name} --version
|
12
|
+
|
13
|
+
Arguments:
|
14
|
+
PROJECT_DIR Path of an empty directory or directory to be created
|
15
|
+
|
16
|
+
Options:
|
17
|
+
-h --help Show this screen.
|
18
|
+
--version Show version.
|
19
|
+
DOCOPT
|
20
|
+
|
21
|
+
require 'docopt'
|
22
|
+
begin
|
23
|
+
args = Docopt::docopt(doc)
|
24
|
+
puts args
|
25
|
+
rescue Docopt::Exit => e
|
26
|
+
puts e.message
|
27
|
+
exit
|
28
|
+
end
|
29
|
+
|
30
|
+
require 'musicality'
|
31
|
+
|
32
|
+
if args["--version"]
|
33
|
+
puts "#{exe_name} in musicality v#{Musicality::VERSION}"
|
34
|
+
exit
|
35
|
+
end
|
36
|
+
|
37
|
+
if args["new"]
|
38
|
+
Musicality::Project.new(args["PROJECT_DIR"])
|
39
|
+
end
|
@@ -5,8 +5,8 @@ include Pitches
|
|
5
5
|
bass_pitch_palette = [ C2, D2, E2, F2, G2, A2, B2, C3 ]
|
6
6
|
guitar_pitch_palette = [ C3, D3, E3, F3, G3, A3, B3, C4 ]
|
7
7
|
|
8
|
-
bass = Part.new(Dynamics::MF)
|
9
|
-
guitar = Part.new(Dynamics::MF)
|
8
|
+
bass = Part.new(Dynamics::MF, settings: [MidiSettings::ELECTRIC_BASS_FINGER])
|
9
|
+
guitar = Part.new(Dynamics::MF, settings: [MidiSettings::ELECTRIC_GUITAR_JAZZ])
|
10
10
|
|
11
11
|
def random_melody rhythm, pitch_palette
|
12
12
|
pitches = pitch_palette.sample(rand(2..pitch_palette.size))
|
@@ -43,11 +43,10 @@ end
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
-
score = Score::
|
46
|
+
score = Score::Tempo.new(Meters::FOUR_FOUR, 120,
|
47
47
|
parts: { "bass" => bass, "guitar" => guitar },
|
48
48
|
program: [ 0...([bass.duration,guitar.duration].min) ]
|
49
49
|
)
|
50
50
|
|
51
|
-
|
52
|
-
seq = ScoreSequencer.new(score.to_timed(200)).make_midi_seq(instr_map)
|
51
|
+
seq = ScoreSequencer.new(score.to_timed(200)).make_midi_seq
|
53
52
|
File.open("./auto_counterpoint.mid", 'wb'){ |fout| seq.write(fout) }
|
@@ -16,8 +16,10 @@ end
|
|
16
16
|
|
17
17
|
rhythm_seq2 = RepeatingSequence.new([3/8.to_r]*4)
|
18
18
|
|
19
|
-
score = Score::
|
19
|
+
score = Score::Tempo.new(SIX_EIGHT,90) do |s|
|
20
20
|
s.parts["main"] = Part.new(Dynamics::MF) do |p|
|
21
|
+
p.settings.push MidiSettings::LEAD_SAWTOOTH
|
22
|
+
|
21
23
|
rhythm_seq = RepeatingSequence.new(([1/8.to_r]*3)*3 + [1/4.to_r,1/8.to_r])
|
22
24
|
selector = RepeatingSequence.new([4,2,0])
|
23
25
|
rhythm = rhythm_seq.take(pitch_seqs.size * rhythm_seq.pattern_size).to_a
|
@@ -27,6 +29,8 @@ score = Score::Measured.new(SIX_EIGHT,90) do |s|
|
|
27
29
|
end
|
28
30
|
|
29
31
|
s.parts["bass"] = Part.new(Dynamics::MP) do |p|
|
32
|
+
p.settings.push MidiSettings::LEAD_SQUARE
|
33
|
+
|
30
34
|
rhythm_seq = RepeatingSequence.new([3/8.to_r]*4)
|
31
35
|
selector = RepeatingSequence.new([-7])
|
32
36
|
rhythm = rhythm_seq.take(pitch_seqs.size * rhythm_seq.pattern_size).to_a
|
@@ -36,6 +40,8 @@ score = Score::Measured.new(SIX_EIGHT,90) do |s|
|
|
36
40
|
end
|
37
41
|
|
38
42
|
s.parts["pluck"] = Part.new(Dynamics::MP) do |p|
|
43
|
+
p.settings.push MidiSettings::ORCHESTRAL_HARP
|
44
|
+
|
39
45
|
rhythm_seq = RepeatingSequence.new(([1/8.to_r]*3)*4)
|
40
46
|
selector = RepeatingSequence.new([0,2,4])
|
41
47
|
rhythm = rhythm_seq.take(pitch_seqs.size * rhythm_seq.pattern_size).to_a
|
@@ -47,5 +53,5 @@ score = Score::Measured.new(SIX_EIGHT,90) do |s|
|
|
47
53
|
s.program = [0...s.measures_long]*2
|
48
54
|
end
|
49
55
|
|
50
|
-
seq = ScoreSequencer.new(score.to_timed(200)).make_midi_seq
|
56
|
+
seq = ScoreSequencer.new(score.to_timed(200)).make_midi_seq
|
51
57
|
File.open("./part_generator.mid", 'wb'){ |fout| seq.write(fout) }
|
@@ -26,7 +26,7 @@ def scale_exercise scale_class, base_pitch, rhythm
|
|
26
26
|
return notes
|
27
27
|
end
|
28
28
|
|
29
|
-
score = Score::
|
29
|
+
score = Score::Tempo.new(FOUR_FOUR,120) do |s|
|
30
30
|
s.parts["scale"] = Part.new(Dynamics::MP) do |p|
|
31
31
|
Heptatonic::Prima::MODES.each do |mode_n,scale_class|
|
32
32
|
[[1/4.to_r,1/4.to_r,1/2.to_r]].each do |rhythm|
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'musicality'
|
2
|
+
include Musicality
|
3
|
+
include Pitches
|
4
|
+
|
5
|
+
#
|
6
|
+
# convenience methods for common durations
|
7
|
+
#
|
8
|
+
single = Note.quarter(Ab4)
|
9
|
+
rest = Note.quarter
|
10
|
+
chord = Note.whole([C3,E3,G3])
|
11
|
+
|
12
|
+
#
|
13
|
+
# specific duration + articulation
|
14
|
+
#
|
15
|
+
note = Note.new(Rational(7,8), Bb3, articulation: Articulations::STACCATO)
|
16
|
+
puts note.to_s # => "7/8Bb3."
|
17
|
+
|
18
|
+
#
|
19
|
+
# magic!
|
20
|
+
#
|
21
|
+
puts note.transpose(2).to_s # => "7/8C4."
|
22
|
+
|
23
|
+
#
|
24
|
+
# create notes from a compact syntax
|
25
|
+
#
|
26
|
+
notes = "/4C3 /4D3 /2E3,G3,B3".to_notes
|
27
|
+
puts notes.join(" ") # => "/4C3 /4D3 /2E3,G3,B3"
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'musicality'
|
2
|
+
include Musicality
|
3
|
+
include Pitches
|
4
|
+
include Dynamics
|
5
|
+
|
6
|
+
|
7
|
+
#
|
8
|
+
# Building up a part piece-by-piece
|
9
|
+
#
|
10
|
+
|
11
|
+
# an empty part with no notes and default dynamic (loudness)
|
12
|
+
p = Part.new(MP)
|
13
|
+
|
14
|
+
# add some notes
|
15
|
+
p.notes += "/4C3 /4D3 /2E3,G3,B3".to_notes * 2
|
16
|
+
|
17
|
+
# add dynamic changes
|
18
|
+
p.dynamic_changes[0.5] = Change::Gradual.linear(FF, 0.5)
|
19
|
+
p.dynamic_changes[1] = Change::Immediate.new(MP)
|
20
|
+
|
21
|
+
# Add custom settings for LilyPond engraving
|
22
|
+
p.settings.push LilypondSettings::CLARINET
|
23
|
+
|
24
|
+
# Add custom settings for MIDI conversion
|
25
|
+
p.settings.push MidiSettings::CLARINET
|
26
|
+
|
27
|
+
|
28
|
+
#
|
29
|
+
# Using block initialization to do the same
|
30
|
+
#
|
31
|
+
|
32
|
+
p = Part.new(MP) do |p|
|
33
|
+
p.notes += "/4C3 /4D3 /2E3,G3,B3".to_notes * 2
|
34
|
+
p.dynamic_changes[0.5] = Change::Gradual.linear(FF, 0.5)
|
35
|
+
p.dynamic_changes[1] = Change::Immediate.new(MP)
|
36
|
+
p.settings.push LilypondSettings::CLARINET
|
37
|
+
p.settings.push MidiSettings::CLARINET
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
#
|
42
|
+
# Passing all the pieces as keyword parameters
|
43
|
+
#
|
44
|
+
p = Part.new(MP,
|
45
|
+
notes: "/4C3 /4D3 /2E3,G3,B3".to_notes * 2,
|
46
|
+
dynamic_changes: {
|
47
|
+
0.5 => Change::Gradual.linear(FF, 0.5),
|
48
|
+
1.0 => Change::Immediate.new(MP)
|
49
|
+
},
|
50
|
+
settings: [ LilypondSettings::CLARINET, MidiSettings::CLARINET ]
|
51
|
+
)
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'musicality'
|
2
|
+
include Musicality
|
3
|
+
include Pitches
|
4
|
+
include Dynamics
|
5
|
+
include Keys
|
6
|
+
include Meters
|
7
|
+
|
8
|
+
#
|
9
|
+
# Basics of creating a score from scratch
|
10
|
+
#
|
11
|
+
|
12
|
+
# minimum score, with no parts
|
13
|
+
s = Score::Tempo.new(FOUR_FOUR, 120)
|
14
|
+
|
15
|
+
# add a part
|
16
|
+
s.parts["piano"] = Part.new(MP) do |p|
|
17
|
+
p.notes = q(C4,C4,G4,G4,A4,A4) + h(G4) +
|
18
|
+
q(F4,F4,E4,E4,D4,D4) + h(C4)
|
19
|
+
end
|
20
|
+
|
21
|
+
# add a key and tempo change
|
22
|
+
s.key_changes[s.measures_long] = Change::Immediate.new(D_MAJOR)
|
23
|
+
s.tempo_changes[s.measures_long] = Change::Immediate.new(140)
|
24
|
+
s.parts["piano"].notes += transpose(s.parts["piano"].notes, 2)
|
25
|
+
|
26
|
+
|
27
|
+
#
|
28
|
+
# Score conversion
|
29
|
+
#
|
30
|
+
|
31
|
+
# Convert tempo-based score to time-based
|
32
|
+
s.to_timed(200) # requires tempo sampling rate
|
33
|
+
|
34
|
+
# Engrave the score using LilyPond
|
35
|
+
puts s.to_lilypond
|
36
|
+
|
37
|
+
# Convert the score to a MIDI file
|
38
|
+
s.to_midi_seq(200)
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'musicality'
|
2
|
+
include Musicality
|
3
|
+
include Meters
|
4
|
+
include Dynamics
|
5
|
+
include Pitches
|
6
|
+
|
7
|
+
score = Score::Tempo.new(FOUR_FOUR, 120, title: "Twinkle, Twinkle, Little Star") do |s|
|
8
|
+
s.parts["rhand"] = Part.new(MF) do |p|
|
9
|
+
a_notes = q(C4,C4,G4,G4,A4,A4) + h(G4) +
|
10
|
+
q(F4,F4,E4,E4,D4,D4) + h(C4)
|
11
|
+
b_notes = q(G4,G4,F4,F4,E4,E4) + h(D4)
|
12
|
+
p.notes += a_notes + b_notes
|
13
|
+
end
|
14
|
+
|
15
|
+
s.parts["lhand"] = Part.new(MF) do |p|
|
16
|
+
Cmaj = [C3,E3,G3]
|
17
|
+
Fmaj = [F2,A2,C3]
|
18
|
+
Gmaj = [G2,B2,D3]
|
19
|
+
|
20
|
+
a_chords = h(Cmaj,Cmaj,Fmaj,Cmaj) +
|
21
|
+
h(Fmaj,Cmaj,Gmaj,Cmaj)
|
22
|
+
b_chords = h(Cmaj,Fmaj,Cmaj,Gmaj)
|
23
|
+
p.notes += a_chords + b_chords
|
24
|
+
end
|
25
|
+
|
26
|
+
s.program.push 0...4
|
27
|
+
s.program.push 4...6
|
28
|
+
s.program.push 4...6
|
29
|
+
s.program.push 0...4
|
30
|
+
end
|
31
|
+
|
32
|
+
File.open('twinkle.ly','w'){|f| f.write(score.to_lilypond) }
|
33
|
+
File.open('twinkle.mid','wb'){|f| score.to_midi_seq(200).write(f) }
|
34
|
+
score.to_osc(200,'twinkle')
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# run me with the following ruby code:
|
2
|
+
# require 'musicality'
|
3
|
+
# include Musicality
|
4
|
+
# include Pitches
|
5
|
+
# ScoreDSL.load('twinkle.score')
|
6
|
+
|
7
|
+
tempo_score Meters::FOUR_FOUR, 120 do
|
8
|
+
title "Twinkle, Twinkle, Little Star"
|
9
|
+
|
10
|
+
Cmaj = [C3,E3,G3]
|
11
|
+
Fmaj = [F2,A2,C3]
|
12
|
+
Gmaj = [G2,B2,D3]
|
13
|
+
section "A" do
|
14
|
+
notes(
|
15
|
+
"rhand" => q(C4,C4,G4,G4,A4,A4) + h(G4) +
|
16
|
+
q(F4,F4,E4,E4,D4,D4) + h(C4),
|
17
|
+
"lhand" => h(Cmaj,Cmaj,Fmaj,Cmaj) +
|
18
|
+
h(Fmaj,Cmaj,Gmaj,Cmaj)
|
19
|
+
)
|
20
|
+
end
|
21
|
+
|
22
|
+
section "B" do
|
23
|
+
notes(
|
24
|
+
"rhand" => q(G4,G4,F4,F4,E4,E4) + h(D4),
|
25
|
+
"lhand" => h(Cmaj,Fmaj,Cmaj,Gmaj)
|
26
|
+
)
|
27
|
+
end
|
28
|
+
repeat "B"
|
29
|
+
repeat "A"
|
30
|
+
end
|
31
|
+
|
32
|
+
File.open('twinkle.ly','w'){|f| f.write(score.to_lilypond) }
|
33
|
+
File.open('twinkle.mid','wb'){|f| score.to_midi_seq(200).write(f) }
|
data/lib/musicality.rb
CHANGED
@@ -1,24 +1,31 @@
|
|
1
1
|
# basic core classes
|
2
2
|
require 'musicality/version'
|
3
|
+
require 'musicality/packable'
|
3
4
|
require 'musicality/validatable'
|
4
5
|
require 'musicality/errors'
|
5
6
|
|
7
|
+
require 'musicality/pitch_class'
|
8
|
+
require 'musicality/pitch_classes'
|
9
|
+
|
6
10
|
#
|
7
11
|
# Notation
|
8
12
|
#
|
9
13
|
|
10
14
|
require 'musicality/notation/model/pitch'
|
11
15
|
require 'musicality/notation/model/pitches'
|
12
|
-
require 'musicality/notation/model/links'
|
13
16
|
require 'musicality/notation/model/articulations'
|
14
|
-
require 'musicality/notation/model/symbols'
|
15
17
|
require 'musicality/notation/model/link'
|
18
|
+
require 'musicality/notation/model/mark'
|
19
|
+
require 'musicality/notation/model/marks'
|
20
|
+
require 'musicality/notation/model/symbols'
|
16
21
|
require 'musicality/notation/model/note'
|
17
22
|
require 'musicality/notation/model/dynamics'
|
18
23
|
require 'musicality/notation/model/change'
|
19
24
|
require 'musicality/notation/model/part'
|
20
25
|
require 'musicality/notation/model/meter'
|
21
26
|
require 'musicality/notation/model/meters'
|
27
|
+
require 'musicality/notation/model/key'
|
28
|
+
require 'musicality/notation/model/keys'
|
22
29
|
require 'musicality/notation/model/score'
|
23
30
|
|
24
31
|
require 'treetop'
|
@@ -35,6 +42,7 @@ require 'musicality/notation/parsing/duration_nodes'
|
|
35
42
|
require 'musicality/notation/parsing/articulation_parsing'
|
36
43
|
require 'musicality/notation/parsing/link_parsing'
|
37
44
|
require 'musicality/notation/parsing/link_nodes'
|
45
|
+
require 'musicality/notation/parsing/mark_parsing'
|
38
46
|
require 'musicality/notation/parsing/note_parsing'
|
39
47
|
require 'musicality/notation/parsing/note_node'
|
40
48
|
require 'musicality/notation/parsing/meter_parsing'
|
@@ -42,10 +50,6 @@ require 'musicality/notation/parsing/segment_parsing'
|
|
42
50
|
require 'musicality/notation/parsing/parseable'
|
43
51
|
require 'musicality/notation/parsing/convenience_methods'
|
44
52
|
|
45
|
-
require 'musicality/notation/packing/change_packing'
|
46
|
-
require 'musicality/notation/packing/part_packing'
|
47
|
-
require 'musicality/notation/packing/score_packing'
|
48
|
-
|
49
53
|
require 'musicality/notation/util/interpolation'
|
50
54
|
require 'musicality/notation/util/function'
|
51
55
|
require 'musicality/notation/util/piecewise_function'
|
@@ -71,8 +75,6 @@ require 'musicality/composition/util/random_sampler'
|
|
71
75
|
require 'musicality/composition/util/probabilities'
|
72
76
|
require 'musicality/composition/util/note_generation'
|
73
77
|
|
74
|
-
require 'musicality/composition/model/pitch_class'
|
75
|
-
require 'musicality/composition/model/pitch_classes'
|
76
78
|
require 'musicality/composition/model/scale'
|
77
79
|
require 'musicality/composition/model/scale_class'
|
78
80
|
require 'musicality/composition/model/scale_classes'
|
@@ -89,11 +91,12 @@ require 'musicality/composition/convenience_methods'
|
|
89
91
|
# Performance
|
90
92
|
#
|
91
93
|
|
92
|
-
require 'musicality/performance/model/
|
94
|
+
require 'musicality/performance/model/attack'
|
95
|
+
require 'musicality/performance/model/separation'
|
96
|
+
require 'musicality/performance/model/duration_functions'
|
93
97
|
require 'musicality/performance/model/note_sequence'
|
94
98
|
|
95
99
|
require 'musicality/performance/util/optimization'
|
96
|
-
require 'musicality/performance/util/note_linker'
|
97
100
|
|
98
101
|
require 'musicality/performance/conversion/glissando_converter'
|
99
102
|
require 'musicality/performance/conversion/portamento_converter'
|
@@ -103,17 +106,49 @@ require 'musicality/performance/conversion/score_collator'
|
|
103
106
|
require 'midilib'
|
104
107
|
require 'musicality/performance/midi/midi_util'
|
105
108
|
require 'musicality/performance/midi/midi_events'
|
109
|
+
require 'musicality/performance/midi/midi_settings'
|
106
110
|
require 'musicality/performance/midi/part_sequencer'
|
107
111
|
require 'musicality/performance/midi/score_sequencer'
|
108
112
|
require 'musicality/performance/midi/score_sequencing'
|
109
113
|
|
114
|
+
require 'musicality/performance/supercollider/message'
|
115
|
+
require 'musicality/performance/supercollider/bundle'
|
116
|
+
require 'musicality/performance/supercollider/server'
|
117
|
+
require 'musicality/performance/supercollider/add_actions'
|
118
|
+
require 'musicality/performance/supercollider/node'
|
119
|
+
require 'musicality/performance/supercollider/synth'
|
120
|
+
require 'musicality/performance/supercollider/group'
|
121
|
+
require 'musicality/performance/supercollider/synthdef'
|
122
|
+
require 'musicality/performance/supercollider/synthdefs'
|
123
|
+
require 'musicality/performance/supercollider/performer'
|
124
|
+
require 'musicality/performance/supercollider/conductor'
|
125
|
+
require 'musicality/performance/supercollider/score_conducting'
|
126
|
+
|
110
127
|
#
|
111
128
|
# Printing
|
112
129
|
#
|
113
130
|
|
114
131
|
require 'musicality/printing/lilypond/errors'
|
132
|
+
require 'musicality/printing/lilypond/pitch_class_engraving'
|
115
133
|
require 'musicality/printing/lilypond/pitch_engraving'
|
116
134
|
require 'musicality/printing/lilypond/note_engraving'
|
117
135
|
require 'musicality/printing/lilypond/meter_engraving'
|
136
|
+
require 'musicality/printing/lilypond/key_engraving'
|
137
|
+
require 'musicality/printing/lilypond/clef'
|
138
|
+
require 'musicality/printing/lilypond/lilypond_settings'
|
139
|
+
require 'musicality/printing/lilypond/part_engraver'
|
118
140
|
require 'musicality/printing/lilypond/score_engraver'
|
119
|
-
require 'musicality/printing/lilypond/score_engraving'
|
141
|
+
require 'musicality/printing/lilypond/score_engraving'
|
142
|
+
|
143
|
+
#
|
144
|
+
# Project
|
145
|
+
#
|
146
|
+
|
147
|
+
require 'rake'
|
148
|
+
require 'yaml'
|
149
|
+
require 'rake/tasklib'
|
150
|
+
require 'musicality/project/file_raker'
|
151
|
+
require 'musicality/project/file_cleaner'
|
152
|
+
require 'musicality/project/project'
|
153
|
+
require 'musicality/project/load_config'
|
154
|
+
require 'musicality/project/create_tasks'
|