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 && mix != HB_AMIXDOWN_6CH)
75 widget = GHB_WIDGET(ud->builder, "AudioBitrate");
76 gval = ghb_widget_value(widget);
77 br = ghb_lookup_combo_int("AudioBitrate", gval);
80 ghb_ui_update(ud, "AudioBitrate", ghb_int64_value(160));
81 ghb_set_default_bitrate_opts (ud->builder, 160);
85 ghb_set_default_bitrate_opts (ud->builder, -1);
90 free_audio_index_list(gpointer data)
96 ghb_get_user_audio_lang(signal_user_data_t *ud, gint titleindex, gint track)
98 GValue *audio_list, *asettings;
101 audio_list = ghb_settings_get_value(ud->settings, "audio_list");
102 if (ghb_array_len(audio_list) <= track)
104 asettings = ghb_array_get_nth(audio_list, track);
105 track = ghb_settings_get_int(asettings, "AudioTrack");
106 lang = ghb_get_source_audio_lang(titleindex, track);
111 ghb_set_pref_audio(gint titleindex, signal_user_data_t *ud)
113 gint acodec_code, mix_code, track;
114 gchar *source_lang = NULL;
116 ghb_audio_info_t ainfo;
117 GHashTable *track_indices;
119 const GValue *pref_audio;
120 const GValue *audio, *acodec, *bitrate, *rate, *mix, *drc;
121 gint count, ii, list_count;
123 g_debug("set_pref_audio");
124 track_indices = g_hash_table_new_full(g_int_hash, g_int_equal,
125 NULL, free_audio_index_list);
126 // Clear the audio list
127 ghb_clear_audio_list(ud);
128 // Find "best" audio based on audio preferences
129 button = GHB_WIDGET (ud->builder, "audio_add");
130 if (!ghb_settings_get_boolean(ud->settings, "AudioDUB"))
132 source_lang = ghb_get_source_audio_lang(titleindex, 0);
134 if (source_lang == NULL)
135 source_lang = ghb_settings_get_string(ud->settings, "PreferredLanguage");
137 pref_audio = ghb_settings_get_value(ud->settings, "AudioList");
140 count = ghb_array_len(pref_audio);
141 for (ii = 0; ii < count; ii++)
143 audio = ghb_array_get_nth(pref_audio, ii);
144 acodec = ghb_settings_get_value(audio, "AudioEncoder");
145 bitrate = ghb_settings_get_value(audio, "AudioBitrate");
146 rate = ghb_settings_get_value(audio, "AudioSamplerate");
147 mix = ghb_settings_get_value(audio, "AudioMixdown");
148 drc = ghb_settings_get_value(audio, "AudioTrackDRCSlider");
149 acodec_code = ghb_lookup_combo_int("AudioEncoder", acodec);
150 // If there are multiple audios using the same codec, then
151 // select sequential tracks for each. The hash keeps track
152 // of the tracks used for each codec.
153 track = ghb_find_audio_track(titleindex, source_lang,
154 acodec_code, track_indices);
156 // 1. pref codec is ac3
157 // 2. source codec is not ac3
158 // 3. next pref is enabled
159 if (ghb_get_audio_info (&ainfo, titleindex, track) &&
160 ghb_audio_is_passthru (acodec_code))
162 // HB_ACODEC_* are bit fields. Treat acodec_code as mask
163 if (!(ainfo.codec & acodec_code))
165 acodec_code = ghb_get_default_acodec();
166 // If there's more audio to process, or we've already
167 // placed one in the list, then we can skip this one
168 if ((ii + 1 < count) || (list_count != 0))
176 acodec_code &= ainfo.codec;
179 if (titleindex >= 0 && track < 0)
181 if (acodec_code != 0)
184 g_signal_emit_by_name(button, "clicked", ud);
186 ghb_ui_update(ud, "AudioTrack", ghb_int64_value(track));
187 ghb_ui_update(ud, "AudioEncoder", acodec);
188 if (!ghb_audio_is_passthru (acodec_code))
190 // This gets set autimatically if the codec is passthru
191 ghb_ui_update(ud, "AudioBitrate", bitrate);
192 ghb_ui_update(ud, "AudioSamplerate", rate);
193 mix_code = ghb_lookup_combo_int("AudioMixdown", mix);
194 mix_code = ghb_get_best_mix(
195 titleindex, track, acodec_code, mix_code);
196 ghb_ui_update(ud, "AudioMixdown", ghb_int64_value(mix_code));
198 ghb_adjust_audio_rate_combos(ud);
199 ghb_ui_update(ud, "AudioTrackDRCSlider", drc);
203 g_hash_table_destroy(track_indices);
207 get_selected_asettings(signal_user_data_t *ud)
209 GtkTreeView *treeview;
210 GtkTreePath *treepath;
211 GtkTreeSelection *selection;
216 GValue *asettings = NULL;
217 const GValue *audio_list;
219 g_debug("get_selected_asettings ()");
220 treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
221 selection = gtk_tree_view_get_selection (treeview);
222 if (gtk_tree_selection_get_selected(selection, &store, &iter))
224 // Get the row number
225 treepath = gtk_tree_model_get_path (store, &iter);
226 indices = gtk_tree_path_get_indices (treepath);
228 gtk_tree_path_free(treepath);
229 // find audio settings
230 if (row < 0) return NULL;
231 audio_list = ghb_settings_get_value(ud->settings, "audio_list");
232 if (row >= ghb_array_len(audio_list))
234 asettings = ghb_array_get_nth(audio_list, row);
240 ghb_audio_list_refresh_selected(signal_user_data_t *ud)
242 GtkTreeView *treeview;
243 GtkTreePath *treepath;
244 GtkTreeSelection *selection;
249 GValue *asettings = NULL;
250 const GValue *audio_list;
252 g_debug("ghb_audio_list_refresh_selected ()");
253 treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
254 selection = gtk_tree_view_get_selection (treeview);
255 if (gtk_tree_selection_get_selected(selection, &store, &iter))
257 const gchar *track, *codec, *br, *sr, *mix;
258 gchar *s_drc, *s_track, *s_codec, *s_br, *s_sr, *s_mix;
261 // Get the row number
262 treepath = gtk_tree_model_get_path (store, &iter);
263 indices = gtk_tree_path_get_indices (treepath);
265 gtk_tree_path_free(treepath);
266 // find audio settings
268 audio_list = ghb_settings_get_value(ud->settings, "audio_list");
269 if (row >= ghb_array_len(audio_list))
271 asettings = ghb_array_get_nth(audio_list, row);
273 track = ghb_settings_combo_option(asettings, "AudioTrack");
274 itrack = ghb_settings_combo_int(asettings, "AudioTrack");
275 codec = ghb_settings_combo_option(asettings, "AudioEncoder");
276 icodec = ghb_settings_combo_int(asettings, "AudioEncoder");
277 br = ghb_settings_combo_option(asettings, "AudioBitrate");
278 sr = ghb_settings_combo_option(asettings, "AudioSamplerate");
279 mix = ghb_settings_combo_option(asettings, "AudioMixdown");
281 s_track = ghb_settings_get_string(asettings, "AudioTrack");
282 s_codec = ghb_settings_get_string(asettings, "AudioEncoder");
283 s_br = ghb_settings_get_string(asettings, "AudioBitrate");
284 s_sr = ghb_settings_get_string(asettings, "AudioSamplerate");
285 s_mix = ghb_settings_get_string(asettings, "AudioMixdown");
286 drc = ghb_settings_get_double(asettings, "AudioTrackDRCSlider");
288 s_drc = g_strdup("Off");
290 s_drc = g_strdup_printf("%.1f", drc);
292 if (icodec == HB_ACODEC_MASK)
294 codec = ghb_select_audio_codec_str(ud, itrack);
297 gtk_list_store_set(GTK_LIST_STORE(store), &iter,
298 // These are displayed in list
305 // These are used to set combo values when a list item is selected
323 audio_codec_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
325 static gint prev_acodec = 0;
326 gint acodec_code, mix_code;
327 GValue *asettings, *gval;
329 g_debug("audio_codec_changed_cb ()");
330 gval = ghb_widget_value(widget);
331 acodec_code = ghb_lookup_combo_int("AudioEncoder", gval);
332 ghb_value_free(gval);
333 if (ghb_audio_is_passthru (prev_acodec) &&
334 !ghb_audio_is_passthru (acodec_code))
336 // Transition from passthru to not, put some audio settings back to
341 titleindex = ghb_settings_combo_int(ud->settings, "title");
342 track = ghb_settings_combo_int(ud->settings, "AudioTrack");
344 ghb_ui_update(ud, "AudioBitrate", ghb_string_value("160"));
345 ghb_ui_update(ud, "AudioSamplerate", ghb_string_value("source"));
346 mix_code = ghb_lookup_combo_int("AudioMixdown", ghb_string_value("dpl2"));
347 mix_code = ghb_get_best_mix( titleindex, track, acodec_code, mix_code);
348 ghb_ui_update(ud, "AudioMixdown", ghb_int64_value(mix_code));
350 ghb_adjust_audio_rate_combos(ud);
351 ghb_grey_combo_options (ud->builder);
352 ghb_check_dependency(ud, widget);
353 prev_acodec = acodec_code;
354 asettings = get_selected_asettings(ud);
355 if (asettings != NULL)
357 ghb_widget_to_setting(asettings, widget);
358 ghb_audio_list_refresh_selected(ud);
360 ghb_update_destination_extension(ud);
365 audio_track_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
369 g_debug("audio_track_changed_cb ()");
370 ghb_adjust_audio_rate_combos(ud);
371 ghb_check_dependency(ud, widget);
372 ghb_grey_combo_options(ud->builder);
373 asettings = get_selected_asettings(ud);
374 if (asettings != NULL)
378 ghb_widget_to_setting(asettings, widget);
379 ghb_audio_list_refresh_selected(ud);
380 track = ghb_settings_combo_option(asettings, "AudioTrack");
381 ghb_settings_set_string(asettings, "AudioTrackDescription", track);
387 audio_mix_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
391 g_debug("audio_mix_changed_cb ()");
392 ghb_adjust_audio_rate_combos(ud);
393 ghb_check_dependency(ud, widget);
394 asettings = get_selected_asettings(ud);
395 if (asettings != NULL)
397 ghb_widget_to_setting(asettings, widget);
398 ghb_audio_list_refresh_selected(ud);
404 audio_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
408 g_debug("audio_widget_changed_cb ()");
409 ghb_check_dependency(ud, widget);
410 asettings = get_selected_asettings(ud);
411 if (asettings != NULL)
413 ghb_widget_to_setting(asettings, widget);
414 ghb_audio_list_refresh_selected(ud);
420 drc_widget_changed_cb(GtkWidget *widget, gdouble val, signal_user_data_t *ud)
426 g_debug("drc_widget_changed_cb ()");
428 label = GTK_LABEL(GHB_WIDGET(ud->builder, "drc_label"));
430 drc = g_strdup_printf("Off");
432 drc = g_strdup_printf("%.1f", val);
433 gtk_label_set_text(label, drc);
435 ghb_check_dependency(ud, widget);
436 asettings = get_selected_asettings(ud);
437 if (asettings != NULL)
439 ghb_widget_to_setting(asettings, widget);
440 ghb_audio_list_refresh_selected(ud);
445 // subtitles differ from other settings in that
446 // the selection is updated automaitcally when the title
447 // changes. I don't want the preset selection changed as
448 // would happen for regular settings.
450 subtitle_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
452 const gchar *name = gtk_widget_get_name(widget);
453 g_debug("subtitle_changed_cb () %s", name);
454 ghb_widget_to_setting(ud->settings, widget);
455 ghb_check_dependency(ud, widget);
460 ghb_clear_audio_list(signal_user_data_t *ud)
462 GtkTreeView *treeview;
466 g_debug("clear_audio_list ()");
467 audio_list = ghb_settings_get_value(ud->settings, "audio_list");
468 if (audio_list == NULL)
470 audio_list = ghb_array_value_new(8);
471 ghb_settings_set_value(ud->settings, "audio_list", audio_list);
474 ghb_array_value_reset(audio_list, 8);
475 treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
476 store = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
477 gtk_list_store_clear (store);
481 add_to_audio_list(signal_user_data_t *ud, GValue *settings)
483 GtkTreeView *treeview;
486 GtkTreeSelection *selection;
487 const gchar *track, *codec, *br, *sr, *mix;
488 gchar *s_drc, *s_track, *s_codec, *s_br, *s_sr, *s_mix;
492 g_debug("add_to_audio_list ()");
493 treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
494 selection = gtk_tree_view_get_selection (treeview);
495 store = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
497 track = ghb_settings_combo_option(settings, "AudioTrack");
498 itrack = ghb_settings_combo_int(settings, "AudioTrack");
499 codec = ghb_settings_combo_option(settings, "AudioEncoder");
500 icodec = ghb_settings_combo_int(settings, "AudioEncoder");
501 br = ghb_settings_combo_option(settings, "AudioBitrate");
502 sr = ghb_settings_combo_option(settings, "AudioSamplerate");
503 mix = ghb_settings_combo_option(settings, "AudioMixdown");
505 s_track = ghb_settings_get_string(settings, "AudioTrack");
506 s_codec = ghb_settings_get_string(settings, "AudioEncoder");
507 s_br = ghb_settings_get_string(settings, "AudioBitrate");
508 s_sr = ghb_settings_get_string(settings, "AudioSamplerate");
509 s_mix = ghb_settings_get_string(settings, "AudioMixdown");
510 drc = ghb_settings_get_double(settings, "AudioTrackDRCSlider");
512 s_drc = g_strdup("Off");
514 s_drc = g_strdup_printf("%.1f", drc);
516 if (icodec == HB_ACODEC_MASK)
518 codec = ghb_select_audio_codec_str(ud, itrack);
521 gtk_list_store_append(store, &iter);
522 gtk_list_store_set(store, &iter,
523 // These are displayed in list
530 // These are used to set combo box values when a list item is selected
538 gtk_tree_selection_select_iter(selection, &iter);
548 audio_list_selection_changed_cb(GtkTreeSelection *selection, signal_user_data_t *ud)
554 g_debug("audio_list_selection_changed_cb ()");
555 if (gtk_tree_selection_get_selected(selection, &store, &iter))
557 const gchar *track, *codec, *bitrate, *sample_rate, *mix;
560 gtk_tree_model_get(store, &iter,
568 ghb_ui_update(ud, "AudioTrack", ghb_string_value(track));
569 ghb_ui_update(ud, "AudioEncoder", ghb_string_value(codec));
570 ghb_ui_update(ud, "AudioBitrate", ghb_string_value(bitrate));
571 ghb_ui_update(ud, "AudioSamplerate", ghb_string_value(sample_rate));
572 ghb_ui_update(ud, "AudioMixdown", ghb_string_value(mix));
573 ghb_ui_update(ud, "AudioTrackDRCSlider", ghb_double_value(drc));
574 widget = GHB_WIDGET (ud->builder, "audio_remove");
575 gtk_widget_set_sensitive(widget, TRUE);
579 widget = GHB_WIDGET (ud->builder, "audio_remove");
580 gtk_widget_set_sensitive(widget, FALSE);
585 audio_add_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
587 // Add the current audio settings to the list.
594 g_debug("audio_add_clicked_cb ()");
595 asettings = ghb_dict_value_new();
596 // Only allow up to 8 audio entries
597 widget = GHB_WIDGET(ud->builder, "AudioTrack");
598 ghb_settings_take_value(asettings, "AudioTrack", ghb_widget_value(widget));
599 widget = GHB_WIDGET(ud->builder, "AudioEncoder");
600 ghb_settings_take_value(asettings, "AudioEncoder", ghb_widget_value(widget));
601 widget = GHB_WIDGET(ud->builder, "AudioBitrate");
602 ghb_settings_take_value(asettings, "AudioBitrate", ghb_widget_value(widget));
603 widget = GHB_WIDGET(ud->builder, "AudioSamplerate");
604 ghb_settings_take_value(asettings, "AudioSamplerate", ghb_widget_value(widget));
605 widget = GHB_WIDGET(ud->builder, "AudioMixdown");
606 ghb_settings_take_value(asettings, "AudioMixdown", ghb_widget_value(widget));
607 widget = GHB_WIDGET(ud->builder, "AudioTrackDRCSlider");
608 ghb_settings_take_value(asettings, "AudioTrackDRCSlider", ghb_widget_value(widget));
609 track = ghb_settings_combo_option(asettings, "AudioTrack");
610 ghb_settings_set_string(asettings, "AudioTrackDescription", track);
612 audio_list = ghb_settings_get_value(ud->settings, "audio_list");
613 if (audio_list == NULL)
615 audio_list = ghb_array_value_new(8);
616 ghb_settings_set_value(ud->settings, "audio_list", audio_list);
618 ghb_array_append(audio_list, asettings);
619 add_to_audio_list(ud, asettings);
620 count = ghb_array_len(audio_list);
623 gtk_widget_set_sensitive(xwidget, FALSE);
625 ghb_update_destination_extension(ud);
629 audio_remove_clicked_cb(GtkWidget *widget, signal_user_data_t *ud)
631 GtkTreeView *treeview;
632 GtkTreePath *treepath;
633 GtkTreeSelection *selection;
635 GtkTreeIter iter, nextIter;
640 g_debug("audio_remove_clicked_cb ()");
641 treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
642 selection = gtk_tree_view_get_selection (treeview);
643 if (gtk_tree_selection_get_selected(selection, &store, &iter))
646 if (!gtk_tree_model_iter_next(store, &nextIter))
649 if (gtk_tree_model_get_iter_first(store, &nextIter))
651 gtk_tree_selection_select_iter (selection, &nextIter);
656 gtk_tree_selection_select_iter (selection, &nextIter);
658 // Get the row number
659 treepath = gtk_tree_model_get_path (store, &iter);
660 indices = gtk_tree_path_get_indices (treepath);
662 gtk_tree_path_free(treepath);
663 // Remove the selected item
664 gtk_list_store_remove (GTK_LIST_STORE(store), &iter);
665 // remove from audio settings list
667 widget = GHB_WIDGET (ud->builder, "audio_add");
668 gtk_widget_set_sensitive(widget, TRUE);
669 audio_list = ghb_settings_get_value(ud->settings, "audio_list");
670 if (row >= ghb_array_len(audio_list))
672 GValue *old = ghb_array_get_nth(audio_list, row);
674 ghb_array_remove(audio_list, row);
679 ghb_set_audio(signal_user_data_t *ud, GValue *settings)
685 GValue *track, *audio, *acodec, *bitrate, *rate, *mix, *drc;
688 g_debug("set_audio");
689 // Clear the audio list
690 ghb_clear_audio_list(ud);
691 button = GHB_WIDGET (ud->builder, "audio_add");
692 alist = ghb_settings_get_value(settings, "audio_list");
694 count = ghb_array_len(alist);
695 for (ii = 0; ii < count; ii++)
697 audio = ghb_array_get_nth(alist, ii);
698 track = ghb_settings_get_value(audio, "AudioTrack");
699 acodec = ghb_settings_get_value(audio, "AudioEncoder");
700 bitrate = ghb_settings_get_value(audio, "AudioBitrate");
701 rate = ghb_settings_get_value(audio, "AudioSamplerate");
702 mix = ghb_settings_get_value(audio, "AudioMixdown");
703 drc = ghb_settings_get_value(audio, "AudioTrackDRCSlider");
704 acodec_code = ghb_lookup_combo_int("AudioEncoder", acodec);
706 if (acodec_code != 0)
709 g_signal_emit_by_name(button, "clicked", ud);
710 ghb_ui_update(ud, "AudioTrack", track);
711 ghb_ui_update(ud, "AudioEncoder", acodec);
712 if (!ghb_audio_is_passthru (acodec_code))
714 // This gets set autimatically if the codec is passthru
715 ghb_ui_update(ud, "AudioBitrate", bitrate);
716 ghb_ui_update(ud, "AudioSamplerate", rate);
717 ghb_ui_update(ud, "AudioMixdown", mix);
719 ghb_ui_update(ud, "AudioTrackDRCSlider", drc);