1 //=========================================================
2 // MusE
3 // Linux Music Editor
4 // $Id: globals.cpp,v 1.15.2.11 2009/11/25 09:09:43 terminator356 Exp $
5 //
6 // (C) Copyright 1999-2004 Werner Schweer (ws@seh.de)
7 //
8 // This program is free software; you can redistribute it and/or
9 // modify 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
24 #include <stdio.h>
25 #include <errno.h>
26 #include <unistd.h>
27 #include <stdlib.h>
28
29 #include <QActionGroup>
30 #include <QDir>
31 #include <QFileInfo>
32 #include <QToolButton>
33
34 #include "globals.h"
35 #include "config.h"
36
37 namespace MusEGlobal {
38
39 int sampleRate = 44100;
40 unsigned segmentSize = 1024U; // segmentSize in frames (set by JACK)
41 unsigned fifoLength = 128; // 131072/segmentSize
42 // 131072 - magic number that gives a sufficient buffer size
43 int segmentCount = 2;
44
45 // NOTE: For now, this is TEMPORARILY set to the project sample rate during song loading,
46 // then at the END of song loading is immediately set to the real current rate.
47 // See comments in Song::read() at the "samplerate" tag section.
48 int projectSampleRate = sampleRate;
49 const int numAudioSampleRates = 8;
50 const int selectableAudioSampleRates[] = {
51 22050, 32000, 44100, 48000, 64000, 88200, 96000, 192000
52 };
53
54 MusECore::SndFileList sndFiles;
55
56 MusECore::AudioConverterPluginList audioConverterPluginList;
57 // This global variable is a pointer so that we can replace it quickly with a new one in RT operations.
58 MusECore::AudioConverterSettingsGroup* defaultAudioConverterSettings = nullptr;
59
60 // denormal bias value used to eliminate the manifestation of denormals by
61 // lifting the zero level slightly above zero
62 // denormal problems occur when values get extremely close to zero
63 const float denormalBias=1e-18;
64
65 bool overrideAudioOutput = false;
66 bool overrideAudioInput = false;
67
68 const QString selectableAudioBackendDevices[] = {
69 "Jack Audio (default)",
70 "Midi only",
71 "RtAudio Pulse Audio",
72 "RtAudio ALSA",
73 "RtAudio OSS - Open Sound System",
74 "RtAudio best guess"
75 };
76
77 const int numRtAudioDevices = 6;
78
79 MusEGui::Rasterizer *globalRasterizer = nullptr;
80
81 QTimer* heartBeatTimer;
82
83 bool blinkTimerPhase = false;
84
85 bool hIsB = true; // call note h "b"
86
87 const signed char sharpTab[14][7] = {
88 { 0, 3, -1, 2, 5, 1, 4 },
89 { 0, 3, -1, 2, 5, 1, 4 },
90 { 0, 3, -1, 2, 5, 1, 4 },
91 { 0, 3, -1, 2, 5, 1, 4 },
92 { 2, 5, 1, 4, 7, 3, 6 },
93 { 2, 5, 1, 4, 7, 3, 6 },
94 { 2, 5, 1, 4, 7, 3, 6 },
95 { 4, 0, 3, -1, 2, 5, 1 },
96 { 7, 3, 6, 2, 5, 1, 4 },
97 { 5, 8, 4, 7, 3, 6, 2 },
98 { 3, 6, 2, 5, 1, 4, 7 },
99 { 1, 4, 0, 3, 6, 2, 5 },
100 { 6, 2, 5, 1, 4, 0, 3 },
101 { 0, 3, -1, 2, 5, 1, 4 },
102 };
103 const signed char flatTab[14][7] = {
104 { 4, 1, 5, 2, 6, 3, 7 },
105 { 4, 1, 5, 2, 6, 3, 7 },
106 { 4, 1, 5, 2, 6, 3, 7 },
107 { 4, 1, 5, 2, 6, 3, 7 },
108 { 6, 3, 7, 4, 8, 5, 9 },
109 { 6, 3, 7, 4, 8, 5, 9 },
110 { 6, 3, 7, 4, 8, 5, 9 },
111
112 { 1, 5, 2, 6, 3, 7, 4 },
113 { 4, 1, 5, 2, 6, 3, 7 },
114 { 2, 6, 3, 7, 4, 8, 5 },
115 { 7, 4, 1, 5, 2, 6, 3 },
116 { 5, 2, 6, 3, 7, 4, 8 },
117 { 3, 0, 4, 1, 5, 2, 6 },
118 { 4, 1, 5, 2, 6, 3, 7 },
119 };
120
121 QString museGlobalLib;
122 QString museGlobalShare;
123 QString museUser;
124 QString museProject;
125 QString museProjectInitPath("./");
126
127 QString configName;
128 QString configPath;
129 QString cachePath;
130 QString museInstruments;
131 QString museUserInstruments;
132
133 QString lastWavePath(".");
134 QString lastMidiPath(".");
135
136 bool debugMode = false;
137 bool unityWorkaround = false;
138 bool debugMsg = false;
139 bool heavyDebugMsg = false;
140 bool midiInputTrace = false;
141 bool midiOutputTrace = false;
142 bool realTimeScheduling = false;
143 int realTimePriority = 40; // 80
144 int midiRTPrioOverride = -1;
145 bool loadPlugins = true;
146 bool loadMESS = true;
147 bool loadVST = true;
148 bool loadNativeVST = true;
149 bool loadDSSI = true;
150 bool loadLV2 = true;
151 bool usePythonBridge = false;
152 QString pythonBridgePyroNSHostname;
153 QString pythonBridgePyroNSPort;
154 QString pythonBridgePyroDaemonHostname;
155 QString pythonBridgePyroDaemonPort;
156 float pythonBridgePyroCommTimeout = 5.0;
157 bool useLASH = true;
158 bool useAlsaWithJack = false;
159 bool noAutoStartJack = false;
160 bool populateMidiPortsOnStart = true;
161
162 const char* midi_file_pattern[] = {
163 QT_TRANSLATE_NOOP("file_patterns", "Midi/Kar (*.mid *.MID *.kar *.KAR *.mid.gz *.mid.bz2)"),
164 QT_TRANSLATE_NOOP("file_patterns", "Midi (*.mid *.MID *.mid.gz *.mid.bz2)"),
165 QT_TRANSLATE_NOOP("file_patterns", "Karaoke (*.kar *.KAR *.kar.gz *.kar.bz2)"),
166 QT_TRANSLATE_NOOP("file_patterns", "All Files (*)"),
167 0
168 };
169
170 //FIXME: By T356 01/19/2010
171 // If saving as a compressed file (gz or bz2),
172 // the file is a pipe, and pipes can't seek !
173 // This results in a corrupted midi file from MidiFile::writeTrack().
174 // So exporting compressed midi has simply been disabled here for now...
175 // For re-enabling, add .mid.gz and .mid.bz2 and same for .kar again
176 const char* midi_file_save_pattern[] = {
177 QT_TRANSLATE_NOOP("file_patterns", "Midi (*.mid)"),
178 QT_TRANSLATE_NOOP("file_patterns", "Karaoke (*.kar)"),
179 QT_TRANSLATE_NOOP("file_patterns", "All Files (*)"),
180 0
181 };
182
183 const char* med_file_pattern[] = {
184 QT_TRANSLATE_NOOP("file_patterns", "all known files (*.med *.med.gz *.med.bz2 *.mid *.midi *.kar)"),
185 QT_TRANSLATE_NOOP("file_patterns", "med Files (*.med *.med.gz *.med.bz2)"),
186 QT_TRANSLATE_NOOP("file_patterns", "Uncompressed med Files (*.med)"),
187 QT_TRANSLATE_NOOP("file_patterns", "gzip compressed med Files (*.med.gz)"),
188 QT_TRANSLATE_NOOP("file_patterns", "bzip2 compressed med Files (*.med.bz2)"),
189 QT_TRANSLATE_NOOP("file_patterns", "mid Files (*.mid *.midi *.kar *.MID *.MIDI *.KAR)"),
190 QT_TRANSLATE_NOOP("file_patterns", "All Files (*)"),
191 0
192 };
193 const char* med_file_save_pattern[] = {
194 QT_TRANSLATE_NOOP("file_patterns", "Uncompressed med Files (*.med)"),
195 QT_TRANSLATE_NOOP("file_patterns", "gzip compressed med Files (*.med.gz)"),
196 QT_TRANSLATE_NOOP("file_patterns", "bzip2 compressed med Files (*.med.bz2)"),
197 QT_TRANSLATE_NOOP("file_patterns", "All Files (*)"),
198 0
199 };
200 const char* project_create_file_save_pattern[] = {
201 QT_TRANSLATE_NOOP("file_patterns", "Uncompressed med Files (*.med)"),
202 QT_TRANSLATE_NOOP("file_patterns", "gzip compressed med Files (*.med.gz)"),
203 QT_TRANSLATE_NOOP("file_patterns", "bzip2 compressed med Files (*.med.bz2)"),
204 0
205 };
206
207 const char* image_file_pattern[] = {
208 QT_TRANSLATE_NOOP("file_patterns", "(*.jpg *.gif *.png)"),
209 QT_TRANSLATE_NOOP("file_patterns", "(*.jpg)"),
210 QT_TRANSLATE_NOOP("file_patterns", "(*.gif)"),
211 QT_TRANSLATE_NOOP("file_patterns", "(*.png)"),
212 QT_TRANSLATE_NOOP("file_patterns", "All Files (*)"),
213 0
214 };
215
216 const char* part_file_pattern[] = {
217 QT_TRANSLATE_NOOP("file_patterns", "part Files (*.mpt *.mpt.gz *.mpt.bz2)"),
218 QT_TRANSLATE_NOOP("file_patterns", "All Files (*)"),
219 0
220 };
221 const char* part_file_save_pattern[] = {
222 QT_TRANSLATE_NOOP("file_patterns", "part Files (*.mpt)"),
223 QT_TRANSLATE_NOOP("file_patterns", "gzip compressed part Files (*.mpt.gz)"),
224 QT_TRANSLATE_NOOP("file_patterns", "bzip2 compressed part Files (*.mpt.bz2)"),
225 QT_TRANSLATE_NOOP("file_patterns", "All Files (*)"),
226 0
227 };
228
229 const char* preset_file_pattern[] = {
230 QT_TRANSLATE_NOOP("file_patterns", "Presets (*.pre *.pre.gz *.pre.bz2)"),
231 QT_TRANSLATE_NOOP("file_patterns", "All Files (*)"),
232 0
233 };
234
235 const char* preset_file_save_pattern[] = {
236 QT_TRANSLATE_NOOP("file_patterns", "Presets (*.pre)"),
237 QT_TRANSLATE_NOOP("file_patterns", "gzip compressed presets (*.pre.gz)"),
238 QT_TRANSLATE_NOOP("file_patterns", "bzip2 compressed presets (*.pre.bz2)"),
239 QT_TRANSLATE_NOOP("file_patterns", "All Files (*)"),
240 0
241 };
242
243 const char* drum_map_file_pattern[] = {
244 QT_TRANSLATE_NOOP("file_patterns", "Presets (*.map *.map.gz *.map.bz2)"),
245 QT_TRANSLATE_NOOP("file_patterns", "All Files (*)"),
246 0
247 };
248
249 const char* drum_map_file_save_pattern[] = {
250 QT_TRANSLATE_NOOP("file_patterns", "Presets (*.map)"),
251 QT_TRANSLATE_NOOP("file_patterns", "gzip compressed presets (*.map.gz)"),
252 QT_TRANSLATE_NOOP("file_patterns", "bzip2 compressed presets (*.map.bz2)"),
253 QT_TRANSLATE_NOOP("file_patterns", "All Files (*)"),
254 0
255 };
256
257 const char* audio_file_pattern[] = {
258 QT_TRANSLATE_NOOP("file_patterns", "Wave/Binary (*.wav *.ogg *.flac *.bin)"),
259 QT_TRANSLATE_NOOP("file_patterns", "Wave (*.wav *.ogg *.flac)"),
260 QT_TRANSLATE_NOOP("file_patterns", "Binary (*.bin)"),
261 QT_TRANSLATE_NOOP("file_patterns", "All Files (*)"),
262 0
263 };
264
265 const char* colors_config_file_pattern[] = {
266 QT_TRANSLATE_NOOP("file_patterns", "Color configuration files (*.cfc)"),
267 QT_TRANSLATE_NOOP("file_patterns", "All Files (*)"),
268 0
269 };
270
271 const char* stylesheet_file_pattern[] = {
272 QT_TRANSLATE_NOOP("file_patterns", "Qt style sheets (*.qss)"),
273 QT_TRANSLATE_NOOP("file_patterns", "All Files (*)"),
274 0
275 };
276
277 Qt::KeyboardModifiers globalKeyState;
278
279 // Midi Filter Parameter
280 int midiInputPorts = 0; // receive from all devices
281 int midiInputChannel = 0; // receive all channel
282 int midiRecordType = 0; // receive all events
283 int midiThruType = 0; // transmit all events
284 int midiFilterCtrl1 = 0;
285 int midiFilterCtrl2 = 0;
286 int midiFilterCtrl3 = 0;
287 int midiFilterCtrl4 = 0;
288
289 QActionGroup* undoRedo;
290 QAction* undoAction;
291 QAction* redoAction;
292 QActionGroup* transportAction;
293 QAction* playAction;
294 QAction* startAction;
295 QAction* stopAction;
296 QAction* rewindAction;
297 QAction* forwardAction;
298 QAction* loopAction;
299 QAction* punchinAction;
300 QAction* punchoutAction;
301 QAction* recordAction;
302 QAction* panicAction;
303 QAction* metronomeAction;
304 QAction* cpuLoadAction;
305
306 MusEGui::MusE* muse = nullptr;
307
308 MusECore::MetroAccentsPresetsMap metroAccentPresets;
309 MusECore::MetronomeSettings metroGlobalSettings;
310 MusECore::MetronomeSettings metroSongSettings;
311 // Whether to use the global or song metronome settings.
312 bool metroUseSongSettings = false;
313
314 bool rcEnable = false;
315 unsigned char rcStopNote = 28;
316 unsigned char rcRecordNote = 31;
317 unsigned char rcGotoLeftMarkNote = 33;
318 unsigned char rcPlayNote = 29;
319 unsigned char rcSteprecNote = 36;
320 unsigned char rcForwardNote = 26;
321 unsigned char rcBackwardNote = 24;
322
323 bool rcEnableCC = false;
324 unsigned char rcGotoLeftMarkCC = 111;
325 unsigned char rcBackwardCC = 112;
326 unsigned char rcForwardCC = 113;
327 unsigned char rcStopCC = 114;
328 unsigned char rcPlayCC = 115;
329 //unsigned char rcInsertPauseCC = 116;
330 unsigned char rcRecordCC = 117;
331
332 // REMOVE Tim. automation. Remove this.
333 // Deprecated. MusEGlobal::automation is now fixed TRUE
334 // for now until we decide what to do with it.
335 bool automation = true;
336
337 // Midi learn params. These will be initialized to -1 by any midi learn function,
338 // and then filled by the midi engine in response to the drivers.
339 int midiLearnPort = -1;
340 int midiLearnChan = -1;
341 int midiLearnCtrl = -1;
342
343 const QString inputRoutingToolTipBase = QObject::tr("Input routing");
344 const QString noInputRoutingToolTipWarn = inputRoutingToolTipBase + QString("\n") + QObject::tr("Warning: No input routes! Click to connect...");
345
346 const QString outputRoutingToolTipBase = QObject::tr("Output routing");
347 const QString noOutputRoutingToolTipWarn = outputRoutingToolTipBase + QString("\n") + QObject::tr("Warning: No output routes! Click to connect...");
348
349 // REMOVE Tim. setuid. Removed.
350 //uid_t euid, ruid; // effective user id, real user id
351
352 bool midiSeqRunning = false;
353
354 QString defaultStyle = "Fusion";
355
356 //---------------------------------------------------------
357 // convertFrame4ProjectSampleRate
358 //---------------------------------------------------------
359
convertFrame4ProjectSampleRate(unsigned frame)360 unsigned convertFrame4ProjectSampleRate(unsigned frame)
361 {
362 return double(frame) * double(MusEGlobal::sampleRate) / double(MusEGlobal::projectSampleRate);
363 }
364
365 //---------------------------------------------------------
366 // doSetuid
367 // Restore the effective UID to its original value.
368 //---------------------------------------------------------
369
doSetuid()370 void doSetuid()
371 {
372 // BUG REMOVE Tim. setuid. Removed. Ancient stuff no longer required?
373 // Tests OK under several scenarios: Jack started externally,
374 // Jack started by MusE, Jack started as root, dummy driver etc.
375 // Was causing crash with new DrumGizmo 0.9.11
376 // #ifndef RTCAP
377 // int status;
378 // #ifdef _POSIX_SAVED_IDS
379 // status = seteuid (euid);
380 // #else
381 // status = setreuid (ruid, euid);
382 // #endif
383 // if (status < 0) {
384 // perror("doSetuid: Couldn't set uid");
385 // }
386 // #endif
387 }
388
389 //---------------------------------------------------------
390 // undoSetuid
391 // Set the effective UID to the real UID.
392 //---------------------------------------------------------
393
undoSetuid()394 void undoSetuid()
395 {
396 // BUG REMOVE Tim. setuid. Removed. Ancient stuff no longer required?
397 // Tests OK under several scenarios: Jack started externally,
398 // Jack started by MusE, Jack started as root, dummy driver etc.
399 // Was causing crash with new DrumGizmo 0.9.11
400 // #ifndef RTCAP
401 // int status;
402 //
403 // #ifdef _POSIX_SAVED_IDS
404 // status = seteuid (ruid);
405 // #else
406 // status = setreuid (euid, ruid);
407 // #endif
408 // if (status < 0) {
409 // fprintf(stderr, "undoSetuid: Couldn't set uid (eff:%d,real:%d): %s\n",
410 // euid, ruid, strerror(errno));
411 // exit (status);
412 // }
413 // #endif
414 }
415
416 //---------------------------------------------------------
417 // getUniqueTmpfileName
418 //---------------------------------------------------------
getUniqueTmpfileName(QString subDir,QString ext,QString & newFilename)419 bool getUniqueTmpfileName(QString subDir, QString ext, QString& newFilename)
420 {
421 // Check if tmp-directory exists under project path
422 QString tmpInDir = museProject + "/" + subDir;
423 QDir absDir(tmpInDir);
424 tmpInDir = absDir.cleanPath(absDir.absolutePath());
425
426 QFileInfo tmpdirfi(tmpInDir);
427 if (!tmpdirfi.isDir()) {
428 // Try to create a tmpdir
429 QDir projdir(museProject);
430 if (!projdir.mkdir(subDir)) {
431 printf("Could not create tmp dir %s!\n", tmpInDir.toLatin1().data() );
432 return false;
433 }
434 }
435
436 tmpdirfi.setFile(tmpInDir);
437
438 if (!tmpdirfi.isWritable()) {
439 printf("Temp directory is not writable - aborting\n");
440 return false;
441 }
442
443 QDir tmpdir = tmpdirfi.dir();
444
445 // Find a new filename
446 for (int i=0; i<10000; i++) {
447 QString filename = "muse_tmp";
448 filename.append(QString::number(i));
449 if (!ext.startsWith("."))
450 filename.append(".");
451 filename.append(ext);
452
453 if (!tmpdir.exists(tmpInDir +"/" + filename)) {
454 newFilename = tmpInDir + "/" + filename;
455 if (debugMsg)
456 printf("returning temporary filename %s\n", newFilename.toLatin1().data());
457 return true;
458 }
459
460 }
461
462 printf("Could not find a suitable tmpfilename (more than 10000 tmpfiles in tmpdir - clean up!\n");
463 return false;
464 }
465
466 } // namespace MusEGlobal
467