doc: note about python 3 in NEWS file
[jack_mixer.git] / jack_mixer.c
blob7c5e756362a05ea0ef6548a4637fcca2df1def3f
1 /* -*- Mode: C ; c-basic-offset: 2 -*- */
2 /*****************************************************************************
4 * This file is part of jack_mixer
6 * Copyright (C) 2006 Nedko Arnaudov <nedko@arnaudov.name>
7 * Copyright (C) 2009 Frederic Peters <fpeters@0d.be>
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
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.
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.
22 *****************************************************************************/
24 #include "config.h"
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>
38 #include <glib.h>
40 #include "jack_mixer.h"
41 //#define LOG_LEVEL LOG_LEVEL_DEBUG
42 #include "log.h"
44 #include "jack_compat.h"
46 #define VOLUME_TRANSITION_SECONDS 0.01
47 #define PEAK_FRAMES_CHUNK 4800
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)
54 #define FLOAT_EXISTS(x) (!((x) - (x)))
56 struct channel
58 struct jack_mixer * mixer_ptr;
59 char * name;
60 bool stereo;
61 bool out_mute;
62 float volume_transition_seconds;
63 unsigned int num_volume_transition_steps;
64 float volume;
65 jack_nframes_t volume_idx;
66 float volume_new;
67 float balance;
68 jack_nframes_t balance_idx;
69 float balance_new;
70 float volume_left;
71 float volume_left_new;
72 float volume_right;
73 float volume_right_new;
74 float meter_left;
75 float meter_right;
76 float abspeak;
77 jack_port_t * port_left;
78 jack_port_t * port_right;
80 jack_nframes_t peak_frames;
81 float peak_left;
82 float peak_right;
84 jack_default_audio_sample_t * tmp_mixed_frames_left;
85 jack_default_audio_sample_t * tmp_mixed_frames_right;
86 jack_default_audio_sample_t * frames_left;
87 jack_default_audio_sample_t * frames_right;
88 jack_default_audio_sample_t * prefader_frames_left;
89 jack_default_audio_sample_t * prefader_frames_right;
91 bool NaN_detected;
93 int midi_cc_volume_index;
94 int midi_cc_balance_index;
95 int midi_cc_mute_index;
96 int midi_cc_solo_index;
98 jack_default_audio_sample_t * left_buffer_ptr;
99 jack_default_audio_sample_t * right_buffer_ptr;
101 bool midi_in_got_events;
102 void (*midi_change_callback) (void*);
103 void *midi_change_callback_data;
104 bool midi_out_has_events;
106 jack_mixer_scale_t midi_scale;
109 struct output_channel {
110 struct channel channel;
111 GSList *soloed_channels;
112 GSList *muted_channels;
113 bool system; /* system channel, without any associated UI */
114 bool prefader;
117 struct jack_mixer
119 pthread_mutex_t mutex;
120 jack_client_t * jack_client;
121 GSList *input_channels_list;
122 GSList *output_channels_list;
123 GSList *soloed_channels;
125 jack_port_t * port_midi_in;
126 jack_port_t * port_midi_out;
127 int last_midi_channel;
129 struct channel* midi_cc_map[128];
132 static jack_mixer_output_channel_t create_output_channel(
133 jack_mixer_t mixer,
134 const char * channel_name,
135 bool stereo,
136 bool system);
138 static inline void
139 update_channel_buffers(
140 struct channel * channel_ptr,
141 jack_nframes_t nframes);
144 float
145 value_to_db(
146 float value)
148 if (value <= 0)
150 return -INFINITY;
153 return 20.0 * log10f(value);
156 float
157 db_to_value(
158 float db)
160 return powf(10.0, db/20.0);
163 #define channel_ptr ((struct channel *)channel)
165 const char*
166 channel_get_name(
167 jack_mixer_channel_t channel)
169 return channel_ptr->name;
172 void
173 channel_rename(
174 jack_mixer_channel_t channel,
175 const char * name)
177 char * new_name;
178 size_t channel_name_size;
179 char * port_name;
180 int ret;
182 new_name = strdup(name);
183 if (new_name == NULL)
185 return;
188 if (channel_ptr->name)
190 free(channel_ptr->name);
193 channel_ptr->name = new_name;
195 if (channel_ptr->stereo)
197 channel_name_size = strlen(name);
198 port_name = malloc(channel_name_size + 3);
199 memcpy(port_name, name, channel_name_size);
201 port_name[channel_name_size] = ' ';
202 port_name[channel_name_size+1] = 'L';
203 port_name[channel_name_size+2] = 0;
205 ret = jack_port_set_name(channel_ptr->port_left, port_name);
206 if (ret != 0)
208 /* what could we do here? */
211 port_name[channel_name_size+1] = 'R';
213 ret = jack_port_set_name(channel_ptr->port_right, port_name);
214 if (ret != 0)
216 /* what could we do here? */
219 free(port_name);
221 else
223 ret = jack_port_set_name(channel_ptr->port_left, name);
224 if (ret != 0)
226 /* what could we do here? */
231 bool
232 channel_is_stereo(
233 jack_mixer_channel_t channel)
235 return channel_ptr->stereo;
239 channel_get_balance_midi_cc(
240 jack_mixer_channel_t channel)
242 return channel_ptr->midi_cc_balance_index;
245 static void
246 channel_unset_midi_cc_map(
247 jack_mixer_channel_t channel,
248 int new_cc) {
249 if (channel_ptr->mixer_ptr->midi_cc_map[new_cc]->midi_cc_volume_index == new_cc) {
250 channel_ptr->mixer_ptr->midi_cc_map[new_cc]->midi_cc_volume_index = -1;
251 } else if (channel_ptr->mixer_ptr->midi_cc_map[new_cc]->midi_cc_balance_index == new_cc) {
252 channel_ptr->mixer_ptr->midi_cc_map[new_cc]->midi_cc_balance_index = -1;
253 } else if (channel_ptr->mixer_ptr->midi_cc_map[new_cc]->midi_cc_mute_index == new_cc) {
254 channel_ptr->mixer_ptr->midi_cc_map[new_cc]->midi_cc_mute_index = -1;
255 } else if (channel_ptr->mixer_ptr->midi_cc_map[new_cc]->midi_cc_solo_index == new_cc) {
256 channel_ptr->mixer_ptr->midi_cc_map[new_cc]->midi_cc_solo_index = -1;
260 unsigned int
261 channel_set_balance_midi_cc(
262 jack_mixer_channel_t channel,
263 int new_cc)
265 if (new_cc < 0 || new_cc > 127) {
266 return 2; /* error: outside limit CC */
268 if (channel_ptr->mixer_ptr->midi_cc_map[new_cc] != NULL) {
269 channel_unset_midi_cc_map(channel, new_cc);
271 if (channel_ptr->midi_cc_balance_index != -1) {
272 channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_balance_index] = NULL;
274 channel_ptr->mixer_ptr->midi_cc_map[new_cc] = channel_ptr;
275 channel_ptr->midi_cc_balance_index = new_cc;
276 return 0;
280 channel_get_volume_midi_cc(
281 jack_mixer_channel_t channel)
283 return channel_ptr->midi_cc_volume_index;
286 unsigned int
287 channel_set_volume_midi_cc(
288 jack_mixer_channel_t channel, int new_cc)
290 if (new_cc< 0 || new_cc > 127) {
291 return 2; /* error: outside limit CC */
293 if (channel_ptr->mixer_ptr->midi_cc_map[new_cc] != NULL) {
294 channel_unset_midi_cc_map(channel, new_cc);
296 if (channel_ptr->midi_cc_volume_index != -1) {
297 channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_volume_index] = NULL;
299 channel_ptr->mixer_ptr->midi_cc_map[new_cc] = channel_ptr;
300 channel_ptr->midi_cc_volume_index = new_cc;
301 return 0;
305 channel_get_mute_midi_cc(
306 jack_mixer_channel_t channel)
308 return channel_ptr->midi_cc_mute_index;
311 unsigned int
312 channel_set_mute_midi_cc(
313 jack_mixer_channel_t channel,
314 int new_cc)
316 if (new_cc < 0 || new_cc > 127) {
317 return 2; /* error: outside limit CC */
319 if (channel_ptr->mixer_ptr->midi_cc_map[new_cc] != NULL) {
320 channel_unset_midi_cc_map(channel, new_cc);
323 if (channel_ptr->midi_cc_mute_index != -1) {
324 channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_mute_index] = NULL;
326 channel_ptr->mixer_ptr->midi_cc_map[new_cc] = channel_ptr;
327 channel_ptr->midi_cc_mute_index = new_cc;
328 return 0;
332 channel_get_solo_midi_cc(
333 jack_mixer_channel_t channel)
335 return channel_ptr->midi_cc_solo_index;
338 unsigned int
339 channel_set_solo_midi_cc(
340 jack_mixer_channel_t channel,
341 int new_cc)
343 if (new_cc < 0 || new_cc > 127) {
344 return 2; /* error: outside limit CC */
346 if (channel_ptr->mixer_ptr->midi_cc_map[new_cc] != NULL) {
347 channel_unset_midi_cc_map(channel, new_cc);
349 if (channel_ptr->midi_cc_solo_index != -1) {
350 channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_solo_index] = NULL;
352 channel_ptr->mixer_ptr->midi_cc_map[new_cc] = channel_ptr;
353 channel_ptr->midi_cc_solo_index = new_cc;
354 return 0;
357 void
358 channel_autoset_midi_cc(
359 jack_mixer_channel_t channel)
361 struct jack_mixer *mixer_ptr;
362 int i;
364 mixer_ptr = channel_ptr->mixer_ptr;
366 for (i = 11 ; i < 128 ; i++)
368 if (mixer_ptr->midi_cc_map[i] == NULL)
370 mixer_ptr->midi_cc_map[i] = channel_ptr;
371 channel_ptr->midi_cc_volume_index = i;
373 LOG_NOTICE("New channel \"%s\" volume mapped to CC#%i", channel_ptr->name, i);
375 break;
379 for (; i < 128 ; i++)
381 if (mixer_ptr->midi_cc_map[i] == NULL)
383 mixer_ptr->midi_cc_map[i] = channel_ptr;
384 channel_ptr->midi_cc_balance_index = i;
386 LOG_NOTICE("New channel \"%s\" balance mapped to CC#%i", channel_ptr->name, i);
388 break;
392 for (; i < 128 ; i++)
394 if (mixer_ptr->midi_cc_map[i] == NULL)
396 mixer_ptr->midi_cc_map[i] = channel_ptr;
397 channel_ptr->midi_cc_mute_index = i;
399 LOG_NOTICE("New channel \"%s\" mute mapped to CC#%i", channel_ptr->name, i);
401 break;
405 for (; i < 128 ; i++)
407 if (mixer_ptr->midi_cc_map[i] == NULL)
409 mixer_ptr->midi_cc_map[i] = channel_ptr;
410 channel_ptr->midi_cc_solo_index = i;
412 LOG_NOTICE("New channel \"%s\" solo mapped to CC#%i", channel_ptr->name, i);
414 break;
419 void
420 remove_channel(
421 jack_mixer_channel_t channel)
423 GSList *list_ptr;
424 channel_ptr->mixer_ptr->input_channels_list = g_slist_remove(
425 channel_ptr->mixer_ptr->input_channels_list, channel_ptr);
426 free(channel_ptr->name);
428 /* remove references to input channel from all output channels */
429 for (list_ptr = channel_ptr->mixer_ptr->output_channels_list; list_ptr; list_ptr = g_slist_next(list_ptr))
431 struct output_channel *output_channel_ptr = list_ptr->data;
432 output_channel_set_solo(output_channel_ptr, channel, false);
433 output_channel_set_muted(output_channel_ptr, channel, false);
436 jack_port_unregister(channel_ptr->mixer_ptr->jack_client, channel_ptr->port_left);
437 if (channel_ptr->stereo)
439 jack_port_unregister(channel_ptr->mixer_ptr->jack_client, channel_ptr->port_right);
442 if (channel_ptr->midi_cc_volume_index != -1)
444 assert(channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_volume_index] == channel_ptr);
445 channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_volume_index] = NULL;
448 if (channel_ptr->midi_cc_balance_index != -1)
450 assert(channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_balance_index] == channel_ptr);
451 channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_balance_index] = NULL;
454 if (channel_ptr->midi_cc_mute_index != -1)
456 assert(channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_mute_index] == channel_ptr);
457 channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_mute_index] = NULL;
459 if (channel_ptr->midi_cc_solo_index != -1)
461 assert(channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_solo_index] == channel_ptr);
462 channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_solo_index] = NULL;
464 free(channel_ptr);
467 void
468 channel_stereo_meter_read(
469 jack_mixer_channel_t channel,
470 double * left_ptr,
471 double * right_ptr)
473 assert(channel_ptr);
474 *left_ptr = value_to_db(channel_ptr->meter_left);
475 *right_ptr = value_to_db(channel_ptr->meter_right);
478 void
479 channel_mono_meter_read(
480 jack_mixer_channel_t channel,
481 double * mono_ptr)
483 *mono_ptr = value_to_db(channel_ptr->meter_left);
486 void
487 channel_volume_write(
488 jack_mixer_channel_t channel,
489 double volume)
491 assert(channel_ptr);
492 /*If changing volume and find we're in the middle of a previous transition,
493 *then set current volume to place in transition to avoid a jump.*/
494 if (channel_ptr->volume_new != channel_ptr->volume) {
495 channel_ptr->volume = channel_ptr->volume + channel_ptr->volume_idx *
496 (channel_ptr->volume_new - channel_ptr->volume) /
497 channel_ptr->num_volume_transition_steps;
499 channel_ptr->volume_idx = 0;
500 channel_ptr->volume_new = db_to_value(volume);
501 channel_ptr->midi_out_has_events = true;
504 double
505 channel_volume_read(
506 jack_mixer_channel_t channel)
508 assert(channel_ptr);
509 return value_to_db(channel_ptr->volume_new);
512 void
513 channel_balance_write(
514 jack_mixer_channel_t channel,
515 double balance)
517 assert(channel_ptr);
518 if (channel_ptr->balance != channel_ptr->balance_new) {
519 channel_ptr->balance = channel_ptr->balance + channel_ptr->balance_idx *
520 (channel_ptr->balance_new - channel_ptr->balance) /
521 channel_ptr->num_volume_transition_steps;
523 channel_ptr->balance_idx = 0;
524 channel_ptr->balance_new = balance;
527 double
528 channel_balance_read(
529 jack_mixer_channel_t channel)
531 assert(channel_ptr);
532 return channel_ptr->balance_new;
535 double
536 channel_abspeak_read(
537 jack_mixer_channel_t channel)
539 assert(channel_ptr);
540 if (channel_ptr->NaN_detected)
542 return sqrt(-1);
544 else
546 return value_to_db(channel_ptr->abspeak);
550 void
551 channel_abspeak_reset(
552 jack_mixer_channel_t channel)
554 channel_ptr->abspeak = 0;
555 channel_ptr->NaN_detected = false;
558 void
559 channel_out_mute(
560 jack_mixer_channel_t channel)
562 channel_ptr->out_mute = true;
565 void
566 channel_out_unmute(
567 jack_mixer_channel_t channel)
569 channel_ptr->out_mute = false;
572 bool
573 channel_is_out_muted(
574 jack_mixer_channel_t channel)
576 return channel_ptr->out_mute;
579 void
580 channel_solo(
581 jack_mixer_channel_t channel)
583 if (g_slist_find(channel_ptr->mixer_ptr->soloed_channels, channel) != NULL)
584 return;
585 channel_ptr->mixer_ptr->soloed_channels = g_slist_prepend(channel_ptr->mixer_ptr->soloed_channels, channel);
588 void
589 channel_unsolo(
590 jack_mixer_channel_t channel)
592 if (g_slist_find(channel_ptr->mixer_ptr->soloed_channels, channel) == NULL)
593 return;
594 channel_ptr->mixer_ptr->soloed_channels = g_slist_remove(channel_ptr->mixer_ptr->soloed_channels, channel);
597 bool
598 channel_is_soloed(
599 jack_mixer_channel_t channel)
601 if (g_slist_find(channel_ptr->mixer_ptr->soloed_channels, channel))
602 return true;
603 return false;
606 void
607 channel_set_midi_scale(
608 jack_mixer_channel_t channel,
609 jack_mixer_scale_t scale)
611 channel_ptr->midi_scale = scale;
614 void
615 channel_set_midi_change_callback(
616 jack_mixer_channel_t channel,
617 void (*midi_change_callback) (void*),
618 void *user_data)
620 channel_ptr->midi_change_callback = midi_change_callback;
621 channel_ptr->midi_change_callback_data = user_data;
624 bool
625 channel_get_midi_in_got_events(
626 jack_mixer_channel_t channel)
628 bool t = channel_ptr->midi_in_got_events;
629 channel_ptr->midi_in_got_events = false;
630 return t;
633 #undef channel_ptr
635 /* process input channels and mix them into main mix */
636 static inline void
637 mix_one(
638 struct output_channel *output_mix_channel,
639 GSList *channels_list,
640 jack_nframes_t start, /* index of first sample to process */
641 jack_nframes_t end) /* index of sample to stop processing before */
643 jack_nframes_t i;
644 GSList *node_ptr;
645 struct channel * channel_ptr;
646 jack_default_audio_sample_t frame_left;
647 jack_default_audio_sample_t frame_right;
648 struct channel *mix_channel = (struct channel*)output_mix_channel;
650 for (i = start; i < end; i++)
652 mix_channel->left_buffer_ptr[i] = mix_channel->tmp_mixed_frames_left[i] = 0.0;
653 if (mix_channel->stereo)
654 mix_channel->right_buffer_ptr[i] = mix_channel->tmp_mixed_frames_right[i] = 0.0;
657 for (node_ptr = channels_list; node_ptr; node_ptr = g_slist_next(node_ptr))
659 channel_ptr = node_ptr->data;
661 if (g_slist_find(output_mix_channel->muted_channels, channel_ptr) != NULL || channel_ptr->out_mute) {
662 /* skip muted channels */
663 continue;
666 if ((!channel_ptr->mixer_ptr->soloed_channels && !output_mix_channel->soloed_channels) ||
667 (channel_ptr->mixer_ptr->soloed_channels &&
668 g_slist_find(channel_ptr->mixer_ptr->soloed_channels, channel_ptr) != NULL) ||
669 (output_mix_channel->soloed_channels &&
670 g_slist_find(output_mix_channel->soloed_channels, channel_ptr) != NULL)) {
672 for (i = start ; i < end ; i++)
674 if (! output_mix_channel->prefader) {
675 frame_left = channel_ptr->frames_left[i-start];
676 } else {
677 frame_left = channel_ptr->prefader_frames_left[i-start];
679 if (frame_left == NAN)
680 break;
681 mix_channel->tmp_mixed_frames_left[i] += frame_left;
682 if (mix_channel->stereo)
684 if (! output_mix_channel->prefader) {
685 frame_right = channel_ptr->frames_right[i-start];
686 } else {
687 frame_right = channel_ptr->prefader_frames_right[i-start];
689 if (frame_right == NAN)
690 break;
691 mix_channel->tmp_mixed_frames_right[i] += frame_right;
697 /* process main mix channel */
698 unsigned int steps = mix_channel->num_volume_transition_steps;
699 for (i = start ; i < end ; i++)
701 if (! output_mix_channel->prefader) {
702 float volume = mix_channel->volume;
703 float volume_new = mix_channel->volume_new;
704 float vol = volume;
705 float balance = mix_channel->balance;
706 float balance_new = mix_channel->balance_new;
707 float bal = balance;
708 if (volume != volume_new) {
709 vol = mix_channel->volume_idx * (volume_new - volume) / steps + volume;
711 if (balance != balance_new) {
712 bal = mix_channel->balance_idx * (balance_new - balance) / steps + balance;
715 float vol_l;
716 float vol_r;
717 if (mix_channel->stereo) {
718 if (bal > 0) {
719 vol_l = vol * (1 - bal);
720 vol_r = vol;
721 } else {
722 vol_l = vol;
723 vol_r = vol * (1 + bal);
725 } else {
726 vol_l = vol * (1 - bal);
727 vol_r = vol * (1 + bal);
729 mix_channel->tmp_mixed_frames_left[i] *= vol_l;
730 mix_channel->tmp_mixed_frames_right[i] *= vol_r;
733 frame_left = fabsf(mix_channel->tmp_mixed_frames_left[i]);
734 if (mix_channel->peak_left < frame_left)
736 mix_channel->peak_left = frame_left;
738 if (frame_left > mix_channel->abspeak)
740 mix_channel->abspeak = frame_left;
744 if (mix_channel->stereo)
746 frame_right = fabsf(mix_channel->tmp_mixed_frames_right[i]);
747 if (mix_channel->peak_right < frame_right)
749 mix_channel->peak_right = frame_right;
751 if (frame_right > mix_channel->abspeak)
753 mix_channel->abspeak = frame_right;
758 mix_channel->peak_frames++;
759 if (mix_channel->peak_frames >= PEAK_FRAMES_CHUNK)
761 mix_channel->meter_left = mix_channel->peak_left;
762 mix_channel->peak_left = 0.0;
764 if (mix_channel->stereo)
766 mix_channel->meter_right = mix_channel->peak_right;
767 mix_channel->peak_right = 0.0;
770 mix_channel->peak_frames = 0;
772 mix_channel->volume_idx++;
773 if ((mix_channel->volume != mix_channel->volume_new) && (mix_channel->volume_idx == steps)) {
774 mix_channel->volume = mix_channel->volume_new;
775 mix_channel->volume_idx = 0;
777 mix_channel->balance_idx++;
778 if ((mix_channel->balance != mix_channel->balance_new) && (mix_channel->balance_idx == steps)) {
779 mix_channel->balance = mix_channel->balance_new;
780 mix_channel->balance_idx = 0;
783 if (!mix_channel->out_mute) {
784 mix_channel->left_buffer_ptr[i] = mix_channel->tmp_mixed_frames_left[i];
785 if (mix_channel->stereo)
786 mix_channel->right_buffer_ptr[i] = mix_channel->tmp_mixed_frames_right[i];
791 static inline void
792 calc_channel_frames(
793 struct channel *channel_ptr,
794 jack_nframes_t start,
795 jack_nframes_t end)
797 jack_nframes_t i;
798 jack_default_audio_sample_t frame_left;
799 jack_default_audio_sample_t frame_right;
800 unsigned int steps = channel_ptr->num_volume_transition_steps;
801 for (i = start ; i < end ; i++)
803 if (i-start >= MAX_BLOCK_SIZE)
805 fprintf(stderr, "i-start too high: %d - %d\n", i, start);
807 channel_ptr->prefader_frames_left[i-start] = channel_ptr->left_buffer_ptr[i];
808 if (channel_ptr->stereo)
809 channel_ptr->prefader_frames_right[i-start] = channel_ptr->right_buffer_ptr[i];
811 if (!FLOAT_EXISTS(channel_ptr->left_buffer_ptr[i]))
813 channel_ptr->NaN_detected = true;
814 channel_ptr->frames_left[i-start] = NAN;
815 break;
817 float volume = channel_ptr->volume;
818 float volume_new = channel_ptr->volume_new;
819 float vol = volume;
820 float balance = channel_ptr->balance;
821 float balance_new = channel_ptr->balance_new;
822 float bal = balance;
823 if (channel_ptr->volume != channel_ptr->volume_new) {
824 vol = channel_ptr->volume_idx * (volume_new - volume) / steps + volume;
826 if (channel_ptr->balance != channel_ptr->balance_new) {
827 bal = channel_ptr->balance_idx * (balance_new - balance) / steps + balance;
829 float vol_l;
830 float vol_r;
831 if (channel_ptr->stereo) {
832 if (bal > 0) {
833 vol_l = vol * (1 - bal);
834 vol_r = vol;
835 } else {
836 vol_l = vol;
837 vol_r = vol * (1 + bal);
839 } else {
840 vol_l = vol * (1 - bal);
841 vol_r = vol * (1 + bal);
843 frame_left = channel_ptr->left_buffer_ptr[i] * vol_l;
844 if (channel_ptr->stereo)
846 if (!FLOAT_EXISTS(channel_ptr->right_buffer_ptr[i]))
848 channel_ptr->NaN_detected = true;
849 channel_ptr->frames_right[i-start] = NAN;
850 break;
853 frame_right = channel_ptr->right_buffer_ptr[i] * vol_r;
855 else
857 frame_right = channel_ptr->left_buffer_ptr[i] * vol_r;
859 channel_ptr->frames_left[i-start] = frame_left;
860 channel_ptr->frames_right[i-start] = frame_right;
862 if (channel_ptr->stereo)
864 frame_left = fabsf(frame_left);
865 frame_right = fabsf(frame_right);
867 if (channel_ptr->peak_left < frame_left)
869 channel_ptr->peak_left = frame_left;
871 if (frame_left > channel_ptr->abspeak)
873 channel_ptr->abspeak = frame_left;
877 if (channel_ptr->peak_right < frame_right)
879 channel_ptr->peak_right = frame_right;
881 if (frame_right > channel_ptr->abspeak)
883 channel_ptr->abspeak = frame_right;
887 else
889 frame_left = (fabsf(frame_left) + fabsf(frame_right)) / 2;
891 if (channel_ptr->peak_left < frame_left)
893 channel_ptr->peak_left = frame_left;
895 if (frame_left > channel_ptr->abspeak)
897 channel_ptr->abspeak = frame_left;
902 channel_ptr->peak_frames++;
903 if (channel_ptr->peak_frames >= PEAK_FRAMES_CHUNK)
905 channel_ptr->meter_left = channel_ptr->peak_left;
906 channel_ptr->peak_left = 0.0;
908 if (channel_ptr->stereo)
910 channel_ptr->meter_right = channel_ptr->peak_right;
911 channel_ptr->peak_right = 0.0;
914 channel_ptr->peak_frames = 0;
916 channel_ptr->volume_idx++;
917 if ((channel_ptr->volume != channel_ptr->volume_new) &&
918 (channel_ptr->volume_idx == steps)) {
919 channel_ptr->volume = channel_ptr->volume_new;
920 channel_ptr->volume_idx = 0;
922 channel_ptr->balance_idx++;
923 if ((channel_ptr->balance != channel_ptr->balance_new) &&
924 (channel_ptr->balance_idx >= steps)) {
925 channel_ptr->balance = channel_ptr->balance_new;
926 channel_ptr->balance_idx = 0;
931 static inline void
932 mix(
933 struct jack_mixer * mixer_ptr,
934 jack_nframes_t start, /* index of first sample to process */
935 jack_nframes_t end) /* index of sample to stop processing before */
937 GSList *node_ptr;
938 struct output_channel * output_channel_ptr;
939 struct channel *channel_ptr;
941 for (node_ptr = mixer_ptr->input_channels_list; node_ptr; node_ptr = g_slist_next(node_ptr))
943 channel_ptr = (struct channel*)node_ptr->data;
944 calc_channel_frames(channel_ptr, start, end);
947 for (node_ptr = mixer_ptr->output_channels_list; node_ptr; node_ptr = g_slist_next(node_ptr))
949 output_channel_ptr = node_ptr->data;
950 channel_ptr = (struct channel*)output_channel_ptr;
952 if (output_channel_ptr->system)
954 /* Don't bother mixing the channels if we are not connected */
955 if (channel_ptr->stereo)
957 if (jack_port_connected(channel_ptr->port_left) == 0 &&
958 jack_port_connected(channel_ptr->port_right) == 0)
959 continue;
960 } else {
961 if (jack_port_connected(channel_ptr->port_left) == 0)
962 continue;
966 mix_one(output_channel_ptr, mixer_ptr->input_channels_list, start, end);
970 static inline void
971 update_channel_buffers(
972 struct channel * channel_ptr,
973 jack_nframes_t nframes)
975 channel_ptr->left_buffer_ptr = jack_port_get_buffer(channel_ptr->port_left, nframes);
977 if (channel_ptr->stereo)
979 channel_ptr->right_buffer_ptr = jack_port_get_buffer(channel_ptr->port_right, nframes);
983 #define mixer_ptr ((struct jack_mixer *)context)
985 static int
986 process(
987 jack_nframes_t nframes,
988 void * context)
990 jack_nframes_t i;
991 GSList *node_ptr;
992 struct channel * channel_ptr;
993 #if defined(HAVE_JACK_MIDI)
994 jack_nframes_t event_count;
995 jack_midi_event_t in_event;
996 unsigned char* midi_out_buffer;
997 void * midi_buffer;
998 signed char byte;
999 unsigned int cc_channel_index;
1000 #endif
1002 for (node_ptr = mixer_ptr->input_channels_list; node_ptr; node_ptr = g_slist_next(node_ptr))
1004 channel_ptr = node_ptr->data;
1005 update_channel_buffers(channel_ptr, nframes);
1008 // Fill output buffers with the input
1009 for (node_ptr = mixer_ptr->output_channels_list; node_ptr; node_ptr = g_slist_next(node_ptr))
1011 channel_ptr = node_ptr->data;
1012 update_channel_buffers(channel_ptr, nframes);
1015 #if defined(HAVE_JACK_MIDI)
1016 midi_buffer = jack_port_get_buffer(mixer_ptr->port_midi_in, nframes);
1017 event_count = jack_midi_get_event_count(midi_buffer);
1019 for (i = 0 ; i < event_count; i++)
1021 jack_midi_event_get(&in_event, midi_buffer, i);
1023 if (in_event.size != 3 ||
1024 (in_event.buffer[0] & 0xF0) != 0xB0 ||
1025 in_event.buffer[1] > 127 ||
1026 in_event.buffer[2] > 127)
1028 continue;
1031 assert(in_event.time < nframes);
1033 LOG_DEBUG(
1034 "%u: CC#%u -> %u",
1035 (unsigned int)(in_event.buffer[0]),
1036 (unsigned int)in_event.buffer[1],
1037 (unsigned int)in_event.buffer[2]);
1039 mixer_ptr->last_midi_channel = (unsigned int)in_event.buffer[1];
1040 channel_ptr = mixer_ptr->midi_cc_map[in_event.buffer[1]];
1042 /* if we have mapping for particular CC and MIDI scale is set for corresponding channel */
1043 if (channel_ptr != NULL && channel_ptr->midi_scale != NULL)
1045 if (channel_ptr->midi_cc_balance_index == (unsigned int)in_event.buffer[1])
1047 byte = in_event.buffer[2];
1048 if (byte == 0)
1050 byte = 1;
1052 byte -= 64;
1054 if (channel_ptr->balance != channel_ptr->balance_new) {
1055 channel_ptr->balance = channel_ptr->balance + channel_ptr->balance_idx *
1056 (channel_ptr->balance_new - channel_ptr->balance) /
1057 channel_ptr->num_volume_transition_steps;
1059 channel_ptr->balance_idx = 0;
1060 channel_ptr->balance_new = (float)byte / 63;
1061 LOG_DEBUG("\"%s\" balance -> %f", channel_ptr->name, channel_ptr->balance_new);
1063 else if (channel_ptr->midi_cc_volume_index == in_event.buffer[1])
1065 if (channel_ptr->volume_new != channel_ptr->volume) {
1066 channel_ptr->volume = channel_ptr->volume + channel_ptr->volume_idx *
1067 (channel_ptr->volume_new - channel_ptr->volume) /
1068 channel_ptr->num_volume_transition_steps;
1070 channel_ptr->volume_idx = 0;
1071 channel_ptr->volume_new = db_to_value(scale_scale_to_db(channel_ptr->midi_scale,
1072 (double)in_event.buffer[2] / 127));
1073 LOG_DEBUG("\"%s\" volume -> %f", channel_ptr->name, channel_ptr->volume_new);
1075 else if (channel_ptr->midi_cc_mute_index == in_event.buffer[1])
1077 if ((unsigned int)in_event.buffer[2] == 127) {
1078 channel_ptr->out_mute = !channel_ptr->out_mute;
1080 LOG_DEBUG("\"%s\" out_mute %d", channel_ptr->name, channel_ptr->out_mute);
1082 else if (channel_ptr->midi_cc_solo_index == in_event.buffer[1])
1084 if ((unsigned int)in_event.buffer[2] == 127) {
1085 if (channel_is_soloed(channel_ptr)) {
1086 channel_unsolo(channel_ptr);
1087 } else {
1088 channel_solo(channel_ptr);
1091 LOG_DEBUG("\"%s\" solo %d", channel_ptr->name, channel_is_soloed(channel_ptr));
1093 channel_ptr->midi_in_got_events = true;
1094 if (channel_ptr->midi_change_callback)
1095 channel_ptr->midi_change_callback(channel_ptr->midi_change_callback_data);
1101 midi_buffer = jack_port_get_buffer(mixer_ptr->port_midi_out, nframes);
1102 jack_midi_clear_buffer(midi_buffer);
1104 for(i=0; i<nframes; i++)
1106 for (cc_channel_index=0; cc_channel_index<128; cc_channel_index++)
1108 channel_ptr = mixer_ptr->midi_cc_map[cc_channel_index];
1109 if (channel_ptr == NULL || channel_ptr->midi_scale == NULL)
1111 continue;
1113 if (channel_ptr->midi_out_has_events == false)
1115 continue;
1117 if (channel_ptr->midi_cc_balance_index == (unsigned int)cc_channel_index)
1119 continue;
1121 midi_out_buffer = jack_midi_event_reserve(midi_buffer, i, 3);
1122 if (midi_out_buffer == NULL)
1124 continue;
1126 midi_out_buffer[0] = 0xB0; /* control change */
1127 midi_out_buffer[1] = cc_channel_index;
1128 midi_out_buffer[2] = (unsigned char)(127*scale_db_to_scale(channel_ptr->midi_scale, value_to_db(channel_ptr->volume_new)));
1130 LOG_DEBUG(
1131 "%u: CC#%u <- %u",
1132 (unsigned int)(midi_out_buffer[0]),
1133 (unsigned int)midi_out_buffer[1],
1134 (unsigned int)midi_out_buffer[2]);
1136 channel_ptr->midi_out_has_events = false;
1140 #endif
1142 mix(mixer_ptr, 0, nframes);
1144 return 0;
1147 #undef mixer_ptr
1149 jack_mixer_t
1150 create(
1151 const char * jack_client_name_ptr,
1152 bool stereo)
1154 int ret;
1155 struct jack_mixer * mixer_ptr;
1156 int i;
1159 mixer_ptr = malloc(sizeof(struct jack_mixer));
1160 if (mixer_ptr == NULL)
1162 goto exit;
1165 ret = pthread_mutex_init(&mixer_ptr->mutex, NULL);
1166 if (ret != 0)
1168 goto exit_free;
1171 mixer_ptr->input_channels_list = NULL;
1172 mixer_ptr->output_channels_list = NULL;
1174 mixer_ptr->soloed_channels = NULL;
1176 mixer_ptr->last_midi_channel = -1;
1178 for (i = 0 ; i < 128 ; i++)
1180 mixer_ptr->midi_cc_map[i] = NULL;
1183 LOG_DEBUG("Initializing JACK");
1184 mixer_ptr->jack_client = jack_client_open(jack_client_name_ptr, 0, NULL);
1185 if (mixer_ptr->jack_client == NULL)
1187 LOG_ERROR("Cannot create JACK client.");
1188 LOG_NOTICE("Please make sure JACK daemon is running.");
1189 goto exit_destroy_mutex;
1192 LOG_DEBUG("JACK client created");
1194 LOG_DEBUG("Sample rate: %" PRIu32, jack_get_sample_rate(mixer_ptr->jack_client));
1197 #if defined(HAVE_JACK_MIDI)
1198 mixer_ptr->port_midi_in = jack_port_register(mixer_ptr->jack_client, "midi in", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0);
1199 if (mixer_ptr->port_midi_in == NULL)
1201 LOG_ERROR("Cannot create JACK MIDI in port");
1202 goto close_jack;
1205 mixer_ptr->port_midi_out = jack_port_register(mixer_ptr->jack_client, "midi out", JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0);
1206 if (mixer_ptr->port_midi_out == NULL)
1208 LOG_ERROR("Cannot create JACK MIDI out port");
1209 goto close_jack;
1212 #endif
1214 ret = jack_set_process_callback(mixer_ptr->jack_client, process, mixer_ptr);
1215 if (ret != 0)
1217 LOG_ERROR("Cannot set JACK process callback");
1218 goto close_jack;
1221 ret = jack_activate(mixer_ptr->jack_client);
1222 if (ret != 0)
1224 LOG_ERROR("Cannot activate JACK client");
1225 goto close_jack;
1228 return mixer_ptr;
1230 close_jack:
1231 jack_client_close(mixer_ptr->jack_client); /* this should clear all other resources we obtained through the client handle */
1233 exit_destroy_mutex:
1234 pthread_mutex_destroy(&mixer_ptr->mutex);
1236 exit_free:
1237 free(mixer_ptr);
1239 exit:
1240 return NULL;
1243 #define mixer_ctx_ptr ((struct jack_mixer *)mixer)
1245 void
1246 destroy(
1247 jack_mixer_t mixer)
1249 LOG_DEBUG("Uninitializing JACK");
1251 assert(mixer_ctx_ptr->jack_client != NULL);
1253 jack_client_close(mixer_ctx_ptr->jack_client);
1255 pthread_mutex_destroy(&mixer_ctx_ptr->mutex);
1257 free(mixer_ctx_ptr);
1261 unsigned int
1262 get_channels_count(
1263 jack_mixer_t mixer)
1265 return g_slist_length(mixer_ctx_ptr->input_channels_list);
1268 const char*
1269 get_client_name(
1270 jack_mixer_t mixer)
1272 return jack_get_client_name(mixer_ctx_ptr->jack_client);
1276 get_last_midi_channel(
1277 jack_mixer_t mixer)
1279 return mixer_ctx_ptr->last_midi_channel;
1282 unsigned int
1283 set_last_midi_channel(
1284 jack_mixer_t mixer,
1285 int new_channel) {
1286 mixer_ctx_ptr->last_midi_channel = new_channel;
1287 return 0;
1290 jack_mixer_channel_t
1291 add_channel(
1292 jack_mixer_t mixer,
1293 const char * channel_name,
1294 bool stereo)
1296 struct channel * channel_ptr;
1297 char * port_name;
1298 size_t channel_name_size;
1300 channel_ptr = malloc(sizeof(struct channel));
1301 if (channel_ptr == NULL)
1303 goto fail;
1306 channel_ptr->mixer_ptr = mixer_ctx_ptr;
1308 channel_ptr->name = strdup(channel_name);
1309 if (channel_ptr->name == NULL)
1311 goto fail_free_channel;
1314 channel_name_size = strlen(channel_name);
1316 if (stereo)
1318 port_name = malloc(channel_name_size + 3);
1319 if (port_name == NULL)
1321 goto fail_free_channel_name;
1324 memcpy(port_name, channel_name, channel_name_size);
1325 port_name[channel_name_size] = ' ';
1326 port_name[channel_name_size+1] = 'L';
1327 port_name[channel_name_size+2] = 0;
1329 channel_ptr->port_left = jack_port_register(channel_ptr->mixer_ptr->jack_client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
1330 if (channel_ptr->port_left == NULL)
1332 goto fail_free_port_name;
1335 port_name[channel_name_size+1] = 'R';
1337 channel_ptr->port_right = jack_port_register(channel_ptr->mixer_ptr->jack_client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
1338 if (channel_ptr->port_right == NULL)
1340 goto fail_unregister_left_channel;
1343 else
1345 channel_ptr->port_left = jack_port_register(channel_ptr->mixer_ptr->jack_client, channel_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
1346 if (channel_ptr->port_left == NULL)
1348 goto fail_free_channel_name;
1352 channel_ptr->stereo = stereo;
1354 channel_ptr->volume_transition_seconds = VOLUME_TRANSITION_SECONDS;
1355 channel_ptr->num_volume_transition_steps =
1356 channel_ptr->volume_transition_seconds *
1357 jack_get_sample_rate(channel_ptr->mixer_ptr->jack_client) + 1;
1358 channel_ptr->volume = 0.0;
1359 channel_ptr->volume_new = 0.0;
1360 channel_ptr->balance = 0.0;
1361 channel_ptr->balance_new = 0.0;
1362 channel_ptr->meter_left = -1.0;
1363 channel_ptr->meter_right = -1.0;
1364 channel_ptr->abspeak = 0.0;
1365 channel_ptr->out_mute = false;
1367 channel_ptr->peak_left = 0.0;
1368 channel_ptr->peak_right = 0.0;
1369 channel_ptr->peak_frames = 0;
1371 channel_ptr->frames_left = calloc(MAX_BLOCK_SIZE, sizeof(jack_default_audio_sample_t));
1372 channel_ptr->frames_right = calloc(MAX_BLOCK_SIZE, sizeof(jack_default_audio_sample_t));
1373 channel_ptr->prefader_frames_left = calloc(MAX_BLOCK_SIZE, sizeof(jack_default_audio_sample_t));
1374 channel_ptr->prefader_frames_right = calloc(MAX_BLOCK_SIZE, sizeof(jack_default_audio_sample_t));
1376 channel_ptr->NaN_detected = false;
1378 channel_ptr->midi_cc_volume_index = -1;
1379 channel_ptr->midi_cc_balance_index = -1;
1380 channel_ptr->midi_cc_mute_index = -1;
1381 channel_ptr->midi_cc_solo_index = -1;
1383 channel_ptr->midi_change_callback = NULL;
1384 channel_ptr->midi_change_callback_data = NULL;
1385 channel_ptr->midi_out_has_events = false;
1387 channel_ptr->midi_scale = NULL;
1389 channel_ptr->mixer_ptr->input_channels_list = g_slist_prepend(
1390 channel_ptr->mixer_ptr->input_channels_list, channel_ptr);
1392 return channel_ptr;
1394 fail_unregister_left_channel:
1395 jack_port_unregister(channel_ptr->mixer_ptr->jack_client, channel_ptr->port_left);
1397 fail_free_port_name:
1398 free(port_name);
1400 fail_free_channel_name:
1401 free(channel_ptr->name);
1403 fail_free_channel:
1404 free(channel_ptr);
1405 channel_ptr = NULL;
1407 fail:
1408 return NULL;
1411 static jack_mixer_output_channel_t
1412 create_output_channel(
1413 jack_mixer_t mixer,
1414 const char * channel_name,
1415 bool stereo,
1416 bool system)
1418 struct channel * channel_ptr;
1419 struct output_channel * output_channel_ptr;
1420 char * port_name;
1421 size_t channel_name_size;
1423 output_channel_ptr = malloc(sizeof(struct output_channel));
1424 channel_ptr = (struct channel*)output_channel_ptr;
1425 if (channel_ptr == NULL)
1427 goto fail;
1430 channel_ptr->mixer_ptr = mixer_ctx_ptr;
1432 channel_ptr->name = strdup(channel_name);
1433 if (channel_ptr->name == NULL)
1435 goto fail_free_channel;
1438 if (stereo)
1440 channel_name_size = strlen(channel_name);
1442 port_name = malloc(channel_name_size + 4);
1443 if (port_name == NULL)
1445 goto fail_free_channel_name;
1448 memcpy(port_name, channel_name, channel_name_size);
1449 port_name[channel_name_size] = ' ';
1450 port_name[channel_name_size+1] = 'L';
1451 port_name[channel_name_size+2] = 0;
1453 channel_ptr->port_left = jack_port_register(channel_ptr->mixer_ptr->jack_client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
1454 if (channel_ptr->port_left == NULL)
1456 goto fail_free_port_name;
1459 port_name[channel_name_size+1] = 'R';
1461 channel_ptr->port_right = jack_port_register(channel_ptr->mixer_ptr->jack_client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
1462 if (channel_ptr->port_right == NULL)
1464 goto fail_unregister_left_channel;
1467 else
1469 channel_ptr->port_left = jack_port_register(channel_ptr->mixer_ptr->jack_client, channel_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
1470 if (channel_ptr->port_left == NULL)
1472 goto fail_free_channel_name;
1476 channel_ptr->stereo = stereo;
1477 channel_ptr->out_mute = false;
1479 channel_ptr->volume_transition_seconds = VOLUME_TRANSITION_SECONDS;
1480 channel_ptr->num_volume_transition_steps =
1481 channel_ptr->volume_transition_seconds *
1482 jack_get_sample_rate(channel_ptr->mixer_ptr->jack_client) + 1;
1483 channel_ptr->volume = 0.0;
1484 channel_ptr->volume_new = 0.0;
1485 channel_ptr->balance = 0.0;
1486 channel_ptr->balance_new = 0.0;
1487 channel_ptr->meter_left = -1.0;
1488 channel_ptr->meter_right = -1.0;
1489 channel_ptr->abspeak = 0.0;
1491 channel_ptr->peak_left = 0.0;
1492 channel_ptr->peak_right = 0.0;
1493 channel_ptr->peak_frames = 0;
1495 channel_ptr->tmp_mixed_frames_left = calloc(MAX_BLOCK_SIZE, sizeof(jack_default_audio_sample_t));
1496 channel_ptr->tmp_mixed_frames_right = calloc(MAX_BLOCK_SIZE, sizeof(jack_default_audio_sample_t));
1497 channel_ptr->frames_left = calloc(MAX_BLOCK_SIZE, sizeof(jack_default_audio_sample_t));
1498 channel_ptr->frames_right = calloc(MAX_BLOCK_SIZE, sizeof(jack_default_audio_sample_t));
1499 channel_ptr->prefader_frames_left = calloc(MAX_BLOCK_SIZE, sizeof(jack_default_audio_sample_t));
1500 channel_ptr->prefader_frames_right = calloc(MAX_BLOCK_SIZE, sizeof(jack_default_audio_sample_t));
1502 channel_ptr->NaN_detected = false;
1504 channel_ptr->midi_cc_volume_index = -1;
1505 channel_ptr->midi_cc_balance_index = -1;
1506 channel_ptr->midi_cc_mute_index = -1;
1507 channel_ptr->midi_cc_solo_index = -1;
1509 channel_ptr->midi_change_callback = NULL;
1510 channel_ptr->midi_change_callback_data = NULL;
1512 channel_ptr->midi_scale = NULL;
1514 output_channel_ptr->soloed_channels = NULL;
1515 output_channel_ptr->muted_channels = NULL;
1516 output_channel_ptr->system = system;
1517 output_channel_ptr->prefader = false;
1519 return output_channel_ptr;
1521 fail_unregister_left_channel:
1522 jack_port_unregister(channel_ptr->mixer_ptr->jack_client, channel_ptr->port_left);
1524 fail_free_port_name:
1525 free(port_name);
1527 fail_free_channel_name:
1528 free(channel_ptr->name);
1530 fail_free_channel:
1531 free(channel_ptr);
1532 channel_ptr = NULL;
1534 fail:
1535 return NULL;
1538 jack_mixer_output_channel_t
1539 add_output_channel(
1540 jack_mixer_t mixer,
1541 const char * channel_name,
1542 bool stereo,
1543 bool system)
1545 struct output_channel *output_channel_ptr;
1546 struct channel *channel_ptr;
1548 output_channel_ptr = create_output_channel(mixer, channel_name, stereo, system);
1549 if (output_channel_ptr == NULL) {
1550 return NULL;
1552 channel_ptr = (struct channel*)output_channel_ptr;
1554 ((struct jack_mixer*)mixer)->output_channels_list = g_slist_prepend(
1555 ((struct jack_mixer*)mixer)->output_channels_list, channel_ptr);
1557 return output_channel_ptr;
1560 void
1561 remove_output_channel(
1562 jack_mixer_output_channel_t output_channel)
1564 struct output_channel *output_channel_ptr = output_channel;
1565 struct channel *channel_ptr = output_channel;
1567 channel_ptr->mixer_ptr->output_channels_list = g_slist_remove(
1568 channel_ptr->mixer_ptr->output_channels_list, channel_ptr);
1569 free(channel_ptr->name);
1571 jack_port_unregister(channel_ptr->mixer_ptr->jack_client, channel_ptr->port_left);
1572 if (channel_ptr->stereo)
1574 jack_port_unregister(channel_ptr->mixer_ptr->jack_client, channel_ptr->port_right);
1577 if (channel_ptr->midi_cc_volume_index != -1)
1579 assert(channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_volume_index] == channel_ptr);
1580 channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_volume_index] = NULL;
1583 if (channel_ptr->midi_cc_balance_index != -1)
1585 assert(channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_balance_index] == channel_ptr);
1586 channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_balance_index] = NULL;
1589 if (channel_ptr->midi_cc_mute_index != -1)
1591 assert(channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_mute_index] == channel_ptr);
1592 channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_mute_index] = NULL;
1595 if (channel_ptr->midi_cc_solo_index != -1)
1597 assert(channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_solo_index] == channel_ptr);
1598 channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_solo_index] = NULL;
1601 g_slist_free(output_channel_ptr->soloed_channels);
1602 g_slist_free(output_channel_ptr->muted_channels);
1604 free(channel_ptr);
1607 void
1608 output_channel_set_solo(
1609 jack_mixer_output_channel_t output_channel,
1610 jack_mixer_channel_t channel,
1611 bool solo_value)
1613 struct output_channel *output_channel_ptr = output_channel;
1615 if (solo_value) {
1616 if (g_slist_find(output_channel_ptr->soloed_channels, channel) != NULL)
1617 return;
1618 output_channel_ptr->soloed_channels = g_slist_prepend(output_channel_ptr->soloed_channels, channel);
1619 } else {
1620 if (g_slist_find(output_channel_ptr->soloed_channels, channel) == NULL)
1621 return;
1622 output_channel_ptr->soloed_channels = g_slist_remove(output_channel_ptr->soloed_channels, channel);
1626 void
1627 output_channel_set_muted(
1628 jack_mixer_output_channel_t output_channel,
1629 jack_mixer_channel_t channel,
1630 bool muted_value)
1632 struct output_channel *output_channel_ptr = output_channel;
1634 if (muted_value) {
1635 if (g_slist_find(output_channel_ptr->muted_channels, channel) != NULL)
1636 return;
1637 output_channel_ptr->muted_channels = g_slist_prepend(output_channel_ptr->muted_channels, channel);
1638 } else {
1639 if (g_slist_find(output_channel_ptr->muted_channels, channel) == NULL)
1640 return;
1641 output_channel_ptr->muted_channels = g_slist_remove(output_channel_ptr->muted_channels, channel);
1645 bool
1646 output_channel_is_muted(
1647 jack_mixer_output_channel_t output_channel,
1648 jack_mixer_channel_t channel)
1650 struct output_channel *output_channel_ptr = output_channel;
1652 if (g_slist_find(output_channel_ptr->muted_channels, channel) != NULL)
1653 return true;
1654 return false;
1657 bool
1658 output_channel_is_solo(
1659 jack_mixer_output_channel_t output_channel,
1660 jack_mixer_channel_t channel)
1662 struct output_channel *output_channel_ptr = output_channel;
1664 if (g_slist_find(output_channel_ptr->soloed_channels, channel) != NULL)
1665 return true;
1666 return false;
1669 void
1670 output_channel_set_prefader(
1671 jack_mixer_output_channel_t output_channel,
1672 bool pfl_value)
1674 struct output_channel *output_channel_ptr = output_channel;
1675 output_channel_ptr->prefader = pfl_value;
1678 bool
1679 output_channel_is_prefader(
1680 jack_mixer_output_channel_t output_channel)
1682 struct output_channel *output_channel_ptr = output_channel;
1683 return output_channel_ptr->prefader;