brevity 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|