stretto 0.6.1

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