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.
Files changed (77) hide show
  1. data/CHANGELOG.markdown +0 -0
  2. data/README.markdown +67 -0
  3. data/Rakefile +9 -0
  4. data/lib/stretto.rb +14 -0
  5. data/lib/stretto/grammar/channel_pressure_grammar.treetop +9 -0
  6. data/lib/stretto/grammar/chord_grammar.treetop +60 -0
  7. data/lib/stretto/grammar/controller_change_grammar.treetop +9 -0
  8. data/lib/stretto/grammar/duration_grammar.treetop +60 -0
  9. data/lib/stretto/grammar/grammar_helper.rb +6 -0
  10. data/lib/stretto/grammar/harmonic_chord_grammar.treetop +15 -0
  11. data/lib/stretto/grammar/harmony_grammar.treetop +15 -0
  12. data/lib/stretto/grammar/instrument_grammar.treetop +9 -0
  13. data/lib/stretto/grammar/key_signature_grammar.treetop +10 -0
  14. data/lib/stretto/grammar/layer_change_grammar.treetop +9 -0
  15. data/lib/stretto/grammar/measure_grammar.treetop +7 -0
  16. data/lib/stretto/grammar/note_grammar.treetop +32 -0
  17. data/lib/stretto/grammar/pitch_bend_grammar.treetop +7 -0
  18. data/lib/stretto/grammar/polyphonic_pressure_grammar.treetop +9 -0
  19. data/lib/stretto/grammar/rest_grammar.treetop +9 -0
  20. data/lib/stretto/grammar/stretto_grammar.treetop +62 -0
  21. data/lib/stretto/grammar/tempo_grammar.treetop +9 -0
  22. data/lib/stretto/grammar/timing_grammar.treetop +9 -0
  23. data/lib/stretto/grammar/tokens/attack_decay_token.rb +42 -0
  24. data/lib/stretto/grammar/tokens/chord_token.rb +67 -0
  25. data/lib/stretto/grammar/tokens/controller_change_token.rb +26 -0
  26. data/lib/stretto/grammar/tokens/duration_token.rb +55 -0
  27. data/lib/stretto/grammar/tokens/harmonic_chord_token.rb +25 -0
  28. data/lib/stretto/grammar/tokens/harmony_with_melody_token.rb +66 -0
  29. data/lib/stretto/grammar/tokens/hash_token.rb +15 -0
  30. data/lib/stretto/grammar/tokens/key_signature_token.rb +30 -0
  31. data/lib/stretto/grammar/tokens/measure_token.rb +21 -0
  32. data/lib/stretto/grammar/tokens/modifier_token.rb +99 -0
  33. data/lib/stretto/grammar/tokens/note_string_token.rb +106 -0
  34. data/lib/stretto/grammar/tokens/note_token.rb +25 -0
  35. data/lib/stretto/grammar/tokens/pattern_token.rb +26 -0
  36. data/lib/stretto/grammar/tokens/polyphonic_pressure_token.rb +28 -0
  37. data/lib/stretto/grammar/tokens/rest_token.rb +21 -0
  38. data/lib/stretto/grammar/tokens/value_token.rb +28 -0
  39. data/lib/stretto/grammar/tokens/variable_definition_token.rb +30 -0
  40. data/lib/stretto/grammar/value_grammar.treetop +45 -0
  41. data/lib/stretto/grammar/variable_grammar.treetop +10 -0
  42. data/lib/stretto/grammar/voice_change_grammar.treetop +9 -0
  43. data/lib/stretto/music_elements/channel_pressure.rb +44 -0
  44. data/lib/stretto/music_elements/chord.rb +194 -0
  45. data/lib/stretto/music_elements/controller_change.rb +49 -0
  46. data/lib/stretto/music_elements/harmonic_chord.rb +56 -0
  47. data/lib/stretto/music_elements/harmony.rb +37 -0
  48. data/lib/stretto/music_elements/instrument.rb +57 -0
  49. data/lib/stretto/music_elements/key_signature.rb +110 -0
  50. data/lib/stretto/music_elements/layer.rb +22 -0
  51. data/lib/stretto/music_elements/layer_change.rb +39 -0
  52. data/lib/stretto/music_elements/measure.rb +38 -0
  53. data/lib/stretto/music_elements/melody.rb +72 -0
  54. data/lib/stretto/music_elements/modifiers/attack_decay.rb +55 -0
  55. data/lib/stretto/music_elements/modifiers/chord_intervals.rb +44 -0
  56. data/lib/stretto/music_elements/modifiers/duration.rb +180 -0
  57. data/lib/stretto/music_elements/modifiers/value.rb +172 -0
  58. data/lib/stretto/music_elements/modifiers/variables.rb +365 -0
  59. data/lib/stretto/music_elements/music_element.rb +88 -0
  60. data/lib/stretto/music_elements/note.rb +282 -0
  61. data/lib/stretto/music_elements/pattern.rb +100 -0
  62. data/lib/stretto/music_elements/pitch_bend.rb +46 -0
  63. data/lib/stretto/music_elements/polyphonic_pressure.rb +62 -0
  64. data/lib/stretto/music_elements/rest.rb +26 -0
  65. data/lib/stretto/music_elements/tempo.rb +42 -0
  66. data/lib/stretto/music_elements/timing.rb +33 -0
  67. data/lib/stretto/music_elements/variable.rb +49 -0
  68. data/lib/stretto/music_elements/voice.rb +49 -0
  69. data/lib/stretto/music_elements/voice_change.rb +39 -0
  70. data/lib/stretto/parsers/exceptions.rb +11 -0
  71. data/lib/stretto/parsers/parser.rb +89 -0
  72. data/lib/stretto/renderers/midiator/player.rb +200 -0
  73. data/lib/stretto/util/jfugue_format_parser.rb +20 -0
  74. data/lib/stretto/util/node.rb +5 -0
  75. data/lib/stretto/util/utils.rb +41 -0
  76. data/lib/stretto/version.rb +3 -0
  77. metadata +203 -0
File without changes
@@ -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
@@ -0,0 +1,9 @@
1
+ require 'rake'
2
+ require 'spec/rake/spectask'
3
+
4
+ task :default => 'spec'
5
+
6
+ desc 'Run all examples'
7
+ Spec::Rake::SpecTask.new('spec') do |t|
8
+ t.spec_files = FileList['spec/**/*spec.rb']
9
+ end
@@ -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,9 @@
1
+ grammar ChannelPressureGrammar
2
+
3
+ include ValueGrammar
4
+
5
+ rule channel_pressure
6
+ kind:'+' __value:variable_or_integer <Stretto::Tokens::ChannelPressureToken>
7
+ end
8
+
9
+ end
@@ -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,9 @@
1
+ grammar ControllerChangeGrammar
2
+
3
+ include ValueGrammar
4
+
5
+ rule controller_change
6
+ 'X' __controller:variable_or_integer '=' __value:variable_or_integer <Stretto::Tokens::ControllerChangeToken>
7
+ end
8
+
9
+ 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,6 @@
1
+ require File.dirname(__FILE__) + '/tokens/hash_token'
2
+
3
+ # Load automatically all token definition files from the directory tokens
4
+ Dir[File.dirname(__FILE__) + '/tokens/*_token.rb'].each do |token_file|
5
+ require token_file
6
+ 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,9 @@
1
+ grammar InstrumentGrammar
2
+
3
+ include ValueGrammar
4
+
5
+ rule instrument
6
+ kind:'I' __value:variable_or_integer <Stretto::Tokens::InstrumentToken>
7
+ end
8
+
9
+ end
@@ -0,0 +1,10 @@
1
+ grammar KeySignatureGrammar
2
+
3
+ include NoteGrammar
4
+ include ChordGrammar
5
+
6
+ rule key_signature
7
+ [kK] __note_key:note_key __scale:(maj / min) <Stretto::Tokens::KeySignatureToken>
8
+ end
9
+
10
+ end
@@ -0,0 +1,9 @@
1
+ grammar LayerChangeGrammar
2
+
3
+ include ValueGrammar
4
+
5
+ rule layer
6
+ kind:'L' __value:variable_or_integer <Stretto::Tokens::LayerChangeToken>
7
+ end
8
+
9
+ end
@@ -0,0 +1,7 @@
1
+ grammar MeasureGrammar
2
+
3
+ rule measure
4
+ '|' <Stretto::Tokens::MeasureToken>
5
+ end
6
+
7
+ 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,7 @@
1
+ grammar PitchBendGrammar
2
+ include ValueGrammar
3
+
4
+ rule pitch_bend
5
+ kind:'&' __value:variable_or_integer <Stretto::Tokens::PitchBendToken>
6
+ end
7
+ end
@@ -0,0 +1,9 @@
1
+ grammar PolyphonicPressureGrammar
2
+
3
+ include ValueGrammar
4
+
5
+ rule polyphonic_pressure
6
+ '*' __pitch:variable_or_integer ',' __value:variable_or_integer <Stretto::Tokens::PolyphonicPressureToken>
7
+ end
8
+
9
+ end
@@ -0,0 +1,9 @@
1
+ grammar RestGrammar
2
+
3
+ include DurationGrammar
4
+
5
+ rule rest
6
+ [Rr] __duration:duration? <Stretto::Tokens::RestToken>
7
+ end
8
+
9
+ 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