]> git.0d.be Git - jack_mixer.git/blob - jack_mixer.c
fix crash when midi scale is not set
[jack_mixer.git] / jack_mixer.c
1 /* -*- Mode: C ; c-basic-offset: 2 -*- */
2 /*****************************************************************************
3  *
4  *   This file is part of jack_mixer
5  *
6  *   Copyright (C) 2006 Nedko Arnaudov <nedko@arnaudov.name>
7  *   Copyright (C) 2009 Frederic Peters <fpeters@0d.be>
8  *
9  *   This program is free software; you can redistribute it and/or modify
10  *   it under the terms of the GNU General Public License as published by
11  *   the Free Software Foundation; version 2 of the License
12  *
13  *   This program is distributed in the hope that it will be useful,
14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *   GNU General Public License for more details.
17  *
18  *   You should have received a copy of the GNU General Public License
19  *   along with this program; if not, write to the Free Software
20  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21  *
22  *****************************************************************************/
23
24 #include "config.h"
25
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <string.h>
29 #include <stdbool.h>
30 #include <math.h>
31 #include <jack/jack.h>
32 #if defined(HAVE_JACK_MIDI)
33 #include <jack/midiport.h>
34 #endif
35 #include <assert.h>
36 #include <pthread.h>
37
38 #include <glib.h>
39
40 #include "jack_mixer.h"
41 //#define LOG_LEVEL LOG_LEVEL_DEBUG
42 #include "log.h"
43
44 #include "jack_compat.h"
45
46 #define PEAK_FRAMES_CHUNK 4800
47
48 // we don't know how much to allocate, but we don't want to wait with 
49 // allocating until we're in the process() callback, so we just take a 
50 // fairly big chunk: 4 periods per buffer, 4096 samples per period.
51 // (not sure if the '*4' is needed)
52 #define MAX_BLOCK_SIZE (4 * 4096)
53
54 #define FLOAT_EXISTS(x) (!((x) - (x)))
55
56 struct channel
57 {
58   struct jack_mixer * mixer_ptr;
59   char * name;
60   bool stereo;
61   float volume;
62   float balance;
63   float volume_left;
64   float volume_right;
65   float meter_left;
66   float meter_right;
67   float abspeak;
68   jack_port_t * port_left;
69   jack_port_t * port_right;
70
71   jack_nframes_t peak_frames;
72   float peak_left;
73   float peak_right;
74
75   jack_default_audio_sample_t * frames_left;
76   jack_default_audio_sample_t * frames_right;
77   jack_default_audio_sample_t * prefader_frames_left;
78   jack_default_audio_sample_t * prefader_frames_right;
79
80   bool NaN_detected;
81
82   int midi_cc_volume_index;
83   int midi_cc_balance_index;
84
85   jack_default_audio_sample_t * left_buffer_ptr;
86   jack_default_audio_sample_t * right_buffer_ptr;
87
88   bool midi_in_got_events;
89   void (*midi_change_callback) (void*);
90   void *midi_change_callback_data;
91   bool midi_out_has_events;
92
93   jack_mixer_scale_t midi_scale;
94 };
95
96 struct output_channel {
97   struct channel channel;
98   GSList *soloed_channels;
99   GSList *muted_channels;
100   bool system; /* system channel, without any associated UI */
101   bool prefader;
102 };
103
104 struct jack_mixer
105 {
106   pthread_mutex_t mutex;
107   jack_client_t * jack_client;
108   GSList *input_channels_list;
109   GSList *output_channels_list;
110   struct output_channel *main_mix_channel;
111
112   jack_port_t * port_midi_in;
113   jack_port_t * port_midi_out;
114   unsigned int last_midi_channel;
115
116   struct channel* midi_cc_map[128];
117 };
118
119 static jack_mixer_output_channel_t create_output_channel(
120   jack_mixer_t mixer,
121   const char * channel_name,
122   bool stereo,
123   bool system);
124
125 static inline void
126 update_channel_buffers(
127   struct channel * channel_ptr,
128   jack_nframes_t nframes);
129
130
131 float
132 value_to_db(
133   float value)
134 {
135   if (value <= 0)
136   {
137     return -INFINITY;
138   }
139
140   return 20.0 * log10f(value);
141 }
142
143 float
144 db_to_value(
145   float db)
146 {
147   return powf(10.0, db/20.0);
148 }
149
150 void
151 calc_channel_volumes(
152   struct channel * channel_ptr)
153 {
154   if (channel_ptr->stereo)
155   {
156     if (channel_ptr->balance > 0)
157     {
158       channel_ptr->volume_left = channel_ptr->volume * (1 - channel_ptr->balance);
159       channel_ptr->volume_right = channel_ptr->volume;
160     }
161     else
162     {
163       channel_ptr->volume_left = channel_ptr->volume;
164       channel_ptr->volume_right = channel_ptr->volume * (1 + channel_ptr->balance);
165     }
166   }
167   else
168   {
169     channel_ptr->volume_left = channel_ptr->volume * (1 - channel_ptr->balance);
170     channel_ptr->volume_right = channel_ptr->volume * (1 + channel_ptr->balance);
171   }
172 }
173
174 void
175 calc_all_channel_volumes(
176   struct jack_mixer * mixer_ptr)
177 {
178   struct channel * channel_ptr;
179   GSList *list_ptr;
180
181   for (list_ptr = mixer_ptr->input_channels_list; list_ptr; list_ptr = g_slist_next(list_ptr))
182   {
183     channel_ptr = list_ptr->data;
184     calc_channel_volumes(channel_ptr);
185   }
186 }
187
188 #define channel_ptr ((struct channel *)channel)
189
190 const char*
191 channel_get_name(
192   jack_mixer_channel_t channel)
193 {
194   return channel_ptr->name;
195 }
196
197 void
198 channel_rename(
199   jack_mixer_channel_t channel,
200   const char * name)
201 {
202   char * new_name;
203   size_t channel_name_size;
204   char * port_name;
205   int ret;
206
207   new_name = strdup(name);
208   if (new_name == NULL)
209   {
210     return;
211   }
212
213   if (channel_ptr->name)
214   {
215     free(channel_ptr->name);
216   }
217
218   channel_ptr->name = new_name;
219
220   if (channel_ptr->stereo)
221   {
222     channel_name_size = strlen(name);
223     port_name = malloc(channel_name_size + 3);
224     memcpy(port_name, name, channel_name_size);
225
226     port_name[channel_name_size] = ' ';
227     port_name[channel_name_size+1] = 'L';
228     port_name[channel_name_size+2] = 0;
229
230     ret = jack_port_set_name(channel_ptr->port_left, port_name);
231     if (ret != 0)
232     {
233       /* what could we do here? */
234     }
235
236     port_name[channel_name_size+1] = 'R';
237
238     ret = jack_port_set_name(channel_ptr->port_right, port_name);
239     if (ret != 0)
240     {
241       /* what could we do here? */
242     }
243
244     free(port_name);
245   }
246   else
247   {
248     ret = jack_port_set_name(channel_ptr->port_left, name);
249     if (ret != 0)
250     {
251       /* what could we do here? */
252     }
253   }
254 }
255
256 bool
257 channel_is_stereo(
258   jack_mixer_channel_t channel)
259 {
260   return channel_ptr->stereo;
261 }
262
263 unsigned int
264 channel_get_balance_midi_cc(
265   jack_mixer_channel_t channel)
266 {
267   return channel_ptr->midi_cc_balance_index;
268 }
269
270 unsigned int
271 channel_set_balance_midi_cc(
272   jack_mixer_channel_t channel,
273   unsigned int new_cc)
274 {
275   if (new_cc > 127) {
276     return 2; /* error: over limit CC */
277   }
278   if (channel_ptr->midi_cc_balance_index == new_cc) {
279     /* no change */
280     return 0;
281   }
282   if (new_cc == 0) {
283     /* 0 is special, it removes the link */
284     channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_balance_index] = NULL;
285     channel_ptr->midi_cc_balance_index = 0;
286   } else {
287     if (channel_ptr->mixer_ptr->midi_cc_map[new_cc] != NULL) {
288       return 1; /* error: cc in use */
289     }
290     channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_balance_index] = NULL;
291     channel_ptr->mixer_ptr->midi_cc_map[new_cc] = channel_ptr;
292     channel_ptr->midi_cc_balance_index = new_cc;
293   }
294   return 0;
295 }
296
297 unsigned int
298 channel_get_volume_midi_cc(
299   jack_mixer_channel_t channel)
300 {
301   return channel_ptr->midi_cc_volume_index;
302 }
303
304 unsigned int
305 channel_set_volume_midi_cc(
306   jack_mixer_channel_t channel, unsigned int new_cc)
307 {
308   if (new_cc > 127) {
309     return 2; /* error: over limit CC */
310   }
311   if (channel_ptr->midi_cc_volume_index == new_cc) {
312     /* no change */
313     return 0;
314   }
315   if (new_cc == 0) {
316     /* 0 is special, it removes the link */
317     channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_volume_index] = NULL;
318     channel_ptr->midi_cc_volume_index = 0;
319   } else {
320     if (channel_ptr->mixer_ptr->midi_cc_map[new_cc] != NULL) {
321       return 1; /* error: cc in use */
322     }
323     channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_volume_index] = NULL;
324     channel_ptr->mixer_ptr->midi_cc_map[new_cc] = channel_ptr;
325     channel_ptr->midi_cc_volume_index = new_cc;
326   }
327   return 0;
328 }
329
330 void
331 channel_autoset_midi_cc(
332   jack_mixer_channel_t channel)
333 {
334   struct jack_mixer *mixer_ptr;
335   int i;
336
337   mixer_ptr = channel_ptr->mixer_ptr;
338
339   for (i = 11 ; i < 128 ; i++)
340   {
341     if (mixer_ptr->midi_cc_map[i] == NULL)
342     {
343       mixer_ptr->midi_cc_map[i] = channel_ptr;
344       channel_ptr->midi_cc_volume_index = i;
345
346       LOG_NOTICE("New channel \"%s\" volume mapped to CC#%i", channel_ptr->name, i);
347
348       break;
349     }
350   }
351
352   for (; i < 128 ; i++)
353   {
354     if (mixer_ptr->midi_cc_map[i] == NULL)
355     {
356       mixer_ptr->midi_cc_map[i] = channel_ptr;
357       channel_ptr->midi_cc_balance_index = i;
358
359       LOG_NOTICE("New channel \"%s\" balance mapped to CC#%i", channel_ptr->name, i);
360
361       break;
362     }
363   }
364 }
365
366 void
367 remove_channel(
368   jack_mixer_channel_t channel)
369 {
370   GSList *list_ptr;
371
372   channel_ptr->mixer_ptr->input_channels_list = g_slist_remove(
373                   channel_ptr->mixer_ptr->input_channels_list, channel_ptr);
374   free(channel_ptr->name);
375
376   /* remove references to input channel from all output channels */
377   channel_unmute(channel_ptr);
378   channel_unsolo(channel_ptr);
379   for (list_ptr = channel_ptr->mixer_ptr->output_channels_list; list_ptr; list_ptr = g_slist_next(list_ptr))
380   {
381     struct output_channel *output_channel_ptr = list_ptr->data;
382     output_channel_set_solo(output_channel_ptr, channel, false);
383     output_channel_set_muted(output_channel_ptr, channel, false);
384   }
385
386   jack_port_unregister(channel_ptr->mixer_ptr->jack_client, channel_ptr->port_left);
387   if (channel_ptr->stereo)
388   {
389     jack_port_unregister(channel_ptr->mixer_ptr->jack_client, channel_ptr->port_right);
390   }
391
392   if (channel_ptr->midi_cc_volume_index != 0)
393   {
394     assert(channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_volume_index] == channel_ptr);
395     channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_volume_index] = NULL;
396   }
397
398   if (channel_ptr->midi_cc_balance_index != 0)
399   {
400     assert(channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_balance_index] == channel_ptr);
401     channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_balance_index] = NULL;
402   }
403
404   free(channel_ptr);
405 }
406
407 void
408 channel_stereo_meter_read(
409   jack_mixer_channel_t channel,
410   double * left_ptr,
411   double * right_ptr)
412 {
413   assert(channel_ptr);
414   *left_ptr = value_to_db(channel_ptr->meter_left);
415   *right_ptr = value_to_db(channel_ptr->meter_right);
416 }
417
418 void
419 channel_mono_meter_read(
420   jack_mixer_channel_t channel,
421   double * mono_ptr)
422 {
423   *mono_ptr = value_to_db(channel_ptr->meter_left);
424 }
425
426 void
427 channel_volume_write(
428   jack_mixer_channel_t channel,
429   double volume)
430 {
431   assert(channel_ptr);
432   channel_ptr->volume = db_to_value(volume);
433   channel_ptr->midi_out_has_events = true;
434   calc_channel_volumes(channel_ptr);
435 }
436
437 double
438 channel_volume_read(
439   jack_mixer_channel_t channel)
440 {
441   assert(channel_ptr);
442   return value_to_db(channel_ptr->volume);
443 }
444
445 void
446 channel_balance_write(
447   jack_mixer_channel_t channel,
448   double balance)
449 {
450   assert(channel_ptr);
451   channel_ptr->balance = balance;
452   calc_channel_volumes(channel_ptr);
453 }
454
455 double
456 channel_balance_read(
457   jack_mixer_channel_t channel)
458 {
459   assert(channel_ptr);
460   return channel_ptr->balance;
461 }
462
463 double
464 channel_abspeak_read(
465   jack_mixer_channel_t channel)
466 {
467   assert(channel_ptr);
468   if (channel_ptr->NaN_detected)
469   {
470     return sqrt(-1);
471   }
472   else
473   {
474     return value_to_db(channel_ptr->abspeak);
475   }
476 }
477
478 void
479 channel_abspeak_reset(
480   jack_mixer_channel_t channel)
481 {
482   channel_ptr->abspeak = 0;
483   channel_ptr->NaN_detected = false;
484 }
485
486 void
487 channel_mute(
488   jack_mixer_channel_t channel)
489 {
490   output_channel_set_muted(channel_ptr->mixer_ptr->main_mix_channel, channel, true);
491 }
492
493 void
494 channel_unmute(
495   jack_mixer_channel_t channel)
496 {
497   output_channel_set_muted(channel_ptr->mixer_ptr->main_mix_channel, channel, false);
498 }
499
500 void
501 channel_solo(
502   jack_mixer_channel_t channel)
503 {
504   output_channel_set_solo(channel_ptr->mixer_ptr->main_mix_channel, channel, true);
505 }
506
507 void
508 channel_unsolo(
509   jack_mixer_channel_t channel)
510 {
511   output_channel_set_solo(channel_ptr->mixer_ptr->main_mix_channel, channel, false);
512 }
513
514 bool
515 channel_is_muted(
516   jack_mixer_channel_t channel)
517 {
518   if (g_slist_find(channel_ptr->mixer_ptr->main_mix_channel->muted_channels, channel))
519     return true;
520   return false;
521 }
522
523 bool
524 channel_is_soloed(
525   jack_mixer_channel_t channel)
526 {
527   if (g_slist_find(channel_ptr->mixer_ptr->main_mix_channel->soloed_channels, channel))
528     return true;
529   return false;
530 }
531
532 void
533 channel_set_midi_scale(
534   jack_mixer_channel_t channel,
535   jack_mixer_scale_t scale)
536 {
537   channel_ptr->midi_scale = scale;
538 }
539
540 void
541 channel_set_midi_change_callback(
542   jack_mixer_channel_t channel,
543   void (*midi_change_callback) (void*),
544   void *user_data)
545 {
546   channel_ptr->midi_change_callback = midi_change_callback;
547   channel_ptr->midi_change_callback_data = user_data;
548 }
549
550 bool
551 channel_get_midi_in_got_events(
552   jack_mixer_channel_t channel)
553 {
554   bool t = channel_ptr->midi_in_got_events;
555   channel_ptr->midi_in_got_events = false;
556   return t;
557 }
558
559 #undef channel_ptr
560
561 /* process input channels and mix them into main mix */
562 static inline void
563 mix_one(
564   struct output_channel *output_mix_channel,
565   GSList *channels_list,
566   jack_nframes_t start,         /* index of first sample to process */
567   jack_nframes_t end)           /* index of sample to stop processing before */
568 {
569   jack_nframes_t i;
570   GSList *node_ptr;
571   struct channel * channel_ptr;
572   jack_default_audio_sample_t frame_left;
573   jack_default_audio_sample_t frame_right;
574   struct channel *mix_channel = (struct channel*)output_mix_channel;
575
576   for (i = start; i < end; i++)
577   {
578     mix_channel->left_buffer_ptr[i] = 0.0;
579     if (mix_channel->stereo)
580       mix_channel->right_buffer_ptr[i] = 0.0;
581   }
582
583
584   for (node_ptr = channels_list; node_ptr; node_ptr = g_slist_next(node_ptr))
585   {
586     channel_ptr = node_ptr->data;
587
588     if (g_slist_find(output_mix_channel->muted_channels, channel_ptr) != NULL) {
589       /* skip muted channels */
590       continue;
591     }
592
593     if (output_mix_channel->soloed_channels &&
594         g_slist_find(output_mix_channel->soloed_channels, channel_ptr) == NULL) {
595       /* skip channels that are not soloed, when some are */
596       continue;
597     }
598
599     for (i = start ; i < end ; i++)
600     {
601       if (! output_mix_channel->prefader) {
602         frame_left = channel_ptr->frames_left[i-start];
603       } else {
604         frame_left = channel_ptr->prefader_frames_left[i-start];
605       }
606       if (frame_left == NAN)
607         break;
608       mix_channel->left_buffer_ptr[i] += frame_left;
609
610       if (mix_channel->stereo)
611       {
612         if (! output_mix_channel->prefader) {
613           frame_right = channel_ptr->frames_right[i-start];
614         } else {
615           frame_right = channel_ptr->prefader_frames_right[i-start];
616         }
617         if (frame_right == NAN)
618           break;
619
620         mix_channel->right_buffer_ptr[i] += frame_right;
621       }
622
623     }
624
625   }
626
627   /* process main mix channel */
628   for (i = start ; i < end ; i++)
629   {
630     if (! output_mix_channel->prefader) {
631       mix_channel->left_buffer_ptr[i] *= mix_channel->volume_left;
632       if (mix_channel->stereo)
633       {
634         mix_channel->right_buffer_ptr[i] *= mix_channel->volume_right;
635       }
636     }
637
638     frame_left = fabsf(mix_channel->left_buffer_ptr[i]);
639     if (mix_channel->peak_left < frame_left)
640     {
641       mix_channel->peak_left = frame_left;
642
643       if (frame_left > mix_channel->abspeak)
644       {
645         mix_channel->abspeak = frame_left;
646       }
647     }
648
649     if (mix_channel->stereo)
650     {
651       frame_right = fabsf(mix_channel->right_buffer_ptr[i]);
652       if (mix_channel->peak_right < frame_right)
653       {
654         mix_channel->peak_right = frame_right;
655
656         if (frame_right > mix_channel->abspeak)
657         {
658           mix_channel->abspeak = frame_right;
659         }
660       }
661     }
662
663     mix_channel->peak_frames++;
664     if (mix_channel->peak_frames >= PEAK_FRAMES_CHUNK)
665     {
666       mix_channel->meter_left = mix_channel->peak_left;
667       mix_channel->peak_left = 0.0;
668
669       if (mix_channel->stereo)
670       {
671         mix_channel->meter_right = mix_channel->peak_right;
672         mix_channel->peak_right = 0.0;
673       }
674
675       mix_channel->peak_frames = 0;
676     }
677   }
678 }
679
680 static inline void
681 calc_channel_frames(
682   struct channel *channel_ptr,
683   jack_nframes_t start,
684   jack_nframes_t end)
685 {
686   jack_nframes_t i;
687   jack_default_audio_sample_t frame_left;
688   jack_default_audio_sample_t frame_right;
689
690   for (i = start ; i < end ; i++)
691   {
692     if (i-start >= MAX_BLOCK_SIZE)
693     {
694       fprintf(stderr, "i-start too high: %d - %d\n", i, start);
695     }
696     channel_ptr->prefader_frames_left[i-start] = channel_ptr->left_buffer_ptr[i];
697     if (channel_ptr->stereo)
698       channel_ptr->prefader_frames_right[i-start] = channel_ptr->right_buffer_ptr[i];
699
700     if (!FLOAT_EXISTS(channel_ptr->left_buffer_ptr[i]))
701     {
702       channel_ptr->NaN_detected = true;
703       channel_ptr->frames_left[i-start] = NAN;
704       break;
705     }
706
707     frame_left = channel_ptr->left_buffer_ptr[i] * channel_ptr->volume_left;
708
709     if (channel_ptr->stereo)
710     {
711       if (!FLOAT_EXISTS(channel_ptr->right_buffer_ptr[i]))
712       {
713         channel_ptr->NaN_detected = true;
714         channel_ptr->frames_right[i-start] = NAN;
715         break;
716       }
717
718       frame_right = channel_ptr->right_buffer_ptr[i] * channel_ptr->volume_right;
719     }
720     else
721     {
722       frame_right = channel_ptr->left_buffer_ptr[i] * channel_ptr->volume_right;
723     }
724
725     channel_ptr->frames_left[i-start] = frame_left;
726     channel_ptr->frames_right[i-start] = frame_right;
727
728     if (channel_ptr->stereo)
729     {
730       frame_left = fabsf(frame_left);
731       frame_right = fabsf(frame_right);
732
733       if (channel_ptr->peak_left < frame_left)
734       {
735         channel_ptr->peak_left = frame_left;
736
737         if (frame_left > channel_ptr->abspeak)
738         {
739           channel_ptr->abspeak = frame_left;
740         }
741       }
742
743       if (channel_ptr->peak_right < frame_right)
744       {
745         channel_ptr->peak_right = frame_right;
746
747         if (frame_right > channel_ptr->abspeak)
748         {
749           channel_ptr->abspeak = frame_right;
750         }
751       }
752     }
753     else
754     {
755       frame_left = (fabsf(frame_left) + fabsf(frame_right)) / 2;
756
757       if (channel_ptr->peak_left < frame_left)
758       {
759         channel_ptr->peak_left = frame_left;
760
761         if (frame_left > channel_ptr->abspeak)
762         {
763           channel_ptr->abspeak = frame_left;
764         }
765       }
766     }
767
768     channel_ptr->peak_frames++;
769     if (channel_ptr->peak_frames >= PEAK_FRAMES_CHUNK)
770     {
771       channel_ptr->meter_left = channel_ptr->peak_left;
772       channel_ptr->peak_left = 0.0;
773
774       if (channel_ptr->stereo)
775       {
776         channel_ptr->meter_right = channel_ptr->peak_right;
777         channel_ptr->peak_right = 0.0;
778       }
779
780       channel_ptr->peak_frames = 0;
781     }
782   }
783
784 }
785
786 static inline void
787 mix(
788   struct jack_mixer * mixer_ptr,
789   jack_nframes_t start,         /* index of first sample to process */
790   jack_nframes_t end)           /* index of sample to stop processing before */
791 {
792   GSList *node_ptr;
793   struct output_channel * output_channel_ptr;
794   struct channel *channel_ptr;
795
796   for (node_ptr = mixer_ptr->input_channels_list; node_ptr; node_ptr = g_slist_next(node_ptr))
797   {
798     channel_ptr = (struct channel*)node_ptr->data;
799     calc_channel_frames(channel_ptr, start, end);
800   }
801
802   mix_one((struct output_channel*)mixer_ptr->main_mix_channel, mixer_ptr->input_channels_list, start, end);
803
804   for (node_ptr = mixer_ptr->output_channels_list; node_ptr; node_ptr = g_slist_next(node_ptr))
805   {
806     output_channel_ptr = node_ptr->data;
807     channel_ptr = (struct channel*)output_channel_ptr;
808
809     if (output_channel_ptr->system)
810     {
811       /* Don't bother mixing the channels if we are not connected */
812       if (channel_ptr->stereo)
813       {
814         if (jack_port_connected(channel_ptr->port_left) == 0 &&
815             jack_port_connected(channel_ptr->port_right) == 0)
816           continue;
817       } else {
818          if (jack_port_connected(channel_ptr->port_left) == 0)
819            continue;
820       }
821     }
822
823     mix_one(output_channel_ptr, mixer_ptr->input_channels_list, start, end);
824   }
825 }
826
827 static inline void
828 update_channel_buffers(
829   struct channel * channel_ptr,
830   jack_nframes_t nframes)
831 {
832   channel_ptr->left_buffer_ptr = jack_port_get_buffer(channel_ptr->port_left, nframes);
833
834   if (channel_ptr->stereo)
835   {
836     channel_ptr->right_buffer_ptr = jack_port_get_buffer(channel_ptr->port_right, nframes);
837   }
838 }
839
840 #define mixer_ptr ((struct jack_mixer *)context)
841
842 static int
843 process(
844   jack_nframes_t nframes,
845   void * context)
846 {
847   jack_nframes_t i;
848   GSList *node_ptr;
849   struct channel * channel_ptr;
850 #if defined(HAVE_JACK_MIDI)
851   jack_nframes_t event_count;
852   jack_midi_event_t in_event;
853   unsigned char* midi_out_buffer;
854   void * midi_buffer;
855   signed char byte;
856   unsigned int cc_channel_index;
857 #endif
858   jack_nframes_t offset;
859
860   for (node_ptr = mixer_ptr->input_channels_list; node_ptr; node_ptr = g_slist_next(node_ptr))
861   {
862     channel_ptr = node_ptr->data;
863     update_channel_buffers(channel_ptr, nframes);
864   }
865
866   // Fill output buffers with the input 
867   update_channel_buffers((struct channel*)mixer_ptr->main_mix_channel, nframes);
868   for (node_ptr = mixer_ptr->output_channels_list; node_ptr; node_ptr = g_slist_next(node_ptr))
869   {
870     channel_ptr = node_ptr->data;
871     update_channel_buffers(channel_ptr, nframes);
872   }
873
874   offset = 0;
875
876 #if defined(HAVE_JACK_MIDI)
877   midi_buffer = jack_port_get_buffer(mixer_ptr->port_midi_in, nframes);
878   event_count = jack_midi_get_event_count(midi_buffer);
879
880   for (i = 0 ; i < event_count; i++)
881   {
882     jack_midi_event_get(&in_event, midi_buffer, i);
883
884     if (in_event.size != 3 ||
885         (in_event.buffer[0] & 0xF0) != 0xB0 ||
886         in_event.buffer[1] > 127 ||
887         in_event.buffer[2] > 127)
888     {
889       continue;
890     }
891
892     assert(in_event.time < nframes);
893
894     LOG_DEBUG(
895       "%u: CC#%u -> %u",
896       (unsigned int)(in_event.buffer[0]),
897       (unsigned int)in_event.buffer[1],
898       (unsigned int)in_event.buffer[2]);
899
900     mixer_ptr->last_midi_channel = (unsigned int)in_event.buffer[1];
901     channel_ptr = mixer_ptr->midi_cc_map[in_event.buffer[1]];
902
903     /* if we have mapping for particular CC and MIDI scale is set for corresponding channel */
904     if (channel_ptr != NULL && channel_ptr->midi_scale != NULL)
905     {
906       assert(in_event.time >= offset);
907
908       if (in_event.time > offset)
909       {
910         // Perform the mixing of the part between the previous volume change
911         // (or the start of the block) up until this one.
912         mix(mixer_ptr, offset, in_event.time);
913         offset = in_event.time;
914       }
915
916       if (channel_ptr->midi_cc_balance_index == (unsigned int)in_event.buffer[1])
917       {
918         byte = in_event.buffer[2];
919         if (byte == 0)
920         {
921           byte = 1;
922         }
923         byte -= 64;
924
925         channel_ptr->balance = (float)byte / 63;
926         LOG_DEBUG("\"%s\" balance -> %f", channel_ptr->name, channel_ptr->balance);
927       }
928       else
929       {
930         channel_ptr->volume = db_to_value(scale_scale_to_db(channel_ptr->midi_scale, (double)in_event.buffer[2] / 127));
931         LOG_DEBUG("\"%s\" volume -> %f", channel_ptr->name, channel_ptr->volume);
932       }
933
934       calc_channel_volumes(channel_ptr);
935
936       channel_ptr->midi_in_got_events = true;
937       if (channel_ptr->midi_change_callback)
938         channel_ptr->midi_change_callback(channel_ptr->midi_change_callback_data);
939
940     }
941
942   }
943
944   midi_buffer = jack_port_get_buffer(mixer_ptr->port_midi_out, nframes);
945   jack_midi_clear_buffer(midi_buffer);
946
947   for(i=0; i<nframes; i++)
948   {
949     for (cc_channel_index=0; cc_channel_index<128; cc_channel_index++)
950     {
951       channel_ptr = mixer_ptr->midi_cc_map[cc_channel_index];
952       if (channel_ptr == NULL || channel_ptr->midi_scale == NULL)
953       {
954         continue;
955       }
956       if (channel_ptr->midi_out_has_events == false)
957       {
958         continue;
959       }
960       if (channel_ptr->midi_cc_balance_index == (unsigned int)cc_channel_index)
961       {
962         continue;
963       }
964       midi_out_buffer = jack_midi_event_reserve(midi_buffer, i, 3);
965       if (midi_out_buffer == NULL)
966       {
967         continue;
968       }
969       midi_out_buffer[0] = 0xB0; /* control change */
970       midi_out_buffer[1] = cc_channel_index;
971       midi_out_buffer[2] = (unsigned char)(127*scale_db_to_scale(channel_ptr->midi_scale, value_to_db(channel_ptr->volume)));
972
973       LOG_DEBUG(
974         "%u: CC#%u <- %u",
975         (unsigned int)(midi_out_buffer[0]),
976         (unsigned int)midi_out_buffer[1],
977         (unsigned int)midi_out_buffer[2]);
978
979       channel_ptr->midi_out_has_events = false;
980     }
981   }
982
983 #endif
984
985   mix(mixer_ptr, offset, nframes);
986
987   return 0;
988 }
989
990 #undef mixer_ptr
991
992 jack_mixer_t
993 create(
994   const char * jack_client_name_ptr,
995   bool stereo)
996 {
997   int ret;
998   struct jack_mixer * mixer_ptr;
999   int i;
1000
1001
1002   mixer_ptr = malloc(sizeof(struct jack_mixer));
1003   if (mixer_ptr == NULL)
1004   {
1005     goto exit;
1006   }
1007
1008   ret = pthread_mutex_init(&mixer_ptr->mutex, NULL);
1009   if (ret != 0)
1010   {
1011     goto exit_free;
1012   }
1013
1014   mixer_ptr->input_channels_list = NULL;
1015   mixer_ptr->output_channels_list = NULL;
1016
1017   mixer_ptr->last_midi_channel = 0;
1018
1019   for (i = 0 ; i < 128 ; i++)
1020   {
1021     mixer_ptr->midi_cc_map[i] = NULL;
1022   }
1023
1024   LOG_DEBUG("Initializing JACK");
1025   mixer_ptr->jack_client = jack_client_open(jack_client_name_ptr, 0, NULL);
1026   if (mixer_ptr->jack_client == NULL)
1027   {
1028     LOG_ERROR("Cannot create JACK client.");
1029     LOG_NOTICE("Please make sure JACK daemon is running.");
1030     goto exit_destroy_mutex;
1031   }
1032
1033   LOG_DEBUG("JACK client created");
1034
1035   LOG_DEBUG("Sample rate: %" PRIu32, jack_get_sample_rate(mixer_ptr->jack_client));
1036
1037   mixer_ptr->main_mix_channel = create_output_channel(mixer_ptr, "MAIN", stereo, false);
1038   if (mixer_ptr->main_mix_channel == NULL) {
1039     LOG_ERROR("Cannot create main mix channel");
1040     goto close_jack;
1041   }
1042   channel_set_volume_midi_cc(mixer_ptr->main_mix_channel, 7);
1043   channel_set_balance_midi_cc(mixer_ptr->main_mix_channel, 8);
1044
1045   ((struct channel*)(mixer_ptr->main_mix_channel))->mixer_ptr = mixer_ptr;
1046
1047 #if defined(HAVE_JACK_MIDI)
1048   mixer_ptr->port_midi_in = jack_port_register(mixer_ptr->jack_client, "midi in", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0);
1049   if (mixer_ptr->port_midi_in == NULL)
1050   {
1051     LOG_ERROR("Cannot create JACK MIDI in port");
1052     goto close_jack;
1053   }
1054
1055   mixer_ptr->port_midi_out = jack_port_register(mixer_ptr->jack_client, "midi out", JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0);
1056   if (mixer_ptr->port_midi_out == NULL)
1057   {
1058     LOG_ERROR("Cannot create JACK MIDI out port");
1059     goto close_jack;
1060   }
1061
1062 #endif
1063
1064   calc_channel_volumes((struct channel*)mixer_ptr->main_mix_channel);
1065
1066   ret = jack_set_process_callback(mixer_ptr->jack_client, process, mixer_ptr);
1067   if (ret != 0)
1068   {
1069     LOG_ERROR("Cannot set JACK process callback");
1070     goto close_jack;
1071   }
1072
1073   ret = jack_activate(mixer_ptr->jack_client);
1074   if (ret != 0)
1075   {
1076     LOG_ERROR("Cannot activate JACK client");
1077     goto close_jack;
1078   }
1079
1080   return mixer_ptr;
1081
1082 close_jack:
1083   jack_client_close(mixer_ptr->jack_client); /* this should clear all other resources we obtained through the client handle */
1084
1085 exit_destroy_mutex:
1086   pthread_mutex_destroy(&mixer_ptr->mutex);
1087
1088 exit_free:
1089   free(mixer_ptr);
1090
1091 exit:
1092   return NULL;
1093 }
1094
1095 #define mixer_ctx_ptr ((struct jack_mixer *)mixer)
1096
1097 void
1098 destroy(
1099   jack_mixer_t mixer)
1100 {
1101   LOG_DEBUG("Uninitializing JACK");
1102
1103   assert(mixer_ctx_ptr->jack_client != NULL);
1104
1105   jack_client_close(mixer_ctx_ptr->jack_client);
1106
1107   pthread_mutex_destroy(&mixer_ctx_ptr->mutex);
1108
1109   free(mixer_ctx_ptr->main_mix_channel);
1110   free(mixer_ctx_ptr);
1111 }
1112
1113 jack_mixer_channel_t
1114 get_main_mix_channel(
1115   jack_mixer_t mixer)
1116 {
1117   return (struct channel*)mixer_ctx_ptr->main_mix_channel;
1118 }
1119
1120 unsigned int
1121 get_channels_count(
1122   jack_mixer_t mixer)
1123 {
1124   return g_slist_length(mixer_ctx_ptr->input_channels_list);
1125 }
1126
1127 unsigned int
1128 get_last_midi_channel(
1129   jack_mixer_t mixer)
1130 {
1131   return mixer_ctx_ptr->last_midi_channel;
1132 }
1133
1134 jack_mixer_channel_t
1135 add_channel(
1136   jack_mixer_t mixer,
1137   const char * channel_name,
1138   bool stereo)
1139 {
1140   struct channel * channel_ptr;
1141   char * port_name;
1142   size_t channel_name_size;
1143
1144   channel_ptr = malloc(sizeof(struct channel));
1145   if (channel_ptr == NULL)
1146   {
1147     goto fail;
1148   }
1149
1150   channel_ptr->mixer_ptr = mixer_ctx_ptr;
1151
1152   channel_ptr->name = strdup(channel_name);
1153   if (channel_ptr->name == NULL)
1154   {
1155     goto fail_free_channel;
1156   }
1157
1158   channel_name_size = strlen(channel_name);
1159
1160   if (stereo)
1161   {
1162     port_name = malloc(channel_name_size + 3);
1163     if (port_name == NULL)
1164     {
1165         goto fail_free_channel_name;
1166     }
1167
1168     memcpy(port_name, channel_name, channel_name_size);
1169     port_name[channel_name_size] = ' ';
1170     port_name[channel_name_size+1] = 'L';
1171     port_name[channel_name_size+2] = 0;
1172
1173     channel_ptr->port_left = jack_port_register(channel_ptr->mixer_ptr->jack_client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
1174     if (channel_ptr->port_left == NULL)
1175     {
1176         goto fail_free_port_name;
1177     }
1178
1179     port_name[channel_name_size+1] = 'R';
1180
1181     channel_ptr->port_right = jack_port_register(channel_ptr->mixer_ptr->jack_client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
1182     if (channel_ptr->port_right == NULL)
1183     {
1184         goto fail_unregister_left_channel;
1185     }
1186   }
1187   else
1188   {
1189     channel_ptr->port_left = jack_port_register(channel_ptr->mixer_ptr->jack_client, channel_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
1190     if (channel_ptr->port_left == NULL)
1191     {
1192         goto fail_free_channel_name;
1193     }
1194   }
1195
1196   channel_ptr->stereo = stereo;
1197
1198   channel_ptr->volume = 0.0;
1199   channel_ptr->balance = 0.0;
1200   channel_ptr->meter_left = -1.0;
1201   channel_ptr->meter_right = -1.0;
1202   channel_ptr->abspeak = 0.0;
1203
1204   channel_ptr->peak_left = 0.0;
1205   channel_ptr->peak_right = 0.0;
1206   channel_ptr->peak_frames = 0;
1207
1208   channel_ptr->frames_left = calloc(MAX_BLOCK_SIZE, sizeof(jack_default_audio_sample_t));
1209   channel_ptr->frames_right = calloc(MAX_BLOCK_SIZE, sizeof(jack_default_audio_sample_t));
1210   channel_ptr->prefader_frames_left = calloc(MAX_BLOCK_SIZE, sizeof(jack_default_audio_sample_t));
1211   channel_ptr->prefader_frames_right = calloc(MAX_BLOCK_SIZE, sizeof(jack_default_audio_sample_t));
1212
1213   channel_ptr->NaN_detected = false;
1214
1215   channel_ptr->midi_cc_volume_index = 0;
1216   channel_ptr->midi_cc_balance_index = 0;
1217   channel_ptr->midi_change_callback = NULL;
1218   channel_ptr->midi_change_callback_data = NULL;
1219   channel_ptr->midi_out_has_events = false;
1220
1221   channel_ptr->midi_scale = NULL;
1222
1223   calc_channel_volumes(channel_ptr);
1224
1225   channel_ptr->mixer_ptr->input_channels_list = g_slist_prepend(
1226                   channel_ptr->mixer_ptr->input_channels_list, channel_ptr);
1227
1228   return channel_ptr;
1229
1230 fail_unregister_left_channel:
1231   jack_port_unregister(channel_ptr->mixer_ptr->jack_client, channel_ptr->port_left);
1232
1233 fail_free_port_name:
1234   free(port_name);
1235
1236 fail_free_channel_name:
1237   free(channel_ptr->name);
1238
1239 fail_free_channel:
1240   free(channel_ptr);
1241   channel_ptr = NULL;
1242
1243 fail:
1244   return NULL;
1245 }
1246
1247 static jack_mixer_output_channel_t
1248 create_output_channel(
1249   jack_mixer_t mixer,
1250   const char * channel_name,
1251   bool stereo,
1252   bool system)
1253 {
1254   struct channel * channel_ptr;
1255   struct output_channel * output_channel_ptr;
1256   char * port_name;
1257   size_t channel_name_size;
1258
1259   output_channel_ptr = malloc(sizeof(struct output_channel));
1260   channel_ptr = (struct channel*)output_channel_ptr;
1261   if (channel_ptr == NULL)
1262   {
1263     goto fail;
1264   }
1265
1266   channel_ptr->mixer_ptr = mixer_ctx_ptr;
1267
1268   channel_ptr->name = strdup(channel_name);
1269   if (channel_ptr->name == NULL)
1270   {
1271     goto fail_free_channel;
1272   }
1273
1274   if (stereo)
1275   {
1276     channel_name_size = strlen(channel_name);
1277
1278     port_name = malloc(channel_name_size + 4);
1279     if (port_name == NULL)
1280     {
1281         goto fail_free_channel_name;
1282     }
1283
1284     memcpy(port_name, channel_name, channel_name_size);
1285     port_name[channel_name_size] = ' ';
1286     port_name[channel_name_size+1] = 'L';
1287     port_name[channel_name_size+2] = 0;
1288
1289     channel_ptr->port_left = jack_port_register(channel_ptr->mixer_ptr->jack_client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
1290     if (channel_ptr->port_left == NULL)
1291     {
1292         goto fail_free_port_name;
1293     }
1294
1295     port_name[channel_name_size+1] = 'R';
1296
1297     channel_ptr->port_right = jack_port_register(channel_ptr->mixer_ptr->jack_client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
1298     if (channel_ptr->port_right == NULL)
1299     {
1300         goto fail_unregister_left_channel;
1301     }
1302   }
1303   else
1304   {
1305     channel_ptr->port_left = jack_port_register(channel_ptr->mixer_ptr->jack_client, channel_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
1306     if (channel_ptr->port_left == NULL)
1307     {
1308         goto fail_free_channel_name;
1309     }
1310   }
1311
1312   channel_ptr->stereo = stereo;
1313
1314   channel_ptr->volume = 0.0;
1315   channel_ptr->balance = 0.0;
1316   channel_ptr->meter_left = -1.0;
1317   channel_ptr->meter_right = -1.0;
1318   channel_ptr->abspeak = 0.0;
1319
1320   channel_ptr->peak_left = 0.0;
1321   channel_ptr->peak_right = 0.0;
1322   channel_ptr->peak_frames = 0;
1323
1324   channel_ptr->frames_left = calloc(MAX_BLOCK_SIZE, sizeof(jack_default_audio_sample_t));
1325   channel_ptr->frames_right = calloc(MAX_BLOCK_SIZE, sizeof(jack_default_audio_sample_t));
1326   channel_ptr->prefader_frames_left = calloc(MAX_BLOCK_SIZE, sizeof(jack_default_audio_sample_t));
1327   channel_ptr->prefader_frames_right = calloc(MAX_BLOCK_SIZE, sizeof(jack_default_audio_sample_t));
1328
1329   channel_ptr->NaN_detected = false;
1330
1331   channel_ptr->midi_cc_volume_index = 0;
1332   channel_ptr->midi_cc_balance_index = 0;
1333   channel_ptr->midi_change_callback = NULL;
1334   channel_ptr->midi_change_callback_data = NULL;
1335
1336   channel_ptr->midi_scale = NULL;
1337
1338   output_channel_ptr->soloed_channels = NULL;
1339   output_channel_ptr->muted_channels = NULL;
1340   output_channel_ptr->system = system;
1341   output_channel_ptr->prefader = false;
1342
1343   return output_channel_ptr;
1344
1345 fail_unregister_left_channel:
1346   jack_port_unregister(channel_ptr->mixer_ptr->jack_client, channel_ptr->port_left);
1347
1348 fail_free_port_name:
1349   free(port_name);
1350
1351 fail_free_channel_name:
1352   free(channel_ptr->name);
1353
1354 fail_free_channel:
1355   free(channel_ptr);
1356   channel_ptr = NULL;
1357
1358 fail:
1359   return NULL;
1360 }
1361
1362 jack_mixer_output_channel_t
1363 add_output_channel(
1364   jack_mixer_t mixer,
1365   const char * channel_name,
1366   bool stereo,
1367   bool system)
1368 {
1369   struct output_channel *output_channel_ptr;
1370   struct channel *channel_ptr;
1371
1372   output_channel_ptr = create_output_channel(mixer, channel_name, stereo, system);
1373   if (output_channel_ptr == NULL) {
1374     return NULL;
1375   }
1376   channel_ptr = (struct channel*)output_channel_ptr;
1377
1378   ((struct jack_mixer*)mixer)->output_channels_list = g_slist_prepend(
1379                   ((struct jack_mixer*)mixer)->output_channels_list, channel_ptr);
1380
1381   return output_channel_ptr;
1382 }
1383
1384 void
1385 remove_output_channel(
1386   jack_mixer_output_channel_t output_channel)
1387 {
1388   struct output_channel *output_channel_ptr = output_channel;
1389   struct channel *channel_ptr = output_channel;
1390
1391   channel_ptr->mixer_ptr->output_channels_list = g_slist_remove(
1392                   channel_ptr->mixer_ptr->output_channels_list, channel_ptr);
1393   free(channel_ptr->name);
1394
1395   jack_port_unregister(channel_ptr->mixer_ptr->jack_client, channel_ptr->port_left);
1396   if (channel_ptr->stereo)
1397   {
1398     jack_port_unregister(channel_ptr->mixer_ptr->jack_client, channel_ptr->port_right);
1399   }
1400
1401   if (channel_ptr->midi_cc_volume_index != 0)
1402   {
1403     assert(channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_volume_index] == channel_ptr);
1404     channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_volume_index] = NULL;
1405   }
1406
1407   if (channel_ptr->midi_cc_balance_index != 0)
1408   {
1409     assert(channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_balance_index] == channel_ptr);
1410     channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_balance_index] = NULL;
1411   }
1412
1413   g_slist_free(output_channel_ptr->soloed_channels);
1414   g_slist_free(output_channel_ptr->muted_channels);
1415
1416   free(channel_ptr);
1417 }
1418
1419 void
1420 output_channel_set_solo(
1421   jack_mixer_output_channel_t output_channel,
1422   jack_mixer_channel_t channel,
1423   bool solo_value)
1424 {
1425   struct output_channel *output_channel_ptr = output_channel;
1426
1427   if (solo_value) {
1428     if (g_slist_find(output_channel_ptr->soloed_channels, channel) != NULL)
1429       return;
1430     output_channel_ptr->soloed_channels = g_slist_prepend(output_channel_ptr->soloed_channels, channel);
1431   } else {
1432     if (g_slist_find(output_channel_ptr->soloed_channels, channel) == NULL)
1433       return;
1434     output_channel_ptr->soloed_channels = g_slist_remove(output_channel_ptr->soloed_channels, channel);
1435   }
1436 }
1437
1438 void
1439 output_channel_set_muted(
1440   jack_mixer_output_channel_t output_channel,
1441   jack_mixer_channel_t channel,
1442   bool muted_value)
1443 {
1444   struct output_channel *output_channel_ptr = output_channel;
1445
1446   if (muted_value) {
1447     if (g_slist_find(output_channel_ptr->muted_channels, channel) != NULL)
1448       return;
1449     output_channel_ptr->muted_channels = g_slist_prepend(output_channel_ptr->muted_channels, channel);
1450   } else {
1451     if (g_slist_find(output_channel_ptr->muted_channels, channel) == NULL)
1452       return;
1453     output_channel_ptr->muted_channels = g_slist_remove(output_channel_ptr->muted_channels, channel);
1454   }
1455 }
1456
1457 bool
1458 output_channel_is_muted(
1459   jack_mixer_output_channel_t output_channel,
1460   jack_mixer_channel_t channel)
1461 {
1462   struct output_channel *output_channel_ptr = output_channel;
1463
1464   if (g_slist_find(output_channel_ptr->muted_channels, channel) != NULL)
1465     return true;
1466   return false;
1467 }
1468
1469 bool
1470 output_channel_is_solo(
1471   jack_mixer_output_channel_t output_channel,
1472   jack_mixer_channel_t channel)
1473 {
1474   struct output_channel *output_channel_ptr = output_channel;
1475
1476   if (g_slist_find(output_channel_ptr->soloed_channels, channel) != NULL)
1477     return true;
1478   return false;
1479 }
1480
1481 void
1482 output_channel_set_prefader(
1483   jack_mixer_output_channel_t output_channel,
1484   bool pfl_value)
1485 {
1486   struct output_channel *output_channel_ptr = output_channel;
1487   output_channel_ptr->prefader = pfl_value;
1488 }
1489
1490 bool
1491 output_channel_is_prefader(
1492   jack_mixer_output_channel_t output_channel)
1493 {
1494   struct output_channel *output_channel_ptr = output_channel;
1495   return output_channel_ptr->prefader;
1496 }