31 return static_cast<uint16_t
>(
32 (
static_cast<uint32_t
>(v7) * 0xFFFFu + 63u) / 127u);
37 return static_cast<uint8_t
>(
38 (
static_cast<uint32_t
>(v16) * 127u + 0x7FFFu) / 0xFFFFu);
44 constexpr uint32_t src_max = 0x3FFFu;
45 constexpr uint32_t src_center = 0x2000u;
46 constexpr uint64_t dst_center = 0x80000000ull;
47 if (v14 <= src_center) {
48 return static_cast<uint32_t
>((
static_cast<uint64_t
>(v14) * dst_center) / src_center);
50 const uint64_t above =
static_cast<uint64_t
>(v14 - src_center);
51 const uint64_t dst_above_max = 0x7FFFFFFFull;
52 return static_cast<uint32_t
>(dst_center + (above * dst_above_max) / (src_max - src_center));
57 constexpr uint32_t dst_max = 0x3FFFu;
58 constexpr uint32_t dst_center = 0x2000u;
59 constexpr uint64_t src_center = 0x80000000ull;
60 if (v32 <= src_center) {
61 return static_cast<uint16_t
>((
static_cast<uint64_t
>(v32) * dst_center) / src_center);
63 const uint64_t above =
static_cast<uint64_t
>(v32 - src_center);
64 const uint64_t src_above_max = 0x7FFFFFFFull;
65 return static_cast<uint16_t
>(dst_center + (above * (dst_max - dst_center)) / src_above_max);
74 const uint8_t status = ev.
data()[0] & 0xF0;
75 const uint8_t channel = ev.
channel();
77 if (status == 0x90 && ev.
velocity() == 0) {
90 static_cast<uint32_t
>(ev.
cc_value()) << 25);
92 const uint16_t raw =
static_cast<uint16_t
>(
93 ev.
data()[1] | (uint16_t(ev.
data()[2]) << 7));
106 const uint8_t status_byte = ev.
data()[0];
107 const uint32_t mt = (status_byte >= 0xF0) ? 0x1u : 0x2u;
110 p.words[0] = (mt << 28)
111 | (uint32_t(group & 0x0F) << 24)
112 | (uint32_t(status_byte) << 16)
113 | (uint32_t(ev.
size() > 1 ? ev.
data()[1] : 0) << 8)
114 | uint32_t(ev.
size() > 2 ? ev.
data()[2] : 0);
120 for (
const auto& ev : src) {
149 f.program =
static_cast<uint8_t
>((p.words[1] >> 24) & 0x7F);
150 f.bank_valid = (p.words[0] & 0x01u) != 0;
151 f.bank_msb =
static_cast<uint8_t
>((p.words[1] >> 8) & 0x7F);
152 f.bank_lsb =
static_cast<uint8_t
>(p.words[1] & 0x7F);
171 const auto mt = p.message_type();
172 const uint8_t ch = p.channel();
177 const uint8_t s =
static_cast<uint8_t
>((p.words[0] >> 16) & 0xFF);
178 const uint8_t d1 =
static_cast<uint8_t
>((p.words[0] >> 8) & 0xFF);
179 const uint8_t d2 =
static_cast<uint8_t
>(p.words[0] & 0xFF);
180 out = {choc::midi::ShortMessage(s, d1, d2), 0, 0.0};
190 const uint8_t s =
static_cast<uint8_t
>((p.words[0] >> 16) & 0xFF);
191 const uint8_t d1 =
static_cast<uint8_t
>((p.words[0] >> 8) & 0xFF);
192 const uint8_t d2 =
static_cast<uint8_t
>(p.words[0] & 0xFF);
193 out = {choc::midi::ShortMessage(s, d1, d2), 0, 0.0};
198 const uint8_t status_byte =
static_cast<uint8_t
>((p.words[0] >> 16) & 0xF0);
199 switch (status_byte) {
208 const uint16_t v16 = p.velocity_16();
210 if (v16 > 0 && v7 == 0) v7 = 1;
217 out = {choc::midi::ShortMessage(
static_cast<uint8_t
>(0xA0 | (ch & 0x0F)),
219 static_cast<uint8_t
>(p.data_32() >> 25)),
223 out =
MidiEvent::cc(ch,
static_cast<uint8_t
>((p.words[0] >> 8) & 0x7F),
224 static_cast<uint8_t
>(p.data_32() >> 25));
250 out = {choc::midi::ShortMessage(
static_cast<uint8_t
>(0xD0 | (ch & 0x0F)),
251 static_cast<uint8_t
>(p.data_32() >> 25), 0),
267 if ((
static_cast<uint8_t
>((p.words[0] >> 16) & 0xF0)) != 0xC0)
282 for (
const auto& ue : src) {
285 const uint8_t ch = ue.packet.channel();
287 msb.sample_offset = ue.sample_offset;
290 lsb.sample_offset = ue.sample_offset;
Collection of timestamped MIDI events within a single audio buffer period.
Definition buffer.hpp:31
bool add(const MidiEvent &event)
Append a MIDI event to the buffer.
Definition buffer.hpp:98
A time-ordered list of UMP events for one audio block.
Definition ump_buffer.hpp:41
bool add(const UmpEvent &e)
Definition ump_buffer.hpp:63
Definition custom_node_events.hpp:26
uint16_t scale_7_to_16(uint8_t v7)
Scale a 7-bit value (0..127) to 16-bit (0..65535) per MIDI 2.0 spec.
Definition ump_conversion.hpp:29
constexpr uint8_t kBankSelectMsbCc
MIDI 1.0 controller numbers carrying Bank Select for a program change.
Definition ump_conversion.hpp:157
uint32_t scale_14_to_32(uint16_t v14)
Scale a 14-bit value (0..16383, center 8192) to 32-bit (center 0x80000000) using MIDI 2....
Definition ump_conversion.hpp:43
void midi1_to_ump(const MidiBuffer &src, UmpBuffer &dst, uint8_t group=0)
Append a MIDI 1.0 buffer to a UmpBuffer as MIDI 2.0 UMP packets.
Definition ump_conversion.hpp:119
uint16_t scale_32_to_14(uint32_t v32)
Scale a 32-bit value back to 14-bit (0..16383), inverse of scale_14_to_32.
Definition ump_conversion.hpp:56
bool ump_to_midi1_event(const UmpPacket &p, MidiEvent &out)
Convert a UMP Channel Voice packet into a MIDI 1.0 event when possible.
Definition ump_conversion.hpp:170
bool ump_is_bank_valid_program_change(const UmpPacket &p)
True when p is a MIDI 2.0 Program Change carrying a valid bank, i.e.
Definition ump_conversion.hpp:264
uint8_t scale_16_to_7(uint16_t v16)
Scale 16-bit (0..65535) down to 7-bit (0..127).
Definition ump_conversion.hpp:36
constexpr uint8_t kBankSelectLsbCc
Definition ump_conversion.hpp:158
Midi2ProgramChange ump_program_change_fields(const UmpPacket &p)
Decode a MIDI 2.0 Program Change packet's fields without converting it.
Definition ump_conversion.hpp:147
@ Midi2ChannelVoice
Definition ump.hpp:27
@ Midi1ChannelVoice
Definition ump.hpp:25
@ System
Definition ump.hpp:24
UmpPacket midi1_event_to_ump2(const MidiEvent &ev, uint8_t group=0)
Convert a single MIDI 1.0 event to a MIDI 2.0 Channel Voice UMP packet.
Definition ump_conversion.hpp:73
void ump_to_midi1(const UmpBuffer &src, MidiBuffer &dst)
Flatten a UmpBuffer into a MidiBuffer.
Definition ump_conversion.hpp:281
Decoded fields of a MIDI 2.0 Channel Voice Program Change (status 0xC).
Definition ump_conversion.hpp:135
uint8_t bank_msb
0..127, meaningful only when bank_valid
Definition ump_conversion.hpp:138
bool bank_valid
option-flag bit 0
Definition ump_conversion.hpp:137
uint8_t bank_lsb
0..127, meaningful only when bank_valid
Definition ump_conversion.hpp:139
uint8_t program
0..127
Definition ump_conversion.hpp:136
Timestamped MIDI event combining a choc::midi::ShortMessage with timing info.
Definition message.hpp:32
uint8_t cc_value() const
Definition message.hpp:115
uint8_t note() const
Definition message.hpp:112
static MidiEvent cc(uint8_t channel, uint8_t controller, uint8_t value)
Create a Control Change event.
Definition message.hpp:64
uint8_t cc_number() const
Definition message.hpp:114
static MidiEvent program_change(uint8_t channel, uint8_t program)
Create a Program Change event.
Definition message.hpp:95
const uint8_t * data() const
Raw MIDI byte data (for format adapters that need direct byte access).
Definition message.hpp:38
uint32_t size() const
Number of bytes in the MIDI message (1-3).
Definition message.hpp:40
uint8_t channel() const
MIDI channel (0-15).
Definition message.hpp:111
static MidiEvent note_on(uint8_t channel, uint8_t note, uint8_t velocity)
Create a Note On event.
Definition message.hpp:46
static MidiEvent note_off(uint8_t channel, uint8_t note, uint8_t velocity=0)
Create a Note Off event.
Definition message.hpp:54
int32_t sample_offset
Sample position within the current buffer block.
Definition message.hpp:34
uint8_t velocity() const
Definition message.hpp:113
static MidiEvent pitch_bend(uint8_t channel, uint16_t value)
Create a Pitch Bend event.
Definition message.hpp:73
static UmpPacket note_off_2(uint8_t group, uint8_t channel, uint8_t note, uint16_t velocity=0)
Definition ump.hpp:157
static UmpPacket cc_2(uint8_t group, uint8_t channel, uint8_t controller, uint32_t value)
Definition ump.hpp:169
static UmpPacket note_on_2(uint8_t group, uint8_t channel, uint8_t note, uint16_t velocity, uint8_t attr_type=0, uint16_t attr_data=0)
Definition ump.hpp:143
static UmpPacket pitch_bend_2(uint8_t group, uint8_t channel, uint32_t value)
Definition ump.hpp:181
Sample-accurate MIDI 2.0 UMP packet stream.