Line data Source code
1 : /*
2 : * SPDX-License-Identifier: GPL-3.0-only
3 : * MuseScore-Studio-CLA-applies
4 : *
5 : * MuseScore Studio
6 : * Music Composition & Notation
7 : *
8 : * Copyright (C) 2021 MuseScore Limited and others
9 : *
10 : * This program is free software: you can redistribute it and/or modify
11 : * it under the terms of the GNU General Public License version 3 as
12 : * published by the Free Software Foundation.
13 : *
14 : * This program is distributed in the hope that it will be useful,
15 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : * GNU General Public License for more details.
18 : *
19 : * You should have received a copy of the GNU General Public License
20 : * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 : */
22 :
23 : #pragma once
24 :
25 : #include <map>
26 :
27 : #include "../types/fraction.h"
28 :
29 : namespace mu::engraving {
30 : class Harmony;
31 :
32 : //voicing modes to use
33 : enum class Voicing : signed char {
34 : INVALID = -1,
35 : AUTO = 0,
36 : ROOT_ONLY,
37 : CLOSE,
38 : DROP_2,
39 : SIX_NOTE,
40 : FOUR_NOTE,
41 : THREE_NOTE
42 : };
43 :
44 : //duration to realize notes for
45 : enum class HDuration : signed char {
46 : INVALID = -1,
47 : UNTIL_NEXT_CHORD_SYMBOL = 0, //lasts until the next chord symbol or end of the schore
48 : STOP_AT_MEASURE_END, //lasts until next chord symbol or measure end
49 : SEGMENT_DURATION //lasts for the duration of the segment
50 : };
51 :
52 : //-----------------------------------------
53 : // Realized Harmony
54 : /// holds information and functions
55 : /// to assist in the realization of chord
56 : /// symbols. This is what is used to
57 : /// allow for chord symbol playback
58 : //-----------------------------------------
59 : class RealizedHarmony
60 : {
61 : public:
62 : using PitchMap = std::multimap<int, int>; //map from pitch to tpc
63 :
64 1137 : RealizedHarmony()
65 1137 : : m_harmony(0), m_notes(PitchMap()), m_dirty(1) {}
66 1071 : RealizedHarmony(Harmony* h)
67 1071 : : m_harmony(h), m_notes(PitchMap()), m_dirty(1) {}
68 :
69 : void setVoicing(Voicing);
70 : void setDuration(HDuration);
71 : void setLiteral(bool);
72 168 : void setDirty(bool dirty) { cascadeDirty(dirty); } //set dirty flag and cascade
73 66 : void setHarmony(Harmony* h) { m_harmony = h; }
74 :
75 25 : Voicing voicing() const { return m_voicing; }
76 6 : HDuration duration() const { return m_duration; }
77 25 : bool literal() const { return m_literal; }
78 : Harmony* harmony() { return m_harmony; }
79 :
80 25 : bool valid() const { return !m_dirty && m_harmony; }
81 :
82 : const PitchMap& notes() const;
83 : const PitchMap generateNotes(int rootTpc, int bassTpc, bool literal, Voicing voicing, int transposeOffset) const;
84 :
85 : void update(int rootTpc, int bassTpc, int transposeOffset = 0); //updates the notes map
86 :
87 : Fraction getActualDuration(int utick, HDuration durationType = HDuration::INVALID) const;
88 :
89 : private:
90 : PitchMap getIntervals(int rootTpc, bool literal = true) const;
91 : PitchMap normalizeNoteMap(const PitchMap& intervals, int rootTpc, int rootPitch, size_t max = 128, bool enforceMaxAsGoal = false) const;
92 : void cascadeDirty(bool dirty);
93 :
94 : Harmony* m_harmony = nullptr;
95 :
96 : PitchMap m_notes;
97 :
98 : Voicing m_voicing = Voicing::AUTO;
99 : HDuration m_duration = HDuration::INVALID;
100 :
101 : //whether or not the current notes QMap is up to date
102 : bool m_dirty = false;
103 : bool m_literal = false; //use all notes when possible and do not add any notes
104 : };
105 : }
|