Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
android_midi_fifo.hpp
Go to the documentation of this file.
1#pragma once
2
3// Android MIDI input ring buffer.
4//
5// MIDI bytes arrive from the Kotlin side on the MidiReceiver callback
6// thread. They get pushed into this lock-free SPSC queue and the audio
7// thread drains them into a MidiBuffer at the start of each process
8// block, converting the monotonic nanosecond timestamp into a sample
9// offset within the current block.
10//
11// This is an internal bridge API. External consumers should use
12// `pulp::midi::android::drain_into(MidiBuffer&, ...)` from the audio thread.
13
14#if defined(__ANDROID__)
15
16#include <pulp/midi/buffer.hpp>
18
19#include <array>
20#include <cstdint>
21
22namespace pulp::midi::android {
23
24// A single MIDI event delivered from the Kotlin bridge.
25// `data` is the raw MIDI byte stream (bytestream MIDI 1.0); `size`
26// holds the number of valid bytes in `data`. `timestamp_ns` is the
27// Android monotonic timestamp the Kotlin receiver gave us.
28struct AndroidMidiEvent {
29 std::uint64_t timestamp_ns = 0;
30 std::uint8_t size = 0;
31 // Long enough for any MIDI 1.0 message (SysEx is chunked externally).
32 std::array<std::uint8_t, 16> data{};
33};
34
35// Push raw MIDI bytes into the FIFO. Returns false if the queue is
36// full or if `count` > sizeof(AndroidMidiEvent::data) and the caller
37// should split the message. Safe to call from any thread (designed for
38// the Kotlin MidiReceiver thread).
39bool push_bytes(const std::uint8_t* bytes, int count, std::int64_t timestamp_ns);
40
41// Drain pending events into `buffer`, converting timestamps to sample
42// offsets relative to the current block. `block_start_ns` is the
43// monotonic timestamp of the first sample of the block (or 0 if
44// unknown, in which case every event maps to sample 0). `sample_rate`
45// is used to convert nanoseconds to samples. `block_size` clamps the
46// maximum sample offset so out-of-block events appear at the end of
47// the block (they will be applied next block if clamped to the last
48// sample — this is the simplest latency-correct behavior).
49//
50// Call from the audio thread.
51void drain_into(MidiBuffer& buffer,
52 std::int64_t block_start_ns,
53 double sample_rate,
54 int block_size);
55
56// Returns true if at least one event is currently queued. For
57// diagnostics only — do not use for control flow, since the producer
58// may push a new event between the check and a subsequent drain.
59bool has_pending();
60
61} // namespace pulp::midi::android
62
63#endif // __ANDROID__
@ size
Definition config.hpp:216