1 //=============================================================================
2 // MuseScore
3 // Music Composition & Notation
4 //
5 // Copyright (C) 2002-2011 Werner Schweer and others
6 //
7 // This program is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License version 2.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 //=============================================================================
19
20 #include <fenv.h>
21
22 #include "musescore.h"
23 #include "libmscore/score.h"
24 #include "libmscore/instrument.h"
25 #include "libmscore/measure.h"
26 #include "libmscore/segment.h"
27 #include "libmscore/chordrest.h"
28 #include "libmscore/chord.h"
29 #include "libmscore/note.h"
30 #include "libmscore/undo.h"
31 #include "mixer/mixer.h"
32 #include "parteditbase.h"
33 #include "scoreview.h"
34 #include "playpanel.h"
35 #include "preferences.h"
36 #include "seq.h"
37 #include "audio/midi/msynthesizer.h"
38 #include "shortcut.h"
39
40 #ifdef OSC
41 #include "ofqf/qoscserver.h"
42 #endif
43
44 namespace Ms {
45
46 extern MasterSynthesizer* synti;
47
48 //---------------------------------------------------------
49 // initOsc
50 //---------------------------------------------------------
51
52 #ifndef OSC
initOsc()53 void MuseScore::initOsc()
54 {
55 }
56
57 #else // #ifndef OSC
58
59 //---------------------------------------------------------
60 // initOsc
61 //---------------------------------------------------------
62
initOsc()63 void MuseScore::initOsc()
64 {
65 if (!preferences.getBool(PREF_IO_OSC_USEREMOTECONTROL))
66 return;
67 int port = preferences.getInt(PREF_IO_OSC_PORTNUMBER);
68 QOscServer* osc = new QOscServer(port, qApp);
69
70 PathObject* oo = new PathObject( "/addpitch", QVariant::Int, osc);
71 QObject::connect(oo, SIGNAL(data(int)), SLOT(oscIntMessage(int)));
72
73 oo = new PathObject( "/tempo", QVariant::Int, osc);
74 QObject::connect(oo, SIGNAL(data(int)), SLOT(oscTempo(int)));
75 oo = new PathObject( "/volume", QVariant::Int, osc);
76 QObject::connect(oo, SIGNAL(data(int)), SLOT(oscVolume(int)));
77 oo = new PathObject( "/goto", QVariant::Int, osc);
78 QObject::connect(oo, SIGNAL(data(int)), SLOT(oscGoto(int)));
79 oo = new PathObject( "/select-measure", QVariant::Int, osc);
80 QObject::connect(oo, SIGNAL(data(int)), SLOT(oscSelectMeasure(int)));
81 for (int i = 1; i <= 12; i++ ) {
82 oo = new PathObject( QString("/vol%1").arg(i), QVariant::Double, osc);
83 QObject::connect(oo, SIGNAL(data(double)), SLOT(oscVolChannel(double)));
84 }
85 for(int i = 1; i <= 12; i++ ) {
86 oo = new PathObject( QString("/pan%1").arg(i), QVariant::Double, osc);
87 QObject::connect(oo, SIGNAL(data(double)), SLOT(oscPanChannel(double)));
88 }
89 for(int i = 1; i <= 12; i++ ) {
90 oo = new PathObject( QString("/mute%1").arg(i), QVariant::Double, osc);
91 QObject::connect(oo, SIGNAL(data(double)), SLOT(oscMuteChannel(double)));
92 }
93
94 oo = new PathObject( "/open", QVariant::String, osc);
95 QObject::connect(oo, SIGNAL(data(QString)), SLOT(oscOpen(QString)));
96 oo = new PathObject( "/close-all", QVariant::Invalid, osc);
97 QObject::connect(oo, SIGNAL(data()), SLOT(oscCloseAll()));
98
99 oo = new PathObject( "/plugin", QVariant::String, osc);
100 QObject::connect(oo, SIGNAL(data(QString)), SLOT(oscTriggerPlugin(QString)));
101
102 oo = new PathObject( "/color-note", QVariant::List, osc);
103 QObject::connect(oo, SIGNAL(data(QVariantList)), SLOT(oscColorNote(QVariantList)));
104
105 for (const Shortcut* s : Shortcut::shortcuts()) {
106 oo = new PathObject( QString("/actions/%1").arg(s->key().data()), QVariant::Invalid, osc);
107 QObject::connect(oo, SIGNAL(data()), SLOT(oscAction()));
108 }
109 }
110
111 //---------------------------------------------------------
112 // oscIntMessage
113 //---------------------------------------------------------
114
oscIntMessage(int val)115 void MuseScore::oscIntMessage(int val)
116 {
117 if (val < 128) {
118 midiNoteReceived(0, val, 60);
119 midiNoteReceived(0, val, 0);
120 }
121 else
122 midiCtrlReceived(val-128, 22);
123 }
124
oscAction()125 void MuseScore::oscAction()
126 {
127 PathObject* pathObject = qobject_cast<PathObject*>(sender());
128 QString path = pathObject->path().mid(9);
129 QAction* a = getAction(path.toLocal8Bit().data());
130 a->trigger();
131 }
132
oscGoto(int m)133 void MuseScore::oscGoto(int m)
134 {
135 qDebug("GOTO %d", m);
136 if (cv == 0)
137 return;
138 cv->searchPage(m);
139 }
140
oscSelectMeasure(int m)141 void MuseScore::oscSelectMeasure(int m)
142 {
143 qDebug("SelectMeasure %d", m);
144 if (cv == 0)
145 return;
146 // cv->selectMeasure(m);
147 Score* score = cv->score();
148 int i = 0;
149 for (Measure* measure = score->firstMeasure(); measure; measure = measure->nextMeasure()) {
150 if (++i < m)
151 continue;
152 score->selection().setState(SelState::RANGE);
153 score->selection().setStartSegment(measure->first());
154 score->selection().setEndSegment(measure->last());
155 score->selection().setStaffStart(0);
156 score->selection().setStaffEnd(score->nstaves());
157 score->selection().updateSelectedElements();
158 score->selection().setState(SelState::RANGE);
159 score->addRefresh(measure->canvasBoundingRect());
160 cv->adjustCanvasPosition(measure, true);
161 score->setUpdateAll();
162 score->update();
163 break;
164 }
165 }
166
167
oscOpen(QString path)168 void MuseScore::oscOpen(QString path)
169 {
170 qDebug("Open %s", qPrintable(path));
171 openScore(path);
172 }
173
174
oscCloseAll()175 void MuseScore::oscCloseAll()
176 {
177 qDebug("CloseAll");
178 while(cs != 0)
179 closeScore(cs);
180 }
181
182 //---------------------------------------------------------
183 // oscTempo
184 //---------------------------------------------------------
185
oscTempo(int val)186 void MuseScore::oscTempo(int val)
187 {
188 if (val < 10)
189 val = 10;
190 if (val > 300)
191 val = 300;
192 qreal t = val * .01;
193 if (playPanel)
194 playPanel->setSpeed(t);
195 if (seq)
196 seq->setRelTempo(double(t));
197 }
198
199 //---------------------------------------------------------
200 // oscTriggerPlugin
201 //---------------------------------------------------------
202
oscTriggerPlugin(QString)203 void MuseScore::oscTriggerPlugin(QString /*s*/)
204 {
205 #if 0 // TODO
206 #ifdef SCRIPT_INTERFACE
207 QStringList args = s.split(",");
208 if(args.length() > 0) {
209 int idx = pluginIdxFromPath(args.at(0));
210 if(idx != -1) {
211 for(int i = 1; i < args.length()-1; i++) {
212 addGlobalObjectToPluginEngine(qPrintable(args.at(i)), args.at(i+1));
213 i++;
214 }
215 pluginTriggered(idx);
216 }
217 }
218 #endif
219 #endif
220 }
221
222 //---------------------------------------------------------
223 // oscColorNote
224 //---------------------------------------------------------
oscColorNote(QVariantList list)225 void MuseScore::oscColorNote(QVariantList list)
226 {
227 qDebug() << list;
228 if(!cs)
229 return;
230 if (list.length() != 2 && list.length() != 3)
231 return;
232 int tick;
233 int pitch;
234 QColor noteColor("red"); //default to red
235 bool ok;
236 tick = list[0].toInt(&ok);
237 if (!ok)
238 return;
239 pitch = list[1].toInt(&ok);
240 if (!ok)
241 return;
242 if(list.length() == 3 && list[2].canConvert(QVariant::String)) {
243 QColor color(list[2].toString());
244 if(color.isValid())
245 noteColor = color;
246 }
247
248 Measure* measure = cs->tick2measure(Fraction::fromTicks(tick));
249 if(!measure)
250 return;
251 Segment* s = measure->findSegment(SegmentType::ChordRest, Fraction::fromTicks(tick));
252 if (!s)
253 return;
254 //get all chords in segment...
255 int n = cs->nstaves() * VOICES;
256 for (int i = 0; i < n; i++) {
257 Element* e = s->element(i);
258 if (e && e->isChordRest()) {
259 ChordRest* cr = static_cast<ChordRest*>(e);
260 if (cr->type() == ElementType::CHORD) {
261 Chord* chord = static_cast<Chord*>(cr);
262 for (Note* note : chord->notes()) {
263 if (note->pitch() == pitch) {
264 cs->startCmd();
265 cs->undo(new ChangeProperty(note, Pid::COLOR, noteColor));
266 cs->endCmd();
267 return;
268 }
269 }
270 }
271 }
272 }
273 }
274 //---------------------------------------------------------
275 // oscVolume
276 //---------------------------------------------------------
277
oscVolume(int val)278 void MuseScore::oscVolume(int val)
279 {
280 double v = val / 128.0;
281 synti->setGain(v);
282 }
283
284 //---------------------------------------------------------
285 // oscVolChannel
286 //---------------------------------------------------------
287
oscVolChannel(double val)288 void MuseScore::oscVolChannel(double val)
289 {
290 if (!cs)
291 return;
292 PathObject* po = (PathObject*) sender();
293
294 int i = po->path().mid(4).toInt() - 1;
295 auto& mms = cs->masterScore()->midiMapping();
296 if( i >= 0 && i < int(mms.size())) {
297 MidiMapping& mm = mms[i];
298 Channel* channel = mm.articulation();
299 int iv = lrint(val*127);
300 seq->setController(channel->channel(), CTRL_VOLUME, iv);
301 channel->setVolume(val * 100.0);
302 if (mixer)
303 mixer->getPartAtIndex(i)->volume->setValue(val * 100.0);
304 }
305 }
306
307 //---------------------------------------------------------
308 // oscPanChannel
309 //---------------------------------------------------------
310
oscPanChannel(double val)311 void MuseScore::oscPanChannel(double val)
312 {
313 if (!cs)
314 return;
315 PathObject* po = (PathObject*) sender();
316
317 int i = po->path().mid(4).toInt() - 1;
318 auto& mms = cs->masterScore()->midiMapping();
319 if (i >= 0 && i < int(mms.size())) {
320 MidiMapping& mm = mms[i];
321 Channel* channel = mm.articulation();
322 int iv = lrint((val + 1) * 64);
323 seq->setController(channel->channel(), CTRL_PANPOT, iv);
324 channel->setPan(val * 180.0);
325 if (mixer)
326 mixer->getPartAtIndex(i)->pan->setValue(val * 100.0);
327 }
328 }
329
330 //---------------------------------------------------------
331 // oscMuteChannel
332 //---------------------------------------------------------
333
oscMuteChannel(double val)334 void MuseScore::oscMuteChannel(double val)
335 {
336 if (!cs)
337 return;
338 PathObject* po = (PathObject*) sender();
339
340 int i = po->path().mid(5).toInt() - 1;
341 auto& mms = cs->masterScore()->midiMapping();
342 if (i >= 0 && i < int(mms.size())) {
343 MidiMapping& mm = mms[i];
344 Channel* channel = mm.articulation();
345 channel->setMute(val==0.0f ? false : true);
346 if (mixer)
347 mixer->getPartAtIndex(i)->mute->setChecked(channel->mute());
348 }
349 }
350 #endif // #ifndef OSC
351 }
352
353