1 /*-
2 * Copyright (c) 2009-2021 Hans Petter Selasky. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 * SUCH DAMAGE.
24 */
25
26 #ifndef _MIDIPP_H_
27 #define _MIDIPP_H_
28
29 #include <stdint.h>
30 #include <sys/param.h>
31
32 #include <err.h>
33
34 #include <QApplication>
35 #include <QDialog>
36 #include <QPushButton>
37 #include <QGridLayout>
38 #include <QTextEdit>
39 #include <QScrollBar>
40 #include <QPlainTextEdit>
41 #include <QTabBar>
42 #include <QStackedWidget>
43 #include <QLabel>
44 #include <QSpinBox>
45 #include <QTextCursor>
46 #include <QTimer>
47 #include <QKeyEvent>
48 #include <QWheelEvent>
49 #include <QFile>
50 #include <QFileDialog>
51 #include <QLineEdit>
52 #include <QSpacerItem>
53 #include <QLCDNumber>
54 #include <QPicture>
55 #include <QColor>
56 #include <QPaintEvent>
57 #include <QPainter>
58 #include <QFont>
59 #ifdef HAVE_PRINTER
60 #include <QPrintDialog>
61 #include <QPrinter>
62 #endif
63 #include <QFontDialog>
64 #include <QFontInfo>
65 #include <QFileInfo>
66 #include <QMouseEvent>
67 #include <QSizePolicy>
68 #include <QListWidget>
69 #include <QIcon>
70 #include <QCloseEvent>
71 #include <QMenu>
72 #include <QMessageBox>
73 #include <QDir>
74 #include <QGroupBox>
75 #include <QSettings>
76 #include <QStyle>
77 #include <QSlider>
78 #include <QtNetwork>
79 #include <QUrl>
80 #include <QWheelEvent>
81 #include <QColorDialog>
82 #include <QPoint>
83 #include <QSplitter>
84 #include <QThread>
85 #include <QRegExp>
86 #include <QByteArray>
87 #include <QChar>
88 #include <QString>
89 #include <QClipboard>
90 #include <QXmlStreamReader>
91
92 #include <umidi20.h>
93
94 #ifdef __APPLE__
95 #include "TargetConditionals.h"
96 #endif
97
98 #define MPP_MAX_KEYS (128 * 128 * 128 * 128) /* maximum number of keys */
99 #define MPP_MAX_BANDS (12 * 128 * 128 * 128) /* number of divisions per octave */
100 #define MPP_MAX_CHORD_BANDS 192
101 #define MPP_MAX_CHORD_MAP (3 * 12 + 2)
102 #define MPP_MAX_CHORD_FUTURE 12
103 #define MPP_MAX_BUTTON_MAP 16
104 #define MPP_MAX_VIEWS 2
105 #define MPP_MAX_TRACKS (MPP_TRACKS_PER_VIEW * MPP_MAX_VIEWS)
106 #define MPP_MAX_LINES 8192
107 #define MPP_MAX_SCORES 32
108 #define MPP_MAX_LABELS 32
109 #define MPP_MAX_DEVS 8
110 #define MPP_MAX_BPM 32
111 #define MPP_MAX_LBUTTON 16
112 #define MPP_MIN_POS 4 /* ticks */
113 #define MPP_WHEEL_STEP (8 * 15)
114 #define MPP_PRESSED_MAX 128
115 #define MPP_MAX_DURATION 255 /* inclusive */
116 #define MPP_MAGIC_DEVNO (UMIDI20_N_DEVICES - MPP_MAX_TRACKS)
117 #define MPP_DEFAULT_URL "http://home.selasky.org/midipp/database.tar.gz"
118 #define MPP_DEFAULT_HPSJAM "127.0.0.1:12345"
119 #define MPP_DEFAULT_CMD_KEY C3
120 #define MPP_DEFAULT_BASE_KEY ((MPP_C0 + 12 * 5) * MPP_BAND_STEP_12)
121 #define MPP_VISUAL_MARGIN 8
122 #define MPP_VISUAL_R_MAX 8
123 #define MPP_VISUAL_C_MAX 20
124 #define MPP_VOLUME_UNIT 127
125 #define MPP_VOLUME_MAX 511 /* inclusivly */
126 #define MPP_CUSTOM_MAX 10
127 #define MPP_LOOP_MAX 16
128 #define MPP_MAX_TABS 32
129 #define MPP_MAX_WIDGETS 32
130 #define MPP_PIANO_TAB_LABELS 10 /* hard coded */
131 #define MPP_POPUP_DELAY 2000 /* ms */
132
133 #define MPP_CHAN_NONE_MASK (1 << 1)
134 #define MPP_CHAN_ANY_MASK (1 << 2)
135 #define MPP_CHAN_MPE_MASK (1 << 3)
136 #define MPP_CHAN_NONE -1
137 #define MPP_CHAN_ANY -2
138 #define MPP_CHAN_MPE -3 /* multi polyphonic expression */
139 #define MPP_DEV_ALL 1
140 #define MPP_DEV_NONE 2
141
142 /* list of tracks supported */
143 #define MPP_DEFAULT_TRACK(n) ((n) * MPP_TRACKS_PER_VIEW + 0)
144 #define MPP_TREBLE_TRACK(n) ((n) * MPP_TRACKS_PER_VIEW + 1)
145 #define MPP_BASS_TRACK(n) ((n) * MPP_TRACKS_PER_VIEW + 2)
146
147 #define MPP_BLOCKED(obj, what) do { \
148 (obj)->blockSignals(1); \
149 (obj)->what; \
150 (obj)->blockSignals(0); \
151 } while (0)
152
153 #define MPP_TRACKS_PER_VIEW 3
154
155 #if (MPP_MAGIC_DEVNO < MPP_MAX_DEVS)
156 #error "UMIDI20_N_DEVICES is too small."
157 #endif
158
159 /* list of supported band steps */
160 #define MPP_BAND_STEP_12 (MPP_MAX_BANDS / 12)
161 #define MPP_BAND_STEP_24 (MPP_MAX_BANDS / 24)
162 #define MPP_BAND_STEP_48 (MPP_MAX_BANDS / 48)
163 #define MPP_BAND_STEP_96 (MPP_MAX_BANDS / 96)
164 #define MPP_BAND_STEP_192 (MPP_MAX_BANDS / 192)
165 #define MPP_BAND_STEP_CHORD (MPP_MAX_BANDS / MPP_MAX_CHORD_BANDS)
166
167 static inline int
MPP_BAND_REM(int x,int y)168 MPP_BAND_REM(int x, int y)
169 {
170 x = (MPP_MAX_BANDS + (x % MPP_MAX_BANDS)) % MPP_MAX_BANDS;
171 return (x / (MPP_MAX_BANDS / y));
172 }
173
174 static inline int
MPP_SUBDIV_REM_BITREV(int x)175 MPP_SUBDIV_REM_BITREV(int x)
176 {
177 int x_mask = MPP_BAND_STEP_12 / 2;
178 int r_mask = 1;
179 int retval = 0;
180
181 while (r_mask != MPP_BAND_STEP_12) {
182 if (x & x_mask)
183 retval |= r_mask;
184 r_mask <<= 1;
185 x_mask >>= 1;
186 }
187 return (retval);
188 }
189
190 static inline int
MPP_BAND_REM_TO_KEY(int x)191 MPP_BAND_REM_TO_KEY(int x)
192 {
193 int x_mask = 4 * MPP_BAND_STEP_12 / 2;
194 int r_mask = 1;
195 int retval = 0;
196
197 while (r_mask != (4 * MPP_BAND_STEP_12)) {
198 if (x & x_mask)
199 retval |= r_mask;
200 r_mask <<= 1;
201 x_mask >>= 1;
202 }
203
204 retval *= 3;
205
206 if (x & (4 * MPP_BAND_STEP_12))
207 retval += 1;
208 if (x & (8 * MPP_BAND_STEP_12))
209 retval += 2;
210
211 return (retval);
212 }
213
214 static inline int
MPP_KEY_TO_BAND_REM(int x)215 MPP_KEY_TO_BAND_REM(int x)
216 {
217 int x_mask = 4 * MPP_BAND_STEP_12 / 2;
218 int r_mask = 1;
219 int retval;
220
221 retval = (x % 3) * (MPP_MAX_BANDS / 3);
222
223 x /= 3;
224
225 while (r_mask != (4 * MPP_BAND_STEP_12)) {
226 if (x & x_mask)
227 retval += r_mask;
228 r_mask <<= 1;
229 x_mask >>= 1;
230 }
231 return (retval);
232 }
233
234 #define MPP_KEY_MIN (1 << 31)
235
236 /* list of basic 12-step score values */
237 #define MPP_C0 0
238 #define MPP_D0B 1
239 #define MPP_D0 2
240 #define MPP_E0B 3
241 #define MPP_E0 4
242 #define MPP_F0 5
243 #define MPP_G0B 6
244 #define MPP_G0 7
245 #define MPP_A0B 8
246 #define MPP_A0 9
247 #define MPP_H0B 10
248 #define MPP_H0 11
249
250 #define STRLCPY(a,b,c) do { \
251 strncpy(a,b,c); ((char *)(a))[(c)-1] = 0; \
252 } while (0)
253
254 class MppBpm;
255 class MppButton;
256 class MppButtonMap;
257 class MppChanSel;
258 class MppChanSelDiag;
259 class MppCheckBox;
260 class MppCustomTab;
261 class MppDataBase;
262 class MppDecodeTab;
263 class MppDevices;
264 class MppDevSel;
265 class MppDevSelDiag;
266 class MppElement;
267 class MppGPro;
268 class MppGridLayout;
269 class MppGroupBox;
270 class MppHead;
271 class MppImportTab;
272 class MppInstrumentTab;
273 class MppLoopTab;
274 class MppMainWindow;
275 class MppMidi;
276 class MppMetronome;
277 class MppMode;
278 class MppPianoTab;
279 class MppReplace;
280 class MppReplayTab;
281 class MppScoreHighLighter;
282 class MppScoreMain;
283 class MppScoreView;
284 class MppSettings;
285 class MppSettingsWhat;
286 class MppSheet;
287 class MppShortcutTab;
288 class MppShowControl;
289 class MppShowWidget;
290 class MppSpinBox;
291 class MppTabBar;
292 class MppVolume;
293
294 struct MppChord;
295 struct MppChordElement;
296
297 typedef struct MppChord MppChord_t;
298
299 class QPrinter;
300
301 struct MppScoreEntry {
302 int key;
303 int dur;
304 int8_t track;
305 int8_t trackSec;
306 int8_t channel;
307 int8_t channelSec;
308 };
309
310 struct MppInstr {
311 uint16_t bank;
312 uint8_t prog;
313 uint8_t muted;
314 uint8_t updated;
315 };
316
317 struct MppVisualDot {
318 qreal x_off;
319 qreal y_off;
320 };
321
322 struct MppVisualScore {
323 QPicture *pic;
324 QString *str;
325 QString *str_chord;
326 struct MppVisualDot *pdot;
327 MppElement *start;
328 MppElement *stop;
329 int newpage;
330 int ndot;
331 };
332
333 class Mpp {
334 public:
335 Mpp();
336 ~Mpp();
337
338 QColor ColorBlack;
339 QColor ColorWhite;
340 QColor ColorGrey;
341 QColor ColorLogo;
342 QColor ColorGreen;
343 QColor ColorLight;
344 QColor ColorYellow;
345
346 QString VariantList;
347 QString HomeDirTxt;
348 QString HomeDirMid;
349 QString HomeDirGp3;
350 QString HomeDirMXML;
351 QString HomeDirBackground;
352
353 int KeyAdjust[12];
354 };
355
356 class MppSleep : public QThread
357 {
358 public:
usleep(unsigned long usecs)359 static void usleep(unsigned long usecs) { QThread::usleep(usecs); }
msleep(unsigned long msecs)360 static void msleep(unsigned long msecs) { QThread::msleep(msecs); }
sleep(unsigned long secs)361 static void sleep(unsigned long secs) { QThread::sleep(secs); }
362 };
363
364 extern Mpp Mpp;
365
366 extern const QString MppChanName(int);
367 extern const QString MppDevName(int, int = 0);
368 extern QString MppBaseName(const QString &);
369 extern char *MppQStringToAscii(const QString &);
370 extern QString MppReadFile(const QString &);
371 extern void MppWriteFile(const QString &, QString text);
372 extern uint8_t MppReadRawFile(const QString &, QByteArray *pdata);
373 extern uint8_t MppWriteRawFile(const QString &, QByteArray *pdata);
374 extern const char *MppBaseKeyToString(int key, int sharp);
375 extern void MppScoreVariantInit(void);
376 extern uint8_t MppIsLabel(const QString &);
377 extern void MppSplitBaseTreble(const int *, uint8_t, int *, uint8_t *, int *, uint8_t *);
378 extern const QString MppChordModChars;
379 extern const QString MppVersion;
380 extern const QString MppIconFile;
381
382 typedef int (MppCmp_t)(void *, const void *, const void *);
383 extern void MppSort(void *, size_t, size_t, MppCmp_t *, void *);
384 extern void MppSort(int *, size_t);
385 extern void MppTrans(int *ptr, size_t num, int ntrans);
386
387 #ifdef HAVE_SCREENSHOT
388 extern void MppScreenShot(QWidget *, QApplication &);
389 #endif
390
391 #endif /* _MIDIPP_H_ */
392