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);
348 ghb_update_destination_extension(ud);
353 audio_track_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
357 g_debug("audio_track_changed_cb ()");
358 ghb_adjust_audio_rate_combos(ud);
359 ghb_check_dependency(ud, widget);
360 ghb_grey_combo_options(ud->builder);
361 asettings = get_selected_asettings(ud);
362 if (asettings != NULL)
366 ghb_widget_to_setting(asettings, widget);
367 audio_list_refresh_selected(ud);
368 track = ghb_settings_combo_option(asettings, "AudioTrack");
369 ghb_settings_set_string(asettings, "AudioTrackDescription", track);
375 audio_mix_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
379 g_debug("audio_mix_changed_cb ()");
380 ghb_adjust_audio_rate_combos(ud);
381 ghb_check_dependency(ud, widget);
382 asettings = get_selected_asettings(ud);
383 if (asettings != NULL)
385 ghb_widget_to_setting(asettings, widget);
386 audio_list_refresh_selected(ud);
392 audio_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
396 g_debug("audio_widget_changed_cb ()");
397 ghb_check_dependency(ud, widget);
398 asettings = get_selected_asettings(ud);
399 if (asettings != NULL)
401 ghb_widget_to_setting(asettings, widget);
402 audio_list_refresh_selected(ud);
408 drc_widget_changed_cb(GtkWidget *widget, gdouble val, signal_user_data_t *ud)
414 g_debug("drc_widget_changed_cb ()");
416 label = GTK_LABEL(GHB_WIDGET(ud->builder, "drc_label"));
418 drc = g_strdup_printf("Off");
420 drc = g_strdup_printf("%.1f", val);
421 gtk_label_set_text(label, drc);
423 ghb_check_dependency(ud, widget);
424 asettings = get_selected_asettings(ud);
425 if (asettings != NULL)
427 ghb_widget_to_setting(asettings, widget);
428 audio_list_refresh_selected(ud);
433 // subtitles differ from other settings in that
434 // the selection is updated automaitcally when the title
435 // changes. I don't want the preset selection changed as
436 // would happen for regular settings.
438 subtitle_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
440 const gchar *name = gtk_widget_get_name(widget);
441 g_debug("subtitle_changed_cb () %s", name);
442 ghb_widget_to_setting(ud->settings, widget);
443 ghb_check_dependency(ud, widget);
448 ghb_clear_audio_list(signal_user_data_t *ud)
450 GtkTreeView *treeview;
454 g_debug("clear_audio_list ()");
455 audio_list = ghb_settings_get_value(ud->settings, "audio_list");
456 if (audio_list == NULL)
458 audio_list = ghb_array_value_new(8);
459 ghb_settings_set_value(ud->settings, "audio_list", audio_list);
462 ghb_array_value_reset(audio_list, 8);
463 treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
464 store = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
465 gtk_list_store_clear (store);
469 add_to_audio_list(signal_user_data_t *ud, GValue *settings)
471 GtkTreeView *treeview;
474 GtkTreeSelection *selection;
475 const gchar *track, *codec, *br, *sr, *mix;
476 gchar *s_drc, *s_track, *s_codec, *s_br, *s_sr, *s_mix;
479 g_debug("add_to_audio_list ()");
480 treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
481 selection = gtk_tree_view_get_selection (treeview);
482 store = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
484 track = ghb_settings_combo_option(settings, "AudioTrack");
485 codec = ghb_settings_combo_option(settings, "AudioEncoder");
486 br = ghb_settings_combo_option(settings, "AudioBitrate");
487 sr = ghb_settings_combo_option(settings, "AudioSamplerate");
488 mix = ghb_settings_combo_option(settings, "AudioMixdown");
490 s_track = ghb_settings_get_string(settings, "AudioTrack");
491 s_codec = ghb_settings_get_string(settings, "AudioEncoder");
492 s_br = ghb_settings_get_string(settings, "AudioBitrate");
493 s_sr = ghb_settings_get_string(settings, "AudioSamplerate");
494 s_mix = ghb_settings_get_string(settings, "AudioMixdown");
495 drc = ghb_settings_get_double(settings, "AudioTrackDRCSlider");
497 s_drc = g_strdup("Off");
499 s_drc = g_strdup_printf("%.1f", drc);
502 gtk_list_store_append(store, &iter);
503 gtk_list_store_set(store, &iter,
504 // These are displayed in list
511 // These are used to set combo box values when a list item is selected
519 gtk_tree_selection_select_iter(selection, &iter);
529 audio_list_selection_changed_cb(GtkTreeSelection *selection, signal_user_data_t *ud)
535 g_debug("audio_list_selection_changed_cb ()");
536 if (gtk_tree_selection_get_selected(selection, &store, &iter))
538 const gchar *track, *codec, *bitrate, *sample_rate, *mix;
541 gtk_tree_model_get(store, &iter,
549 ghb_ui_update(ud, "AudioTrack", ghb_string_value(track));
550 ghb_ui_update(ud, "AudioEncoder", ghb_string_value(codec));
551 ghb_ui_update(ud, "AudioBitrate", ghb_string_value(bitrate));
552 ghb_ui_update(ud, "AudioSamplerate", ghb_string_value(sample_rate));
553 ghb_ui_update(ud, "AudioMixdown", ghb_string_value(mix));
554 ghb_ui_update(ud, "AudioTrackDRCSlider", ghb_double_value(drc));
555 widget = GHB_WIDGET (ud->builder, "audio_remove");
556 gtk_widget_set_sensitive(widget, TRUE);
560 widget = GHB_WIDGET (ud->builder, "audio_remove");
561 gtk_widget_set_sensitive(widget, FALSE);
566 audio_add_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
568 // Add the current audio settings to the list.
575 g_debug("audio_add_clicked_cb ()");
576 asettings = ghb_dict_value_new();
577 // Only allow up to 8 audio entries
578 widget = GHB_WIDGET(ud->builder, "AudioTrack");
579 ghb_settings_take_value(asettings, "AudioTrack", ghb_widget_value(widget));
580 widget = GHB_WIDGET(ud->builder, "AudioEncoder");
581 ghb_settings_take_value(asettings, "AudioEncoder", ghb_widget_value(widget));
582 widget = GHB_WIDGET(ud->builder, "AudioBitrate");
583 ghb_settings_take_value(asettings, "AudioBitrate", ghb_widget_value(widget));
584 widget = GHB_WIDGET(ud->builder, "AudioSamplerate");
585 ghb_settings_take_value(asettings, "AudioSamplerate", ghb_widget_value(widget));
586 widget = GHB_WIDGET(ud->builder, "AudioMixdown");
587 ghb_settings_take_value(asettings, "AudioMixdown", ghb_widget_value(widget));
588 widget = GHB_WIDGET(ud->builder, "AudioTrackDRCSlider");
589 ghb_settings_take_value(asettings, "AudioTrackDRCSlider", ghb_widget_value(widget));
590 track = ghb_settings_combo_option(asettings, "AudioTrack");
591 ghb_settings_set_string(asettings, "AudioTrackDescription", track);
593 audio_list = ghb_settings_get_value(ud->settings, "audio_list");
594 if (audio_list == NULL)
596 audio_list = ghb_array_value_new(8);
597 ghb_settings_set_value(ud->settings, "audio_list", audio_list);
599 ghb_array_append(audio_list, asettings);
600 add_to_audio_list(ud, asettings);
601 count = ghb_array_len(audio_list);
604 gtk_widget_set_sensitive(xwidget, FALSE);
609 audio_remove_clicked_cb(GtkWidget *widget, signal_user_data_t *ud)
611 GtkTreeView *treeview;
612 GtkTreePath *treepath;
613 GtkTreeSelection *selection;
615 GtkTreeIter iter, nextIter;
620 g_debug("audio_remove_clicked_cb ()");
621 treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
622 selection = gtk_tree_view_get_selection (treeview);
623 if (gtk_tree_selection_get_selected(selection, &store, &iter))
626 if (!gtk_tree_model_iter_next(store, &nextIter))
629 if (gtk_tree_model_get_iter_first(store, &nextIter))
631 gtk_tree_selection_select_iter (selection, &nextIter);
636 gtk_tree_selection_select_iter (selection, &nextIter);
638 // Get the row number
639 treepath = gtk_tree_model_get_path (store, &iter);
640 indices = gtk_tree_path_get_indices (treepath);
642 gtk_tree_path_free(treepath);
643 // Remove the selected item
644 gtk_list_store_remove (GTK_LIST_STORE(store), &iter);
645 // remove from audio settings list
647 widget = GHB_WIDGET (ud->builder, "audio_add");
648 gtk_widget_set_sensitive(widget, TRUE);
649 audio_list = ghb_settings_get_value(ud->settings, "audio_list");
650 if (row >= ghb_array_len(audio_list))
652 GValue *old = ghb_array_get_nth(audio_list, row);
654 ghb_array_remove(audio_list, row);
659 ghb_set_audio(signal_user_data_t *ud, GValue *settings)
665 GValue *track, *audio, *acodec, *bitrate, *rate, *mix, *drc;
668 g_debug("set_audio");
669 // Clear the audio list
670 ghb_clear_audio_list(ud);
671 button = GHB_WIDGET (ud->builder, "audio_add");
672 alist = ghb_settings_get_value(settings, "audio_list");
674 count = ghb_array_len(alist);
675 for (ii = 0; ii < count; ii++)
677 audio = ghb_array_get_nth(alist, ii);
678 track = ghb_settings_get_value(audio, "AudioTrack");
679 acodec = ghb_settings_get_value(audio, "AudioEncoder");
680 bitrate = ghb_settings_get_value(audio, "AudioBitrate");
681 rate = ghb_settings_get_value(audio, "AudioSamplerate");
682 mix = ghb_settings_get_value(audio, "AudioMixdown");
683 drc = ghb_settings_get_value(audio, "AudioTrackDRCSlider");
684 acodec_code = ghb_lookup_combo_int("AudioEncoder", acodec);
686 if (acodec_code != 0)
689 g_signal_emit_by_name(button, "clicked", ud);
690 ghb_ui_update(ud, "AudioTrack", track);
691 ghb_ui_update(ud, "AudioEncoder", acodec);
692 if (!ghb_audio_is_passthru (acodec_code))
694 // This gets set autimatically if the codec is passthru
695 ghb_ui_update(ud, "AudioBitrate", bitrate);
696 ghb_ui_update(ud, "AudioSamplerate", rate);
697 ghb_ui_update(ud, "AudioMixdown", mix);
699 ghb_ui_update(ud, "AudioTrackDRCSlider", drc);