Class: Webmidi::SMF::MetaEvent
Constant Summary collapse
- META_TYPES =
{ sequence_number: 0x00, text: 0x01, copyright: 0x02, track_name: 0x03, instrument_name: 0x04, lyric: 0x05, marker: 0x06, cue_point: 0x07, channel_prefix: 0x20, end_of_track: 0x2F, tempo: 0x51, smpte_offset: 0x54, time_signature: 0x58, key_signature: 0x59, sequencer_specific: 0x7F }.freeze
Instance Attribute Summary collapse
-
#data ⇒ Object
readonly
Returns the value of attribute data.
-
#type ⇒ Object
readonly
Returns the value of attribute type.
Attributes inherited from Event
Class Method Summary collapse
- .end_of_track(**kwargs) ⇒ Object
- .key_signature(key: 0, scale: 0, **kwargs) ⇒ Object
- .tempo(bpm, **kwargs) ⇒ Object
- .text(value, type: :text, encoding: Encoding::UTF_8, **kwargs) ⇒ Object
- .time_signature(numerator: 4, denominator: 4, clocks_per_click: 24, notes_per_quarter: 8, **kwargs) ⇒ Object
- .track_name(name, encoding: Encoding::UTF_8, **kwargs) ⇒ Object
Instance Method Summary collapse
- #bpm ⇒ Object
-
#initialize(type:, data: [], **kwargs) ⇒ MetaEvent
constructor
A new instance of MetaEvent.
- #tempo ⇒ Object
- #text(encoding: Encoding::UTF_8) ⇒ Object
- #text_event? ⇒ Boolean
Constructor Details
#initialize(type:, data: [], **kwargs) ⇒ MetaEvent
Returns a new instance of MetaEvent.
68 69 70 71 72 73 74 |
# File 'lib/webmidi/smf/event.rb', line 68 def initialize(type:, data: [], **kwargs) super(**kwargs) validate_type!(type) validate_data!(data) @type = type @data = data.frozen? ? data : data.dup.freeze end |
Instance Attribute Details
#data ⇒ Object (readonly)
Returns the value of attribute data.
48 49 50 |
# File 'lib/webmidi/smf/event.rb', line 48 def data @data end |
#type ⇒ Object (readonly)
Returns the value of attribute type.
48 49 50 |
# File 'lib/webmidi/smf/event.rb', line 48 def type @type end |
Class Method Details
.end_of_track(**kwargs) ⇒ Object
121 122 123 |
# File 'lib/webmidi/smf/event.rb', line 121 def self.end_of_track(**kwargs) new(type: META_TYPES[:end_of_track], data: [], **kwargs) end |
.key_signature(key: 0, scale: 0, **kwargs) ⇒ Object
140 141 142 143 144 145 146 147 148 149 150 151 152 |
# File 'lib/webmidi/smf/event.rb', line 140 def self.key_signature(key: 0, scale: 0, **kwargs) raise InvalidSMFError, "Key signature must be between -7 and 7, got #{key.inspect}" unless key.is_a?(Integer) && key.between?(-7, 7) scale = case scale when :major then 0 when :minor then 1 else scale end raise InvalidSMFError, "Key signature scale must be 0/:major or 1/:minor" unless [0, 1].include?(scale) sf = (key < 0) ? (256 + key) : key new(type: META_TYPES[:key_signature], data: [sf, scale], **kwargs) end |
.tempo(bpm, **kwargs) ⇒ Object
100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/webmidi/smf/event.rb', line 100 def self.tempo(bpm, **kwargs) raise InvalidSMFError, "Tempo BPM must be positive, got #{bpm.inspect}" unless bpm.is_a?(Numeric) && bpm.positive? microseconds = (60_000_000.0 / bpm).round data = [ (microseconds >> 16) & 0xFF, (microseconds >> 8) & 0xFF, microseconds & 0xFF ] new(type: META_TYPES[:tempo], data: data, **kwargs) end |
.text(value, type: :text, encoding: Encoding::UTF_8, **kwargs) ⇒ Object
112 113 114 115 |
# File 'lib/webmidi/smf/event.rb', line 112 def self.text(value, type: :text, encoding: Encoding::UTF_8, **kwargs) = type.is_a?(Symbol) ? META_TYPES.fetch(type) : type new(type: , data: value.encode(encoding).bytes, **kwargs) end |
.time_signature(numerator: 4, denominator: 4, clocks_per_click: 24, notes_per_quarter: 8, **kwargs) ⇒ Object
125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
# File 'lib/webmidi/smf/event.rb', line 125 def self.time_signature(numerator: 4, denominator: 4, clocks_per_click: 24, notes_per_quarter: 8, **kwargs) unless numerator.is_a?(Integer) && numerator.positive? raise InvalidSMFError, "Time signature numerator must be positive, got #{numerator.inspect}" end unless denominator.is_a?(Integer) && denominator.positive? && (denominator & (denominator - 1)).zero? raise InvalidSMFError, "Time signature denominator must be a power of two, got #{denominator.inspect}" end [clocks_per_click, notes_per_quarter].each do |value| raise InvalidSMFError, "Time signature values must be bytes" unless value.is_a?(Integer) && value.between?(0, 255) end dd = Math.log2(denominator).to_i new(type: META_TYPES[:time_signature], data: [numerator, dd, clocks_per_click, notes_per_quarter], **kwargs) end |
.track_name(name, encoding: Encoding::UTF_8, **kwargs) ⇒ Object
117 118 119 |
# File 'lib/webmidi/smf/event.rb', line 117 def self.track_name(name, encoding: Encoding::UTF_8, **kwargs) text(name, type: :track_name, encoding: encoding, **kwargs) end |
Instance Method Details
#bpm ⇒ Object
93 94 95 96 97 98 |
# File 'lib/webmidi/smf/event.rb', line 93 def bpm t = tempo return nil unless t 60_000_000.0 / t end |
#tempo ⇒ Object
86 87 88 89 90 91 |
# File 'lib/webmidi/smf/event.rb', line 86 def tempo return nil unless @type == META_TYPES[:tempo] return nil unless @data.size == 3 (@data[0] << 16) | (@data[1] << 8) | @data[2] end |
#text(encoding: Encoding::UTF_8) ⇒ Object
76 77 78 79 80 |
# File 'lib/webmidi/smf/event.rb', line 76 def text(encoding: Encoding::UTF_8) return nil unless text_event? @data.pack("C*").force_encoding(encoding) end |
#text_event? ⇒ Boolean
82 83 84 |
# File 'lib/webmidi/smf/event.rb', line 82 def text_event? @type.between?(0x01, 0x07) end |