1 /*
2 * Copyright (C) 2019-2021 Alexandros Theodotou <alex at zrythm dot org>
3 *
4 * This file is part of Zrythm
5 *
6 * Zrythm is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Affero General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * Zrythm is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Affero General Public License for more details.
15 *
16 * You should have received a copy of the GNU Affero General Public License
17 * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20 #include "zrythm-config.h"
21
22 #include "audio/audio_region.h"
23 #include "audio/audio_track.h"
24 #include "audio/channel.h"
25 #include "audio/clip.h"
26 #include "audio/control_port.h"
27 #include "audio/control_room.h"
28 #include "audio/engine.h"
29 #include "audio/fader.h"
30 #include "audio/midi_event.h"
31 #include "audio/midi_mapping.h"
32 #include "audio/midi_track.h"
33 #include "audio/recording_manager.h"
34 #include "audio/track.h"
35 #include "project.h"
36 #include "settings/settings.h"
37 #include "utils/arrays.h"
38 #include "utils/dsp.h"
39 #include "utils/flags.h"
40 #include "utils/math.h"
41 #include "utils/mem.h"
42 #include "utils/objects.h"
43 #include "zrythm.h"
44
45 #include <glib/gi18n.h>
46
47 static void
init_common(TrackProcessor * self)48 init_common (
49 TrackProcessor * self)
50 {
51 if (self->midi_cc[0])
52 {
53 self->cc_mappings = midi_mappings_new ();
54
55 for (size_t i = 0; i < 16; i++)
56 {
57 for (size_t j = 0; j < 128; j++)
58 {
59 Port * cc_port =
60 self->midi_cc[i * 128 + j];
61 g_return_if_fail (cc_port);
62
63 /* set model bytes for CC:
64 * [0] = ctrl change + channel
65 * [1] = controller
66 * [2] (unused) = control */
67 midi_byte_t buf[3];
68 buf[0] =
69 (midi_byte_t)
70 (MIDI_CH1_CTRL_CHANGE | (midi_byte_t) i);
71 buf[1] = (midi_byte_t) j;
72 buf[2] = 0;
73
74 /* bind */
75 midi_mappings_bind_track (
76 self->cc_mappings, buf,
77 cc_port, F_NO_PUBLISH_EVENTS);
78 }
79 }
80 }
81 }
82
83 /**
84 * Inits fader after a project is loaded.
85 */
86 void
track_processor_init_loaded(TrackProcessor * self,Track * track)87 track_processor_init_loaded (
88 TrackProcessor * self,
89 Track * track)
90 {
91 self->magic = TRACK_PROCESSOR_MAGIC;
92 self->track = track;
93
94 GPtrArray * ports = g_ptr_array_new ();
95 track_processor_append_ports (self, ports);
96 for (size_t i = 0; i < ports->len; i++)
97 {
98 Port * port = g_ptr_array_index (ports, i);
99 port_init_loaded (port, self);
100 }
101 object_free_w_func_and_null (
102 g_ptr_array_unref, ports)
103
104 init_common (self);
105 }
106
107 /**
108 * Inits the MIDI In port of the Channel while
109 * exposing it to JACK.
110 *
111 * This assumes the caller already checked that
112 * this channel should have the given MIDI port
113 * enabled.
114 *
115 * @param in 1 for input, 0 for output.
116 * @param loading 1 if loading a channel, 0 if
117 * new.
118 */
119 static void
init_midi_port(TrackProcessor * self,int in)120 init_midi_port (
121 TrackProcessor * self,
122 int in)
123 {
124 if (in)
125 {
126 self->midi_in =
127 port_new_with_type_and_owner (
128 TYPE_EVENT, FLOW_INPUT, "TP MIDI in",
129 PORT_OWNER_TYPE_TRACK_PROCESSOR, self);
130 g_warn_if_fail (IS_PORT (self->midi_in));
131 self->midi_in->id.flags |=
132 PORT_FLAG_SEND_RECEIVABLE;
133 }
134 else
135 {
136 self->midi_out =
137 port_new_with_type_and_owner (
138 TYPE_EVENT, FLOW_OUTPUT, "TP MIDI out",
139 PORT_OWNER_TYPE_TRACK_PROCESSOR, self);
140 g_warn_if_fail (IS_PORT (self->midi_out));
141 }
142 }
143
144 static void
init_midi_cc_ports(TrackProcessor * self,int loading)145 init_midi_cc_ports (
146 TrackProcessor * self,
147 int loading)
148 {
149 #define INIT_MIDI_PORT(x,idx) \
150 x->id.flags |= PORT_FLAG_MIDI_AUTOMATABLE; \
151 x->id.flags |= PORT_FLAG_AUTOMATABLE; \
152 x->id.port_index = idx; \
153
154 char name[400];
155 for (int i = 0; i < 16; i++)
156 {
157 /* starting from 1 */
158 int channel = i + 1;
159
160 for (int j = 0; j < 128; j++)
161 {
162 sprintf (
163 name, "Ch%d %s", channel,
164 midi_get_cc_name (j));
165 Port * cc =
166 port_new_with_type_and_owner (
167 TYPE_CONTROL, FLOW_INPUT, name,
168 PORT_OWNER_TYPE_TRACK_PROCESSOR,
169 self);
170 INIT_MIDI_PORT (cc, i * 128 + j);
171 self->midi_cc[i * 128 + j] = cc;
172 }
173
174 sprintf (
175 name, "Ch%d Pitch bend", i + 1);
176 Port * cc =
177 port_new_with_type_and_owner (
178 TYPE_CONTROL, FLOW_INPUT, name,
179 PORT_OWNER_TYPE_TRACK_PROCESSOR, self);
180 INIT_MIDI_PORT (cc, i);
181 cc->maxf = 8191.f;
182 cc->minf = -8192.f;
183 cc->deff = 0.f;
184 cc->zerof = 0.f;
185 cc->id.flags2 |= PORT_FLAG2_MIDI_PITCH_BEND;
186 self->pitch_bend[i] = cc;
187
188 sprintf (
189 name, "Ch%d Poly key pressure", i + 1);
190 cc =
191 port_new_with_type_and_owner (
192 TYPE_CONTROL, FLOW_INPUT, name,
193 PORT_OWNER_TYPE_TRACK_PROCESSOR, self);
194 INIT_MIDI_PORT (cc, i);
195 cc->id.flags2 |=
196 PORT_FLAG2_MIDI_POLY_KEY_PRESSURE;
197 self->poly_key_pressure[i] = cc;
198
199 sprintf (
200 name, "Ch%d Channel pressure", i + 1);
201 cc =
202 port_new_with_type_and_owner (
203 TYPE_CONTROL, FLOW_INPUT, name,
204 PORT_OWNER_TYPE_TRACK_PROCESSOR, self);
205 INIT_MIDI_PORT (cc, i);
206 cc->id.flags2 |=
207 PORT_FLAG2_MIDI_CHANNEL_PRESSURE;
208 self->channel_pressure[i] = cc;
209 }
210
211 #undef INIT_MIDI_PORT
212 }
213
214 /**
215 * Inits the stereo ports of the Channel while
216 * exposing them to the backend.
217 *
218 * This assumes the caller already checked that
219 * this channel should have the given ports
220 * enabled.
221 *
222 * @param in 1 for input, 0 for output.
223 * @param loading 1 if loading a channel, 0 if
224 * new.
225 */
226 static void
init_stereo_out_ports(TrackProcessor * self,bool in)227 init_stereo_out_ports (
228 TrackProcessor * self,
229 bool in)
230 {
231 Port * l, * r;
232 StereoPorts ** sp =
233 in ? &self->stereo_in : &self->stereo_out;
234 PortFlow flow = in ? FLOW_INPUT : FLOW_OUTPUT;
235
236 l =
237 port_new_with_type_and_owner (
238 TYPE_AUDIO, flow,
239 in ? "TP Stereo in L" : "TP Stereo out L",
240 PORT_OWNER_TYPE_TRACK_PROCESSOR, self);
241
242 r =
243 port_new_with_type_and_owner (
244 TYPE_AUDIO, flow,
245 in ? "TP Stereo in R" : "TP Stereo out R",
246 PORT_OWNER_TYPE_TRACK_PROCESSOR, self);
247
248 *sp = stereo_ports_new_from_existing (l, r);
249
250 if (in)
251 {
252 l->id.flags |= PORT_FLAG_SEND_RECEIVABLE;
253 r->id.flags |= PORT_FLAG_SEND_RECEIVABLE;
254 }
255 }
256
257 /**
258 * Creates a new track processor for the given
259 * track.
260 */
261 TrackProcessor *
track_processor_new(Track * tr)262 track_processor_new (
263 Track * tr)
264 {
265 TrackProcessor * self =
266 object_new (TrackProcessor);
267 self->schema_version =
268 TRACK_PROCESSOR_SCHEMA_VERSION;
269 self->magic = TRACK_PROCESSOR_MAGIC;
270 self->track = tr;
271
272 self->l_port_db = 0.f;
273 self->r_port_db = 0.f;
274
275 switch (tr->in_signal_type)
276 {
277 case TYPE_EVENT:
278 init_midi_port (self, 0);
279 init_midi_port (self, 1);
280
281 /* set up piano roll port */
282 if (track_type_has_piano_roll (tr->type) ||
283 tr->type == TRACK_TYPE_CHORD)
284 {
285 self->piano_roll =
286 port_new_with_type_and_owner (
287 TYPE_EVENT, FLOW_INPUT,
288 "TP Piano Roll",
289 PORT_OWNER_TYPE_TRACK_PROCESSOR,
290 self);
291 self->piano_roll->id.flags =
292 PORT_FLAG_PIANO_ROLL;
293 if (tr->type != TRACK_TYPE_CHORD)
294 {
295 init_midi_cc_ports (self, false);
296 }
297 }
298 break;
299 case TYPE_AUDIO:
300 init_stereo_out_ports (self, false);
301 init_stereo_out_ports (self, true);
302 if (tr->type == TRACK_TYPE_AUDIO)
303 {
304 self->mono =
305 port_new_with_type_and_owner (
306 TYPE_CONTROL, FLOW_INPUT,
307 "TP Mono Toggle",
308 PORT_OWNER_TYPE_TRACK_PROCESSOR,
309 self);
310 self->mono->id.flags |= PORT_FLAG_TOGGLE;
311 self->mono->id.flags |= PORT_FLAG_TP_MONO;
312 self->input_gain =
313 port_new_with_type_and_owner (
314 TYPE_CONTROL, FLOW_INPUT,
315 "TP Input Gain",
316 PORT_OWNER_TYPE_TRACK_PROCESSOR,
317 self);
318 self->input_gain->minf = 0.f;
319 self->input_gain->maxf = 4.f;
320 self->input_gain->zerof = 0.f;
321 self->input_gain->deff = 1.f;
322 self->input_gain->id.flags |=
323 PORT_FLAG_TP_INPUT_GAIN;
324 port_set_control_value (
325 self->input_gain, 1.f, F_NOT_NORMALIZED,
326 F_NO_PUBLISH_EVENTS);
327 }
328 break;
329 default:
330 break;
331 }
332
333 if (tr->type == TRACK_TYPE_AUDIO)
334 {
335 self->output_gain =
336 port_new_with_type_and_owner (
337 TYPE_CONTROL, FLOW_INPUT,
338 "TP Output Gain",
339 PORT_OWNER_TYPE_TRACK_PROCESSOR, self);
340 self->output_gain->minf = 0.f;
341 self->output_gain->maxf = 4.f;
342 self->output_gain->zerof = 0.f;
343 self->output_gain->deff = 1.f;
344 self->output_gain->id.flags2 |=
345 PORT_FLAG2_TP_OUTPUT_GAIN;
346 port_set_control_value (
347 self->output_gain, 1.f, F_NOT_NORMALIZED,
348 F_NO_PUBLISH_EVENTS);
349
350 self->monitor_audio =
351 port_new_with_type_and_owner (
352 TYPE_CONTROL, FLOW_INPUT,
353 "Monitor audio",
354 PORT_OWNER_TYPE_TRACK_PROCESSOR, self);
355 self->monitor_audio->id.flags |=
356 PORT_FLAG_TOGGLE;
357 self->monitor_audio->id.flags2 |=
358 PORT_FLAG2_TP_MONITOR_AUDIO;
359 port_set_control_value (
360 self->monitor_audio, 0.f, F_NOT_NORMALIZED,
361 F_NO_PUBLISH_EVENTS);
362 }
363
364 init_common (self);
365
366 return self;
367 }
368
369 void
track_processor_append_ports(TrackProcessor * self,GPtrArray * ports)370 track_processor_append_ports (
371 TrackProcessor * self,
372 GPtrArray * ports)
373 {
374 #define _ADD(port) \
375 g_warn_if_fail (port); \
376 g_ptr_array_add (ports, port)
377
378 if (self->stereo_in)
379 {
380 _ADD (self->stereo_in->l);
381 _ADD (self->stereo_in->r);
382 }
383 if (self->mono)
384 {
385 _ADD (self->mono);
386 }
387 if (self->input_gain)
388 {
389 _ADD (self->input_gain);
390 }
391 if (self->output_gain)
392 {
393 _ADD (self->output_gain);
394 }
395 if (self->monitor_audio)
396 {
397 _ADD (self->monitor_audio);
398 }
399 if (self->stereo_out)
400 {
401 _ADD (self->stereo_out->l);
402 _ADD (self->stereo_out->r);
403 }
404 if (self->midi_in)
405 {
406 _ADD (self->midi_in);
407 }
408 if (self->midi_out)
409 {
410 _ADD (self->midi_out);
411 }
412 if (self->piano_roll)
413 {
414 _ADD (self->piano_roll);
415 }
416 for (int i = 0; i < 16; i++)
417 {
418 for (int j = 0; j < 128; j++)
419 {
420 if (self->midi_cc[i * 128 + j])
421 {
422 _ADD (self->midi_cc[i * 128 + j]);
423 }
424 }
425 if (self->pitch_bend[i])
426 {
427 _ADD (self->pitch_bend[i]);
428 }
429 if (self->poly_key_pressure[i])
430 {
431 _ADD (self->poly_key_pressure[i]);
432 }
433 if (self->channel_pressure[i])
434 {
435 _ADD (self->channel_pressure[i]);
436 }
437 }
438 }
439
440 /**
441 * Clears all buffers.
442 */
443 void
track_processor_clear_buffers(TrackProcessor * self)444 track_processor_clear_buffers (
445 TrackProcessor * self)
446 {
447 /*Track * track =*/
448 /*track_processor_get_track (self);*/
449
450 if (self->stereo_in)
451 {
452 port_clear_buffer (self->stereo_in->l);
453 port_clear_buffer (self->stereo_in->r);
454 }
455 if (self->stereo_out)
456 {
457 port_clear_buffer (self->stereo_out->l);
458 port_clear_buffer (self->stereo_out->r);
459 }
460 if (self->midi_in)
461 {
462 port_clear_buffer (self->midi_in);
463 }
464 if (self->midi_out)
465 {
466 port_clear_buffer (self->midi_out);
467 }
468 if (self->piano_roll)
469 {
470 port_clear_buffer (self->piano_roll);
471 }
472 }
473
474 /**
475 * Disconnects all ports connected to the
476 * TrackProcessor.
477 */
478 void
track_processor_disconnect_all(TrackProcessor * self)479 track_processor_disconnect_all (
480 TrackProcessor * self)
481 {
482 Track * track =
483 track_processor_get_track (self);
484 g_return_if_fail (track);
485
486 switch (track->in_signal_type)
487 {
488 case TYPE_AUDIO:
489 port_disconnect_all (self->mono);
490 port_disconnect_all (self->input_gain);
491 port_disconnect_all (self->output_gain);
492 port_disconnect_all (self->monitor_audio);
493 port_disconnect_all (self->stereo_in->l);
494 port_disconnect_all (self->stereo_in->r);
495 port_disconnect_all (self->stereo_out->l);
496 port_disconnect_all (self->stereo_out->r);
497 break;
498 case TYPE_EVENT:
499 port_disconnect_all (self->midi_in);
500 port_disconnect_all (self->midi_out);
501 if (track_type_has_piano_roll (track->type))
502 port_disconnect_all (self->piano_roll);
503 break;
504 default:
505 break;
506 }
507 }
508
509 Track *
track_processor_get_track(const TrackProcessor * self)510 track_processor_get_track (
511 const TrackProcessor * self)
512 {
513 g_return_val_if_fail (
514 IS_TRACK_PROCESSOR (self) &&
515 IS_TRACK (self->track), NULL);
516
517 return self->track;
518 }
519
520 /**
521 * Splits the cycle and handles recording for each
522 * slot.
523 */
524 static void
handle_recording(const TrackProcessor * self,const EngineProcessTimeInfo * const time_nfo)525 handle_recording (
526 const TrackProcessor * self,
527 const EngineProcessTimeInfo * const time_nfo)
528 {
529 #if 0
530 g_message ("handle recording %ld %" PRIu32,
531 g_start_frames, nframes);
532 #endif
533
534 long split_points[6];
535 long each_nframes[6];
536 int num_split_points = 1;
537
538 long start_frames = time_nfo->g_start_frames;
539 long end_frames =
540 start_frames + time_nfo->nframes;
541
542 /* split the cycle at loop and punch points and
543 * record */
544 bool loop_hit = false;
545 bool punch_in_hit = false;
546 /*bool punch_out_hit = false;*/
547 /*int loop_end_idx = -1;*/
548 split_points[0] = start_frames;
549 each_nframes[0] = time_nfo->nframes;
550 if (TRANSPORT->loop)
551 {
552 if (TRANSPORT->loop_end_pos.frames ==
553 end_frames)
554 {
555 loop_hit = true;
556 num_split_points = 3;
557
558 /* adjust start slot until loop end */
559 each_nframes[0] =
560 TRANSPORT->loop_end_pos.frames -
561 start_frames;
562 /*loop_end_idx = 0;*/
563
564 /* add loop end pause */
565 split_points[1] =
566 TRANSPORT->loop_end_pos.frames;
567 each_nframes[1] = 0;
568
569 /* add part after looping */
570 split_points[2] =
571 TRANSPORT->loop_start_pos.frames;
572 each_nframes[2] =
573 time_nfo->nframes - each_nframes[0];
574 }
575 }
576 if (TRANSPORT->punch_mode)
577 {
578 if (loop_hit)
579 {
580 /* before loop */
581 if (position_between_frames_excl2 (
582 &TRANSPORT->punch_in_pos,
583 start_frames,
584 TRANSPORT->loop_end_pos.frames))
585 {
586 punch_in_hit = true;
587 num_split_points = 4;
588
589 /* move loop start to next slot */
590 each_nframes[3] = each_nframes[2];
591 split_points[3] = split_points[2];
592 each_nframes[2] = each_nframes[1];
593 split_points[2] = split_points[1];
594
595 /* add punch in pos */
596 split_points[1] =
597 TRANSPORT->punch_in_pos.frames;
598 each_nframes[1] =
599 TRANSPORT->loop_end_pos.frames -
600 TRANSPORT->punch_in_pos.frames;
601 /*loop_end_idx = 1;*/
602
603 /* adjust num frames for initial
604 * pos */
605 each_nframes[0] -= each_nframes[1];
606 }
607 if (position_between_frames_excl2 (
608 &TRANSPORT->punch_out_pos,
609 start_frames,
610 TRANSPORT->loop_end_pos.frames))
611 {
612 /*punch_out_hit = true;*/
613 if (punch_in_hit)
614 {
615 num_split_points = 6;
616
617 /* move loop start to next slot */
618 each_nframes[5] = each_nframes[3];
619 split_points[5] = split_points[3];
620 each_nframes[4] = each_nframes[2];
621 split_points[4] = split_points[2];
622
623 /* add punch out pos */
624 split_points[2] =
625 TRANSPORT->punch_out_pos.frames;
626 each_nframes[2] =
627 TRANSPORT->loop_end_pos.frames -
628 TRANSPORT->punch_out_pos.frames;
629
630 /* add pause */
631 split_points[3] =
632 split_points[2] +
633 each_nframes[2];
634 each_nframes[3] = 0;
635 /*loop_end_idx = 2;*/
636
637 /* adjust num frames for punch in
638 * pos */
639 each_nframes[1] -= each_nframes[2];
640 }
641 else
642 {
643 num_split_points = 5;
644
645 /* move loop start to next slot */
646 each_nframes[4] = each_nframes[2];
647 split_points[4] = split_points[2];
648 each_nframes[3] = each_nframes[1];
649 split_points[3] = split_points[1];
650
651 /* add punch out pos */
652 split_points[1] =
653 TRANSPORT->punch_out_pos.frames;
654 each_nframes[1] =
655 TRANSPORT->loop_end_pos.frames -
656 TRANSPORT->punch_out_pos.frames;
657 /*loop_end_idx = 1;*/
658
659 /* add pause */
660 split_points[2] =
661 split_points[1] +
662 each_nframes[1];
663 each_nframes[2] = 0;
664
665 /* adjust num frames for init
666 * pos */
667 each_nframes[0] -= each_nframes[1];
668 }
669 }
670 }
671 else /* loop not hit */
672 {
673 if (position_between_frames_excl2 (
674 &TRANSPORT->punch_in_pos,
675 start_frames, end_frames))
676 {
677 punch_in_hit = true;
678 num_split_points = 2;
679
680 /* add punch in pos */
681 split_points[1] =
682 TRANSPORT->punch_in_pos.frames;
683 each_nframes[1] =
684 end_frames -
685 TRANSPORT->punch_in_pos.frames;
686
687 /* adjust num frames for initial
688 * pos */
689 each_nframes[0] -= each_nframes[1];
690 }
691 if (position_between_frames_excl2 (
692 &TRANSPORT->punch_out_pos,
693 start_frames, end_frames))
694 {
695 /*punch_out_hit = true;*/
696 if (punch_in_hit)
697 {
698 num_split_points = 4;
699
700 /* add punch out pos */
701 split_points[2] =
702 TRANSPORT->punch_out_pos.frames;
703 each_nframes[2] =
704 end_frames -
705 TRANSPORT->punch_out_pos.frames;
706
707 /* add pause */
708 split_points[3] =
709 split_points[2] +
710 each_nframes[2];
711 each_nframes[3] = 0;
712
713 /* adjust num frames for punch in
714 * pos */
715 each_nframes[1] -= each_nframes[2];
716 }
717 else
718 {
719 num_split_points = 3;
720
721 /* add punch out pos */
722 split_points[1] =
723 TRANSPORT->punch_out_pos.frames;
724 each_nframes[1] =
725 end_frames -
726 TRANSPORT->punch_out_pos.frames;
727
728 /* add pause */
729 split_points[2] =
730 split_points[1] +
731 each_nframes[1];
732 each_nframes[2] = 0;
733
734 /* adjust num frames for init
735 * pos */
736 each_nframes[0] -=
737 each_nframes[1];
738 }
739 }
740 }
741 }
742
743 long split_point = -1;
744 /*bool is_loop_end_idx = false;*/
745 for (int i = 0; i < num_split_points; i++)
746 {
747 g_warn_if_fail (
748 split_points[i] >= 0 &&
749 each_nframes[i] >= 0);
750
751 /* skip if same as previous point */
752 if (split_points[i] == split_point)
753 continue;
754
755 split_point = split_points[i];
756
757 /*is_loop_end_idx =*/
758 /*loop_hit && i == loop_end_idx;*/
759
760 #if 0
761 g_message ("sending %ld for %ld frames",
762 split_point, each_nframes[i]);
763 #endif
764
765 EngineProcessTimeInfo cur_time_nfo = {
766 .g_start_frames = split_point,
767 .local_offset = 0,
768 .nframes = each_nframes[i], };
769 recording_manager_handle_recording (
770 RECORDING_MANAGER, self, &cur_time_nfo);
771 }
772 }
773
774 /**
775 * Adds events to midi out based on any changes in
776 * MIDI CC control ports.
777 */
778 static inline void
add_events_from_midi_cc_control_ports(const TrackProcessor * self,const nframes_t local_offset)779 add_events_from_midi_cc_control_ports (
780 const TrackProcessor * self,
781 const nframes_t local_offset)
782 {
783 /* FIXME optimize (use caches) */
784 for (int i = 0; i < 16; i++)
785 {
786 /* starting from 1 */
787 int channel = i + 1;
788 Port * cc = NULL;
789 int offset = i * 128;
790 for (int j = 0; j < 128; j++)
791 {
792 cc = self->midi_cc[offset + j];
793 if (G_LIKELY (
794 math_floats_equal (
795 cc->last_sent_control,
796 cc->control)))
797 continue;
798
799 midi_events_add_control_change (
800 self->midi_out->midi_events,
801 channel, (midi_byte_t) j,
802 math_round_float_to_type (
803 cc->control * 127.f, midi_byte_t),
804 local_offset, false);
805 cc->last_sent_control = cc->control;
806 }
807
808 cc = self->pitch_bend[i];
809 if (!math_floats_equal (
810 cc->last_sent_control, cc->control))
811 {
812 midi_events_add_pitchbend (
813 self->midi_out->midi_events,
814 channel,
815 math_round_float_to_int (cc->control),
816 local_offset, false);
817 cc->last_sent_control = cc->control;
818 }
819
820 /* TODO */
821 #if 0
822 cc = self->poly_key_pressure[i];
823 midi_events_add_pitchbend (
824 self->midi_out->midi_events,
825 channel,
826 math_round_float_to_int (cc->control),
827 local_offset, false);
828 cc->last_sent_control = cc->control;
829
830 cc = self->channel_pressure[i];
831 midi_events_add_pitchbend (
832 self->midi_out->midi_events,
833 channel,
834 math_round_float_to_int (cc->control),
835 local_offset, false);
836 cc->last_sent_control = cc->control;
837 #endif
838 }
839 }
840
841 /**
842 * Process the TrackProcessor.
843 *
844 * This function performs the following:
845 * - produce output audio/MIDI into stereo out or
846 * midi out, based on any audio/MIDI regions,
847 * if has piano roll or is audio track
848 * - produce additional output MIDI events based on
849 * any MIDI CC automation regions, if applicable
850 * - change MIDI CC control port values based on any
851 * MIDI input, if recording
852 * --- at this point the output is ready ---
853 * - handle recording (create events in regions and
854 * automation, including MIDI CC automation,
855 * based on the MIDI CC control ports)
856 *
857 * @param g_start_frames The global start frames.
858 * @param local_offset The local start frames.
859 * @param nframes The number of frames to process.
860 */
861 void
track_processor_process(const TrackProcessor * self,const EngineProcessTimeInfo * const time_nfo)862 track_processor_process (
863 const TrackProcessor * self,
864 const EngineProcessTimeInfo * const time_nfo)
865 {
866 #define g_start_frames (time_nfo->g_start_frames)
867 #define local_offset (time_nfo->local_offset)
868 #define nframes (time_nfo->nframes)
869
870 Track * tr = track_processor_get_track (self);
871 g_return_if_fail (tr);
872
873 /* if frozen or disabled, skip */
874 if (tr->frozen || !track_is_enabled (tr))
875 {
876 return;
877 }
878
879 /* set the audio clip contents to stereo out */
880 if (tr->type == TRACK_TYPE_AUDIO)
881 {
882 track_fill_events (
883 tr, time_nfo, NULL, self->stereo_out);
884 }
885
886 /* set the piano roll contents to midi out */
887 if (track_type_has_piano_roll (tr->type) ||
888 tr->type == TRACK_TYPE_CHORD)
889 {
890 Port * pr = self->piano_roll;
891
892 /* panic MIDI if necessary */
893 if (g_atomic_int_get (
894 &AUDIO_ENGINE->panic))
895 {
896 midi_events_panic (
897 pr->midi_events, 1);
898 }
899 /* get events from track if playing */
900 else if (TRANSPORT->play_state ==
901 PLAYSTATE_ROLLING ||
902 track_is_auditioner (tr))
903 {
904 /* fill midi events from piano roll
905 * data */
906 #if 0
907 g_message (
908 "filling midi events for %s from %ld",
909 tr->name, g_start_frames);
910 #endif
911 track_fill_events (
912 tr, time_nfo, pr->midi_events, NULL);
913 }
914 midi_events_dequeue (pr->midi_events);
915 #if 0
916 if (pr->midi_events->num_events > 0)
917 {
918 g_message (
919 "%s piano roll has %d events",
920 tr->name,
921 pr->midi_events->num_events);
922 }
923 #endif
924
925 /* append midi events from modwheel and
926 * pitchbend control ports to MIDI out */
927 if (tr->type != TRACK_TYPE_CHORD)
928 {
929 add_events_from_midi_cc_control_ports (
930 self, local_offset);
931 }
932 if (self->midi_out->midi_events->num_events > 0)
933 {
934 #if 0
935 g_debug (
936 "%s midi processor out has %d events",
937 tr->name,
938 self->midi_out->midi_events->num_events);
939 #endif
940 }
941
942 /* append the midi events from piano roll to
943 * MIDI out */
944 midi_events_append (
945 pr->midi_events,
946 self->midi_out->midi_events, local_offset,
947 nframes, false);
948
949 #if 0
950 if (pr->midi_events->num_events > 0)
951 {
952 g_message ("PR");
953 midi_events_print (
954 pr->midi_events, F_NOT_QUEUED);
955 }
956
957 if (self->midi_out->midi_events->num_events >
958 0)
959 {
960 g_message ("midi out");
961 midi_events_print (
962 self->midi_out->midi_events,
963 F_NOT_QUEUED);
964 }
965 #endif
966 } /* if has piano roll or is chord track */
967
968 /* if currently active track on the piano roll,
969 * fetch events */
970 if (tr->in_signal_type == TYPE_EVENT
971 && CLIP_EDITOR->has_region)
972 {
973 Track * clip_editor_track =
974 clip_editor_get_track (CLIP_EDITOR);
975 if (clip_editor_track == tr)
976 {
977 /* if not set to "all channels",
978 * filter-append */
979 if (!tr->channel->all_midi_channels)
980 {
981 midi_events_append_w_filter (
982 AUDIO_ENGINE->
983 midi_editor_manual_press->
984 midi_events,
985 self->midi_in->midi_events,
986 tr->channel->midi_channels,
987 local_offset,
988 nframes, F_NOT_QUEUED);
989 }
990 /* otherwise append normally */
991 else
992 {
993 midi_events_append (
994 AUDIO_ENGINE->
995 midi_editor_manual_press->
996 midi_events,
997 self->midi_in->midi_events,
998 local_offset, nframes,
999 F_NOT_QUEUED);
1000 }
1001 }
1002 }
1003
1004 /* add inputs to outputs */
1005 switch (tr->in_signal_type)
1006 {
1007 case TYPE_AUDIO:
1008 if (tr->type != TRACK_TYPE_AUDIO ||
1009 (tr->type == TRACK_TYPE_AUDIO &&
1010 control_port_is_toggled (
1011 self->monitor_audio)))
1012 {
1013 dsp_mix2 (
1014 &self->stereo_out->l->buf[local_offset],
1015 &self->stereo_in->l->buf[local_offset],
1016 1.f,
1017 self->input_gain ?
1018 self->input_gain->control : 1.f,
1019 nframes);
1020
1021 if (self->mono &&
1022 control_port_is_toggled (self->mono))
1023 {
1024 dsp_mix2 (
1025 &self->stereo_out->r->buf[local_offset],
1026 &self->stereo_in->l->buf[local_offset],
1027 1.f,
1028 self->input_gain ?
1029 self->input_gain->control : 1.f,
1030 nframes);
1031 }
1032 else
1033 {
1034 dsp_mix2 (
1035 &self->stereo_out->r->buf[local_offset],
1036 &self->stereo_in->r->buf[local_offset],
1037 1.f,
1038 self->input_gain ?
1039 self->input_gain->control : 1.f,
1040 nframes);
1041 }
1042 }
1043 break;
1044 case TYPE_EVENT:
1045 /* change the MIDI channel on the midi input
1046 * to the channel set on the track */
1047 if (!tr->passthrough_midi_input)
1048 {
1049 midi_events_set_channel (
1050 self->midi_in->midi_events, 0,
1051 tr->midi_ch);
1052 }
1053
1054 /* process midi bindings */
1055 if (self->cc_mappings && TRANSPORT->recording)
1056 {
1057 midi_mappings_apply_from_cc_events (
1058 self->cc_mappings,
1059 self->midi_in->midi_events,
1060 F_NOT_QUEUED);
1061 }
1062
1063 midi_events_append (
1064 self->midi_in->midi_events,
1065 self->midi_out->midi_events, local_offset,
1066 nframes, F_NOT_QUEUED);
1067 break;
1068 default:
1069 break;
1070 }
1071
1072 if (!track_is_auditioner (tr)
1073 && TRANSPORT->preroll_frames_remaining == 0
1074 &&
1075 (track_type_can_record (tr->type)
1076 || tr->automation_tracklist.num_ats > 0))
1077 {
1078 /* handle recording. this will only create
1079 * events in regions. it will not copy the
1080 * input content to the output ports.
1081 * this will also create automation for MIDI
1082 * CC, if any (see
1083 * midi_mappings_apply_cc_events above) */
1084 handle_recording (self, time_nfo);
1085 }
1086
1087 /* apply output gain */
1088 if (tr->type == TRACK_TYPE_AUDIO)
1089 {
1090 dsp_mul_k2 (
1091 &self->stereo_out->l->buf[local_offset],
1092 self->output_gain->control, nframes);
1093 dsp_mul_k2 (
1094 &self->stereo_out->r->buf[local_offset],
1095 self->output_gain->control, nframes);
1096 }
1097
1098 #undef g_start_frames
1099 #undef local_offset
1100 #undef nframes
1101 }
1102
1103 /**
1104 * Copy port values from \ref src to \ref dest.
1105 */
1106 void
track_processor_copy_values(TrackProcessor * dest,TrackProcessor * src)1107 track_processor_copy_values (
1108 TrackProcessor * dest,
1109 TrackProcessor * src)
1110 {
1111 if (src->input_gain)
1112 {
1113 dest->input_gain->control =
1114 src->input_gain->control;
1115 }
1116 if (src->monitor_audio)
1117 {
1118 dest->monitor_audio->control =
1119 src->monitor_audio->control;
1120 }
1121 if (src->output_gain)
1122 {
1123 dest->output_gain->control =
1124 src->output_gain->control;
1125 }
1126 if (src->mono)
1127 {
1128 dest->mono->control = src->mono->control;
1129 }
1130 }
1131
1132 /**
1133 * Disconnect stereo in ports from the fader.
1134 *
1135 * Used when there is no plugin in the channel.
1136 */
1137 void
track_processor_disconnect_from_prefader(TrackProcessor * self)1138 track_processor_disconnect_from_prefader (
1139 TrackProcessor * self)
1140 {
1141 Track * tr = track_processor_get_track (self);
1142 g_return_if_fail (IS_TRACK_AND_NONNULL (tr));
1143
1144 Fader * prefader = tr->channel->prefader;
1145 switch (tr->in_signal_type)
1146 {
1147 case TYPE_AUDIO:
1148 if (tr->out_signal_type == TYPE_AUDIO)
1149 {
1150 port_disconnect (
1151 self->stereo_out->l,
1152 prefader->stereo_in->l);
1153 port_disconnect (
1154 self->stereo_out->r,
1155 prefader->stereo_in->r);
1156 }
1157 break;
1158 case TYPE_EVENT:
1159 if (tr->out_signal_type == TYPE_EVENT)
1160 {
1161 port_disconnect (
1162 self->midi_out, prefader->midi_in);
1163 }
1164 break;
1165 default:
1166 break;
1167 }
1168 }
1169
1170 /**
1171 * Connects the TrackProcessor's stereo out ports to
1172 * the Channel's prefader in ports.
1173 *
1174 * Used when deleting the only plugin left.
1175 */
1176 void
track_processor_connect_to_prefader(TrackProcessor * self)1177 track_processor_connect_to_prefader (
1178 TrackProcessor * self)
1179 {
1180 Track * tr = track_processor_get_track (self);
1181 g_return_if_fail (IS_TRACK_AND_NONNULL (tr));
1182
1183 Fader * prefader = tr->channel->prefader;
1184 g_return_if_fail (IS_FADER (prefader));
1185
1186 /* connect only if signals match */
1187 if (tr->in_signal_type == TYPE_AUDIO &&
1188 tr->out_signal_type == TYPE_AUDIO)
1189 {
1190 port_connect (
1191 self->stereo_out->l,
1192 prefader->stereo_in->l, 1);
1193 port_connect (
1194 self->stereo_out->r,
1195 prefader->stereo_in->r, 1);
1196 }
1197 if (tr->in_signal_type == TYPE_EVENT &&
1198 tr->out_signal_type == TYPE_EVENT)
1199 {
1200 port_connect (
1201 self->midi_out, prefader->midi_in, 1);
1202 }
1203 }
1204
1205 /**
1206 * Disconnect the TrackProcessor's out ports
1207 * from the Plugin's input ports.
1208 */
1209 void
track_processor_disconnect_from_plugin(TrackProcessor * self,Plugin * pl)1210 track_processor_disconnect_from_plugin (
1211 TrackProcessor * self,
1212 Plugin * pl)
1213 {
1214 Track * tr = track_processor_get_track (self);
1215 g_return_if_fail (IS_TRACK_AND_NONNULL (tr));
1216
1217 int i;
1218 Port * in_port;
1219 PortType type = tr->in_signal_type;
1220
1221 for (i = 0; i < pl->num_in_ports; i++)
1222 {
1223 in_port = pl->in_ports[i];
1224
1225 if (type == TYPE_AUDIO)
1226 {
1227 if (in_port->id.type !=
1228 TYPE_AUDIO)
1229 continue;
1230
1231 if (ports_connected (
1232 self->stereo_out->l,
1233 in_port))
1234 port_disconnect (
1235 self->stereo_out->l,
1236 in_port);
1237 if (ports_connected (
1238 self->stereo_out->r,
1239 in_port))
1240 port_disconnect (
1241 self->stereo_out->r,
1242 in_port);
1243 }
1244 else if (type == TYPE_EVENT)
1245 {
1246 if (in_port->id.type != TYPE_EVENT)
1247 continue;
1248
1249 if (ports_connected (
1250 self->midi_out, in_port))
1251 port_disconnect (
1252 self->midi_out, in_port);
1253 }
1254 }
1255 }
1256
1257 /**
1258 * Connect the TrackProcessor's out ports to the
1259 * Plugin's input ports.
1260 */
1261 void
track_processor_connect_to_plugin(TrackProcessor * self,Plugin * pl)1262 track_processor_connect_to_plugin (
1263 TrackProcessor * self,
1264 Plugin * pl)
1265 {
1266 Track * tr = track_processor_get_track (self);
1267 g_return_if_fail (IS_TRACK_AND_NONNULL (tr));
1268
1269 int last_index, num_ports_to_connect, i;
1270 Port * in_port;
1271
1272 if (tr->in_signal_type == TYPE_EVENT)
1273 {
1274 /* Connect MIDI port to the plugin */
1275 for (i = 0; i < pl->num_in_ports; i++)
1276 {
1277 in_port = pl->in_ports[i];
1278 if (in_port->id.type == TYPE_EVENT &&
1279 in_port->id.flow == FLOW_INPUT)
1280 {
1281 port_connect (
1282 self->midi_out, in_port, 1);
1283 }
1284 }
1285 }
1286 else if (tr->in_signal_type == TYPE_AUDIO)
1287 {
1288 num_ports_to_connect = 0;
1289 if (pl->setting->descr->num_audio_ins == 1)
1290 {
1291 num_ports_to_connect = 1;
1292 }
1293 else if (pl->setting->descr->num_audio_ins > 1)
1294 {
1295 num_ports_to_connect = 2;
1296 }
1297
1298 last_index = 0;
1299 for (i = 0; i < num_ports_to_connect; i++)
1300 {
1301 for (;
1302 last_index < pl->num_in_ports;
1303 last_index++)
1304 {
1305 in_port =
1306 pl->in_ports[
1307 last_index];
1308 if (in_port->id.type == TYPE_AUDIO)
1309 {
1310 if (i == 0)
1311 {
1312 port_connect (
1313 self->stereo_out->l,
1314 in_port, 1);
1315 last_index++;
1316 break;
1317 }
1318 else if (i == 1)
1319 {
1320 port_connect (
1321 self->stereo_out->r,
1322 in_port, 1);
1323 last_index++;
1324 break;
1325 }
1326 }
1327 }
1328 }
1329 }
1330 }
1331
1332 /**
1333 * Frees the members of the TrackProcessor.
1334 */
1335 void
track_processor_free(TrackProcessor * self)1336 track_processor_free (
1337 TrackProcessor * self)
1338 {
1339 object_free_w_func_and_null (
1340 midi_mappings_free, self->cc_mappings);
1341
1342 if (IS_PORT_AND_NONNULL (self->mono))
1343 {
1344 port_disconnect_all (self->mono);
1345 object_free_w_func_and_null (
1346 port_free, self->mono);
1347 }
1348 if (IS_PORT_AND_NONNULL (self->input_gain))
1349 {
1350 port_disconnect_all (self->input_gain);
1351 object_free_w_func_and_null (
1352 port_free, self->input_gain);
1353 }
1354 if (IS_PORT_AND_NONNULL (self->output_gain))
1355 {
1356 port_disconnect_all (self->output_gain);
1357 object_free_w_func_and_null (
1358 port_free, self->output_gain);
1359 }
1360 if (IS_PORT_AND_NONNULL (self->monitor_audio))
1361 {
1362 port_disconnect_all (self->monitor_audio);
1363 object_free_w_func_and_null (
1364 port_free, self->monitor_audio);
1365 }
1366 if (self->stereo_in)
1367 {
1368 stereo_ports_disconnect (self->stereo_in);
1369 object_free_w_func_and_null (
1370 stereo_ports_free, self->stereo_in);
1371 }
1372 if (IS_PORT_AND_NONNULL (self->midi_in))
1373 {
1374 port_disconnect_all (self->midi_in);
1375 object_free_w_func_and_null (
1376 port_free, self->midi_in);
1377 }
1378 if (IS_PORT_AND_NONNULL (self->piano_roll))
1379 {
1380 port_disconnect_all (self->piano_roll);
1381 object_free_w_func_and_null (
1382 port_free, self->piano_roll);
1383 }
1384
1385 #define FREE_CC(cc) \
1386 if (cc) \
1387 { \
1388 port_disconnect_all (cc); \
1389 object_free_w_func_and_null ( \
1390 port_free, cc); \
1391 }
1392
1393 for (int i = 0; i < 16; i++)
1394 {
1395 Port * cc = NULL;
1396 for (int j = 0; j < 128; j++)
1397 {
1398 cc = self->midi_cc[i * 128 + j];
1399 FREE_CC (cc);
1400 }
1401
1402 cc = self->pitch_bend[i];
1403 FREE_CC (cc);
1404
1405 cc = self->poly_key_pressure[i];
1406 FREE_CC (cc);
1407
1408 cc = self->channel_pressure[i];
1409 FREE_CC (cc);
1410 }
1411
1412 #undef FREE_CC
1413
1414 if (self->stereo_out)
1415 {
1416 stereo_ports_disconnect (self->stereo_out);
1417 object_free_w_func_and_null (
1418 stereo_ports_free, self->stereo_out);
1419 }
1420 if (IS_PORT_AND_NONNULL (self->midi_out))
1421 {
1422 port_disconnect_all (self->midi_out);
1423 object_free_w_func_and_null (
1424 port_free, self->midi_out);
1425 }
1426
1427 object_zero_and_free (self);
1428 }
1429