stretto 0.6.1
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.
- data/CHANGELOG.markdown +0 -0
- data/README.markdown +67 -0
- data/Rakefile +9 -0
- data/lib/stretto.rb +14 -0
- data/lib/stretto/grammar/channel_pressure_grammar.treetop +9 -0
- data/lib/stretto/grammar/chord_grammar.treetop +60 -0
- data/lib/stretto/grammar/controller_change_grammar.treetop +9 -0
- data/lib/stretto/grammar/duration_grammar.treetop +60 -0
- data/lib/stretto/grammar/grammar_helper.rb +6 -0
- data/lib/stretto/grammar/harmonic_chord_grammar.treetop +15 -0
- data/lib/stretto/grammar/harmony_grammar.treetop +15 -0
- data/lib/stretto/grammar/instrument_grammar.treetop +9 -0
- data/lib/stretto/grammar/key_signature_grammar.treetop +10 -0
- data/lib/stretto/grammar/layer_change_grammar.treetop +9 -0
- data/lib/stretto/grammar/measure_grammar.treetop +7 -0
- data/lib/stretto/grammar/note_grammar.treetop +32 -0
- data/lib/stretto/grammar/pitch_bend_grammar.treetop +7 -0
- data/lib/stretto/grammar/polyphonic_pressure_grammar.treetop +9 -0
- data/lib/stretto/grammar/rest_grammar.treetop +9 -0
- data/lib/stretto/grammar/stretto_grammar.treetop +62 -0
- data/lib/stretto/grammar/tempo_grammar.treetop +9 -0
- data/lib/stretto/grammar/timing_grammar.treetop +9 -0
- data/lib/stretto/grammar/tokens/attack_decay_token.rb +42 -0
- data/lib/stretto/grammar/tokens/chord_token.rb +67 -0
- data/lib/stretto/grammar/tokens/controller_change_token.rb +26 -0
- data/lib/stretto/grammar/tokens/duration_token.rb +55 -0
- data/lib/stretto/grammar/tokens/harmonic_chord_token.rb +25 -0
- data/lib/stretto/grammar/tokens/harmony_with_melody_token.rb +66 -0
- data/lib/stretto/grammar/tokens/hash_token.rb +15 -0
- data/lib/stretto/grammar/tokens/key_signature_token.rb +30 -0
- data/lib/stretto/grammar/tokens/measure_token.rb +21 -0
- data/lib/stretto/grammar/tokens/modifier_token.rb +99 -0
- data/lib/stretto/grammar/tokens/note_string_token.rb +106 -0
- data/lib/stretto/grammar/tokens/note_token.rb +25 -0
- data/lib/stretto/grammar/tokens/pattern_token.rb +26 -0
- data/lib/stretto/grammar/tokens/polyphonic_pressure_token.rb +28 -0
- data/lib/stretto/grammar/tokens/rest_token.rb +21 -0
- data/lib/stretto/grammar/tokens/value_token.rb +28 -0
- data/lib/stretto/grammar/tokens/variable_definition_token.rb +30 -0
- data/lib/stretto/grammar/value_grammar.treetop +45 -0
- data/lib/stretto/grammar/variable_grammar.treetop +10 -0
- data/lib/stretto/grammar/voice_change_grammar.treetop +9 -0
- data/lib/stretto/music_elements/channel_pressure.rb +44 -0
- data/lib/stretto/music_elements/chord.rb +194 -0
- data/lib/stretto/music_elements/controller_change.rb +49 -0
- data/lib/stretto/music_elements/harmonic_chord.rb +56 -0
- data/lib/stretto/music_elements/harmony.rb +37 -0
- data/lib/stretto/music_elements/instrument.rb +57 -0
- data/lib/stretto/music_elements/key_signature.rb +110 -0
- data/lib/stretto/music_elements/layer.rb +22 -0
- data/lib/stretto/music_elements/layer_change.rb +39 -0
- data/lib/stretto/music_elements/measure.rb +38 -0
- data/lib/stretto/music_elements/melody.rb +72 -0
- data/lib/stretto/music_elements/modifiers/attack_decay.rb +55 -0
- data/lib/stretto/music_elements/modifiers/chord_intervals.rb +44 -0
- data/lib/stretto/music_elements/modifiers/duration.rb +180 -0
- data/lib/stretto/music_elements/modifiers/value.rb +172 -0
- data/lib/stretto/music_elements/modifiers/variables.rb +365 -0
- data/lib/stretto/music_elements/music_element.rb +88 -0
- data/lib/stretto/music_elements/note.rb +282 -0
- data/lib/stretto/music_elements/pattern.rb +100 -0
- data/lib/stretto/music_elements/pitch_bend.rb +46 -0
- data/lib/stretto/music_elements/polyphonic_pressure.rb +62 -0
- data/lib/stretto/music_elements/rest.rb +26 -0
- data/lib/stretto/music_elements/tempo.rb +42 -0
- data/lib/stretto/music_elements/timing.rb +33 -0
- data/lib/stretto/music_elements/variable.rb +49 -0
- data/lib/stretto/music_elements/voice.rb +49 -0
- data/lib/stretto/music_elements/voice_change.rb +39 -0
- data/lib/stretto/parsers/exceptions.rb +11 -0
- data/lib/stretto/parsers/parser.rb +89 -0
- data/lib/stretto/renderers/midiator/player.rb +200 -0
- data/lib/stretto/util/jfugue_format_parser.rb +20 -0
- data/lib/stretto/util/node.rb +5 -0
- data/lib/stretto/util/utils.rb +41 -0
- data/lib/stretto/version.rb +3 -0
- metadata +203 -0
data/CHANGELOG.markdown
ADDED
File without changes
|
data/README.markdown
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
Stretto
|
2
|
+
=======
|
3
|
+
|
4
|
+
Stretto is Ruby's implementation of [JFugue][1], an open source library originally written in Java by [David Koelle][2] for programming MIDI.
|
5
|
+
|
6
|
+
Motivation
|
7
|
+
----------
|
8
|
+
|
9
|
+
JFugue's syntax is great for producing both a human readable and parseable implementation of the MIDI specification. By detaching it from the Java sound engine, it can become an specification and be implemented in several languages/platforms. This implementation aims to be compatible with JFugue as well as serve as the basis for the format specification.
|
10
|
+
|
11
|
+
Installation
|
12
|
+
------------
|
13
|
+
|
14
|
+
gem install stretto
|
15
|
+
|
16
|
+
|
17
|
+
MIDI Playback
|
18
|
+
-------------
|
19
|
+
|
20
|
+
require 'rubygems'
|
21
|
+
require 'stretto'
|
22
|
+
|
23
|
+
# play a scale
|
24
|
+
player = Stretto::Player.new
|
25
|
+
player.play("C D E F G A B")
|
26
|
+
|
27
|
+
# play a .jfugue file
|
28
|
+
file = File.new(File.dirname(__FILE__) + '/examples/entertainer.jfugue')
|
29
|
+
player.play(file)
|
30
|
+
|
31
|
+
Stretto currently supports the following subset of JFugue's syntax For MIDI playback:
|
32
|
+
|
33
|
+
- notes
|
34
|
+
- rests
|
35
|
+
- measures
|
36
|
+
- chords
|
37
|
+
- harmonies
|
38
|
+
- multiple voices
|
39
|
+
- melodies
|
40
|
+
- variables
|
41
|
+
- tempo changes
|
42
|
+
- channel pressure
|
43
|
+
- polyphonic pressure
|
44
|
+
- instruments
|
45
|
+
- pitch bends
|
46
|
+
- controller changes
|
47
|
+
|
48
|
+
For more on syntax, check out [The Complete Guide to JFugue][3]. The
|
49
|
+
second chapter is free, and covers a good chunk of what is possible with JFugue.
|
50
|
+
|
51
|
+
Stretto uses [midiator][4] for MIDI playback. If you're running OS X,
|
52
|
+
the built-in softsynth driver should just work. You can also try creating a Player with another driver, such as core_audio or alsa:
|
53
|
+
|
54
|
+
player = Stretto::Player.new(:driver => :alsa)
|
55
|
+
|
56
|
+
Contributing
|
57
|
+
------------
|
58
|
+
|
59
|
+
Stretto uses Bundler for dependency management. To run the test suite:
|
60
|
+
|
61
|
+
bundle install
|
62
|
+
rake
|
63
|
+
|
64
|
+
[1]: http://www.jfugue.org/
|
65
|
+
[2]: http://blog.davekoelle.com/
|
66
|
+
[3]: http://www.jfugue.org/book.html
|
67
|
+
[4]: https://github.com/bleything/midiator
|
data/Rakefile
ADDED
data/lib/stretto.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
|
4
|
+
require 'treetop'
|
5
|
+
require 'polyglot'
|
6
|
+
require 'midiator'
|
7
|
+
|
8
|
+
$: << File.dirname(__FILE__)
|
9
|
+
|
10
|
+
require 'stretto/util/utils'
|
11
|
+
require 'stretto/parsers/parser'
|
12
|
+
require 'stretto/parsers/exceptions'
|
13
|
+
require 'stretto/music_elements/pattern'
|
14
|
+
require 'stretto/renderers/midiator/player'
|
@@ -0,0 +1,60 @@
|
|
1
|
+
grammar ChordGrammar
|
2
|
+
|
3
|
+
include NoteGrammar
|
4
|
+
|
5
|
+
rule chord
|
6
|
+
__note_string:note_string __named_chord:named_chord __chord_inversions:chord_inversions? __duration:duration? attack_and_decay <Stretto::Tokens::ChordToken>
|
7
|
+
end
|
8
|
+
|
9
|
+
rule named_chord
|
10
|
+
# Make sure they're in reverse order, so 'maj6' is parsed before 'maj', for instance
|
11
|
+
dom "7>5>9" / dom "7>5<9" / dom "7<5>9" / dom "7<5<9" / min maj "7" / maj "7>5" / maj "7<5" /
|
12
|
+
dom "7>5" / dom "7<5" / maj "13" / min "13" / dom "13" / dom "11" / min "11" /
|
13
|
+
[aA] [dD] [dD] "9" / dim "7" /
|
14
|
+
min "9" / maj "9" / dom "9" / min "6" / maj "6" / sus "2" / sus "4" / min "7" / maj "7" /
|
15
|
+
dom "7" / dim / [aA] [uU] [gG] / min / maj
|
16
|
+
end
|
17
|
+
|
18
|
+
rule maj
|
19
|
+
[mM] [aA] [jJ]
|
20
|
+
end
|
21
|
+
|
22
|
+
rule min
|
23
|
+
[mM] [iI] [nN]
|
24
|
+
end
|
25
|
+
|
26
|
+
rule dom
|
27
|
+
[dD] [oO] [mM]
|
28
|
+
end
|
29
|
+
|
30
|
+
rule sus
|
31
|
+
[sS] [uU] [sS]
|
32
|
+
end
|
33
|
+
|
34
|
+
rule dim
|
35
|
+
[dD] [iI] [mM]
|
36
|
+
end
|
37
|
+
|
38
|
+
rule chord_inversions
|
39
|
+
'^' note_string {
|
40
|
+
def inversions
|
41
|
+
0
|
42
|
+
end
|
43
|
+
|
44
|
+
def pivot_note
|
45
|
+
note_string
|
46
|
+
end
|
47
|
+
}
|
48
|
+
/
|
49
|
+
'^'+ {
|
50
|
+
def inversions
|
51
|
+
text_value.size
|
52
|
+
end
|
53
|
+
|
54
|
+
def pivot_note
|
55
|
+
nil
|
56
|
+
end
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
grammar DurationGrammar
|
2
|
+
|
3
|
+
rule duration
|
4
|
+
_end_of_tie:tie? duration_string _start_of_tie:tie? <Stretto::Tokens::DurationToken>
|
5
|
+
end
|
6
|
+
|
7
|
+
rule duration_string
|
8
|
+
_duration_character:[whqistxoWHQISTXO]+ _dots:('.'*) _tuplet:tuplet? {
|
9
|
+
def duration_character
|
10
|
+
_duration_character.text_value
|
11
|
+
end
|
12
|
+
|
13
|
+
def dots
|
14
|
+
_dots.text_value.size
|
15
|
+
end
|
16
|
+
|
17
|
+
def tuplet
|
18
|
+
_tuplet if _tuplet.text_value.present?
|
19
|
+
end
|
20
|
+
|
21
|
+
def value
|
22
|
+
nil
|
23
|
+
end
|
24
|
+
}
|
25
|
+
/
|
26
|
+
'/' _value:variable_or_decimal {
|
27
|
+
def duration_character
|
28
|
+
nil
|
29
|
+
end
|
30
|
+
|
31
|
+
def dots
|
32
|
+
0
|
33
|
+
end
|
34
|
+
|
35
|
+
def tuplet
|
36
|
+
nil
|
37
|
+
end
|
38
|
+
|
39
|
+
def value
|
40
|
+
_value
|
41
|
+
end
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
rule tuplet
|
46
|
+
'*' _ratio:(_numerator:integer ':' _denominator:integer)? {
|
47
|
+
def numerator
|
48
|
+
_ratio._numerator.text_value if _ratio.text_value.present?
|
49
|
+
end
|
50
|
+
def denominator
|
51
|
+
_ratio._denominator.text_value if _ratio.text_value.present?
|
52
|
+
end
|
53
|
+
}
|
54
|
+
end
|
55
|
+
|
56
|
+
rule tie
|
57
|
+
'-'
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
grammar HarmonicChordGrammar
|
2
|
+
|
3
|
+
include NoteGrammar
|
4
|
+
include ChordGrammar
|
5
|
+
|
6
|
+
rule harmonic_chord
|
7
|
+
# Force it to be greedy by putting a lookahead negative assertion.
|
8
|
+
_first_element:chord_or_note _other_elements:('+' _element:chord_or_note)+ ![+_] <Stretto::Tokens::HarmonicChordToken>
|
9
|
+
end
|
10
|
+
|
11
|
+
rule chord_or_note
|
12
|
+
chord / note
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
grammar HarmonyGrammar
|
2
|
+
|
3
|
+
include ChordGrammar
|
4
|
+
include NoteGrammar
|
5
|
+
include RestGrammar
|
6
|
+
|
7
|
+
rule harmony_with_melody
|
8
|
+
_first_element:single_music_element _other_elements:(_sep:[+_] _element:single_music_element)+ <Stretto::Tokens::HarmonyWithMelodyToken>
|
9
|
+
end
|
10
|
+
|
11
|
+
rule single_music_element
|
12
|
+
chord / note / rest
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
grammar NoteGrammar
|
2
|
+
|
3
|
+
include ValueGrammar
|
4
|
+
include DurationGrammar
|
5
|
+
|
6
|
+
rule note
|
7
|
+
note_string __duration:duration? attack_and_decay <Stretto::Tokens::NoteToken>
|
8
|
+
end
|
9
|
+
|
10
|
+
rule note_string
|
11
|
+
note_key _octave:octave? <Stretto::Tokens::NoteKeyAccidentalOctaveToken>
|
12
|
+
/
|
13
|
+
'[' _pitch:integer_or_variable_name ']' <Stretto::Tokens::NotePitchToken>
|
14
|
+
end
|
15
|
+
|
16
|
+
rule note_key
|
17
|
+
key:[A-Ga-g] accidental:accidental?
|
18
|
+
end
|
19
|
+
|
20
|
+
rule accidental
|
21
|
+
"##" / "#" / [bB] [bB] / [bB] / "n" / "N"
|
22
|
+
end
|
23
|
+
|
24
|
+
rule octave
|
25
|
+
integer
|
26
|
+
end
|
27
|
+
|
28
|
+
rule attack_and_decay
|
29
|
+
_attack:([aA] value:variable_or_integer)? _decay:([dD] value:variable_or_integer)? <Stretto::Tokens::AttackDecayToken>
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/grammar_helper'
|
2
|
+
|
3
|
+
require File.dirname(__FILE__) + '/value_grammar'
|
4
|
+
require File.dirname(__FILE__) + '/duration_grammar'
|
5
|
+
require File.dirname(__FILE__) + '/note_grammar'
|
6
|
+
require File.dirname(__FILE__) + '/chord_grammar'
|
7
|
+
require File.dirname(__FILE__) + '/rest_grammar'
|
8
|
+
|
9
|
+
require File.dirname(__FILE__) + '/channel_pressure_grammar'
|
10
|
+
require File.dirname(__FILE__) + '/controller_change_grammar'
|
11
|
+
require File.dirname(__FILE__) + '/instrument_grammar'
|
12
|
+
require File.dirname(__FILE__) + '/harmony_grammar'
|
13
|
+
require File.dirname(__FILE__) + '/harmonic_chord_grammar'
|
14
|
+
require File.dirname(__FILE__) + '/key_signature_grammar'
|
15
|
+
require File.dirname(__FILE__) + '/layer_change_grammar'
|
16
|
+
require File.dirname(__FILE__) + '/measure_grammar'
|
17
|
+
require File.dirname(__FILE__) + '/pitch_bend_grammar'
|
18
|
+
require File.dirname(__FILE__) + '/polyphonic_pressure_grammar'
|
19
|
+
require File.dirname(__FILE__) + '/tempo_grammar'
|
20
|
+
require File.dirname(__FILE__) + '/timing_grammar'
|
21
|
+
require File.dirname(__FILE__) + '/variable_grammar'
|
22
|
+
require File.dirname(__FILE__) + '/voice_change_grammar'
|
23
|
+
|
24
|
+
grammar StrettoGrammar
|
25
|
+
|
26
|
+
include ValueGrammar
|
27
|
+
include DurationGrammar
|
28
|
+
include NoteGrammar
|
29
|
+
include ChordGrammar
|
30
|
+
include RestGrammar
|
31
|
+
|
32
|
+
include ChannelPressureGrammar
|
33
|
+
include ControllerChangeGrammar
|
34
|
+
include InstrumentGrammar
|
35
|
+
include HarmonicChordGrammar
|
36
|
+
include HarmonyGrammar
|
37
|
+
include KeySignatureGrammar
|
38
|
+
include LayerChangeGrammar
|
39
|
+
include MeasureGrammar
|
40
|
+
include PitchBendGrammar
|
41
|
+
include PolyphonicPressureGrammar
|
42
|
+
include TempoGrammar
|
43
|
+
include TimingGrammar
|
44
|
+
include VariableGrammar
|
45
|
+
include VoiceChangeGrammar
|
46
|
+
|
47
|
+
rule notes
|
48
|
+
space? head:music_element? more_elements:(space music_element)* space? <Stretto::Tokens::PatternToken>
|
49
|
+
end
|
50
|
+
|
51
|
+
rule music_element
|
52
|
+
harmonic_chord / harmony_with_melody / single_music_element /
|
53
|
+
measure / key_signature / instrument / voice / layer / tempo /
|
54
|
+
pitch_bend / channel_pressure / polyphonic_pressure / timing /
|
55
|
+
controller_change / variable_definition
|
56
|
+
end
|
57
|
+
|
58
|
+
rule space
|
59
|
+
[\s]+
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|