1 //=============================================================================
2 //  MusE
3 //  Linux Music Editor
4 //
5 //   metronome_class.h
6 //  (C) Copyright 2019 Tim E. Real (terminator356 on sourceforge)
7 //
8 //  This program is free software; you can redistribute it and/or modify
9 //  it under the terms of the GNU General Public License
10 //  as published by the Free Software Foundation; version 2 of
11 //  the License, or (at your option) any later version.
12 //
13 //  This program is distributed in the hope that it will be useful,
14 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
15 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 //  GNU General Public License for more details.
17 //
18 //  You should have received a copy of the GNU General Public License
19 //  along with this program; if not, write to the Free Software
20 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 //=============================================================================
22 
23 #ifndef __METRONOME_CLASS_H__
24 #define __METRONOME_CLASS_H__
25 
26 #include <QString>
27 
28 #include <vector>
29 #include <map>
30 #include <cstdint>
31 
32 #include "xml.h"
33 
34 namespace MusECore {
35 
36 struct MetroAccent
37 {
38   public:
39     enum AccentType { NoAccent = 0x0, Accent1 = 0x1, Accent2 = 0x2, AllAccents = Accent1 | Accent2 };
40     typedef int AccentTypes_t;
41 
42     AccentTypes_t _accentType;
43 
44   public:
MetroAccentMetroAccent45     MetroAccent() : _accentType(NoAccent) { }
46 
47     // Returns true if the accents are the same in both structs.
48     bool operator==(const MetroAccent& other) const;
49     // Returns true if the accents are NOT the same in both structs.
50     bool operator!=(const MetroAccent& other) const;
51     // Returns true if the accents are 'off' (NoAccent).
52     bool isBlank(AccentTypes_t types = AllAccents) const;
53     // Blanks the given type of accent.
54     void blank(AccentTypes_t types);
55 };
56 
57 class MetroAccents : public std::vector<MetroAccent>
58 {
59   public:
60     // Returns true if all the accents are the same in both lists.
61     bool operator==(const MetroAccents& other) const;
62     // Returns true if all the accents are 'off'.
63     bool isBlank(MetroAccent::AccentTypes_t types = MetroAccent::AllAccents) const;
64     // Blanks all accents of a given type.
65     void blank(MetroAccent::AccentTypes_t types);
66 };
67 
68 class MetroAccentsStruct
69 {
70   private:
71     static std::uint64_t _idGen;
newId()72     std::uint64_t newId() { return _idGen++; }
73 
74     std::uint64_t _id;
75 
76   public:
77     enum MetroAccentsType { NoType = 0x0,
78       User = 0x1,
79       UserPreset = 0x2,
80       FactoryPreset = 0x4,
81       AllTypes = User | UserPreset | FactoryPreset
82     };
83     typedef int MetroAccentsTypes_t;
84 
85     MetroAccents _accents;
86     MetroAccentsType _type;
87 
id()88     std::uint64_t id() const { return _id; }
89 
90     // Returns true if all the accents are 'off'.
91     bool isBlank(MetroAccent::AccentTypes_t types = MetroAccent::AllAccents) const;
92     // Blanks all accents of a given type.
93     void blank(MetroAccent::AccentTypes_t types);
94 
95     // Assigns the members of the given MetroAccentsStruct to this one, EXCEPT for the ID.
96     // Returns this MetroAccentsStruct.
97     MetroAccentsStruct& assign(const MetroAccentsStruct&);
98     // Creates a copy of this MetroAccentsStruct but with a new ID.
99     MetroAccentsStruct copy() const;
100 
101     void read(MusECore::Xml&);
102     void write(int, MusECore::Xml&) const;
103 
MetroAccentsStruct(MetroAccentsType type)104     MetroAccentsStruct(MetroAccentsType type) : _id(newId()), _type(type) { }
105 };
106 
107 class MetroAccentsMap : public std::map<const int /*beats*/, MetroAccentsStruct, std::less<int> >
108 {
109   public:
110     // Returns beats.
111     int read(MusECore::Xml&);
112     void write(int, MusECore::Xml&) const;
113 };
114 
115 class MetroAccentsPresets : public std::vector<MetroAccentsStruct>
116 {
117   public:
118     //// Returns beats.
119     //int read(MusECore::Xml&);
120     void write(int, MusECore::Xml&, int beats, MetroAccentsStruct::MetroAccentsType type) const;
121 
122     iterator find(const MetroAccentsStruct&, const MetroAccentsStruct::MetroAccentsTypes_t& types);
123     const_iterator find(const MetroAccentsStruct&, const MetroAccentsStruct::MetroAccentsTypes_t& types) const;
124     iterator findId(std::uint64_t id);
125     const_iterator findId(std::uint64_t id) const;
126 };
127 
128 class MetroAccentsPresetsMap : public std::map<const int /*beats*/, MetroAccentsPresets, std::less<int> >
129 {
130   public:
131     void read(MusECore::Xml&);
132     void write(int, MusECore::Xml&, MetroAccentsStruct::MetroAccentsType type) const;
133     void writeMDF(const QString& filepath, MetroAccentsStruct::MetroAccentsType type) const;
134     // Fills the given accents map with the first items found in this presets map.
135     void defaultAccents(MetroAccentsMap* accents, MetroAccentsStruct::MetroAccentsType type) const;
136 };
137 
138 struct MetronomeSettings
139 {
140   enum ClickSamples {
141       origSamples = 0,
142       newSamples
143   };
144 
145   int preMeasures;
146   unsigned char measureClickNote;
147   unsigned char measureClickVelo;
148   unsigned char beatClickNote;
149   unsigned char beatClickVelo;
150   unsigned char accentClick1;
151   unsigned char accentClick1Velo;
152   unsigned char accentClick2;
153   unsigned char accentClick2Velo;
154 
155   unsigned char clickChan;
156   unsigned char clickPort;
157   bool precountEnableFlag;
158   bool precountFromMastertrackFlag;
159   int precountSigZ;
160   int precountSigN;
161   bool precountOnPlay;
162   bool precountMuteMetronome;
163   bool precountPrerecord;
164   bool precountPreroll;
165   bool midiClickFlag;
166   bool audioClickFlag;
167   float audioClickVolume;
168   float measClickVolume;
169   float beatClickVolume;
170   float accent1ClickVolume;
171   float accent2ClickVolume;
172   ClickSamples clickSamples;
173   QString measSample;
174   QString beatSample;
175   QString accent1Sample;
176   QString accent2Sample;
177 
178   MusECore::MetroAccentsPresetsMap metroAccentPresets;
179   // This is a pointer so that it can quickly swapped with a new map in real-time.
180   MusECore::MetroAccentsMap* metroAccentsMap;
181 
182   MetronomeSettings();
183   ~MetronomeSettings();
184 };
185 
186 extern void initMetronomePresets(const QString& dir, MetroAccentsPresetsMap* presetMap, bool debug = false);
187 
188 } // namespace MusECore
189 
190 #endif
191