kuromusic 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c6bfa0bd38071a7eff140febd8dd6ecd0b306d36
4
+ data.tar.gz: a56453eb5f4890ded06656a5951d0efc8f053ce4
5
+ SHA512:
6
+ metadata.gz: 66ba15156b082ecf6a7e34e06d7086764d61efe202eea111a6e0b7781790cbbeec82aba8678db014268933da90acc40508af64579bab8899cb55e6c686903b71
7
+ data.tar.gz: 99f38c4b27bfd4054f2ea1ced1feb5b4ec7f2c9fb3c5d393f786bda7bd6a3f9e008b775ad45e1e43d32a7f3994d618b88578c85274a5a73643130cf95c98c100
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in kuromusic.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2016 黒澤 預生
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,51 @@
1
+ # KuroMusic
2
+
3
+ KuroMusic is midi controll library writed by ruby.
4
+
5
+ ##version
6
+ 0.0.1
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ ```ruby
13
+ gem 'kuromusic'
14
+ ```
15
+
16
+ And then execute:
17
+
18
+ $ bundle
19
+
20
+ Or install it yourself as:
21
+
22
+ $ gem install kuromusic
23
+
24
+ ## Usage
25
+
26
+ you should require KuroMusic in your source code to use those method.
27
+ ```ruby:
28
+ require "KuroMusic"
29
+ ```
30
+
31
+ ###generate melody automaticaly
32
+ ```ruby:
33
+ DELTA_TIME = 480
34
+ midi = Midi.new(DELTA_TIME, 2)
35
+ melo = MelodyGenerater.new(DELTA_TIME, Scale::MAJOR).extend(MelodyGenerater::Rand)
36
+ midi.tracks[0] = melo.cantus(10)
37
+ midi.tracks[1] = melo.base(10)
38
+ ```
39
+
40
+ ###write midi file
41
+ ```ruby:
42
+ Midi::IO.write("hoge3.mid", midi)
43
+ ```
44
+
45
+ ## Contributing
46
+
47
+ 1. Fork it ( https://github.com/[my-github-username]/kuromusic/fork )
48
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
49
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
50
+ 4. Push to the branch (`git push origin my-new-feature`)
51
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
data/kuromusic.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'kuromusic/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "kuromusic"
8
+ spec.version = Kuromusic::VERSION
9
+ spec.authors = ["黒澤 預生"]
10
+ spec.email = ["yonamachan3@gmail.com"]
11
+ spec.summary = %q{KuroMusic is midi controll library writed by ruby.}
12
+ spec.description = %q{KuroMusic is midi controll library writed by ruby.}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.7"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ end
@@ -0,0 +1,5 @@
1
+ class ChordProgression
2
+ private
3
+ LERDAHF_MAP = [
4
+ 'D#', 'F'
5
+ ]
@@ -0,0 +1,17 @@
1
+ class Event
2
+ module EventType
3
+ NULL = nil
4
+ NOTE = :NOTE
5
+ META = :META
6
+ module Note
7
+ NULL = nil
8
+ ON = :ON
9
+ OFF = :OFF
10
+ REST = :REST
11
+ end
12
+ module Meta
13
+ NULL = nil
14
+ SET_TEMPO = :SET_TEMPO
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,11 @@
1
+ class Event
2
+ module Meta extend self
3
+ def set_tempo(bpm)
4
+ Event.new({
5
+ :type => EventType::META,
6
+ :method => EventType::Meta::SET_TEMPO,
7
+ :tempo => bpm
8
+ })
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,28 @@
1
+ class Event
2
+ module Note extend self
3
+ def on(note, octave, velocity)
4
+ Event.new({
5
+ :type => EventType::NOTE,
6
+ :method => EventType::Note::ON,
7
+ :note => note,
8
+ :octave => octave,
9
+ :velocity => velocity
10
+ })
11
+ end
12
+ def off(note, octave)
13
+ Event.new({
14
+ :type => EventType::NOTE,
15
+ :method => EventType::Note::OFF,
16
+ :note => note,
17
+ :octave => octave
18
+ })
19
+ end
20
+ def rest(dur)
21
+ Event.new({
22
+ :type => EventType::NOTE,
23
+ :method => EventType::Note::REST,
24
+ :dur => dur
25
+ })
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,11 @@
1
+ require_relative "Event/EventType"
2
+ require_relative "Event/NoteEvent"
3
+ require_relative "Event/MetaEvent"
4
+
5
+ class Event
6
+ attr_reader :args
7
+ private
8
+ def initialize(args)
9
+ @args = args
10
+ end
11
+ end
@@ -0,0 +1,53 @@
1
+ class MelodyGenerater
2
+ module Rand
3
+ private
4
+ def fiber(octave, notes, num)
5
+ Fiber.new do |dur, velocity|
6
+ while true do
7
+ ons = (0..(num-1)).to_a.map{|item|
8
+ note = notes.sample
9
+ [Event::Note::rest(0), Event::Note::on(note, octave, velocity)]
10
+ }
11
+ offs = ons.each_with_index.map{|item, i|
12
+ if i == 0
13
+ [Event::Note::rest(dur), Event::Note::off(item[1].args[:note], octave)]
14
+ else
15
+ [Event::Note::rest(0), Event::Note::off(item[1].args[:note], octave)]
16
+ end
17
+ }
18
+ dur, velocity = Fiber.yield [ons, offs].flatten
19
+ end
20
+ end
21
+ end
22
+
23
+ def common(length, octave, _note_times, notes)
24
+ events = []
25
+ f = fiber(octave, notes, 2)
26
+ length.times {|i|
27
+ note_times = _note_times[0..(_note_times.length - 1)]
28
+ dur = note_times.sample
29
+ events.concat f.resume(dur, 100)
30
+ _sub = @measure - dur
31
+ note_times.reverse.each_with_index {|t, i|
32
+ times = note_times[0..(note_times.length - 1 - i)]
33
+ while _sub >= t do
34
+ dur = times.sample
35
+ events.concat f.resume(dur, 100)
36
+ _sub = _sub - dur
37
+ end
38
+ }
39
+ }
40
+ events
41
+ end
42
+
43
+ public
44
+ def base(length)
45
+ octave = 2
46
+ Track.new(common(length, octave, @note_times[4..5], @scale))
47
+ end
48
+ def cantus(length)
49
+ octave = 4
50
+ Track.new(common(length, octave, @note_times[1..3], @scale))
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,63 @@
1
+ class MelodyGenerater
2
+ module Schenker
3
+ MIDDLE = [7, 5, 4, 2, 2, 0]
4
+ BACK = [0, 5, 7, 0]
5
+
6
+ private
7
+ def fiber(octave, notes, num)
8
+ Fiber.new do |dur, velocity|
9
+ while true do
10
+ notes.each{|n|
11
+ ons = (0..(num-1)).to_a.map{|item|
12
+ _n = n + (2 * item)
13
+ octave = octave + _n / 12
14
+ number = _n % 12
15
+ note = Scale::number_to_code(number)
16
+ [Event::Note::rest(0), Event::Note::on(note, octave, velocity)]
17
+ }
18
+ offs = ons.each_with_index.map{|item, i|
19
+ if i == 0
20
+ [Event::Note::rest(dur), Event::Note::off(item[1].args[:note], octave)]
21
+ else
22
+ [Event::Note::rest(0), Event::Note::off(item[1].args[:note], octave)]
23
+ end
24
+ }
25
+ dur, velocity = Fiber.yield [ons, offs].flatten
26
+ }
27
+ end
28
+ end
29
+ end
30
+
31
+ def common(length, octave, _note_times, notes)
32
+ events = []
33
+ f = fiber(octave, notes, 2)
34
+ length.times {|i|
35
+ note_times = _note_times[0..(_note_times.length - 1)]
36
+ dur = note_times.sample
37
+ events.concat f.resume(dur, 100)
38
+ _sub = @measure - dur
39
+ note_times.reverse.each_with_index {|t, i|
40
+ times = note_times[0..(note_times.length - 1 - i)]
41
+ while _sub >= t do
42
+ note = @scale.sample
43
+ dur = times.sample
44
+ events.concat [Event::Note::rest(0), Event::Note::on(note, octave, 100), Event::Note::rest(dur), Event::Note::off(note, octave)]
45
+ _sub = _sub - dur
46
+ end
47
+ }
48
+ }
49
+ events
50
+ end
51
+
52
+ public
53
+ def base(length)
54
+ octave = 2
55
+ Track.new(common(length, octave, @note_times[4..5], BACK))
56
+ end
57
+
58
+ def cantus(length)
59
+ octave = 4
60
+ Track.new(common(length, octave, @note_times[2..3], MIDDLE))
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,43 @@
1
+ class Midi
2
+ private
3
+ module MidiEvent
4
+ private
5
+ def var_len n
6
+ n < 0x80 ? [n] : [(n>>7|0x80), n % 0x80]
7
+ end
8
+
9
+ def note_to_bin()
10
+ case @args[:method]
11
+ when Event::EventType::Note::REST
12
+ dur = var_len(@args[:dur])
13
+ return dur
14
+ when Event::EventType::Note::OFF
15
+ note_num = NOTE[@args[:note]] + @args[:octave] * OCTAVE_UNIT
16
+ return [0x80, note_num, 0]
17
+ when Event::EventType::Note::ON
18
+ note_num = NOTE[@args[:note]] + @args[:octave] * OCTAVE_UNIT
19
+ return [0x90, note_num, @args[:velocity]]
20
+ end
21
+ end
22
+
23
+ def meta_to_bin()
24
+ case @args[:method]
25
+ when Event::EventType::Meta::SET_TEMPO
26
+ tempo = 60000000 / @args[:tempo]
27
+ return [0, 0xff, 0x51, 0x03, tempo >> 16, tempo >> 8, tempo % 256]
28
+ end
29
+ end
30
+
31
+ public
32
+ NOTE = {"C"=>0, "C#"=>1, "D"=>2, "D#"=>3, "E"=>4, "F"=>5, "F#"=>6, "G"=>7, "G#"=>8, "A"=>9, "A#"=>10, "B"=>11}
33
+ OCTAVE_UNIT = 12
34
+
35
+ def to_bin()
36
+ if @args[:type] == Event::EventType::NOTE
37
+ return note_to_bin
38
+ elsif @args[:type] == Event::EventType::META
39
+ return meta_to_bin
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,14 @@
1
+ class Midi
2
+ private
3
+ module MidiTrack
4
+ def to_bin()
5
+ track = []
6
+ @events.each {|e|
7
+ e.extend(MidiEvent)
8
+ track.concat e.to_bin
9
+ }
10
+ tl = track.concat([0, 0xff, 0x02, 0]).size
11
+ result = [0x4d, 0x54, 0x72, 0x6b, tl >> 24, tl >> 16, tl >> 8, tl % 256].concat track
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,29 @@
1
+ require_relative "MIDI/MidiEvent"
2
+ require_relative "MIDI/MidiTrack"
3
+
4
+ class Midi
5
+ module IO
6
+ public
7
+ def self.load(input_path)
8
+ tempo = 120
9
+ Midi.new(tempo)
10
+ end
11
+ def self.write(output_path, midi)
12
+ File.open(output_path, "wb") do |file|
13
+ track_num = midi.tracks.length
14
+ dtime = midi.dtime
15
+ file.write [0x4d, 0x54, 0x68, 0x64, 0, 0, 0, 6, 0, 1, track_num >> 8, track_num % 256, dtime >> 8, dtime % 256].pack('C*')
16
+ midi.tracks.each {|track|
17
+ track.extend(MidiTrack)
18
+ m = track.to_bin
19
+ track.each {|e|
20
+ #[e.args[:type], e.args[:method], e.args[:note], e.args[:octave], e.args[:dur], e.args[:velocity]]
21
+ p e.args
22
+ }
23
+ #p m
24
+ file.write m.pack('C*')
25
+ }
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,3 @@
1
+ class Key
2
+
3
+ end
@@ -0,0 +1,16 @@
1
+ require_relative "IO/MIDI.rb"
2
+ require_relative "Track"
3
+
4
+ class Midi
5
+ attr_reader :tracks, :dtime
6
+
7
+ def initialize()
8
+ @tracks = []
9
+ @dtime = 480
10
+ end
11
+
12
+ def initialize(dtime, track_num)
13
+ @tracks = Array.new(track_num, Track.new([]))
14
+ @dtime = dtime
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ require_relative "Event"
2
+ require_relative "Track"
3
+
4
+ require_relative "Generator/Random"
5
+ require_relative "Generator/Schenker"
6
+
7
+ class MelodyGenerater
8
+ def initialize(dtime, scale, chord, key = nil)
9
+ @chord = chord
10
+ @dtime = dtime
11
+ @note_times = [dtime/8, dtime/4, dtime/2, dtime, dtime*2, dtime*4]
12
+ @scale = scale
13
+ @key = key
14
+ @measure = dtime * 4
15
+ end
16
+ end
@@ -0,0 +1,6 @@
1
+ class Object
2
+ def error_puts(name, message)
3
+ STDERR.puts caller[1] + ": " + message + " for " + self.to_s + " (" + name + ")"
4
+ exit(1)
5
+ end
6
+ end
@@ -0,0 +1,20 @@
1
+ module Scale extend self
2
+ MAJOR = ["C", "D", "E", "F", "G", "A", "B"]
3
+ MINOR = ["C", "D", "D#", "F", "G", "G#", "B"]
4
+ PENTATONIC = ["C", "D", "E", "G", "A"]
5
+ WHOLE_TONE = ["C", "D", "E", "F#", "G#", "A#"]
6
+ OKINAWA = ["C", "E", "F", "G", "B"]
7
+ INDIAN = ["C", "C#", "E", "F#", "G", "A", "B"]
8
+ GYPSY = ["C", "C#", "E", "F", "G", "G#", "B"]
9
+ KUMOI = ["C", "D", "D#", "G", "A"]
10
+
11
+ def note_to_n(note)
12
+ map = {"C"=>0, "C#"=>1, "D"=>2, "D#"=>3, "E"=>4, "F"=>5, "F#"=>6, "G"=>7, "G#"=>8, "A"=>9, "A#"=>10, "B"=>11}
13
+ map[note]
14
+ end
15
+
16
+ def number_to_code(number)
17
+ map = {0=>"C", 1=>"C#", 2=>"D", 3=>"D#", 4=>"E", 5=>"F", 6=>"F#", 7=>"G", 8=>"G#", 9=>"A", 10=>"A#", 11=>"B"}
18
+ map[number]
19
+ end
20
+ end
@@ -0,0 +1,85 @@
1
+ require_relative "Object"
2
+
3
+ class Track < Object
4
+ def initialize(events = [])
5
+ @events = events
6
+ end
7
+
8
+ def [](index)
9
+ @events[index]
10
+ end
11
+
12
+ def []=(index, obj)
13
+ if obj.class.to_s == "Event"
14
+ @events[index] = obj
15
+ else
16
+ self.error_puts("ArgumentTypeError", "undefined method `+'")
17
+ end
18
+ end
19
+
20
+ def insert(index, *objs)
21
+ objs.each {|e|
22
+ if e.class.to_s != "Event"
23
+ self.error_puts("ArgumentTypeError", "undefined method `+'")
24
+ end
25
+ }
26
+ @events.insert(index, *objs)
27
+ end
28
+
29
+ def push(obj)
30
+ if obj.class.to_s == "Event"
31
+ @events.push(obj)
32
+ else
33
+ self.error_puts("ArgumentTypeError", "undefined method `+'")
34
+ end
35
+ self
36
+ end
37
+
38
+ def unshift(obj)
39
+ if obj.class.to_s == "Event"
40
+ @events.unshift(obj)
41
+ else
42
+ self.error_puts("ArgumentTypeError", "undefined method `+'")
43
+ end
44
+ self
45
+ end
46
+
47
+ def each()
48
+ @events.each {|e|
49
+ yield(e)
50
+ }
51
+ end
52
+
53
+ def each_with_index()
54
+ @events.each {|e|
55
+ yield(e)
56
+ }
57
+ end
58
+
59
+ def map()
60
+ result = @events.map {|e|
61
+ yield(e)
62
+ }
63
+ Track.new(result)
64
+ end
65
+
66
+ def map!()
67
+ @events.map! {|e|
68
+ yield(e)
69
+ }
70
+ end
71
+
72
+ def +(other)
73
+ tmp = []
74
+ if other.class.to_s == "Track"
75
+ tmp.push(@events)
76
+ other.each{|e|
77
+ tmp.push(e)
78
+ }
79
+ tmp.flatten!
80
+ else
81
+ self.error_puts("ArgumentTypeError", "undefined method `+'")
82
+ end
83
+ Track.new(tmp)
84
+ end
85
+ end
@@ -0,0 +1,3 @@
1
+ module Kuromusic
2
+ VERSION = "0.0.1"
3
+ end
data/lib/kuromusic.rb ADDED
@@ -0,0 +1,4 @@
1
+ require "kuromusic/version"
2
+ require_relative "kuromusic/MIDI"
3
+ require_relative "kuromusic/Scale"
4
+ require_relative "kuromusic/MelodyGenerater"
@@ -0,0 +1,17 @@
1
+ require_relative "../KuroMusic"
2
+
3
+ DELTA_TIME = 480
4
+ midi = Midi.new(DELTA_TIME, 2)
5
+ melo = MelodyGenerater.new(DELTA_TIME, Scale::MAJOR, []).extend(MelodyGenerater::Schenker)
6
+
7
+ a_can = melo.cantus(5).unshift(Event::Meta::set_tempo(171))
8
+ b_can = melo.cantus(5)#.unshift(Event::Meta::set_tempo(140))
9
+ s_can = melo.cantus(10)#.unshift(Event::Meta::set_tempo(190))
10
+
11
+ a_bas = melo.base(5).unshift(Event::Meta::set_tempo(171))
12
+ b_bas = melo.base(5)#.unshift(Event::Meta::set_tempo(140))
13
+ s_bas = melo.base(10)#.unshift(Event::Meta::set_tempo(190))
14
+
15
+ midi.tracks[0] = a_can + b_can + s_can + a_can + b_can + s_can + a_can
16
+ midi.tracks[1] = a_bas + b_bas + s_bas + a_bas + b_bas + s_bas + a_bas
17
+ Midi::IO.write("../../hoge3.mid", midi)
metadata ADDED
@@ -0,0 +1,97 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kuromusic
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - "黒澤 預生"
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-06-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ description: KuroMusic is midi controll library writed by ruby.
42
+ email:
43
+ - yonamachan3@gmail.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - ".gitignore"
49
+ - Gemfile
50
+ - LICENSE.txt
51
+ - README.md
52
+ - Rakefile
53
+ - kuromusic.gemspec
54
+ - lib/kuromusic.rb
55
+ - lib/kuromusic/ChordProgressionGenerator.rb
56
+ - lib/kuromusic/Event.rb
57
+ - lib/kuromusic/Event/EventType.rb
58
+ - lib/kuromusic/Event/MetaEvent.rb
59
+ - lib/kuromusic/Event/NoteEvent.rb
60
+ - lib/kuromusic/Generator/Random.rb
61
+ - lib/kuromusic/Generator/Schenker.rb
62
+ - lib/kuromusic/IO/MIDI.rb
63
+ - lib/kuromusic/IO/MIDI/MidiEvent.rb
64
+ - lib/kuromusic/IO/MIDI/MidiTrack.rb
65
+ - lib/kuromusic/Key.rb
66
+ - lib/kuromusic/MIDI.rb
67
+ - lib/kuromusic/MelodyGenerater.rb
68
+ - lib/kuromusic/Object.rb
69
+ - lib/kuromusic/Scale.rb
70
+ - lib/kuromusic/Track.rb
71
+ - lib/kuromusic/version.rb
72
+ - lib/sample/main.rb
73
+ homepage: ''
74
+ licenses:
75
+ - MIT
76
+ metadata: {}
77
+ post_install_message:
78
+ rdoc_options: []
79
+ require_paths:
80
+ - lib
81
+ required_ruby_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ required_rubygems_version: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ requirements: []
92
+ rubyforge_project:
93
+ rubygems_version: 2.4.8
94
+ signing_key:
95
+ specification_version: 4
96
+ summary: KuroMusic is midi controll library writed by ruby.
97
+ test_files: []