* Copyright (c) 2026 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef UMP_PROCESSOR_H
#define UMP_PROCESSOR_H
#include <cstdint>
#include <functional>
#include "ump_packet.h"
* @brief Converts legacy MIDI 1.0 byte stream into MIDI 2.0 UMP packets.
* * Supported Mappings:
* - System Real-Time / Common -> MT=0x1
* - Channel Voice (8n-En) -> MT=0x2
* - System Exclusive (F0..F7) -> MT=0x3 (Data Messages)
*
* Also supports reverse conversion: UMP -> MIDI 1.0 byte stream.
*/
class UmpProcessor {
public:
using UmpCallback = std::function<void(const UmpPacket&)>;
using Midi1Callback = std::function<void(const uint8_t*, size_t)>;
static constexpr size_t CV_BUFFER_SIZE = 3;
static constexpr size_t SYSEX_BUFFER_SIZE = 6;
UmpProcessor();
* @brief Process a buffer of MIDI 1.0 bytes.
* @param data Pointer to the byte array.
* @param len Length of the byte array.
* @param callback Function called whenever a UMP is ready.
*/
void ProcessBytes(const uint8_t* data, size_t len, UmpCallback callback);
void SetGroup(uint8_t group);
* @brief Reset internal state (clear any pending SysEx assembly).
* Call this when switching streams or after error recovery.
*/
void Reset();
* @brief Process UMP packets and output MIDI 1.0 bytes.
* @param packets Array of UMP word data (32-bit words).
* @param wordCount Number of 32-bit words in the array.
* @param callback Function called with MIDI 1.0 byte output.
*/
void ProcessUmp(const uint32_t* packets, size_t wordCount, Midi1Callback callback);
* @brief Process a single UmpPacket and output MIDI 1.0 bytes.
* @param packet The UMP packet to process.
* @param callback Function called with MIDI 1.0 byte output.
*/
void ProcessUmpPacket(const UmpPacket& packet, Midi1Callback callback);
private:
uint8_t group_;
uint8_t cv_buffer_[CV_BUFFER_SIZE];
uint8_t cv_pos_;
uint8_t running_status_;
uint8_t expected_len_;
bool in_sysex_;
uint8_t sysex_buffer_[SYSEX_BUFFER_SIZE];
uint8_t sysex_pos_;
bool sysex_has_started_;
bool reverse_sysex_active_;
int GetExpectedDataLength(uint8_t status);
void DispatchChannelMessage(UmpCallback callback);
void ProcessSysExData(uint8_t byte, UmpCallback callback);
void FinalizeSysEx(UmpCallback callback);
void DispatchSysExPacket(UmpCallback callback, uint8_t status_code, uint8_t byte_count);
bool HandleRealTime(uint8_t byte, UmpCallback callback);
void HandleStatusByte(uint8_t byte, UmpCallback callback);
void HandleDataByte(uint8_t byte, UmpCallback callback);
void HandleChannelData(uint8_t byte, UmpCallback callback);
void ProcessUmpType1(uint32_t word0, Midi1Callback callback);
void ProcessUmpType2(uint32_t word0, Midi1Callback callback);
void ProcessUmpType3(uint32_t word0, uint32_t word1, Midi1Callback callback);
};
#endif