hammelin 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ .DS_Store
2
+ .rvmrc
3
+ *.mid
4
+ *.gem
5
+
data/.rvmrc.example ADDED
@@ -0,0 +1,2 @@
1
+ rvm use jruby
2
+ export JRUBY_OPTS=--1.9
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in hammelin.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,66 @@
1
+ # Integration Exercise: Java Library Wrapper
2
+
3
+ # Hammelin
4
+
5
+ JFugue (http://www.jfugue.org/index.html) is a Java library that let's developers program a melody through using the basic notes, chords, etc. The music can be saved to a MIDI file, or played just then.
6
+
7
+ Hammelin wraps around JFugue functionality to let JRuby users create, play and save MIDIs file using Ruby syntax and some sugar with that.
8
+
9
+ # Using Hammelin
10
+
11
+ Hammelin gaves you easiness of play. Right now, you can use a MusicString
12
+ to play your own music:
13
+
14
+ Hammelin.play("E5s A5s C6s B5s E5s B5s D6s C6i E6i G#5i E6i | A5s E5s A5s C6s B5s E5s B5s D6s C6i A5i Ri")
15
+
16
+ You could also work with notes:
17
+
18
+ note = Hammelin::Note.new("E5s")
19
+
20
+ And then just play it
21
+
22
+ note.play
23
+
24
+ Hammelin also allows you to play with ranges:
25
+
26
+ note = Hammelin::Note.new("C")
27
+ note.upto("E5s").play
28
+
29
+ If wanted, you also have access to each note of the range:
30
+
31
+ note.upto("E5s").each do {|note| note.play }
32
+ note.upto("E5s").each do {|note| note.increase_octave }
33
+
34
+
35
+ Now go and make some interesting tunes :)
36
+
37
+ Hammelin.compose do
38
+
39
+ note = Hammelin::Note.new("C")
40
+ tune = note.upto("D#")
41
+
42
+ 2.times do
43
+ play tune
44
+ play tune.reverse
45
+
46
+ 2.times do
47
+ play tune
48
+ play tune.increase_octave
49
+ play tune.increase_octave(2)
50
+ end
51
+
52
+ end
53
+
54
+ end
55
+
56
+ ## Saving your work
57
+
58
+ Just send a filename to the compose method:
59
+
60
+ Hammelin.compose("file.mid") do
61
+
62
+ ### Running on GNU/Linux?
63
+
64
+ There was a reported bug when a missing library wasn't found by the Java VM. The file (libpuse-java.so) should be on
65
+
66
+ /usr/lib/jvm/java-6-openjdk/jre/lib/i386
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
Binary file
@@ -0,0 +1,20 @@
1
+ require_relative '../lib/hammelin'
2
+
3
+ Hammelin.compose("file.mid") do
4
+
5
+ note = Hammelin::Note.new("C")
6
+ tune = note.upto("D#")
7
+
8
+ 2.times do
9
+ play tune
10
+ play tune.reverse
11
+
12
+ 2.times do
13
+ play tune
14
+ play tune.increase_octave
15
+ play tune.increase_octave(2)
16
+ end
17
+
18
+ end
19
+
20
+ end
data/hammelin.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "hammelin/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "hammelin"
7
+ s.version = Hammelin::VERSION
8
+ s.authors = ["Alvaro Pereyra"]
9
+ s.email = "alvaro@xendacentral.com"
10
+ s.homepage = ""
11
+ s.summary = %q{Hammelin allows you to play around with JFugue MIDI capabilities}
12
+ s.description = %q{Hammelin wraps around JFugue and lets your play with notes, making Ruby sing}
13
+
14
+ s.rubyforge_project = "hammelin"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ # s.executables = []
19
+ s.require_paths = ["lib"]
20
+
21
+ # specify any dependencies here; for example:
22
+ # s.add_development_dependency "rspec"
23
+ # s.add_runtime_dependency "rest-client"
24
+ end
data/lib/hammelin.rb ADDED
@@ -0,0 +1,3 @@
1
+ require_relative 'hammelin/hammelin'
2
+ require_relative 'hammelin/note'
3
+ require_relative 'hammelin/notes_range'
@@ -0,0 +1,70 @@
1
+ require 'java'
2
+
3
+ require_relative '../../bin/jfugue-4.0.3.jar'
4
+
5
+ java_import org.jfugue.Player
6
+ java_import org.jfugue.Pattern
7
+ java_import org.jfugue.Rhythm
8
+ java_import org.jfugue.MusicStringParser
9
+
10
+ module Hammelin
11
+
12
+ extend self
13
+
14
+ PADDING = " "
15
+ @logged_music_string = ""
16
+
17
+ def play(tune)
18
+ if playable_tune?(tune)
19
+ play_tune(tune)
20
+ else
21
+ play_string(tune)
22
+ end
23
+ end
24
+
25
+ def play_string(tune)
26
+ player.play(tune)
27
+ add_to_log(tune)
28
+ player.close
29
+ end
30
+
31
+ def playable_tune?(tune)
32
+ return true if tune.respond_to? :play
33
+ return true if tune.is_a?(Array) ? playable_tune?(tune.first) : false
34
+ end
35
+
36
+ def play_tune(tune)
37
+ if tune.respond_to? :play
38
+ tune.play
39
+ else
40
+ tune.each(&:play) if playable_tune?(tune.first)
41
+ end
42
+ end
43
+
44
+ def compose(filename=nil,&block)
45
+ instance_eval &block
46
+ save_to_file(filename) if filename
47
+ ensure
48
+ player.close
49
+ end
50
+
51
+ private
52
+
53
+ def add_to_log(tune)
54
+ logged_music_string << tune + PADDING
55
+ end
56
+
57
+ def logged_music_string
58
+ @logged_music_string
59
+ end
60
+
61
+ def save_to_file(filename)
62
+ file = java.io.File.new(filename)
63
+ player.save_midi(logged_music_string,file)
64
+ end
65
+
66
+ def player
67
+ @player ||= Player.new
68
+ end
69
+
70
+ end
@@ -0,0 +1,84 @@
1
+ module Hammelin
2
+
3
+ class Note
4
+
5
+ include Comparable
6
+ attr_accessor :token
7
+
8
+ OCTAVE_JUMP = 12
9
+ MAX_VALUE = 127
10
+ CAPPED_VALUE = MAX_VALUE - OCTAVE_JUMP
11
+
12
+ def initialize(note)
13
+ self.token = note
14
+ end
15
+
16
+ def play
17
+ Hammelin.play(music_string)
18
+ end
19
+
20
+ def upto(note)
21
+ NotesRange.new(self,Note.new(note))
22
+ end
23
+
24
+ def downto(note)
25
+ NotesRange.new(Note.new(note),self)
26
+ end
27
+
28
+ def self.from_value(value)
29
+ Note.new("[#{value}]")
30
+ end
31
+
32
+ def music_string
33
+ "[#{parse_value}]"
34
+ end
35
+
36
+ def increase_octave(times)
37
+ Note.from_value(higher_octave(times))
38
+ end
39
+
40
+ def decrease_octave(times)
41
+ Note.from_value(lower_octave(times))
42
+ end
43
+
44
+ def increase_octave!(times)
45
+ self.token = increase_octaves(times).value
46
+ end
47
+
48
+ def decrease_octave!(times)
49
+ self.token = decrease_octaves(times).value
50
+ end
51
+
52
+ def value
53
+ parse_value
54
+ end
55
+
56
+ def <=>(other)
57
+ self.value <=> other.value
58
+ end
59
+
60
+ private
61
+
62
+ def parse_value
63
+ MusicStringParser.get_note(self.token).get_value
64
+ end
65
+
66
+ def higher_octave(times=1)
67
+ OCTAVE_JUMP*times + self.value unless highest_octave?
68
+ end
69
+
70
+ def lower_octave(times=1)
71
+ OCTAVE_JUMP*times + self.value unless lowest_octave?
72
+ end
73
+
74
+ def highest_octave?
75
+ self.value >= CAPPED_VALUE
76
+ end
77
+
78
+ def lowest_octave?
79
+ self.value <= OCTAVE_JUMP
80
+ end
81
+
82
+ end
83
+
84
+ end
@@ -0,0 +1,55 @@
1
+ require 'delegate'
2
+
3
+ module Hammelin
4
+
5
+ class NotesRange < DelegateClass(Array)
6
+
7
+ def initialize(from,to)
8
+ @from, @to = from,to
9
+ super(transverse_notes)
10
+ end
11
+
12
+ def play
13
+ Hammelin.play music_string
14
+ self
15
+ end
16
+
17
+ def reverse
18
+ NotesRange.new(@to,@from)
19
+ end
20
+
21
+ # downto and upto are just some sintactic sugar for expanding the range to
22
+ # a new value. It will create a new NotesRange object with the last Note
23
+ # and then will figure out how to get to the newest one.
24
+ def downto(value)
25
+ NotesRange.new(@to,value)
26
+ end
27
+
28
+ alias :upto :downto
29
+
30
+ def increase_octave(times=1)
31
+ NotesRange.new(@from.increase_octave(times), @to.increase_octave(times))
32
+ end
33
+
34
+ def decrease_octave(times=1)
35
+ NotesRange.new(@from.decrease_octave(times), @to.decrease_octave(times))
36
+ end
37
+
38
+ def music_string
39
+ map{|i| i.music_string }.join(" ")
40
+ end
41
+
42
+ private
43
+
44
+ def transverse_notes
45
+ enum = if @from > @to
46
+ @from.value.downto(@to.value)
47
+ else
48
+ @from.value.upto(@to.value)
49
+ end
50
+ enum.map{|value| Note.from_value(value) }
51
+ end
52
+
53
+ end
54
+
55
+ end
@@ -0,0 +1,3 @@
1
+ module Hammelin
2
+ VERSION = "0.0.2"
3
+ end
Binary file
@@ -0,0 +1,13 @@
1
+ import org.jfugue.*;
2
+ public class Main
3
+ {
4
+ public static void main(String[] args)
5
+ {
6
+ Player player = new Player();
7
+ // Pattern pattern = new Pattern("C D E F G A B");
8
+ Pattern pattern = new Pattern("G B C D E A B");
9
+
10
+ player.play(pattern);
11
+ System.exit(0); // If using Java 1.4 or lower
12
+ }
13
+ }
metadata ADDED
@@ -0,0 +1,70 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hammelin
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.2
6
+ platform: ruby
7
+ authors:
8
+ - Alvaro Pereyra
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-09-16 00:00:00 -05:00
14
+ default_executable:
15
+ dependencies: []
16
+
17
+ description: Hammelin wraps around JFugue and lets your play with notes, making Ruby sing
18
+ email: alvaro@xendacentral.com
19
+ executables: []
20
+
21
+ extensions: []
22
+
23
+ extra_rdoc_files: []
24
+
25
+ files:
26
+ - .gitignore
27
+ - .rvmrc.example
28
+ - Gemfile
29
+ - README.md
30
+ - Rakefile
31
+ - bin/jfugue-4.0.3.jar
32
+ - demos/nested_play.rb
33
+ - hammelin.gemspec
34
+ - lib/hammelin.rb
35
+ - lib/hammelin/hammelin.rb
36
+ - lib/hammelin/note.rb
37
+ - lib/hammelin/notes_range.rb
38
+ - lib/hammelin/version.rb
39
+ - reference/Main.class
40
+ - reference/Main.java
41
+ has_rdoc: true
42
+ homepage: ""
43
+ licenses: []
44
+
45
+ post_install_message:
46
+ rdoc_options: []
47
+
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: "0"
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: "0"
62
+ requirements: []
63
+
64
+ rubyforge_project: hammelin
65
+ rubygems_version: 1.5.1
66
+ signing_key:
67
+ specification_version: 3
68
+ summary: Hammelin allows you to play around with JFugue MIDI capabilities
69
+ test_files: []
70
+