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 #include "jack.hxx"
20
21 #include <sstream>
22 #include <cstring>
23 #include <iostream>
24
25 #include "state/state.hxx"
26
27 #include "gui.hxx"
28 #include "logic.hxx"
29 #include "config.hxx"
30 #include "looper.hxx"
31 #include "metronome.hxx"
32 #include "gridlogic.hxx"
33 #include "trackoutput.hxx"
34 #include "timemanager.hxx"
35 #include "controllerupdater.hxx"
36 #include "jacksendreturn.hxx"
37 #include "dsp/dsp_reverb.hxx"
38 #include "dsp/dsp_dbmeter.hxx"
39
40 #include "audiobuffer.hxx"
41 #include "eventhandler.hxx"
42 #include "controller/genericmidi.hxx"
43 #include "controller/guicontroller.hxx"
44
45
46 using namespace std;
47
48 int AudioBuffer::privateID = 0;
49
50 // static pointers from main
51 extern Gui* gui;
52 extern Jack* jack;
53
setup(std::string name)54 void Jack::setup(std::string name)
55 {
56 if ( jack == 0 ) {
57 jack = new Jack( name );
58
59 jack->activate();
60 return;
61 } else {
62 LUPPP_WARN("JACK instance already exists!");
63 }
64 }
65
resetMidiBindingState()66 void Jack::resetMidiBindingState()
67 {
68 // MIDI binding stuff
69 bindingEventRecordEnable = false;
70 bindingEventType = EVENT_NULL;
71 bindingTrack = -2;
72 bindingScene = -1;
73 bindingSend = -1;
74 bindingActive= 1;
75 }
76
Jack(std::string name)77 Jack::Jack( std::string name ) :
78 client( jack_client_open ( name.c_str(), JackNullOption, 0, 0 ) ),
79 state( new State() ),
80 controllerUpdater( new ControllerUpdater() ),
81 clientActive(false)
82 {
83 jack = this;
84 lastnframes=0;
85 samplerate = jack_get_sample_rate( client );
86
87 // calculate smoothing value for current sample rate
88 smoothing_value = SMOOTHING_CONST * (44100.f / samplerate);
89
90 // construct Observer classes here, not in the initializer list as the Jack*
91 // will be 0x0 until then.
92 timeManager = new TimeManager(),
93 metronome = new Metronome();
94 logic = new Logic();
95 gridLogic = new GridLogic();
96
97 // CAREFUL: setup the size by default: otherwise malloc() is called on push_back
98 midiIO.reserve( CONTROLLERS_PREALLOC );
99
100 resetMidiBindingState();
101
102 buffers.nframes = jack_get_buffer_size( client );
103 buffers.samplerate = jack_get_sample_rate( client );
104
105 EventSamplerate e(buffers.samplerate);
106 writeToGuiRingbuffer( &e );
107
108 uiUpdateCounter = buffers.samplerate / 30;
109 uiUpdateConstant = buffers.samplerate / 30;
110
111 masterInputL = jack_port_register( client,
112 "master_in_left",
113 JACK_DEFAULT_AUDIO_TYPE,
114 JackPortIsInput,
115 0 );
116
117 masterInputR = jack_port_register( client,
118 "master_in_right",
119 JACK_DEFAULT_AUDIO_TYPE,
120 JackPortIsInput,
121 0 );
122
123 masterReturnL = jack_port_register( client,
124 "master_return_left",
125 JACK_DEFAULT_AUDIO_TYPE,
126 JackPortIsInput,
127 0 );
128
129 masterReturnR = jack_port_register( client,
130 "master_return_right",
131 JACK_DEFAULT_AUDIO_TYPE,
132 JackPortIsInput,
133 0 );
134
135 masterOutputL = jack_port_register( client,
136 "master_left",
137 JACK_DEFAULT_AUDIO_TYPE,
138 JackPortIsOutput,
139 0 );
140
141 masterOutputR = jack_port_register( client,
142 "master_right",
143 JACK_DEFAULT_AUDIO_TYPE,
144 JackPortIsOutput,
145 0 );
146
147 headphonesPortL = jack_port_register( client,
148 "headphone_out_l",
149 JACK_DEFAULT_AUDIO_TYPE,
150 JackPortIsOutput,
151 0 );
152
153 headphonesPortR = jack_port_register( client,
154 "headphone_out_r",
155 JACK_DEFAULT_AUDIO_TYPE,
156 JackPortIsOutput,
157 0 );
158
159 sendOutputL = jack_port_register( client,
160 "send_out_l",
161 JACK_DEFAULT_AUDIO_TYPE,
162 JackPortIsOutput,
163 0 );
164
165 sendOutputR = jack_port_register( client,
166 "send_out_r",
167 JACK_DEFAULT_AUDIO_TYPE,
168 JackPortIsOutput,
169 0 );
170
171 sidechainKeyOutputL = jack_port_register( client,
172 "sidechain_key_l",
173 JACK_DEFAULT_AUDIO_TYPE,
174 JackPortIsOutput,
175 0 );
176
177 sidechainKeyOutputR = jack_port_register( client,
178 "sidechain_key_r",
179 JACK_DEFAULT_AUDIO_TYPE,
180 JackPortIsOutput,
181 0 );
182
183 sidechainSignalOutputL = jack_port_register( client,
184 "sidechain_signal_l",
185 JACK_DEFAULT_AUDIO_TYPE,
186 JackPortIsOutput,
187 0 );
188
189 sidechainSignalOutputR = jack_port_register( client,
190 "sidechain_signal_r",
191 JACK_DEFAULT_AUDIO_TYPE,
192 JackPortIsOutput,
193 0 );
194
195 /*
196 masterMidiInput = jack_port_register( client,
197 "midi_in",
198 JACK_DEFAULT_MIDI_TYPE,
199 JackPortIsInput,
200 0 );
201 */
202
203
204 returnVol = 1.0f;
205 returnVolLag = 1.0f;
206 inputToMixEnable = false;
207 inputToMixEnableLag = 0.f;
208 inputToSendEnable = false;
209 inputToSendEnableLag = 0.f;
210 inputToKeyEnable = false;
211 inputToKeyEnableLag = 0.f;
212 inputToMixVol = 0.f;
213 inputToMixVolLag = 0.f;
214 inputToSendVol = 0.f;
215 inputToSendVolLag = 0.f;
216 inputToXSideVol = 0.f;
217 inputToXSideVolLag = 0.f;
218
219 /// prepare internal buffers
220 buffers.audio[Buffers::SEND_L] = new float[ buffers.nframes ];
221 buffers.audio[Buffers::SEND_R] = new float[ buffers.nframes ];
222 buffers.audio[Buffers::SIDECHAIN_KEY_L] = new float[ buffers.nframes ];
223 buffers.audio[Buffers::SIDECHAIN_KEY_R] = new float[ buffers.nframes ];
224 buffers.audio[Buffers::SIDECHAIN_SIGNAL_L]= new float[ buffers.nframes ];
225 buffers.audio[Buffers::SIDECHAIN_SIGNAL_R]= new float[ buffers.nframes ];
226
227 buffers.audio[Buffers::MASTER_OUT_L] = new float[ buffers.nframes ];
228 buffers.audio[Buffers::MASTER_OUT_R] = new float[ buffers.nframes ];
229
230 // Traverse tracks using the first track as offset
231 for(int track = 0; track < NTRACKS; track++) {
232 /** Setup the tracks:
233 * The TrackOutput gets a pointer to the next AudioProcessor to call:
234 * This is either a JackSendReturn (providing send and return ports)
235 * or the track's Looper instance.
236 * This is an option in luppp.prfs
237 **/
238 loopers.push_back( new Looper(track) );
239
240 tracksendreturns.push_back(new JackSendReturn(track,loopers.back(),client));
241 trackOutputs.push_back( new TrackOutput(track, tracksendreturns.back() ) );
242
243 // index = first-track + (track * channels)
244 int trackoffset = track * NCHANNELS;
245 buffers.audio[Buffers::TRACK_0_L + trackoffset] = new float[ buffers.nframes ];
246 buffers.audio[Buffers::TRACK_0_R + trackoffset] = new float[ buffers.nframes ];
247 buffers.audio[Buffers::SEND_TRACK_0_L+trackoffset]=new float[buffers.nframes];
248 buffers.audio[Buffers::SEND_TRACK_0_R+trackoffset]=new float[buffers.nframes];
249 buffers.audio[Buffers::RETURN_TRACK_0_L+trackoffset]=new float[buffers.nframes];
250 buffers.audio[Buffers::RETURN_TRACK_0_R+trackoffset]=new float[buffers.nframes];
251
252 timeManager->registerObserver( loopers.back() );
253 if(gui->enablePerTrackOutput) {
254 char name[50];
255 // Left channel
256 sprintf(name,"track_%d_l",track + 1);
257 trackJackOutputPorts[trackoffset]=jack_port_register( client,
258 name,
259 JACK_DEFAULT_AUDIO_TYPE,
260 JackPortIsOutput,
261 0 );
262 // Right channel
263 sprintf(name,"track_%d_r",track + 1);
264 trackJackOutputPorts[trackoffset+1]=jack_port_register( client,
265 name,
266 JACK_DEFAULT_AUDIO_TYPE,
267 JackPortIsOutput,
268 0 );
269
270 }
271 }
272
273 /// setup DSP instances
274 inputVol = 1.0f;
275 inputVolLag = 1.0f;
276 masterVol = 0.75f;
277 masterVolLag =0.75f;
278
279 masterMeter = new DBMeter( buffers.samplerate );
280 inputMeter = new DBMeter( buffers.samplerate );
281
282 buffers.transportPosition = 0;
283
284 /// setup JACK callbacks
285 if ( jack_set_process_callback( client,
286 static_process,
287 static_cast<void*>(this)) ) {
288 LUPPP_ERROR("%s","Error setting process callback");
289 }
290
291 if ( jack_set_timebase_callback(client,
292 0, //0, 0 == must be master, 1 == conditional
293 (JackTimebaseCallback)static_timebase,
294 static_cast<void*>(this)) ) {
295 LUPPP_ERROR("%s","Error setting timebase callback");
296 }
297
298 //Controller* m = new AkaiAPC();
299
300 // TODO: Add GUI dialog to add controllers, and insert them into the controller map.
301 // Watch out for RT stuff, loading file, registering ports etc: before activate?!
302 //Controller* m = new GenericMIDI("akai_apc.ctlr","apc");
303
304 Controller* g = new LupppGUI();
305 controllerUpdater->registerController( g );
306
307 if ( !g ) {
308 LUPPP_ERROR("%s","Error creating LupppGUI Controller instance");
309 }
310
311 // call into the GUI, telling it to register default controllers
312 gui->setupMidiControllers();
313
314 }
315
~Jack()316 Jack::~Jack()
317 {
318 delete timeManager;
319 delete metronome;
320 delete state;
321 delete logic;
322 delete gridLogic;
323 delete controllerUpdater;
324
325 delete inputMeter;
326 delete masterMeter;
327
328 // Traverse tracks using the first track as offset
329 for(int track = 0; track < NTRACKS; track++) {
330 // index = first-track + (track * channels)
331 int trackoffset = track * NCHANNELS;
332 delete [] buffers.audio[Buffers::TRACK_0_L+trackoffset];
333 delete [] buffers.audio[Buffers::TRACK_0_R+trackoffset];
334 delete [] buffers.audio[Buffers::SEND_TRACK_0_L+trackoffset];
335 delete [] buffers.audio[Buffers::SEND_TRACK_0_R+trackoffset];
336 delete [] buffers.audio[Buffers::RETURN_TRACK_0_L+trackoffset];
337 delete [] buffers.audio[Buffers::RETURN_TRACK_0_R+trackoffset];
338 delete tracksendreturns[track];
339 delete loopers[track];
340 delete trackOutputs[track];
341 }
342 }
343
activate()344 void Jack::activate()
345 {
346 jack_activate( client );
347 }
348
transportRolling(bool rolling)349 void Jack::transportRolling(bool rolling)
350 {
351 if(rolling)
352 jack_transport_start(client);
353 else
354 jack_transport_stop(client);
355 }
356
quit()357 void Jack::quit()
358 {
359 //jack_deactivate( client );
360 jack_client_close( client );
361 LUPPP_NOTE("%s","Quit JACK.");
362 }
363
getTrackOutput(int t)364 TrackOutput* Jack::getTrackOutput(int t)
365 {
366 if ( t >= 0 && t < NTRACKS )
367 return trackOutputs.at(t);
368 #ifdef DEBUG_TRACKS
369 else {
370 printf( "Jack::getTrackOutput() returning 0x0: invalid track requested!\n" );
371 }
372 #endif
373
374 return 0;
375 }
376
getJackSendReturn(int t)377 JackSendReturn* Jack::getJackSendReturn(int t)
378 {
379 if ( t >= 0 && t < NTRACKS )
380 return tracksendreturns.at(t);
381 #ifdef DEBUG_TRACKS
382 else {
383 printf( "Jack::getTrackOutput() returning 0x0: invalid track requested!\n" );
384 }
385 #endif
386
387 return 0;
388 }
389
390
getLooper(int t)391 Looper* Jack::getLooper(int t)
392 {
393 if ( t >= 0 && t < NTRACKS )
394 return loopers.at(t);
395 #ifdef DEBUG_TRACKS
396 else {
397 printf( "Jack::getLooper() returning 0x0: invalid track requested!\n" );
398 }
399 #endif
400
401 return 0;
402 }
403
404
registerMidiIO(MidiIO * mo)405 void Jack::registerMidiIO( MidiIO* mo )
406 {
407 //LUPPP_NOTE("Jack::registerMidiIO()" );
408
409 // CAREFUL : this could need to resize and cause malloc() in RT thread
410 midiIO.push_back( mo );
411 }
412
unregisterMidiIO(MidiIO * mo)413 void Jack::unregisterMidiIO( MidiIO* mo )
414 {
415 LUPPP_NOTE("Jack::unregisterMidiIO()");
416
417 // unregister the observer
418 for(unsigned int i = 0; i < midiIO.size(); i++) {
419 if ( midiIO.at(i) == mo ) {
420 cout << "removing mo at " << i << endl;
421 midiIO.erase( midiIO.begin() + i );
422 return;
423 }
424 }
425 }
426
process(jack_nframes_t nframes)427 int Jack::process (jack_nframes_t nframes)
428 {
429 /// get buffers
430 buffers.audio[Buffers::MASTER_INPUT_L] = (float*)jack_port_get_buffer( masterInputL, nframes );
431 buffers.audio[Buffers::MASTER_INPUT_R] = (float*)jack_port_get_buffer( masterInputR, nframes );
432 buffers.audio[Buffers::MASTER_RETURN_L] = (float*)jack_port_get_buffer( masterReturnL, nframes );
433 buffers.audio[Buffers::MASTER_RETURN_R] = (float*)jack_port_get_buffer( masterReturnR, nframes );
434 buffers.audio[Buffers::HEADPHONES_OUT_L] = (float*)jack_port_get_buffer( headphonesPortL, nframes );
435 buffers.audio[Buffers::HEADPHONES_OUT_R] = (float*)jack_port_get_buffer( headphonesPortR, nframes );
436
437 buffers.audio[Buffers::JACK_SEND_OUT_L] = (float*)jack_port_get_buffer( sendOutputL, nframes );
438 buffers.audio[Buffers::JACK_SEND_OUT_R] = (float*)jack_port_get_buffer( sendOutputR, nframes );
439 buffers.audio[Buffers::JACK_MASTER_OUT_L] = (float*)jack_port_get_buffer( masterOutputL, nframes );
440 buffers.audio[Buffers::JACK_MASTER_OUT_R] = (float*)jack_port_get_buffer( masterOutputR, nframes );
441 buffers.audio[Buffers::JACK_SIDECHAIN_KEY_L] = (float*)jack_port_get_buffer( sidechainKeyOutputL, nframes );
442 buffers.audio[Buffers::JACK_SIDECHAIN_KEY_R] = (float*)jack_port_get_buffer( sidechainKeyOutputR, nframes );
443 buffers.audio[Buffers::JACK_SIDECHAIN_SIGNAL_L]= (float*)jack_port_get_buffer( sidechainSignalOutputL,nframes );
444 buffers.audio[Buffers::JACK_SIDECHAIN_SIGNAL_R]= (float*)jack_port_get_buffer( sidechainSignalOutputR,nframes );
445 if(gui->enablePerTrackOutput) {
446 // Traverse tracks using the first track as offset
447 for(int track=0; track<NTRACKS; track++) {
448 // index = first-track + (track * channels)
449 int trackoffset = track * NCHANNELS;
450 buffers.audio[Buffers::JACK_TRACK_0_L+trackoffset] = (float*)jack_port_get_buffer( trackJackOutputPorts[trackoffset], nframes );
451 buffers.audio[Buffers::JACK_TRACK_0_R+trackoffset] = (float*)jack_port_get_buffer( trackJackOutputPorts[trackoffset+1], nframes );
452 }
453 }
454
455
456 // clear the buffers
457 memset( buffers.audio[Buffers::JACK_MASTER_OUT_L], 0, sizeof(float) * nframes );
458 memset( buffers.audio[Buffers::JACK_MASTER_OUT_R], 0, sizeof(float) * nframes );
459 memset( buffers.audio[Buffers::MASTER_OUT_L], 0, sizeof(float) * nframes );
460 memset( buffers.audio[Buffers::MASTER_OUT_R], 0, sizeof(float) * nframes );
461 memset( buffers.audio[Buffers::HEADPHONES_OUT_L], 0, sizeof(float) * nframes );
462 memset( buffers.audio[Buffers::HEADPHONES_OUT_R], 0, sizeof(float) * nframes );
463 memset( buffers.audio[Buffers::SEND_L], 0, sizeof(float) * nframes );
464 memset( buffers.audio[Buffers::SEND_R], 0, sizeof(float) * nframes );
465 memset( buffers.audio[Buffers::SIDECHAIN_KEY_L], 0, sizeof(float) * nframes );
466 memset( buffers.audio[Buffers::SIDECHAIN_KEY_R], 0, sizeof(float) * nframes );
467 memset( buffers.audio[Buffers::SIDECHAIN_SIGNAL_L], 0, sizeof(float) * nframes );
468 memset( buffers.audio[Buffers::SIDECHAIN_SIGNAL_R], 0, sizeof(float) * nframes );
469 if(gui->enablePerTrackOutput) {
470 // Traverse tracks using the first track as offset
471 for(int track=0; track<NTRACKS; track++) {
472 // index = first-track + (track * channels)
473 int trackoffset = track * NCHANNELS;
474 memset( buffers.audio[Buffers::JACK_TRACK_0_L+trackoffset], 0, sizeof(float) * nframes );
475 memset( buffers.audio[Buffers::JACK_TRACK_0_R+trackoffset], 0, sizeof(float) * nframes );
476 }
477 }
478
479
480 //buffers.midi [Buffers::MASTER_MIDI_INPUT] = (void*) jack_port_get_buffer( masterMidiInput, nframes );
481
482 /// init buffers for each MidiIO
483 for(unsigned int i = 0; i < midiIO.size(); i++ ) {
484 midiIO.at(i)->initBuffers( nframes );
485 }
486
487 /// do events from the ringbuffer
488 handleDspEvents();
489
490 /// process incoming MIDI
491 /*
492 jack_midi_event_t in_event;
493 int masterMidiInputIndex = 0;
494 int event_count = (int) jack_midi_get_event_count( buffers.midi[Buffers::MASTER_MIDI_INPUT] );
495 while ( masterMidiInputIndex < event_count )
496 {
497 jack_midi_event_get(&in_event, buffers.midi[Buffers::MASTER_MIDI_INPUT], masterMidiInputIndex);
498
499 char buffer [50];
500 sprintf (buffer, "MIDI %i %i %i", int(in_event.buffer[0]), int(in_event.buffer[1]), int(in_event.buffer[2]) );
501 EventGuiPrint e( buffer );
502 writeToGuiRingbuffer( &e );
503
504 masterMidiInputIndex++;
505 }
506 */
507
508 /// update "time" from JACK master, or write master?
509 buffers.transportFrame = jack_get_current_transport_frame(client);
510
511 // time manager deals with detecting bar() / beat() events, and calls
512 // processFrames() with the appropriate nframes
513 timeManager->process( &buffers );
514
515 return 0;
516 }
517
518
processFrames(int nframes)519 void Jack::processFrames(int nframes)
520 {
521 if ( nframes < 0 ) {
522 LUPPP_WARN("Jack processFrames got nframes < 0");
523 return;
524 }
525
526 /*
527 // extreme debugging of timemanager process-split functionality
528 char buffer [50];
529 sprintf (buffer, "Jack::processFrames() got %i", nframes );
530 EventGuiPrint e2( buffer );
531 writeToGuiRingbuffer( &e2 );
532 */
533
534 /// process each MidiIO registered MIDI port
535 for(unsigned int i = 0; i < midiIO.size(); i++ ) {
536 midiIO.at(i)->process( nframes );
537 }
538
539 /// process each track, starting at output and working up signal path
540 for(unsigned int i = 0; i < NTRACKS; i++) {
541 trackOutputs.at(i)->process( nframes, &buffers );
542 }
543
544 /// metro signal
545 metronome->process( nframes, &buffers );
546
547 /// mix input, reverb & post-sidechain in
548 for(unsigned int i = 0; i < nframes; i++) {
549 // compute *lags für smoothing
550 inputToMixVolLag += smoothing_value * (inputToMixVol - inputToMixVolLag);
551 inputToSendVolLag += smoothing_value * (inputToSendVol - inputToSendVolLag);
552 inputToXSideVolLag += smoothing_value * (inputToXSideVol - inputToXSideVolLag);
553 returnVolLag += smoothing_value * (returnVol - returnVolLag);
554 inputVolLag += smoothing_value * (inputVol - inputVolLag);
555
556 inputToKeyEnableLag += smoothing_value * (inputToKeyEnable - inputToKeyEnableLag);
557 inputToMixEnableLag += smoothing_value * (inputToMixEnable - inputToMixEnableLag);
558 inputToSendEnableLag += smoothing_value * (inputToSendEnable - inputToSendEnableLag);
559
560 float inputL = buffers.audio[Buffers::MASTER_INPUT_L][i] * inputVolLag;
561 float inputR = buffers.audio[Buffers::MASTER_INPUT_R][i] * inputVolLag;
562
563 float L = buffers.audio[Buffers::MASTER_OUT_L][i];
564 float R = buffers.audio[Buffers::MASTER_OUT_R][i];
565 float returnL = buffers.audio[Buffers::MASTER_RETURN_L][i];
566 float returnR = buffers.audio[Buffers::MASTER_RETURN_R][i];
567
568 // if sending to mix, scale by volume *and* by XSide send
569 float tmpL = inputL * inputToMixVolLag * inputToMixEnableLag;
570 float tmpR = inputR * inputToMixVolLag * inputToMixEnableLag;
571 L += tmpL * (1-inputToXSideVolLag);
572 R += tmpR * (1-inputToXSideVolLag);
573
574 // post-mix-send amount: hence * inputToMixVol
575 buffers.audio[Buffers::SEND_L][i] += tmpL * inputToSendVolLag * inputToSendEnableLag;
576 buffers.audio[Buffers::SEND_R][i] += tmpR * inputToSendVolLag * inputToSendEnableLag;
577
578
579 buffers.audio[Buffers::SIDECHAIN_KEY_L][i] += inputL * inputToKeyEnableLag;
580 buffers.audio[Buffers::SIDECHAIN_KEY_R][i] += inputR * inputToKeyEnableLag;
581
582
583 buffers.audio[Buffers::SIDECHAIN_SIGNAL_L][i] += inputL * inputToXSideVolLag;
584 buffers.audio[Buffers::SIDECHAIN_SIGNAL_R][i] += inputR * inputToXSideVolLag;
585
586 //compute master volume lag;
587 masterVolLag += smoothing_value * (masterVol - masterVolLag);
588 /// mixdown returns into master buffers
589 buffers.audio[Buffers::JACK_MASTER_OUT_L][i] = (L + returnL*returnVolLag) * masterVolLag;
590 buffers.audio[Buffers::JACK_MASTER_OUT_R][i] = (R + returnR*returnVolLag) * masterVolLag;
591
592 /// write SEND content to JACK port
593 buffers.audio[Buffers::JACK_SEND_OUT_L][i] = buffers.audio[Buffers::SEND_L][i];
594 buffers.audio[Buffers::JACK_SEND_OUT_R][i] = buffers.audio[Buffers::SEND_R][i];
595 buffers.audio[Buffers::JACK_SIDECHAIN_KEY_L][i] = buffers.audio[Buffers::SIDECHAIN_KEY_L][i];
596 buffers.audio[Buffers::JACK_SIDECHAIN_KEY_R][i] = buffers.audio[Buffers::SIDECHAIN_KEY_R][i];
597 buffers.audio[Buffers::JACK_SIDECHAIN_SIGNAL_L][i] = buffers.audio[Buffers::SIDECHAIN_SIGNAL_L][i];
598 buffers.audio[Buffers::JACK_SIDECHAIN_SIGNAL_R][i] = buffers.audio[Buffers::SIDECHAIN_SIGNAL_R][i];
599 }
600
601
602 /// db meter on master input & output
603 inputMeter->process( nframes, buffers.audio[Buffers::MASTER_INPUT_L], buffers.audio[Buffers::MASTER_INPUT_R]);
604 masterMeter->process(nframes, buffers.audio[Buffers::JACK_MASTER_OUT_L], buffers.audio[Buffers::JACK_MASTER_OUT_R] );
605
606 if ( uiUpdateCounter > uiUpdateConstant ) {
607 // instead of scaling whole buffer, just scale output by vol
608 EventTrackSignalLevel e(-1, masterMeter->getLeftDB(), masterMeter->getRightDB() );
609 writeToGuiRingbuffer( &e );
610 EventTrackSignalLevel e2(-2, inputMeter->getLeftDB() * inputVolLag, inputMeter->getRightDB() * inputVol );
611 writeToGuiRingbuffer( &e2 );
612
613 uiUpdateCounter = 0;
614 }
615
616 uiUpdateCounter += nframes;
617
618 /*
619 // memcpy the internal MASTER_OUTPUT buffer to the JACK_MASTER_OUTPUT
620 memcpy( buffers.audio[Buffers::JACK_MASTER_OUT_L],
621 buffers.audio[Buffers::MASTER_OUT_L],
622 sizeof(float)*nframes);
623
624 memcpy( buffers.audio[Buffers::JACK_MASTER_OUT_R],
625 buffers.audio[Buffers::MASTER_OUT_R],
626 //buffers.audio[Buffers::POST_SIDECHAIN],
627 //buffers.audio[Buffers::SEND], // uncomment to listen to reverb send only
628 sizeof(float)*nframes);
629 */
630
631 // move buffer pointers up nframes: allows processing of one "nframes" from
632 // JACK in multiple parts internally in Luppp: used for processing bar() / beat()
633 // if a full JACK nframes has been processed, this is extra work: its not that expensive
634 /// update buffers by nframes
635 if(lastnframes+nframes<buffers.nframes) {
636 lastnframes=nframes;
637 buffers.audio[Buffers::MASTER_INPUT_L] = &buffers.audio[Buffers::MASTER_INPUT_L][nframes];
638 buffers.audio[Buffers::MASTER_INPUT_R] = &buffers.audio[Buffers::MASTER_INPUT_R][nframes];
639 buffers.audio[Buffers::MASTER_RETURN_L] = &buffers.audio[Buffers::MASTER_RETURN_L][nframes];
640 buffers.audio[Buffers::MASTER_RETURN_R] = &buffers.audio[Buffers::MASTER_RETURN_R][nframes];
641 buffers.audio[Buffers::HEADPHONES_OUT_L] = &buffers.audio[Buffers::HEADPHONES_OUT_L][nframes];
642 buffers.audio[Buffers::HEADPHONES_OUT_R] = &buffers.audio[Buffers::HEADPHONES_OUT_R][nframes];
643
644 buffers.audio[Buffers::JACK_SEND_OUT_L] = &buffers.audio[Buffers::JACK_SEND_OUT_L][nframes];
645 buffers.audio[Buffers::JACK_SEND_OUT_R] = &buffers.audio[Buffers::JACK_SEND_OUT_R][nframes];
646 buffers.audio[Buffers::JACK_MASTER_OUT_L] = &buffers.audio[Buffers::JACK_MASTER_OUT_L][nframes];
647 buffers.audio[Buffers::JACK_MASTER_OUT_R] = &buffers.audio[Buffers::JACK_MASTER_OUT_R][nframes];
648 buffers.audio[Buffers::JACK_SIDECHAIN_KEY_L] = &buffers.audio[Buffers::JACK_SIDECHAIN_KEY_L][nframes];
649 buffers.audio[Buffers::JACK_SIDECHAIN_KEY_R] = &buffers.audio[Buffers::JACK_SIDECHAIN_KEY_R][nframes];
650 buffers.audio[Buffers::JACK_SIDECHAIN_SIGNAL_L]= &buffers.audio[Buffers::JACK_SIDECHAIN_SIGNAL_L][nframes];
651 buffers.audio[Buffers::JACK_SIDECHAIN_SIGNAL_R]= &buffers.audio[Buffers::JACK_SIDECHAIN_SIGNAL_R][nframes];
652 if(gui->enablePerTrackOutput) {
653 // Traverse tracks using the first track as offset
654 for(int track=0; track<NTRACKS; track++) {
655 // index = first-track + (track * channels)
656 int trackoffset = track * NCHANNELS;
657 buffers.audio[Buffers::JACK_TRACK_0_L+trackoffset] = &buffers.audio[Buffers::JACK_TRACK_0_L+trackoffset][nframes];
658 buffers.audio[Buffers::JACK_TRACK_0_R+trackoffset] = &buffers.audio[Buffers::JACK_TRACK_0_R+trackoffset][nframes];
659 }
660 }
661 } else
662 lastnframes=0;
663
664 return;
665 }
666
clearInternalBuffers(int nframes)667 void Jack::clearInternalBuffers(int nframes)
668 {
669 memset(buffers.audio[Buffers::SEND_L],0,sizeof(float)*nframes);
670 memset(buffers.audio[Buffers::SEND_R],0,sizeof(float)*nframes);
671 memset(buffers.audio[Buffers::SIDECHAIN_KEY_L],0,sizeof(float)*nframes);
672 memset(buffers.audio[Buffers::SIDECHAIN_KEY_R],0,sizeof(float)*nframes);
673 memset(buffers.audio[Buffers::SIDECHAIN_SIGNAL_L],0,sizeof(float)*nframes);
674 memset(buffers.audio[Buffers::SIDECHAIN_SIGNAL_R],0,sizeof(float)*nframes);
675 memset(buffers.audio[Buffers::MASTER_OUT_L],0,sizeof(float)*nframes);
676 memset(buffers.audio[Buffers::MASTER_OUT_R],0,sizeof(float)*nframes);
677 // Traverse tracks using the first track as offset
678 for(int track=0; track<NTRACKS; track++) {
679 // index = first-track + (track * channels)
680 int trackoffset = track * NCHANNELS;
681 memset(buffers.audio[Buffers::TRACK_0_L + trackoffset],0,sizeof(float)*nframes);
682 memset(buffers.audio[Buffers::TRACK_0_R + trackoffset],0,sizeof(float)*nframes);
683 memset(buffers.audio[Buffers::SEND_TRACK_0_L + trackoffset],0,sizeof(float)*nframes);
684 memset(buffers.audio[Buffers::SEND_TRACK_0_R + trackoffset],0,sizeof(float)*nframes);
685 memset(buffers.audio[Buffers::RETURN_TRACK_0_L + trackoffset],0,sizeof(float)*nframes);
686 memset(buffers.audio[Buffers::RETURN_TRACK_0_R + trackoffset],0,sizeof(float)*nframes);
687 }
688 }
689
masterVolume(float vol)690 void Jack::masterVolume(float vol)
691 {
692 masterVol = vol;
693 }
694
returnVolume(float vol)695 void Jack::returnVolume(float vol)
696 {
697 returnVol = vol;
698 }
699
inputVolume(float v)700 void Jack::inputVolume(float v)
701 {
702 inputVol = v * 2;
703 }
704
inputTo(INPUT_TO to,float v)705 void Jack::inputTo(INPUT_TO to, float v)
706 {
707 switch ( to ) {
708 case INPUT_TO_MIX:
709 inputToMixVol = v;
710 break;
711 case INPUT_TO_SEND:
712 inputToSendVol = v;
713 break;
714 case INPUT_TO_XSIDE:
715 inputToXSideVol = v;
716 break;
717 default:
718 break;
719 }
720 }
721
inputToActive(INPUT_TO to,bool a)722 void Jack::inputToActive(INPUT_TO to, bool a)
723 {
724 switch ( to ) {
725 case INPUT_TO_MIX:
726 inputToMixEnable = a;
727 break;
728 case INPUT_TO_SEND:
729 inputToSendEnable = a;
730 break;
731 case INPUT_TO_SIDE_KEY:
732 inputToKeyEnable = a;
733 break;
734 default:
735 break;
736 }
737 }
738
getBuffersize()739 int Jack::getBuffersize()
740 {
741 return jack_get_buffer_size( client );
742 }
743
getSamplerate()744 int Jack::getSamplerate()
745 {
746 return samplerate;
747 }
748
timebase(jack_transport_state_t state,jack_nframes_t nframes,jack_position_t * pos,int newPos)749 int Jack::timebase(jack_transport_state_t state,
750 jack_nframes_t nframes,
751 jack_position_t* pos,
752 int newPos)
753 {
754 // fill buffers with data, then pass to timeManager
755 buffers.transportPosition = pos;
756 buffers.transportState =&state;
757
758 return 0;
759 }
760
static_process(jack_nframes_t nframes,void * instance)761 int Jack::static_process(jack_nframes_t nframes, void *instance)
762 {
763 return static_cast<Jack*>(instance)->process(nframes);
764 }
765
static_timebase(jack_transport_state_t state,jack_nframes_t nframes,jack_position_t * pos,int newPos,void * instance)766 int Jack::static_timebase(jack_transport_state_t state,
767 jack_nframes_t nframes,
768 jack_position_t* pos,
769 int newPos,
770 void* instance)
771 {
772 return static_cast<Jack*>(instance)->timebase(state,nframes, pos, newPos );
773 }
774