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
55 ghb_set_passthru_bitrate_opts (ud->builder, br);
56 ghb_ui_update(ud, "AudioBitrate", ghb_int64_value(br));
57 ghb_ui_update(ud, "AudioSamplerate", ghb_int64_value(0));
58 ghb_ui_update(ud, "AudioMixdown", ghb_int64_value(0));
62 ghb_ui_update(ud, "AudioBitrate", ghb_int64_value(384));
63 ghb_ui_update(ud, "AudioSamplerate", ghb_int64_value(0));
64 ghb_ui_update(ud, "AudioMixdown", ghb_int64_value(0));
66 ghb_ui_update(ud, "AudioTrackDRCSlider", ghb_double_value(0));
68 else if (acodec == HB_ACODEC_FAAC && mix != HB_AMIXDOWN_6CH)
72 widget = GHB_WIDGET(ud->builder, "AudioBitrate");
73 gval = ghb_widget_value(widget);
74 br = ghb_lookup_combo_int("AudioBitrate", gval);
77 ghb_ui_update(ud, "AudioBitrate", ghb_int64_value(160));
78 ghb_set_default_bitrate_opts (ud->builder, 160);
82 ghb_set_default_bitrate_opts (ud->builder, -1);
87 free_audio_index_list(gpointer data)
93 ghb_get_user_audio_lang(signal_user_data_t *ud, gint titleindex, gint track)
95 GValue *audio_list, *asettings;
98 audio_list = ghb_settings_get_value(ud->settings, "audio_list");
99 if (ghb_array_len(audio_list) <= track)
101 asettings = ghb_array_get_nth(audio_list, track);
102 track = ghb_settings_get_int(asettings, "AudioTrack");
103 lang = ghb_get_source_audio_lang(titleindex, track);
108 ghb_set_pref_audio(gint titleindex, signal_user_data_t *ud)
110 gint acodec_code, mix_code, track;
111 gchar *source_lang = NULL;
113 ghb_audio_info_t ainfo;
114 GHashTable *track_indices;
116 const GValue *pref_audio;
117 const GValue *audio, *acodec, *bitrate, *rate, *mix, *drc;
118 gint count, ii, list_count;
120 g_debug("set_pref_audio");
121 track_indices = g_hash_table_new_full(g_int_hash, g_int_equal,
122 NULL, free_audio_index_list);
123 // Clear the audio list
124 ghb_clear_audio_list(ud);
125 // Find "best" audio based on audio preferences
126 button = GHB_WIDGET (ud->builder, "audio_add");
127 if (!ghb_settings_get_boolean(ud->settings, "AudioDUB"))
129 source_lang = ghb_get_source_audio_lang(titleindex, 0);
131 if (source_lang == NULL)
132 source_lang = ghb_settings_get_string(ud->settings, "PreferredLanguage");
134 pref_audio = ghb_settings_get_value(ud->settings, "AudioList");
137 count = ghb_array_len(pref_audio);
138 for (ii = 0; ii < count; ii++)
140 audio = ghb_array_get_nth(pref_audio, ii);
141 acodec = ghb_settings_get_value(audio, "AudioEncoder");
142 bitrate = ghb_settings_get_value(audio, "AudioBitrate");
143 rate = ghb_settings_get_value(audio, "AudioSamplerate");
144 mix = ghb_settings_get_value(audio, "AudioMixdown");
145 drc = ghb_settings_get_value(audio, "AudioTrackDRCSlider");
146 acodec_code = ghb_lookup_combo_int("AudioEncoder", acodec);
147 // If there are multiple audios using the same codec, then
148 // select sequential tracks for each. The hash keeps track
149 // of the tracks used for each codec.
150 track = ghb_find_audio_track(titleindex, source_lang,
151 acodec_code, track_indices);
153 // 1. pref codec is ac3
154 // 2. source codec is not ac3
155 // 3. next pref is enabled
156 if (ghb_get_audio_info (&ainfo, titleindex, track) &&
157 ghb_audio_is_passthru (acodec_code))
159 // HB_ACODEC_* are bit fields. Treat acodec_code as mask
160 if (!(ainfo.codec & acodec_code))
162 acodec_code = ghb_get_default_acodec();
163 // If there's more audio to process, or we've already
164 // placed one in the list, then we can skip this one
165 if ((ii + 1 < count) || (list_count != 0))
173 acodec_code &= ainfo.codec;
176 if (titleindex >= 0 && track < 0)
178 if (acodec_code != 0)
181 g_signal_emit_by_name(button, "clicked", ud);
183 ghb_ui_update(ud, "AudioTrack", ghb_int64_value(track));
184 ghb_ui_update(ud, "AudioEncoder", acodec);
185 if (!ghb_audio_is_passthru (acodec_code))
187 // This gets set autimatically if the codec is passthru
188 ghb_ui_update(ud, "AudioBitrate", bitrate);
189 ghb_ui_update(ud, "AudioSamplerate", rate);
190 mix_code = ghb_lookup_combo_int("AudioMixdown", mix);
191 mix_code = ghb_get_best_mix(
192 titleindex, track, acodec_code, mix_code);
193 ghb_ui_update(ud, "AudioMixdown", ghb_int64_value(mix_code));
195 ghb_ui_update(ud, "AudioTrackDRCSlider", drc);
199 g_hash_table_destroy(track_indices);
203 get_selected_asettings(signal_user_data_t *ud)
205 GtkTreeView *treeview;
206 GtkTreePath *treepath;
207 GtkTreeSelection *selection;
212 GValue *asettings = NULL;
213 const GValue *audio_list;
215 g_debug("get_selected_asettings ()");
216 treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
217 selection = gtk_tree_view_get_selection (treeview);
218 if (gtk_tree_selection_get_selected(selection, &store, &iter))
220 // Get the row number
221 treepath = gtk_tree_model_get_path (store, &iter);
222 indices = gtk_tree_path_get_indices (treepath);
224 gtk_tree_path_free(treepath);
225 // find audio settings
226 if (row < 0) return NULL;
227 audio_list = ghb_settings_get_value(ud->settings, "audio_list");
228 if (row >= ghb_array_len(audio_list))
230 asettings = ghb_array_get_nth(audio_list, row);
236 audio_list_refresh_selected(signal_user_data_t *ud)
238 GtkTreeView *treeview;
239 GtkTreePath *treepath;
240 GtkTreeSelection *selection;
245 GValue *asettings = NULL;
246 const GValue *audio_list;
248 g_debug("audio_list_refresh_selected ()");
249 treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
250 selection = gtk_tree_view_get_selection (treeview);
251 if (gtk_tree_selection_get_selected(selection, &store, &iter))
253 const gchar *track, *codec, *br, *sr, *mix;
254 gchar *s_drc, *s_track, *s_codec, *s_br, *s_sr, *s_mix;
256 // Get the row number
257 treepath = gtk_tree_model_get_path (store, &iter);
258 indices = gtk_tree_path_get_indices (treepath);
260 gtk_tree_path_free(treepath);
261 // find audio settings
263 audio_list = ghb_settings_get_value(ud->settings, "audio_list");
264 if (row >= ghb_array_len(audio_list))
266 asettings = ghb_array_get_nth(audio_list, row);
268 track = ghb_settings_combo_option(asettings, "AudioTrack");
269 codec = ghb_settings_combo_option(asettings, "AudioEncoder");
270 br = ghb_settings_combo_option(asettings, "AudioBitrate");
271 sr = ghb_settings_combo_option(asettings, "AudioSamplerate");
272 mix = ghb_settings_combo_option(asettings, "AudioMixdown");
274 s_track = ghb_settings_get_string(asettings, "AudioTrack");
275 s_codec = ghb_settings_get_string(asettings, "AudioEncoder");
276 s_br = ghb_settings_get_string(asettings, "AudioBitrate");
277 s_sr = ghb_settings_get_string(asettings, "AudioSamplerate");
278 s_mix = ghb_settings_get_string(asettings, "AudioMixdown");
279 drc = ghb_settings_get_double(asettings, "AudioTrackDRCSlider");
281 s_drc = g_strdup("Off");
283 s_drc = g_strdup_printf("%.1f", drc);
285 gtk_list_store_set(GTK_LIST_STORE(store), &iter,
286 // These are displayed in list
293 // These are used to set combo values when a list item is selected
311 audio_codec_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
313 static gint prev_acodec = 0;
314 gint acodec_code, mix_code;
315 GValue *asettings, *gval;
317 g_debug("audio_codec_changed_cb ()");
318 gval = ghb_widget_value(widget);
319 acodec_code = ghb_lookup_combo_int("AudioEncoder", gval);
320 ghb_value_free(gval);
321 if (ghb_audio_is_passthru (prev_acodec) &&
322 !ghb_audio_is_passthru (acodec_code))
324 // Transition from passthru to not, put some audio settings back to
329 titleindex = ghb_settings_combo_int(ud->settings, "title");
330 track = ghb_settings_combo_int(ud->settings, "AudioTrack");
332 ghb_ui_update(ud, "AudioBitrate", ghb_string_value("160"));
333 ghb_ui_update(ud, "AudioSamplerate", ghb_string_value("source"));
334 mix_code = ghb_lookup_combo_int("AudioMixdown", ghb_string_value("dpl2"));
335 mix_code = ghb_get_best_mix( titleindex, track, acodec_code, mix_code);
336 ghb_ui_update(ud, "AudioMixdown", ghb_int64_value(mix_code));
338 ghb_adjust_audio_rate_combos(ud);
339 ghb_grey_combo_options (ud->builder);
340 ghb_check_dependency(ud, widget);
341 prev_acodec = acodec_code;
342 asettings = get_selected_asettings(ud);
343 if (asettings != NULL)
345 ghb_widget_to_setting(asettings, widget);
346 audio_list_refresh_selected(ud);
349 const GValue *audio_list;
350 audio_list = ghb_settings_get_value(ud->settings, "audio_list");
351 if (ghb_ac3_in_audio_list (audio_list))
355 container = ghb_settings_get_string(ud->settings, "FileFormat");
356 if (strcmp(container, "mp4") == 0)
358 ghb_ui_update(ud, "FileFormat", ghb_string_value("m4v"));
366 audio_track_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
370 g_debug("audio_track_changed_cb ()");
371 ghb_adjust_audio_rate_combos(ud);
372 ghb_check_dependency(ud, widget);
373 ghb_grey_combo_options(ud->builder);
374 asettings = get_selected_asettings(ud);
375 if (asettings != NULL)
379 ghb_widget_to_setting(asettings, widget);
380 audio_list_refresh_selected(ud);
381 track = ghb_settings_combo_option(asettings, "AudioTrack");
382 ghb_settings_set_string(asettings, "AudioTrackDescription", track);
388 audio_mix_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
392 g_debug("audio_mix_changed_cb ()");
393 ghb_adjust_audio_rate_combos(ud);
394 ghb_check_dependency(ud, widget);
395 asettings = get_selected_asettings(ud);
396 if (asettings != NULL)
398 ghb_widget_to_setting(asettings, widget);
399 audio_list_refresh_selected(ud);
405 audio_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
409 g_debug("audio_widget_changed_cb ()");
410 ghb_check_dependency(ud, widget);
411 asettings = get_selected_asettings(ud);
412 if (asettings != NULL)
414 ghb_widget_to_setting(asettings, widget);
415 audio_list_refresh_selected(ud);
421 drc_widget_changed_cb(GtkWidget *widget, gdouble val, signal_user_data_t *ud)
427 g_debug("drc_widget_changed_cb ()");
429 label = GTK_LABEL(GHB_WIDGET(ud->builder, "drc_label"));
431 drc = g_strdup_printf("Off");
433 drc = g_strdup_printf("%.1f", val);
434 gtk_label_set_text(label, drc);
436 ghb_check_dependency(ud, widget);
437 asettings = get_selected_asettings(ud);
438 if (asettings != NULL)
440 ghb_widget_to_setting(asettings, widget);
441 audio_list_refresh_selected(ud);
446 // subtitles differ from other settings in that
447 // the selection is updated automaitcally when the title
448 // changes. I don't want the preset selection changed as
449 // would happen for regular settings.
451 subtitle_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
453 const gchar *name = gtk_widget_get_name(widget);
454 g_debug("subtitle_changed_cb () %s", name);
455 ghb_widget_to_setting(ud->settings, widget);
456 ghb_check_dependency(ud, widget);
461 ghb_clear_audio_list(signal_user_data_t *ud)
463 GtkTreeView *treeview;
467 g_debug("clear_audio_list ()");
468 audio_list = ghb_settings_get_value(ud->settings, "audio_list");
469 if (audio_list == NULL)
471 audio_list = ghb_array_value_new(8);
472 ghb_settings_set_value(ud->settings, "audio_list", audio_list);
475 ghb_array_value_reset(audio_list, 8);
476 treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
477 store = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
478 gtk_list_store_clear (store);
482 add_to_audio_list(signal_user_data_t *ud, GValue *settings)
484 GtkTreeView *treeview;
487 GtkTreeSelection *selection;
488 const gchar *track, *codec, *br, *sr, *mix;
489 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 codec = ghb_settings_combo_option(settings, "AudioEncoder");
499 br = ghb_settings_combo_option(settings, "AudioBitrate");
500 sr = ghb_settings_combo_option(settings, "AudioSamplerate");
501 mix = ghb_settings_combo_option(settings, "AudioMixdown");
503 s_track = ghb_settings_get_string(settings, "AudioTrack");
504 s_codec = ghb_settings_get_string(settings, "AudioEncoder");
505 s_br = ghb_settings_get_string(settings, "AudioBitrate");
506 s_sr = ghb_settings_get_string(settings, "AudioSamplerate");
507 s_mix = ghb_settings_get_string(settings, "AudioMixdown");
508 drc = ghb_settings_get_double(settings, "AudioTrackDRCSlider");
510 s_drc = g_strdup("Off");
512 s_drc = g_strdup_printf("%.1f", drc);
515 gtk_list_store_append(store, &iter);
516 gtk_list_store_set(store, &iter,
517 // These are displayed in list
524 // These are used to set combo box values when a list item is selected
532 gtk_tree_selection_select_iter(selection, &iter);
542 audio_list_selection_changed_cb(GtkTreeSelection *selection, signal_user_data_t *ud)
548 g_debug("audio_list_selection_changed_cb ()");
549 if (gtk_tree_selection_get_selected(selection, &store, &iter))
551 const gchar *track, *codec, *bitrate, *sample_rate, *mix;
554 gtk_tree_model_get(store, &iter,
562 ghb_ui_update(ud, "AudioTrack", ghb_string_value(track));
563 ghb_ui_update(ud, "AudioEncoder", ghb_string_value(codec));
564 ghb_ui_update(ud, "AudioBitrate", ghb_string_value(bitrate));
565 ghb_ui_update(ud, "AudioSamplerate", ghb_string_value(sample_rate));
566 ghb_ui_update(ud, "AudioMixdown", ghb_string_value(mix));
567 ghb_ui_update(ud, "AudioTrackDRCSlider", ghb_double_value(drc));
568 widget = GHB_WIDGET (ud->builder, "audio_remove");
569 gtk_widget_set_sensitive(widget, TRUE);
573 widget = GHB_WIDGET (ud->builder, "audio_remove");
574 gtk_widget_set_sensitive(widget, FALSE);
579 audio_add_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
581 // Add the current audio settings to the list.
588 g_debug("audio_add_clicked_cb ()");
589 asettings = ghb_dict_value_new();
590 // Only allow up to 8 audio entries
591 widget = GHB_WIDGET(ud->builder, "AudioTrack");
592 ghb_settings_take_value(asettings, "AudioTrack", ghb_widget_value(widget));
593 widget = GHB_WIDGET(ud->builder, "AudioEncoder");
594 ghb_settings_take_value(asettings, "AudioEncoder", ghb_widget_value(widget));
595 widget = GHB_WIDGET(ud->builder, "AudioBitrate");
596 ghb_settings_take_value(asettings, "AudioBitrate", ghb_widget_value(widget));
597 widget = GHB_WIDGET(ud->builder, "AudioSamplerate");
598 ghb_settings_take_value(asettings, "AudioSamplerate", ghb_widget_value(widget));
599 widget = GHB_WIDGET(ud->builder, "AudioMixdown");
600 ghb_settings_take_value(asettings, "AudioMixdown", ghb_widget_value(widget));
601 widget = GHB_WIDGET(ud->builder, "AudioTrackDRCSlider");
602 ghb_settings_take_value(asettings, "AudioTrackDRCSlider", ghb_widget_value(widget));
603 track = ghb_settings_combo_option(asettings, "AudioTrack");
604 ghb_settings_set_string(asettings, "AudioTrackDescription", track);
606 audio_list = ghb_settings_get_value(ud->settings, "audio_list");
607 if (audio_list == NULL)
609 audio_list = ghb_array_value_new(8);
610 ghb_settings_set_value(ud->settings, "audio_list", audio_list);
612 ghb_array_append(audio_list, asettings);
613 add_to_audio_list(ud, asettings);
614 count = ghb_array_len(audio_list);
617 gtk_widget_set_sensitive(xwidget, FALSE);
622 audio_remove_clicked_cb(GtkWidget *widget, signal_user_data_t *ud)
624 GtkTreeView *treeview;
625 GtkTreePath *treepath;
626 GtkTreeSelection *selection;
628 GtkTreeIter iter, nextIter;
633 g_debug("audio_remove_clicked_cb ()");
634 treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
635 selection = gtk_tree_view_get_selection (treeview);
636 if (gtk_tree_selection_get_selected(selection, &store, &iter))
639 if (!gtk_tree_model_iter_next(store, &nextIter))
642 if (gtk_tree_model_get_iter_first(store, &nextIter))
644 gtk_tree_selection_select_iter (selection, &nextIter);
649 gtk_tree_selection_select_iter (selection, &nextIter);
651 // Get the row number
652 treepath = gtk_tree_model_get_path (store, &iter);
653 indices = gtk_tree_path_get_indices (treepath);
655 gtk_tree_path_free(treepath);
656 // Remove the selected item
657 gtk_list_store_remove (GTK_LIST_STORE(store), &iter);
658 // remove from audio settings list
660 widget = GHB_WIDGET (ud->builder, "audio_add");
661 gtk_widget_set_sensitive(widget, TRUE);
662 audio_list = ghb_settings_get_value(ud->settings, "audio_list");
663 if (row >= ghb_array_len(audio_list))
665 GValue *old = ghb_array_get_nth(audio_list, row);
667 ghb_array_remove(audio_list, row);
672 ghb_set_audio(signal_user_data_t *ud, GValue *settings)
678 GValue *track, *audio, *acodec, *bitrate, *rate, *mix, *drc;
681 g_debug("set_audio");
682 // Clear the audio list
683 ghb_clear_audio_list(ud);
684 button = GHB_WIDGET (ud->builder, "audio_add");
685 alist = ghb_settings_get_value(settings, "audio_list");
687 count = ghb_array_len(alist);
688 for (ii = 0; ii < count; ii++)
690 audio = ghb_array_get_nth(alist, ii);
691 track = ghb_settings_get_value(audio, "AudioTrack");
692 acodec = ghb_settings_get_value(audio, "AudioEncoder");
693 bitrate = ghb_settings_get_value(audio, "AudioBitrate");
694 rate = ghb_settings_get_value(audio, "AudioSamplerate");
695 mix = ghb_settings_get_value(audio, "AudioMixdown");
696 drc = ghb_settings_get_value(audio, "AudioTrackDRCSlider");
697 acodec_code = ghb_lookup_combo_int("AudioEncoder", acodec);
699 if (acodec_code != 0)
702 g_signal_emit_by_name(button, "clicked", ud);
703 ghb_ui_update(ud, "AudioTrack", track);
704 ghb_ui_update(ud, "AudioEncoder", acodec);
705 if (!ghb_audio_is_passthru (acodec_code))
707 // This gets set autimatically if the codec is passthru
708 ghb_ui_update(ud, "AudioBitrate", bitrate);
709 ghb_ui_update(ud, "AudioSamplerate", rate);
710 ghb_ui_update(ud, "AudioMixdown", mix);
712 ghb_ui_update(ud, "AudioTrackDRCSlider", drc);