1 /*
2 * Author: Harry van Haaren 2013
3 * harryhaaren@gmail.com
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
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, see <http://www.gnu.org/licenses/>.
17 */
18
19 #ifndef LUPPP_EVENT_HANDLER_DSP_H
20 #define LUPPP_EVENT_HANDLER_DSP_H
21
22
23 // Library
24 #include <cstring>
25 #include <iostream>
26 #include <jack/ringbuffer.h>
27
28 // Internal
29 #include "gui.hxx"
30 #include "event.hxx"
31 #include "audiobuffer.hxx"
32 #include "eventhandler.hxx"
33
34 #include "controller/controller.hxx"
35
36 #pragma GCC diagnostic ignored "-Wunused-parameter"
37
38 extern Gui* gui;
39
40 using namespace std;
41
handleGuiEvents()42 void handleGuiEvents()
43 {
44 uint availableRead = jack_ringbuffer_read_space( rbToGui );
45
46 while ( availableRead >= sizeof(EventBase) ) {
47 jack_ringbuffer_peek( rbToGui, (char*)processGuiMem, sizeof(EventBase) );
48
49 EventBase* e = (EventBase*)processGuiMem;
50
51 // recheck the size against the actual event size
52 if ( availableRead >= e->size() ) {
53 //cout << "reading event type " << e->type() << endl;
54
55 switch ( e->type() ) {
56 case Event::QUIT: {
57 if ( availableRead >= sizeof(EventQuit) ) {
58 EventQuit ev;
59 jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventQuit) );
60 LUPPP_NOTE("%s","GUI QUIT");
61 gui->quit();
62 }
63 break;
64 }
65
66 case Event::SAMPLERATE: {
67 if ( availableRead >= sizeof(EventSamplerate) ) {
68 EventSamplerate ev;
69 jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventSamplerate) );
70 gui->samplerate = ev.samplerate;
71 //LUPPP_NOTE("Gui Samplerate: %i", gui->samplerate);
72 }
73 break;
74 }
75
76 /// master
77 case Event::MASTER_INPUT_TO: {
78 if ( availableRead >= sizeof(EventMasterInputTo) ) {
79 EventMasterInputTo ev;
80 jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventMasterInputTo) );
81 gui->getMasterTrack()->setInputTo( (int)ev.place, ev.value );
82 }
83 break;
84 }
85 case Event::MASTER_INPUT_TO_ACTIVE: {
86 if ( availableRead >= sizeof(EventMasterInputToActive) ) {
87 EventMasterInputToActive ev;
88 jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventMasterInputToActive) );
89 gui->getMasterTrack()->setInputToActive( (int)ev.place, ev.active );
90 }
91 break;
92 }
93 case Event::MASTER_INPUT_VOL: {
94 if ( availableRead >= sizeof(EventMasterInputVol) ) {
95 EventMasterInputVol ev;
96 jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventMasterInputVol) );
97 gui->getMasterTrack()->setInputVol( ev.vol );
98 }
99 break;
100 }
101 case Event::MASTER_RETURN: {
102 if ( availableRead >= sizeof(EventMasterReturn) ) {
103 EventMasterReturn ev;
104 jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventMasterReturn) );
105 gui->getMasterTrack()->setReturnVol( ev.vol );
106 }
107 break;
108 }
109 case Event::MASTER_VOL: {
110 if ( availableRead >= sizeof(EventMasterVol) ) {
111 EventMasterVol ev(0);
112 jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventMasterVol) );
113 gui->getMasterTrack()->getVolume()->fader( ev.vol );
114 }
115 break;
116 }
117
118
119 case Event::METRONOME_ACTIVE: {
120 if ( availableRead >= sizeof(EventMetronomeActive) ) {
121 EventMetronomeActive ev(false);
122 jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventMetronomeActive) );
123 gui->getMasterTrack()->metronomeEnable(ev.active);
124 }
125 break;
126 }
127 case Event::LOOPER_STATE: {
128 if ( availableRead >= sizeof(EventLooperState) ) {
129 EventLooperState ev;
130 jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventLooperState) );
131 //gui->getTrack(ev.track)->getClipSelector()->setState(ev.scene, ev.state);
132 //jack->setLooperState( ev.track, ev.state );
133 }
134 break;
135 }
136 case Event::LOOPER_LOOP_LENGTH: {
137 if ( availableRead >= sizeof(EventLooperLoopLength) ) {
138 //EventLooperLoopLength ev;
139 //jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventLooperLoopLength) );
140 //jack->setLooperLoopLength( ev.track, ev.scale );
141 } break;
142 }
143 case Event::LOOPER_PROGRESS: {
144 if ( availableRead >= sizeof(EventLooperProgress) ) {
145 EventLooperProgress ev;
146 jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventLooperProgress) );
147
148 // only update if significant change
149 //if ( ev.progress - gui->getTrack(ev.track)->radial.value() >= 0.05 ||
150 // ev.progress > 0.9 )
151 gui->getTrack(ev.track)->radial.value(ev.progress);
152
153 }
154 break;
155 }
156
157
158 // FIXME: reset signal level to 0
159 case Event::TRACK_SIGNAL_LEVEL: {
160 if ( availableRead >= sizeof(EventTrackSignalLevel) ) {
161 EventTrackSignalLevel ev;
162 jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventTrackSignalLevel) );
163 if ( ev.track == -2 ) {
164 gui->getMasterTrack()->getInputVolume()->amplitude( ev.left, ev.right );
165 } else if ( ev.track == -1 ) {
166 gui->getMasterTrack()->getVolume()->amplitude( ev.left, ev.right );
167 } else {
168 gui->getTrack(ev.track)->getVolume()->amplitude( ev.left, ev.right );
169 }
170 }
171 break;
172 }
173 case Event::TRACK_VOLUME: {
174 if ( availableRead >= sizeof(EventTrackVol) ) {
175 EventTrackVol ev;
176 jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventTrackVol) );
177 gui->getTrack(ev.track)->getVolume()->fader( ev.vol );
178 }
179 break;
180 }
181 case Event::TRACK_PAN: {
182 if ( availableRead >= sizeof(EventTrackPan) ) {
183 EventTrackPan ev;
184 jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventTrackPan) );
185 gui->getTrack(ev.track)->setPan( ev.pan );
186 }
187 break;
188 }
189
190
191 case Event::TRACK_RECORD_ARM: {
192 if ( availableRead >= sizeof(EventTrackRecordArm) ) {
193 EventTrackRecordArm ev;
194 jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventTrackRecordArm) );
195 gui->getTrack(ev.track)->setRecordActive( ev.recordArm );
196 break;
197 }
198 }
199
200 case Event::TIME_BPM: {
201 if ( availableRead >= sizeof(EventTimeBPM) ) {
202 EventTimeBPM ev;
203 jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventTimeBPM) );
204 gui->getMasterTrack()->setBpm( ev.bpm );
205 }
206 break;
207 }
208
209
210 case Event::STATE_SAVE_BUFFER: {
211 if ( availableRead >= sizeof(EventStateSaveBuffer) ) {
212 EventStateSaveBuffer ev;
213 jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventStateSaveBuffer) );
214 #ifdef DEBUG_SAVE
215 cout << "EventSaveBuffer: " << ev.track << " " << ev.scene << " " << ev.ab->getID() << endl;
216 #endif
217 gui->getDiskWriter()->writeAudioBuffer( ev.track, ev.scene, ev.ab );
218 // de allocate the AudioBuffer only if reqested
219 if(!ev.no_dealloc) {
220 gui->getDiskWriter()->writeAudioBuffer( ev.track, ev.scene, ev.ab );
221 delete ev.ab;
222 } else {
223 gui->getDiskWriter()->writeAudioBuffer(ev.track, ev.scene, ev.ab,
224 gui->saveBufferPath.c_str());
225 gui->saveBufferPath = "";
226 }
227
228 }
229 break;
230 }
231
232 case Event::STATE_SAVE_FINISH: {
233 if ( availableRead >= sizeof(EventStateSaveFinish) ) {
234 EventStateSaveFinish ev;
235 jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventStateSaveFinish) );
236 #ifdef DEBUG_SAVE
237 cout << "EventSaveFinish!" << endl;
238 #endif
239 gui->getDiskWriter()->writeSession();
240 }
241 break;
242 }
243
244
245 case Event::GRID_STATE: {
246 if ( availableRead >= sizeof(EventGridState) ) {
247 EventGridState ev;
248 jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventGridState) );
249 gui->getTrack(ev.track)->getClipSelector()->setState( ev.scene, ev.state );
250 if ( ev.state == GridLogic::STATE_RECORDING )
251 gui->getTrack(ev.track)->getRadialStatus()->recording( true );
252 else if ( ev.state == GridLogic::STATE_EMPTY ) {
253 // reset clip name if clip gets cleared
254 gui->getTrack(ev.track)->getClipSelector()->clips[ ev.scene ].setName("");
255 gui->getTrack(ev.track)->getRadialStatus()->recording(false);
256 }
257 else
258 gui->getTrack(ev.track)->getRadialStatus()->recording( false );
259 }
260 break;
261 }
262 case Event::GRID_LAUNCH_SCENE: {
263 if ( availableRead >= sizeof(EventGridLaunchScene) ) {
264 EventGridLaunchScene ev;
265 jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventGridLaunchScene) );
266 for(int i = 0; i < NSCENES; i++)
267 gui->getMasterTrack()->getClipSelector()->setState( i, GridLogic::STATE_EMPTY );
268 gui->getMasterTrack()->getClipSelector()->setState( ev.scene, GridLogic::STATE_PLAYING );
269 }
270 break;
271 }
272
273 case Event::GRID_SELECT_NEW_CHOSEN: {
274 if ( availableRead >= sizeof(EventGridSelectNewChosen) ) {
275 EventGridSelectNewChosen ev;
276 jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventGridSelectNewChosen) );
277 //LUPPP_NOTE("New special, %i, %i", ev.track, ev.scene);
278 for(int i = 0; i < NTRACKS; i++) {
279 gui->getTrack(i)->getClipSelector()->setSpecial( i == ev.track ? ev.scene : -1 );
280 }
281 gui->specialTrack = ev.track;
282 gui->specialScene = ev.scene;
283 }
284 break;
285 }
286
287
288 case Event::TRACK_SEND: {
289 if ( availableRead >= sizeof(EventTrackSend) ) {
290 EventTrackSend ev;
291 jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventTrackSend) );
292 if ( ev.send == SEND_POSTFADER )
293 if ( ev.track < NTRACKS ) {
294 gui->getTrack(ev.track)->setSend(ev.value );
295 }
296 if ( ev.send == SEND_XSIDE )
297 if ( ev.track < NTRACKS ) {
298 gui->getTrack(ev.track)->setXSide( ev.value );
299 }
300 }
301 break;
302 }
303
304 case Event::TRACK_JACKSEND: {
305 if ( availableRead >= sizeof(EventTrackJackSend) ) {
306 EventTrackJackSend ev;
307 jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventTrackJackSend) );
308 gui->getTrack(ev.track)->setJackSend(ev.value);
309 }
310 break;
311 }
312
313 case Event::TRACK_JACKSEND_ACTIVATE: {
314 if ( availableRead >= sizeof(EventTrackJackSendActivate) ) {
315 EventTrackJackSendActivate ev;
316 jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventTrackJackSendActivate) );
317 gui->getTrack(ev.track)->setJackSendActivate(ev.active);
318 }
319 break;
320 }
321
322 case Event::TRACK_SEND_ACTIVE: {
323 if ( availableRead >= sizeof(EventTrackSendActive) ) {
324 EventTrackSendActive ev;
325 jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventTrackSendActive) );
326 if ( ev.send == SEND_POSTFADER )
327 if ( ev.track < NTRACKS ) {
328 gui->getTrack(ev.track)->setSendActive(ev.active );
329 }
330 if ( ev.send == SEND_KEY ) {
331 if ( ev.track < NTRACKS ) {
332 gui->getTrack(ev.track)->setKeyActive( ev.active );
333 }
334 }
335 }
336 break;
337 }
338
339 case Event::GUI_PRINT: {
340 if ( availableRead >= sizeof(EventGuiPrint) ) {
341 EventGuiPrint ev;
342 jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventGuiPrint) );
343 //cout << "DSP: " << ev.getMessage() << endl;
344 LUPPP_DSP("%s", ev.getMessage() );
345 }
346 break;
347 }
348 case Event::TIME_BAR_BEAT: {
349 if ( availableRead >= sizeof(EventTimeBarBeat) ) {
350 EventTimeBarBeat ev;
351 jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventTimeBarBeat) );
352 gui->getMasterTrack()->setBarBeat( ev.bar, ev.beat);
353 }
354 break;
355 }
356 case Event::TIME_TEMPO_TAP: {
357 if ( availableRead >= sizeof(EventTimeTempoTap) ) {
358 EventTimeTempoTap ev;
359 jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventTimeTempoTap) );
360 gui->getMasterTrack()->setTapTempo( ev.pressed );
361 }
362 break;
363 }
364
365
366 case Event::LOOPER_REQUEST_BUFFER: {
367 if ( availableRead >= sizeof(EventLooperClipRequestBuffer) ) {
368 EventLooperClipRequestBuffer ev;
369 jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventLooperClipRequestBuffer) );
370
371 /// allocate a new AudioBuffer with ev.numElements, pass back to DSP
372 AudioBuffer* ab = new AudioBuffer(ev.numElements);
373 EventLooperClipRequestBuffer returnEvent(ev.track, ev.scene, ab);
374 writeToDspRingbuffer( &returnEvent );
375 #ifdef DEBUG_BUFFER
376 printf("new buffer going to track %i, scene %i\n",ev.track, ev.scene);
377 #endif
378 }
379 break;
380 }
381
382 case Event::REQUEST_SAVE_BUFFER: {
383 if ( availableRead >= sizeof(EventRequestSaveBuffer) ) {
384 EventRequestSaveBuffer ev;
385 jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventRequestSaveBuffer) );
386 #ifdef DEBUG_BUFFER
387 printf("Save buffer to track %i, scene %i\n",ev.track, ev.scene);
388 #endif
389 /// allocate a new AudioBuffer with ev.numElements, pass back to DSP
390 AudioBuffer* ab = new AudioBuffer(ev.bufferSize);
391
392 if ( ab ) {
393 //LUPPP_NOTE("Save buffer sent with t %i, s %i, ab* %i", ev.track, ev.scene, ab );
394 EventRequestSaveBuffer returnEvent( ev.track, ev.scene, ab);
395 writeToDspRingbuffer( &returnEvent );
396 } else {
397 cout << "error allocating save buffer!" << endl;
398 }
399 }
400 break;
401 }
402
403 case Event::DEALLOCATE_BUFFER: {
404 if ( availableRead >= sizeof(EventDeallocateBuffer) ) {
405 EventDeallocateBuffer ev;
406 jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventDeallocateBuffer) );
407 delete ev.ab;
408 }
409 break;
410 }
411
412 case Event::CONTROLLER_BINDING_ENABLE: {
413 if ( availableRead >= sizeof(EventControllerBindingEnable) ) {
414 EventControllerBindingEnable ev;
415 jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventControllerBindingEnable) );
416 ControllerUI* c = gui->getOptionsWindow()->getControllerUI( ev.controllerID );
417 if ( c )
418 c->setBindEnable( ev.enable );
419 else
420 LUPPP_WARN("ControllerUI %i doesn't exist in the UI", ev.controllerID );
421 }
422 break;
423 }
424
425 case Event::CONTROLLER_BINDING_TARGET: {
426 if ( availableRead >= sizeof(EventControllerBindingTarget) ) {
427 EventControllerBindingTarget ev;
428 jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventControllerBindingTarget) );
429 gui->getOptionsWindow()->setTarget( ev.target );
430 }
431 break;
432 }
433
434 case Event::CONTROLLER_BINDING_MADE: {
435 if ( availableRead >= sizeof(EventControllerBindingMade) ) {
436 EventControllerBindingMade ev;
437 jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventControllerBindingMade) );
438 ControllerUI* c = gui->getOptionsWindow()->getControllerUI( ev.controllerID );
439 if ( c )
440 c->addBinding( (Binding*)ev.binding );
441 else
442 LUPPP_WARN("ControllerUI %i doesn't exist in the UI", ev.controllerID );
443 }
444 break;
445 }
446
447 case Event::CONTROLLER_INSTANCE_GET_TO_WRITE: {
448 if ( availableRead >= sizeof(EventControllerInstanceGetToWrite) ) {
449 EventControllerInstanceGetToWrite ev;
450 jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventControllerInstanceGetToWrite) );
451 // write the contents of the GenericMIDI controller to .ctlr file
452 gui->getDiskWriter()->writeControllerFile( (Controller*)ev.controller );
453 }
454 break;
455 }
456
457 case Event::CONTROLLER_INSTANCE: {
458 if ( availableRead >= sizeof(EventControllerInstance) ) {
459 EventControllerInstance ev;
460 jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventControllerInstance) );
461 // remove this controller from use:
462 Controller* c = (Controller*)ev.controller;
463 LUPPP_NOTE("Deleting controller %s", c->getName().c_str() );
464 // delete will call the destructor for the Controller: this should
465 // clean up ports etc, all from the GUI thread as appropriate
466 delete c;
467 }
468 break;
469 }
470
471
472
473 default: {
474 cout << "GUI: Unkown message!! Will clog ringbuffer" << endl;
475 // just do nothing
476 break;
477 }
478 }
479 } else {
480 // next call will get the half-written event
481 return;
482 }
483
484 // update available read, and loop over events
485 availableRead = jack_ringbuffer_read_space( rbToGui );
486 }
487 }
488
writeToGuiRingbuffer(EventBase * e)489 void writeToGuiRingbuffer(EventBase* e)
490 {
491 if ( jack_ringbuffer_write_space(rbToGui) >= e->size() ) {
492 jack_ringbuffer_write( rbToGui, (const char*)e, e->size() );
493 } else {
494 cout << "->GUI ringbuffer full!" << endl;
495 }
496 }
497
498 #endif // LUPPP_EVENT_HANDLER_DSP_H
499
500