Module: Webmidi::Message::Parser
- Defined in:
- lib/webmidi/message/parser.rb
Constant Summary collapse
- CHANNEL_LENGTHS =
{ 0x80 => 3, 0x90 => 3, 0xA0 => 3, 0xB0 => 3, 0xC0 => 2, 0xD0 => 2, 0xE0 => 3 }.freeze
- SYSTEM_LENGTHS =
{ 0xF1 => 2, 0xF2 => 3, 0xF3 => 2, 0xF6 => 1, 0xF8 => 1, 0xFA => 1, 0xFB => 1, 0xFC => 1, 0xFE => 1, 0xFF => 1 }.freeze
- REAL_TIME_STATUSES =
[0xF8, 0xFA, 0xFB, 0xFC, 0xFE, 0xFF].freeze
- INVALID_SYSTEM_STATUSES =
[0xF4, 0xF5, 0xF7, 0xF9, 0xFD].freeze
Class Method Summary collapse
- .parse_many(bytes, normalize_note_on_zero: true) ⇒ Object
- .parse_single(bytes, normalize_note_on_zero: true) ⇒ Object
- .parse_stream(bytes, running_status: true, normalize_note_on_zero: true) ⇒ Object
Class Method Details
.parse_many(bytes, normalize_note_on_zero: true) ⇒ Object
68 69 70 |
# File 'lib/webmidi/message/parser.rb', line 68 def parse_many(bytes, normalize_note_on_zero: true) parse_stream(bytes, running_status: false, normalize_note_on_zero: normalize_note_on_zero) end |
.parse_single(bytes, normalize_note_on_zero: true) ⇒ 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 |
# File 'lib/webmidi/message/parser.rb', line 34 def parse_single(bytes, normalize_note_on_zero: true) bytes = validate_bytes!(bytes) raise InvalidMessageError, "Empty message" if bytes.empty? status = bytes[0] validate_status!(status) if status == 0xF0 return parse_sysex(bytes) end validate_exact_length!(bytes, (status)) validate_data_bytes!(bytes[1..]) case status & 0xF0 when 0x80 parse_note_off(bytes) when 0x90 parse_note_on(bytes, normalize_note_on_zero: normalize_note_on_zero) when 0xA0 parse_polyphonic_pressure(bytes) when 0xB0 parse_control_change(bytes) when 0xC0 parse_program_change(bytes) when 0xD0 parse_channel_pressure(bytes) when 0xE0 parse_pitch_bend(bytes) when 0xF0 parse_system(bytes) end end |
.parse_stream(bytes, running_status: true, normalize_note_on_zero: true) ⇒ Object
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 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 |
# File 'lib/webmidi/message/parser.rb', line 72 def parse_stream(bytes, running_status: true, normalize_note_on_zero: true) bytes = validate_bytes!(bytes) = [] pending = [] needed = nil last_channel_status = nil bytes.each do |byte| if real_time_status?(byte) << parse_single([byte], normalize_note_on_zero: normalize_note_on_zero) next end if pending.empty? if byte < 0x80 raise InvalidMessageError, "Data byte #{format_byte(byte)} without status" unless running_status && last_channel_status pending = [last_channel_status, byte] needed = (last_channel_status) else validate_status!(byte) pending = [byte] needed = (byte == 0xF0) ? :sysex : (byte) last_channel_status = channel_status?(byte) ? byte : nil end elsif needed == :sysex validate_sysex_data_or_end!(byte) pending << byte else raise InvalidMessageError, "Unexpected status byte #{format_byte(byte)} inside message" if byte >= 0x80 pending << byte end next unless (pending, needed) << parse_single(pending, normalize_note_on_zero: normalize_note_on_zero) pending = [] needed = nil end raise_incomplete!(pending, needed) unless pending.empty? end |