banjo 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 25a2db070a4d537dd0f0507fa271e5b1392861d3
4
- data.tar.gz: 2f9d961e602991034a2a90445b9c6b369390cfa1
3
+ metadata.gz: f7be890f11132a6586510d1318db7a1490302eb9
4
+ data.tar.gz: 11dfd1affb2cb7ff03ac187dc25ce04358e83386
5
5
  SHA512:
6
- metadata.gz: 7b98de3fd1fb5692a6ca401bfe86ec02dc35e2fb0596fc54853d77b6ca774881aac35304c8c50c8ad39e475c15038f953b92cb8817be048d954b29066b595619
7
- data.tar.gz: b657cff30587dbac401d57dbb6656b2060150c634f95660b9ba67b1fe49e1e9763e871072aba129149672f9376e9dee58fc1c82494e838fa0130e349aafa6874
6
+ metadata.gz: 1513b019ec8d7efc6199b5358694c39e10c984ab5f6fec51f5bc516b0a9ec2e2f7db7c4605ab318b720fd5e678c6fd7824acecac150d04b942529fc60a04faef
7
+ data.tar.gz: 92ac9053013d58bbcfc981fb4ac8d37059b836cebaca095a78a7ad7a7f3bff645549e2131edf81d850aeca8c52dd293bda0894832187e817cdf2d0aac3fbc145
@@ -1,2 +1,9 @@
1
+ language: ruby
2
+ cache: bundler
3
+
1
4
  rvm:
2
5
  - 2.0.0
6
+
7
+ before_install:
8
+ - sudo apt-get install libasound2
9
+ - sudo apt-get install libasound-dev
data/README.md CHANGED
@@ -1,3 +1,4 @@
1
+ [![Build Status](http://allthebadges.io/dabit/banjo/travis.png)](http://allthebadges.io/dabit/banjo/travis)
1
2
  [![Code Climate](http://allthebadges.io/dabit/banjo/code_climate.png)](http://allthebadges.io/dabit/banjo/code_climate)
2
3
 
3
4
  # Banjo
@@ -14,8 +15,20 @@ Install it:
14
15
 
15
16
  ### Mac OS X
16
17
 
17
- You need to create virtual MIDI IAC inputs. You can learn how to do so by
18
- watching [this video][1].
18
+ You need to create virtual MIDI IAC inputs.
19
+
20
+ Open Audio Midi Setup
21
+
22
+ ![](http://monosnap.com/image/u5lWy0g41Qt2JnjJqFp1nPExF9aIK9.png)
23
+
24
+ Then on the Window Menu click on Show MIDI Window
25
+
26
+ ![](http://monosnap.com/image/TswtEsSbER5dKiB7gLoxEzjptzzjzy.png)
27
+
28
+ Double Click the IAC Driver icon and press the + where it says Ports, you should
29
+ see something like this:
30
+
31
+ ![](http://monosnap.com/image/D8wQ6wC2SPvhW2fW7f3qjznlUrUV4J.png)
19
32
 
20
33
  Each one of these inputs will work as a Channel for Banjo.
21
34
 
@@ -26,8 +39,14 @@ command:
26
39
 
27
40
  input:
28
41
  0) Apple Inc. IAC Driver
42
+ 2) Apple Inc. IAC Driver
43
+ 4) Apple Inc. IAC Driver
44
+ 6) Apple Inc. IAC Driver
29
45
  output:
30
46
  1) Apple Inc. IAC Driver
47
+ 3) Apple Inc. IAC Driver
48
+ 5) Apple Inc. IAC Driver
49
+ 7) Apple Inc. IAC Driver
31
50
 
32
51
  The `unimidi list` command will show you a list of the available IAC drivers
33
52
  that can be used with Banjo.
@@ -56,4 +75,4 @@ reactor is running and you will notice the changes in realtime.
56
75
  4. Push to the branch (`git push origin my-new-feature`)
57
76
  5. Create new Pull Request
58
77
 
59
- [1]:[http://www.youtube.com/watch?v=hgFA_fdup7g]
78
+ [1]:http://www.youtube.com/watch?v=hgFA_fdup7g
@@ -21,8 +21,13 @@ Gem::Specification.new do |spec|
21
21
  spec.add_dependency "unimidi", "0.3.3"
22
22
  spec.add_dependency "eventmachine", "~> 1.0.3"
23
23
  spec.add_dependency "rubysl-yaml", "2.0.0"
24
+ spec.add_dependency "alsa-rawmidi"
25
+ spec.add_dependency "midi-winmm"
26
+ spec.add_dependency "midi-jruby"
24
27
 
25
28
  spec.add_development_dependency "bundler", "~> 1.3"
29
+ spec.add_development_dependency "minitest", "4.7.5"
26
30
  spec.add_development_dependency "rake"
27
31
  spec.add_development_dependency "rr"
32
+ spec.add_development_dependency "simplecov"
28
33
  end
@@ -3,12 +3,15 @@ require 'banjo/version'
3
3
  require 'eventmachine'
4
4
  require 'unimidi'
5
5
 
6
+ require 'banjo/keys'
6
7
  require 'banjo/channel'
8
+ require 'banjo/note'
7
9
 
8
10
  $: << '.'
9
11
 
10
12
  module Banjo
11
13
  class << self
14
+ attr_accessor :tick
12
15
  attr_accessor :beats_per_measure
13
16
  attr_accessor :measures_per_loop
14
17
  attr_accessor :tempo
@@ -28,25 +31,40 @@ module Banjo
28
31
  end
29
32
  end
30
33
 
34
+ def self.hush_all
35
+ Banjo::Channel.channels.each do |channel|
36
+ channel.new.hush
37
+ end
38
+ end
39
+
31
40
  def self.play
32
41
  Banjo.measures_per_loop ||= 1
33
- Banjo.ticks_per_period = Banjo.ticks_per_beat * Banjo.beats_per_measure * Banjo.measures_per_loop
34
- tempo_in_ms = 60.0 / Banjo.tempo / Banjo.ticks_per_beat
35
- puts "Beat every: #{tempo_in_ms}"
42
+ Banjo.ticks_per_period = Banjo.ticks_per_beat * Banjo.beats_per_measure * Banjo.measures_per_loop
43
+ poll_rate = (60.0 / Banjo.tempo / Banjo.ticks_per_beat)
44
+ p "Tick every: #{poll_rate} seconds"
36
45
 
37
46
  EventMachine.run do
38
- tick = 0
47
+ Banjo.tick = 0
39
48
  self.loop_count = 0
40
49
 
41
- EM.add_periodic_timer(tempo_in_ms) do
42
- Banjo.load_channels if tick == 0
50
+ # Display available channels
51
+ p Banjo::Channel.channels
52
+
53
+ # Shut down all channels
54
+ hush_all
55
+
56
+ EM.add_periodic_timer(poll_rate) do
57
+ #puts Time.now if (Banjo.tick % 4 == 0)
58
+ p Banjo.tick
59
+
60
+ Banjo.load_channels if Banjo.tick == 0
43
61
 
44
62
  Banjo::Channel.channels.each do |klass|
45
- channel = klass.new(tick)
63
+ channel = klass.new
46
64
  channel.perform
47
65
  end
48
66
 
49
- tick = update_counters(tick)
67
+ Banjo.tick = update_counters(Banjo.tick)
50
68
  end
51
69
 
52
70
  puts "Banjo Reactor started..."
@@ -57,7 +75,7 @@ module Banjo
57
75
  if tick < (ticks_per_period - 1)
58
76
  tick += 1
59
77
  else
60
- puts self.loop_count += 1
78
+ puts "Loop: #{self.loop_count += 1}"
61
79
  tick = 0
62
80
  end
63
81
  tick
@@ -1,13 +1,20 @@
1
1
  module Banjo
2
2
  class Channel
3
- attr_accessor :output, :tick
3
+ include Banjo::Keys
4
+
5
+ attr_accessor :output
6
+
4
7
  DEFAULT_DURATION = 0.5
5
8
 
6
9
  def channel
7
10
  0
8
11
  end
9
12
 
10
- def midi_channels
13
+ def play(note)
14
+ Note.new(self, note)
15
+ end
16
+
17
+ def midi_messages
11
18
  [0x90, 0x80]
12
19
  end
13
20
 
@@ -19,27 +26,8 @@ module Banjo
19
26
  channels << child
20
27
  end
21
28
 
22
- def initialize(tick)
29
+ def initialize
23
30
  @output = UniMIDI::Output.all[channel]
24
- @tick = tick
25
- end
26
-
27
- def tick_note(tick, note, velocity = 50, duration = DEFAULT_DURATION)
28
- play_note(note, velocity, duration) if tick == self.tick
29
- end
30
-
31
- def tick_notes(notes, velocity = 50, duration = DEFAULT_DURATION)
32
- notes.each do |tick, note|
33
- tick_note(tick, note, velocity, duration)
34
- end
35
- end
36
-
37
- def mod_note(mod, note, offset = 0, velocity = 50, duration = DEFAULT_DURATION)
38
- play_note(note, velocity, duration) if ((tick + offset) % mod == 0)
39
- end
40
-
41
- def play_note(note, velocity = 50, duration = DEFAULT_DURATION)
42
- EM.defer { play_note!(note, velocity, duration) }
43
31
  end
44
32
 
45
33
  def modulation(value = 0)
@@ -61,14 +49,19 @@ module Banjo
61
49
  end
62
50
  end
63
51
 
64
- def stfu
52
+ def hush
65
53
  output.puts 0xB0, 0x7B, 0
66
54
  end
67
55
 
68
- def play_note!(note, velocity = 50, duration = DEFAULT_DURATION)
69
- output.puts(midi_channels[0], note, velocity)
70
- sleep(duration)
71
- output.puts(midi_channels[1], note, velocity)
56
+ def play_note!(note, velocity = 100, duration = DEFAULT_DURATION)
57
+ output.puts(midi_messages[0], note, velocity)
58
+ EventMachine.add_timer(duration, proc { output.puts(midi_messages[1], note, 100) })
59
+ end
60
+
61
+ def within(lower, upper, &block)
62
+ if(Banjo.tick >= lower && Banjo.tick <= upper)
63
+ block.call
64
+ end
72
65
  end
73
66
  end
74
67
  end
@@ -0,0 +1,13 @@
1
+ module Banjo
2
+ module Keys
3
+ KEYS = %i{c cs d ds e f fs g gs a as b}
4
+
5
+ def self.included(base)
6
+ KEYS.each_with_index do |key, i|
7
+ base.send(:define_method, key) do |scale=3|
8
+ 24 + i + (scale * 12)
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,34 @@
1
+ module Banjo
2
+ class Note
3
+ attr_accessor :channel, :note, :velocity, :duration
4
+
5
+ def initialize(channel, note)
6
+ self.channel = channel
7
+ self.note = note
8
+ self.velocity = 100
9
+ self.duration = 0.5
10
+ end
11
+
12
+ def at(tick)
13
+ play if Banjo.tick == tick
14
+ end
15
+
16
+ def every(period, offset = 0)
17
+ play if ((Banjo.tick + offset) % period == 0)
18
+ end
19
+
20
+ def with_velocity(velocity)
21
+ self.velocity = velocity
22
+ self
23
+ end
24
+
25
+ def for(duration)
26
+ self.duration = duration
27
+ self
28
+ end
29
+
30
+ def play
31
+ channel.play_note!(note, velocity, duration)
32
+ end
33
+ end
34
+ end
@@ -1,3 +1,3 @@
1
1
  module Banjo
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
@@ -0,0 +1 @@
1
+ 2.0.0
@@ -1,37 +1,75 @@
1
1
  require 'test_helper'
2
2
 
3
3
  class ChannelTest < Test::Unit::TestCase
4
- def subject
5
- @subject ||= Banjo::Channel.new(0)
4
+ def channel
5
+ @channel ||= Banjo::Channel.new
6
6
  end
7
7
 
8
- def test_channel
9
- assert_equal 0, subject.channel
8
+ def test_inherited
9
+ klass = Class.new(Banjo::Channel)
10
+ assert_includes Banjo::Channel.channels, klass
10
11
  end
11
12
 
12
- def test_tick_note_plays
13
- mock(subject).play_note(15, 50, 0.5)
14
- subject.tick_note(0, 15)
13
+ def test_channel
14
+ assert_equal 0, channel.channel
15
15
  end
16
16
 
17
- def test_tick_note_does_not_play
18
- mock(subject).play_note(15, 50, 0.5).never
19
- subject.tick_note(3, 15)
17
+ def test_play
18
+ note = channel.play(22)
19
+ assert_equal 22, note.note
20
+ assert_equal channel, note.channel
21
+ assert_kind_of Banjo::Note, note
20
22
  end
21
23
 
22
- def test_mod_note_when_note_plays
23
- [0, 4, 8, 12].each do |tick|
24
- subject.tick = tick
25
- mock(subject).play_note(15, 50, 0.5)
26
- subject.mod_note(4, 15)
24
+ def test_within_plays
25
+ Banjo.tick = 1
26
+ called = false
27
+ channel.within(0, 2) do
28
+ called = true
27
29
  end
30
+
31
+ assert called, "Given block should be called"
28
32
  end
29
33
 
30
- def test_mod_note_when_note_does_not_play
31
- ((0..15).to_a - [0, 4, 8, 12]).each do |tick|
32
- subject.tick = tick
33
- mock(subject).play_note(15, 50, 0.5).never
34
- subject.mod_note(4, 15)
34
+ def test_within_does_not_play
35
+ Banjo.tick = 1
36
+ called = true
37
+ channel.within(10, 20) do
38
+ called = false
35
39
  end
40
+
41
+ assert called, "Given block should not be called"
42
+ end
43
+
44
+ def test_midi_messages
45
+ assert_equal [0x90, 0x80], channel.midi_messages
46
+ end
47
+
48
+ def test_channels
49
+ assert_equal [], Banjo::Channel.channels
50
+ end
51
+
52
+ def test_modulation
53
+ channel.output = stub!
54
+ mock(channel.output).puts(0xB0, 0x01, 100)
55
+ channel.modulation(100)
56
+ end
57
+
58
+ def test_pitch
59
+ channel.output = stub!
60
+ mock(channel.output).puts(0xE0, 0, 100)
61
+ channel.pitch(100)
62
+ end
63
+
64
+ def test_sustain
65
+ channel.output = stub!
66
+ mock(channel.output).puts(0xB0, 0x40, 100)
67
+ channel.sustain(100)
68
+ end
69
+
70
+ def test_hush
71
+ channel.output = stub!
72
+ mock(channel.output).puts(0xB0, 0x7B, 0)
73
+ channel.hush
36
74
  end
37
75
  end
@@ -0,0 +1,24 @@
1
+ require 'test_helper'
2
+
3
+ class KeysTest < Test::Unit::TestCase
4
+ def channel
5
+ @channel ||= Banjo::Channel.new
6
+ end
7
+
8
+ def test_c_scale_0_key
9
+ assert_equal 24, channel.c(0)
10
+ end
11
+
12
+ def test_c_key
13
+ assert_equal 60, channel.c
14
+ end
15
+
16
+ def test_cs_key
17
+ assert_equal 61, channel.cs
18
+ end
19
+
20
+ def test_b_key
21
+ assert_equal 71, channel.b
22
+ end
23
+ end
24
+
@@ -0,0 +1,46 @@
1
+ require 'test_helper'
2
+
3
+ class NoteTest < Test::Unit::TestCase
4
+ def channel
5
+ @channel ||= Banjo::Channel.new
6
+ end
7
+
8
+ def note
9
+ @note ||= Banjo::Note.new(channel, 2)
10
+ end
11
+
12
+ def test_at
13
+ Banjo.tick = 1
14
+ mock(note).play.once
15
+ note.at(1)
16
+ end
17
+
18
+ def test_at_dont_play
19
+ Banjo.tick = 1
20
+ mock(note).play.never
21
+ note.at(2)
22
+ end
23
+
24
+ def test_every
25
+ mock(note).play.times(4)
26
+ (0..12).each do |i|
27
+ Banjo.tick = i
28
+ note.every(4)
29
+ end
30
+ end
31
+
32
+ def test_with_velocity
33
+ assert_equal note, note.with_velocity(3)
34
+ assert_equal 3, note.velocity
35
+ end
36
+
37
+ def test_for
38
+ assert_equal note, note.for(5)
39
+ assert_equal 5, note.duration
40
+ end
41
+
42
+ def test_play
43
+ mock(channel).play_note!(2, 100, 0.5)
44
+ note.play
45
+ end
46
+ end
@@ -1,3 +1,11 @@
1
+ require 'simplecov'
2
+
3
+ SimpleCov.start do
4
+ add_filter 'test'
5
+ end
6
+
7
+ gem 'minitest', '4.7.5'
8
+
1
9
  require 'test/unit'
2
10
  require 'rr'
3
11
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: banjo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Padilla
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-24 00:00:00.000000000 Z
11
+ date: 2014-11-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: unimidi
@@ -52,6 +52,48 @@ dependencies:
52
52
  - - '='
53
53
  - !ruby/object:Gem::Version
54
54
  version: 2.0.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: alsa-rawmidi
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: midi-winmm
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: midi-jruby
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
55
97
  - !ruby/object:Gem::Dependency
56
98
  name: bundler
57
99
  requirement: !ruby/object:Gem::Requirement
@@ -66,6 +108,20 @@ dependencies:
66
108
  - - "~>"
67
109
  - !ruby/object:Gem::Version
68
110
  version: '1.3'
111
+ - !ruby/object:Gem::Dependency
112
+ name: minitest
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - '='
116
+ - !ruby/object:Gem::Version
117
+ version: 4.7.5
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - '='
123
+ - !ruby/object:Gem::Version
124
+ version: 4.7.5
69
125
  - !ruby/object:Gem::Dependency
70
126
  name: rake
71
127
  requirement: !ruby/object:Gem::Requirement
@@ -94,6 +150,20 @@ dependencies:
94
150
  - - ">="
95
151
  - !ruby/object:Gem::Version
96
152
  version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: simplecov
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
97
167
  description: MIDI looper designed for live performances
98
168
  email:
99
169
  - david@crowdint.com
@@ -110,8 +180,17 @@ files:
110
180
  - banjo.gemspec
111
181
  - lib/banjo.rb
112
182
  - lib/banjo/channel.rb
183
+ - lib/banjo/keys.rb
184
+ - lib/banjo/note.rb
113
185
  - lib/banjo/version.rb
186
+ - sample/basic/basic.band/Alternatives/000/Autosave/.dummy
187
+ - sample/heartbreaker/.ruby-version
188
+ - sample/heartbreaker/heartbreaker.logicx/Alternatives/000/Autosave/.dummy
189
+ - sample/nickel/logic/.musicapps-project-folder
190
+ - sample/nickel/logic/logic.logicx/Alternatives/000/Autosave/.dummy
114
191
  - test/cases/banjo/channel_test.rb
192
+ - test/cases/banjo/keys_test.rb
193
+ - test/cases/banjo/note_test.rb
115
194
  - test/cases/banjo_test.rb
116
195
  - test/channels/load_test.rb
117
196
  - test/test_helper.rb
@@ -135,12 +214,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
135
214
  version: '0'
136
215
  requirements: []
137
216
  rubyforge_project:
138
- rubygems_version: 2.2.0
217
+ rubygems_version: 2.2.2
139
218
  signing_key:
140
219
  specification_version: 4
141
220
  summary: MIDI looper designed for live performances
142
221
  test_files:
143
222
  - test/cases/banjo/channel_test.rb
223
+ - test/cases/banjo/keys_test.rb
224
+ - test/cases/banjo/note_test.rb
144
225
  - test/cases/banjo_test.rb
145
226
  - test/channels/load_test.rb
146
227
  - test/test_helper.rb