Class: Ramekin::NoteEvent

Inherits:
Element
  • Object
show all
Includes:
Error::Helpers
Defined in:
lib/ramekin/note_aggregator.rb

Direct Known Subclasses

Bend, CombinedRestEvent, NoteWrapper

Constant Summary collapse

NOTES =
{ 'c' => 0, 'd' => 2, 'e' => 4, 'f' => 5, 'g' => 7, 'a' => 9, 'b' => 11 }

Instance Attribute Summary collapse

Attributes inherited from Element

#channel, #components, #macro_stack, #start_tick

Instance Method Summary collapse

Methods inherited from Element

make

Constructor Details

#initialize(note, octave, triplets, extensions = []) ⇒ NoteEvent

Returns a new instance of NoteEvent.



9
10
11
12
13
14
# File 'lib/ramekin/note_aggregator.rb', line 9

def initialize(note, octave, triplets, extensions=[])
  @note = note
  @octave = octave
  @triplets = triplets
  @extensions = extensions
end

Instance Attribute Details

#extensionsObject (readonly)

Returns the value of attribute extensions.



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

def extensions
  @extensions
end

#noteObject (readonly)

Returns the value of attribute note.



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

def note
  @note
end

#octaveObject (readonly)

Returns the value of attribute octave.



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

def octave
  @octave
end

Instance Method Details

#default_error_locationObject



4
5
6
# File 'lib/ramekin/note_aggregator.rb', line 4

def default_error_location
  self
end

#default_lengthObject



110
111
112
# File 'lib/ramekin/note_aggregator.rb', line 110

def default_length
  @note.meta[:l]
end

#finObject



24
25
26
# File 'lib/ramekin/note_aggregator.rb', line 24

def fin
  (@extensions.last || @note).fin
end

#inspectObject



139
140
141
# File 'lib/ramekin/note_aggregator.rb', line 139

def inspect
  repr
end

#length_amk(div) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/ramekin/note_aggregator.rb', line 49

def length_amk(div)
  return '=0' if ticks == 0

  if ticks % div != 0
    divisible = div == 2 ? 'even' : "divisible by #{div}"
    error!("too fast! tick count must be #{divisible} at this tempo", el: self)
  end

  t = ticks / div

  tie? ? Util.nice_length_amk(t) : Util.extra_nice_length_amk(t)
end

#metaObject



16
17
18
# File 'lib/ramekin/note_aggregator.rb', line 16

def meta
  @note.meta
end

#note_hexObject



63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/ramekin/note_aggregator.rb', line 63

def note_hex
  @note_hex ||= begin
    out = 0x80
    out += 12 * (octave - 1)
    @note.value =~ /(\w)([+-])?/
    out += NOTES.fetch($1) # trust the tokenizer

    out += 1 if $2 == '+'
    out -= 1 if $2 == '-'

    out
  end
end

#note_nameObject



35
36
37
38
39
# File 'lib/ramekin/note_aggregator.rb', line 35

def note_name
  return 'r' if rest?
  return '^' if tie?
  @note.value
end

#octave_amk(current_octave = nil) ⇒ Object



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/ramekin/note_aggregator.rb', line 77

def octave_amk(current_octave=nil)
  return '' if rest? || tie?

  return "o#{octave_num}" if current_octave.nil?

  case octave_num
  when current_octave
    ""
  when current_octave + 1
    ">"
  when current_octave - 1
    "<"
  else
    "o#{octave_num}"
  end
end

#octave_numObject



28
29
30
31
32
33
# File 'lib/ramekin/note_aggregator.rb', line 28

def octave_num
  case @octave
  when Token then @octave.value.to_i
  else @octave.to_i
  end
end

#octave_switching_amk(current_octave) ⇒ Object



94
95
96
97
98
99
100
# File 'lib/ramekin/note_aggregator.rb', line 94

def octave_switching_amk(current_octave)
  diff = octave_num - current_octave

  return '' if diff == 0
  return '<' * (-diff) if diff < 0
  return '>' * diff if diff > 0
end

#reprObject



106
107
108
# File 'lib/ramekin/note_aggregator.rb', line 106

def repr
  "note:#{to_amk}"
end

#rest?Boolean

Returns:

  • (Boolean)


41
42
43
# File 'lib/ramekin/note_aggregator.rb', line 41

def rest?
  @note.type == :r
end

#startObject



20
21
22
# File 'lib/ramekin/note_aggregator.rb', line 20

def start
  @note.start
end

#ticksObject



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/ramekin/note_aggregator.rb', line 114

def ticks
  exts = @extensions
  default = default_length&.value || '16'
  exts = [default] if exts.empty?

  base = exts.map do |ext|
    ext = ext.value if Token === ext
    ext ||= default

    case ext
    when /\A=(\d+)\z/ then $1.to_i
    # special case for a 0-length note, useful for bends
    when '0' then 0
    when /\A(\d+)\z/ then 192 / $1.to_i
    when /\A(\d+)[.]\z/ then 192 * 3 / ($1.to_i * 2)
    else
      error! "unknown length specifier #{ext}", el: ext
    end
  end.sum

  base = (base * 2) / 3 if @triplets

  base
end

#tie?Boolean

Returns:

  • (Boolean)


45
46
47
# File 'lib/ramekin/note_aggregator.rb', line 45

def tie?
  @note.type == :native_tie
end

#to_amk(current_octave = nil, divisor = 1) ⇒ Object



102
103
104
# File 'lib/ramekin/note_aggregator.rb', line 102

def to_amk(current_octave=nil, divisor=1)
  return "#{octave_amk(current_octave)}#{note_name}#{length_amk(divisor)}"
end