Import r193 from triton repository
[jack_mixer.git] / jack_mixer.c
blob5eb59e744116bb66525424b850de1dd189d038aa
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 <stdio.h>
26 #include <math.h>
27 #include <jack/jack.h>
29 #include "jack_mixer.h"
30 #include "list.h"
32 jack_client_t * g_jack_client;
34 #define PEAK_FRAMES_CHUNK 4800
36 struct list_head g_channels_list;
38 struct channel
40 struct list_head siblings;
41 char * name;
42 int stereo; /* boolean */
43 float volume;
44 float balance;
45 int muted;
46 int soloed;
47 float volume_left;
48 float volume_right;
49 float meter_left;
50 float meter_right;
51 float abspeak;
52 jack_port_t * port_left;
53 jack_port_t * port_right;
55 jack_nframes_t peak_frames;
56 float peak_left;
57 float peak_right;
60 struct channel g_main_mix_channel;
62 int g_channels_count;
63 int g_soloed_channels_count;
65 float value_to_db(float value)
67 if (value <= 0)
69 return -INFINITY;
72 return 20.0 * log10f(value);
75 float db_to_value(float db)
77 return powf(10.0, db/20.0);
80 void * get_main_mix_channel()
82 return &g_main_mix_channel;
85 int get_channels_count()
87 return g_channels_count;
90 void
91 calc_channel_volumes(struct channel * channel_ptr)
93 if (channel_ptr->muted)
95 channel_ptr->volume_left = 0;
96 channel_ptr->volume_right = 0;
97 return;
100 if (g_soloed_channels_count > 0 && !channel_ptr->soloed) /* there are soloed channels but we are not one of them */
102 channel_ptr->volume_left = 0;
103 channel_ptr->volume_right = 0;
104 return;
107 if (channel_ptr->stereo)
109 if (channel_ptr->balance > 0)
111 channel_ptr->volume_left = channel_ptr->volume * (1 - channel_ptr->balance);
112 channel_ptr->volume_right = channel_ptr->volume;
114 else
116 channel_ptr->volume_left = channel_ptr->volume;
117 channel_ptr->volume_right = channel_ptr->volume * (1 + channel_ptr->balance);
120 else
122 channel_ptr->volume_left = channel_ptr->volume * (1 - channel_ptr->balance);
123 channel_ptr->volume_right = channel_ptr->volume * (1 + channel_ptr->balance);
127 void
128 calc_all_channel_volumes()
130 struct list_head * node_ptr;
131 struct channel * channel_ptr;
133 list_for_each(node_ptr, &g_channels_list)
135 channel_ptr = list_entry(node_ptr, struct channel, siblings);
136 calc_channel_volumes(channel_ptr);
140 void * add_channel(const char * channel_name, int stereo)
142 struct channel * channel_ptr;
143 char * port_name;
144 size_t channel_name_size;
146 channel_ptr = malloc(sizeof(struct channel));
147 if (channel_ptr == NULL)
149 goto exit;
152 channel_ptr->name = strdup(channel_name);
153 if (channel_ptr->name == NULL)
155 goto exit_free_channel;
158 if (stereo)
160 channel_name_size = strlen(channel_name);
161 port_name = malloc(channel_name_size + 3);
162 memcpy(port_name, channel_name, channel_name_size);
163 port_name[channel_name_size] = ' ';
164 port_name[channel_name_size+1] = 'L';
165 port_name[channel_name_size+2] = 0;
166 channel_ptr->port_left = jack_port_register(g_jack_client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
167 port_name[channel_name_size+1] = 'R';
168 channel_ptr->port_right = jack_port_register(g_jack_client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
169 free(port_name);
171 else
173 channel_ptr->port_left = jack_port_register(g_jack_client, channel_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
176 channel_ptr->stereo = stereo;
178 channel_ptr->volume = 0.0;
179 channel_ptr->balance = 0.0;
180 channel_ptr->muted = 0;
181 channel_ptr->soloed = 0;
182 channel_ptr->meter_left = -1.0;
183 channel_ptr->meter_right = -1.0;
184 channel_ptr->abspeak = 0.0;
186 channel_ptr->peak_left = 0.0;
187 channel_ptr->peak_right = 0.0;
188 channel_ptr->peak_frames = 0;
190 calc_channel_volumes(channel_ptr);
192 list_add_tail(&channel_ptr->siblings, &g_channels_list);
193 g_channels_count++;
195 goto exit;
197 exit_free_channel:
198 free(channel_ptr);
200 exit:
201 return channel_ptr;
204 #define channel_ptr ((struct channel *)channel)
206 const char * channel_get_name(void * channel)
208 return channel_ptr->name;
211 void channel_rename(void * channel, const char * name)
213 char * new_name;
214 size_t channel_name_size;
215 char * port_name;
216 int ret;
218 new_name = strdup(name);
219 if (new_name == NULL)
221 return;
224 if (channel_ptr->name)
226 free(channel_ptr->name);
229 channel_ptr->name = new_name;
231 if (channel_ptr->stereo)
233 channel_name_size = strlen(name);
234 port_name = malloc(channel_name_size + 3);
235 memcpy(port_name, name, channel_name_size);
237 port_name[channel_name_size] = ' ';
238 port_name[channel_name_size+1] = 'L';
239 port_name[channel_name_size+2] = 0;
241 ret = jack_port_set_name(channel_ptr->port_left, port_name);
242 if (ret != 0)
244 /* what could we do here? */
247 port_name[channel_name_size+1] = 'R';
249 ret = jack_port_set_name(channel_ptr->port_right, port_name);
250 if (ret != 0)
252 /* what could we do here? */
255 free(port_name);
257 else
259 ret = jack_port_set_name(channel_ptr->port_left, port_name);
260 if (ret != 0)
262 /* what could we do here? */
267 int channel_is_stereo(void * channel)
269 return channel_ptr->stereo;
272 void remove_channel(void * channel)
274 list_del(&channel_ptr->siblings);
275 free(channel_ptr->name);
277 jack_port_unregister(g_jack_client, channel_ptr->port_left);
278 if (channel_ptr->stereo)
280 jack_port_unregister(g_jack_client, channel_ptr->port_right);
283 free(channel_ptr);
285 g_channels_count--;
288 void channel_stereo_meter_read(void * channel, double * left_ptr, double * right_ptr)
290 *left_ptr = value_to_db(channel_ptr->meter_left);
291 *right_ptr = value_to_db(channel_ptr->meter_right);
294 void channel_mono_meter_read(void * channel, double * mono_ptr)
296 *mono_ptr = value_to_db(channel_ptr->meter_left);
299 void channel_volume_write(void * channel, double volume)
301 channel_ptr->volume = db_to_value(volume);
302 calc_channel_volumes(channel_ptr);
305 void channel_balance_write(void * channel, double balance)
307 channel_ptr->balance = balance;
308 calc_channel_volumes(channel_ptr);
311 double channel_abspeak_read(void * channel)
313 return value_to_db(channel_ptr->abspeak);
316 void channel_abspeak_reset(void * channel)
318 channel_ptr->abspeak = 0;
321 void channel_mute(void * channel)
323 channel_ptr->muted = 1;
324 calc_channel_volumes(channel_ptr);
327 void channel_unmute(void * channel)
329 channel_ptr->muted = 0;
330 calc_channel_volumes(channel_ptr);
333 void channel_solo(void * channel)
335 if (!channel_ptr->soloed)
337 channel_ptr->soloed = 1;
338 g_soloed_channels_count++;
340 if (g_soloed_channels_count == 1)
342 calc_all_channel_volumes();
344 else
346 calc_channel_volumes(channel_ptr);
351 void channel_unsolo(void * channel)
353 if (channel_ptr->soloed)
355 channel_ptr->soloed = 0;
356 g_soloed_channels_count--;
358 if (g_soloed_channels_count == 0)
360 calc_all_channel_volumes();
362 else
364 calc_channel_volumes(channel_ptr);
369 int channel_is_muted(void * channel)
371 return channel_ptr->muted;
374 int channel_is_soloed(void * channel)
376 return channel_ptr->soloed;
379 #undef channel_ptr
382 process(jack_nframes_t nframes, void *arg)
384 jack_default_audio_sample_t * out_left;
385 jack_default_audio_sample_t * out_right;
386 jack_default_audio_sample_t * in_left;
387 jack_default_audio_sample_t * in_right;
388 jack_nframes_t i;
389 struct list_head * node_ptr;
390 struct channel * channel_ptr;
391 jack_default_audio_sample_t frame_left;
392 jack_default_audio_sample_t frame_right;
394 out_left = jack_port_get_buffer(g_main_mix_channel.port_left, nframes);
395 out_right = jack_port_get_buffer(g_main_mix_channel.port_right, nframes);
397 for (i = 0 ; i < nframes ; i++)
399 out_left[i] = 0.0;
400 out_right[i] = 0.0;
403 /* process input channels and mix them into main mix */
404 list_for_each(node_ptr, &g_channels_list)
406 channel_ptr = list_entry(node_ptr, struct channel, siblings);
408 in_left = jack_port_get_buffer(channel_ptr->port_left, nframes);
410 if (channel_ptr->stereo)
412 in_right = jack_port_get_buffer(channel_ptr->port_right, nframes);
415 for (i = 0 ; i < nframes ; i++)
417 frame_left = in_left[i] * channel_ptr->volume_left;
418 out_left[i] += frame_left;
420 if (channel_ptr->stereo)
422 frame_right = in_right[i] * channel_ptr->volume_right;
424 else
426 frame_right = in_left[i] * channel_ptr->volume_right;
428 out_right[i] += frame_right;
430 if (channel_ptr->stereo)
432 frame_left = fabsf(frame_left);
433 frame_right = fabsf(frame_right);
435 if (channel_ptr->peak_left < frame_left)
437 channel_ptr->peak_left = frame_left;
439 if (frame_left > channel_ptr->abspeak)
441 channel_ptr->abspeak = frame_left;
445 if (channel_ptr->peak_right < frame_right)
447 channel_ptr->peak_right = frame_right;
449 if (frame_right > channel_ptr->abspeak)
451 channel_ptr->abspeak = frame_right;
455 else
457 frame_left = (fabsf(frame_left) + fabsf(frame_right)) / 2;
459 if (channel_ptr->peak_left < frame_left)
461 channel_ptr->peak_left = frame_left;
463 if (frame_left > channel_ptr->abspeak)
465 channel_ptr->abspeak = frame_left;
470 channel_ptr->peak_frames++;
471 if (channel_ptr->peak_frames >= PEAK_FRAMES_CHUNK)
473 channel_ptr->meter_left = channel_ptr->peak_left;
474 channel_ptr->peak_left = 0.0;
476 if (channel_ptr->stereo)
478 channel_ptr->meter_right = channel_ptr->peak_right;
479 channel_ptr->peak_right = 0.0;
482 channel_ptr->peak_frames = 0;
487 /* process main mix channel */
488 for (i = 0 ; i < nframes ; i++)
490 out_left[i] = out_left[i] * g_main_mix_channel.volume_left;
491 out_right[i] = out_right[i] * g_main_mix_channel.volume_right;
493 frame_left = fabsf(out_left[i]);
494 if (g_main_mix_channel.peak_left < frame_left)
496 g_main_mix_channel.peak_left = frame_left;
498 if (frame_left > g_main_mix_channel.abspeak)
500 g_main_mix_channel.abspeak = frame_left;
504 frame_right = fabsf(out_right[i]);
505 if (g_main_mix_channel.peak_right < frame_right)
507 g_main_mix_channel.peak_right = frame_right;
509 if (frame_right > g_main_mix_channel.abspeak)
511 g_main_mix_channel.abspeak = frame_right;
515 g_main_mix_channel.peak_frames++;
516 if (g_main_mix_channel.peak_frames >= PEAK_FRAMES_CHUNK)
518 g_main_mix_channel.meter_left = g_main_mix_channel.peak_left;
519 g_main_mix_channel.peak_left = 0.0;
521 g_main_mix_channel.meter_right = g_main_mix_channel.peak_right;
522 g_main_mix_channel.peak_right = 0.0;
524 g_main_mix_channel.peak_frames = 0;
528 return 0;
531 int init(const char * jack_client_name_ptr)
533 int ret;
535 INIT_LIST_HEAD(&g_channels_list);
537 printf("Initializing JACK\n");
538 g_jack_client = jack_client_new(jack_client_name_ptr);
539 if (g_jack_client == NULL)
541 fprintf(stderr, "Cannot create JACK client.\n");
542 fprintf(stderr, "Please make sure JACK daemon is running.\n");
543 goto exit;
546 printf("JACK client created\n");
548 printf("Sample rate: %" PRIu32 "\n", jack_get_sample_rate(g_jack_client));
550 g_main_mix_channel.port_left = jack_port_register(g_jack_client, "main out L", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
551 if (g_main_mix_channel.port_left == NULL)
553 fprintf(stderr, "Cannot create JACK port");
554 goto close_jack;
557 g_main_mix_channel.port_right = jack_port_register(g_jack_client, "main out R", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
558 if (g_main_mix_channel.port_right == NULL)
560 fprintf(stderr, "Cannot create JACK port");
561 goto close_jack;
564 g_main_mix_channel.stereo = 1; /* true */
566 g_main_mix_channel.volume = 0.0;
567 g_main_mix_channel.balance = 0.0;
568 g_main_mix_channel.muted = 0;
569 g_main_mix_channel.soloed = 0;
570 g_main_mix_channel.meter_left = 0.0;
571 g_main_mix_channel.meter_right = 0.0;
572 g_main_mix_channel.abspeak = 0.0;
574 g_main_mix_channel.peak_left = 0.0;
575 g_main_mix_channel.peak_right = 0.0;
576 g_main_mix_channel.peak_frames = 0;
578 calc_channel_volumes(&g_main_mix_channel);
580 ret = jack_set_process_callback(g_jack_client, process, NULL);
581 if (ret != 0)
583 fprintf(stderr, "Cannot set JACK process callback");
584 goto close_jack;
587 ret = jack_activate(g_jack_client);
588 if (ret != 0)
590 fprintf(stderr, "Cannot activate JACK client");
591 goto close_jack;
594 return 1; /* true */
596 close_jack:
597 jack_client_close(g_jack_client); /* this should clear all other resources we obtained through the client handle */
599 exit:
600 return 0; /* false */
603 void uninit()
605 printf("Uninitializing JACK\n");
606 if (g_jack_client != NULL)
608 jack_client_close(g_jack_client);