MNX Document Model
Loading...
Searching...
No Matches
Dynamics.h
1/*
2 * Copyright (C) 2025, 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 "BaseTypes.h"
25#include "ContentArray.h"
26
27namespace mnx {
28namespace part {
29
30class DynamicGroupArray;
31class DynamicAccent;
32class DynamicGradual;
33class DynamicImmediate;
34class DynamicRelative;
35
40class DynamicGroupBase : public ContentObject<DynamicGroupBase>
41{
42public:
43 std::string_view defaultType() const override { return ""; }
45 DynamicGroupBase(const std::shared_ptr<json>& root, json_pointer pointer)
47 {
48 }
49
55 DynamicGroupBase(Base& parent, std::string_view key, const FractionValue& position)
56 : ContentObject(parent, key)
57 {
58 create_position(position);
59 }
60
61 MNX_OPTIONAL_PROPERTY(DynamicValue, attackValue);
67 RhythmicPosition, position,
68 (const FractionValue&, position));
69 MNX_OPTIONAL_PROPERTY(std::string, prefix);
71 MNX_OPTIONAL_PROPERTY(std::string, suffix);
72 MNX_OPTIONAL_PROPERTY(DynamicValue, value);
73 MNX_OPTIONAL_PROPERTY(std::string, voice);
74
78 {
79 return value() || attackValue() || !prefix_or({}).empty() || !suffix_or({}).empty()
80 || (glyphs() && !glyphs().value().empty());
81 }
82};
83
89{
90public:
92 struct Required
93 {
94 DynamicValue value{};
96 };
97
99 DynamicAccent(const std::shared_ptr<json>& root, json_pointer pointer)
101 {}
102
108 DynamicAccent(Base& parent, std::string_view key, DynamicValue value, const FractionValue& position)
109 : DynamicGroupBase(parent, key, position)
110 {
111 set_value(value);
112 }
113
115 operator Required() const { return { value().value(), position().fraction() }; }
116
118 static Required make(DynamicValue value, const FractionValue& position) { return { value, position }; }
119
120 inline static constexpr std::string_view ContentTypeValue = "accent";
121};
122
128{
129public:
138
140 DynamicGradual(const std::shared_ptr<json>& root, json_pointer pointer)
142 {
143 }
144
151 DynamicGradual(Base& parent, std::string_view key, DynamicWedgeType wedgeType, const FractionValue& position,
152 const MeasureRhythmicPosition::Required& endPosition)
153 : DynamicGroupBase(parent, key, position)
154 {
155 create_end(endPosition.measureId, endPosition.position);
156 set_wedgeType(wedgeType);
157 }
158
160 operator Required() const
161 {
162 return { wedgeType(), position().fraction(), end().measure(), end().position().fraction() };
163 }
164
166 static Required make(DynamicWedgeType wedgeType, const FractionValue& position, const MeasureRhythmicPosition::Required& endPosition)
167 { return { wedgeType, position, endPosition.measureId, endPosition.position }; }
168
170 (const std::string&, measureId), (const FractionValue&, position));
172
173 inline static constexpr std::string_view ContentTypeValue = "gradual";
174};
175
181{
182public:
184 struct Required
185 {
186 DynamicValue value{};
188 };
189
191 DynamicImmediate(const std::shared_ptr<json>& root, json_pointer pointer)
193 {}
194
200 DynamicImmediate(Base& parent, std::string_view key, DynamicValue value, const FractionValue& position)
201 : DynamicGroupBase(parent, key, position)
202 {
203 set_value(value);
204 }
205
207 operator Required() const { return { value().value(), position().fraction() }; }
208
210 static Required make(DynamicValue value, const FractionValue& position) { return { value, position }; }
211
212 inline static constexpr std::string_view ContentTypeValue = "immediate";
213};
214
220{
221public:
228
230 DynamicRelative(const std::shared_ptr<json>& root, json_pointer pointer)
232 {}
233
239 DynamicRelative(Base& parent, std::string_view key, DynamicRelativeValue relativeValue, const FractionValue& position)
240 : DynamicGroupBase(parent, key, position)
241 {
242 set_relativeValue(relativeValue);
243 }
244
246 operator Required() const { return { relativeValue(), position().fraction() }; }
247
249 static Required make(DynamicRelativeValue relativeValue, const FractionValue& position) { return { relativeValue, position }; }
250
252
253 inline static constexpr std::string_view ContentTypeValue = "relative";
254};
255
256class DynamicGroupArray : public ContentArray<part::DynamicGroupBase>
257{
258public:
259 using ContentArray<part::DynamicGroupBase>::ContentArray;
260
261 part::DynamicAccent appendAccent(DynamicValue value, const FractionValue& position)
262 { return appendWithType<part::DynamicAccent>(value, position); }
263
264 part::DynamicGradual appendGradual(DynamicWedgeType wedgeType, const FractionValue& position,
265 const MeasureRhythmicPosition::Required& endPosition)
266 { return appendWithType<part::DynamicGradual>(wedgeType, position, endPosition); }
267
268 part::DynamicImmediate appendImmediate(DynamicValue value, const FractionValue& position)
269 { return appendWithType<part::DynamicImmediate>(value, position); }
270
271 part::DynamicRelative appendRelative(DynamicRelativeValue relativeValue, const FractionValue& position)
272 { return appendWithType<part::DynamicRelative>(relativeValue, position); }
273};
274
275} // namespace part
276} // namespace mnx
Represents an MNX array, encapsulating property access.
Definition BaseTypes.h:531
Base class wrapper for all MNX JSON nodes.
Definition BaseTypes.h:212
json_pointer pointer() const
Returns the json_pointer for this node.
Definition BaseTypes.h:274
T parent() const
Returns the parent object for this node.
Definition BaseTypes.h:260
bool empty() const
Returns true if the object is empty.
Definition BaseTypes.h:280
const std::shared_ptr< json > & root() const
Returns the root.
Definition BaseTypes.h:297
Class for content arrays.
Definition ContentArray.h:49
Base class for objects that are elements of content arrays.
Definition BaseTypes.h:742
Represents a system on a page in a score.
Definition CommonClasses.h:550
Represents a system on a page in a score.
Definition CommonClasses.h:489
Immediate dynamics (e.g., ff, ppp)
Definition Dynamics.h:89
static Required make(DynamicValue value, const FractionValue &position)
Create a Required instance for DynamicAccent.
Definition Dynamics.h:118
DynamicAccent(Base &parent, std::string_view key, DynamicValue value, const FractionValue &position)
Creates a new Space class as a child of a JSON element.
Definition Dynamics.h:108
DynamicAccent(const std::shared_ptr< json > &root, json_pointer pointer)
Constructor for existing Space objects.
Definition Dynamics.h:99
static constexpr std::string_view ContentTypeValue
type value that identifies the type of dynamic
Definition Dynamics.h:120
Gradual dynamics (hairpins)
Definition Dynamics.h:128
static constexpr std::string_view ContentTypeValue
type value that identifies the type of dynamic
Definition Dynamics.h:173
DynamicGradual(Base &parent, std::string_view key, DynamicWedgeType wedgeType, const FractionValue &position, const MeasureRhythmicPosition::Required &endPosition)
Creates a new Space class as a child of a JSON element.
Definition Dynamics.h:151
MNX_REQUIRED_CHILD(MeasureRhythmicPosition, end,(const std::string &, measureId),(const FractionValue &, position))
the end position of the hairpin dynamic; set graceIndex to 0 to include preceding grace notes at the ...
static Required make(DynamicWedgeType wedgeType, const FractionValue &position, const MeasureRhythmicPosition::Required &endPosition)
Create a Required instance for DynamicGradual.
Definition Dynamics.h:166
DynamicGradual(const std::shared_ptr< json > &root, json_pointer pointer)
Constructor for existing Space objects.
Definition Dynamics.h:140
MNX_REQUIRED_PROPERTY(DynamicWedgeType, wedgeType)
the type of hairpin dynamic
Definition Dynamics.h:257
Base class for dynamics.
Definition Dynamics.h:41
DynamicGroupBase(Base &parent, std::string_view key, const FractionValue &position)
Creates a new Space class as a child of a JSON element.
Definition Dynamics.h:55
MNX_OPTIONAL_PROPERTY_WITH_DEFAULT(MultiStaffOrientation, orient, MultiStaffOrientation::Auto)
positioning of the dynamic relative to its part staves
DynamicGroupBase(const std::shared_ptr< json > &root, json_pointer pointer)
Constructor for existing Space objects.
Definition Dynamics.h:45
MNX_OPTIONAL_PROPERTY(std::string, suffix)
Text following the dynamics representation, e.g., "subito".
MNX_OPTIONAL_PROPERTY(std::string, voice)
Optionally specify the voice this dynamic applies to.
bool calcHasImmediateText() const
Calculates if this dynamic has immediate text. If this value returns false, then it should be a hairp...
Definition Dynamics.h:77
MNX_OPTIONAL_PROPERTY(std::string, prefix)
Text preceding the dynamics representation, e.g., "più".
MNX_OPTIONAL_PROPERTY(DynamicValue, attackValue)
MNX_OPTIONAL_PROPERTY(DynamicValue, value)
The value of the dynamic. Currently the MNX spec allows any string here.
MNX_REQUIRED_CHILD(RhythmicPosition, position,(const FractionValue &, position))
The rhythmic position of the dynamic within the measure.
MNX_OPTIONAL_PROPERTY(int, staff)
The staff (within the part) this dynamic applies to.
MNX_OPTIONAL_CHILD(Array< std::string >, glyphs)
Immediate dynamics (e.g., ff, ppp)
Definition Dynamics.h:181
DynamicImmediate(Base &parent, std::string_view key, DynamicValue value, const FractionValue &position)
Creates a new Space class as a child of a JSON element.
Definition Dynamics.h:200
DynamicImmediate(const std::shared_ptr< json > &root, json_pointer pointer)
Constructor for existing Space objects.
Definition Dynamics.h:191
static Required make(DynamicValue value, const FractionValue &position)
Create a Required instance for DynamicImmediate.
Definition Dynamics.h:210
static constexpr std::string_view ContentTypeValue
type value that identifies the type of dynamic
Definition Dynamics.h:212
Relative dynamics (e.g., più f)
Definition Dynamics.h:220
DynamicRelative(Base &parent, std::string_view key, DynamicRelativeValue relativeValue, const FractionValue &position)
Creates a new Space class as a child of a JSON element.
Definition Dynamics.h:239
MNX_REQUIRED_PROPERTY(DynamicRelativeValue, relativeValue)
Whether the dynamic is relatively softer or louder.
static Required make(DynamicRelativeValue relativeValue, const FractionValue &position)
Create a Required instance for DynamicRelative.
Definition Dynamics.h:249
DynamicRelative(const std::shared_ptr< json > &root, json_pointer pointer)
Constructor for existing Space objects.
Definition Dynamics.h:230
static constexpr std::string_view ContentTypeValue
type value that identifies the type of dynamic
Definition Dynamics.h:253
object model for MNX format
DynamicWedgeType
The types of dynamic wedges (hairpins)
Definition Enumerations.h:130
json::json_pointer json_pointer
JSON pointer class for MNX.
Definition BaseTypes.h:68
DynamicRelativeValue
The possible relative changes in dynamic value.
Definition Enumerations.h:105
MultiStaffOrientation
Specifies the vertical visual orientation of a symbol with respect to its part's staves.
Definition Enumerations.h:278
@ Auto
the default value determined by implementation
Represents a detached arithmetic fraction with normalization.
Definition CommonClasses.h:74
initializer class for MeasureRhythmicPosition
Definition CommonClasses.h:554
std::string measureId
the global measure id of the position
Definition CommonClasses.h:555
FractionValue position
the position within the measure
Definition CommonClasses.h:556
initializer class for DynamicAccent
Definition Dynamics.h:93
FractionValue position
the position within the measure
Definition Dynamics.h:95
DynamicValue value
the value of the dynamic
Definition Dynamics.h:94
initializer class for DynamicGradual
Definition Dynamics.h:132
std::string endMeasureId
the end measure id
Definition Dynamics.h:135
FractionValue endPosition
the end position within the measure
Definition Dynamics.h:136
DynamicWedgeType wedgeType
the type of hairpin dynamic
Definition Dynamics.h:133
FractionValue position
the start position within the measure
Definition Dynamics.h:134
initializer class for DynamicImmediate
Definition Dynamics.h:185
DynamicValue value
the value of the dynamic
Definition Dynamics.h:186
FractionValue position
the position within the measure
Definition Dynamics.h:187
initializer class for DynamicRelative
Definition Dynamics.h:224
DynamicRelativeValue relativeValue
Whether the dynamic is relatively softer or louder.
Definition Dynamics.h:225
FractionValue position
the position within the measure
Definition Dynamics.h:226