Pass height/width to cairo.Surface.create_similar as integers
[jack_mixer.git] / jack_mixer.c
blob2ae8e934cca7880c5a702eea6764eccb17b1d258
1 /* -*- Mode: C ; c-basic-offset: 2 -*- */
2 /*****************************************************************************
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
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 PEAK_FRAMES_CHUNK 4800
48 #define FLOAT_EXISTS(x) (!((x) - (x)))
50 struct channel
52 struct jack_mixer * mixer_ptr;
53 char * name;
54 bool stereo;
55 float volume;
56 float balance;
57 float volume_left;
58 float volume_right;
59 float meter_left;
60 float meter_right;
61 float abspeak;
62 jack_port_t * port_left;
63 jack_port_t * port_right;
65 jack_nframes_t peak_frames;
66 float peak_left;
67 float peak_right;
69 jack_default_audio_sample_t * frames_left;
70 jack_default_audio_sample_t * frames_right;
72 bool NaN_detected;
74 int midi_cc_volume_index;
75 int midi_cc_balance_index;
77 jack_default_audio_sample_t * left_buffer_ptr;
78 jack_default_audio_sample_t * right_buffer_ptr;
80 void (*midi_change_callback) (void*);
81 void *midi_change_callback_data;
83 jack_mixer_scale_t midi_scale;
85 jack_mixer_output_channel_t output;
88 struct output_channel {
89 struct channel channel;
90 GSList *soloed_channels;
91 GSList *muted_channels;
92 bool system; /* system channel, without any associated UI */
95 struct jack_mixer
97 pthread_mutex_t mutex;
98 jack_client_t * jack_client;
99 GSList *input_channels_list;
100 GSList *output_channels_list;
101 struct output_channel *main_mix_channel;
103 jack_port_t * port_midi_in;
104 unsigned int last_midi_channel;
106 struct channel* midi_cc_map[128];
109 float value_to_db(float value)
111 if (value <= 0)
113 return -INFINITY;
116 return 20.0 * log10f(value);
119 float db_to_value(float db)
121 return powf(10.0, db/20.0);
124 static jack_mixer_output_channel_t
125 create_output_channel(
126 jack_mixer_t mixer,
127 const char * channel_name,
128 bool stereo,
129 bool system);
132 void
133 calc_channel_volumes(struct channel * channel_ptr)
135 if (channel_ptr->stereo)
137 if (channel_ptr->balance > 0)
139 channel_ptr->volume_left = channel_ptr->volume * (1 - channel_ptr->balance);
140 channel_ptr->volume_right = channel_ptr->volume;
142 else
144 channel_ptr->volume_left = channel_ptr->volume;
145 channel_ptr->volume_right = channel_ptr->volume * (1 + channel_ptr->balance);
148 else
150 channel_ptr->volume_left = channel_ptr->volume * (1 - channel_ptr->balance);
151 channel_ptr->volume_right = channel_ptr->volume * (1 + channel_ptr->balance);
155 void
156 calc_all_channel_volumes(
157 struct jack_mixer * mixer_ptr)
159 struct channel * channel_ptr;
160 GSList *list_ptr;
162 for (list_ptr = mixer_ptr->input_channels_list; list_ptr; list_ptr = g_slist_next(list_ptr))
164 channel_ptr = list_ptr->data;
165 calc_channel_volumes(channel_ptr);
169 #define channel_ptr ((struct channel *)channel)
171 const char * channel_get_name(jack_mixer_channel_t channel)
173 return channel_ptr->name;
176 void channel_rename(jack_mixer_channel_t channel, const char * name)
178 char * new_name;
179 size_t channel_name_size;
180 char * port_name;
181 int ret;
183 new_name = strdup(name);
184 if (new_name == NULL)
186 return;
189 if (channel_ptr->name)
191 free(channel_ptr->name);
194 channel_ptr->name = new_name;
196 if (channel_ptr->stereo)
198 channel_name_size = strlen(name);
199 port_name = malloc(channel_name_size + 3);
200 memcpy(port_name, name, channel_name_size);
202 port_name[channel_name_size] = ' ';
203 port_name[channel_name_size+1] = 'L';
204 port_name[channel_name_size+2] = 0;
206 ret = jack_port_set_name(channel_ptr->port_left, port_name);
207 if (ret != 0)
209 /* what could we do here? */
212 port_name[channel_name_size+1] = 'R';
214 ret = jack_port_set_name(channel_ptr->port_right, port_name);
215 if (ret != 0)
217 /* what could we do here? */
220 free(port_name);
222 else
224 ret = jack_port_set_name(channel_ptr->port_left, name);
225 if (ret != 0)
227 /* what could we do here? */
232 bool channel_is_stereo(jack_mixer_channel_t channel)
234 return channel_ptr->stereo;
237 unsigned int channel_get_balance_midi_cc(jack_mixer_channel_t channel)
239 return channel_ptr->midi_cc_balance_index;
242 unsigned int channel_set_balance_midi_cc(jack_mixer_channel_t channel, unsigned int new_cc)
244 if (new_cc > 127) {
245 return 2; /* error: over limit CC */
247 if (channel_ptr->midi_cc_balance_index == new_cc) {
248 /* no change */
249 return 0;
251 if (new_cc == 0) {
252 /* 0 is special, it removes the link */
253 channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_balance_index] = NULL;
254 channel_ptr->midi_cc_balance_index = 0;
255 } else {
256 if (channel_ptr->mixer_ptr->midi_cc_map[new_cc] != NULL) {
257 return 1; /* error: cc in use */
259 channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_balance_index] = NULL;
260 channel_ptr->mixer_ptr->midi_cc_map[new_cc] = channel_ptr;
261 channel_ptr->midi_cc_balance_index = new_cc;
263 return 0;
266 unsigned int channel_get_volume_midi_cc(jack_mixer_channel_t channel)
268 return channel_ptr->midi_cc_volume_index;
271 unsigned int channel_set_volume_midi_cc(jack_mixer_channel_t channel, unsigned int new_cc)
273 if (new_cc > 127) {
274 return 2; /* error: over limit CC */
276 if (channel_ptr->midi_cc_volume_index == new_cc) {
277 /* no change */
278 return 0;
280 if (new_cc == 0) {
281 /* 0 is special, it removes the link */
282 channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_volume_index] = NULL;
283 channel_ptr->midi_cc_volume_index = 0;
284 } else {
285 if (channel_ptr->mixer_ptr->midi_cc_map[new_cc] != NULL) {
286 return 1; /* error: cc in use */
288 channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_volume_index] = NULL;
289 channel_ptr->mixer_ptr->midi_cc_map[new_cc] = channel_ptr;
290 channel_ptr->midi_cc_volume_index = new_cc;
292 return 0;
295 void
296 channel_autoset_midi_cc(jack_mixer_channel_t channel)
298 struct jack_mixer *mixer_ptr;
299 int i;
301 mixer_ptr = channel_ptr->mixer_ptr;
303 for (i = 11 ; i < 128 ; i++)
305 if (mixer_ptr->midi_cc_map[i] == NULL)
307 mixer_ptr->midi_cc_map[i] = channel_ptr;
308 channel_ptr->midi_cc_volume_index = i;
310 LOG_NOTICE("New channel \"%s\" volume mapped to CC#%i", channel_ptr->name, i);
312 break;
316 for (; i < 128 ; i++)
318 if (mixer_ptr->midi_cc_map[i] == NULL)
320 mixer_ptr->midi_cc_map[i] = channel_ptr;
321 channel_ptr->midi_cc_balance_index = i;
323 LOG_NOTICE("New channel \"%s\" balance mapped to CC#%i", channel_ptr->name, i);
325 break;
331 void remove_channel(jack_mixer_channel_t channel)
333 channel_ptr->mixer_ptr->input_channels_list = g_slist_remove(
334 channel_ptr->mixer_ptr->input_channels_list, channel_ptr);
335 free(channel_ptr->name);
337 jack_port_unregister(channel_ptr->mixer_ptr->jack_client, channel_ptr->port_left);
338 if (channel_ptr->stereo)
340 jack_port_unregister(channel_ptr->mixer_ptr->jack_client, channel_ptr->port_right);
343 if (channel_ptr->midi_cc_volume_index != 0)
345 assert(channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_volume_index] == channel_ptr);
346 channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_volume_index] = NULL;
349 if (channel_ptr->midi_cc_balance_index != 0)
351 assert(channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_balance_index] == channel_ptr);
352 channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_balance_index] = NULL;
354 remove_output_channel(channel_ptr->output);
356 free(channel_ptr);
359 void channel_stereo_meter_read(jack_mixer_channel_t channel, double * left_ptr, double * right_ptr)
361 assert(channel_ptr);
362 *left_ptr = value_to_db(channel_ptr->meter_left);
363 *right_ptr = value_to_db(channel_ptr->meter_right);
366 void channel_mono_meter_read(jack_mixer_channel_t channel, double * mono_ptr)
368 *mono_ptr = value_to_db(channel_ptr->meter_left);
371 void channel_volume_write(jack_mixer_channel_t channel, double volume)
373 assert(channel_ptr);
374 channel_ptr->volume = db_to_value(volume);
375 calc_channel_volumes(channel_ptr);
378 double
379 channel_volume_read(
380 jack_mixer_channel_t channel)
382 assert(channel_ptr);
383 return value_to_db(channel_ptr->volume);
386 void channel_balance_write(jack_mixer_channel_t channel, double balance)
388 assert(channel_ptr);
389 channel_ptr->balance = balance;
390 calc_channel_volumes(channel_ptr);
393 double
394 channel_balance_read(
395 jack_mixer_channel_t channel)
397 assert(channel_ptr);
398 return channel_ptr->balance;
401 double channel_abspeak_read(jack_mixer_channel_t channel)
403 assert(channel_ptr);
404 if (channel_ptr->NaN_detected)
406 return sqrt(-1);
408 else
410 return value_to_db(channel_ptr->abspeak);
414 void channel_abspeak_reset(jack_mixer_channel_t channel)
416 channel_ptr->abspeak = 0;
417 channel_ptr->NaN_detected = false;
420 void channel_mute(jack_mixer_channel_t channel)
422 output_channel_set_muted(channel_ptr->mixer_ptr->main_mix_channel, channel, true);
425 void channel_unmute(jack_mixer_channel_t channel)
427 output_channel_set_muted(channel_ptr->mixer_ptr->main_mix_channel, channel, false);
430 void channel_solo(jack_mixer_channel_t channel)
432 output_channel_set_solo(channel_ptr->mixer_ptr->main_mix_channel, channel, true);
435 void channel_unsolo(jack_mixer_channel_t channel)
437 output_channel_set_solo(channel_ptr->mixer_ptr->main_mix_channel, channel, false);
440 bool channel_is_muted(jack_mixer_channel_t channel)
442 if (g_slist_find(channel_ptr->mixer_ptr->main_mix_channel->muted_channels, channel))
443 return true;
444 return false;
447 bool channel_is_soloed(jack_mixer_channel_t channel)
449 if (g_slist_find(channel_ptr->mixer_ptr->main_mix_channel->soloed_channels, channel))
450 return true;
451 return false;
454 void
455 channel_set_midi_scale(
456 jack_mixer_channel_t channel,
457 jack_mixer_scale_t scale)
459 channel_ptr->midi_scale = scale;
462 void
463 channel_set_midi_change_callback(
464 jack_mixer_channel_t channel,
465 void (*midi_change_callback) (void*),
466 void *user_data)
468 channel_ptr->midi_change_callback = midi_change_callback;
469 channel_ptr->midi_change_callback_data = user_data;
472 #undef channel_ptr
474 /* process input channels and mix them into main mix */
475 static
476 inline
477 void
478 mix_one(
479 struct output_channel *output_mix_channel,
480 GSList *channels_list,
481 jack_nframes_t start, /* index of first sample to process */
482 jack_nframes_t end) /* index of sample to stop processing before */
484 jack_nframes_t i;
485 GSList *node_ptr;
486 struct channel * channel_ptr;
487 jack_default_audio_sample_t frame_left;
488 jack_default_audio_sample_t frame_right;
489 struct channel *mix_channel = (struct channel*)output_mix_channel;
491 for (node_ptr = channels_list; node_ptr; node_ptr = g_slist_next(node_ptr))
493 channel_ptr = node_ptr->data;
495 if (g_slist_find(output_mix_channel->muted_channels, channel_ptr) != NULL) {
496 /* skip muted channels */
497 continue;
500 if (output_mix_channel->soloed_channels &&
501 g_slist_find(output_mix_channel->soloed_channels, channel_ptr) == NULL) {
502 /* skip channels that are not soloed, when some are */
503 continue;
506 for (i = start ; i < end ; i++)
508 frame_left = channel_ptr->frames_left[i-start];
509 if (frame_left == NAN)
510 break;
511 mix_channel->left_buffer_ptr[i] += frame_left;
513 if (mix_channel->stereo)
515 frame_right = channel_ptr->frames_right[i-start];
516 if (frame_right == NAN)
517 break;
519 mix_channel->right_buffer_ptr[i] += frame_right;
526 /* process main mix channel */
527 for (i = start ; i < end ; i++)
529 mix_channel->left_buffer_ptr[i] *= mix_channel->volume_left;
530 if (mix_channel->stereo)
532 mix_channel->right_buffer_ptr[i] *= mix_channel->volume_right;
535 frame_left = fabsf(mix_channel->left_buffer_ptr[i]);
536 if (mix_channel->peak_left < frame_left)
538 mix_channel->peak_left = frame_left;
540 if (frame_left > mix_channel->abspeak)
542 mix_channel->abspeak = frame_left;
546 if (mix_channel->stereo)
548 frame_right = fabsf(mix_channel->right_buffer_ptr[i]);
549 if (mix_channel->peak_right < frame_right)
551 mix_channel->peak_right = frame_right;
553 if (frame_right > mix_channel->abspeak)
555 mix_channel->abspeak = frame_right;
560 mix_channel->peak_frames++;
561 if (mix_channel->peak_frames >= PEAK_FRAMES_CHUNK)
563 mix_channel->meter_left = mix_channel->peak_left;
564 mix_channel->peak_left = 0.0;
566 if (mix_channel->stereo)
568 mix_channel->meter_right = mix_channel->peak_right;
569 mix_channel->peak_right = 0.0;
572 mix_channel->peak_frames = 0;
577 static
578 inline
579 void
580 calc_channel_frames(
581 struct channel *channel_ptr,
582 jack_nframes_t start,
583 jack_nframes_t end)
585 jack_nframes_t i;
586 jack_default_audio_sample_t frame_left;
587 jack_default_audio_sample_t frame_right;
589 channel_ptr->frames_left = calloc(end-start, sizeof(jack_default_audio_sample_t));
590 channel_ptr->frames_right = calloc(end-start, sizeof(jack_default_audio_sample_t));
592 for (i = start ; i < end ; i++)
594 if (!FLOAT_EXISTS(channel_ptr->left_buffer_ptr[i]))
596 channel_ptr->NaN_detected = true;
597 channel_ptr->frames_left[i-start] = NAN;
598 break;
601 frame_left = channel_ptr->left_buffer_ptr[i] * channel_ptr->volume_left;
603 if (channel_ptr->stereo)
605 if (!FLOAT_EXISTS(channel_ptr->right_buffer_ptr[i]))
607 channel_ptr->NaN_detected = true;
608 channel_ptr->frames_right[i-start] = NAN;
609 break;
612 frame_right = channel_ptr->right_buffer_ptr[i] * channel_ptr->volume_right;
614 else
616 frame_right = channel_ptr->left_buffer_ptr[i] * channel_ptr->volume_right;
619 channel_ptr->frames_left[i-start] = frame_left;
620 channel_ptr->frames_right[i-start] = frame_right;
622 if (channel_ptr->stereo)
624 frame_left = fabsf(frame_left);
625 frame_right = fabsf(frame_right);
627 if (channel_ptr->peak_left < frame_left)
629 channel_ptr->peak_left = frame_left;
631 if (frame_left > channel_ptr->abspeak)
633 channel_ptr->abspeak = frame_left;
637 if (channel_ptr->peak_right < frame_right)
639 channel_ptr->peak_right = frame_right;
641 if (frame_right > channel_ptr->abspeak)
643 channel_ptr->abspeak = frame_right;
647 else
649 frame_left = (fabsf(frame_left) + fabsf(frame_right)) / 2;
651 if (channel_ptr->peak_left < frame_left)
653 channel_ptr->peak_left = frame_left;
655 if (frame_left > channel_ptr->abspeak)
657 channel_ptr->abspeak = frame_left;
662 channel_ptr->peak_frames++;
663 if (channel_ptr->peak_frames >= PEAK_FRAMES_CHUNK)
665 channel_ptr->meter_left = channel_ptr->peak_left;
666 channel_ptr->peak_left = 0.0;
668 if (channel_ptr->stereo)
670 channel_ptr->meter_right = channel_ptr->peak_right;
671 channel_ptr->peak_right = 0.0;
674 channel_ptr->peak_frames = 0;
680 static
681 inline
682 void
683 mix(
684 struct jack_mixer * mixer_ptr,
685 jack_nframes_t start, /* index of first sample to process */
686 jack_nframes_t end) /* index of sample to stop processing before */
688 GSList *node_ptr;
689 struct output_channel * output_channel_ptr;
690 struct channel *channel_ptr;
692 for (node_ptr = mixer_ptr->input_channels_list; node_ptr; node_ptr = g_slist_next(node_ptr))
694 channel_ptr = (struct channel*)node_ptr->data;
695 calc_channel_frames(channel_ptr, start, end);
698 mix_one((struct output_channel*)mixer_ptr->main_mix_channel, mixer_ptr->input_channels_list, start, end);
700 for (node_ptr = mixer_ptr->output_channels_list; node_ptr; node_ptr = g_slist_next(node_ptr))
702 output_channel_ptr = node_ptr->data;
703 channel_ptr = (struct channel*)output_channel_ptr;
705 if (output_channel_ptr->system)
707 /* Don't bother mixing the channels if we are not connected */
708 if (channel_ptr->stereo)
710 if (jack_port_connected(channel_ptr->port_left) == 0 &&
711 jack_port_connected(channel_ptr->port_right) == 0)
712 continue;
713 } else {
714 if (jack_port_connected(channel_ptr->port_left) == 0)
715 continue;
719 mix_one(output_channel_ptr, mixer_ptr->input_channels_list, start, end);
722 for (node_ptr = mixer_ptr->input_channels_list; node_ptr; node_ptr = g_slist_next(node_ptr))
724 channel_ptr = (struct channel*)node_ptr->data;
725 free(channel_ptr->frames_left);
726 free(channel_ptr->frames_right);
730 static
731 inline
732 void
733 update_channel_buffers(
734 struct channel * channel_ptr,
735 jack_nframes_t nframes)
737 channel_ptr->left_buffer_ptr = jack_port_get_buffer(channel_ptr->port_left, nframes);
739 if (channel_ptr->stereo)
741 channel_ptr->right_buffer_ptr = jack_port_get_buffer(channel_ptr->port_right, nframes);
745 #define mixer_ptr ((struct jack_mixer *)context)
748 process(jack_nframes_t nframes, void * context)
750 jack_nframes_t i;
751 GSList *node_ptr;
752 struct channel * channel_ptr;
753 #if defined(HAVE_JACK_MIDI)
754 jack_nframes_t event_count;
755 jack_midi_event_t in_event;
756 void * midi_buffer;
757 signed char byte;
758 #endif
759 jack_nframes_t offset;
761 update_channel_buffers((struct channel*)mixer_ptr->main_mix_channel, nframes);
763 for (node_ptr = mixer_ptr->input_channels_list; node_ptr; node_ptr = g_slist_next(node_ptr))
765 channel_ptr = node_ptr->data;
767 update_channel_buffers(channel_ptr, nframes);
770 for (i = 0 ; i < nframes ; i++)
772 ((struct channel*)(mixer_ptr->main_mix_channel))->left_buffer_ptr[i] = 0.0;
773 ((struct channel*)(mixer_ptr->main_mix_channel))->right_buffer_ptr[i] = 0.0;
776 for (node_ptr = mixer_ptr->output_channels_list; node_ptr; node_ptr = g_slist_next(node_ptr))
778 channel_ptr = node_ptr->data;
779 update_channel_buffers(channel_ptr, nframes);
780 for (i = 0 ; i < nframes ; i++)
782 channel_ptr->left_buffer_ptr[i] = 0.0;
783 if (channel_ptr->stereo) {
784 channel_ptr->right_buffer_ptr[i] = 0.0;
789 offset = 0;
792 #if defined(HAVE_JACK_MIDI)
793 midi_buffer = jack_port_get_buffer(mixer_ptr->port_midi_in, nframes);
794 event_count = jack_midi_get_event_count(midi_buffer);
796 for (i = 0 ; i < event_count; i++)
798 jack_midi_event_get(&in_event, midi_buffer, i);
800 if (in_event.size != 3 ||
801 (in_event.buffer[0] & 0xF0) != 0xB0 ||
802 in_event.buffer[1] > 127 ||
803 in_event.buffer[2] > 127)
805 continue;
808 assert(in_event.time < nframes);
810 LOG_DEBUG(
811 "%u: CC#%u -> %u",
812 (unsigned int)(in_event.buffer[0] & 0x0F),
813 (unsigned int)in_event.buffer[1],
814 (unsigned int)in_event.buffer[2]);
816 mixer_ptr->last_midi_channel = (unsigned int)in_event.buffer[1];
817 channel_ptr = mixer_ptr->midi_cc_map[in_event.buffer[1]];
819 /* if we have mapping for particular CC and MIDI scale is set for corresponding channel */
820 if (channel_ptr != NULL && channel_ptr->midi_scale != NULL)
822 assert(in_event.time >= offset);
824 if (in_event.time > offset)
826 mix(mixer_ptr, offset, in_event.time);
827 offset = in_event.time;
830 if (channel_ptr->midi_cc_balance_index == (unsigned int)in_event.buffer[1])
832 byte = in_event.buffer[2];
833 if (byte == 0)
835 byte = 1;
837 byte -= 64;
839 channel_ptr->balance = (float)byte / 63;
840 LOG_DEBUG("\"%s\" balance -> %f", channel_ptr->name, channel_ptr->balance);
842 else
844 channel_ptr->volume = db_to_value(scale_scale_to_db(channel_ptr->midi_scale, (double)in_event.buffer[2] / 127));
845 LOG_DEBUG("\"%s\" volume -> %f", channel_ptr->name, channel_ptr->volume);
848 calc_channel_volumes(channel_ptr);
850 if (channel_ptr->midi_change_callback)
851 channel_ptr->midi_change_callback(channel_ptr->midi_change_callback_data);
857 #endif
859 mix(mixer_ptr, offset, nframes);
861 return 0;
864 #undef mixer_ptr
866 jack_mixer_t
867 create(
868 const char * jack_client_name_ptr)
870 int ret;
871 struct jack_mixer * mixer_ptr;
872 int i;
875 mixer_ptr = malloc(sizeof(struct jack_mixer));
876 if (mixer_ptr == NULL)
878 goto exit;
881 ret = pthread_mutex_init(&mixer_ptr->mutex, NULL);
882 if (ret != 0)
884 goto exit_free;
887 mixer_ptr->input_channels_list = NULL;
888 mixer_ptr->output_channels_list = NULL;
890 mixer_ptr->last_midi_channel = 0;
892 for (i = 0 ; i < 128 ; i++)
894 mixer_ptr->midi_cc_map[i] = NULL;
897 LOG_DEBUG("Initializing JACK");
898 mixer_ptr->jack_client = jack_client_open(jack_client_name_ptr, 0, NULL);
899 if (mixer_ptr->jack_client == NULL)
901 LOG_ERROR("Cannot create JACK client.");
902 LOG_NOTICE("Please make sure JACK daemon is running.");
903 goto exit_destroy_mutex;
906 LOG_DEBUG("JACK client created");
908 LOG_DEBUG("Sample rate: %" PRIu32, jack_get_sample_rate(mixer_ptr->jack_client));
910 mixer_ptr->main_mix_channel = create_output_channel(mixer_ptr, "MAIN", true, false);
911 if (mixer_ptr->main_mix_channel == NULL) {
912 LOG_ERROR("Cannot create main mix channel");
913 goto close_jack;
915 channel_set_volume_midi_cc(mixer_ptr->main_mix_channel, 7);
916 channel_set_balance_midi_cc(mixer_ptr->main_mix_channel, 8);
918 ((struct channel*)(mixer_ptr->main_mix_channel))->mixer_ptr = mixer_ptr;
920 #if defined(HAVE_JACK_MIDI)
921 mixer_ptr->port_midi_in = jack_port_register(mixer_ptr->jack_client, "midi in", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0);
922 if (mixer_ptr->port_midi_in == NULL)
924 LOG_ERROR("Cannot create JACK port");
925 goto close_jack;
927 #endif
929 calc_channel_volumes((struct channel*)mixer_ptr->main_mix_channel);
931 ret = jack_set_process_callback(mixer_ptr->jack_client, process, mixer_ptr);
932 if (ret != 0)
934 LOG_ERROR("Cannot set JACK process callback");
935 goto close_jack;
938 ret = jack_activate(mixer_ptr->jack_client);
939 if (ret != 0)
941 LOG_ERROR("Cannot activate JACK client");
942 goto close_jack;
945 return mixer_ptr;
947 close_jack:
948 jack_client_close(mixer_ptr->jack_client); /* this should clear all other resources we obtained through the client handle */
950 exit_destroy_mutex:
951 pthread_mutex_destroy(&mixer_ptr->mutex);
953 exit_free:
954 free(mixer_ptr);
956 exit:
957 return NULL;
960 #define mixer_ctx_ptr ((struct jack_mixer *)mixer)
962 void
963 destroy(
964 jack_mixer_t mixer)
966 LOG_DEBUG("Uninitializing JACK");
968 assert(mixer_ctx_ptr->jack_client != NULL);
970 jack_client_close(mixer_ctx_ptr->jack_client);
972 pthread_mutex_destroy(&mixer_ctx_ptr->mutex);
974 free(mixer_ctx_ptr->main_mix_channel);
975 free(mixer_ctx_ptr);
978 jack_mixer_channel_t
979 get_main_mix_channel(
980 jack_mixer_t mixer)
982 return (struct channel*)mixer_ctx_ptr->main_mix_channel;
985 unsigned int
986 get_channels_count(
987 jack_mixer_t mixer)
989 return g_slist_length(mixer_ctx_ptr->input_channels_list);
992 unsigned int
993 get_last_midi_channel(
994 jack_mixer_t mixer)
996 return mixer_ctx_ptr->last_midi_channel;
999 jack_mixer_channel_t
1000 add_channel(
1001 jack_mixer_t mixer,
1002 const char * channel_name,
1003 bool stereo)
1005 struct channel * channel_ptr;
1006 char * port_name;
1007 size_t channel_name_size;
1008 char * output_channel_name;
1010 channel_ptr = malloc(sizeof(struct channel));
1011 if (channel_ptr == NULL)
1013 goto fail;
1016 channel_ptr->mixer_ptr = mixer_ctx_ptr;
1018 channel_ptr->name = strdup(channel_name);
1019 if (channel_ptr->name == NULL)
1021 goto fail_free_channel;
1024 channel_name_size = strlen(channel_name);
1026 if (stereo)
1028 port_name = malloc(channel_name_size + 3);
1029 if (port_name == NULL)
1031 goto fail_free_channel_name;
1034 memcpy(port_name, channel_name, channel_name_size);
1035 port_name[channel_name_size] = ' ';
1036 port_name[channel_name_size+1] = 'L';
1037 port_name[channel_name_size+2] = 0;
1039 channel_ptr->port_left = jack_port_register(channel_ptr->mixer_ptr->jack_client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
1040 if (channel_ptr->port_left == NULL)
1042 goto fail_free_port_name;
1045 port_name[channel_name_size+1] = 'R';
1047 channel_ptr->port_right = jack_port_register(channel_ptr->mixer_ptr->jack_client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
1048 if (channel_ptr->port_right == NULL)
1050 goto fail_unregister_left_channel;
1053 else
1055 channel_ptr->port_left = jack_port_register(channel_ptr->mixer_ptr->jack_client, channel_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
1056 if (channel_ptr->port_left == NULL)
1058 goto fail_free_channel_name;
1062 channel_ptr->stereo = stereo;
1064 channel_ptr->volume = 0.0;
1065 channel_ptr->balance = 0.0;
1066 channel_ptr->meter_left = -1.0;
1067 channel_ptr->meter_right = -1.0;
1068 channel_ptr->abspeak = 0.0;
1070 channel_ptr->peak_left = 0.0;
1071 channel_ptr->peak_right = 0.0;
1072 channel_ptr->peak_frames = 0;
1074 channel_ptr->NaN_detected = false;
1076 channel_ptr->midi_cc_volume_index = 0;
1077 channel_ptr->midi_cc_balance_index = 0;
1078 channel_ptr->midi_change_callback = NULL;
1079 channel_ptr->midi_change_callback_data = NULL;
1081 channel_ptr->midi_scale = NULL;
1083 calc_channel_volumes(channel_ptr);
1085 // for monitoring etc.
1086 output_channel_name = malloc(channel_name_size + 5);
1087 sprintf(output_channel_name, "%s Out", channel_name);
1088 channel_ptr->output = add_output_channel(mixer, output_channel_name, stereo, true);
1089 free(output_channel_name);
1091 channel_ptr->mixer_ptr->input_channels_list = g_slist_prepend(
1092 channel_ptr->mixer_ptr->input_channels_list, channel_ptr);
1094 return channel_ptr;
1096 fail_unregister_left_channel:
1097 jack_port_unregister(channel_ptr->mixer_ptr->jack_client, channel_ptr->port_left);
1099 fail_free_port_name:
1100 free(port_name);
1102 fail_free_channel_name:
1103 free(channel_ptr->name);
1105 fail_free_channel:
1106 free(channel_ptr);
1107 channel_ptr = NULL;
1109 fail:
1110 return NULL;
1113 static jack_mixer_output_channel_t
1114 create_output_channel(
1115 jack_mixer_t mixer,
1116 const char * channel_name,
1117 bool stereo,
1118 bool system)
1120 struct channel * channel_ptr;
1121 struct output_channel * output_channel_ptr;
1122 char * port_name;
1123 size_t channel_name_size;
1125 output_channel_ptr = malloc(sizeof(struct output_channel));
1126 channel_ptr = (struct channel*)output_channel_ptr;
1127 if (channel_ptr == NULL)
1129 goto fail;
1132 channel_ptr->mixer_ptr = mixer_ctx_ptr;
1134 channel_ptr->name = strdup(channel_name);
1135 if (channel_ptr->name == NULL)
1137 goto fail_free_channel;
1140 if (stereo)
1142 channel_name_size = strlen(channel_name);
1144 port_name = malloc(channel_name_size + 4);
1145 if (port_name == NULL)
1147 goto fail_free_channel_name;
1150 memcpy(port_name, channel_name, channel_name_size);
1151 port_name[channel_name_size] = ' ';
1152 port_name[channel_name_size+1] = 'L';
1153 port_name[channel_name_size+2] = 0;
1155 channel_ptr->port_left = jack_port_register(channel_ptr->mixer_ptr->jack_client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
1156 if (channel_ptr->port_left == NULL)
1158 goto fail_free_port_name;
1161 port_name[channel_name_size+1] = 'R';
1163 channel_ptr->port_right = jack_port_register(channel_ptr->mixer_ptr->jack_client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
1164 if (channel_ptr->port_right == NULL)
1166 goto fail_unregister_left_channel;
1169 else
1171 channel_ptr->port_left = jack_port_register(channel_ptr->mixer_ptr->jack_client, channel_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
1172 if (channel_ptr->port_left == NULL)
1174 goto fail_free_channel_name;
1178 channel_ptr->stereo = stereo;
1180 channel_ptr->volume = 0.0;
1181 channel_ptr->balance = 0.0;
1182 channel_ptr->meter_left = -1.0;
1183 channel_ptr->meter_right = -1.0;
1184 channel_ptr->abspeak = 0.0;
1186 channel_ptr->peak_left = 0.0;
1187 channel_ptr->peak_right = 0.0;
1188 channel_ptr->peak_frames = 0;
1190 channel_ptr->NaN_detected = false;
1192 channel_ptr->midi_cc_volume_index = 0;
1193 channel_ptr->midi_cc_balance_index = 0;
1194 channel_ptr->midi_change_callback = NULL;
1195 channel_ptr->midi_change_callback_data = NULL;
1197 channel_ptr->midi_scale = NULL;
1199 output_channel_ptr->soloed_channels = NULL;
1200 output_channel_ptr->muted_channels = NULL;
1201 output_channel_ptr->system = system;
1203 return output_channel_ptr;
1205 fail_unregister_left_channel:
1206 jack_port_unregister(channel_ptr->mixer_ptr->jack_client, channel_ptr->port_left);
1208 fail_free_port_name:
1209 free(port_name);
1211 fail_free_channel_name:
1212 free(channel_ptr->name);
1214 fail_free_channel:
1215 free(channel_ptr);
1216 channel_ptr = NULL;
1218 fail:
1219 return NULL;
1222 jack_mixer_output_channel_t
1223 add_output_channel(
1224 jack_mixer_t mixer,
1225 const char * channel_name,
1226 bool stereo,
1227 bool system)
1229 struct output_channel *output_channel_ptr;
1230 struct channel *channel_ptr;
1232 output_channel_ptr = create_output_channel(mixer, channel_name, stereo, system);
1233 if (output_channel_ptr == NULL) {
1234 return NULL;
1236 channel_ptr = (struct channel*)output_channel_ptr;
1238 ((struct jack_mixer*)mixer)->output_channels_list = g_slist_prepend(
1239 ((struct jack_mixer*)mixer)->output_channels_list, channel_ptr);
1241 return output_channel_ptr;
1244 void
1245 remove_output_channel(jack_mixer_output_channel_t output_channel)
1247 struct output_channel *output_channel_ptr = output_channel;
1248 struct channel *channel_ptr = output_channel;
1250 channel_ptr->mixer_ptr->output_channels_list = g_slist_remove(
1251 channel_ptr->mixer_ptr->output_channels_list, channel_ptr);
1252 free(channel_ptr->name);
1254 jack_port_unregister(channel_ptr->mixer_ptr->jack_client, channel_ptr->port_left);
1255 if (channel_ptr->stereo)
1257 jack_port_unregister(channel_ptr->mixer_ptr->jack_client, channel_ptr->port_right);
1260 if (channel_ptr->midi_cc_volume_index != 0)
1262 assert(channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_volume_index] == channel_ptr);
1263 channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_volume_index] = NULL;
1266 if (channel_ptr->midi_cc_balance_index != 0)
1268 assert(channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_balance_index] == channel_ptr);
1269 channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_cc_balance_index] = NULL;
1272 g_slist_free(output_channel_ptr->soloed_channels);
1273 g_slist_free(output_channel_ptr->muted_channels);
1275 free(channel_ptr);
1279 void
1280 output_channel_set_solo(
1281 jack_mixer_output_channel_t output_channel,
1282 jack_mixer_channel_t channel,
1283 bool solo_value)
1285 struct output_channel *output_channel_ptr = output_channel;
1287 if (solo_value) {
1288 if (g_slist_find(output_channel_ptr->soloed_channels, channel) != NULL)
1289 return;
1290 output_channel_ptr->soloed_channels = g_slist_prepend(output_channel_ptr->soloed_channels, channel);
1291 } else {
1292 if (g_slist_find(output_channel_ptr->soloed_channels, channel) == NULL)
1293 return;
1294 output_channel_ptr->soloed_channels = g_slist_remove(output_channel_ptr->soloed_channels, channel);
1298 void
1299 output_channel_set_muted(
1300 jack_mixer_output_channel_t output_channel,
1301 jack_mixer_channel_t channel,
1302 bool muted_value)
1304 struct output_channel *output_channel_ptr = output_channel;
1306 if (muted_value) {
1307 if (g_slist_find(output_channel_ptr->muted_channels, channel) != NULL)
1308 return;
1309 output_channel_ptr->muted_channels = g_slist_prepend(output_channel_ptr->muted_channels, channel);
1310 } else {
1311 if (g_slist_find(output_channel_ptr->muted_channels, channel) == NULL)
1312 return;
1313 output_channel_ptr->muted_channels = g_slist_remove(output_channel_ptr->muted_channels, channel);