Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
capability_tables.hpp
Go to the documentation of this file.
1// Generated by core/interchange/tools/capability_emit.py -- do not edit.
2// Source of truth: core/interchange/capabilities/*.json
3#pragma once
4
6
7#include <cstddef>
8#include <cstdint>
9#include <string_view>
10
11namespace pulp::interchange {
12
14enum class ImportLevel : std::uint8_t {
15 None = 0,
18 Full = 3,
19};
20
22enum class ExportLevel : std::uint8_t {
23 Drop = 0,
26 Full = 3,
27};
28
30enum class LossClass : std::uint8_t {
35};
36
38enum class Format : std::uint8_t {
40 Smf = 1,
41};
42
43inline constexpr std::size_t kFormatCount = 2;
44
45struct ImportRow {
48 std::string_view notes;
50 std::string_view refusal;
51};
52
61
62namespace detail {
64 std::string_view id;
65 std::string_view display_name;
67};
68
70 {"dawproject", "DAWproject", true},
71 {"smf", "Standard MIDI File", true},
72};
73
75 // dawproject
76 {
77 {ImportLevel::None, "", ""}, // unknown
78 {ImportLevel::Full, "", ""}, // track.flat
79 {ImportLevel::None, "", "nested group tracks"}, // track.group
80 {ImportLevel::None, "", ""}, // track.video
81 {ImportLevel::Full, "", ""}, // clip.musical
82 {ImportLevel::None, "", "seconds-timed lanes, clips, and notes"}, // clip.absolute
83 {ImportLevel::Full, "", ""}, // clip.note
84 {ImportLevel::Full, "", ""}, // clip.media
85 {ImportLevel::None, "", "per-clip gain"}, // clip.gain
86 {ImportLevel::None, "", "per-clip fades"}, // clip.fades
87 {ImportLevel::None, "", ""}, // clip.crossfade
88 {ImportLevel::None, "", "warped clip content"}, // clip.warp
89 {ImportLevel::None, "", "scenes and clip-launcher content"}, // clip.launch
90 {ImportLevel::None, "", ""}, // gap.explicit
91 {ImportLevel::Full, "", ""}, // tempo.single
92 {ImportLevel::None, "", "tempo changing after bar 1"}, // tempo.map
93 {ImportLevel::Full, "", ""}, // meter.single
94 {ImportLevel::None, "", "time signature changing after bar 1"}, // meter.map
95 {ImportLevel::None, "", "arrangement markers"}, // marker
96 {ImportLevel::None, "", ""}, // timecode.origin
97 {ImportLevel::None, "", ""}, // media.provenance
98 {ImportLevel::None, "", "channel volume"}, // mixer.track-gain
99 {ImportLevel::None, "", "channel pan"}, // mixer.track-pan
100 {ImportLevel::None, "", ""}, // mixer.sends
101 {ImportLevel::None, "", "automation lanes"}, // automation.device-param
102 {ImportLevel::None, "", "volume automation lanes"}, // automation.track-gain
103 {ImportLevel::None, "", "pan automation lanes"}, // automation.track-pan
104 {ImportLevel::None, "", "device chains"}, // device.placement
105 {ImportLevel::None, "", "plugin state"}, // device.payload
106 {ImportLevel::None, "", ""}, // effect.timewarp
107 {ImportLevel::None, "", ""}, // take.lane
108 {ImportLevel::None, "", ""}, // take.comp
109 {ImportLevel::None, "", ""}, // track.freeze
110 {ImportLevel::Full, "", ""}, // asset.sealed-hash
111 {ImportLevel::None, "", ""}, // asset.embedded-media
112 {ImportLevel::Full, "package-relative locator retained verbatim; identity sealed to the resolved bytes", ""}, // asset.referenced-media
113 {ImportLevel::None, "", ""}, // sequence.multiple
114 {ImportLevel::None, "", ""}, // sequence.nested
115 {ImportLevel::None, "", ""}, // content.registered
116 {ImportLevel::None, "", ""}, // content.opaque
117 {ImportLevel::None, "", ""}, // edit-rate.non-audio
118 {ImportLevel::None, "", "chord and scale context lanes"}, // context.chord-scale
119 {ImportLevel::None, "", "groove templates and swing"}, // context.groove
120 {ImportLevel::None, "", "per-note probability, conditions, and ratchets"}, // clip.note-modifier
121 {ImportLevel::Full, "", ""}, // clip.empty
122 {ImportLevel::None, "", ""}, // tempo.ramp
123 {ImportLevel::None, "", ""}, // clip.note-velocity-quantized
124 {ImportLevel::None, "", ""}, // tempo.value-quantized
125 {ImportLevel::None, "", ""}, // clip.media-window
126 {ImportLevel::None, "", ""}, // clip.fade-shape
127 {ImportLevel::None, "", "per-clip controller and expression streams"}, // clip.midi-expression-lane
128 {ImportLevel::None, "", ""}, // sequence.section-role
129 {ImportLevel::None, "", ""}, // context.chord-bass
130 {ImportLevel::None, "", ""}, // context.chord-extension
131 {ImportLevel::None, "", ""}, // context.chord-voicing
132 {ImportLevel::None, "", ""}, // tuning.project
133 {ImportLevel::None, "", ""}, // tuning.instrument
134 {ImportLevel::None, "", ""}, // modulation.modulator
135 {ImportLevel::None, "", ""}, // modulation.macro
136 {ImportLevel::None, "", ""}, // modulation.route-device-param
137 {ImportLevel::None, "", ""}, // modulation.route-track-mixer
138 },
139 // smf
140 {
141 {ImportLevel::None, "", ""}, // unknown
142 {ImportLevel::Full, "", ""}, // track.flat
143 {ImportLevel::None, "", ""}, // track.group
144 {ImportLevel::None, "", ""}, // track.video
145 {ImportLevel::Partial, "positions are exact when the file division divides the canonical tick grid; otherwise import reports bounded nearest-tick rounding", ""}, // clip.musical
146 {ImportLevel::None, "", "sample-anchored clips"}, // clip.absolute
147 {ImportLevel::Full, "", ""}, // clip.note
148 {ImportLevel::None, "", "media clips"}, // clip.media
149 {ImportLevel::None, "", ""}, // clip.gain
150 {ImportLevel::None, "", ""}, // clip.fades
151 {ImportLevel::None, "", ""}, // clip.crossfade
152 {ImportLevel::None, "", ""}, // clip.warp
153 {ImportLevel::None, "", ""}, // clip.launch
154 {ImportLevel::None, "", ""}, // gap.explicit
155 {ImportLevel::Partial, "tempo periods are represented as integer microseconds and may round on import", ""}, // tempo.single
156 {ImportLevel::Partial, "tempo positions may use bounded nearest-tick rounding on non-dividing file grids, and periods are integer microseconds", ""}, // tempo.map
157 {ImportLevel::Partial, "meter positions may use bounded nearest-tick rounding on non-dividing file grids", ""}, // meter.single
158 {ImportLevel::Partial, "time-signature changes are admitted only when they land on canonical bar boundaries", ""}, // meter.map
159 {ImportLevel::None, "", "arrangement markers"}, // marker
160 {ImportLevel::None, "", ""}, // timecode.origin
161 {ImportLevel::None, "", ""}, // media.provenance
162 {ImportLevel::None, "", ""}, // mixer.track-gain
163 {ImportLevel::None, "", ""}, // mixer.track-pan
164 {ImportLevel::None, "", ""}, // mixer.sends
165 {ImportLevel::None, "", "automation lanes"}, // automation.device-param
166 {ImportLevel::None, "", ""}, // automation.track-gain
167 {ImportLevel::None, "", ""}, // automation.track-pan
168 {ImportLevel::None, "", "device chains"}, // device.placement
169 {ImportLevel::None, "", ""}, // device.payload
170 {ImportLevel::None, "", ""}, // effect.timewarp
171 {ImportLevel::None, "", "takes and comp lanes"}, // take.lane
172 {ImportLevel::None, "", ""}, // take.comp
173 {ImportLevel::None, "", ""}, // track.freeze
174 {ImportLevel::None, "", ""}, // asset.sealed-hash
175 {ImportLevel::None, "", ""}, // asset.embedded-media
176 {ImportLevel::None, "", ""}, // asset.referenced-media
177 {ImportLevel::None, "", ""}, // sequence.multiple
178 {ImportLevel::None, "", ""}, // sequence.nested
179 {ImportLevel::None, "", ""}, // content.registered
180 {ImportLevel::None, "", ""}, // content.opaque
181 {ImportLevel::None, "", ""}, // edit-rate.non-audio
182 {ImportLevel::None, "", ""}, // context.chord-scale
183 {ImportLevel::None, "", ""}, // context.groove
184 {ImportLevel::None, "", "per-note probability, conditions, and ratchets"}, // clip.note-modifier
185 {ImportLevel::None, "", "empty positioned clips"}, // clip.empty
186 {ImportLevel::None, "", "continuous tempo ramps"}, // tempo.ramp
187 {ImportLevel::None, "", ""}, // clip.note-velocity-quantized
188 {ImportLevel::None, "", ""}, // tempo.value-quantized
189 {ImportLevel::None, "", ""}, // clip.media-window
190 {ImportLevel::None, "", ""}, // clip.fade-shape
191 {ImportLevel::None, "", "per-clip controller and expression streams"}, // clip.midi-expression-lane
192 {ImportLevel::None, "", ""}, // sequence.section-role
193 {ImportLevel::None, "", ""}, // context.chord-bass
194 {ImportLevel::None, "", ""}, // context.chord-extension
195 {ImportLevel::None, "", ""}, // context.chord-voicing
196 {ImportLevel::None, "", ""}, // tuning.project
197 {ImportLevel::None, "", ""}, // tuning.instrument
198 {ImportLevel::None, "", ""}, // modulation.modulator
199 {ImportLevel::None, "", ""}, // modulation.macro
200 {ImportLevel::None, "", ""}, // modulation.route-device-param
201 {ImportLevel::None, "", ""}, // modulation.route-track-mixer
202 },
203};
204
206 // dawproject
207 {
208 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "DAWproject declares no support for unknown"}, // unknown
210 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "DAWproject declares no support for track.group"}, // track.group
211 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "DAWproject declares no support for track.video"}, // track.video
213 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "the writer cannot place sample-anchored clips on its beats-only lane, so the clip and its content are omitted"}, // clip.absolute
216 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "the writer does not emit a clip gain, so an authored clip gain is dropped and the clip exports at unity"}, // clip.gain
217 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "the writer does not emit clip fades, so authored fade-in and fade-out durations are dropped and the clip exports with hard edges"}, // clip.fades
218 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "DAWproject declares no support for clip.crossfade"}, // clip.crossfade
219 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "DAWproject declares no support for clip.warp"}, // clip.warp
220 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "DAWproject declares no support for clip.launch"}, // clip.launch
221 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "DAWproject declares no support for gap.explicit"}, // gap.explicit
223 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "DAWproject declares no support for tempo.map"}, // tempo.map
225 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "DAWproject declares no support for meter.map"}, // meter.map
226 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "the writer does not emit markers or regions, so every named point and range on the timeline is dropped"}, // marker
227 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "the writer does not emit a session timecode origin, so the exported document starts at zero and every timecode reference shifts"}, // timecode.origin
228 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "DAWproject declares no support for media.provenance"}, // media.provenance
229 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "the writer does not emit a channel volume, so an authored track gain is dropped and the track exports at unity"}, // mixer.track-gain
230 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "the writer does not emit a channel pan, so an authored track pan is dropped and the track exports centred"}, // mixer.track-pan
231 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "DAWproject declares no support for mixer.sends"}, // mixer.sends
232 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "device identity does not survive without a device payload, so its automation has no target"}, // automation.device-param
233 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "a volume automation lane has no export target while channel volume itself is dropped"}, // automation.track-gain
234 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "a pan automation lane has no export target while channel pan itself is dropped"}, // automation.track-pan
235 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "devices are identity-only in the document; DAWproject requires a device type to place one"}, // device.placement
236 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "DAWproject declares no support for device.payload"}, // device.payload
237 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "DAWproject declares no support for effect.timewarp"}, // effect.timewarp
238 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "the writer does not inspect take lanes, so alternate takes are omitted"}, // take.lane
239 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "the writer does not flatten comp selections, so comp segment choices are omitted"}, // take.comp
240 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "DAWproject has no freeze concept; the authored track is exported and the sealed render is dropped"}, // track.freeze
241 {ExportLevel::Full, Concept::Unknown, LossClass::Dropped, ""}, // asset.sealed-hash
242 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "the writer does not emit embedded media bytes, so an embedded asset is omitted"}, // asset.embedded-media
243 {ExportLevel::Full, Concept::Unknown, LossClass::Dropped, ""}, // asset.referenced-media
244 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "only the root sequence is written; other sequences are dropped"}, // sequence.multiple
245 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "DAWproject declares no support for sequence.nested"}, // sequence.nested
246 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "the writer cannot preserve registered extension payloads, so the clip content is omitted"}, // content.registered
247 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "the writer cannot preserve opaque extension payloads, so the clip content is omitted"}, // content.opaque
248 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "DAWproject declares no support for edit-rate.non-audio"}, // edit-rate.non-audio
249 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "DAWproject declares no support for context.chord-scale"}, // context.chord-scale
250 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "DAWproject declares no support for context.groove"}, // context.groove
251 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "DAWproject notes carry no probability, pass condition, or ratchet; the notes are written and play unconditionally once"}, // clip.note-modifier
253 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "the writer emits only its first constant tempo, so continuous tempo curves are dropped with the rest of the tempo map"}, // tempo.ramp
254 {ExportLevel::Full, Concept::Unknown, LossClass::Dropped, ""}, // clip.note-velocity-quantized
255 {ExportLevel::Full, Concept::Unknown, LossClass::Dropped, ""}, // tempo.value-quantized
256 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "the writer references the complete media asset, so a nonzero source start or partial frame count is dropped"}, // clip.media-window
257 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "the writer emits no fade at all, so a non-linear fade curve goes with the fade it shaped"}, // clip.fade-shape
258 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "the writer emits clip notes without their controller streams, so authored control change, pitch bend, pressure, program change, and parameter movement are omitted"}, // clip.midi-expression-lane
259 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "DAWproject arrangement markers carry a name and span but no typed structural role"}, // sequence.section-role
260 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "the DAWproject chord representation carries quality and root but no bass"}, // context.chord-bass
261 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "the DAWproject chord representation carries no added scale degrees"}, // context.chord-extension
262 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "the DAWproject chord representation carries no voicing hint"}, // context.chord-voicing
263 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "DAWproject has no document-wide tuning statement"}, // tuning.project
264 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "DAWproject has no per-instrument tuning statement"}, // tuning.instrument
265 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "DAWproject declares no support for modulation.modulator"}, // modulation.modulator
266 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "DAWproject declares no support for modulation.macro"}, // modulation.macro
267 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "DAWproject declares no support for modulation.route-device-param"}, // modulation.route-device-param
268 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "DAWproject declares no support for modulation.route-track-mixer"}, // modulation.route-track-mixer
269 },
270 // smf
271 {
272 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "Standard MIDI File declares no support for unknown"}, // unknown
274 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "Standard MIDI File declares no support for track.group"}, // track.group
275 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "Standard MIDI File declares no support for track.video"}, // track.video
277 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "sample-anchored clips cannot be placed on the Standard MIDI File tick grid, so the clip and its content are omitted"}, // clip.absolute
279 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "Standard MIDI Files carry MIDI events rather than audio media, so media clips are omitted"}, // clip.media
280 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "Standard MIDI Files have no per-clip gain, so authored clip gain is omitted"}, // clip.gain
281 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "Standard MIDI Files have no per-clip fades, so authored fade-in and fade-out durations are omitted"}, // clip.fades
282 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "Standard MIDI File declares no support for clip.crossfade"}, // clip.crossfade
283 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "Standard MIDI File declares no support for clip.warp"}, // clip.warp
284 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "Standard MIDI Files describe a linear arrangement, so launcher scenes are omitted"}, // clip.launch
285 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "Standard MIDI File declares no support for gap.explicit"}, // gap.explicit
290 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "the bounded writer does not emit marker meta-events, so markers and regions are omitted"}, // marker
291 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "the bounded writer does not emit a session timecode origin, so the document opens at zero"}, // timecode.origin
292 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "Standard MIDI File declares no support for media.provenance"}, // media.provenance
293 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "the bounded writer does not lower authored track gain to MIDI controller events"}, // mixer.track-gain
294 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "the bounded writer does not lower authored track pan to MIDI controller events"}, // mixer.track-pan
295 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "Standard MIDI File declares no support for mixer.sends"}, // mixer.sends
296 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "the bounded writer does not lower device automation to MIDI controller events"}, // automation.device-param
297 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "the bounded writer does not lower track-gain automation to MIDI controller events"}, // automation.track-gain
298 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "the bounded writer does not lower track-pan automation to MIDI controller events"}, // automation.track-pan
299 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "device chains have no Standard MIDI File representation and are omitted"}, // device.placement
300 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "Standard MIDI File declares no support for device.payload"}, // device.payload
301 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "Standard MIDI File declares no support for effect.timewarp"}, // effect.timewarp
302 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "takes and comp lanes have no Standard MIDI File representation and are omitted"}, // take.lane
303 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "take comp selections have no Standard MIDI File representation and are omitted"}, // take.comp
304 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "frozen audio renders have no Standard MIDI File representation and are omitted"}, // track.freeze
305 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "Standard MIDI Files do not carry Pulp media identity hashes"}, // asset.sealed-hash
306 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "Standard MIDI Files do not embed authored media assets"}, // asset.embedded-media
307 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "Standard MIDI Files do not retain external media locators"}, // asset.referenced-media
308 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "only the root sequence is written; other sequences are omitted"}, // sequence.multiple
309 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "nested sequence placements have no Standard MIDI File representation and are omitted"}, // sequence.nested
310 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "registered extension clip content has no Standard MIDI File representation and is omitted"}, // content.registered
311 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "opaque extension clip content has no Standard MIDI File representation and is omitted"}, // content.opaque
312 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "Standard MIDI File declares no support for edit-rate.non-audio"}, // edit-rate.non-audio
313 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "the bounded writer does not emit chord or scale context"}, // context.chord-scale
314 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "the bounded writer does not apply or serialize authored groove context"}, // context.groove
315 {ExportLevel::Degrade, Concept::ClipNote, LossClass::Degraded, "Standard MIDI notes carry no probability, pass condition, or ratchet, so the notes play unconditionally once"}, // clip.note-modifier
316 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "Standard MIDI Files have no positioned empty-clip object, so the clip is omitted"}, // clip.empty
317 {ExportLevel::Degrade, Concept::TempoMap, LossClass::Approximated, "continuous tempo curves become discrete Set Tempo steps at the authored tempo points"}, // tempo.ramp
318 {ExportLevel::Degrade, Concept::ClipNote, LossClass::Approximated, "16-bit note velocities are quantized to the nearest nonzero 7-bit Standard MIDI velocity"}, // clip.note-velocity-quantized
319 {ExportLevel::Degrade, Concept::TempoMap, LossClass::Approximated, "tempo values are rounded to the nearest representable integer microseconds per quarter note"}, // tempo.value-quantized
320 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "Standard MIDI File declares no support for clip.media-window"}, // clip.media-window
321 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "Standard MIDI Files have no per-clip fades, so a non-linear fade curve is omitted with the fade it shaped"}, // clip.fade-shape
322 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "Pulp's Standard MIDI File writer emits note, tempo, and meter events only, so an authored controller stream is omitted and the file plays with every controller left wherever the receiving instrument already had it"}, // clip.midi-expression-lane
323 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "the bounded writer emits a region's name and span but not the part it names"}, // sequence.section-role
324 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "the bounded writer does not emit chord or scale context"}, // context.chord-bass
325 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "the bounded writer does not emit chord or scale context"}, // context.chord-extension
326 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "the bounded writer does not emit chord or scale context"}, // context.chord-voicing
327 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "Standard MIDI Files have no document-wide tuning statement"}, // tuning.project
328 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "Standard MIDI Files have no per-instrument tuning statement"}, // tuning.instrument
329 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "Standard MIDI File declares no support for modulation.modulator"}, // modulation.modulator
330 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "Standard MIDI File declares no support for modulation.macro"}, // modulation.macro
331 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "Standard MIDI File declares no support for modulation.route-device-param"}, // modulation.route-device-param
332 {ExportLevel::Drop, Concept::Unknown, LossClass::Dropped, "Standard MIDI File declares no support for modulation.route-track-mixer"}, // modulation.route-track-mixer
333 },
334};
335} // namespace detail
336
338constexpr std::string_view format_id(Format format) noexcept {
339 return detail::kFormatRecords[static_cast<std::size_t>(format)].id;
340}
341
343constexpr std::string_view format_display_name(Format format) noexcept {
344 return detail::kFormatRecords[static_cast<std::size_t>(format)].display_name;
345}
346
348constexpr bool format_has_writer(Format format) noexcept {
349 return detail::kFormatRecords[static_cast<std::size_t>(format)].has_writer;
350}
351
353constexpr bool format_from_id(std::string_view id, Format& out) noexcept {
354 for (std::size_t index = 0; index < kFormatCount; ++index) {
355 if (detail::kFormatRecords[index].id == id) {
356 out = static_cast<Format>(index);
357 return true;
358 }
359 }
360 return false;
361}
362
366 Concept concept_value) noexcept {
367 return detail::kImportRows[static_cast<std::size_t>(format)]
368 [static_cast<std::size_t>(concept_value)];
369}
370
374 Concept concept_value) noexcept {
375 return detail::kExportRows[static_cast<std::size_t>(format)]
376 [static_cast<std::size_t>(concept_value)];
377}
378
381constexpr bool import_supports(Format format, Concept concept_value) noexcept {
382 return import_capability(format, concept_value).level != ImportLevel::None;
383}
384
386constexpr bool export_is_lossless(Format format, Concept concept_value) noexcept {
387 const ExportLevel level = export_capability(format, concept_value).level;
388 return level == ExportLevel::Full || level == ExportLevel::RoundtripOnly;
389}
390
391static_assert(static_cast<std::size_t>(Concept::Unknown) == 0,
392 "Concept::Unknown must be the zero value so a reader that cannot"
393 " classify a construct refuses by default");
394
395} // namespace pulp::interchange
What the product grants a device: the quota table indexed by capability tier and live thermal state.
Definition aax_editor.hpp:31
Definition capability_tables.hpp:62
constexpr ImportRow kImportRows[kFormatCount][kConceptCount]
Definition capability_tables.hpp:74
constexpr FormatRecord kFormatRecords[kFormatCount]
Definition capability_tables.hpp:69
constexpr ExportRow kExportRows[kFormatCount][kConceptCount]
Definition capability_tables.hpp:205
Definition census.hpp:13
Concept
The format-neutral interchange concept vocabulary.
Definition concepts.hpp:13
@ ClipNote
Definition concepts.hpp:20
@ Unknown
Definition concepts.hpp:14
@ TempoMap
Definition concepts.hpp:29
ExportLevel
What a format's writer does with a concept the document uses.
Definition capability_tables.hpp:22
@ Degrade
Definition capability_tables.hpp:25
@ Drop
Definition capability_tables.hpp:23
@ RoundtripOnly
Definition capability_tables.hpp:24
@ Full
Definition capability_tables.hpp:26
constexpr const ExportRow & export_capability(Format format, Concept concept_value) noexcept
The format's export declaration for one concept, generated the same way (omitted concepts become Drop...
Definition capability_tables.hpp:373
constexpr std::size_t kFormatCount
Definition capability_tables.hpp:43
constexpr bool import_supports(Format format, Concept concept_value) noexcept
Whether the format's reader may admit the concept at all.
Definition capability_tables.hpp:381
constexpr const ImportRow & import_capability(Format format, Concept concept_value) noexcept
The format's import declaration for one concept.
Definition capability_tables.hpp:365
constexpr bool format_has_writer(Format format) noexcept
Whether a writer exists for this format. run_export refuses without one.
Definition capability_tables.hpp:348
Format
Interchange formats with a committed capability declaration.
Definition capability_tables.hpp:38
@ Smf
Definition capability_tables.hpp:40
@ DawProject
Definition capability_tables.hpp:39
constexpr std::size_t kConceptCount
Definition concepts.hpp:77
ImportLevel
How much of a concept a format's reader admits.
Definition capability_tables.hpp:14
@ Partial
Definition capability_tables.hpp:17
@ None
Definition capability_tables.hpp:15
@ Full
Definition capability_tables.hpp:18
@ PreserveOpaque
Definition capability_tables.hpp:16
constexpr bool export_is_lossless(Format format, Concept concept_value) noexcept
Whether exporting the concept costs the document anything.
Definition capability_tables.hpp:386
LossClass
How a concept is lost when a format cannot carry it intact.
Definition capability_tables.hpp:30
@ Flattened
Definition capability_tables.hpp:33
@ Approximated
Definition capability_tables.hpp:34
@ Dropped
Definition capability_tables.hpp:31
@ Degraded
Definition capability_tables.hpp:32
constexpr bool format_from_id(std::string_view id, Format &out) noexcept
Resolve a string id to its format. Returns false when unrecognized.
Definition capability_tables.hpp:353
constexpr std::string_view format_display_name(Format format) noexcept
The format's human-facing name.
Definition capability_tables.hpp:343
constexpr std::string_view format_id(Format format) noexcept
The format's stable string id.
Definition capability_tables.hpp:338
Definition capability_tables.hpp:53
LossClass loss_class
Definition capability_tables.hpp:57
Concept degrade_to
The concept a degrade lands on. Meaningful only for Degrade.
Definition capability_tables.hpp:56
ExportLevel level
Definition capability_tables.hpp:54
std::string_view loss
What the loss manifest reports. Empty when nothing is lost.
Definition capability_tables.hpp:59
Definition capability_tables.hpp:45
std::string_view notes
How the reader converts a partial or opaque concept.
Definition capability_tables.hpp:48
std::string_view refusal
What the refusal message names. Empty unless level is None.
Definition capability_tables.hpp:50
ImportLevel level
Definition capability_tables.hpp:46
Definition capability_tables.hpp:63
bool has_writer
Definition capability_tables.hpp:66
std::string_view display_name
Definition capability_tables.hpp:65
std::string_view id
Definition capability_tables.hpp:64