Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
aax_midi_packets.hpp
Go to the documentation of this file.
1#pragma once
2
19
20#include <pulp/midi/buffer.hpp>
21#include <pulp/midi/message.hpp>
22
23#include <array>
24#include <cstdint>
25#include <span>
26#include <vector>
27
28namespace pulp::format::aax {
29
33 std::array<uint8_t, 4> data{};
34 uint8_t length = 0;
35 uint32_t timestamp = 0;
36};
37
53inline void decode_midi_packets(std::span<const MidiPacketBytes> packets,
54 midi::MidiBuffer& out) {
55 std::vector<uint8_t> sysex_buffer;
56 bool sysex_in_progress = false;
57 int32_t sysex_start_offset = 0;
58
59 for (const auto& packet : packets) {
60 if (packet.length == 0) {
61 continue;
62 }
63
64 const bool starts_sysex =
65 (!sysex_in_progress && packet.data[0] == 0xF0);
66 if (starts_sysex || sysex_in_progress) {
67 if (starts_sysex) {
68 sysex_buffer.clear();
69 sysex_start_offset = static_cast<int32_t>(packet.timestamp);
70 sysex_in_progress = true;
71 }
72 for (uint8_t b = 0; b < packet.length && b < 4; ++b) {
73 const uint8_t byte = packet.data[b];
74 sysex_buffer.push_back(byte);
75 if (byte == 0xF7) {
76 out.add_sysex(std::move(sysex_buffer), sysex_start_offset,
77 0.0);
78 sysex_buffer.clear();
79 sysex_in_progress = false;
80 break;
81 }
82 }
83 continue;
84 }
85
86 // Short channel-voice or system-common (1..3 bytes).
87 if (packet.length > 3) {
88 continue;
89 }
90 const unsigned char data1 = packet.length > 1 ? packet.data[1] : 0;
91 const unsigned char data2 = packet.length > 2 ? packet.data[2] : 0;
93 .message = choc::midi::ShortMessage(packet.data[0], data1, data2),
94 .sample_offset = static_cast<int32_t>(packet.timestamp),
95 .timestamp = 0.0,
96 });
97 }
98
99 out.sort();
100}
101
106inline std::vector<MidiPacketBytes> fragment_sysex(
107 std::span<const uint8_t> payload, uint32_t timestamp) {
108 std::vector<MidiPacketBytes> packets;
109 std::size_t offset = 0;
110 while (offset < payload.size()) {
111 const std::size_t chunk = std::min<std::size_t>(4, payload.size() - offset);
112 MidiPacketBytes packet{};
113 packet.timestamp = timestamp;
114 packet.length = static_cast<uint8_t>(chunk);
115 for (std::size_t b = 0; b < chunk; ++b) {
116 packet.data[b] = payload[offset + b];
117 }
118 packets.push_back(packet);
119 offset += chunk;
120 }
121 return packets;
122}
123
124} // namespace pulp::format::aax
Collection of timestamped MIDI events within a single audio buffer period.
Definition buffer.hpp:31
bool add_sysex(std::vector< uint8_t > data, int32_t sample_offset=0, double ts=0.0)
Definition buffer.hpp:352
void sort()
Sort events by sample_offset for sample-accurate processing.
Definition buffer.hpp:177
bool add(const MidiEvent &event)
Append a MIDI event to the buffer.
Definition buffer.hpp:98
Definition aax_editor.hpp:31
std::vector< MidiPacketBytes > fragment_sysex(std::span< const uint8_t > payload, uint32_t timestamp)
Fragment one full F0..F7 SysEx payload into consecutive 4-byte packets that all share timestamp — the...
Definition aax_midi_packets.hpp:106
void decode_midi_packets(std::span< const MidiPacketBytes > packets, midi::MidiBuffer &out)
Decode a stream of AAX-style packets into out (short messages plus reassembled SysEx).
Definition aax_midi_packets.hpp:53
SDK-free mirror of the fields of AAX_CMidiPacket this layer needs.
Definition aax_midi_packets.hpp:32
uint32_t timestamp
Definition aax_midi_packets.hpp:35
uint8_t length
Definition aax_midi_packets.hpp:34
std::array< uint8_t, 4 > data
Definition aax_midi_packets.hpp:33
Timestamped MIDI event combining a choc::midi::ShortMessage with timing info.
Definition message.hpp:32