banjo 0.0.4 → 0.0.5

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.
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