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>
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 *****************************************************************************/
27 #include <jack/jack.h>
29 #include "jack_mixer.h"
32 jack_client_t
* g_jack_client
;
34 #define PEAK_FRAMES_CHUNK 4800
36 struct list_head g_channels_list
;
40 struct list_head siblings
;
42 int stereo
; /* boolean */
52 jack_port_t
* port_left
;
53 jack_port_t
* port_right
;
55 jack_nframes_t peak_frames
;
60 struct channel g_main_mix_channel
;
63 int g_soloed_channels_count
;
65 float value_to_db(float value
)
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
;
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;
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;
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
;
116 channel_ptr
->volume_left
= channel_ptr
->volume
;
117 channel_ptr
->volume_right
= channel_ptr
->volume
* (1 + channel_ptr
->balance
);
122 channel_ptr
->volume_left
= channel_ptr
->volume
* (1 - channel_ptr
->balance
);
123 channel_ptr
->volume_right
= channel_ptr
->volume
* (1 + channel_ptr
->balance
);
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
;
144 size_t channel_name_size
;
146 channel_ptr
= malloc(sizeof(struct channel
));
147 if (channel_ptr
== NULL
)
152 channel_ptr
->name
= strdup(channel_name
);
153 if (channel_ptr
->name
== NULL
)
155 goto exit_free_channel
;
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);
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
);
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
)
214 size_t channel_name_size
;
218 new_name
= strdup(name
);
219 if (new_name
== NULL
)
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
);
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
);
252 /* what could we do here? */
259 ret
= jack_port_set_name(channel_ptr
->port_left
, port_name
);
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
);
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();
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();
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
;
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
;
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
++)
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
;
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
;
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;
531 int init(const char * jack_client_name_ptr
)
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");
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");
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");
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
);
583 fprintf(stderr
, "Cannot set JACK process callback");
587 ret
= jack_activate(g_jack_client
);
590 fprintf(stderr
, "Cannot activate JACK client");
597 jack_client_close(g_jack_client
); /* this should clear all other resources we obtained through the client handle */
600 return 0; /* false */
605 printf("Uninitializing JACK\n");
606 if (g_jack_client
!= NULL
)
608 jack_client_close(g_jack_client
);