Class: Composer

Inherits:
Object show all
Defined in:
lib/composer.rb

Overview

contains the functions a music composer needs. all functions are related to music instead of audio.

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.bpmObject

beats per minute of the track. (Set this first thing in your input file)



6
7
8
# File 'lib/composer.rb', line 6

def bpm
  @bpm
end

.samplerateObject

fames per second



8
9
10
# File 'lib/composer.rb', line 8

def samplerate
  @samplerate
end

.scaleObject

the current scale to be used by many commands that require it. String. def: “major”.



10
11
12
# File 'lib/composer.rb', line 10

def scale
  @scale
end

Class Method Details

.beat(beats) ⇒ Object

convert beats to seconds @beat: the beat denominator. ie 4 means 4 beats, .125 means 1 8th beat.



71
72
73
74
# File 'lib/composer.rb', line 71

def self.beat(beats)
  bps = (self.bpm/60.0)
  return (beats) * (1.0/bps) * self.samplerate.to_f
end

.chordsObject



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/composer.rb', line 12

def self.chords
  all = Hash.new
  #Triads
  all["maj"] = [4, 7] # major
  all["min"] = [3, 7] # minor
  all["aug"] = [4, 8] # augmented
  all["dim"] = [3, 6] # diminished

  #Seventh chords
  all["dim7"] = [3, 6, 9] # diminished 7th
  all["mm7"] = [3, 7, 11] # major minor 7th
  all["min7"] = [3, 7, 10] # minor 7th
  all["dom7"] = [4, 7, 10] # dominant 7th
  all["maj7"] = [4, 7, 11] # major 7th
  # half diminished
  # augmented
  # augmented major

  all["sus4"] = [5, 7]
  all["sus2"] = [2, 7]
  all["6"] = [4, 7, 9]
  all["m13"] = [2, 4, 7, 9, 11]
  all["9#11"] = [2, 4, 6, 7, 10]
  all["tonic"] = [6]
  all
end

.get_notes(notes_ar, offset = 0) ⇒ Object

return an array of notes from a array of notes with an offset, adding the root note at the start. e.g. ([1,10,2],2) outputs [2,3,0,4] (root note is 2, 10 + 2 becomes 0, 1 + 2 is 3 etc)



56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/composer.rb', line 56

def self.get_notes(notes_ar, offset = 0)
  notes = [0] + notes_ar
  #offset
  notes.collect! do |val|
    if offset >= 0
      val+offset>11 ? val+offset-12 : val+offset
    else
      val+offset<0 ? val+offset+12 : val+offset
    end
  end
  notes
end

.matching_chords(offset = 0) ⇒ Object

return set of chord names of chords that fit in the scale, offset upward by offset notes.



77
78
79
80
81
82
83
84
85
86
87
# File 'lib/composer.rb', line 77

def self.matching_chords(offset = 0)
  all = Composer.chords
  scale_n = [0] + Composer.scales[scale] # not offset at all
  out = []
  all.each do |chord|
    name = chord[0]
    notes=Composer.get_notes all[name], offset # lookup chord with name and offset
    out.push name if (scale_n&notes).sort==notes.sort # if all notes are in scale
  end
  out
end

.note_m(note) ⇒ Object

convert a note as a string to midi value

note

range: “A” to “G#”. No a flats.



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/composer.rb', line 91

def self.note_m(note)
  val=nil
  note.upcase!
  case note
  when 'A'
    val=0
  when 'A#'
    val=1
  when 'B'
    val=2
  when 'C'
    val=3
  when 'C#'
    val=4
  when 'D'
    val=5
  when 'D#'
    val=6
  when 'E'
    val=7
  when 'F'
    val=8
  when 'F#'
    val=9
  when 'G'
    val=10
  when 'G#'
    val=11
  else
    raise "Unknown note name recieved."
  end
  val
end

.scalesObject



39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/composer.rb', line 39

def self.scales
  all = Hash.new
  all["major"] = [2,4,5,7,9,11] # 7 total
  all["minor"] = [2,3,5,7,8,10]
  all["chromatic"] = *(1..10) #splat
  #all["ionian"] = [2,4,5,7,9,11]
  all["dorian"] = [2,3,5,7,9,10]
  all["phygian"] = [1,3,5,7,8,10]
  all["lydian"] = [2,4,6,7,9,11]
  all["mixolydian"] = [2,4,5,7,9,10]
  #all["aeolian"] = [2,3,5,7,8,10]
  all["locrian"] = [1,3,5,6,8,10]
  all
end