38 switch (safety_class) {
40 return "audio-callback-safe";
42 return "audio-callback-safe-after-prepare";
44 return "audio-callback-safe-with-immutable-inputs";
46 return "realtime-telemetry-only";
48 return "control-thread-only";
50 return "background-thread-only";
52 return "offline-only";
59 switch (safety_class) {
75 switch (safety_class) {
92 std::string_view component,
93 std::string_view operation,
95 bool audio_callback_allowed,
99 bool requires_prepare,
100 std::string_view owner_boundary,
101 std::string_view notes)
noexcept {
105 audio_callback_allowed,
118 "PlanarAudioRingBuffer",
126 "one source producer and one host consumer",
127 "Prepared fixed storage; short reads zero-fill and short writes drop excess frames."),
129 "AudioStreamHandoff",
137 "one generated-audio producer and one host consumer",
138 "Prepared resampler handoff; underruns are zero-filled."),
140 "RollingAudioCaptureBuffer",
141 "append_snapshot_hold",
148 "single capture owner",
149 "Append/snapshot/hold are owner-thread operations; held appends are discarded and counted."),
151 "RollingAudioCaptureBuffer",
159 "capture owner or paused external materializer",
160 "Materialization copies held or quiescent storage and must not race live append."),
162 "RealtimeSampleRecorder",
163 "enqueue_pop_process",
170 "one command producer, one event consumer, one audio processor",
171 "Prepared queues/storage; commands are block-offset sorted inside process()."),
173 "RealtimeSampleRecorder",
174 "materialize_snapshot",
181 "paused capture owner or active hold owner",
182 "Copies rolling-capture data into recorder storage outside the callback."),
184 "RealtimeSampleRecorder",
185 "release_reset_consume",
193 "Do not call concurrently with process(); use queued reset for live control."),
196 "publish_from_buffer",
203 "single serialized publication owner",
204 "Prepared fixed slots are mutated off callback and exposed through generation-safe views."),
207 "read_published_view",
214 "audio reader with externally retained slot generations",
215 "Audio code reads PublishedSampleView snapshots and generation-aware channel pointers only."),
217 "PublishedSampleStore",
225 "controller, importer, or background publication owner",
226 "Load/publish may copy, allocate, block, and take the store mutex."),
228 "PublishedSampleView",
236 "generation-pinned audio reader",
237 "Borrowed channel pointers remain valid only while the published generation is retained."),
248 "Copies zone metadata and publishes whole-map snapshots for realtime readers."),
258 "audio reader over immutable map snapshot",
259 "Selection owns no sample storage and performs bounded metadata lookup."),
269 "audio reader over immutable pool snapshot",
270 "Borrowed PublishedSampleStore instances must outlive realtime readers."),
280 "audio trigger path with immutable zone map and sample pool",
281 "Resolves pool-backed zones and playback rate without allocating voices."),
283 "InstrumentVoiceAllocator",
284 "trigger_release_finish",
291 "audio-owned prepared voice slots",
292 "Mutates only the prepared voice array; publish telemetry through separate queues."),
302 "per-voice envelope owner",
303 "Prepared envelope state renders gains into caller-owned buffers."),
305 "VoiceModulationBuffer",
313 "per-voice or per-block modulation owner",
314 "Prepared lane/value storage is reused for each block."),
316 "SampleVoiceRenderer",
324 "voice render owner with borrowed sample view and caller-owned scratch",
325 "Renders scalar one-shot or region playback into caller-owned output buffers."),
335 "caller-owned voice scratch and output buffers",
336 "Static mixer over non-overlapping source and destination buffers."),
338 "SampleStreamWindow",
346 "audio reader with generation-gated page lifetimes",
347 "Reads resident prepared pages only; never loads, fills, evicts, or performs file I/O."),
357 "renderer that already validated source region for the block",
358 "Unchecked fast path for hot loops; public read() remains the guard rail."),
368 "voice or loop render owner with immutable source buffer",
369 "Stateful overwrite renderer for caller-owned scratch/output buffers."),
379 "audio reader over an immutable asset publication",
380 "Metadata, preload pointer, and stream identity reads do not mutate the asset."),
382 "PreparedSampleInterpolation",
383 "footprint_evaluate",
390 "renderer over prepared interpolation state and caller-owned taps",
391 "Footprint resolution and evaluation are bounded arithmetic over fixed spans."),
393 "LoopPlaybackCursor",
394 "frame_read_plan_advance",
401 "audio-owned cursor with an immutable validated loop region",
402 "Read planning and cursor advancement mutate only bounded per-voice state."),
404 "SampleStreamRequestInbox",
412 "one demand producer and one scheduler consumer",
413 "Fixed-capacity SPSC demand publication drops overflow instead of allocating."),
415 "SampleStreamCommandInbox",
423 "one audio command producer and one cache-service consumer",
424 "Demand and cancellation commands carry fixed-size tokens through SPSC storage."),
426 "SampleStreamService",
427 "begin_complete_audio_page_read",
434 "audio reader bracketing immutable page-view access",
435 "Epoch entry and completion protect cache-page reclamation without locks."),
437 "SampleStreamVoiceReader",
445 "audio-owned forward voice reader over prepared asset and page views",
446 "Narrow one-shot planning and rendering use fixed demand and tap storage."),
448 "SampleStreamLoopVoiceReader",
456 "audio-owned loop voice reader over prepared asset and page views",
457 "Loop-aware planning and rendering use fixed demand, page, cursor, and tap storage."),
459 "SampleStarvationEnvelope",
467 "per-voice starvation state owner",
468 "Gain transitions are bounded arithmetic over prepared fade lengths."),
478 "serialized asset owner after realtime readers quiesce",
479 "Preparation copies or adopts preload storage and publishes immutable metadata."),
481 "SampleStreamService",
482 "prepare_mutate_cache",
489 "single cache-service owner",
490 "Preparation, fill completion, eviction, cancellation, and reclamation mutate shared cache state."),
492 "SampleStreamDecodePool",
500 "registered source worker selected by the decode pool",
501 "Workers may wait, call decoder bindings, and publish completion records."),
503 "SampleStreamAsyncService",
511 "single async-service owner coordinating cache and decode workers",
512 "Demand draining, reservations, completion handling, and retirement are off callback."),
514 "SampleMemoryGovernorHandle",
522 "sampler memory-budget owner",
523 "Reservations and statistics lock shared accounting and may create lease ownership."),
533 "lease owner outside realtime processing",
534 "Lease reset and destruction return bytes through locked shared accounting."),
544 "editor, importer, or analysis job",
545 "May inspect long windows and run candidate search outside Processor::process()."),
555 "editor, importer, or analysis job",
556 "Produces onset markers for slice analysis outside package-specific APIs."),
558 "SlicePointAnalyzer",
566 "editor, importer, or analysis job",
567 "Combines transient/beat/manual/imported markers into slice maps off callback."),
569 "TimePitchProcessor",
570 "prepare_process_release",
577 "offline render, bounce, or analysis owner",
578 "Package-backed processors are optional and may initialize package/platform internals."),
580 "SampleAssetImporter",
588 "importer or platform adapter",
589 "May do file I/O, codec work, locks, and decoded-audio allocation."),
591 "SampleAssetExporter",
599 "exporter or platform adapter",
600 "May do file I/O, codec work, locks, and encoded-audio allocation."),
602 "SampleSlotMaterializer",
603 "publish_completed_recording",
610 "publication owner with recorder and slot bank quiesced as required",
611 "Moves completed recorder data into prepared slots outside the callback."),
621 "waveform analysis/cache owner",
622 "Builds peaks, serializes cache payloads, and may read files, lock, or allocate."),
625[[nodiscard]]
constexpr std::span<const RtSafetyContract>
631 std::string_view component,
632 std::string_view operation)
noexcept {
634 if (contract.component == component && contract.operation == operation) {
662 "one writer thread; any number of reader threads",
663 "Lock-free coherent snapshot via acquire/release seq counter; readers "
664 "bounded-spin-retry on a concurrent write, never block on a lock."),
674 "single writer thread",
675 "Relaxed atomic word/tail-byte payload copy bracketed by an odd/even "
676 "seq increment; cost scales with sizeof(T), so keep T small for "
677 "audio-thread writers."),
687 "one writer thread and one reader thread",
688 "Lock-free latest-value publication via a dirty-bit CAS; the writer "
689 "copies whole T into the back buffer, so bound sizeof(T)."),
699 "one producer thread and one consumer thread",
700 "Wraps choc SingleReaderSingleWriterFIFO; fixed capacity, overflow is "
701 "counted and the push fails rather than allocating."),
703 "RealtimeResourceSlot",
711 "one non-RT publisher/reclaimer; any number of audio readers",
712 "Acquire-loads a raw prepared-resource pointer. The pointer is not "
713 "reader-pinned; the non-RT owner reclaims retired resources only after "
714 "a block-boundary grace point."),
716 "ParameterEventQueue",
724 "per-block automation owner on the audio thread",
725 "Fixed-capacity (kCapacity) std::array storage; push/sort/clear never "
726 "allocate, overflow is dropped and counted. sort() is a stable "
727 "insertion sort tuned for near-sorted host automation."),
729 "AudioProcessLoadMeasurer",
737 "one measuring thread; any number of polling threads",
738 "steady_clock delta plus relaxed-atomic latest-value stores; emits "
739 "telemetry only, performs no signal processing or control mutation."),
741 "ScopedFlushDenormals",
749 "audio callback boundary owner",
750 "Sets the CPU flush-to-zero FP mode (MXCSR FTZ / FPCR.FZ) on entry and "
751 "restores the caller's mode on exit; no allocation, lock, or syscall."),
761 "audio thread over a prepared, published CompiledGraph snapshot",
762 "Loads the live snapshot via an atomic raw pointer under a reader-count "
763 "guard (deliberately not atomic<shared_ptr>), then walks ordered_runtime "
764 "single-threaded; topology mutation happens off the callback."),
774 "exactly one writer per MidiInput node; audio-thread snapshot consumer",
775 "Publishes a latest-wins, one-shot fixed-capacity mailbox batch. A "
776 "preserved node ID shares the mailbox across a gap-free graph swap; "
777 "concurrent writers are unsupported."),
787 "audio thread; format adapter sets RT sidecars before the call",
788 "The plugin DSP entry point: no allocation, lock, I/O, or exceptions. "
789 "Adapters wrap it in ScopedNoAlloc; prepare() must run first."),
791 "GraphRuntimeExecutor",
799 "audio thread over a prepared snapshot + pre-sized GraphRuntimeBufferPool",
800 "Routes inter-node audio through caller-allocated scratch slots: "
801 "gather/scatter, the one-block feedback capture, and the per-connection "
802 "delay-compensation rings are bounded fills and copies, no allocation or "
803 "lock. The snapshot's buffer assignment and the pool (slots + delay "
804 "rings) are built off the callback; pool.fits() must hold for the block."),
807[[nodiscard]]
constexpr std::span<const RtSafetyContract>
813 std::string_view component,
814 std::string_view operation)
noexcept {
816 if (contract.component == component && contract.operation == operation) {
constexpr RtSafetyContract make_rt_safety_contract(std::string_view component, std::string_view operation, RtSafetyClass safety_class, bool audio_callback_allowed, bool may_allocate, bool may_lock, bool may_block, bool requires_prepare, std::string_view owner_boundary, std::string_view notes) noexcept
Definition rt_safety_contract.hpp:91
Definition analyzer_provider.hpp:12
constexpr std::array kCoreRuntimeRtSafetyContracts
Definition rt_safety_contract.hpp:652
constexpr bool rt_safety_class_may_be_called_from_realtime_thread(RtSafetyClass safety_class) noexcept
Definition rt_safety_contract.hpp:57
constexpr const RtSafetyContract * find_sampler_looper_rt_safety_contract(std::string_view component, std::string_view operation) noexcept
Definition rt_safety_contract.hpp:630
constexpr std::span< const RtSafetyContract > core_runtime_rt_safety_contracts() noexcept
Definition rt_safety_contract.hpp:808
constexpr std::array kSamplerLooperRtSafetyContracts
Definition rt_safety_contract.hpp:116
RtSafetyClass
Definition rt_safety_contract.hpp:11
@ ControlThreadOnly
Definition rt_safety_contract.hpp:18
@ BackgroundThreadOnly
Definition rt_safety_contract.hpp:19
@ AudioCallbackSafeAfterPrepare
Definition rt_safety_contract.hpp:13
@ AudioCallbackSafe
Definition rt_safety_contract.hpp:12
@ OfflineOnly
Definition rt_safety_contract.hpp:20
@ RealtimeTelemetryOnly
Definition rt_safety_contract.hpp:17
@ AudioCallbackSafeWithImmutableInputs
Definition rt_safety_contract.hpp:14
constexpr std::string_view rt_safety_class_name(RtSafetyClass safety_class) noexcept
Definition rt_safety_contract.hpp:36
constexpr std::span< const RtSafetyContract > sampler_looper_rt_safety_contracts() noexcept
Definition rt_safety_contract.hpp:626
constexpr const RtSafetyContract * find_core_runtime_rt_safety_contract(std::string_view component, std::string_view operation) noexcept
Definition rt_safety_contract.hpp:812
constexpr bool rt_safety_class_is_audio_dsp_safe(RtSafetyClass safety_class) noexcept
Definition rt_safety_contract.hpp:73
@ OfflineOnly
Definition analyzer_provider.hpp:52
Definition rt_safety_contract.hpp:23
bool may_lock
Definition rt_safety_contract.hpp:29
bool requires_prepare
Definition rt_safety_contract.hpp:31
bool may_block
Definition rt_safety_contract.hpp:30
std::string_view operation
Definition rt_safety_contract.hpp:25
bool audio_callback_allowed
Definition rt_safety_contract.hpp:27
bool may_allocate
Definition rt_safety_contract.hpp:28
RtSafetyClass safety_class
Definition rt_safety_contract.hpp:26
std::string_view owner_boundary
Definition rt_safety_contract.hpp:32
std::string_view component
Definition rt_safety_contract.hpp:24
std::string_view notes
Definition rt_safety_contract.hpp:33