denigma 4.0.0
Loading...
Searching...
No Matches
expressions.h
1/*
2 * Copyright (C) 2026, Robert Patterson
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 * THE SOFTWARE.
21 */
22#pragma once
23
24#include <cassert>
25#include <cstddef>
26#include <optional>
27#include <stdexcept>
28#include <string>
29#include <string_view>
30#include <variant>
31#include <vector>
32
33#include "denigma/classify/articulations.h"
34#include "denigma/classify/classifier_common.h"
35#include "denigma/classify/dynamics.h"
36#include "denigma/classify/keyboard_pedals.h"
37#include "musx/musx.h"
38
39namespace denigma {
40namespace classify {
41
43using ExpressionCategoryType = musx::dom::others::MarkingCategory::CategoryType;
44
68
78
85enum class ExpressionScope {
87 Staff,
88 TopStaff,
90};
91
94
95namespace expression {
96
100{
103 enum class Type {
104 None,
105 Arco,
106 Pizzicato,
107 ColLegno,
111 SulTasto,
112 Flautando,
113 Ordinario,
114 Mute,
116 CupMute,
117 HarmonMute,
119 BucketMute,
121 StopMute,
122 Stopped,
123 Open,
124 Other
125 };
126
130 std::string text;
131};
132
136{
138 std::string text;
143};
144
148{
151};
152
156{
160 musx::dom::NoteType noteType{musx::dom::NoteType::Quarter};
162 std::string noteGlyphName;
164 std::size_t augmentationDots{};
167};
168
176
180{
184 std::optional<std::string> glyphName;
189};
190
194{
198 std::optional<std::string> glyphName;
199};
200
228
232{
234 musx::util::ArpeggioSpanCandidate candidate;
235};
236
240{
242 std::string text;
243};
244
253{
255 int number{};
256};
257
266{
268 int count{};
269};
270
274{
276 std::string text;
277};
278
282{
284 dynamics::Change change{dynamics::Change::Absolute};
286 std::string text;
287};
288
291struct Error
292{
294 std::string message;
295};
296
300{};
301
303using RunValue = std::variant<std::monostate, dynamics::Mark, DynamicQualifier, Fermata, BreathMark, TempoText, TempoAlteration, TechniqueText,
305
309{
311 musx::util::EnigmaTextChunk chunk;
315 RunValue value{};
316
320 template <typename T>
321 const T* as() const noexcept
322 {
323 return std::get_if<T>(&value);
324 }
325};
326
327} // namespace expression
328
334
338{
346 std::optional<musx::util::EnigmaParsingContext> enigmaCtx;
350 std::vector<expression::RunClassification> runs;
351
355 template <typename T>
356 const T* as() const noexcept
357 {
358 return std::get_if<T>(&value);
359 }
360
361private:
362 template <typename T, ExpressionType EnumVal>
363 const T& checkedPayload(const char* enumDesc) const
364 {
365 assert(type == EnumVal);
366 if (type != EnumVal) {
367 throw std::logic_error(std::string("ExpressionClassification type is not ") + enumDesc + ".");
368 }
369 return std::get<T>(value);
370 }
371
372public:
375 const dynamics::Mark& dynamic() const { return checkedPayload<dynamics::Mark, ExpressionType::Dynamic>("Dynamic"); }
376
379 const expression::Fermata& fermata() const { return checkedPayload<expression::Fermata, ExpressionType::Fermata>("Fermata"); }
380
383 const expression::BreathMark& breathMark() const { return checkedPayload<expression::BreathMark, ExpressionType::BreathMark>("BreathMark"); }
384
387 const articulation::StringMute& stringMute() const { return checkedPayload<articulation::StringMute, ExpressionType::StringMute>("StringMute"); }
388
392 {
393 return checkedPayload<articulation::AccordionRegistration, ExpressionType::AccordionRegistration>("AccordionRegistration");
394 }
395
398 const expression::HarpDiagram& harpDiagram() const { return checkedPayload<expression::HarpDiagram, ExpressionType::HarpDiagram>("HarpDiagram"); }
399
402 keyboardpedal::Type keyboardPedal() const { return checkedPayload<keyboardpedal::Type, ExpressionType::KeyboardPedal>("KeyboardPedal"); }
403
406 const PseudoTie& pseudoTie() const { return checkedPayload<PseudoTie, ExpressionType::PseudoTie>("PseudoTie"); }
407
410 const expression::NonArpeggio& nonArpeggio() const { return checkedPayload<expression::NonArpeggio, ExpressionType::NonArpeggio>("NonArpeggio"); }
411
414 const expression::TempoText& tempoText() const { return checkedPayload<expression::TempoText, ExpressionType::TempoMark>("TempoText"); }
415
419 {
420 return checkedPayload<expression::MetronomeMark, ExpressionType::MetronomeMark>("MetronomeMark");
421 }
422
426 {
427 return checkedPayload<expression::TempoAlteration, ExpressionType::TempoAlteration>("TempoAlteration");
428 }
429
433 {
434 return checkedPayload<expression::TechniqueText, ExpressionType::TechniqueText>("TechniqueText");
435 }
436
440 {
441 return checkedPayload<expression::RehearsalMark, ExpressionType::RehearsalMark>("RehearsalMark");
442 }
443
447 {
448 return checkedPayload<expression::MultimeasureRestNumber, ExpressionType::MultimeasureRestNumber>("MultimeasureRestNumber");
449 }
450
454 {
455 return checkedPayload<expression::MeasureRepeatCount, ExpressionType::MeasureRepeatCount>("MeasureRepeatCount");
456 }
457
460 const expression::GenericText& genericText() const { return checkedPayload<expression::GenericText, ExpressionType::GenericText>("GenericText"); }
461
464 const expression::Error& error() const { return checkedPayload<expression::Error, ExpressionType::Error>("Error"); }
465};
466
470{
472 musx::dom::MusxInstance<musx::dom::others::MeasureExprAssign> assignment;
475};
476
487{
491 musx::dom::MusxInstance<musx::dom::others::MeasureExprAssign> primary;
493 std::vector<musx::dom::MusxInstance<musx::dom::others::MeasureExprAssign>> members;
496
498 [[nodiscard]] bool isStaffListGroup() const noexcept { return staffGroup != 0; }
499};
500
502ExpressionScope classifyExpressionScope(const musx::dom::MusxInstance<musx::dom::others::MeasureExprAssign>& assignment);
503
507ExpressionClassification classifyExpression(const musx::dom::MusxInstance<musx::dom::others::MeasureExprAssign>& assignment);
508
516std::vector<ExpressionAssignmentGroup> groupExpressionAssignments(
517 const musx::dom::MusxInstanceList<musx::dom::others::MeasureExprAssign>& assignments);
518
526std::vector<ExpressionAssignmentClassification> classifyExpressionAssignments(
527 const musx::dom::MusxInstanceList<musx::dom::others::MeasureExprAssign>& assignments);
528
533ExpressionClassification classifyExpression(const musx::dom::MusxInstance<musx::dom::others::TextExpressionDef>& def,
534 const musx::dom::MusxInstance<musx::dom::others::MeasureExprAssign>& assignment = {});
535
540ExpressionClassification classifyExpression(const musx::dom::MusxInstance<musx::dom::others::ShapeExpressionDef>& def,
541 const musx::dom::MusxInstance<musx::dom::others::MeasureExprAssign>& assignment = {});
542
543} // namespace classify
544} // namespace denigma
ExpressionScope classifyExpressionScope(const musx::dom::MusxInstance< musx::dom::others::MeasureExprAssign > &assignment)
Determines where a Finale measure-expression assignment draws its expression.
musx::dom::others::MarkingCategory::CategoryType ExpressionCategoryType
Finale marking-category type used while classifying expressions.
Definition expressions.h:43
std::vector< ExpressionAssignmentGroup > groupExpressionAssignments(const musx::dom::MusxInstanceList< musx::dom::others::MeasureExprAssign > &assignments)
Groups one measure's assignments by Finale staff group and classifies each group once.
std::variant< std::monostate, dynamics::Mark, expression::Fermata, expression::BreathMark, articulation::StringMute, articulation::AccordionRegistration, expression::HarpDiagram, keyboardpedal::Type, PseudoTie, expression::NonArpeggio, expression::TempoText, expression::MetronomeMark, expression::TempoAlteration, expression::TechniqueText, expression::RehearsalMark, expression::MultimeasureRestNumber, expression::MeasureRepeatCount, expression::GenericText, expression::Error, expression::Suppress > ExpressionValue
Semantic payload associated with an ExpressionClassification.
Definition expressions.h:333
bool isFloatingScope(ExpressionScope scope)
True for the scopes that float to a system edge rather than naming a staff.
std::vector< ExpressionAssignmentClassification > classifyExpressionAssignments(const musx::dom::MusxInstanceList< musx::dom::others::MeasureExprAssign > &assignments)
Classifies a list of Finale measure-expression assignments.
ClassificationBasis
Diagnostic reason for the selected expression classification.
Definition expressions.h:71
@ Heuristic
Classification was inferred without a usable Finale category.
@ FinaleCategory
Classification follows the assigned Finale category.
@ FallbackToGenericText
No specialized classification matched the expression.
@ FinaleCategoryConfirmed
Content analysis confirmed the assigned Finale category.
@ FinaleCategoryCorrected
Content analysis overrode the assigned Finale category.
ExpressionType
Exporter-neutral semantic classes for Finale/MUSX text expressions.
Definition expressions.h:47
@ RehearsalMark
A rehearsal mark.
@ BreathMark
A breath-mark symbol.
@ MetronomeMark
A standalone metronome-note equation.
@ TechniqueText
Text identifying a performance technique.
@ StringMute
A string-mute on/off symbol.
@ KeyboardPedal
A keyboard-pedal marking.
@ HarpDiagram
A harp-pedal diagram.
@ TempoAlteration
A relative tempo alteration.
@ Suppress
An expression that should not be exported.
@ Error
An expression that could not be classified because of invalid source data.
@ MeasureRepeatCount
A count of the iterations of a measure repeat.
@ NonArpeggio
A shape expression used as a non-arpeggio sign.
@ MultimeasureRestNumber
A numeric label for a multimeasure rest.
@ TempoMark
A tempo indication.
@ AccordionRegistration
An accordion-registration glyph or combining glyph sequence.
@ GenericText
Text with no more specific recognized semantic.
ExpressionClassification classifyExpression(const musx::dom::MusxInstance< musx::dom::others::MeasureExprAssign > &assignment)
Classifies the expression referenced by a Finale measure-expression assignment.
ExpressionScope
Where a Finale measure-expression assignment draws its expression.
Definition expressions.h:85
@ Unassigned
Classified from a definition alone; no assignment says where it is drawn.
@ Staff
Drawn on the one staff it is assigned to.
@ TopStaff
Floating assignment drawn on the top staff of every system.
@ BottomStaff
Floating assignment drawn on the bottom staff of every system.
Core public API for the Denigma conversion libraries.
Definition articulations.h:33
Classification paired with the Finale measure-expression assignment that produced it.
Definition expressions.h:470
musx::dom::MusxInstance< musx::dom::others::MeasureExprAssign > assignment
Source measure-expression assignment.
Definition expressions.h:472
ExpressionClassification classification
Semantic classification of the assigned expression.
Definition expressions.h:474
The assignments Finale created together from one staff list, or a lone assignment as a group of one.
Definition expressions.h:487
int staffGroup
Finale staff group shared by the members, or zero for a lone assignment.
Definition expressions.h:489
bool isStaffListGroup() const noexcept
True when the group came from a staff list rather than from a single assignment.
Definition expressions.h:498
std::vector< musx::dom::MusxInstance< musx::dom::others::MeasureExprAssign > > members
Every member shown in the requested score or part, primary first.
Definition expressions.h:493
musx::dom::MusxInstance< musx::dom::others::MeasureExprAssign > primary
The member that names the group: the lowest inci, or the floating top-staff member of an ungrouped se...
Definition expressions.h:491
ExpressionClassification classification
The group's classification. A floating top-staff member's classification wins.
Definition expressions.h:495
Exporter-neutral semantic classification of one Finale expression.
Definition expressions.h:338
std::vector< expression::RunClassification > runs
Per-run classifications for expressions containing mixed content.
Definition expressions.h:350
const articulation::AccordionRegistration & accordionRegistration() const
Returns the classified accordion-registration glyph sequence.
Definition expressions.h:391
const expression::GenericText & genericText() const
Returns the unclassified expression text.
Definition expressions.h:460
ClassificationBasis basis
Evidence used to select type and value.
Definition expressions.h:342
const PseudoTie & pseudoTie() const
Returns the classified pseudo-tie.
Definition expressions.h:406
const expression::BreathMark & breathMark() const
Returns the classified breath mark.
Definition expressions.h:383
const expression::RehearsalMark & rehearsalMark() const
Returns the classified rehearsal mark.
Definition expressions.h:439
ExpressionValue value
Semantic payload associated with type.
Definition expressions.h:348
std::optional< musx::util::EnigmaParsingContext > enigmaCtx
Parsing context retained when the source contains Enigma text commands.
Definition expressions.h:346
const expression::MetronomeMark & metronomeMark() const
Returns the classified standalone metronome marking.
Definition expressions.h:418
const expression::TechniqueText & techniqueText() const
Returns the classified performance-technique text.
Definition expressions.h:432
const expression::TempoAlteration & tempoAlteration() const
Returns the classified relative tempo alteration.
Definition expressions.h:425
const dynamics::Mark & dynamic() const
Returns the classified dynamic mark.
Definition expressions.h:375
const articulation::StringMute & stringMute() const
Returns the classified string-mute symbol.
Definition expressions.h:387
const expression::TempoText & tempoText() const
Returns the classified absolute tempo indication.
Definition expressions.h:414
keyboardpedal::Type keyboardPedal() const
Returns the classified keyboard-pedal marking.
Definition expressions.h:402
const expression::NonArpeggio & nonArpeggio() const
Returns the classified non-arpeggio sign.
Definition expressions.h:410
ExpressionType type
Top-level semantic class.
Definition expressions.h:340
const expression::HarpDiagram & harpDiagram() const
Returns the classified harp-pedal diagram.
Definition expressions.h:398
const expression::Error & error() const
Returns the classification diagnostic.
Definition expressions.h:464
ExpressionScope scope
Where the classified assignment draws the expression. Unassigned when no assignment was given.
Definition expressions.h:344
const expression::MeasureRepeatCount & measureRepeatCount() const
Returns the classified measure repeat count.
Definition expressions.h:453
const expression::Fermata & fermata() const
Returns the classified fermata.
Definition expressions.h:379
const expression::MultimeasureRestNumber & multimeasureRestNumber() const
Returns the classified multimeasure rest number.
Definition expressions.h:446
const T * as() const noexcept
Returns the payload as T when it contains that type.
Definition expressions.h:356
Visual style encoded by the source glyph variant.
Definition classifier_common.h:32
A source shape used as a stand-in for a laissez-vibrer tie or tie end.
Definition classifier_common.h:48
A precomposed SMuFL accordion-registration glyph found in Finale notation.
Definition articulations.h:168
Classification for breath marks.
Definition articulations.h:291
Classification for fermata articulation marks.
Definition articulations.h:256
Classification for a string mute on/off symbol.
Definition articulations.h:146
Dynamic metadata attached to a source text run.
Definition dynamics.h:145
Breath-mark expression and its resolved source glyph.
Definition expressions.h:194
articulation::BreathMark breathMark
Semantic breath-mark classification.
Definition expressions.h:196
std::optional< std::string > glyphName
SMuFL glyph name when the source glyph can be resolved.
Definition expressions.h:198
Text run that qualifies a neighboring dynamic mark.
Definition expressions.h:282
std::string text
Source display text.
Definition expressions.h:286
dynamics::Change change
Dynamic change indicated by the qualifier.
Definition expressions.h:284
Classification failure caused by invalid or unsupported source data.
Definition expressions.h:292
std::string message
Human-readable diagnostic.
Definition expressions.h:294
Fermata expression and its source-specific display properties.
Definition expressions.h:180
articulation::Fermata fermata
Semantic fermata classification.
Definition expressions.h:182
std::optional< std::string > glyphName
SMuFL glyph name when the source glyph can be resolved.
Definition expressions.h:184
bool isRightBarline
Whether the fermata is assigned to the right barline.
Definition expressions.h:188
GlyphStyle glyphStyle
Visual style encoded by the source glyph.
Definition expressions.h:186
Expression text without a more specific semantic classification.
Definition expressions.h:274
std::string text
Source display text.
Definition expressions.h:276
Seven-pedal state encoded by a Finale harp-pedal diagram.
Definition expressions.h:204
PedalPosition b
B-pedal position.
Definition expressions.h:218
PedalPosition c
C-pedal position.
Definition expressions.h:216
PedalPosition a
A-pedal position.
Definition expressions.h:226
PedalPosition d
D-pedal position.
Definition expressions.h:214
PedalPosition e
E-pedal position.
Definition expressions.h:220
PedalPosition
Notated position of one harp pedal.
Definition expressions.h:207
PedalPosition g
G-pedal position.
Definition expressions.h:224
PedalPosition f
F-pedal position.
Definition expressions.h:222
Classified count of the iterations of a measure repeat.
Definition expressions.h:266
int count
Iteration number displayed by the marking.
Definition expressions.h:268
A standalone metronome-note equation.
Definition expressions.h:156
std::string noteGlyphName
Canonical SMuFL name of the metronome-note glyph.
Definition expressions.h:162
std::size_t augmentationDots
Number of augmentation dots following the note.
Definition expressions.h:164
TempoInfo tempo
Source text and any independently configured Finale playback values.
Definition expressions.h:158
musx::dom::NoteType noteType
Undotted semantic value of the displayed metronome note.
Definition expressions.h:160
double displayedBeatsPerMinute
Number displayed to the right of the equals sign. It may have a fractional part.
Definition expressions.h:166
Classified numeric label for a multimeasure rest.
Definition expressions.h:253
int number
Measure count displayed by the marking.
Definition expressions.h:255
Shape expression recognized as a non-arpeggio sign.
Definition expressions.h:232
musx::util::ArpeggioSpanCandidate candidate
Source candidate describing the vertical arpeggio span.
Definition expressions.h:234
Classified rehearsal-mark text.
Definition expressions.h:240
std::string text
Display text of the rehearsal mark.
Definition expressions.h:242
Classification of one logical run within an expression.
Definition expressions.h:309
const T * as() const noexcept
Returns the payload as T when it contains that type.
Definition expressions.h:321
RunValue value
Semantic payload for this run.
Definition expressions.h:315
musx::util::EnigmaTextChunk chunk
Parsed Finale text chunk represented by this run.
Definition expressions.h:311
ClassificationBasis basis
Evidence used to select value.
Definition expressions.h:313
Marker payload for an expression that should not be exported.
Definition expressions.h:300
Classified text identifying a performance technique.
Definition expressions.h:100
Type type
Semantic technique identified by the classifier.
Definition expressions.h:128
std::string text
Source display text.
Definition expressions.h:130
Type
Common performance technique text values recognized by the classifier.
Definition expressions.h:103
@ ColLegno
Unqualified col legno technique.
@ ColLegnoTratto
Draw the wood of the bow across the string.
@ Other
A recognized technique not represented by another value.
@ ColLegnoBattuto
Strike the string with the wood of the bow.
@ Stopped
Use the stopped-horn technique.
@ Open
Return to an open or unmuted technique.
Classified relative tempo alteration.
Definition expressions.h:172
TempoInfo tempo
Tempo text and any associated playback values.
Definition expressions.h:174
Text and playback data associated with a tempo expression.
Definition expressions.h:136
std::string text
Source display text.
Definition expressions.h:138
int beatUnitEdu
Finale EDU duration of one playback beat, or zero when unspecified.
Definition expressions.h:142
int beatsPerMinute
Finale playback tempo in beats per minute, or zero when unspecified.
Definition expressions.h:140
Classified absolute tempo indication.
Definition expressions.h:148
TempoInfo tempo
Tempo text and playback values.
Definition expressions.h:150