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
65 RhythmicPosition, position,
66 (const FractionValue&, position));
67 MNX_OPTIONAL_PROPERTY(std::string, prefix);
69 MNX_OPTIONAL_PROPERTY(std::string, suffix);
70 MNX_OPTIONAL_PROPERTY(DynamicValue, value);
71 MNX_OPTIONAL_PROPERTY(std::string, visuallyContinues);
72 MNX_OPTIONAL_PROPERTY(std::string, voice);
73
76 virtual bool calcHasImmediateText() const
77 {
78 return value() || !prefix_or({}).empty() || !suffix_or({}).empty()
79 || (glyphs() && !glyphs().value().empty());
80 }
81};
82
88{
89public:
91 struct Required
92 {
93 DynamicValue value{};
95 };
96
98 DynamicAccent(const std::shared_ptr<json>& root, json_pointer pointer)
100 {}
101
107 DynamicAccent(Base& parent, std::string_view key, DynamicValue value, const FractionValue& position)
108 : DynamicGroupBase(parent, key, position)
109 {
110 set_value(value);
111 }
112
114 operator Required() const { return { value().value(), position().fraction() }; }
115
117 static Required make(DynamicValue value, const FractionValue& position) { return { value, position }; }
118
121 MNX_OPTIONAL_PROPERTY(DynamicValue, residualValue);
124
125 bool calcHasImmediateText() const override
126 {
128 || accentPrefix() != DynamicPrefix::None
129 || accentSuffix() != DynamicSuffix::None
130 || residualValue();
131 }
132
133 inline static constexpr std::string_view ContentTypeValue = "accent";
134};
135
141{
142public:
151
153 DynamicGradual(const std::shared_ptr<json>& root, json_pointer pointer)
155 {
156 }
157
164 DynamicGradual(Base& parent, std::string_view key, DynamicWedgeType wedgeType, const FractionValue& position,
165 const MeasureRhythmicPosition::Required& endPosition)
166 : DynamicGroupBase(parent, key, position)
167 {
168 create_end(endPosition.measureId, endPosition.position);
169 set_wedgeType(wedgeType);
170 }
171
173 operator Required() const
174 {
175 return { wedgeType(), position().fraction(), end().measure(), end().position().fraction() };
176 }
177
179 static Required make(DynamicWedgeType wedgeType, const FractionValue& position, const MeasureRhythmicPosition::Required& endPosition)
180 { return { wedgeType, position, endPosition.measureId, endPosition.position }; }
181
183 (const std::string&, measureId), (const FractionValue&, position));
184 MNX_OPTIONAL_PROPERTY(int, staffEnd);
186
187 inline static constexpr std::string_view ContentTypeValue = "gradual";
188};
189
195{
196public:
198 struct Required
199 {
200 DynamicValue value{};
202 };
203
205 DynamicImmediate(const std::shared_ptr<json>& root, json_pointer pointer)
207 {}
208
214 DynamicImmediate(Base& parent, std::string_view key, DynamicValue value, const FractionValue& position)
215 : DynamicGroupBase(parent, key, position)
216 {
217 set_value(value);
218 }
219
221 operator Required() const { return { value().value(), position().fraction() }; }
222
224 static Required make(DynamicValue value, const FractionValue& position) { return { value, position }; }
225
226 inline static constexpr std::string_view ContentTypeValue = "immediate";
227};
228
234{
235public:
242
244 DynamicRelative(const std::shared_ptr<json>& root, json_pointer pointer)
246 {}
247
253 DynamicRelative(Base& parent, std::string_view key, DynamicRelativeValue relativeValue, const FractionValue& position)
254 : DynamicGroupBase(parent, key, position)
255 {
256 set_relativeValue(relativeValue);
257 }
258
260 operator Required() const { return { relativeValue(), position().fraction() }; }
261
263 static Required make(DynamicRelativeValue relativeValue, const FractionValue& position) { return { relativeValue, position }; }
264
266
267 inline static constexpr std::string_view ContentTypeValue = "relative";
268};
269
270class DynamicGroupArray : public ContentArray<part::DynamicGroupBase>
271{
272public:
273 using ContentArray<part::DynamicGroupBase>::ContentArray;
274
275 part::DynamicAccent appendAccent(DynamicValue value, const FractionValue& position)
276 { return appendWithType<part::DynamicAccent>(value, position); }
277
278 part::DynamicGradual appendGradual(DynamicWedgeType wedgeType, const FractionValue& position,
279 const MeasureRhythmicPosition::Required& endPosition)
280 { return appendWithType<part::DynamicGradual>(wedgeType, position, endPosition); }
281
282 part::DynamicImmediate appendImmediate(DynamicValue value, const FractionValue& position)
283 { return appendWithType<part::DynamicImmediate>(value, position); }
284
285 part::DynamicRelative appendRelative(DynamicRelativeValue relativeValue, const FractionValue& position)
286 { return appendWithType<part::DynamicRelative>(relativeValue, position); }
287};
288
289} // namespace part
290} // 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:88
static Required make(DynamicValue value, const FractionValue &position)
Create a Required instance for DynamicAccent.
Definition Dynamics.h:117
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:107
MNX_OPTIONAL_PROPERTY_WITH_DEFAULT(DynamicSuffix, accentSuffix, DynamicSuffix::z)
defines suffix ("z" or "");
DynamicAccent(const std::shared_ptr< json > &root, json_pointer pointer)
Constructor for existing Space objects.
Definition Dynamics.h:98
static constexpr std::string_view ContentTypeValue
type value that identifies the type of dynamic
Definition Dynamics.h:133
MNX_OPTIONAL_PROPERTY_WITH_DEFAULT(DynamicPrefix, accentPrefix, DynamicPrefix::s)
defines prefix ("r", "s", or "");
MNX_OPTIONAL_PROPERTY(DynamicValue, residualValue)
bool calcHasImmediateText() const override
Calculates if this dynamic has immediate text. If this value returns false, then it should be a hairp...
Definition Dynamics.h:125
Gradual dynamics (hairpins)
Definition Dynamics.h:141
static constexpr std::string_view ContentTypeValue
type value that identifies the type of dynamic
Definition Dynamics.h:187
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:164
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:179
DynamicGradual(const std::shared_ptr< json > &root, json_pointer pointer)
Constructor for existing Space objects.
Definition Dynamics.h:153
MNX_REQUIRED_PROPERTY(DynamicWedgeType, wedgeType)
the type of hairpin dynamic
MNX_OPTIONAL_PROPERTY(int, staffEnd)
the staff (within the part) on which the hairpin ends
Definition Dynamics.h:271
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.
MNX_OPTIONAL_PROPERTY(std::string, prefix)
Text preceding the dynamics representation, e.g., "più".
MNX_OPTIONAL_PROPERTY(DynamicValue, value)
The value of the dynamic.
MNX_REQUIRED_CHILD(RhythmicPosition, position,(const FractionValue &, position))
The rhythmic position of the dynamic within the measure.
MNX_OPTIONAL_PROPERTY(std::string, visuallyContinues)
Points to the ID of the directly previous dynamic group.
MNX_OPTIONAL_PROPERTY(int, staff)
The staff (within the part) this dynamic applies to.
MNX_OPTIONAL_CHILD(Array< std::string >, glyphs)
virtual bool calcHasImmediateText() const
Calculates if this dynamic has immediate text. If this value returns false, then it should be a hairp...
Definition Dynamics.h:76
Immediate dynamics (e.g., ff, ppp)
Definition Dynamics.h:195
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:214
DynamicImmediate(const std::shared_ptr< json > &root, json_pointer pointer)
Constructor for existing Space objects.
Definition Dynamics.h:205
static Required make(DynamicValue value, const FractionValue &position)
Create a Required instance for DynamicImmediate.
Definition Dynamics.h:224
static constexpr std::string_view ContentTypeValue
type value that identifies the type of dynamic
Definition Dynamics.h:226
Relative dynamics (e.g., più f)
Definition Dynamics.h:234
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:253
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:263
DynamicRelative(const std::shared_ptr< json > &root, json_pointer pointer)
Constructor for existing Space objects.
Definition Dynamics.h:244
static constexpr std::string_view ContentTypeValue
type value that identifies the type of dynamic
Definition Dynamics.h:267
object model for MNX format
DynamicWedgeType
The types of dynamic wedges (hairpins)
Definition Enumerations.h:153
json::json_pointer json_pointer
JSON pointer class for MNX.
Definition BaseTypes.h:68
DynamicPrefix
Definition Enumerations.h:105
@ s
"s-" as in sforzando (sf)
@ None
empty string
DynamicSuffix
Definition Enumerations.h:122
@ None
empty string
@ z
"-zato" as in forzato (fz)
DynamicRelativeValue
The possible relative changes in dynamic value.
Definition Enumerations.h:114
MultiStaffOrientation
Specifies the vertical visual orientation of a symbol with respect to its part's staves.
Definition Enumerations.h:301
@ 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:92
FractionValue position
the position within the measure
Definition Dynamics.h:94
DynamicValue value
the value of the dynamic
Definition Dynamics.h:93
initializer class for DynamicGradual
Definition Dynamics.h:145
std::string endMeasureId
the end measure id
Definition Dynamics.h:148
FractionValue endPosition
the end position within the measure
Definition Dynamics.h:149
DynamicWedgeType wedgeType
the type of hairpin dynamic
Definition Dynamics.h:146
FractionValue position
the start position within the measure
Definition Dynamics.h:147
initializer class for DynamicImmediate
Definition Dynamics.h:199
DynamicValue value
the value of the dynamic
Definition Dynamics.h:200
FractionValue position
the position within the measure
Definition Dynamics.h:201
initializer class for DynamicRelative
Definition Dynamics.h:238
DynamicRelativeValue relativeValue
Whether the dynamic is relatively softer or louder.
Definition Dynamics.h:239
FractionValue position
the position within the measure
Definition Dynamics.h:240