release: 12
[jack_mixer.git] / jack_mixer.c
blob461e395a203599cd73da9e9bb9c5c93c7a5944ec
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_rename(channel_ptr->mixer_ptr->jack_client, 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_rename(channel_ptr->mixer_ptr->jack_client, 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_rename(channel_ptr->mixer_ptr->jack_client, 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;
465 free(channel_ptr->frames_left);
466 free(channel_ptr->frames_right);
467 free(channel_ptr->prefader_frames_left);
468 free(channel_ptr->prefader_frames_right);
470 free(channel_ptr);
473 void
474 channel_stereo_meter_read(
475 jack_mixer_channel_t channel,
476 double * left_ptr,
477 double * right_ptr)
479 assert(channel_ptr);
480 *left_ptr = value_to_db(channel_ptr->meter_left);
481 *right_ptr = value_to_db(channel_ptr->meter_right);
484 void
485 channel_mono_meter_read(
486 jack_mixer_channel_t channel,
487 double * mono_ptr)
489 *mono_ptr = value_to_db(channel_ptr->meter_left);
492 void
493 channel_volume_write(
494 jack_mixer_channel_t channel,
495 double volume)
497 assert(channel_ptr);
498 /*If changing volume and find we're in the middle of a previous transition,
499 *then set current volume to place in transition to avoid a jump.*/
500 if (channel_ptr->volume_new != channel_ptr->volume) {
501 channel_ptr->volume = channel_ptr->volume + channel_ptr->volume_idx *
502 (channel_ptr->volume_new - channel_ptr->volume) /
503 channel_ptr->num_volume_transition_steps;
505 channel_ptr->volume_idx = 0;
506 channel_ptr->volume_new = db_to_value(volume);
507 channel_ptr->midi_out_has_events = true;
510 double
511 channel_volume_read(
512 jack_mixer_channel_t channel)
514 assert(channel_ptr);
515 return value_to_db(channel_ptr->volume_new);
518 void
519 channels_volumes_read(jack_mixer_t mixer_ptr)
521 GSList *node_ptr;
522 struct channel *pChannel;
523 struct jack_mixer * pMixer = (struct jack_mixer *)mixer_ptr;
525 for (node_ptr = pMixer->input_channels_list; node_ptr; node_ptr = g_slist_next(node_ptr))
527 pChannel = (struct channel *)node_ptr->data;
528 double vol = channel_volume_read( (jack_mixer_channel_t)pChannel);
529 printf("%s : volume is %f dbFS for mixer channel: %s\n", jack_get_client_name(pMixer->jack_client), vol, pChannel->name);
533 void
534 channel_balance_write(
535 jack_mixer_channel_t channel,
536 double balance)
538 assert(channel_ptr);
539 if (channel_ptr->balance != channel_ptr->balance_new) {
540 channel_ptr->balance = channel_ptr->balance + channel_ptr->balance_idx *
541 (channel_ptr->balance_new - channel_ptr->balance) /
542 channel_ptr->num_volume_transition_steps;
544 channel_ptr->balance_idx = 0;
545 channel_ptr->balance_new = balance;
548 double
549 channel_balance_read(
550 jack_mixer_channel_t channel)
552 assert(channel_ptr);
553 return channel_ptr->balance_new;
556 double
557 channel_abspeak_read(
558 jack_mixer_channel_t channel)
560 assert(channel_ptr);
561 if (channel_ptr->NaN_detected)
563 return sqrt(-1);
565 else
567 return value_to_db(channel_ptr->abspeak);
571 void
572 channel_abspeak_reset(
573 jack_mixer_channel_t channel)
575 channel_ptr->abspeak = 0;
576 channel_ptr->NaN_detected = false;
579 void
580 channel_out_mute(
581 jack_mixer_channel_t channel)
583 channel_ptr->out_mute = true;
586 void
587 channel_out_unmute(
588 jack_mixer_channel_t channel)
590 channel_ptr->out_mute = false;
593 bool
594 channel_is_out_muted(
595 jack_mixer_channel_t channel)
597 return channel_ptr->out_mute;
600 void
601 channel_solo(
602 jack_mixer_channel_t channel)
604 if (g_slist_find(channel_ptr->mixer_ptr->soloed_channels, channel) != NULL)
605 return;
606 channel_ptr->mixer_ptr->soloed_channels = g_slist_prepend(channel_ptr->mixer_ptr->soloed_channels, channel);
609 void
610 channel_unsolo(
611 jack_mixer_channel_t channel)
613 if (g_slist_find(channel_ptr->mixer_ptr->soloed_channels, channel) == NULL)
614 return;
615 channel_ptr->mixer_ptr->soloed_channels = g_slist_remove(channel_ptr->mixer_ptr->soloed_channels, channel);
618 bool
619 channel_is_soloed(
620 jack_mixer_channel_t channel)
622 if (g_slist_find(channel_ptr->mixer_ptr->soloed_channels, channel))
623 return true;
624 return false;
627 void
628 channel_set_midi_scale(
629 jack_mixer_channel_t channel,
630 jack_mixer_scale_t scale)
632 channel_ptr->midi_scale = scale;
635 void
636 channel_set_midi_change_callback(
637 jack_mixer_channel_t channel,
638 void (*midi_change_callback) (void*),
639 void *user_data)
641 channel_ptr->midi_change_callback = midi_change_callback;
642 channel_ptr->midi_change_callback_data = user_data;
645 bool
646 channel_get_midi_in_got_events(
647 jack_mixer_channel_t channel)
649 bool t = channel_ptr->midi_in_got_events;
650 channel_ptr->midi_in_got_events = false;
651 return t;
654 #undef channel_ptr
656 /* process input channels and mix them into main mix */
657 static inline void
658 mix_one(
659 struct output_channel *output_mix_channel,
660 GSList *channels_list,
661 jack_nframes_t start, /* index of first sample to process */
662 jack_nframes_t end) /* index of sample to stop processing before */
664 jack_nframes_t i;
665 GSList *node_ptr;
666 struct channel * channel_ptr;
667 jack_default_audio_sample_t frame_left;
668 jack_default_audio_sample_t frame_right;
669 struct channel *mix_channel = (struct channel*)output_mix_channel;
671 for (i = start; i < end; i++)
673 mix_channel->left_buffer_ptr[i] = mix_channel->tmp_mixed_frames_left[i] = 0.0;
674 if (mix_channel->stereo)
675 mix_channel->right_buffer_ptr[i] = mix_channel->tmp_mixed_frames_right[i] = 0.0;
678 for (node_ptr = channels_list; node_ptr; node_ptr = g_slist_next(node_ptr))
680 channel_ptr = node_ptr->data;
682 if (g_slist_find(output_mix_channel->muted_channels, channel_ptr) != NULL || channel_ptr->out_mute) {
683 /* skip muted channels */
684 continue;
687 if ((!channel_ptr->mixer_ptr->soloed_channels && !output_mix_channel->soloed_channels) ||
688 (channel_ptr->mixer_ptr->soloed_channels &&
689 g_slist_find(channel_ptr->mixer_ptr->soloed_channels, channel_ptr) != NULL) ||
690 (output_mix_channel->soloed_channels &&
691 g_slist_find(output_mix_channel->soloed_channels, channel_ptr) != NULL)) {
693 for (i = start ; i < end ; i++)
695 if (! output_mix_channel->prefader) {
696 frame_left = channel_ptr->frames_left[i-start];
697 } else {
698 frame_left = channel_ptr->prefader_frames_left[i-start];
700 if (frame_left == NAN)
701 break;
702 mix_channel->tmp_mixed_frames_left[i] += frame_left;
703 if (mix_channel->stereo)
705 if (! output_mix_channel->prefader) {
706 frame_right = channel_ptr->frames_right[i-start];
707 } else {
708 frame_right = channel_ptr->prefader_frames_right[i-start];
710 if (frame_right == NAN)
711 break;
712 mix_channel->tmp_mixed_frames_right[i] += frame_right;
718 /* process main mix channel */
719 unsigned int steps = mix_channel->num_volume_transition_steps;
720 for (i = start ; i < end ; i++)
722 if (! output_mix_channel->prefader) {
723 float volume = mix_channel->volume;
724 float volume_new = mix_channel->volume_new;
725 float vol = volume;
726 float balance = mix_channel->balance;
727 float balance_new = mix_channel->balance_new;
728 float bal = balance;
729 if (volume != volume_new) {
730 vol = mix_channel->volume_idx * (volume_new - volume) / steps + volume;
732 if (balance != balance_new) {
733 bal = mix_channel->balance_idx * (balance_new - balance) / steps + balance;
736 float vol_l;
737 float vol_r;
738 if (mix_channel->stereo) {
739 if (bal > 0) {
740 vol_l = vol * (1 - bal);
741 vol_r = vol;
742 } else {
743 vol_l = vol;
744 vol_r = vol * (1 + bal);
746 } else {
747 vol_l = vol * (1 - bal);
748 vol_r = vol * (1 + bal);
750 mix_channel->tmp_mixed_frames_left[i] *= vol_l;
751 mix_channel->tmp_mixed_frames_right[i] *= vol_r;
754 frame_left = fabsf(mix_channel->tmp_mixed_frames_left[i]);
755 if (mix_channel->peak_left < frame_left)
757 mix_channel->peak_left = frame_left;
759 if (frame_left > mix_channel->abspeak)
761 mix_channel->abspeak = frame_left;
765 if (mix_channel->stereo)
767 frame_right = fabsf(mix_channel->tmp_mixed_frames_right[i]);
768 if (mix_channel->peak_right < frame_right)
770 mix_channel->peak_right = frame_right;
772 if (frame_right > mix_channel->abspeak)
774 mix_channel->abspeak = frame_right;
779 mix_channel->peak_frames++;
780 if (mix_channel->peak_frames >= PEAK_FRAMES_CHUNK)
782 mix_channel->meter_left = mix_channel->peak_left;
783 mix_channel->peak_left = 0.0;
785 if (mix_channel->stereo)
787 mix_channel->meter_right = mix_channel->peak_right;
788 mix_channel->peak_right = 0.0;
791 mix_channel->peak_frames = 0;
793 mix_channel->volume_idx++;
794 if ((mix_channel->volume != mix_channel->volume_new) && (mix_channel->volume_idx == steps)) {
795 mix_channel->volume = mix_channel->volume_new;
796 mix_channel->volume_idx = 0;
798 mix_channel->balance_idx++;
799 if ((mix_channel->balance != mix_channel->balance_new) && (mix_channel->balance_idx == steps)) {
800 mix_channel->balance = mix_channel->balance_new;
801 mix_channel->balance_idx = 0;
804 if (!mix_channel->out_mute) {
805 mix_channel->left_buffer_ptr[i] = mix_channel->tmp_mixed_frames_left[i];
806 if (mix_channel->stereo)
807 mix_channel->right_buffer_ptr[i] = mix_channel->tmp_mixed_frames_right[i];
812 static inline void
813 calc_channel_frames(
814 struct channel *channel_ptr,
815 jack_nframes_t start,
816 jack_nframes_t end)
818 jack_nframes_t i;
819 jack_default_audio_sample_t frame_left = 0.0f;
820 jack_default_audio_sample_t frame_right = 0.0f;
821 unsigned int steps = channel_ptr->num_volume_transition_steps;
822 for (i = start ; i < end ; i++)
824 if (i-start >= MAX_BLOCK_SIZE)
826 fprintf(stderr, "i-start too high: %d - %d\n", i, start);
828 channel_ptr->prefader_frames_left[i-start] = channel_ptr->left_buffer_ptr[i];
829 if (channel_ptr->stereo)
830 channel_ptr->prefader_frames_right[i-start] = channel_ptr->right_buffer_ptr[i];
832 if (!FLOAT_EXISTS(channel_ptr->left_buffer_ptr[i]))
834 channel_ptr->NaN_detected = true;
835 channel_ptr->frames_left[i-start] = NAN;
836 break;
838 float volume = channel_ptr->volume;
839 float volume_new = channel_ptr->volume_new;
840 float vol = volume;
841 float balance = channel_ptr->balance;
842 float balance_new = channel_ptr->balance_new;
843 float bal = balance;
844 if (channel_ptr->volume != channel_ptr->volume_new) {
845 vol = channel_ptr->volume_idx * (volume_new - volume) / steps + volume;
847 if (channel_ptr->balance != channel_ptr->balance_new) {
848 bal = channel_ptr->balance_idx * (balance_new - balance) / steps + balance;
850 float vol_l;
851 float vol_r;
852 if (channel_ptr->stereo) {
853 if (bal > 0) {
854 vol_l = vol * (1 - bal);
855 vol_r = vol;
856 } else {
857 vol_l = vol;
858 vol_r = vol * (1 + bal);
860 } else {
861 vol_l = vol * (1 - bal);
862 vol_r = vol * (1 + bal);
864 frame_left = channel_ptr->left_buffer_ptr[i] * vol_l;
865 if (channel_ptr->stereo)
867 if (!FLOAT_EXISTS(channel_ptr->right_buffer_ptr[i]))
869 channel_ptr->NaN_detected = true;
870 channel_ptr->frames_right[i-start] = NAN;
871 break;
874 frame_right = channel_ptr->right_buffer_ptr[i] * vol_r;
877 channel_ptr->frames_left[i-start] = frame_left;
878 channel_ptr->frames_right[i-start] = frame_right;
880 if (channel_ptr->stereo)
882 frame_left = fabsf(frame_left);
883 frame_right = fabsf(frame_right);
885 if (channel_ptr->peak_left < frame_left)
887 channel_ptr->peak_left = frame_left;
889 if (frame_left > channel_ptr->abspeak)
891 channel_ptr->abspeak = frame_left;
895 if (channel_ptr->peak_right < frame_right)
897 channel_ptr->peak_right = frame_right;
899 if (frame_right > channel_ptr->abspeak)
901 channel_ptr->abspeak = frame_right;
905 else
907 frame_left = (fabsf(frame_left) + fabsf(frame_right)) / 2;
909 if (channel_ptr->peak_left < frame_left)
911 channel_ptr->peak_left = frame_left;
913 if (frame_left > channel_ptr->abspeak)
915 channel_ptr->abspeak = frame_left;
920 channel_ptr->peak_frames++;
921 if (channel_ptr->peak_frames >= PEAK_FRAMES_CHUNK)
923 channel_ptr->meter_left = channel_ptr->peak_left;
924 channel_ptr->peak_left = 0.0;
926 if (channel_ptr->stereo)
928 channel_ptr->meter_right = channel_ptr->peak_right;
929 channel_ptr->peak_right = 0.0;
932 channel_ptr->peak_frames = 0;
934 channel_ptr->volume_idx++;
935 if ((channel_ptr->volume != channel_ptr->volume_new) &&
936 (channel_ptr->volume_idx == steps)) {
937 channel_ptr->volume = channel_ptr->volume_new;
938 channel_ptr->volume_idx = 0;
940 channel_ptr->balance_idx++;
941 if ((channel_ptr->balance != channel_ptr->balance_new) &&
942 (channel_ptr->balance_idx >= steps)) {
943 channel_ptr->balance = channel_ptr->balance_new;
944 channel_ptr->balance_idx = 0;
949 static inline void
950 mix(
951 struct jack_mixer * mixer_ptr,
952 jack_nframes_t start, /* index of first sample to process */
953 jack_nframes_t end) /* index of sample to stop processing before */
955 GSList *node_ptr;
956 struct output_channel * output_channel_ptr;
957 struct channel *channel_ptr;
959 for (node_ptr = mixer_ptr->input_channels_list; node_ptr; node_ptr = g_slist_next(node_ptr))
961 channel_ptr = (struct channel*)node_ptr->data;
962 calc_channel_frames(channel_ptr, start, end);
965 for (node_ptr = mixer_ptr->output_channels_list; node_ptr; node_ptr = g_slist_next(node_ptr))
967 output_channel_ptr = node_ptr->data;
968 channel_ptr = (struct channel*)output_channel_ptr;
970 if (output_channel_ptr->system)
972 /* Don't bother mixing the channels if we are not connected */
973 if (channel_ptr->stereo)
975 if (jack_port_connected(channel_ptr->port_left) == 0 &&
976 jack_port_connected(channel_ptr->port_right) == 0)
977 continue;
978 } else {
979 if (jack_port_connected(channel_ptr->port_left) == 0)
980 continue;
984 mix_one(output_channel_ptr, mixer_ptr->input_channels_list, start, end);
988 static inline void
989 update_channel_buffers(
990 struct channel * channel_ptr,
991 jack_nframes_t nframes)
993 channel_ptr->left_buffer_ptr = jack_port_get_buffer(channel_ptr->port_left, nframes);
995 if (channel_ptr->stereo)
997 channel_ptr->right_buffer_ptr = jack_port_get_buffer(channel_ptr->port_right, nframes);
1001 #define mixer_ptr ((struct jack_mixer *)context)
1003 static int
1004 process(
1005 jack_nframes_t nframes,
1006 void * context)
1008 jack_nframes_t i;
1009 GSList *node_ptr;
1010 struct channel * channel_ptr;
1011 #if defined(HAVE_JACK_MIDI)
1012 jack_nframes_t event_count;
1013 jack_midi_event_t in_event;
1014 unsigned char* midi_out_buffer;
1015 void * midi_buffer;
1016 signed char byte;
1017 unsigned int cc_channel_index;
1018 #endif
1020 for (node_ptr = mixer_ptr->input_channels_list; node_ptr; node_ptr = g_slist_next(node_ptr))
1022 channel_ptr = node_ptr->data;
1023 update_channel_buffers(channel_ptr, nframes);
1026 // Fill output buffers with the input
1027 for (node_ptr = mixer_ptr->output_channels_list; node_ptr; node_ptr = g_slist_next(node_ptr))
1029 channel_ptr = node_ptr->data;
1030 update_channel_buffers(channel_ptr, nframes);
1033 #if defined(HAVE_JACK_MIDI)
1034 midi_buffer = jack_port_get_buffer(mixer_ptr->port_midi_in, nframes);
1035 event_count = jack_midi_get_event_count(midi_buffer);
1037 for (i = 0 ; i < event_count; i++)
1039 jack_midi_event_get(&in_event, midi_buffer, i);
1041 if (in_event.size != 3 ||
1042 (in_event.buffer[0] & 0xF0) != 0xB0 ||
1043 in_event.buffer[1] > 127 ||
1044 in_event.buffer[2] > 127)
1046 continue;
1049 assert(in_event.time < nframes);
1051 LOG_DEBUG(
1052 "%u: CC#%u -> %u",
1053 (unsigned int)(in_event.buffer[0]),
1054 (unsigned int)in_event.buffer[1],
1055 (unsigned int)in_event.buffer[2]);
1057 mixer_ptr->last_midi_channel = (int)in_event.buffer[1];
1058 channel_ptr = mixer_ptr->midi_cc_map[in_event.buffer[1]];
1060 /* if we have mapping for particular CC and MIDI scale is set for corresponding channel */
1061 if (channel_ptr != NULL && channel_ptr->midi_scale != NULL)
1063 if (channel_ptr->midi_cc_balance_index == (char)in_event.buffer[1])
1065 byte = in_event.buffer[2];
1066 if (byte == 0)
1068 byte = 1;
1070 byte -= 64;
1072 if (channel_ptr->balance != channel_ptr->balance_new) {
1073 channel_ptr->balance = channel_ptr->balance + channel_ptr->balance_idx *
1074 (channel_ptr->balance_new - channel_ptr->balance) /
1075 channel_ptr->num_volume_transition_steps;
1077 channel_ptr->balance_idx = 0;
1078 channel_ptr->balance_new = (float)byte / 63;
1079 LOG_DEBUG("\"%s\" balance -> %f", channel_ptr->name, channel_ptr->balance_new);
1081 else if (channel_ptr->midi_cc_volume_index == in_event.buffer[1])
1083 if (channel_ptr->volume_new != channel_ptr->volume) {
1084 channel_ptr->volume = channel_ptr->volume + channel_ptr->volume_idx *
1085 (channel_ptr->volume_new - channel_ptr->volume) /
1086 channel_ptr->num_volume_transition_steps;
1088 channel_ptr->volume_idx = 0;
1089 channel_ptr->volume_new = db_to_value(scale_scale_to_db(channel_ptr->midi_scale,
1090 (double)in_event.buffer[2] / 127));
1091 LOG_DEBUG("\"%s\" volume -> %f", channel_ptr->name, channel_ptr->volume_new);
1093 else if (channel_ptr->midi_cc_mute_index == in_event.buffer[1])
1095 if ((unsigned int)in_event.buffer[2] == 127) {
1096 channel_ptr->out_mute = !channel_ptr->out_mute;
1098 LOG_DEBUG("\"%s\" out_mute %d", channel_ptr->name, channel_ptr->out_mute);
1100 else if (channel_ptr->midi_cc_solo_index == in_event.buffer[1])
1102 if ((unsigned int)in_event.buffer[2] == 127) {
1103 if (channel_is_soloed(channel_ptr)) {
1104 channel_unsolo(channel_ptr);
1105 } else {
1106 channel_solo(channel_ptr);
1109 LOG_DEBUG("\"%s\" solo %d", channel_ptr->name, channel_is_soloed(channel_ptr));
1111 channel_ptr->midi_in_got_events = true;
1112 if (channel_ptr->midi_change_callback)
1113 channel_ptr->midi_change_callback(channel_ptr->midi_change_callback_data);
1119 midi_buffer = jack_port_get_buffer(mixer_ptr->port_midi_out, nframes);
1120 jack_midi_clear_buffer(midi_buffer);
1122 for(i=0; i<nframes; i++)
1124 for (cc_channel_index=0; cc_channel_index<128; cc_channel_index++)
1126 channel_ptr = mixer_ptr->midi_cc_map[cc_channel_index];
1127 if (channel_ptr == NULL || channel_ptr->midi_scale == NULL)
1129 continue;
1131 if (channel_ptr->midi_out_has_events == false)
1133 continue;
1135 if (channel_ptr->midi_cc_balance_index == (int)cc_channel_index)
1137 continue;
1139 midi_out_buffer = jack_midi_event_reserve(midi_buffer, i, 3);
1140 if (midi_out_buffer == NULL)
1142 continue;
1144 midi_out_buffer[0] = 0xB0; /* control change */
1145 midi_out_buffer[1] = cc_channel_index;
1146 midi_out_buffer[2] = (unsigned char)(127*scale_db_to_scale(channel_ptr->midi_scale, value_to_db(channel_ptr->volume_new)));
1148 LOG_DEBUG(
1149 "%u: CC#%u <- %u",
1150 (unsigned int)(midi_out_buffer[0]),
1151 (unsigned int)midi_out_buffer[1],
1152 (unsigned int)midi_out_buffer[2]);
1154 channel_ptr->midi_out_has_events = false;
1158 #endif
1160 mix(mixer_ptr, 0, nframes);
1162 return 0;
1165 #undef mixer_ptr
1167 jack_mixer_t
1168 create(
1169 const char * jack_client_name_ptr,
1170 bool stereo)
1172 (void) stereo;
1173 int ret;
1174 struct jack_mixer * mixer_ptr;
1175 int i;
1178 mixer_ptr = malloc(sizeof(struct jack_mixer));
1179 if (mixer_ptr == NULL)
1181 goto exit;
1184 ret = pthread_mutex_init(&mixer_ptr->mutex, NULL);
1185 if (ret != 0)
1187 goto exit_free;
1190 mixer_ptr->input_channels_list = NULL;
1191 mixer_ptr->output_channels_list = NULL;
1193 mixer_ptr->soloed_channels = NULL;
1195 mixer_ptr->last_midi_channel = -1;
1197 for (i = 0 ; i < 128 ; i++)
1199 mixer_ptr->midi_cc_map[i] = NULL;
1202 LOG_DEBUG("Initializing JACK");
1203 mixer_ptr->jack_client = jack_client_open(jack_client_name_ptr, 0, NULL);
1204 if (mixer_ptr->jack_client == NULL)
1206 LOG_ERROR("Cannot create JACK client.");
1207 LOG_NOTICE("Please make sure JACK daemon is running.");
1208 goto exit_destroy_mutex;
1211 LOG_DEBUG("JACK client created");
1213 LOG_DEBUG("Sample rate: %" PRIu32, jack_get_sample_rate(mixer_ptr->jack_client));
1216 #if defined(HAVE_JACK_MIDI)
1217 mixer_ptr->port_midi_in = jack_port_register(mixer_ptr->jack_client, "midi in", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0);
1218 if (mixer_ptr->port_midi_in == NULL)
1220 LOG_ERROR("Cannot create JACK MIDI in port");
1221 goto close_jack;
1224 mixer_ptr->port_midi_out = jack_port_register(mixer_ptr->jack_client, "midi out", JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0);
1225 if (mixer_ptr->port_midi_out == NULL)
1227 LOG_ERROR("Cannot create JACK MIDI out port");
1228 goto close_jack;
1231 #endif
1233 ret = jack_set_process_callback(mixer_ptr->jack_client, process, mixer_ptr);
1234 if (ret != 0)
1236 LOG_ERROR("Cannot set JACK process callback");
1237 goto close_jack;
1240 ret = jack_activate(mixer_ptr->jack_client);
1241 if (ret != 0)
1243 LOG_ERROR("Cannot activate JACK client");
1244 goto close_jack;
1247 return mixer_ptr;
1249 close_jack:
1250 jack_client_close(mixer_ptr->jack_client); /* this should clear all other resources we obtained through the client handle */
1252 exit_destroy_mutex:
1253 pthread_mutex_destroy(&mixer_ptr->mutex);
1255 exit_free:
1256 free(mixer_ptr);
1258 exit:
1259 return NULL;
1262 #define mixer_ctx_ptr ((struct jack_mixer *)mixer)
1264 void
1265 destroy(
1266 jack_mixer_t mixer)
1268 LOG_DEBUG("Uninitializing JACK");
1270 assert(mixer_ctx_ptr->jack_client != NULL);
1272 jack_client_close(mixer_ctx_ptr->jack_client);
1274 pthread_mutex_destroy(&mixer_ctx_ptr->mutex);
1276 free(mixer_ctx_ptr);
1280 unsigned int
1281 get_channels_count(
1282 jack_mixer_t mixer)
1284 return g_slist_length(mixer_ctx_ptr->input_channels_list);
1287 const char*
1288 get_client_name(
1289 jack_mixer_t mixer)
1291 return jack_get_client_name(mixer_ctx_ptr->jack_client);
1295 get_last_midi_channel(
1296 jack_mixer_t mixer)
1298 return mixer_ctx_ptr->last_midi_channel;
1301 unsigned int
1302 set_last_midi_channel(
1303 jack_mixer_t mixer,
1304 int new_channel) {
1305 mixer_ctx_ptr->last_midi_channel = new_channel;
1306 return 0;
1309 jack_mixer_channel_t
1310 add_channel(
1311 jack_mixer_t mixer,
1312 const char * channel_name,
1313 bool stereo)
1315 struct channel * channel_ptr;
1316 char * port_name = NULL;
1317 size_t channel_name_size;
1319 channel_ptr = malloc(sizeof(struct channel));
1320 if (channel_ptr == NULL)
1322 goto fail;
1325 channel_ptr->mixer_ptr = mixer_ctx_ptr;
1327 channel_ptr->name = strdup(channel_name);
1328 if (channel_ptr->name == NULL)
1330 goto fail_free_channel;
1333 channel_name_size = strlen(channel_name);
1335 if (stereo)
1337 port_name = malloc(channel_name_size + 3);
1338 if (port_name == NULL)
1340 goto fail_free_channel_name;
1343 memcpy(port_name, channel_name, channel_name_size);
1344 port_name[channel_name_size] = ' ';
1345 port_name[channel_name_size+1] = 'L';
1346 port_name[channel_name_size+2] = 0;
1348 channel_ptr->port_left = jack_port_register(channel_ptr->mixer_ptr->jack_client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
1349 if (channel_ptr->port_left == NULL)
1351 goto fail_free_port_name;
1354 port_name[channel_name_size+1] = 'R';
1356 channel_ptr->port_right = jack_port_register(channel_ptr->mixer_ptr->jack_client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
1357 if (channel_ptr->port_right == NULL)
1359 goto fail_unregister_left_channel;
1362 else
1364 channel_ptr->port_left = jack_port_register(channel_ptr->mixer_ptr->jack_client, channel_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
1365 if (channel_ptr->port_left == NULL)
1367 goto fail_free_channel_name;
1371 channel_ptr->stereo = stereo;
1373 channel_ptr->volume_transition_seconds = VOLUME_TRANSITION_SECONDS;
1374 channel_ptr->num_volume_transition_steps =
1375 channel_ptr->volume_transition_seconds *
1376 jack_get_sample_rate(channel_ptr->mixer_ptr->jack_client) + 1;
1377 channel_ptr->volume = 0.0;
1378 channel_ptr->volume_new = 0.0;
1379 channel_ptr->balance = 0.0;
1380 channel_ptr->balance_new = 0.0;
1381 channel_ptr->meter_left = -1.0;
1382 channel_ptr->meter_right = -1.0;
1383 channel_ptr->abspeak = 0.0;
1384 channel_ptr->out_mute = false;
1386 channel_ptr->peak_left = 0.0;
1387 channel_ptr->peak_right = 0.0;
1388 channel_ptr->peak_frames = 0;
1390 channel_ptr->frames_left = calloc(MAX_BLOCK_SIZE, sizeof(jack_default_audio_sample_t));
1391 channel_ptr->frames_right = calloc(MAX_BLOCK_SIZE, sizeof(jack_default_audio_sample_t));
1392 channel_ptr->prefader_frames_left = calloc(MAX_BLOCK_SIZE, sizeof(jack_default_audio_sample_t));
1393 channel_ptr->prefader_frames_right = calloc(MAX_BLOCK_SIZE, sizeof(jack_default_audio_sample_t));
1395 channel_ptr->NaN_detected = false;
1397 channel_ptr->midi_cc_volume_index = -1;
1398 channel_ptr->midi_cc_balance_index = -1;
1399 channel_ptr->midi_cc_mute_index = -1;
1400 channel_ptr->midi_cc_solo_index = -1;
1402 channel_ptr->midi_change_callback = NULL;
1403 channel_ptr->midi_change_callback_data = NULL;
1404 channel_ptr->midi_out_has_events = false;
1406 channel_ptr->midi_scale = NULL;
1408 channel_ptr->mixer_ptr->input_channels_list = g_slist_prepend(
1409 channel_ptr->mixer_ptr->input_channels_list, channel_ptr);
1411 free(port_name);
1412 return channel_ptr;
1414 fail_unregister_left_channel:
1415 jack_port_unregister(channel_ptr->mixer_ptr->jack_client, channel_ptr->port_left);
1417 fail_free_port_name:
1418 free(port_name);
1420 fail_free_channel_name:
1421 free(channel_ptr->name);
1423 fail_free_channel:
1424 free(channel_ptr);
1425 channel_ptr = NULL;
1427 fail:
1428 return NULL;
1431 static jack_mixer_output_channel_t
1432 create_output_channel(
1433 jack_mixer_t mixer,
1434 const char * channel_name,
1435 bool stereo,
1436 bool system)
1438 struct channel * channel_ptr;
1439 struct output_channel * output_channel_ptr;
1440 char * port_name = NULL;
1441 size_t channel_name_size;
1443 output_channel_ptr = malloc(sizeof(struct output_channel));
1444 channel_ptr = (struct channel*)output_channel_ptr;
1445 if (channel_ptr == NULL)
1447 goto fail;
1450 channel_ptr->mixer_ptr = mixer_ctx_ptr;
1452 channel_ptr->name = strdup(channel_name);
1453 if (channel_ptr->name == NULL)
1455 goto fail_free_channel;
1458 if (stereo)
1460 channel_name_size = strlen(channel_name);
1462 port_name = malloc(channel_name_size + 4);
1463 if (port_name == NULL)
1465 goto fail_free_channel_name;
1468 memcpy(port_name, channel_name, channel_name_size);
1469 port_name[channel_name_size] = ' ';
1470 port_name[channel_name_size+1] = 'L';
1471 port_name[channel_name_size+2] = 0;
1473 channel_ptr->port_left = jack_port_register(channel_ptr->mixer_ptr->jack_client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
1474 if (channel_ptr->port_left == NULL)
1476 goto fail_free_port_name;
1479 port_name[channel_name_size+1] = 'R';
1481 channel_ptr->port_right = jack_port_register(channel_ptr->mixer_ptr->jack_client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
1482 if (channel_ptr->port_right == NULL)
1484 goto fail_unregister_left_channel;
1487 else
1489 channel_ptr->port_left = jack_port_register(channel_ptr->mixer_ptr->jack_client, channel_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
1490 if (channel_ptr->port_left == NULL)
1492 goto fail_free_channel_name;
1496 channel_ptr->stereo = stereo;
1497 channel_ptr->out_mute = false;
1499 channel_ptr->volume_transition_seconds = VOLUME_TRANSITION_SECONDS;
1500 channel_ptr->num_volume_transition_steps =
1501 channel_ptr->volume_transition_seconds *
1502 jack_get_sample_rate(channel_ptr->mixer_ptr->jack_client) + 1;
1503 channel_ptr->volume = 0.0;
1504 channel_ptr->volume_new = 0.0;
1505 channel_ptr->balance = 0.0;
1506 channel_ptr->balance_new = 0.0;
1507 channel_ptr->meter_left = -1.0;
1508 channel_ptr->meter_right = -1.0;
1509 channel_ptr->abspeak = 0.0;
1511 channel_ptr->peak_left = 0.0;
1512 channel_ptr->peak_right = 0.0;
1513 channel_ptr->peak_frames = 0;
1515 channel_ptr->tmp_mixed_frames_left = calloc(MAX_BLOCK_SIZE, sizeof(jack_default_audio_sample_t));
1516 channel_ptr->tmp_mixed_frames_right = calloc(MAX_BLOCK_SIZE, sizeof(jack_default_audio_sample_t));
1517 channel_ptr->frames_left = calloc(MAX_BLOCK_SIZE, sizeof(jack_default_audio_sample_t));
1518 channel_ptr->frames_right = calloc(MAX_BLOCK_SIZE, sizeof(jack_default_audio_sample_t));
1519 channel_ptr->prefader_frames_left = calloc(MAX_BLOCK_SIZE, sizeof(jack_default_audio_sample_t));
1520 channel_ptr->prefader_frames_right = calloc(MAX_BLOCK_SIZE, sizeof(jack_default_audio_sample_t));
1522 channel_ptr->NaN_detected = false;
1524 channel_ptr->midi_cc_volume_index = -1;
1525 channel_ptr->midi_cc_balance_index = -1;
1526 channel_ptr->midi_cc_mute_index = -1;
1527 channel_ptr->midi_cc_solo_index = -1;
1529 channel_ptr->midi_change_callback = NULL;
1530 channel_ptr->midi_change_callback_data = NULL;
1532 channel_ptr->midi_scale = NULL;
1534 output_channel_ptr->soloed_channels = NULL;
1535 output_channel_ptr->muted_channels = NULL;
1536 output_channel_ptr->system = system;
1537 output_channel_ptr->prefader = false;
1539 free(port_name);
1540 return output_channel_ptr;
1542 fail_unregister_left_channel:
1543 jack_port_unregister(channel_ptr->mixer_ptr->jack_client, channel_ptr->port_left);
1545 fail_free_port_name:
1546 free(port_name);
1548 fail_free_channel_name:
1549 free(channel_ptr->name);
1551 fail_free_channel:
1552 free(channel_ptr);
1553 channel_ptr = NULL;
1555 fail:
1556 return NULL;
1559 jack_mixer_output_channel_t
1560 add_output_channel(
1561 jack_mixer_t mixer,
1562 const char * channel_name,
1563 bool stereo,
1564 bool system)
1566 struct output_channel *output_channel_ptr;
1567 struct channel *channel_ptr;
1569 output_channel_ptr = create_output_channel(mixer, channel_name, stereo, system);
1570 if (output_channel_ptr == NULL) {
1571 return NULL;
1573 channel_ptr = (struct channel*)output_channel_ptr;
1575 ((struct jack_mixer*)mixer)->output_channels_list = g_slist_prepend(
1576 ((struct jack_mixer*)mixer)->output_channels_list, channel_ptr);
1578 return output_channel_ptr;
1581 void
1582 remove_channels(
1583 jack_mixer_t mixer)
1585 GSList *list_ptr;
1586 for (list_ptr = mixer_ctx_ptr->input_channels_list; list_ptr; list_ptr = g_slist_next(list_ptr))
1588 struct channel *input_channel_ptr = list_ptr->data;
1589 remove_channel((jack_mixer_channel_t)input_channel_ptr);
1593 void
1594 remove_output_channel(
1595 jack_mixer_output_channel_t output_channel)
1597 struct output_channel *output_channel_ptr = output_channel;
1598 struct channel *channel_ptr = output_channel;
1600 channel_ptr->mixer_ptr->output_channels_list = g_slist_remove(
1601 channel_ptr->mixer_ptr->output_channels_list, channel_ptr);
1602 free(channel_ptr->name);
1604 jack_port_unregister(channel_ptr->mixer_ptr->jack_client, channel_ptr->port_left);
1605 if (channel_ptr->stereo)
1607 jack_port_unregister(channel_ptr->mixer_ptr->jack_client, channel_ptr->port_right);
1610 if (channel_ptr->midi_cc_volume_index != -1)
1612 assert(channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_volume_index] == channel_ptr);
1613 channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_volume_index] = NULL;
1616 if (channel_ptr->midi_cc_balance_index != -1)
1618 assert(channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_balance_index] == channel_ptr);
1619 channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_balance_index] = NULL;
1622 if (channel_ptr->midi_cc_mute_index != -1)
1624 assert(channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_mute_index] == channel_ptr);
1625 channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_mute_index] = NULL;
1628 if (channel_ptr->midi_cc_solo_index != -1)
1630 assert(channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_solo_index] == channel_ptr);
1631 channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_solo_index] = NULL;
1634 g_slist_free(output_channel_ptr->soloed_channels);
1635 g_slist_free(output_channel_ptr->muted_channels);
1637 free(channel_ptr->tmp_mixed_frames_left);
1638 free(channel_ptr->tmp_mixed_frames_right);
1639 free(channel_ptr->frames_left);
1640 free(channel_ptr->frames_right);
1641 free(channel_ptr->prefader_frames_left);
1642 free(channel_ptr->prefader_frames_right);
1644 free(channel_ptr);
1647 void
1648 output_channel_set_solo(
1649 jack_mixer_output_channel_t output_channel,
1650 jack_mixer_channel_t channel,
1651 bool solo_value)
1653 struct output_channel *output_channel_ptr = output_channel;
1655 if (solo_value) {
1656 if (g_slist_find(output_channel_ptr->soloed_channels, channel) != NULL)
1657 return;
1658 output_channel_ptr->soloed_channels = g_slist_prepend(output_channel_ptr->soloed_channels, channel);
1659 } else {
1660 if (g_slist_find(output_channel_ptr->soloed_channels, channel) == NULL)
1661 return;
1662 output_channel_ptr->soloed_channels = g_slist_remove(output_channel_ptr->soloed_channels, channel);
1666 void
1667 output_channel_set_muted(
1668 jack_mixer_output_channel_t output_channel,
1669 jack_mixer_channel_t channel,
1670 bool muted_value)
1672 struct output_channel *output_channel_ptr = output_channel;
1674 if (muted_value) {
1675 if (g_slist_find(output_channel_ptr->muted_channels, channel) != NULL)
1676 return;
1677 output_channel_ptr->muted_channels = g_slist_prepend(output_channel_ptr->muted_channels, channel);
1678 } else {
1679 if (g_slist_find(output_channel_ptr->muted_channels, channel) == NULL)
1680 return;
1681 output_channel_ptr->muted_channels = g_slist_remove(output_channel_ptr->muted_channels, channel);
1685 bool
1686 output_channel_is_muted(
1687 jack_mixer_output_channel_t output_channel,
1688 jack_mixer_channel_t channel)
1690 struct output_channel *output_channel_ptr = output_channel;
1692 if (g_slist_find(output_channel_ptr->muted_channels, channel) != NULL)
1693 return true;
1694 return false;
1697 bool
1698 output_channel_is_solo(
1699 jack_mixer_output_channel_t output_channel,
1700 jack_mixer_channel_t channel)
1702 struct output_channel *output_channel_ptr = output_channel;
1704 if (g_slist_find(output_channel_ptr->soloed_channels, channel) != NULL)
1705 return true;
1706 return false;
1709 void
1710 output_channel_set_prefader(
1711 jack_mixer_output_channel_t output_channel,
1712 bool pfl_value)
1714 struct output_channel *output_channel_ptr = output_channel;
1715 output_channel_ptr->prefader = pfl_value;
1718 bool
1719 output_channel_is_prefader(
1720 jack_mixer_output_channel_t output_channel)
1722 struct output_channel *output_channel_ptr = output_channel;
1723 return output_channel_ptr->prefader;