1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
4 * Copyright (C) John Stebbins 2008 <stebbins@stebbins>
6 * audiohandler.c is free software.
8 * You may redistribute it and/or modify it under the terms of the
9 * GNU General Public License, as published by the Free Software
10 * Foundation; either version 2 of the License, or (at your option)
17 #include "hb-backend.h"
19 #include "callbacks.h"
21 #include "audiohandler.h"
24 ghb_adjust_audio_rate_combos(signal_user_data_t *ud)
26 gint titleindex, audioindex, acodec, mix;
27 ghb_audio_info_t ainfo;
31 g_debug("ghb_adjust_audio_rate_combos ()");
32 titleindex = ghb_settings_combo_int(ud->settings, "title");
34 widget = GHB_WIDGET(ud->builder, "AudioTrack");
35 gval = ghb_widget_value(widget);
36 audioindex = ghb_lookup_combo_int("AudioTrack", gval);
39 widget = GHB_WIDGET(ud->builder, "AudioEncoder");
40 gval = ghb_widget_value(widget);
41 acodec = ghb_lookup_combo_int("AudioEncoder", gval);
43 widget = GHB_WIDGET(ud->builder, "AudioMixdown");
44 gval = ghb_widget_value(widget);
45 mix = ghb_lookup_combo_int("AudioMixdown", gval);
48 if (ghb_audio_is_passthru (acodec))
50 ghb_set_default_bitrate_opts (ud->builder, -1);
51 if (ghb_get_audio_info (&ainfo, titleindex, audioindex))
53 gint br = ainfo.bitrate / 1000;
54 // Set the values for bitrate and samplerate to the input rates
56 ghb_set_passthru_bitrate_opts (ud->builder, br);
59 ghb_ui_update(ud, "AudioBitrate", ghb_int64_value(br));
60 ghb_ui_update(ud, "AudioSamplerate", ghb_int64_value(0));
61 ghb_ui_update(ud, "AudioMixdown", ghb_int64_value(0));
65 ghb_ui_update(ud, "AudioBitrate", ghb_int64_value(384));
66 ghb_ui_update(ud, "AudioSamplerate", ghb_int64_value(0));
67 ghb_ui_update(ud, "AudioMixdown", ghb_int64_value(0));
69 ghb_ui_update(ud, "AudioTrackDRCSlider", ghb_double_value(0));
71 else if (acodec == HB_ACODEC_FAAC)
75 if (mix == HB_AMIXDOWN_6CH)
80 widget = GHB_WIDGET(ud->builder, "AudioBitrate");
81 gval = ghb_widget_value(widget);
82 br = ghb_lookup_combo_int("AudioBitrate", gval);
85 ghb_ui_update(ud, "AudioBitrate", ghb_int64_value(last));
86 ghb_set_default_bitrate_opts (ud->builder, last);
90 ghb_set_default_bitrate_opts (ud->builder, -1);
95 free_audio_index_list(gpointer data)
101 ghb_get_user_audio_lang(signal_user_data_t *ud, gint titleindex, gint track)
103 GValue *audio_list, *asettings;
106 audio_list = ghb_settings_get_value(ud->settings, "audio_list");
107 if (ghb_array_len(audio_list) <= track)
109 asettings = ghb_array_get_nth(audio_list, track);
110 track = ghb_settings_get_int(asettings, "AudioTrack");
111 lang = ghb_get_source_audio_lang(titleindex, track);
116 ghb_set_pref_audio(gint titleindex, signal_user_data_t *ud)
118 gint acodec_code, mix_code, track;
119 gchar *source_lang = NULL;
121 ghb_audio_info_t ainfo;
122 GHashTable *track_indices;
124 const GValue *pref_audio;
125 const GValue *audio, *acodec, *bitrate, *rate, *mix, *drc;
126 gint count, ii, list_count;
128 g_debug("set_pref_audio");
129 track_indices = g_hash_table_new_full(g_int_hash, g_int_equal,
130 NULL, free_audio_index_list);
131 // Clear the audio list
132 ghb_clear_audio_list(ud);
133 // Find "best" audio based on audio preferences
134 button = GHB_WIDGET (ud->builder, "audio_add");
135 if (!ghb_settings_get_boolean(ud->settings, "AudioDUB"))
137 source_lang = ghb_get_source_audio_lang(titleindex, 0);
139 if (source_lang == NULL)
140 source_lang = ghb_settings_get_string(ud->settings, "PreferredLanguage");
142 pref_audio = ghb_settings_get_value(ud->settings, "AudioList");
145 count = ghb_array_len(pref_audio);
146 for (ii = 0; ii < count; ii++)
148 audio = ghb_array_get_nth(pref_audio, ii);
149 acodec = ghb_settings_get_value(audio, "AudioEncoder");
150 bitrate = ghb_settings_get_value(audio, "AudioBitrate");
151 rate = ghb_settings_get_value(audio, "AudioSamplerate");
152 mix = ghb_settings_get_value(audio, "AudioMixdown");
153 drc = ghb_settings_get_value(audio, "AudioTrackDRCSlider");
154 acodec_code = ghb_lookup_combo_int("AudioEncoder", acodec);
155 // If there are multiple audios using the same codec, then
156 // select sequential tracks for each. The hash keeps track
157 // of the tracks used for each codec.
158 track = ghb_find_audio_track(titleindex, source_lang,
159 acodec_code, track_indices);
161 // 1. pref codec is ac3
162 // 2. source codec is not ac3
163 // 3. next pref is enabled
164 if (ghb_get_audio_info (&ainfo, titleindex, track) &&
165 ghb_audio_is_passthru (acodec_code))
167 // HB_ACODEC_* are bit fields. Treat acodec_code as mask
168 if (!(ainfo.codec & acodec_code))
170 acodec_code = ghb_get_default_acodec();
171 // If there's more audio to process, or we've already
172 // placed one in the list, then we can skip this one
173 if ((ii + 1 < count) || (list_count != 0))
181 acodec_code &= ainfo.codec;
184 if (titleindex >= 0 && track < 0)
186 if (acodec_code != 0)
189 g_signal_emit_by_name(button, "clicked", ud);
191 ghb_ui_update(ud, "AudioTrack", ghb_int64_value(track));
192 ghb_ui_update(ud, "AudioEncoder", acodec);
193 if (!ghb_audio_is_passthru (acodec_code))
195 // This gets set autimatically if the codec is passthru
196 ghb_ui_update(ud, "AudioBitrate", bitrate);
197 ghb_ui_update(ud, "AudioSamplerate", rate);
198 mix_code = ghb_lookup_combo_int("AudioMixdown", mix);
199 mix_code = ghb_get_best_mix(
200 titleindex, track, acodec_code, mix_code);
201 ghb_ui_update(ud, "AudioMixdown", ghb_int64_value(mix_code));
203 ghb_adjust_audio_rate_combos(ud);
204 ghb_ui_update(ud, "AudioTrackDRCSlider", drc);
208 g_hash_table_destroy(track_indices);
212 get_selected_asettings(signal_user_data_t *ud)
214 GtkTreeView *treeview;
215 GtkTreePath *treepath;
216 GtkTreeSelection *selection;
221 GValue *asettings = NULL;
222 const GValue *audio_list;
224 g_debug("get_selected_asettings ()");
225 treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
226 selection = gtk_tree_view_get_selection (treeview);
227 if (gtk_tree_selection_get_selected(selection, &store, &iter))
229 // Get the row number
230 treepath = gtk_tree_model_get_path (store, &iter);
231 indices = gtk_tree_path_get_indices (treepath);
233 gtk_tree_path_free(treepath);
234 // find audio settings
235 if (row < 0) return NULL;
236 audio_list = ghb_settings_get_value(ud->settings, "audio_list");
237 if (row >= ghb_array_len(audio_list))
239 asettings = ghb_array_get_nth(audio_list, row);
245 ghb_audio_list_refresh_selected(signal_user_data_t *ud)
247 GtkTreeView *treeview;
248 GtkTreePath *treepath;
249 GtkTreeSelection *selection;
254 GValue *asettings = NULL;
255 const GValue *audio_list;
257 g_debug("ghb_audio_list_refresh_selected ()");
258 treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
259 selection = gtk_tree_view_get_selection (treeview);
260 if (gtk_tree_selection_get_selected(selection, &store, &iter))
262 const gchar *track, *codec, *br, *sr, *mix;
263 gchar *s_drc, *s_track, *s_codec, *s_br, *s_sr, *s_mix;
266 // Get the row number
267 treepath = gtk_tree_model_get_path (store, &iter);
268 indices = gtk_tree_path_get_indices (treepath);
270 gtk_tree_path_free(treepath);
271 // find audio settings
273 audio_list = ghb_settings_get_value(ud->settings, "audio_list");
274 if (row >= ghb_array_len(audio_list))
276 asettings = ghb_array_get_nth(audio_list, row);
278 track = ghb_settings_combo_option(asettings, "AudioTrack");
279 itrack = ghb_settings_combo_int(asettings, "AudioTrack");
280 codec = ghb_settings_combo_option(asettings, "AudioEncoder");
281 icodec = ghb_settings_combo_int(asettings, "AudioEncoder");
282 br = ghb_settings_combo_option(asettings, "AudioBitrate");
283 sr = ghb_settings_combo_option(asettings, "AudioSamplerate");
284 mix = ghb_settings_combo_option(asettings, "AudioMixdown");
286 s_track = ghb_settings_get_string(asettings, "AudioTrack");
287 s_codec = ghb_settings_get_string(asettings, "AudioEncoder");
288 s_br = ghb_settings_get_string(asettings, "AudioBitrate");
289 s_sr = ghb_settings_get_string(asettings, "AudioSamplerate");
290 s_mix = ghb_settings_get_string(asettings, "AudioMixdown");
291 drc = ghb_settings_get_double(asettings, "AudioTrackDRCSlider");
293 s_drc = g_strdup("Off");
295 s_drc = g_strdup_printf("%.1f", drc);
297 if (icodec == HB_ACODEC_MASK)
298 codec = ghb_select_audio_codec_str(ud, itrack);
300 gtk_list_store_set(GTK_LIST_STORE(store), &iter,
301 // These are displayed in list
308 // These are used to set combo values when a list item is selected
326 audio_codec_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
328 static gint prev_acodec = 0;
329 gint acodec_code, mix_code;
330 GValue *asettings, *gval;
332 g_debug("audio_codec_changed_cb ()");
333 gval = ghb_widget_value(widget);
334 acodec_code = ghb_lookup_combo_int("AudioEncoder", gval);
335 ghb_value_free(gval);
336 if (ghb_audio_is_passthru (prev_acodec) &&
337 !ghb_audio_is_passthru (acodec_code))
339 // Transition from passthru to not, put some audio settings back to
344 titleindex = ghb_settings_combo_int(ud->settings, "title");
345 track = ghb_settings_combo_int(ud->settings, "AudioTrack");
347 ghb_ui_update(ud, "AudioBitrate", ghb_string_value("160"));
348 ghb_ui_update(ud, "AudioSamplerate", ghb_string_value("source"));
349 mix_code = ghb_lookup_combo_int("AudioMixdown", ghb_string_value("dpl2"));
350 mix_code = ghb_get_best_mix( titleindex, track, acodec_code, mix_code);
351 ghb_ui_update(ud, "AudioMixdown", ghb_int64_value(mix_code));
353 ghb_adjust_audio_rate_combos(ud);
354 ghb_grey_combo_options (ud->builder);
355 ghb_check_dependency(ud, widget, NULL);
356 prev_acodec = acodec_code;
357 asettings = get_selected_asettings(ud);
358 if (asettings != NULL)
360 ghb_widget_to_setting(asettings, widget);
361 ghb_audio_list_refresh_selected(ud);
363 ghb_update_destination_extension(ud);
368 audio_track_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
372 g_debug("audio_track_changed_cb ()");
373 ghb_adjust_audio_rate_combos(ud);
374 ghb_check_dependency(ud, widget, NULL);
375 ghb_grey_combo_options(ud->builder);
376 asettings = get_selected_asettings(ud);
377 if (asettings != NULL)
381 ghb_widget_to_setting(asettings, widget);
382 ghb_audio_list_refresh_selected(ud);
383 track = ghb_settings_combo_option(asettings, "AudioTrack");
384 ghb_settings_set_string(asettings, "AudioTrackDescription", track);
390 audio_mix_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
394 g_debug("audio_mix_changed_cb ()");
395 ghb_adjust_audio_rate_combos(ud);
396 ghb_check_dependency(ud, widget, NULL);
397 asettings = get_selected_asettings(ud);
398 if (asettings != NULL)
400 ghb_widget_to_setting(asettings, widget);
401 ghb_audio_list_refresh_selected(ud);
407 audio_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
411 g_debug("audio_widget_changed_cb ()");
412 ghb_check_dependency(ud, widget, NULL);
413 asettings = get_selected_asettings(ud);
414 if (asettings != NULL)
416 ghb_widget_to_setting(asettings, widget);
417 ghb_audio_list_refresh_selected(ud);
423 drc_widget_changed_cb(GtkWidget *widget, gdouble val, signal_user_data_t *ud)
429 g_debug("drc_widget_changed_cb ()");
431 label = GTK_LABEL(GHB_WIDGET(ud->builder, "drc_label"));
433 drc = g_strdup_printf("Off");
435 drc = g_strdup_printf("%.1f", val);
436 gtk_label_set_text(label, drc);
438 ghb_check_dependency(ud, widget, NULL);
439 asettings = get_selected_asettings(ud);
440 if (asettings != NULL)
442 ghb_widget_to_setting(asettings, widget);
443 ghb_audio_list_refresh_selected(ud);
448 // subtitles differ from other settings in that
449 // the selection is updated automaitcally when the title
450 // changes. I don't want the preset selection changed as
451 // would happen for regular settings.
453 subtitle_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
455 const gchar *name = gtk_widget_get_name(widget);
456 g_debug("subtitle_changed_cb () %s", name);
457 ghb_widget_to_setting(ud->settings, widget);
458 ghb_check_dependency(ud, widget, NULL);
463 ghb_clear_audio_list(signal_user_data_t *ud)
465 GtkTreeView *treeview;
469 g_debug("clear_audio_list ()");
470 audio_list = ghb_settings_get_value(ud->settings, "audio_list");
471 if (audio_list == NULL)
473 audio_list = ghb_array_value_new(8);
474 ghb_settings_set_value(ud->settings, "audio_list", audio_list);
477 ghb_array_value_reset(audio_list, 8);
478 treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
479 store = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
480 gtk_list_store_clear (store);
484 add_to_audio_list(signal_user_data_t *ud, GValue *settings)
486 GtkTreeView *treeview;
489 GtkTreeSelection *selection;
490 const gchar *track, *codec, *br, *sr, *mix;
491 gchar *s_drc, *s_track, *s_codec, *s_br, *s_sr, *s_mix;
495 g_debug("add_to_audio_list ()");
496 treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
497 selection = gtk_tree_view_get_selection (treeview);
498 store = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
500 track = ghb_settings_combo_option(settings, "AudioTrack");
501 itrack = ghb_settings_combo_int(settings, "AudioTrack");
502 codec = ghb_settings_combo_option(settings, "AudioEncoder");
503 icodec = ghb_settings_combo_int(settings, "AudioEncoder");
504 br = ghb_settings_combo_option(settings, "AudioBitrate");
505 sr = ghb_settings_combo_option(settings, "AudioSamplerate");
506 mix = ghb_settings_combo_option(settings, "AudioMixdown");
508 s_track = ghb_settings_get_string(settings, "AudioTrack");
509 s_codec = ghb_settings_get_string(settings, "AudioEncoder");
510 s_br = ghb_settings_get_string(settings, "AudioBitrate");
511 s_sr = ghb_settings_get_string(settings, "AudioSamplerate");
512 s_mix = ghb_settings_get_string(settings, "AudioMixdown");
513 drc = ghb_settings_get_double(settings, "AudioTrackDRCSlider");
515 s_drc = g_strdup("Off");
517 s_drc = g_strdup_printf("%.1f", drc);
519 if (icodec == HB_ACODEC_MASK)
521 codec = ghb_select_audio_codec_str(ud, itrack);
524 gtk_list_store_append(store, &iter);
525 gtk_list_store_set(store, &iter,
526 // These are displayed in list
533 // These are used to set combo box values when a list item is selected
541 gtk_tree_selection_select_iter(selection, &iter);
551 audio_list_selection_changed_cb(GtkTreeSelection *selection, signal_user_data_t *ud)
557 g_debug("audio_list_selection_changed_cb ()");
558 if (gtk_tree_selection_get_selected(selection, &store, &iter))
560 const gchar *track, *codec, *bitrate, *sample_rate, *mix;
563 gtk_tree_model_get(store, &iter,
571 ghb_ui_update(ud, "AudioTrack", ghb_string_value(track));
572 ghb_ui_update(ud, "AudioEncoder", ghb_string_value(codec));
573 ghb_ui_update(ud, "AudioBitrate", ghb_string_value(bitrate));
574 ghb_ui_update(ud, "AudioSamplerate", ghb_string_value(sample_rate));
575 ghb_ui_update(ud, "AudioMixdown", ghb_string_value(mix));
576 ghb_ui_update(ud, "AudioTrackDRCSlider", ghb_double_value(drc));
577 widget = GHB_WIDGET (ud->builder, "audio_remove");
578 gtk_widget_set_sensitive(widget, TRUE);
582 widget = GHB_WIDGET (ud->builder, "audio_remove");
583 gtk_widget_set_sensitive(widget, FALSE);
588 audio_add_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
590 // Add the current audio settings to the list.
597 g_debug("audio_add_clicked_cb ()");
598 asettings = ghb_dict_value_new();
599 // Only allow up to 8 audio entries
600 widget = GHB_WIDGET(ud->builder, "AudioTrack");
601 ghb_settings_take_value(asettings, "AudioTrack", ghb_widget_value(widget));
602 widget = GHB_WIDGET(ud->builder, "AudioEncoder");
603 ghb_settings_take_value(asettings, "AudioEncoder", ghb_widget_value(widget));
604 widget = GHB_WIDGET(ud->builder, "AudioBitrate");
605 ghb_settings_take_value(asettings, "AudioBitrate", ghb_widget_value(widget));
606 widget = GHB_WIDGET(ud->builder, "AudioSamplerate");
607 ghb_settings_take_value(asettings, "AudioSamplerate", ghb_widget_value(widget));
608 widget = GHB_WIDGET(ud->builder, "AudioMixdown");
609 ghb_settings_take_value(asettings, "AudioMixdown", ghb_widget_value(widget));
610 widget = GHB_WIDGET(ud->builder, "AudioTrackDRCSlider");
611 ghb_settings_take_value(asettings, "AudioTrackDRCSlider", ghb_widget_value(widget));
612 track = ghb_settings_combo_option(asettings, "AudioTrack");
613 ghb_settings_set_string(asettings, "AudioTrackDescription", track);
615 audio_list = ghb_settings_get_value(ud->settings, "audio_list");
616 if (audio_list == NULL)
618 audio_list = ghb_array_value_new(8);
619 ghb_settings_set_value(ud->settings, "audio_list", audio_list);
621 ghb_array_append(audio_list, asettings);
622 add_to_audio_list(ud, asettings);
623 count = ghb_array_len(audio_list);
626 gtk_widget_set_sensitive(xwidget, FALSE);
628 ghb_update_destination_extension(ud);
632 audio_remove_clicked_cb(GtkWidget *widget, signal_user_data_t *ud)
634 GtkTreeView *treeview;
635 GtkTreePath *treepath;
636 GtkTreeSelection *selection;
638 GtkTreeIter iter, nextIter;
643 g_debug("audio_remove_clicked_cb ()");
644 treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
645 selection = gtk_tree_view_get_selection (treeview);
646 if (gtk_tree_selection_get_selected(selection, &store, &iter))
649 if (!gtk_tree_model_iter_next(store, &nextIter))
652 if (gtk_tree_model_get_iter_first(store, &nextIter))
654 gtk_tree_selection_select_iter (selection, &nextIter);
659 gtk_tree_selection_select_iter (selection, &nextIter);
661 // Get the row number
662 treepath = gtk_tree_model_get_path (store, &iter);
663 indices = gtk_tree_path_get_indices (treepath);
665 gtk_tree_path_free(treepath);
666 // Remove the selected item
667 gtk_list_store_remove (GTK_LIST_STORE(store), &iter);
668 // remove from audio settings list
670 widget = GHB_WIDGET (ud->builder, "audio_add");
671 gtk_widget_set_sensitive(widget, TRUE);
672 audio_list = ghb_settings_get_value(ud->settings, "audio_list");
673 if (row >= ghb_array_len(audio_list))
675 GValue *old = ghb_array_get_nth(audio_list, row);
677 ghb_array_remove(audio_list, row);
682 ghb_set_audio(signal_user_data_t *ud, GValue *settings)
688 GValue *track, *audio, *acodec, *bitrate, *rate, *mix, *drc;
691 g_debug("set_audio");
692 // Clear the audio list
693 ghb_clear_audio_list(ud);
694 button = GHB_WIDGET (ud->builder, "audio_add");
695 alist = ghb_settings_get_value(settings, "audio_list");
697 count = ghb_array_len(alist);
698 for (ii = 0; ii < count; ii++)
700 audio = ghb_array_get_nth(alist, ii);
701 track = ghb_settings_get_value(audio, "AudioTrack");
702 acodec = ghb_settings_get_value(audio, "AudioEncoder");
703 bitrate = ghb_settings_get_value(audio, "AudioBitrate");
704 rate = ghb_settings_get_value(audio, "AudioSamplerate");
705 mix = ghb_settings_get_value(audio, "AudioMixdown");
706 drc = ghb_settings_get_value(audio, "AudioTrackDRCSlider");
707 acodec_code = ghb_lookup_combo_int("AudioEncoder", acodec);
709 if (acodec_code != 0)
712 g_signal_emit_by_name(button, "clicked", ud);
713 ghb_ui_update(ud, "AudioTrack", track);
714 ghb_ui_update(ud, "AudioEncoder", acodec);
715 if (!ghb_audio_is_passthru (acodec_code))
717 // This gets set autimatically if the codec is passthru
718 ghb_ui_update(ud, "AudioBitrate", bitrate);
719 ghb_ui_update(ud, "AudioSamplerate", rate);
720 ghb_ui_update(ud, "AudioMixdown", mix);
722 ghb_ui_update(ud, "AudioTrackDRCSlider", drc);