music_theory 0.0.1
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 +7 -0
- data/.gitignore +20 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +31 -0
- data/Rakefile +2 -0
- data/lib/music_theory.rb +18 -0
- data/lib/music_theory/chord.rb +37 -0
- data/lib/music_theory/harmonize.rb +26 -0
- data/lib/music_theory/modes.rb +33 -0
- data/lib/music_theory/note.rb +59 -0
- data/lib/music_theory/octave.rb +35 -0
- data/lib/music_theory/output.rb +30 -0
- data/lib/music_theory/play.rb +20 -0
- data/lib/music_theory/scale.rb +70 -0
- data/lib/music_theory/third.rb +37 -0
- data/lib/music_theory/transpose.rb +26 -0
- data/lib/music_theory/version.rb +3 -0
- data/music_theory.gemspec +27 -0
- metadata +132 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c15cd87fabd67ca0ede6f68605d580bc3cc7ba2d
|
4
|
+
data.tar.gz: 0e93f91ed13aca5f3fc89e35b5084571bf3b7333
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6b92d549db767e82445777e9224badc158750ec740a2eaf292fc5071f2ffc944b6355907423b1e0e8c4269a6c6f52614f1d3db8c6c4f21a9ef53be316d7cf19d
|
7
|
+
data.tar.gz: 7b52db9f8d81ed3bce32b9ce275b81087e8d388a92a196f0691c78a4651ce883497eabc73638002fe91d26383d40113a26c7c7c7f7f38b1789c6ba6c1385c59d
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Ben Eggett
|
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,31 @@
|
|
1
|
+
# MusicTheory
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'music_theory'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install music_theory
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
TODO: Write usage instructions here
|
24
|
+
|
25
|
+
## Contributing
|
26
|
+
|
27
|
+
1. Fork it ( https://github.com/[my-github-username]/music_theory/fork )
|
28
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
29
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
30
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
31
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/lib/music_theory.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'wavefile'
|
2
|
+
require 'active_support/all'
|
3
|
+
|
4
|
+
require "music_theory/version"
|
5
|
+
require "music_theory/note"
|
6
|
+
require "music_theory/octave"
|
7
|
+
require "music_theory/scale"
|
8
|
+
require "music_theory/modes"
|
9
|
+
require "music_theory/third"
|
10
|
+
require "music_theory/chord"
|
11
|
+
require "music_theory/harmonize"
|
12
|
+
require "music_theory/output"
|
13
|
+
require "music_theory/play"
|
14
|
+
|
15
|
+
|
16
|
+
module MusicTheory
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'music_theory/output'
|
2
|
+
|
3
|
+
module MusicTheory
|
4
|
+
class Chord
|
5
|
+
include MusicTheory::Output
|
6
|
+
|
7
|
+
attr_accessor :third, :duration, :all_notes, :output_file_name
|
8
|
+
|
9
|
+
def initialize(third, options = {})
|
10
|
+
@duration = options[:duration] || 2.0
|
11
|
+
@third = third
|
12
|
+
@output_file_name = options[:output_file_name] || 'chord' # File name to write (without extension)
|
13
|
+
end
|
14
|
+
|
15
|
+
def flatten_third
|
16
|
+
third.all_notes.each {|note| note.duration = duration}
|
17
|
+
new_samples = []
|
18
|
+
sample_count = third.all_notes.first.samples.count
|
19
|
+
third.samples.in_groups_of(sample_count).each do |group|
|
20
|
+
group.each_with_index do |value, i|
|
21
|
+
new_samples[i] ||= 0
|
22
|
+
new_samples[i] += value
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
max = new_samples.map {|s| s.abs }.max
|
27
|
+
multiplier = 1.0 / max
|
28
|
+
new_samples.map!{ |s| multiplier * s }
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
def samples
|
33
|
+
flatten_third
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'music_theory/output'
|
2
|
+
|
3
|
+
module MusicTheory
|
4
|
+
class Harmonize
|
5
|
+
include MusicTheory::Output
|
6
|
+
|
7
|
+
attr_accessor :samples
|
8
|
+
|
9
|
+
def initialize(*things_to_flatten)
|
10
|
+
@samples = []
|
11
|
+
[*things_to_flatten].each do |group|
|
12
|
+
group.each_with_index do |value, i|
|
13
|
+
@samples[i] ||= 0
|
14
|
+
@samples[i] += value
|
15
|
+
end
|
16
|
+
end
|
17
|
+
max = @samples.map {|s| s.abs }.max
|
18
|
+
multiplier = 1.0 / max
|
19
|
+
@samples.map!{ |s| multiplier * s }
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'music_theory/output'
|
2
|
+
|
3
|
+
module MusicTheory
|
4
|
+
class Modes
|
5
|
+
include MusicTheory::Output
|
6
|
+
S = 1
|
7
|
+
T = 2
|
8
|
+
I = [T, T, S, T, T, T, S]
|
9
|
+
II = I.rotate
|
10
|
+
III = I.rotate(2)
|
11
|
+
IV = I.rotate(3)
|
12
|
+
V = I.rotate(4)
|
13
|
+
VI = I.rotate(5)
|
14
|
+
VII = I.rotate(6)
|
15
|
+
CHROMATIC = [S,S,S,S,S,S,S,S,S,S,S,S]
|
16
|
+
|
17
|
+
# Map the music theory names as class methods
|
18
|
+
|
19
|
+
def self.ionian; I; end
|
20
|
+
self.singleton_class.send(:alias_method, :major, :ionian)
|
21
|
+
def self.dorian; II; end
|
22
|
+
def self.phrygian; III; end
|
23
|
+
def self.lydian; IV; end
|
24
|
+
def self.mixolydian; V; end
|
25
|
+
def self.aeolian; VI; end
|
26
|
+
self.singleton_class.send(:alias_method, :minor, :aeolian)
|
27
|
+
def self.locrian; VII; end
|
28
|
+
def self.chromatic; CHROMATIC; end
|
29
|
+
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'music_theory/output'
|
2
|
+
|
3
|
+
module MusicTheory
|
4
|
+
class Note
|
5
|
+
include MusicTheory::Output
|
6
|
+
attr_accessor :frequency, :duration, :output_file_name, :distort
|
7
|
+
|
8
|
+
def initialize(options = {})
|
9
|
+
@frequency = options[:frequency].to_f || 220.0 # Note frequency in Hz
|
10
|
+
@duration = options[:duration] || 1.0 # Number of seconds per note
|
11
|
+
@distort = options[:distort] || false
|
12
|
+
@output_file_name = options[:output_file_name] || 'note' # File name to write (without extension)
|
13
|
+
end
|
14
|
+
|
15
|
+
def total_frames
|
16
|
+
# We want 1 second of the note, so we need 1 second's worth of frames
|
17
|
+
(duration * sample_rate).to_i
|
18
|
+
end
|
19
|
+
|
20
|
+
def cycles_per_frame
|
21
|
+
# each frame, we want this fraction of a cycle:
|
22
|
+
frequency / sample_rate
|
23
|
+
end
|
24
|
+
|
25
|
+
def sine_wave_cycle
|
26
|
+
# A cycle is a full sine wave, which is 2π radians:
|
27
|
+
2 * Math::PI * cycles_per_frame
|
28
|
+
end
|
29
|
+
|
30
|
+
def samples
|
31
|
+
# So to create a note that's one second long, we need to write out all the samples in the sine waves
|
32
|
+
phase = 0
|
33
|
+
samples = total_frames.times.map do
|
34
|
+
sample = (Math.sin phase).to_f
|
35
|
+
phase += sine_wave_cycle
|
36
|
+
sample
|
37
|
+
end
|
38
|
+
samples = distort!(samples) if distort
|
39
|
+
samples
|
40
|
+
end
|
41
|
+
|
42
|
+
def distort!(samples)
|
43
|
+
samples.map do |sample|
|
44
|
+
negative = (sample) < 0
|
45
|
+
sample *= 8.to_f
|
46
|
+
if sample.abs > 5
|
47
|
+
sample = 5
|
48
|
+
sample *= -1 if negative
|
49
|
+
end
|
50
|
+
sample /= 8.to_f
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def scale
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'music_theory/output'
|
2
|
+
|
3
|
+
module MusicTheory
|
4
|
+
class Octave
|
5
|
+
include MusicTheory::Output
|
6
|
+
attr_accessor :starting_note, :number_of_octaves, :direction, :output_file_name, :all_notes
|
7
|
+
|
8
|
+
def initialize(options = {})
|
9
|
+
@starting_note = options[:starting_note] || MusicTheory::Note.new # Note to start on
|
10
|
+
@number_of_octaves= options[:number_of_octaves] || 2 # Number of octaves to repeat
|
11
|
+
@direction = options[:direction] || 'asc' # Number of seconds per note
|
12
|
+
@output_file_name = options[:output_file_name] || 'octave' # File name to write (without extension)
|
13
|
+
@all_notes = []
|
14
|
+
all_notes << starting_note
|
15
|
+
number_of_octaves.to_i.times do
|
16
|
+
new_note = all_notes.last.clone
|
17
|
+
if direction == 'asc'
|
18
|
+
new_note.frequency = all_notes.last.frequency * 2
|
19
|
+
elsif direction == 'desc'
|
20
|
+
new_note.frequency = all_notes.last.frequency / 2
|
21
|
+
end
|
22
|
+
all_notes << new_note unless new_note.frequency > 20000
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def samples
|
27
|
+
all_notes.map(&:samples).flatten
|
28
|
+
end
|
29
|
+
|
30
|
+
def sample_rate
|
31
|
+
starting_note.sample_rate
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module MusicTheory
|
2
|
+
module Output
|
3
|
+
|
4
|
+
def sample_rate
|
5
|
+
22050
|
6
|
+
end
|
7
|
+
|
8
|
+
def format
|
9
|
+
WaveFile::Format.new :mono, :pcm_16, sample_rate
|
10
|
+
end
|
11
|
+
|
12
|
+
def buffer_format
|
13
|
+
WaveFile::Format.new :mono, :float, sample_rate
|
14
|
+
end
|
15
|
+
|
16
|
+
def output_track
|
17
|
+
WaveFile::Writer.new "#{output_file_name || 'music'}.wav", format do |writer|
|
18
|
+
buffer = WaveFile::Buffer.new samples, buffer_format
|
19
|
+
writer.write buffer
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def play
|
24
|
+
output_track # unless File.file?("#{output_file_name}.wav")
|
25
|
+
`afplay #{output_file_name}.wav`
|
26
|
+
nil
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'music_theory/output'
|
2
|
+
|
3
|
+
module MusicTheory
|
4
|
+
class Play
|
5
|
+
include MusicTheory::Output
|
6
|
+
|
7
|
+
attr_accessor :samples, :output_file_name, :playable_music
|
8
|
+
def initialize(playable_music = [], options = {} )
|
9
|
+
@playable_music = playable_music
|
10
|
+
@output_file_name = options[:output_file_name] || 'music'
|
11
|
+
extract_samples
|
12
|
+
play
|
13
|
+
end
|
14
|
+
|
15
|
+
def extract_samples
|
16
|
+
@samples = playable_music.map { |music| music.samples }.flatten
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'music_theory/output'
|
2
|
+
|
3
|
+
module MusicTheory
|
4
|
+
class Scale
|
5
|
+
include MusicTheory::Output
|
6
|
+
attr_accessor :starting_note, :number_of_octaves, :direction, :output_file_name, :all_notes, :scale_type, :scale_notes, :distort, :duration, :frequency, :sample_rate
|
7
|
+
|
8
|
+
def initialize(scale_type = :major, options = {})
|
9
|
+
@scale_type = scale_type
|
10
|
+
@distort = options[:distort] || false
|
11
|
+
@duration = options[:duration] || 0.5
|
12
|
+
@frequency = options[:frequency] || 220.0
|
13
|
+
@starting_note = create_new_note # Note to start on
|
14
|
+
|
15
|
+
@number_of_octaves= options[:number_of_octaves] || 2 # Number of octaves to repeat
|
16
|
+
@direction = options[:direction] || 'asc' # Number of seconds per note
|
17
|
+
@output_file_name = options[:output_file_name] || 'scale' # File name to write (without extension)
|
18
|
+
set_all_notes
|
19
|
+
set_scale_notes
|
20
|
+
end
|
21
|
+
|
22
|
+
def third
|
23
|
+
third ||= MusicTheory::Third.new self
|
24
|
+
end
|
25
|
+
|
26
|
+
def chord
|
27
|
+
third.chord
|
28
|
+
end
|
29
|
+
|
30
|
+
def twelth_root_of_two
|
31
|
+
(2 ** (1.0/12))
|
32
|
+
end
|
33
|
+
|
34
|
+
def mode
|
35
|
+
MusicTheory::Modes.send(scale_type)
|
36
|
+
end
|
37
|
+
|
38
|
+
def set_scale_notes
|
39
|
+
@scale_notes = [all_notes.first]
|
40
|
+
note_index = 0
|
41
|
+
mode.each do |interval|
|
42
|
+
note_index += interval
|
43
|
+
scale_notes << all_notes[note_index]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def create_new_note
|
48
|
+
MusicTheory::Note.new( frequency: frequency, duration: duration, distort: distort)
|
49
|
+
end
|
50
|
+
|
51
|
+
def set_all_notes
|
52
|
+
@all_notes = [@starting_note]
|
53
|
+
12.times do
|
54
|
+
new_note = create_new_note
|
55
|
+
new_note.frequency = (all_notes.last.frequency * twelth_root_of_two)
|
56
|
+
all_notes << new_note
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def samples
|
61
|
+
scale_notes.map(&:samples).flatten
|
62
|
+
end
|
63
|
+
|
64
|
+
def sample_rate
|
65
|
+
starting_note.sample_rate
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'music_theory/output'
|
2
|
+
|
3
|
+
module MusicTheory
|
4
|
+
class Third
|
5
|
+
include MusicTheory::Output
|
6
|
+
|
7
|
+
attr_accessor :scale, :all_notes
|
8
|
+
|
9
|
+
def initialize(scale)
|
10
|
+
@scale = scale
|
11
|
+
@all_notes = [@scale.scale_notes.first]
|
12
|
+
current = 0
|
13
|
+
double_scale_notes = @scale.scale_notes * 2
|
14
|
+
@scale.mode.in_groups_of(2, false) do |group|
|
15
|
+
current += group.sum
|
16
|
+
all_notes << double_scale_notes[current]
|
17
|
+
end
|
18
|
+
all_notes.uniq! {|note| note.frequency}
|
19
|
+
all_notes.sort_by! {|note| note.frequency}
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
def output_file_name
|
24
|
+
scale.output_file_name || 'thirds'
|
25
|
+
end
|
26
|
+
|
27
|
+
def samples
|
28
|
+
all_notes.map(&:samples).flatten
|
29
|
+
# chord_samples
|
30
|
+
end
|
31
|
+
|
32
|
+
def chord
|
33
|
+
chord ||= MusicTheory::Chord.new self
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'music_theory/output'
|
2
|
+
|
3
|
+
module MusicTheory
|
4
|
+
class Transpose
|
5
|
+
include MusicTheory::Output
|
6
|
+
|
7
|
+
attr_accessor :samples
|
8
|
+
|
9
|
+
def initialize(*things_to_flatten)
|
10
|
+
@samples = []
|
11
|
+
[*things_to_flatten].each do |group|
|
12
|
+
group.each_with_index do |value, i|
|
13
|
+
@samples[i] ||= 0
|
14
|
+
@samples[i] += value
|
15
|
+
end
|
16
|
+
end
|
17
|
+
max = @samples.map {|s| s.abs }.max
|
18
|
+
multiplier = 1.0 / max
|
19
|
+
@samples.map!{ |s| multiplier * s }
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'music_theory/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "music_theory"
|
8
|
+
spec.version = MusicTheory::VERSION
|
9
|
+
spec.authors = ["Ben Eggett"]
|
10
|
+
spec.email = ["beneggett@gmail.com"]
|
11
|
+
spec.summary = %q{Music theory with ruby}
|
12
|
+
spec.description = %q{Create music with pure ruby goodness}
|
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_dependency "wavefile"
|
22
|
+
spec.add_dependency "activesupport"
|
23
|
+
|
24
|
+
spec.add_development_dependency "pry"
|
25
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
26
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
27
|
+
end
|
metadata
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: music_theory
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ben Eggett
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-03-09 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: wavefile
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: activesupport
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: pry
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bundler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.7'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.7'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '10.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '10.0'
|
83
|
+
description: Create music with pure ruby goodness
|
84
|
+
email:
|
85
|
+
- beneggett@gmail.com
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- ".gitignore"
|
91
|
+
- Gemfile
|
92
|
+
- LICENSE.txt
|
93
|
+
- README.md
|
94
|
+
- Rakefile
|
95
|
+
- lib/music_theory.rb
|
96
|
+
- lib/music_theory/chord.rb
|
97
|
+
- lib/music_theory/harmonize.rb
|
98
|
+
- lib/music_theory/modes.rb
|
99
|
+
- lib/music_theory/note.rb
|
100
|
+
- lib/music_theory/octave.rb
|
101
|
+
- lib/music_theory/output.rb
|
102
|
+
- lib/music_theory/play.rb
|
103
|
+
- lib/music_theory/scale.rb
|
104
|
+
- lib/music_theory/third.rb
|
105
|
+
- lib/music_theory/transpose.rb
|
106
|
+
- lib/music_theory/version.rb
|
107
|
+
- music_theory.gemspec
|
108
|
+
homepage: ''
|
109
|
+
licenses:
|
110
|
+
- MIT
|
111
|
+
metadata: {}
|
112
|
+
post_install_message:
|
113
|
+
rdoc_options: []
|
114
|
+
require_paths:
|
115
|
+
- lib
|
116
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
117
|
+
requirements:
|
118
|
+
- - ">="
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: '0'
|
121
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - ">="
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
requirements: []
|
127
|
+
rubyforge_project:
|
128
|
+
rubygems_version: 2.4.6
|
129
|
+
signing_key:
|
130
|
+
specification_version: 4
|
131
|
+
summary: Music theory with ruby
|
132
|
+
test_files: []
|