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"
31 //#define LOG_LEVEL LOG_LEVEL_DEBUG
34 #define PEAK_FRAMES_CHUNK 4800
36 #define FLOAT_EXISTS(x) (!((x) - (x)))
40 struct list_head siblings
;
41 struct jack_mixer
* mixer_ptr
;
53 jack_port_t
* port_left
;
54 jack_port_t
* port_right
;
56 jack_nframes_t peak_frames
;
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
)
79 return 20.0 * log10f(value
);
82 float db_to_value(float db
)
84 return powf(10.0, db
/20.0);
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;
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;
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
;
113 channel_ptr
->volume_left
= channel_ptr
->volume
;
114 channel_ptr
->volume_right
= channel_ptr
->volume
* (1 + channel_ptr
->balance
);
119 channel_ptr
->volume_left
= channel_ptr
->volume
* (1 - channel_ptr
->balance
);
120 channel_ptr
->volume_right
= channel_ptr
->volume
* (1 + channel_ptr
->balance
);
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
)
148 size_t channel_name_size
;
152 new_name
= strdup(name
);
153 if (new_name
== NULL
)
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
);
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
);
186 /* what could we do here? */
193 ret
= jack_port_set_name(channel_ptr
->port_left
, name
);
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
--;
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
)
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
);
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
);
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
;
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
;
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
++)
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;
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;
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
;
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;
493 const char * jack_client_name_ptr
)
496 struct jack_mixer
* mixer_ptr
;
499 mixer_ptr
= malloc(sizeof(struct jack_mixer
));
500 if (mixer_ptr
== NULL
)
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.");
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");
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");
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
);
560 LOG_ERROR("Cannot set JACK process callback");
564 ret
= jack_activate(mixer_ptr
->jack_client
);
567 LOG_ERROR("Cannot activate JACK client");
574 jack_client_close(mixer_ptr
->jack_client
); /* this should clear all other resources we obtained through the client handle */
583 #define mixer_ctx_ptr ((struct jack_mixer *)mixer)
589 LOG_DEBUG("Uninitializing JACK");
590 if (mixer_ctx_ptr
->jack_client
!= NULL
)
592 jack_client_close(mixer_ctx_ptr
->jack_client
);
599 get_main_mix_channel(
602 return &mixer_ctx_ptr
->main_mix_channel
;
609 return mixer_ctx_ptr
->channels_count
;
615 const char * channel_name
,
618 struct channel
* channel_ptr
;
620 size_t channel_name_size
;
622 channel_ptr
= malloc(sizeof(struct channel
));
623 if (channel_ptr
== NULL
)
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
;
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);
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
++;