Class: Juicy::Chord

Inherits:
Object
  • Object
show all
Defined in:
lib/juicy/chord.rb

Constant Summary collapse

QUALITIES =
{
  :major => [0, 4, 7],
  :minor => [0, 3, 7],
  :diminished => [0, 3, 6],
  :augmented => [0, 4, 8]
}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {root: Note.new(name: :C), quality: :major, inversion: 0, context: :none, duration: Duration.new("quarter")}) ⇒ Chord

Returns a new instance of Chord.



15
16
17
18
19
20
21
22
23
24
# File 'lib/juicy/chord.rb', line 15

def initialize(options = {root: Note.new(name: :C), quality: :major, inversion: 0, context: :none, duration: Duration.new("quarter")})
  #binding.pry
  @root = (options[:root].kind_of?(Note) ? options[:root] : Note.new(name: options[:root])) || Note.new(name: :C)
  @quality = options[:quality] || :major
  @inversion = options[:inversion] || 0
  @context = options[:context] || :none
  @duration = options[:duration] || Duration.new("quarter")
 @type = :triad
  @notes = [@root + QUALITIES[@quality][0], @root + QUALITIES[@quality][1], @root + QUALITIES[@quality][2]]
end

Instance Attribute Details

#durationObject (readonly)

Returns the value of attribute duration.



12
13
14
# File 'lib/juicy/chord.rb', line 12

def duration
  @duration
end

#how_far_into_the_song_you_areObject

Returns the value of attribute how_far_into_the_song_you_are.



13
14
15
# File 'lib/juicy/chord.rb', line 13

def how_far_into_the_song_you_are
  @how_far_into_the_song_you_are
end

#notesObject (readonly)

Returns the value of attribute notes.



12
13
14
# File 'lib/juicy/chord.rb', line 12

def notes
  @notes
end

#sum_of_queued_chord_durationsObject

Returns the value of attribute sum_of_queued_chord_durations.



13
14
15
# File 'lib/juicy/chord.rb', line 13

def sum_of_queued_chord_durations
  @sum_of_queued_chord_durations
end

Instance Method Details

#+(interval) ⇒ Object



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/juicy/chord.rb', line 71

def +(interval)
  #in the context of a scale, change the base pitch to the new scale
  # degree and the quality to match
  
  #in a context of :none, change the base pitch
  # up a half step times the interval
  if @context.eql? :none
    options = {
      root: (Pitch.new(@root) + interval).frequency,
      quality: @quality,
      inversion: @inversion,
      context: @context
    }
    Chord.new(options)
  end
end

#-(interval) ⇒ Object



88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/juicy/chord.rb', line 88

def -(interval)
  
  if @context.eql? :none
    options = {
      root: (Pitch.new(@root) - interval).frequency,
      quality: @quality,
      inversion: @inversion,
      context: @context
    }
    Chord.new(options)
  end
end

#cycle(direction = :up, amount = 1) ⇒ Object Also known as: invert



101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/juicy/chord.rb', line 101

def cycle(direction = :up, amount = 1)
  #inverts the chord
  # ex. 1, 3, 5 -> cycle(:up, 2) -> 5, 1, 3
  case direction
  when :up
    @inversion = @inversion + amount
  when :down
    @inversion = @inversion - amount
  else
    puts "Unknown Direction"
  end
  puts self.inspect
end

#duration_in_milliseconds(tempo) ⇒ Object



148
149
150
# File 'lib/juicy/chord.rb', line 148

def duration_in_milliseconds(tempo)
  @duration.duration_in_milliseconds(tempo)
end

#initial_play_timeObject



144
145
146
# File 'lib/juicy/chord.rb', line 144

def initial_play_time
  @initial_play_time
end

#initial_play_time=(time) ⇒ Object



140
141
142
# File 'lib/juicy/chord.rb', line 140

def initial_play_time=(time)
  @initial_play_time = time
end

#inspectObject



30
31
32
# File 'lib/juicy/chord.rb', line 30

def inspect
  "#{@root.name} #{@quality} Chord, inversion: #{@inversion}"
end

#play(options = {duration: 200, style: :default}) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/juicy/chord.rb', line 34

def play(options = {duration: 200, style: :default})

  #Quick and dirty play function.  Not intended for genuine use

  duration = options[:duration] || 200
  style = options[:style] || :default
  notes = []
  pitches = QUALITIES[@quality]
  inversion = @inversion
  
  while inversion > 0
    pitches = pitches[1..-1] + [(pitches[0]+12)]
    inversion -= 1
  end
  
  pitches.each do |interval|
    notes << Note.new(name: PITCHES.key((PITCHES[@root.name]+interval) % 12))
  end
  
  case style
  when :arpeggiate
    notes.each do |note|
      Thread.new{note.play(duration: duration)}.join
    end
  when :default
    threads = []
    notes.each do |note|
      threads << Thread.new{note.play(duration: duration)}
    end
    threads.each {|t| t.join}
  else
    puts "Unknown style type"
  end
  
  self
end

#play_preparedObject



127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/juicy/chord.rb', line 127

def play_prepared
  th = []
  #puts @prepared_notes.inspect
  @prepared_notes.each do |note|
    th << Thread.new {
      note.play_prepared.join
      
      
    }
  end
 th.each {|t| t.join}
end

#prepare(options = {duration: 200, octave: (@octave-Note.default_octave)}) ⇒ Object



117
118
119
120
121
122
123
124
125
# File 'lib/juicy/chord.rb', line 117

def prepare(options = {duration: 200, octave: (@octave-Note.default_octave)})
  @prepared_notes = []
  @notes.each do |note|
    options[:duration] = options[:duration] || 200
    options[:octave] = options[:octave] || (note.octave-Note.default_octave)
    
    @prepared_notes << note.prepare(options)
  end
end

#to_sObject



26
27
28
# File 'lib/juicy/chord.rb', line 26

def to_s
  "chord type: #{@type}, quality: #{@quality}, root: #{@root}, inversion: #{@inversion}"
end