Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
program_wire.hpp
Go to the documentation of this file.
1#pragma once
2
130
137#include <pulp/timebase/tick.hpp>
139
140#include <array>
141#include <bit>
142#include <cstddef>
143#include <cstdint>
144#include <span>
145#include <type_traits>
146
147namespace pulp::playback {
148
149namespace detail {
150struct ProgramWireDecoder;
151}
152
153static_assert(std::endian::native == std::endian::little,
154 "the program wire is a native-layout little-endian byte range; a big-endian "
155 "host must gain an explicit byte-swapping codec before it can produce or "
156 "consume one, not silently emit records a reader would misread");
157
192inline constexpr std::uint16_t kProgramWireVersion = 3;
193
197inline constexpr std::uint16_t kProgramWireMinReaderVersion = 2;
198
202inline constexpr std::uint16_t kProgramWireControllerMinReaderVersion = 3;
203
205inline constexpr std::uint32_t kProgramWireMagic = 0x5750'4C50u;
206
208inline constexpr std::uint32_t kProgramWireNoLane = 0xFFFF'FFFFu;
209
211inline constexpr std::size_t kProgramWireMaximumTracks = 1'024;
212
216inline constexpr std::size_t kProgramWireMaximumAutomationLanes = 1'024;
217
227
245
248inline constexpr std::uint32_t kProgramWireSectionOptional = 1u << 0u;
249
254enum class AutomationEvaluationRate : std::uint8_t {
257};
258
259enum class ProgramWireTargetKind : std::uint8_t {
262};
263
358
368
369#pragma pack(push, 8)
370
375 std::uint32_t magic = kProgramWireMagic;
378 std::uint32_t header_bytes = 0;
379 std::uint32_t section_count = 0;
380 std::uint64_t payload_bytes = 0;
381 std::uint64_t body_checksum = 0;
382 std::uint64_t reserved0 = 0;
383 std::uint64_t reserved1 = 0;
384 std::uint64_t reserved2 = 0;
385 std::uint64_t reserved3 = 0;
386};
387
389 std::uint32_t id = 0;
390 std::uint32_t flags = 0;
392 std::uint64_t offset = 0;
393 std::uint64_t bytes = 0;
394};
395
403 std::uint64_t producer_epoch = 0;
404 std::uint64_t generation = 0;
405 std::uint64_t document_revision = 0;
406 std::uint64_t project_id = 0;
407 std::uint64_t sequence_id = 0;
408 std::uint64_t generated_id_base = 0;
409 std::uint64_t sample_rate_numerator = 0;
410 std::uint64_t sample_rate_denominator = 0;
412 std::uint32_t max_lanes_per_track = 0;
413 std::uint32_t max_points_per_lane = 0;
414 std::uint32_t max_points_per_track = 0;
417};
418
424 std::int64_t tick = 0;
426 std::uint64_t bpm_bits = 0;
427 std::uint8_t curve_to_next = 0;
428 std::uint8_t pad[7] = {};
429};
430
434 std::uint64_t id = 0;
435 std::uint64_t generation = 0;
436 std::uint32_t clip_first = 0;
437 std::uint32_t clip_count = 0;
438 std::uint32_t note_event_first = 0;
439 std::uint32_t note_event_count = 0;
440 std::uint32_t note_modifier_first = 0;
441 std::uint32_t note_modifier_count = 0;
442 std::uint32_t device_placement_first = 0;
443 std::uint32_t device_placement_count = 0;
444 std::uint32_t automation_lane_first = 0;
445 std::uint32_t automation_lane_count = 0;
446 std::uint64_t expanded_clip_count = 0;
447 std::uint64_t expanded_note_event_count = 0;
448 std::uint64_t generated_id_start = 0;
449 std::uint64_t generated_id_count = 0;
450 float mixer_gain_linear = 1.0f;
451 float mixer_pan = 0.0f;
457 std::uint8_t provider_selected = 0;
458 std::uint8_t provider_available_mask = 0;
459 std::uint8_t state_policy = 0;
463 std::uint8_t flags = 0;
464 std::uint32_t pad = 0;
465};
466
467inline constexpr std::uint8_t kProgramWireTrackHasAutomationProgram = 1u << 0u;
468
470 std::uint64_t value = 0;
471};
472
481 std::int64_t sample = 0;
482 std::int64_t tick = 0;
483 std::uint64_t clip_id = 0;
484 std::uint64_t note_id = 0;
485 std::uint16_t velocity = 0;
486 std::uint8_t pitch = 0;
487 std::uint8_t channel = 0;
488 std::uint8_t kind = 0;
489 std::uint8_t pad[3] = {};
490};
491
493 std::uint64_t draw_key = 0;
494 std::uint64_t note_id = 0;
495 std::uint16_t probability = 0;
496 std::uint16_t condition_period = 0;
497 std::uint16_t condition_offset = 0;
498 std::uint16_t ratchet_count = 0;
499 std::uint8_t condition = 0;
500 std::uint8_t pad[7] = {};
501};
502
508 std::uint32_t first = 0;
509 std::uint32_t count = 0;
510};
511
522 std::int64_t sample = 0;
523 std::int64_t tick = 0;
524 std::uint64_t clip_id = 0;
525 std::uint64_t lane_id = 0;
526 std::uint64_t point_id = 0;
527 std::uint32_t value = 0;
528 std::uint8_t group = 0;
529 std::uint8_t channel = 0;
530 std::uint8_t status = 0;
531 std::uint8_t bank = 0;
532 std::uint8_t index = 0;
533 std::uint8_t origin = 0;
534 std::uint8_t pad[6] = {};
535};
536
569 std::uint64_t lane_id = 0;
570 std::uint64_t generation = 0;
573 std::uint64_t instance_token = 0;
574 std::uint32_t segment_first = 0;
575 std::uint32_t segment_count = 0;
576 float leading_value = 0.0f;
577 std::uint8_t target_kind = 0;
578 std::uint8_t evaluation_rate = 0;
579 std::uint16_t pad0 = 0;
581 std::uint64_t device_placement_id = 0;
583 std::uint32_t device_param_id = 0;
585 std::uint8_t mixer_parameter = 0;
586 std::uint8_t pad1[3] = {};
587};
588
595 std::int64_t start_tick = 0;
596 std::int64_t end_tick = 0;
597 std::int64_t start_sample = 0;
598 std::int64_t end_sample = 0;
599 float start_value = 0.0f;
600 float end_value = 0.0f;
601 float curvature = 0.0f;
602 std::uint8_t interpolation = 0;
603 std::uint8_t pad[3] = {};
604};
605
606#pragma pack(pop)
607
608// A record whose size changes is a wire-format change. These are the
609// compile-time half of the format's stability guard; the byte-level golden in
610// the tests is the other half.
611static_assert(sizeof(ProgramWireHeader) == 64);
612static_assert(sizeof(ProgramWireSectionEntry) == 24);
613static_assert(sizeof(ProgramWireProgramRecord) == 88);
614static_assert(sizeof(ProgramWireTempoPointRecord) == 24);
615static_assert(sizeof(ProgramWireTrackRecord) == 112);
616static_assert(sizeof(ProgramWireIdRecord) == 8);
617static_assert(sizeof(ProgramWireNoteEventRecord) == 40);
618static_assert(sizeof(ProgramWireNoteModifierRecord) == 32);
619static_assert(sizeof(ProgramWireAutomationLaneRecord) == 56);
620static_assert(sizeof(ProgramWireAutomationSegmentRecord) == 48);
621static_assert(sizeof(ProgramWireControllerRangeRecord) == 8);
622static_assert(sizeof(ProgramWireControllerEventRecord) == 56);
623
626static_assert(sizeof(ProgramWireHeader) % 8 == 0);
627static_assert(sizeof(ProgramWireSectionEntry) % 8 == 0);
628static_assert(sizeof(ProgramWireProgramRecord) % 8 == 0);
629static_assert(sizeof(ProgramWireTempoPointRecord) % 8 == 0);
630static_assert(sizeof(ProgramWireTrackRecord) % 8 == 0);
631static_assert(sizeof(ProgramWireIdRecord) % 8 == 0);
632static_assert(sizeof(ProgramWireNoteEventRecord) % 8 == 0);
633static_assert(sizeof(ProgramWireNoteModifierRecord) % 8 == 0);
634static_assert(sizeof(ProgramWireAutomationLaneRecord) % 8 == 0);
635static_assert(sizeof(ProgramWireAutomationSegmentRecord) % 8 == 0);
636static_assert(sizeof(ProgramWireControllerRangeRecord) % 8 == 0);
637static_assert(sizeof(ProgramWireControllerEventRecord) % 8 == 0);
638
639static_assert(std::is_trivially_copyable_v<ProgramWireHeader>);
640static_assert(std::is_trivially_copyable_v<ProgramWireControllerRangeRecord>);
641static_assert(std::is_trivially_copyable_v<ProgramWireControllerEventRecord>);
642static_assert(std::is_trivially_copyable_v<ProgramWireProgramRecord>);
643static_assert(std::is_trivially_copyable_v<ProgramWireTrackRecord>);
644static_assert(std::is_trivially_copyable_v<ProgramWireNoteEventRecord>);
645static_assert(std::is_trivially_copyable_v<ProgramWireAutomationLaneRecord>);
646static_assert(std::is_trivially_copyable_v<ProgramWireAutomationSegmentRecord>);
647
650inline constexpr std::size_t kProgramWireAlignment = 8;
651
655constexpr std::uint64_t program_wire_checksum(std::span<const std::byte> bytes) noexcept {
656 std::uint64_t hash = 0xcbf2'9ce4'8422'2325ull;
657 for (const auto byte : bytes) {
658 hash ^= static_cast<std::uint64_t>(std::to_integer<std::uint8_t>(byte));
659 hash *= 0x0000'0100'0000'01b3ull;
660 }
661 return hash;
662}
663
671 public:
672 ProgramWireView() = default;
673
674 std::span<const std::byte> bytes() const noexcept {
675 return bytes_;
676 }
677 const ProgramWireHeader& header() const noexcept {
678 return *header_;
679 }
680 const ProgramWireProgramRecord& program() const noexcept {
681 return *program_;
682 }
683 std::uint64_t producer_epoch() const noexcept {
684 return program_->producer_epoch;
685 }
687 return {program_->sample_rate_numerator, program_->sample_rate_denominator};
688 }
690
691 std::span<const ProgramWireTempoPointRecord> tempo_points() const noexcept {
692 return tempo_points_;
693 }
694 std::span<const ProgramWireTrackRecord> tracks() const noexcept {
695 return tracks_;
696 }
697 std::span<const ProgramWireIdRecord> clip_ids() const noexcept {
698 return clip_ids_;
699 }
700 std::span<const ProgramWireNoteEventRecord> note_events() const noexcept {
701 return note_events_;
702 }
703 std::span<const ProgramWireNoteModifierRecord> note_modifiers() const noexcept {
704 return note_modifiers_;
705 }
706 std::span<const ProgramWireIdRecord> device_placement_ids() const noexcept {
707 return device_placement_ids_;
708 }
709 std::span<const ProgramWireAutomationLaneRecord> automation_lanes() const noexcept {
710 return automation_lanes_;
711 }
712 std::span<const ProgramWireAutomationSegmentRecord> automation_segments() const noexcept {
713 return automation_segments_;
714 }
715
717 std::span<const ProgramWireControllerRangeRecord> controller_ranges() const noexcept {
718 return controller_ranges_;
719 }
720 std::span<const ProgramWireControllerEventRecord> controller_events() const noexcept {
721 return controller_events_;
722 }
723
724 // Every range below was bounds-checked at decode, so these never read past
725 // their section.
726 std::span<const ProgramWireIdRecord>
727 clip_ids_for(const ProgramWireTrackRecord& track) const noexcept {
728 return clip_ids_.subspan(track.clip_first, track.clip_count);
729 }
730 std::span<const ProgramWireNoteEventRecord>
731 note_events_for(const ProgramWireTrackRecord& track) const noexcept {
732 return note_events_.subspan(track.note_event_first, track.note_event_count);
733 }
734 std::span<const ProgramWireNoteModifierRecord>
735 note_modifiers_for(const ProgramWireTrackRecord& track) const noexcept {
736 return note_modifiers_.subspan(track.note_modifier_first, track.note_modifier_count);
737 }
738 std::span<const ProgramWireIdRecord>
740 return device_placement_ids_.subspan(track.device_placement_first,
741 track.device_placement_count);
742 }
743 std::span<const ProgramWireAutomationLaneRecord>
744 automation_lanes_for(const ProgramWireTrackRecord& track) const noexcept {
745 return automation_lanes_.subspan(track.automation_lane_first, track.automation_lane_count);
746 }
747 std::span<const ProgramWireAutomationSegmentRecord>
748 segments_for(const ProgramWireAutomationLaneRecord& lane) const noexcept {
749 return automation_segments_.subspan(lane.segment_first, lane.segment_count);
750 }
751
753 std::span<const ProgramWireControllerEventRecord>
755 return controller_events_.subspan(range.first, range.count);
756 }
757
758 private:
760
761 std::span<const std::byte> bytes_;
762 const ProgramWireHeader* header_ = nullptr;
763 const ProgramWireProgramRecord* program_ = nullptr;
764 std::span<const ProgramWireTempoPointRecord> tempo_points_;
765 std::span<const ProgramWireTrackRecord> tracks_;
766 std::span<const ProgramWireIdRecord> clip_ids_;
767 std::span<const ProgramWireNoteEventRecord> note_events_;
768 std::span<const ProgramWireNoteModifierRecord> note_modifiers_;
769 std::span<const ProgramWireIdRecord> device_placement_ids_;
770 std::span<const ProgramWireAutomationLaneRecord> automation_lanes_;
771 std::span<const ProgramWireAutomationSegmentRecord> automation_segments_;
772 std::span<const ProgramWireControllerRangeRecord> controller_ranges_;
773 std::span<const ProgramWireControllerEventRecord> controller_events_;
774};
775
781std::uint64_t program_wire_process_epoch() noexcept;
782
787runtime::Result<std::size_t, ProgramWireError>
789 std::span<const timebase::TempoPoint> tempo_points) noexcept;
790
805runtime::Result<std::size_t, ProgramWireError>
807 std::span<const timebase::TempoPoint> tempo_points,
808 std::uint64_t producer_epoch, std::span<std::byte> out) noexcept;
809
816decode_program_wire(std::span<const std::byte> bytes) noexcept;
817
825 std::span<const timebase::TempoPoint> tempo_points,
826 std::uint64_t producer_epoch) noexcept;
827
832 public:
834 explicit ProgramWireBytePin(std::span<const std::byte> bytes,
835 std::uintptr_t owner_token = 0) noexcept
836 : bytes_(bytes), owner_token_(owner_token) {}
840 : bytes_(other.bytes_), owner_token_(other.owner_token_) {
841 other.bytes_ = {};
842 other.owner_token_ = 0;
843 }
845 if (this != &other) {
846 bytes_ = other.bytes_;
847 owner_token_ = other.owner_token_;
848 other.bytes_ = {};
849 other.owner_token_ = 0;
850 }
851 return *this;
852 }
853
854 std::span<const std::byte> bytes() const noexcept {
855 return bytes_;
856 }
857 std::uintptr_t owner_token() const noexcept {
858 return owner_token_;
859 }
860 explicit operator bool() const noexcept {
861 return !bytes_.empty();
862 }
863
864 private:
865 std::span<const std::byte> bytes_;
866 std::uintptr_t owner_token_ = 0;
867};
868
880
881enum class ProgramWireAdoption : std::uint8_t {
885};
886
894
905
912 std::array<AutomationBlockEvent, AutomationPlaybackLimits::kMaximumEventsPerDevicePerBlock>
915 std::uint32_t event_count = 0;
916 std::uint32_t merge_position = 0;
917 std::uint32_t selected_count = 0;
918 std::uint32_t write_position = 0;
919 std::size_t output_index = 0;
920 bool group_coalesced = false;
921};
922
929
934
940 public:
941 static constexpr std::size_t kDefaultWireByteCapacity = 16u * 1'024u * 1'024u;
942
943 explicit ProgramWireAutomationConsumer(std::span<ProgramWireLaneState> lane_state,
944 std::size_t track_capacity,
945 std::size_t wire_byte_capacity) noexcept
946 : lane_state_(lane_state), track_capacity_(track_capacity),
947 wire_byte_capacity_(wire_byte_capacity) {}
948 explicit ProgramWireAutomationConsumer(std::span<ProgramWireLaneState> lane_state,
949 std::size_t track_capacity) noexcept
950 : ProgramWireAutomationConsumer(lane_state, track_capacity,
952 explicit ProgramWireAutomationConsumer(std::span<ProgramWireLaneState> lane_state) noexcept
953 : ProgramWireAutomationConsumer(lane_state, lane_state.size()) {}
956
958 const timebase::CompiledTempoMap& tempo_map,
959 std::span<const timebase::TempoPoint> tempo_points) noexcept;
961 render(const TransportSnapshot& transport,
962 std::span<ProgramWireAutomationLaneOutput> output) noexcept;
963
964 std::span<const std::byte> active_bytes() const noexcept {
965 return active_pin_.bytes();
966 }
967 std::size_t lane_count() const noexcept {
968 return lane_count_;
969 }
970
971 private:
972 struct ActiveLane {
973 ProgramWireLaneState* state = nullptr;
974 const ProgramWireTrackRecord* track = nullptr;
975 const ProgramWireAutomationLaneRecord* lane = nullptr;
976 std::size_t group_index = 0;
977 };
978 struct CapacityGroup {
979 std::size_t first_lane = 0;
980 std::size_t lane_count = 0;
981 };
982 struct LaneHighWater {
983 timeline::ItemId lane_id;
984 ProgramGeneration generation = 0;
985 };
986
987 std::span<ProgramWireLaneState> lane_state_;
988 ProgramWireBytePin active_pin_;
989 ProgramWireView active_view_;
990 const timebase::CompiledTempoMap* tempo_map_ = nullptr;
991 std::size_t lane_count_ = 0;
992 std::size_t track_capacity_ = 0;
993 std::size_t wire_byte_capacity_ = 0;
994 std::array<ActiveLane, kProgramWireMaximumAutomationLanes> active_lanes_{};
995 std::array<CapacityGroup, kProgramWireMaximumAutomationLanes> groups_{};
996 std::array<std::size_t, kProgramWireMaximumAutomationLanes>
997 group_lane_indices_{};
998 std::size_t group_count_ = 0;
999 std::array<LaneHighWater, kProgramWireMaximumAutomationLanes * 2u> lane_high_water_{};
1000 std::uint64_t lane_high_water_epoch_ = 0;
1001 std::array<ProgramWireLaneState*, kProgramWireMaximumAutomationLanes>
1002 merge_heap_{};
1003};
1004
1005} // namespace pulp::playback
Allocation-free renderer for one immutable AutomationProgram.
Definition automation_cursor.hpp:221
Definition program.hpp:290
ProgramWireAutomationRenderResult render(const TransportSnapshot &transport, std::span< ProgramWireAutomationLaneOutput > output) noexcept
ProgramWireAutomationConsumer(std::span< ProgramWireLaneState > lane_state, std::size_t track_capacity, std::size_t wire_byte_capacity) noexcept
Definition program_wire.hpp:943
static constexpr std::size_t kDefaultWireByteCapacity
Definition program_wire.hpp:941
ProgramWireAutomationConsumer(std::span< ProgramWireLaneState > lane_state, std::size_t track_capacity) noexcept
Definition program_wire.hpp:948
std::size_t lane_count() const noexcept
Definition program_wire.hpp:967
ProgramWireAutomationConsumer & operator=(const ProgramWireAutomationConsumer &)=delete
std::span< const std::byte > active_bytes() const noexcept
Definition program_wire.hpp:964
ProgramWireAutomationConsumer(std::span< ProgramWireLaneState > lane_state) noexcept
Definition program_wire.hpp:952
ProgramWireAdoptionResult adopt(ProgramWireBytePin candidate, const timebase::CompiledTempoMap &tempo_map, std::span< const timebase::TempoPoint > tempo_points) noexcept
ProgramWireAutomationConsumer(const ProgramWireAutomationConsumer &)=delete
A unique lease over immutable publication bytes.
Definition program_wire.hpp:831
ProgramWireBytePin & operator=(const ProgramWireBytePin &)=delete
ProgramWireBytePin & operator=(ProgramWireBytePin &&other) noexcept
Definition program_wire.hpp:844
std::uintptr_t owner_token() const noexcept
Definition program_wire.hpp:857
ProgramWireBytePin(const ProgramWireBytePin &)=delete
ProgramWireBytePin(std::span< const std::byte > bytes, std::uintptr_t owner_token=0) noexcept
Definition program_wire.hpp:834
std::span< const std::byte > bytes() const noexcept
Definition program_wire.hpp:854
ProgramWireBytePin(ProgramWireBytePin &&other) noexcept
Definition program_wire.hpp:839
A validated, zero-copy view over one encoded program generation.
Definition program_wire.hpp:670
std::span< const ProgramWireControllerEventRecord > controller_events_for(const ProgramWireControllerRangeRecord &range) const noexcept
The events of the track whose index in tracks() matches range's in controller_ranges().
Definition program_wire.hpp:754
std::span< const ProgramWireIdRecord > clip_ids() const noexcept
Definition program_wire.hpp:697
timebase::RationalRate sample_rate() const noexcept
Definition program_wire.hpp:686
std::span< const ProgramWireNoteModifierRecord > note_modifiers_for(const ProgramWireTrackRecord &track) const noexcept
Definition program_wire.hpp:735
std::span< const ProgramWireAutomationLaneRecord > automation_lanes_for(const ProgramWireTrackRecord &track) const noexcept
Definition program_wire.hpp:744
std::span< const ProgramWireNoteEventRecord > note_events_for(const ProgramWireTrackRecord &track) const noexcept
Definition program_wire.hpp:731
std::span< const ProgramWireIdRecord > device_placement_ids_for(const ProgramWireTrackRecord &track) const noexcept
Definition program_wire.hpp:739
std::span< const std::byte > bytes() const noexcept
Definition program_wire.hpp:674
std::span< const ProgramWireNoteModifierRecord > note_modifiers() const noexcept
Definition program_wire.hpp:703
std::span< const ProgramWireControllerEventRecord > controller_events() const noexcept
Definition program_wire.hpp:720
std::span< const ProgramWireTempoPointRecord > tempo_points() const noexcept
Definition program_wire.hpp:691
std::span< const ProgramWireControllerRangeRecord > controller_ranges() const noexcept
One range per track, in track order; empty only for a version 2 payload that carried no such section,...
Definition program_wire.hpp:717
std::span< const ProgramWireAutomationLaneRecord > automation_lanes() const noexcept
Definition program_wire.hpp:709
std::span< const ProgramWireTrackRecord > tracks() const noexcept
Definition program_wire.hpp:694
std::uint64_t producer_epoch() const noexcept
Definition program_wire.hpp:683
std::span< const ProgramWireAutomationSegmentRecord > automation_segments() const noexcept
Definition program_wire.hpp:712
std::span< const ProgramWireNoteEventRecord > note_events() const noexcept
Definition program_wire.hpp:700
const ProgramWireProgramRecord & program() const noexcept
Definition program_wire.hpp:680
friend struct detail::ProgramWireDecoder
Definition program_wire.hpp:759
const ProgramWireHeader & header() const noexcept
Definition program_wire.hpp:677
std::span< const ProgramWireAutomationSegmentRecord > segments_for(const ProgramWireAutomationLaneRecord &lane) const noexcept
Definition program_wire.hpp:748
AutomationPlaybackLimits automation_limits() const noexcept
std::span< const ProgramWireIdRecord > device_placement_ids() const noexcept
Definition program_wire.hpp:706
std::span< const ProgramWireIdRecord > clip_ids_for(const ProgramWireTrackRecord &track) const noexcept
Definition program_wire.hpp:727
Definition compiled_tempo_map.hpp:91
Definition automation_program.hpp:17
Definition audio_renderer.hpp:20
constexpr std::size_t kProgramWireMaximumAutomationLanes
Total automation lanes one publication consumer can prepare across all tracks.
Definition program_wire.hpp:216
runtime::Result< ProgramWireView, ProgramWireError > decode_program_wire(std::span< const std::byte > bytes) noexcept
Validates bytes and returns a borrowing view.
constexpr std::uint32_t kProgramWireSectionOptional
The section is safe to ignore: a reader that does not know this id still renders the program the writ...
Definition program_wire.hpp:248
ProgramWireConsumerCode
Definition program_wire.hpp:869
@ StateCapacityExceeded
Definition program_wire.hpp:873
@ CursorRejected
Definition program_wire.hpp:878
@ StalePublication
Definition program_wire.hpp:874
@ Ok
Definition program_wire.hpp:870
@ DecodeRejected
Definition program_wire.hpp:871
@ OutputCapacityExceeded
Definition program_wire.hpp:877
constexpr std::uint16_t kProgramWireVersion
The format this build writes and is able to read.
Definition program_wire.hpp:192
constexpr std::size_t kProgramWireAlignment
Every record is a multiple of eight bytes, so tiling sections back to back keeps each one eight-byte ...
Definition program_wire.hpp:650
bool program_wire_matches(const ProgramWireView &view, const PlaybackProgram &program, std::span< const timebase::TempoPoint > tempo_points, std::uint64_t producer_epoch) noexcept
Whether view carries exactly program compiled from tempo_points.
ProgramWireErrorCode
Definition program_wire.hpp:264
@ AudioProgramUnsupported
A track carries an audio renderer program, which this version does not represent.
Definition program_wire.hpp:275
@ UnsupportedVersion
The payload's min_reader_version exceeds this build's version.
Definition program_wire.hpp:291
@ ChecksumMismatch
Definition program_wire.hpp:294
@ SectionOutOfBounds
A section's offset plus length overflows or leaves the payload.
Definition program_wire.hpp:296
@ StaleLaneGeneration
A publication from the active producer regresses one lane generation.
Definition program_wire.hpp:326
@ MixerAutomationUnresolved
A mixer control points at an automation program that is not one of the owning track's lanes.
Definition program_wire.hpp:282
@ ProductionDeclarationUnsupported
A track has a non-default production declaration, which this wire version cannot carry.
Definition program_wire.hpp:279
@ NonCanonicalRangeOwnership
Track and lane ranges must exclusively partition their sections in canonical track/lane order; aliase...
Definition program_wire.hpp:320
@ UnknownSection
An unknown section id that the writer did not mark optional.
Definition program_wire.hpp:307
@ CountOverflow
A count exceeded the 32-bit index domain the flat layout addresses.
Definition program_wire.hpp:284
@ BadRecordSize
A section's byte length is not a whole number of its records.
Definition program_wire.hpp:313
@ MalformedNoteModifier
A note modifier is not a combination the document model admits — a zero condition period,...
Definition program_wire.hpp:332
@ MissingSection
A known section id is absent.
Definition program_wire.hpp:309
@ BadHeaderSize
header_bytes disagrees with this format's fixed header size.
Definition program_wire.hpp:293
@ MalformedSegment
An automation segment runs backwards or carries a non-finite value, either of which would propagate t...
Definition program_wire.hpp:335
@ RangeOutOfBounds
A track's (first, count) range leaves the section it indexes.
Definition program_wire.hpp:317
@ MalformedControllerEvent
A controller event names no clip, lane, or point, or carries an address component wider than the MIDI...
Definition program_wire.hpp:343
@ AutomationTargetUnresolved
A device lane names no placement in its owning track.
Definition program_wire.hpp:322
@ SectionsNotTiled
Sections do not tile the payload exactly: unsorted, gapped, overlapping, or not reaching payload_byte...
Definition program_wire.hpp:299
@ DuplicateSection
Definition program_wire.hpp:305
@ ShortBuffer
Fewer bytes than the fixed header, the section directory, or the payload the header declares.
Definition program_wire.hpp:288
@ DuplicateAutomationTarget
Two lanes in one track drive the same device parameter or mixer control.
Definition program_wire.hpp:324
@ BadSectionCardinality
A section holds a record count the format does not admit.
Definition program_wire.hpp:315
@ InvalidEnum
A record holds a value outside its enumeration.
Definition program_wire.hpp:328
@ InvalidInstanceToken
An automation lane's instance token is zero.
Definition program_wire.hpp:356
@ BadMagic
Definition program_wire.hpp:289
@ InvalidProducerEpoch
The producer epoch is zero.
Definition program_wire.hpp:351
@ SectionMisaligned
A section's payload offset is not eight-byte aligned.
Definition program_wire.hpp:301
@ MisalignedBuffer
The buffer's base address is not eight-byte aligned, so typed spans borrowed from it would be misalig...
Definition program_wire.hpp:270
@ NonCanonicalSectionOrder
Known sections must appear in ascending canonical id order.
Definition program_wire.hpp:304
@ TrailingData
The buffer holds bytes past the payload the header declares.
Definition program_wire.hpp:311
@ InvalidLimits
The carried automation ceilings are not a configuration the renderer accepts.
Definition program_wire.hpp:347
constexpr std::uint8_t kProgramWireTrackHasAutomationProgram
Definition program_wire.hpp:467
@ InvalidTransport
Definition audio_renderer.hpp:218
runtime::Result< std::size_t, ProgramWireError > encode_program_wire(const PlaybackProgram &program, std::span< const timebase::TempoPoint > tempo_points, std::uint64_t producer_epoch, std::span< std::byte > out) noexcept
Writes program into out and returns the bytes written.
constexpr std::uint16_t kProgramWireControllerMinReaderVersion
The floor written into a payload that carries at least one controller event.
Definition program_wire.hpp:202
constexpr std::uint16_t kProgramWireMinReaderVersion
The floor written into a payload that carries no controller events: the version whose readers can sti...
Definition program_wire.hpp:197
constexpr std::size_t kMaximumControllerEventsPerTrack
Ceiling on controller events one track program may carry.
Definition program.hpp:100
@ Unchanged
Definition automation_cursor.hpp:40
@ Adopted
Definition automation_cursor.hpp:39
@ Rejected
Definition automation_cursor.hpp:41
@ MissingProgram
Definition note_renderer.hpp:38
@ InsufficientCapacity
Definition automation_cursor.hpp:34
@ TempoMapMismatch
Definition automation_cursor.hpp:33
@ Ok
Definition automation_cursor.hpp:29
ProgramWireTargetKind
Definition program_wire.hpp:259
@ TrackMixer
Definition program_wire.hpp:261
@ DeviceParameter
Definition program_wire.hpp:260
constexpr std::size_t kProgramWireMaximumControllerEventsPerTrack
Controller events one track may carry on the wire.
Definition program_wire.hpp:225
AutomationEvaluationRate
How often the adopting realm must evaluate one automation lane.
Definition program_wire.hpp:254
@ BlockRate
Definition program_wire.hpp:256
@ SampleAccurate
Definition program_wire.hpp:255
ProgramWireAdoption
Definition program_wire.hpp:881
@ Unchanged
Definition program_wire.hpp:883
constexpr std::uint32_t kProgramWireMagic
Spells PLPW in the first four bytes of every payload.
Definition program_wire.hpp:205
constexpr std::uint32_t kProgramWireNoLane
A track's mixer control that no automation lane supersedes.
Definition program_wire.hpp:208
constexpr std::uint64_t program_wire_checksum(std::span< const std::byte > bytes) noexcept
FNV-1a over 64 bits.
Definition program_wire.hpp:655
constexpr std::size_t kProgramWireMaximumTracks
Decoder work and fixed scratch remain bounded even for untrusted payloads.
Definition program_wire.hpp:211
std::uint64_t ProgramGeneration
Definition program_identity.hpp:10
@ InvalidSampleRate
Definition external_sync.hpp:96
std::uint64_t program_wire_process_epoch() noexcept
A nonzero value that is stable for this process and differs between processes.
runtime::Result< std::size_t, ProgramWireError > program_wire_encoded_size(const PlaybackProgram &program, std::span< const timebase::TempoPoint > tempo_points) noexcept
Bytes encode_program_wire needs for this program.
ProgramWireSection
Definition program_wire.hpp:228
@ NoteModifiers
Definition program_wire.hpp:234
@ DevicePlacementIds
Definition program_wire.hpp:235
@ Tracks
Definition program_wire.hpp:231
@ AutomationLanes
Definition program_wire.hpp:236
@ TempoPoints
Definition program_wire.hpp:230
@ AutomationSegments
Definition program_wire.hpp:237
@ NoteEvents
Definition program_wire.hpp:233
@ Program
Definition program_wire.hpp:229
@ ControllerRanges
One (first, count) range per track into ControllerEvents, in track order.
Definition program_wire.hpp:242
@ ControllerEvents
Definition program_wire.hpp:243
@ ClipIds
Definition program_wire.hpp:232
Definition generated_event_source.hpp:33
SequencerStateChannel is the audio-safe transport for a plugin's structured NON-parameter state: the ...
Definition audio_device_manager.hpp:48
Definition beat_division.hpp:11
Hover-cursor tracking for platform window hosts.
Definition fwd.hpp:27
STL namespace.
Result<T, E> — success / failure union for fallible operations.
Definition automation_cursor.hpp:44
Preparation and callback-work ceilings shared by document compilation and track automation rendering.
Definition automation_limits.hpp:12
Definition automation_program.hpp:21
Definition program_wire.hpp:887
ProgramWireBytePin returned_pin
Candidate on reject/unchanged, or the previous active pin on adoption.
Definition program_wire.hpp:892
ProgramWireConsumerCode code
Definition program_wire.hpp:888
ProgramWireAdoption adoption
Definition program_wire.hpp:889
ProgramWireError wire_error
Definition program_wire.hpp:890
timeline::ItemId lane_id
Definition program_wire.hpp:925
AutomationCursorResult result
Definition program_wire.hpp:927
timeline::ItemId track_id
Definition program_wire.hpp:924
std::span< AutomationBlockEvent > events
Definition program_wire.hpp:926
instance_token is the producer's own AutomationProgram::instance_token() carried verbatim,...
Definition program_wire.hpp:568
float leading_value
Definition program_wire.hpp:576
std::uint32_t segment_count
Definition program_wire.hpp:575
std::uint8_t pad1[3]
Definition program_wire.hpp:586
std::uint8_t target_kind
Definition program_wire.hpp:577
std::uint32_t device_param_id
Zero unless target_kind is DeviceParameter.
Definition program_wire.hpp:583
std::uint8_t mixer_parameter
Zero unless target_kind is TrackMixer.
Definition program_wire.hpp:585
std::uint8_t evaluation_rate
Definition program_wire.hpp:578
std::uint64_t lane_id
Definition program_wire.hpp:569
std::uint32_t segment_first
Definition program_wire.hpp:574
std::uint64_t instance_token
Nonzero always.
Definition program_wire.hpp:573
std::uint64_t device_placement_id
Zero unless target_kind is DeviceParameter.
Definition program_wire.hpp:581
std::uint16_t pad0
Definition program_wire.hpp:579
std::uint64_t generation
Definition program_wire.hpp:570
ProgramWireConsumerCode code
Definition program_wire.hpp:931
std::uint32_t rendered_lanes
Definition program_wire.hpp:932
Deliberately not laid out like AutomationProgramSegment: this groups the three floats and puts interp...
Definition program_wire.hpp:594
float start_value
Definition program_wire.hpp:599
std::uint8_t interpolation
Definition program_wire.hpp:602
float end_value
Definition program_wire.hpp:600
std::int64_t end_sample
Definition program_wire.hpp:598
std::int64_t end_tick
Definition program_wire.hpp:596
float curvature
Definition program_wire.hpp:601
std::int64_t start_tick
Definition program_wire.hpp:595
std::int64_t start_sample
Definition program_wire.hpp:597
std::uint8_t pad[3]
Definition program_wire.hpp:603
One ControllerProgramEvent, field by field — never cast between the two, for the reason given on Prog...
Definition program_wire.hpp:521
std::uint32_t value
Definition program_wire.hpp:527
std::int64_t tick
Definition program_wire.hpp:523
std::int64_t sample
Definition program_wire.hpp:522
std::uint8_t origin
Definition program_wire.hpp:533
std::uint64_t clip_id
Definition program_wire.hpp:524
std::uint64_t lane_id
Definition program_wire.hpp:525
std::uint8_t group
Definition program_wire.hpp:528
std::uint64_t point_id
Definition program_wire.hpp:526
std::uint8_t bank
Definition program_wire.hpp:531
std::uint8_t status
Definition program_wire.hpp:530
std::uint8_t index
Definition program_wire.hpp:532
std::uint8_t pad[6]
Definition program_wire.hpp:534
std::uint8_t channel
Definition program_wire.hpp:529
One track's range into the ControllerEvents section.
Definition program_wire.hpp:507
std::uint32_t first
Definition program_wire.hpp:508
std::uint32_t count
Definition program_wire.hpp:509
Definition program_wire.hpp:359
std::uint32_t section
The section id the failure concerns, or zero when it concerns the header or the directory as a whole.
Definition program_wire.hpp:363
std::uint64_t detail
Failure-specific context: a required byte count, an offset, a record index, an item id,...
Definition program_wire.hpp:366
ProgramWireErrorCode code
Definition program_wire.hpp:360
The fixed prefix every payload starts with.
Definition program_wire.hpp:374
std::uint32_t header_bytes
Definition program_wire.hpp:378
std::uint64_t payload_bytes
Definition program_wire.hpp:380
std::uint32_t magic
Definition program_wire.hpp:375
std::uint64_t body_checksum
Definition program_wire.hpp:381
std::uint64_t reserved2
Definition program_wire.hpp:384
std::uint64_t reserved1
Definition program_wire.hpp:383
std::uint64_t reserved3
Definition program_wire.hpp:385
std::uint64_t reserved0
Definition program_wire.hpp:382
std::uint16_t version
Definition program_wire.hpp:376
std::uint16_t min_reader_version
Definition program_wire.hpp:377
std::uint32_t section_count
Definition program_wire.hpp:379
Definition program_wire.hpp:469
std::uint64_t value
Definition program_wire.hpp:470
Definition program_wire.hpp:895
timeline::ItemId track_id
Definition program_wire.hpp:898
constexpr bool operator==(const ProgramWireLaneIdentity &) const =default
AutomationProgramInstanceToken instance_token
Definition program_wire.hpp:902
std::uint64_t producer_epoch
Definition program_wire.hpp:896
ProgramGeneration track_generation
Definition program_wire.hpp:899
ProgramGeneration lane_generation
Definition program_wire.hpp:901
timeline::ItemId lane_id
Definition program_wire.hpp:900
ProgramGeneration program_generation
Definition program_wire.hpp:897
One caller-provided fixed-capacity state slot.
Definition program_wire.hpp:908
bool group_coalesced
Definition program_wire.hpp:920
AutomationCursorResult cursor_result
Definition program_wire.hpp:914
std::uint32_t write_position
Definition program_wire.hpp:918
AutomationCursor cursor
Definition program_wire.hpp:910
AutomationCursor next_cursor
Definition program_wire.hpp:911
std::uint32_t selected_count
Definition program_wire.hpp:917
ProgramWireLaneIdentity identity
Definition program_wire.hpp:909
std::size_t output_index
Definition program_wire.hpp:919
std::array< AutomationBlockEvent, AutomationPlaybackLimits::kMaximumEventsPerDevicePerBlock > scratch
Definition program_wire.hpp:913
std::uint32_t merge_position
Definition program_wire.hpp:916
std::uint32_t event_count
Definition program_wire.hpp:915
This happens to hold the same fields in the same order as NoteProgramEvent, and that correspondence i...
Definition program_wire.hpp:480
std::uint8_t kind
Definition program_wire.hpp:488
std::uint64_t clip_id
Definition program_wire.hpp:483
std::uint8_t pad[3]
Definition program_wire.hpp:489
std::uint8_t channel
Definition program_wire.hpp:487
std::uint64_t note_id
Definition program_wire.hpp:484
std::uint16_t velocity
Definition program_wire.hpp:485
std::int64_t sample
Definition program_wire.hpp:481
std::int64_t tick
Definition program_wire.hpp:482
std::uint8_t pitch
Definition program_wire.hpp:486
Definition program_wire.hpp:492
std::uint16_t condition_period
Definition program_wire.hpp:496
std::uint16_t probability
Definition program_wire.hpp:495
std::uint8_t pad[7]
Definition program_wire.hpp:500
std::uint16_t ratchet_count
Definition program_wire.hpp:498
std::uint64_t note_id
Definition program_wire.hpp:494
std::uint64_t draw_key
Definition program_wire.hpp:493
std::uint16_t condition_offset
Definition program_wire.hpp:497
std::uint8_t condition
Definition program_wire.hpp:499
The whole-program scalars, including the tempo map's sample rate and the automation ceilings the adop...
Definition program_wire.hpp:398
std::uint32_t max_points_per_track
Definition program_wire.hpp:414
std::uint32_t max_device_placements_per_track
Definition program_wire.hpp:411
std::uint32_t max_lanes_per_track
Definition program_wire.hpp:412
std::uint64_t sequence_id
Definition program_wire.hpp:407
std::uint32_t max_events_per_device_per_block
Definition program_wire.hpp:416
std::uint64_t sample_rate_numerator
Definition program_wire.hpp:409
std::uint64_t document_revision
Definition program_wire.hpp:405
std::uint64_t project_id
Definition program_wire.hpp:406
std::uint64_t sample_rate_denominator
Definition program_wire.hpp:410
std::uint32_t max_intersecting_segments_per_block
Definition program_wire.hpp:415
std::uint32_t max_points_per_lane
Definition program_wire.hpp:413
std::uint64_t generated_id_base
Definition program_wire.hpp:408
std::uint64_t producer_epoch
Identifies the producer that minted generation.
Definition program_wire.hpp:403
std::uint64_t generation
Definition program_wire.hpp:404
Definition program_wire.hpp:388
std::uint64_t offset
Byte offset from the first payload byte, not from the buffer base.
Definition program_wire.hpp:392
std::uint64_t bytes
Definition program_wire.hpp:393
std::uint32_t flags
Definition program_wire.hpp:390
The editable tempo points, not the compiled segments.
Definition program_wire.hpp:423
std::int64_t tick
Definition program_wire.hpp:424
std::uint8_t pad[7]
Definition program_wire.hpp:428
std::uint8_t curve_to_next
Definition program_wire.hpp:427
std::uint64_t bpm_bits
bpm as its IEEE-754 bit pattern, so a payload round-trips bit-exactly.
Definition program_wire.hpp:426
One track.
Definition program_wire.hpp:433
std::uint32_t device_placement_count
Definition program_wire.hpp:443
std::uint8_t state_policy
Definition program_wire.hpp:459
std::uint32_t automation_lane_first
Definition program_wire.hpp:444
std::uint32_t pad
Definition program_wire.hpp:464
std::uint64_t generation
Definition program_wire.hpp:435
std::uint32_t clip_first
Definition program_wire.hpp:436
std::uint32_t mixer_pan_lane
Definition program_wire.hpp:456
std::uint8_t provider_available_mask
Definition program_wire.hpp:458
std::uint32_t note_event_count
Definition program_wire.hpp:439
std::uint32_t note_modifier_count
Definition program_wire.hpp:441
std::uint64_t generated_id_start
Definition program_wire.hpp:448
std::uint32_t automation_lane_count
Definition program_wire.hpp:445
std::uint8_t provider_selected
Definition program_wire.hpp:457
std::uint32_t note_modifier_first
Definition program_wire.hpp:440
std::uint8_t flags
Bit 0: the track carries an automation program at all.
Definition program_wire.hpp:463
std::uint64_t generated_id_count
Definition program_wire.hpp:449
std::uint32_t mixer_gain_lane
Index within this track's own automation lane range, or kProgramWireNoLane.
Definition program_wire.hpp:455
std::uint32_t clip_count
Definition program_wire.hpp:437
std::uint32_t note_event_first
Definition program_wire.hpp:438
std::uint64_t expanded_note_event_count
Definition program_wire.hpp:447
std::uint64_t expanded_clip_count
Definition program_wire.hpp:446
float mixer_pan
Definition program_wire.hpp:451
float mixer_gain_linear
Definition program_wire.hpp:450
std::uint32_t device_placement_first
Definition program_wire.hpp:442
Definition transport.hpp:71
Definition rational_time.hpp:14
Nonzero monotonic identity for a Timeline-owned object.
Definition item_id.hpp:19