juicy 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NDk5YWVkNTIyMzU4OWQyOGE3NmM4MTllYWMwODFhMTJiNmZmMmU1Nw==
4
+ YjIwNTk4OWI5YjJhM2M1N2Q2MjEwMGRiN2Q5ZjVlNjk0YzgzMzQzNg==
5
5
  data.tar.gz: !binary |-
6
- MGRiOTRkYzRiOWQzYmFhNWUyNjZmOWIzNzNlY2JmNzJjYjA5NTBjOQ==
6
+ MGNjOWNlMDBkMzVmMWUzNjE5YTQxY2RiZmVjMTJjOWQxOWExZWQ2ZA==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- MzMyOTllNGI2ZmRhODIzYjg4ZjA4ODIwYWMwMGYwNTUyN2Y3MTdiODQ0N2Uw
10
- N2I0MjJhN2MwZjk1ZjAxMTM4YTdiOGEzNWMxZWUwYmJjNWJjZTAyZjVkN2Uw
11
- YWRmZjM3ZDUyOTMwZGIyNDY4MjMyOGEyM2M5ZTZhMzY5YzVjYTM=
9
+ NWYyOTgxNzQ5ZjViZDIxNzA3YjFiMTdlZjA3ODRjMWZmOGUwODAxZTk3YWFk
10
+ ZTA1M2JjMTMzMTk3YzllZjhkZGU3MGY2ZGEwN2RlM2U2M2U3NzExODYxZmU4
11
+ NTVmODFiODE0YmY4ZGNlNWNhN2I2OWIzYzZhOGJlODY2ZjU2YmU=
12
12
  data.tar.gz: !binary |-
13
- NjlkMjZmNGNlMmUxMzU3NzUyNmFlNGViNzM0MWU4MTMzNjYwNmIwMzk5Yjdl
14
- YjhmYjdlOWUzYjMzZmRlNmZlMzhkOTBmMjQyZGNlMmNkOTBjNzc1MmZkZjlm
15
- MzFkYzg4NDU0YjJiNzE3MjYyZGFhYWZkMzQwYTQ1NjMyZTU5MDY=
13
+ ZTA5N2E4NDA1NWRlZmJkMTdhOWQ5M2VlN2Y0ZjM5ZDhkZDI1MmNmZmZlY2Fm
14
+ NDlkYzA0ZDI2Nzk5ODlhMTQ2MDlhMDQ3Nzg5MWM3NGE5Y2Y5ZTE4YzA1YjY4
15
+ MmNlMzIzODNjMGZmNTkyMWE1MjRkMjFiYTY5NWQ1Yzc5MDUzNzQ=
@@ -1,4 +1,4 @@
1
- require_relative '../lib/juicy.rb'
1
+ require 'juicy'
2
2
  include Juicy
3
3
  play = true
4
4
  # To make a pitch, give it a frequency.
@@ -45,7 +45,8 @@ sleep 0.3
45
45
  puts "----------"
46
46
  # Of course, this is cumbersome to do all on our own,
47
47
  # so you have a Scale available to you.
48
- scale = Scale.new(:major, Note.new(name: "D", octave_change: -1))
48
+ root = Note.new(name: "D", octave_change: -1)
49
+ scale = Scale.new(mode: :major, root: root)
49
50
  puts scale
50
51
  scale.each_note do |note|
51
52
  note.play if play
@@ -63,13 +64,13 @@ end
63
64
  # and a beat sequencer to bring it all together.
64
65
 
65
66
  sleep 0.3
66
- scale = Scale.new(:major, Note.new(name: "G", octave_change: -1))
67
+ root = Note.new(name: "G", octave_change: -1)
68
+ scale = Scale.new(mode: :major, root: root)
67
69
  puts scale
68
70
  scale.each_note do |note|
69
71
  note.play if play
70
72
  end
71
73
 
72
- puts
73
74
 
74
75
  # threads = []
75
76
  #
@@ -1,19 +1,18 @@
1
- # require 'win32-sound'
1
+
2
2
  #require 'pry'
3
3
  require 'sound'
4
4
 
5
- require_relative 'juicy/pitch' #toned (or not) frequency in a chosen pitch space (temperament/intonation)
6
- require_relative 'juicy/note' #named pitch
7
- require_relative 'juicy/duration' #length of note in musical time (quarter note, eighth note, etc.)
8
- require_relative 'juicy/chord' #collection of notes
9
- require_relative 'juicy/chord_progression' #collection of chords in sequence
10
- require_relative 'juicy/melody' #collection of chords in sequence
11
-
12
- require_relative 'juicy/scale' #sequence of relative pitch changes ex. chromatic, diatonic, whole-note, pentatonic
13
- require_relative 'juicy/mode' #'flavor' of diatonic scale
14
- require_relative 'juicy/scale_degree' #index of given scale relative to root/tonic
15
- require_relative 'juicy/key' #scale at a given root note, i.e. Juicy::Note
16
- require_relative 'juicy/voice' #an instrument
17
- require_relative 'juicy/measure' #a measure of beats
18
- require_relative 'juicy/track' #a track of notes
19
- require_relative 'juicy/song' #
5
+ require 'juicy/pitch' #toned (or not) frequency in a chosen pitch space (temperament/intonation)
6
+ require 'juicy/note' #named pitch
7
+ require 'juicy/duration' #length of note in musical time (quarter note, eighth note, etc.)
8
+ require 'juicy/chord' #collection of notes
9
+ require 'juicy/chord_progression' #collection of chords in sequence
10
+ require 'juicy/melody' #collection of chords in sequence
11
+ require 'juicy/scale' #sequence of relative pitch changes ex. chromatic, diatonic, whole-note, pentatonic
12
+ require 'juicy/mode' #'flavor' of diatonic scale
13
+ require 'juicy/scale_degree' #index of given scale relative to root/tonic
14
+ require 'juicy/key' #scale at a given root note, i.e. Juicy::Note
15
+ require 'juicy/voice' #an instrument
16
+ require 'juicy/measure' #a measure of beats
17
+ require 'juicy/track' #a track of notes
18
+ require 'juicy/song' #
@@ -6,8 +6,7 @@ module Juicy
6
6
  :major => [0, 4, 7],
7
7
  :minor => [0, 3, 7],
8
8
  :diminished => [0, 3, 6],
9
- :augmented => [0, 4, 8],
10
-
9
+ :augmented => [0, 4, 8]
11
10
  }
12
11
 
13
12
  attr_reader :duration, :notes
@@ -5,23 +5,31 @@ module Juicy
5
5
 
6
6
  class Mode
7
7
 
8
- attr_reader :rotate
8
+ attr_reader :rotate, :type
9
9
 
10
- def initialize(type = :ionian)
11
- @type = type
12
- @rotate = case @type
13
- when :major
14
- 0
15
- when :minor
16
- -2
17
- else
18
- 0
19
- end
20
- end
21
-
22
- def to_s
23
- "#{@type}"
24
- end
10
+ def initialize(type = :ionian)
11
+ @type = type
12
+ @rotate = case @type
13
+ when :major
14
+ 0
15
+ when :minor
16
+ -2
17
+ else
18
+ 0
19
+ end
20
+ end
21
+
22
+ def to_s
23
+ "#{@type}"
24
+ end
25
+
26
+ def ==(other_mode)
27
+ if other_mode.kind_of? Mode
28
+ type == other_mode.type
29
+ elsif other_mode.kind_of? Symbol
30
+ type == other_mode
31
+ end
32
+ end
25
33
 
26
34
  end
27
35
 
@@ -4,7 +4,10 @@ module Juicy
4
4
 
5
5
  include Comparable
6
6
 
7
- @@default_octave = 5
7
+ class << self
8
+ attr_reader :default_octave
9
+ end
10
+ @default_octave = 5
8
11
  attr_reader :name, :pitch, :duration, :octave, :occupying_beat
9
12
  attr_accessor :sum_of_queued_note_durations, :how_far_into_the_song_you_are
10
13
  attr_accessor :distance_from_beat_in_milliseconds
@@ -16,7 +19,7 @@ module Juicy
16
19
  @name = parse_note_name(options[:name])
17
20
  @pitch = Pitch.new(@name)
18
21
  @duration = Duration.new(options[:duration])
19
- @octave = @@default_octave + options[:octave_change]
22
+ @octave = Note.default_octave + options[:octave_change]
20
23
  end
21
24
 
22
25
  def to_s
@@ -25,46 +28,38 @@ module Juicy
25
28
  name += "b" if @name=~/flat/
26
29
  "#{name}#{@octave}"
27
30
  end
28
-
31
+
29
32
  def inspect
30
- "#{@name}"
33
+ "#{@name}#{@octave}"
31
34
  end
32
35
 
33
- def play(options = {duration: 200, octave: (@octave-@@default_octave)})
36
+ def play(options = {duration: 200, octave: (@octave-Note.default_octave)})
34
37
  if @name == :_
35
38
  options[:volume] = 0
36
39
  end
37
40
  @pitch.play(options)
38
41
  end
39
42
 
40
- def prepare(options = {duration: 200, octave: (@octave-@@default_octave)})
43
+ def prepare(options = {duration: 200, octave: (@octave-Note.default_octave)})
41
44
  options[:duration] = options[:duration] || 200
42
- options[:octave] = options[:octave] || (@octave-@@default_octave)
45
+ options[:octave] = options[:octave] || (@octave-Note.default_octave)
43
46
  if @name == :_
44
47
  options[:volume] = 0
45
48
  end
46
49
  Thread.pass
47
50
  @prepared_note = @pitch.prepare(options)
48
51
  @prepared_note[:sleep_time] = @distance_from_beat_in_milliseconds/1000.0
49
- #puts @prepared_note.status
50
52
  until @prepared_note.status.eql? "sleep"
51
53
  sleep 0.001
52
- #puts @prepared_note.status
53
54
  end
54
55
  @prepared_note
55
56
  self
56
57
  end
57
58
 
58
59
  def play_prepared
59
- #puts @prepared_note.status
60
- #puts "playing"
61
60
  until @prepared_note.status.eql? "sleep"
62
61
  sleep 0.001
63
- #puts @prepared_note.status
64
- #Thread.pass
65
62
  end
66
- #Thread.pass
67
- #puts "waking up"
68
63
  @prepared_note.wakeup
69
64
  end
70
65
 
@@ -114,10 +109,6 @@ module Juicy
114
109
  @duration.duration_in_milliseconds(tempo)
115
110
  end
116
111
 
117
- def self.default_octave
118
- @@default_octave
119
- end
120
-
121
112
  def plays_during(beat)
122
113
  @occupying_beat = beat
123
114
  end
@@ -133,7 +124,7 @@ module Juicy
133
124
  private
134
125
 
135
126
  def octave_change
136
- @octave - @@default_octave + @step/12
127
+ @octave - Note.default_octave + @step/12
137
128
  end
138
129
 
139
130
  def step(interval)
@@ -147,21 +138,19 @@ module Juicy
147
138
  def parse_note_name(name)
148
139
  # parses note name input
149
140
  # user should be able to say "A#" or "a#" or "a sharp" or "A_sharp" or "a_s"
150
- groups = name.to_s.match(/([a-gA-G])( |_)?(.*)/)
151
- #binding.pry
152
- puts "name: #{name}" if groups.nil?
153
- if name.to_s.match "rest"
141
+ groups = name.to_s.match(/(?<name>[a-gA-G])(?<space> |_)?(?<accidental>.*)/)
142
+ if name.to_s.match "rest" || name.to_s.match(/^_$/)
154
143
  note_name = "_"
155
144
  else
156
- note_name = groups[1].upcase
157
- unless groups[3].nil? || groups[3].empty?
158
- note_name += case groups[3]
145
+ note_name = groups[:name].upcase
146
+ unless groups[:accidental].nil? || groups[:accidental].empty?
147
+ note_name += case groups[:accidental]
159
148
  when /^(s|#)/
160
149
  "_sharp"
161
150
  when /^(f|b)/
162
151
  "_flat"
163
152
  else
164
- puts "Unknown note modifier: '#{groups[3]}'"
153
+ puts "Unknown note modifier: '#{groups[:accidental]}'"
165
154
  ""
166
155
  end
167
156
  end
@@ -30,20 +30,25 @@ module Juicy
30
30
  class Pitch
31
31
 
32
32
  include Comparable
33
- @@temperament = :equal
34
- @@pitch_standard = 440.0
33
+ @temperament = :equal
34
+ @pitch_standard = 440.0
35
+
36
+ class << self
37
+ attr_reader :temperament, :pitch_standard
38
+ end
35
39
 
36
40
  attr_reader :frequency, :confidence
37
41
 
38
- def initialize(pitch = @@pitch_standard, tune_now = true)
42
+ def initialize(pitch = Pitch.pitch_standard, tune_now = true)
39
43
 
40
44
  if pitch.kind_of? Numeric
41
45
  @frequency = pitch
42
46
  @tuned = false
43
47
  tune if tune_now
44
48
  else
49
+ raise ArgumentError unless pitch.kind_of? Symbol
45
50
  step = PITCHES[pitch.to_sym]
46
- @frequency = @@pitch_standard*2**(step/12.0)
51
+ @frequency = Pitch.pitch_standard*2**(step/12.0)
47
52
  @tuned = true
48
53
  end
49
54
 
@@ -57,7 +62,7 @@ module Juicy
57
62
  if out_of_tune
58
63
  step = Math.log(@frequency/440.0,2)*12
59
64
  @confidence = (1.0-2*(step - step.round).abs)*100.0
60
- @frequency = @@pitch_standard*2**((step.round)/12.0)
65
+ @frequency = Pitch.pitch_standard*2**((step.round)/12.0)
61
66
  @tuned = true
62
67
  end
63
68
  self
@@ -80,7 +85,10 @@ module Juicy
80
85
  options[:duration] ||= 200
81
86
  options[:octave] ||= 0
82
87
  options[:volume] ||= 1
83
- ::Sound::Out.play_freq(@frequency*2**(options[:octave]), options[:duration], options[:volume])
88
+ device = Sound::Device.new
89
+ data = Sound::Data.new(device.format)
90
+ data.generate_sine_wave(@frequency*2**(options[:octave]), options[:duration], options[:volume])
91
+ device.play data
84
92
  end
85
93
 
86
94
  def prepare(options = {duration: 200, octave: 0, volume: 1})
@@ -102,7 +110,7 @@ module Juicy
102
110
  end
103
111
 
104
112
  def change_by (interval)
105
- if @@temperament.eql? :equal
113
+ if Pitch.temperament.eql? :equal
106
114
  Pitch.new(@frequency*2**(interval/12.0))
107
115
  end
108
116
  end
@@ -24,9 +24,13 @@ module Juicy
24
24
 
25
25
  class Scale
26
26
  include Enumerable
27
+
28
+ attr_reader :root, :mode
27
29
 
28
- def initialize(type = :major, root = Note.new)
29
- case type
30
+ def initialize(options = {mode: :major, root: Note.new})
31
+ options[:mode] ||= :major
32
+ options[:root] ||= Note.new
33
+ case options[:mode]
30
34
  when :major
31
35
  @type = :diatonic
32
36
  when :minor
@@ -34,8 +38,8 @@ module Juicy
34
38
  else
35
39
  @type = type
36
40
  end
37
- @mode = Mode.new(type)
38
- @root = root
41
+ @mode = Mode.new(options[:mode])
42
+ @root = options[:root]
39
43
  generate_notes
40
44
 
41
45
  end
@@ -49,7 +53,7 @@ module Juicy
49
53
  end
50
54
 
51
55
  def play
52
-
56
+ each_note &:play
53
57
  end
54
58
 
55
59
  def mode=(type)
@@ -72,9 +76,13 @@ module Juicy
72
76
  end
73
77
  end
74
78
 
75
- def each_note
76
- (SCALE_TYPES[@type].size+1).times do
77
- yield @notes.next
79
+ def each_note &block
80
+ if block_given?
81
+ (SCALE_TYPES[@type].size+1).times do
82
+ yield @notes.next
83
+ end
84
+ else
85
+ @notes
78
86
  end
79
87
  end
80
88
 
@@ -98,6 +106,48 @@ module Juicy
98
106
  half_steps
99
107
  end
100
108
 
109
+ def do
110
+ if @mode == :major
111
+ @root
112
+ end
113
+ end
114
+
115
+ def re
116
+ if @mode == :major
117
+ @root + 2
118
+ end
119
+ end
120
+
121
+ def mi
122
+ if @mode == :major
123
+ @root + 4
124
+ end
125
+ end
126
+
127
+ def fa
128
+ if @mode == :major
129
+ @root + 5
130
+ end
131
+ end
132
+
133
+ def so
134
+ if @mode == :major
135
+ @root + 7
136
+ end
137
+ end
138
+
139
+ def la
140
+ if @mode == :major
141
+ @root + 9
142
+ end
143
+ end
144
+
145
+ def ti
146
+ if @mode == :major
147
+ @root + 11
148
+ end
149
+ end
150
+
101
151
  private
102
152
 
103
153
  def generate_notes
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: juicy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dominic Muller
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-03 00:00:00.000000000 Z
11
+ date: 2014-08-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sound
@@ -19,7 +19,7 @@ dependencies:
19
19
  version: '0.0'
20
20
  - - ! '>='
21
21
  - !ruby/object:Gem::Version
22
- version: 0.0.2
22
+ version: 0.0.6
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
@@ -29,14 +29,28 @@ dependencies:
29
29
  version: '0.0'
30
30
  - - ! '>='
31
31
  - !ruby/object:Gem::Version
32
- version: 0.0.2
32
+ version: 0.0.6
33
+ - !ruby/object:Gem::Dependency
34
+ name: rspec
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ~>
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ~>
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
33
47
  description: Generates songs
34
48
  email: nicklink483@gmail.com
35
49
  executables: []
36
50
  extensions: []
37
51
  extra_rdoc_files: []
38
52
  files:
39
- - bin/juicy.rb
53
+ - examples/juicy.rb
40
54
  - lib/juicy.rb
41
55
  - lib/juicy/chord.rb
42
56
  - lib/juicy/chord_progression.rb