Refactor engine interface and remove global mixer engine variable.
[jack_mixer.git] / jack_mixer.c
blob410814fc163598848a9fa8fd72e1f60e49a2a143
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 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21 *****************************************************************************/
23 #include <stdlib.h>
24 #include <string.h>
25 #include <stdbool.h>
26 #include <math.h>
27 #include <jack/jack.h>
29 #include "jack_mixer.h"
30 #include "list.h"
31 //#define LOG_LEVEL LOG_LEVEL_DEBUG
32 #include "log.h"
34 #define PEAK_FRAMES_CHUNK 4800
36 #define FLOAT_EXISTS(x) (!((x) - (x)))
38 struct channel
40 struct list_head siblings;
41 struct jack_mixer * mixer_ptr;
42 char * name;
43 bool stereo;
44 float volume;
45 float balance;
46 bool muted;
47 bool soloed;
48 float volume_left;
49 float volume_right;
50 float meter_left;
51 float meter_right;
52 float abspeak;
53 jack_port_t * port_left;
54 jack_port_t * port_right;
56 jack_nframes_t peak_frames;
57 float peak_left;
58 float peak_right;
60 bool NaN_detected;
63 struct jack_mixer
65 jack_client_t * jack_client;
66 struct list_head channels_list;
67 struct channel main_mix_channel;
68 unsigned int channels_count;
69 unsigned int soloed_channels_count;
72 float value_to_db(float value)
74 if (value <= 0)
76 return -INFINITY;
79 return 20.0 * log10f(value);
82 float db_to_value(float db)
84 return powf(10.0, db/20.0);
87 void
88 calc_channel_volumes(struct channel * channel_ptr)
90 if (channel_ptr->muted)
92 channel_ptr->volume_left = 0;
93 channel_ptr->volume_right = 0;
94 return;
97 if (channel_ptr->mixer_ptr->soloed_channels_count > 0 && !channel_ptr->soloed) /* there are soloed channels but we are not one of them */
99 channel_ptr->volume_left = 0;
100 channel_ptr->volume_right = 0;
101 return;
104 if (channel_ptr->stereo)
106 if (channel_ptr->balance > 0)
108 channel_ptr->volume_left = channel_ptr->volume * (1 - channel_ptr->balance);
109 channel_ptr->volume_right = channel_ptr->volume;
111 else
113 channel_ptr->volume_left = channel_ptr->volume;
114 channel_ptr->volume_right = channel_ptr->volume * (1 + channel_ptr->balance);
117 else
119 channel_ptr->volume_left = channel_ptr->volume * (1 - channel_ptr->balance);
120 channel_ptr->volume_right = channel_ptr->volume * (1 + channel_ptr->balance);
124 void
125 calc_all_channel_volumes(
126 struct jack_mixer * mixer_ptr)
128 struct list_head * node_ptr;
129 struct channel * channel_ptr;
131 list_for_each(node_ptr, &mixer_ptr->channels_list)
133 channel_ptr = list_entry(node_ptr, struct channel, siblings);
134 calc_channel_volumes(channel_ptr);
138 #define channel_ptr ((struct channel *)channel)
140 const char * channel_get_name(jack_mixer_channel_t channel)
142 return channel_ptr->name;
145 void channel_rename(jack_mixer_channel_t channel, const char * name)
147 char * new_name;
148 size_t channel_name_size;
149 char * port_name;
150 int ret;
152 new_name = strdup(name);
153 if (new_name == NULL)
155 return;
158 if (channel_ptr->name)
160 free(channel_ptr->name);
163 channel_ptr->name = new_name;
165 if (channel_ptr->stereo)
167 channel_name_size = strlen(name);
168 port_name = malloc(channel_name_size + 3);
169 memcpy(port_name, name, channel_name_size);
171 port_name[channel_name_size] = ' ';
172 port_name[channel_name_size+1] = 'L';
173 port_name[channel_name_size+2] = 0;
175 ret = jack_port_set_name(channel_ptr->port_left, port_name);
176 if (ret != 0)
178 /* what could we do here? */
181 port_name[channel_name_size+1] = 'R';
183 ret = jack_port_set_name(channel_ptr->port_right, port_name);
184 if (ret != 0)
186 /* what could we do here? */
189 free(port_name);
191 else
193 ret = jack_port_set_name(channel_ptr->port_left, name);
194 if (ret != 0)
196 /* what could we do here? */
201 bool channel_is_stereo(jack_mixer_channel_t channel)
203 return channel_ptr->stereo;
206 void remove_channel(jack_mixer_channel_t channel)
208 list_del(&channel_ptr->siblings);
209 free(channel_ptr->name);
211 jack_port_unregister(channel_ptr->mixer_ptr->jack_client, channel_ptr->port_left);
212 if (channel_ptr->stereo)
214 jack_port_unregister(channel_ptr->mixer_ptr->jack_client, channel_ptr->port_right);
217 channel_ptr->mixer_ptr->channels_count--;
219 free(channel_ptr);
222 void channel_stereo_meter_read(jack_mixer_channel_t channel, double * left_ptr, double * right_ptr)
224 *left_ptr = value_to_db(channel_ptr->meter_left);
225 *right_ptr = value_to_db(channel_ptr->meter_right);
228 void channel_mono_meter_read(jack_mixer_channel_t channel, double * mono_ptr)
230 *mono_ptr = value_to_db(channel_ptr->meter_left);
233 void channel_volume_write(jack_mixer_channel_t channel, double volume)
235 channel_ptr->volume = db_to_value(volume);
236 calc_channel_volumes(channel_ptr);
239 void channel_balance_write(jack_mixer_channel_t channel, double balance)
241 channel_ptr->balance = balance;
242 calc_channel_volumes(channel_ptr);
245 double channel_abspeak_read(jack_mixer_channel_t channel)
247 if (channel_ptr->NaN_detected)
249 return sqrt(-1);
251 else
253 return value_to_db(channel_ptr->abspeak);
257 void channel_abspeak_reset(jack_mixer_channel_t channel)
259 channel_ptr->abspeak = 0;
260 channel_ptr->NaN_detected = false;
263 void channel_mute(jack_mixer_channel_t channel)
265 channel_ptr->muted = true;
266 calc_channel_volumes(channel_ptr);
269 void channel_unmute(jack_mixer_channel_t channel)
271 channel_ptr->muted = false;
272 calc_channel_volumes(channel_ptr);
275 void channel_solo(jack_mixer_channel_t channel)
277 if (!channel_ptr->soloed)
279 channel_ptr->soloed = true;
280 channel_ptr->mixer_ptr->soloed_channels_count++;
282 if (channel_ptr->mixer_ptr->soloed_channels_count == 1)
284 calc_all_channel_volumes(channel_ptr->mixer_ptr);
286 else
288 calc_channel_volumes(channel_ptr);
293 void channel_unsolo(jack_mixer_channel_t channel)
295 if (channel_ptr->soloed)
297 channel_ptr->soloed = false;
298 channel_ptr->mixer_ptr->soloed_channels_count--;
300 if (channel_ptr->mixer_ptr->soloed_channels_count == 0)
302 calc_all_channel_volumes(channel_ptr->mixer_ptr);
304 else
306 calc_channel_volumes(channel_ptr);
311 bool channel_is_muted(jack_mixer_channel_t channel)
313 return channel_ptr->muted;
316 bool channel_is_soloed(jack_mixer_channel_t channel)
318 return channel_ptr->soloed;
321 #undef channel_ptr
323 #define mixer_ptr ((struct jack_mixer *)context)
326 process(jack_nframes_t nframes, void * context)
328 jack_default_audio_sample_t * out_left;
329 jack_default_audio_sample_t * out_right;
330 jack_default_audio_sample_t * in_left;
331 jack_default_audio_sample_t * in_right;
332 jack_nframes_t i;
333 struct list_head * node_ptr;
334 struct channel * channel_ptr;
335 jack_default_audio_sample_t frame_left;
336 jack_default_audio_sample_t frame_right;
338 out_left = jack_port_get_buffer(mixer_ptr->main_mix_channel.port_left, nframes);
339 out_right = jack_port_get_buffer(mixer_ptr->main_mix_channel.port_right, nframes);
341 for (i = 0 ; i < nframes ; i++)
343 out_left[i] = 0.0;
344 out_right[i] = 0.0;
347 in_right = NULL; /* disable warning */
349 /* process input channels and mix them into main mix */
350 list_for_each(node_ptr, &mixer_ptr->channels_list)
352 channel_ptr = list_entry(node_ptr, struct channel, siblings);
354 in_left = jack_port_get_buffer(channel_ptr->port_left, nframes);
356 if (channel_ptr->stereo)
358 in_right = jack_port_get_buffer(channel_ptr->port_right, nframes);
361 for (i = 0 ; i < nframes ; i++)
363 if (!FLOAT_EXISTS(in_left[i]))
365 channel_ptr->NaN_detected = true;
366 break;
369 frame_left = in_left[i] * channel_ptr->volume_left;
370 out_left[i] += frame_left;
372 if (channel_ptr->stereo)
374 frame_right = in_right[i] * channel_ptr->volume_right;
376 if (!FLOAT_EXISTS(in_right[i]))
378 channel_ptr->NaN_detected = true;
379 break;
382 else
384 frame_right = in_left[i] * channel_ptr->volume_right;
386 out_right[i] += frame_right;
388 if (channel_ptr->stereo)
390 frame_left = fabsf(frame_left);
391 frame_right = fabsf(frame_right);
393 if (channel_ptr->peak_left < frame_left)
395 channel_ptr->peak_left = frame_left;
397 if (frame_left > channel_ptr->abspeak)
399 channel_ptr->abspeak = frame_left;
403 if (channel_ptr->peak_right < frame_right)
405 channel_ptr->peak_right = frame_right;
407 if (frame_right > channel_ptr->abspeak)
409 channel_ptr->abspeak = frame_right;
413 else
415 frame_left = (fabsf(frame_left) + fabsf(frame_right)) / 2;
417 if (channel_ptr->peak_left < frame_left)
419 channel_ptr->peak_left = frame_left;
421 if (frame_left > channel_ptr->abspeak)
423 channel_ptr->abspeak = frame_left;
428 channel_ptr->peak_frames++;
429 if (channel_ptr->peak_frames >= PEAK_FRAMES_CHUNK)
431 channel_ptr->meter_left = channel_ptr->peak_left;
432 channel_ptr->peak_left = 0.0;
434 if (channel_ptr->stereo)
436 channel_ptr->meter_right = channel_ptr->peak_right;
437 channel_ptr->peak_right = 0.0;
440 channel_ptr->peak_frames = 0;
445 /* process main mix channel */
446 for (i = 0 ; i < nframes ; i++)
448 out_left[i] = out_left[i] * mixer_ptr->main_mix_channel.volume_left;
449 out_right[i] = out_right[i] * mixer_ptr->main_mix_channel.volume_right;
451 frame_left = fabsf(out_left[i]);
452 if (mixer_ptr->main_mix_channel.peak_left < frame_left)
454 mixer_ptr->main_mix_channel.peak_left = frame_left;
456 if (frame_left > mixer_ptr->main_mix_channel.abspeak)
458 mixer_ptr->main_mix_channel.abspeak = frame_left;
462 frame_right = fabsf(out_right[i]);
463 if (mixer_ptr->main_mix_channel.peak_right < frame_right)
465 mixer_ptr->main_mix_channel.peak_right = frame_right;
467 if (frame_right > mixer_ptr->main_mix_channel.abspeak)
469 mixer_ptr->main_mix_channel.abspeak = frame_right;
473 mixer_ptr->main_mix_channel.peak_frames++;
474 if (mixer_ptr->main_mix_channel.peak_frames >= PEAK_FRAMES_CHUNK)
476 mixer_ptr->main_mix_channel.meter_left = mixer_ptr->main_mix_channel.peak_left;
477 mixer_ptr->main_mix_channel.peak_left = 0.0;
479 mixer_ptr->main_mix_channel.meter_right = mixer_ptr->main_mix_channel.peak_right;
480 mixer_ptr->main_mix_channel.peak_right = 0.0;
482 mixer_ptr->main_mix_channel.peak_frames = 0;
486 return 0;
489 #undef mixer_ptr
491 jack_mixer_t
492 create(
493 const char * jack_client_name_ptr)
495 int ret;
496 struct jack_mixer * mixer_ptr;
499 mixer_ptr = malloc(sizeof(struct jack_mixer));
500 if (mixer_ptr == NULL)
502 goto exit;
505 INIT_LIST_HEAD(&mixer_ptr->channels_list);
507 mixer_ptr->channels_count = 0;
508 mixer_ptr->soloed_channels_count = 0;
510 LOG_DEBUG("Initializing JACK");
511 mixer_ptr->jack_client = jack_client_new(jack_client_name_ptr);
512 if (mixer_ptr->jack_client == NULL)
514 LOG_ERROR("Cannot create JACK client.");
515 LOG_NOTICE("Please make sure JACK daemon is running.");
516 goto exit_free;
519 LOG_DEBUG("JACK client created");
521 LOG_DEBUG("Sample rate: %" PRIu32, jack_get_sample_rate(mixer_ptr->jack_client));
523 mixer_ptr->main_mix_channel.mixer_ptr = mixer_ptr;
525 mixer_ptr->main_mix_channel.port_left = jack_port_register(mixer_ptr->jack_client, "main out L", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
526 if (mixer_ptr->main_mix_channel.port_left == NULL)
528 LOG_ERROR("Cannot create JACK port");
529 goto close_jack;
532 mixer_ptr->main_mix_channel.port_right = jack_port_register(mixer_ptr->jack_client, "main out R", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
533 if (mixer_ptr->main_mix_channel.port_right == NULL)
535 LOG_ERROR("Cannot create JACK port");
536 goto close_jack;
539 mixer_ptr->main_mix_channel.stereo = true;
541 mixer_ptr->main_mix_channel.volume = 0.0;
542 mixer_ptr->main_mix_channel.balance = 0.0;
543 mixer_ptr->main_mix_channel.muted = false;
544 mixer_ptr->main_mix_channel.soloed = false;
545 mixer_ptr->main_mix_channel.meter_left = 0.0;
546 mixer_ptr->main_mix_channel.meter_right = 0.0;
547 mixer_ptr->main_mix_channel.abspeak = 0.0;
549 mixer_ptr->main_mix_channel.peak_left = 0.0;
550 mixer_ptr->main_mix_channel.peak_right = 0.0;
551 mixer_ptr->main_mix_channel.peak_frames = 0;
553 mixer_ptr->main_mix_channel.NaN_detected = false;
555 calc_channel_volumes(&mixer_ptr->main_mix_channel);
557 ret = jack_set_process_callback(mixer_ptr->jack_client, process, mixer_ptr);
558 if (ret != 0)
560 LOG_ERROR("Cannot set JACK process callback");
561 goto close_jack;
564 ret = jack_activate(mixer_ptr->jack_client);
565 if (ret != 0)
567 LOG_ERROR("Cannot activate JACK client");
568 goto close_jack;
571 return mixer_ptr;
573 close_jack:
574 jack_client_close(mixer_ptr->jack_client); /* this should clear all other resources we obtained through the client handle */
576 exit_free:
577 free(mixer_ptr);
579 exit:
580 return NULL;
583 #define mixer_ctx_ptr ((struct jack_mixer *)mixer)
585 void
586 destroy(
587 jack_mixer_t mixer)
589 LOG_DEBUG("Uninitializing JACK");
590 if (mixer_ctx_ptr->jack_client != NULL)
592 jack_client_close(mixer_ctx_ptr->jack_client);
595 free(mixer_ctx_ptr);
598 jack_mixer_channel_t
599 get_main_mix_channel(
600 jack_mixer_t mixer)
602 return &mixer_ctx_ptr->main_mix_channel;
605 unsigned int
606 get_channels_count(
607 jack_mixer_t mixer)
609 return mixer_ctx_ptr->channels_count;
612 jack_mixer_channel_t
613 add_channel(
614 jack_mixer_t mixer,
615 const char * channel_name,
616 bool stereo)
618 struct channel * channel_ptr;
619 char * port_name;
620 size_t channel_name_size;
622 channel_ptr = malloc(sizeof(struct channel));
623 if (channel_ptr == NULL)
625 goto exit;
628 channel_ptr->mixer_ptr = mixer_ctx_ptr;
630 channel_ptr->name = strdup(channel_name);
631 if (channel_ptr->name == NULL)
633 goto exit_free_channel;
636 if (stereo)
638 channel_name_size = strlen(channel_name);
639 port_name = malloc(channel_name_size + 3);
640 memcpy(port_name, channel_name, channel_name_size);
641 port_name[channel_name_size] = ' ';
642 port_name[channel_name_size+1] = 'L';
643 port_name[channel_name_size+2] = 0;
644 channel_ptr->port_left = jack_port_register(channel_ptr->mixer_ptr->jack_client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
645 port_name[channel_name_size+1] = 'R';
646 channel_ptr->port_right = jack_port_register(channel_ptr->mixer_ptr->jack_client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
647 free(port_name);
649 else
651 channel_ptr->port_left = jack_port_register(channel_ptr->mixer_ptr->jack_client, channel_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
654 channel_ptr->stereo = stereo;
656 channel_ptr->volume = 0.0;
657 channel_ptr->balance = 0.0;
658 channel_ptr->muted = false;
659 channel_ptr->soloed = false;
660 channel_ptr->meter_left = -1.0;
661 channel_ptr->meter_right = -1.0;
662 channel_ptr->abspeak = 0.0;
664 channel_ptr->peak_left = 0.0;
665 channel_ptr->peak_right = 0.0;
666 channel_ptr->peak_frames = 0;
668 channel_ptr->NaN_detected = false;
670 calc_channel_volumes(channel_ptr);
672 list_add_tail(&channel_ptr->siblings, &channel_ptr->mixer_ptr->channels_list);
673 channel_ptr->mixer_ptr->channels_count++;
675 goto exit;
677 exit_free_channel:
678 free(channel_ptr);
680 exit:
681 return channel_ptr;