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