brevity 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.document +3 -0
- data/.gitignore +7 -0
- data/.rspec +1 -0
- data/.ruby-version +1 -0
- data/.yardopts +1 -0
- data/ChangeLog.rdoc +4 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +27 -0
- data/Rakefile +67 -0
- data/bin/debrief +56 -0
- data/brevity.gemspec +28 -0
- data/examples/alley_cat.br +50 -0
- data/examples/hip.br +15 -0
- data/examples/missed_connection.br +6 -0
- data/examples/song1.br +11 -0
- data/examples/song2.br +10 -0
- data/examples/twinkle.br +18 -0
- data/lib/brevity/commands/constants.rb +18 -0
- data/lib/brevity/commands/expr.rb +17 -0
- data/lib/brevity/commands/meter.rb +20 -0
- data/lib/brevity/commands/part.rb +47 -0
- data/lib/brevity/commands/tempo.rb +13 -0
- data/lib/brevity/itemization.rb +73 -0
- data/lib/brevity/parsing/expression/dynamic.rb +280 -0
- data/lib/brevity/parsing/expression/dynamic.treetop +41 -0
- data/lib/brevity/parsing/expression/dynamic_nodes.rb +55 -0
- data/lib/brevity/parsing/expression/expression.rb +429 -0
- data/lib/brevity/parsing/expression/expression.treetop +39 -0
- data/lib/brevity/parsing/expression/expression_nodes.rb +26 -0
- data/lib/brevity/parsing/expression/gradual.rb +44 -0
- data/lib/brevity/parsing/expression/gradual.treetop +9 -0
- data/lib/brevity/parsing/expression/gradual_node.rb +11 -0
- data/lib/brevity/parsing/expression/label.rb +75 -0
- data/lib/brevity/parsing/expression/label.treetop +9 -0
- data/lib/brevity/parsing/expression/label_node.rb +15 -0
- data/lib/brevity/parsing/expression/sequence.rb +130 -0
- data/lib/brevity/parsing/expression/sequence.treetop +12 -0
- data/lib/brevity/parsing/expression/sequence_node.rb +14 -0
- data/lib/brevity/parsing/file/command.rb +216 -0
- data/lib/brevity/parsing/file/command.treetop +17 -0
- data/lib/brevity/parsing/file/command_node.rb +11 -0
- data/lib/brevity/parsing/file/comment.rb +178 -0
- data/lib/brevity/parsing/file/comment.treetop +21 -0
- data/lib/brevity/parsing/file/comment_node.rb +3 -0
- data/lib/brevity/parsing/file/file.rb +152 -0
- data/lib/brevity/parsing/file/file.treetop +16 -0
- data/lib/brevity/parsing/file/file_node.rb +7 -0
- data/lib/brevity/parsing/file/path.rb +235 -0
- data/lib/brevity/parsing/file/path.treetop +12 -0
- data/lib/brevity/parsing/modifiers/duplicate_modifier.rb +65 -0
- data/lib/brevity/parsing/modifiers/duplicate_modifier.treetop +11 -0
- data/lib/brevity/parsing/modifiers/duplicate_modifier_node.rb +8 -0
- data/lib/brevity/parsing/modifiers/modifier.rb +64 -0
- data/lib/brevity/parsing/modifiers/modifier.treetop +13 -0
- data/lib/brevity/parsing/modifiers/stretch_modifier.rb +69 -0
- data/lib/brevity/parsing/modifiers/stretch_modifier.treetop +11 -0
- data/lib/brevity/parsing/modifiers/stretch_modifier_node.rb +21 -0
- data/lib/brevity/parsing/modifiers/transpose_modifier.rb +69 -0
- data/lib/brevity/parsing/modifiers/transpose_modifier.treetop +11 -0
- data/lib/brevity/parsing/modifiers/transpose_modifier_node.rb +13 -0
- data/lib/brevity/parsing/note/accent.rb +44 -0
- data/lib/brevity/parsing/note/accent.treetop +9 -0
- data/lib/brevity/parsing/note/duration.rb +203 -0
- data/lib/brevity/parsing/note/duration.treetop +23 -0
- data/lib/brevity/parsing/note/duration_nodes.rb +19 -0
- data/lib/brevity/parsing/note/link.rb +69 -0
- data/lib/brevity/parsing/note/link.treetop +11 -0
- data/lib/brevity/parsing/note/link_node.rb +19 -0
- data/lib/brevity/parsing/note/note.rb +300 -0
- data/lib/brevity/parsing/note/note.treetop +30 -0
- data/lib/brevity/parsing/note/note_nodes.rb +77 -0
- data/lib/brevity/parsing/note/pitch.rb +81 -0
- data/lib/brevity/parsing/note/pitch.treetop +9 -0
- data/lib/brevity/parsing/note/pitch_node.rb +50 -0
- data/lib/brevity/parsing/numbers/nonnegative_integer.rb +53 -0
- data/lib/brevity/parsing/numbers/nonnegative_integer.treetop +9 -0
- data/lib/brevity/parsing/numbers/positive_integer.rb +91 -0
- data/lib/brevity/parsing/numbers/positive_integer.treetop +15 -0
- data/lib/brevity/read_file.rb +18 -0
- data/lib/brevity/score_maker.rb +64 -0
- data/lib/brevity/version.rb +4 -0
- data/lib/brevity.rb +53 -0
- data/manuals/brevity.pdf +0 -0
- data/manuals/brevity.tex +273 -0
- data/spec/brevity_spec.rb +8 -0
- data/spec/commands/expr_spec.rb +15 -0
- data/spec/commands/meter_spec.rb +21 -0
- data/spec/commands/part_spec.rb +16 -0
- data/spec/commands/tempo_spec.rb +20 -0
- data/spec/itemization_spec.rb +46 -0
- data/spec/parsing/expression/dynamic_nodes_spec.rb +32 -0
- data/spec/parsing/expression/dynamic_spec.rb +23 -0
- data/spec/parsing/expression/expression_nodes_spec.rb +87 -0
- data/spec/parsing/expression/expression_spec.rb +85 -0
- data/spec/parsing/expression/gradual_spec.rb +10 -0
- data/spec/parsing/expression/label_node_spec.rb +13 -0
- data/spec/parsing/expression/label_spec.rb +35 -0
- data/spec/parsing/file/command_node_spec.rb +29 -0
- data/spec/parsing/file/command_spec.rb +18 -0
- data/spec/parsing/file/comment_spec.rb +14 -0
- data/spec/parsing/file/file_node_spec.rb +19 -0
- data/spec/parsing/file/file_spec.rb +30 -0
- data/spec/parsing/modifiers/modifier_nodes_spec.rb +25 -0
- data/spec/parsing/modifiers/modifier_parsers_spec.rb +20 -0
- data/spec/parsing/note/accent_spec.rb +27 -0
- data/spec/parsing/note/duration_nodes_spec.rb +79 -0
- data/spec/parsing/note/duration_spec.rb +69 -0
- data/spec/parsing/note/link_node_spec.rb +30 -0
- data/spec/parsing/note/link_spec.rb +23 -0
- data/spec/parsing/note/note_nodes_spec.rb +82 -0
- data/spec/parsing/note/note_spec.rb +188 -0
- data/spec/parsing/note/pitch_node_spec.rb +48 -0
- data/spec/parsing/note/pitch_spec.rb +23 -0
- data/spec/parsing/numbers/nonnegative_integer_spec.rb +11 -0
- data/spec/parsing/numbers/positive_integer_spec.rb +17 -0
- data/spec/spec_helper.rb +112 -0
- metadata +293 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: a75a79f97d04f510ba6fe4b19c2f9d16ad4e29c4
|
|
4
|
+
data.tar.gz: ffd37ed1f4e1bdb122b5482fb06c6de9a9798549
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: a68eff07683640d944d6d620bd24f65f14263d399099dedeaea6a402f1bc80de4a05dfea84cb073ddd2f3b552655c6ab628202f58a6545042fb75e31b2e4b35d
|
|
7
|
+
data.tar.gz: 46252d7032b3ec064c85aa59f66685f7d0fdfe90eca956148ce8efcc79b8c936b553e38527ef9db1b088e0d8ae384f735819407b2eca90fd76e49f007372eed9
|
data/.document
ADDED
data/.gitignore
ADDED
data/.rspec
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
--colour
|
data/.ruby-version
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
2.0
|
data/.yardopts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
--markup rdoc --title "brevity Documentation" --protected
|
data/ChangeLog.rdoc
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright (c) 2013 James Tunnell
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
= brevity
|
|
2
|
+
|
|
3
|
+
* {Homepage}[https://rubygems.org/gems/brevity]
|
|
4
|
+
* {Documentation}[http://rubydoc.info/gems/brevity/frames]
|
|
5
|
+
* {Email}[mailto:jamestunnell at gmail.com]
|
|
6
|
+
|
|
7
|
+
== Description
|
|
8
|
+
|
|
9
|
+
Parse and process brevity files, used for music notation. Convert them to other formats.
|
|
10
|
+
|
|
11
|
+
== Features
|
|
12
|
+
|
|
13
|
+
== Examples
|
|
14
|
+
|
|
15
|
+
require 'brevity'
|
|
16
|
+
|
|
17
|
+
== Requirements
|
|
18
|
+
|
|
19
|
+
== Install
|
|
20
|
+
|
|
21
|
+
$ gem install brevity
|
|
22
|
+
|
|
23
|
+
== Copyright
|
|
24
|
+
|
|
25
|
+
Copyright (c) 2013 James Tunnell
|
|
26
|
+
|
|
27
|
+
See LICENSE.txt for details.
|
data/Rakefile
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'rubygems'
|
|
4
|
+
|
|
5
|
+
begin
|
|
6
|
+
require 'bundler'
|
|
7
|
+
rescue LoadError => e
|
|
8
|
+
warn e.message
|
|
9
|
+
warn "Run `gem install bundler` to install Bundler."
|
|
10
|
+
exit -1
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
begin
|
|
14
|
+
Bundler.setup(:development)
|
|
15
|
+
rescue Bundler::BundlerError => e
|
|
16
|
+
warn e.message
|
|
17
|
+
warn "Run `bundle install` to install missing gems."
|
|
18
|
+
exit e.status_code
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
require 'rake'
|
|
22
|
+
|
|
23
|
+
require 'rspec/core/rake_task'
|
|
24
|
+
RSpec::Core::RakeTask.new
|
|
25
|
+
|
|
26
|
+
task :test => :spec
|
|
27
|
+
task :default => :spec
|
|
28
|
+
|
|
29
|
+
require 'yard'
|
|
30
|
+
YARD::Rake::YardocTask.new
|
|
31
|
+
task :doc => :yard
|
|
32
|
+
|
|
33
|
+
require "bundler/gem_tasks"
|
|
34
|
+
|
|
35
|
+
def rb_fname fname
|
|
36
|
+
basename = File.basename(fname, File.extname(fname))
|
|
37
|
+
dirname = File.dirname(fname)
|
|
38
|
+
"#{dirname}/#{basename}.rb"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
task :build_parsers do
|
|
42
|
+
wd = Dir.pwd
|
|
43
|
+
Dir.chdir "lib/brevity/parsing"
|
|
44
|
+
parser_files = Dir.glob(["**/*.treetop","**/*.tt"])
|
|
45
|
+
|
|
46
|
+
if parser_files.empty?
|
|
47
|
+
puts "No parsers found"
|
|
48
|
+
return
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
build_list = parser_files.select do |fname|
|
|
52
|
+
rb_name = rb_fname(fname)
|
|
53
|
+
!File.exists?(rb_name) || (File.mtime(fname) > File.mtime(rb_name))
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
if build_list.any?
|
|
57
|
+
puts "building parsers:"
|
|
58
|
+
build_list.each do |fname|
|
|
59
|
+
puts " #{fname} -> #{rb_fname(fname)}"
|
|
60
|
+
`tt -f #{fname}`
|
|
61
|
+
end
|
|
62
|
+
else
|
|
63
|
+
puts "Parsers are up-to-date"
|
|
64
|
+
end
|
|
65
|
+
Dir.chdir wd
|
|
66
|
+
end
|
|
67
|
+
task :spec => :build_parsers
|
data/bin/debrief
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'brevity'
|
|
4
|
+
require 'docopt'
|
|
5
|
+
require 'yaml'
|
|
6
|
+
|
|
7
|
+
exe_name = File.basename(__FILE__)
|
|
8
|
+
|
|
9
|
+
doc = <<DOCOPT
|
|
10
|
+
Parses a Brevity file, outputting a music-transcription parts as YAML.
|
|
11
|
+
|
|
12
|
+
Usage:
|
|
13
|
+
#{exe_name} <input>
|
|
14
|
+
#{exe_name} <input> <output>
|
|
15
|
+
#{exe_name} -h | --help
|
|
16
|
+
#{exe_name} --version
|
|
17
|
+
|
|
18
|
+
Options:
|
|
19
|
+
-h --help Show this screen.
|
|
20
|
+
--version Show version.
|
|
21
|
+
|
|
22
|
+
DOCOPT
|
|
23
|
+
|
|
24
|
+
begin
|
|
25
|
+
require "pp"
|
|
26
|
+
args = Docopt::docopt(doc)
|
|
27
|
+
pp args
|
|
28
|
+
rescue Docopt::Exit => e
|
|
29
|
+
puts e.message
|
|
30
|
+
exit
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
fin = args["<input>"]
|
|
34
|
+
print "Reading file '#{fin}'..."
|
|
35
|
+
cmd_nodes = Brevity.read_file fin
|
|
36
|
+
puts "complete"
|
|
37
|
+
|
|
38
|
+
sm = Brevity::ScoreMaker.new
|
|
39
|
+
|
|
40
|
+
print "Processing commands..."
|
|
41
|
+
sm.process_nodes cmd_nodes
|
|
42
|
+
puts "complete"
|
|
43
|
+
|
|
44
|
+
print "Making score..."
|
|
45
|
+
score = sm.make_score
|
|
46
|
+
puts "complete"
|
|
47
|
+
|
|
48
|
+
fout = args["[output]"]
|
|
49
|
+
if fout.nil?
|
|
50
|
+
fout = "#{File.dirname(fin)}/#{File.basename(fin,File.extname(fin))}.yml"
|
|
51
|
+
end
|
|
52
|
+
print "Writing file '#{fout}'..."
|
|
53
|
+
File.open(fout,"w") do |f|
|
|
54
|
+
f.write(YAML.dump(score))
|
|
55
|
+
end
|
|
56
|
+
puts "complete"
|
data/brevity.gemspec
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
require File.expand_path('../lib/brevity/version', __FILE__)
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |gem|
|
|
6
|
+
gem.name = "brevity"
|
|
7
|
+
gem.version = Brevity::VERSION
|
|
8
|
+
gem.summary = %q{Parse and process brevity files. Convert them to other formats.}
|
|
9
|
+
gem.description = %q{Parse and process brevity files, used for music notation. Convert them to other formats.}
|
|
10
|
+
gem.license = "MIT"
|
|
11
|
+
gem.authors = ["James Tunnell"]
|
|
12
|
+
gem.email = "jamestunnell@gmail.com"
|
|
13
|
+
gem.homepage = "https://rubygems.org/gems/brevity"
|
|
14
|
+
|
|
15
|
+
gem.files = `git ls-files`.split($/)
|
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
|
18
|
+
gem.require_paths = ['lib']
|
|
19
|
+
|
|
20
|
+
gem.add_development_dependency 'bundler', '~> 1.0'
|
|
21
|
+
gem.add_development_dependency 'rake', '~> 0.8'
|
|
22
|
+
gem.add_development_dependency 'rspec', '~> 2.4'
|
|
23
|
+
gem.add_development_dependency 'yard', '~> 0.8'
|
|
24
|
+
gem.add_development_dependency 'pry'
|
|
25
|
+
|
|
26
|
+
gem.add_dependency 'treetop'
|
|
27
|
+
gem.add_dependency 'music-transcription', '~> 0.7'
|
|
28
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
\meter{4}{/4}
|
|
2
|
+
\tempo{120}
|
|
3
|
+
|
|
4
|
+
#-------------------------------------------------------------------------
|
|
5
|
+
|
|
6
|
+
\expr{r1}{ /4C5 /4B4 /4A4 /4Ab4 /4G4 /4Ab4 /4A4 /4 /4G4 /4Ab4 /4A4 }
|
|
7
|
+
\expr{r2}{ r1 /4Bb4 /4B4 3/4 }
|
|
8
|
+
\expr{r3}{ r1 /4F4 /4E4 3/4 }
|
|
9
|
+
\expr{r4}{ r1 /4B4 /4C5 2/4 mf /4C5 }
|
|
10
|
+
|
|
11
|
+
\part{r}{f}{
|
|
12
|
+
r2 r3 r2 r4
|
|
13
|
+
|
|
14
|
+
/4D5 /2D5 /4Ab4 /4A4 /2 /4C5
|
|
15
|
+
/4D5 /2D5 /4Gb4 /4D4 /2 /4C5
|
|
16
|
+
/4D5 /2D5 /4F4 /4Gb4 3/4
|
|
17
|
+
|
|
18
|
+
/4D5 /4C5 /4B4 /4A4 /4G4 /4Gb4 /4F4 /4
|
|
19
|
+
/4C5 /4B4 /4A4 /4Ab4 /4G4 /4Ab4 /4A3 /4
|
|
20
|
+
/4G4 /4Ab4 /4A4 /4Bb4 /4B4 3/4
|
|
21
|
+
|
|
22
|
+
r1 /4B4 /4C5 3/4
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
#-------------------------------------------------------------------------
|
|
26
|
+
|
|
27
|
+
\expr{l1}{ /4E3,C4 }
|
|
28
|
+
\expr{l2}{ /4F3,B4 }
|
|
29
|
+
\expr{l3}{ (/4G2 /4A2 /4G2)=/4 }
|
|
30
|
+
\expr{l4}{
|
|
31
|
+
/4C2 l1 /4G2 l1 /4C2 l1 l1 l3
|
|
32
|
+
/4C2 l1 /4E2 /4Eb2 /4D2 (/4G2,G3 /4Gb2,Gb3 /4G2,G3)=/4 /4Ab2,Ab3 /4G2,G3
|
|
33
|
+
/4D2 l2 /4G2 l2 /4D2 l2 l2 l3
|
|
34
|
+
}
|
|
35
|
+
\expr{l5}{
|
|
36
|
+
l4
|
|
37
|
+
/4D2 /4F3,B3 /4G2,F3,A3 /4F3,G3
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
\part{l}{mf}{
|
|
41
|
+
l5 /4C2 /4E2 /4Eb2 /4D2
|
|
42
|
+
l5 /4C2,E3,C4 /4C2 /4D2 mp /4E2,Ab3
|
|
43
|
+
|
|
44
|
+
/4F2,F3,A3 /4F3,A3 /4C2 /4Db4 /4F2,D4 /4C4 /4C2,A3 /4F3
|
|
45
|
+
/4C3,E3,G3 /4E3,G3 /4G2 /4Eb4 /4C2,E4 /4C4 /4G2,A3 /4G3
|
|
46
|
+
/4D2,Gb3,C4 /4Gb3,C4 /4A2 /4Db4 /4D2,D4 /4C4 /4A2,A3 /4Gb3
|
|
47
|
+
/4D2 /4E2 /4F2 /4Gb2,C4 /4G2,B3 /4A2,A3 /4B2,G3 /4G2
|
|
48
|
+
|
|
49
|
+
l4 /4D2 /4F2 /4E2 /4D2 /4C2 /4Db2,Ab2,F3,Bb3,Eb4 /2C2,G2,E3,A3,D4
|
|
50
|
+
}
|
data/examples/hip.br
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
\meter{4}{/4}
|
|
2
|
+
\tempo{120}
|
|
3
|
+
|
|
4
|
+
\expr{bass}{
|
|
5
|
+
/6Bb2 /4 /3Ab2 /6F2 /12Ab2
|
|
6
|
+
/6Bb2 /4 /3Ab2 /4Ab2
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
\expr{lead}{
|
|
10
|
+
/6Bb3 /4 5/18Db4 /36Eb4 /36Db4 /6Ab4 /12Db4
|
|
11
|
+
/6Bb3 /4 11/24Db4 /8C4
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
\part{Bass}{mf}{ bass:2 bass+2 bass }
|
|
15
|
+
\part{Lead}{mf}{ lead:2 lead+2 lead }
|
data/examples/song1.br
ADDED
data/examples/song2.br
ADDED
data/examples/twinkle.br
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
\meter{4}{/4}
|
|
2
|
+
\tempo{90}
|
|
3
|
+
|
|
4
|
+
# A
|
|
5
|
+
|
|
6
|
+
\expr{rhA}{ /4C4:2 /4G4:2 /4A4:2 /2G4
|
|
7
|
+
/4F4:2 /4E4:2 /4D4:2 /2C4 }
|
|
8
|
+
|
|
9
|
+
\expr{lhA}{ 1E3 /2F3 /2E3
|
|
10
|
+
/2A3 /2G3 /2F3 /2E3 }
|
|
11
|
+
|
|
12
|
+
# B
|
|
13
|
+
|
|
14
|
+
\expr{rhB}{ /4G4:2 /4F4:2 /4E4:2 /2D4 }
|
|
15
|
+
\expr{lhB}{ 1C4 /2C4 /2G3 }
|
|
16
|
+
|
|
17
|
+
\part{L. Hand}{mf}{ rhA rhB:2 rhA }
|
|
18
|
+
\part{R. Hand}{f }{ lhA lhB:2 lhA }
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module Brevity
|
|
2
|
+
module Commands
|
|
3
|
+
ENV_START_TEMPO = :start_tempo
|
|
4
|
+
ENV_START_METER = :start_meter
|
|
5
|
+
ENV_EXPRS = :exprs
|
|
6
|
+
ENV_PARTS = :parts
|
|
7
|
+
ENV_TEMPO_CHANGES = :tempo_changes
|
|
8
|
+
ENV_METER_CHANGES = :meter_changes
|
|
9
|
+
|
|
10
|
+
EXPR_PARSER = ExpressionParser.new
|
|
11
|
+
LABEL_PARSER = LabelParser.new
|
|
12
|
+
DYNAMIC_PARSER = DynamicParser.new
|
|
13
|
+
|
|
14
|
+
def class_const sym
|
|
15
|
+
self.class.const_get(sym)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module Brevity
|
|
2
|
+
module Commands
|
|
3
|
+
def expr label_str, expr_str
|
|
4
|
+
label_node = LABEL_PARSER.parse(label_str)
|
|
5
|
+
expr_node = EXPR_PARSER.parse(expr_str)
|
|
6
|
+
|
|
7
|
+
if label_node.nil?
|
|
8
|
+
raise ArgumentError, "Could not parse label string '#{label_str}'"
|
|
9
|
+
end
|
|
10
|
+
if expr_node.nil?
|
|
11
|
+
raise ArgumentError, "Could not parse expr string '#{expr_str}'"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
@env[ENV_EXPRS][label_node.to_key] = expr_node.primitives(@env[ENV_EXPRS])
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Brevity
|
|
2
|
+
module Commands
|
|
3
|
+
def meter beats_per_measure_str, beat_dur_str
|
|
4
|
+
beats_per_measure_node = PositiveIntegerParser.new.parse(beats_per_measure_str)
|
|
5
|
+
beat_dur_node = DurationParser.new.parse(beat_dur_str)
|
|
6
|
+
|
|
7
|
+
if beats_per_measure_node.nil?
|
|
8
|
+
raise ArgumentError, "Could not parse beats per measure string '#{beats_per_measure_str}'"
|
|
9
|
+
end
|
|
10
|
+
if beat_dur_node.nil?
|
|
11
|
+
raise ArgumentError, "Could not parse beat duration string '#{beat_dur_str}'"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
@env[ENV_START_METER] = Music::Transcription::Meter.new(
|
|
15
|
+
beats_per_measure_node.to_i,
|
|
16
|
+
beat_dur_node.to_r
|
|
17
|
+
)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
module Brevity
|
|
2
|
+
module Commands
|
|
3
|
+
def part name_str, startdynamic_str, expr_str
|
|
4
|
+
dyn_node = DYNAMIC_PARSER.parse(startdynamic_str.strip)
|
|
5
|
+
expr_node = EXPR_PARSER.parse(expr_str)
|
|
6
|
+
|
|
7
|
+
if dyn_node.nil?
|
|
8
|
+
raise ArgumentError, "Could not parse start dynamic string '#{startdynamic_str}'"
|
|
9
|
+
end
|
|
10
|
+
if expr_node.nil?
|
|
11
|
+
raise ArgumentError, "Could not parse expr string '#{expr_str}'"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
startdyn = dyn_node.to_dynamic
|
|
15
|
+
notes = []
|
|
16
|
+
dynamic_changes = {}
|
|
17
|
+
offset = 0.to_r
|
|
18
|
+
change_mark = nil
|
|
19
|
+
|
|
20
|
+
expr_node.primitives(@env[ENV_EXPRS]).each do |p|
|
|
21
|
+
case p
|
|
22
|
+
when Music::Transcription::Note
|
|
23
|
+
note = p
|
|
24
|
+
notes.push note
|
|
25
|
+
offset += note.duration
|
|
26
|
+
when Music::Transcription::Dynamic
|
|
27
|
+
dynamic = p
|
|
28
|
+
if change_mark.nil?
|
|
29
|
+
change = Music::Transcription::Change::Immediate.new(dynamic)
|
|
30
|
+
else
|
|
31
|
+
duration = offset - change_mark
|
|
32
|
+
change = Music::Transcription::Change::Gradual.new(dynamic,duration)
|
|
33
|
+
change_mark = nil
|
|
34
|
+
end
|
|
35
|
+
dynamic_changes[offset] = change
|
|
36
|
+
when GradualNode
|
|
37
|
+
change_mark = offset
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
@env[ENV_PARTS][name_str] = Music::Transcription::Part.new(
|
|
42
|
+
startdyn,
|
|
43
|
+
notes: notes,
|
|
44
|
+
dynamic_changes: dynamic_changes)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module Brevity
|
|
2
|
+
module Commands
|
|
3
|
+
def tempo beats_per_minute_str
|
|
4
|
+
bpm_node = PositiveIntegerParser.new.parse(beats_per_minute_str)
|
|
5
|
+
|
|
6
|
+
if bpm_node.nil?
|
|
7
|
+
raise ArgumentError, "Could not parse beats per minute string '#{beats_per_minute_str}'"
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
@env[ENV_START_TEMPO] = bpm_node.to_i
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
module Brevity
|
|
2
|
+
class Itemization
|
|
3
|
+
attr_reader :notes, :dynamic_changes, :tempo_changes, :duration
|
|
4
|
+
|
|
5
|
+
def initialize notes:[], dynamic_changes:{}, tempo_changes:{}
|
|
6
|
+
@notes = notes
|
|
7
|
+
@dynamic_changes = dynamic_changes
|
|
8
|
+
@tempo_changes = tempo_changes
|
|
9
|
+
@duration = @notes.map{ |n| n.duration }.each.inject(0.to_r,:+)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def eql?(other)
|
|
13
|
+
self == other
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def clone
|
|
17
|
+
Marshal.load(Marshal.dump(self))
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def ==(other)
|
|
21
|
+
(self.notes == other.notes) &&
|
|
22
|
+
(self.dynamic_changes == other.dynamic_changes) &&
|
|
23
|
+
(self.tempo_changes == other.tempo_changes)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def append other
|
|
27
|
+
self.clone.append! other
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def append! other
|
|
31
|
+
other.dynamic_changes.each do |offset,change|
|
|
32
|
+
@dynamic_changes[offset + @duration] = change
|
|
33
|
+
end
|
|
34
|
+
other.tempo_changes.each do |offset,change|
|
|
35
|
+
@tempo_changes[offset + @duration] = change
|
|
36
|
+
end
|
|
37
|
+
@notes += other.notes
|
|
38
|
+
@duration += other.duration
|
|
39
|
+
|
|
40
|
+
return self
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def calc_duration
|
|
44
|
+
@notes.each.inject(0.to_r,:+)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def stretch ratio
|
|
48
|
+
self.clone.stretch! ratio
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def stretch! ratio
|
|
52
|
+
@notes.each_index do |i|
|
|
53
|
+
n1 = @notes[i]
|
|
54
|
+
@notes[i] = Music::Transcription::Note.new(n1.duration * ratio, n1.pitches, links: n1.links, accent: n1.accent)
|
|
55
|
+
end
|
|
56
|
+
@dynamic_changes = Hash[ @dynamic_changes.map {|k,v| [k*ratio,v] }]
|
|
57
|
+
@tempo_changes = Hash[ @tempo_changes.map {|k,v| [k*ratio,v] }]
|
|
58
|
+
return self
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def transpose diff
|
|
62
|
+
self.clone.transpose! diff
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def transpose! diff
|
|
66
|
+
@notes[0...-1].each do |note|
|
|
67
|
+
note.transpose_pitches_and_links! diff
|
|
68
|
+
end
|
|
69
|
+
@notes[-1].transpose_pitches_only! diff
|
|
70
|
+
return self
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|