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_set_pref_audio(gint titleindex, signal_user_data_t *ud)
95 gint acodec_code, mix_code, track;
98 ghb_audio_info_t ainfo;
99 GHashTable *track_indices;
101 const GValue *pref_audio;
102 const GValue *audio, *acodec, *bitrate, *rate, *mix, *drc;
103 gint count, ii, list_count;
105 g_debug("set_pref_audio");
106 track_indices = g_hash_table_new_full(g_int_hash, g_int_equal,
107 NULL, free_audio_index_list);
108 // Clear the audio list
109 ghb_clear_audio_list(ud);
110 // Find "best" audio based on audio preferences
111 button = GHB_WIDGET (ud->builder, "audio_add");
112 source_lang = ghb_settings_get_string(ud->settings, "SourceAudioLang");
114 pref_audio = ghb_settings_get_value(ud->settings, "AudioList");
117 count = ghb_array_len(pref_audio);
118 for (ii = 0; ii < count; ii++)
120 audio = ghb_array_get_nth(pref_audio, ii);
121 acodec = ghb_settings_get_value(audio, "AudioEncoder");
122 bitrate = ghb_settings_get_value(audio, "AudioBitrate");
123 rate = ghb_settings_get_value(audio, "AudioSamplerate");
124 mix = ghb_settings_get_value(audio, "AudioMixdown");
125 drc = ghb_settings_get_value(audio, "AudioTrackDRCSlider");
126 acodec_code = ghb_lookup_combo_int("AudioEncoder", acodec);
127 // If there are multiple audios using the same codec, then
128 // select sequential tracks for each. The hash keeps track
129 // of the tracks used for each codec.
130 track = ghb_find_audio_track(titleindex, source_lang,
131 acodec_code, track_indices);
133 // 1. pref codec is ac3
134 // 2. source codec is not ac3
135 // 3. next pref is enabled
136 if (ghb_get_audio_info (&ainfo, titleindex, track) &&
137 ghb_audio_is_passthru (acodec_code))
139 // HB_ACODEC_* are bit fields. Treat acodec_code as mask
140 if (!(ainfo.codec & acodec_code))
142 acodec_code = ghb_get_default_acodec();
143 // If there's more audio to process, or we've already
144 // placed one in the list, then we can skip this one
145 if ((ii + 1 < count) || (list_count != 0))
153 acodec_code &= ainfo.codec;
156 if (titleindex >= 0 && track < 0)
158 if (acodec_code != 0)
161 g_signal_emit_by_name(button, "clicked", ud);
163 ghb_ui_update(ud, "AudioTrack", ghb_int64_value(track));
164 ghb_ui_update(ud, "AudioEncoder", acodec);
165 if (!ghb_audio_is_passthru (acodec_code))
167 // This gets set autimatically if the codec is passthru
168 ghb_ui_update(ud, "AudioBitrate", bitrate);
169 ghb_ui_update(ud, "AudioSamplerate", rate);
170 mix_code = ghb_lookup_combo_int("AudioMixdown", mix);
171 mix_code = ghb_get_best_mix(
172 titleindex, track, acodec_code, mix_code);
173 ghb_ui_update(ud, "AudioMixdown", ghb_int64_value(mix_code));
175 ghb_ui_update(ud, "AudioTrackDRCSlider", drc);
179 g_hash_table_destroy(track_indices);
183 get_selected_asettings(signal_user_data_t *ud)
185 GtkTreeView *treeview;
186 GtkTreePath *treepath;
187 GtkTreeSelection *selection;
192 GValue *asettings = NULL;
193 const GValue *audio_list;
195 g_debug("get_selected_asettings ()");
196 treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
197 selection = gtk_tree_view_get_selection (treeview);
198 if (gtk_tree_selection_get_selected(selection, &store, &iter))
200 // Get the row number
201 treepath = gtk_tree_model_get_path (store, &iter);
202 indices = gtk_tree_path_get_indices (treepath);
204 gtk_tree_path_free(treepath);
205 // find audio settings
206 if (row < 0) return NULL;
207 audio_list = ghb_settings_get_value(ud->settings, "audio_list");
208 if (row >= ghb_array_len(audio_list))
210 asettings = ghb_array_get_nth(audio_list, row);
216 audio_list_refresh_selected(signal_user_data_t *ud)
218 GtkTreeView *treeview;
219 GtkTreePath *treepath;
220 GtkTreeSelection *selection;
225 GValue *asettings = NULL;
226 const GValue *audio_list;
228 g_debug("audio_list_refresh_selected ()");
229 treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
230 selection = gtk_tree_view_get_selection (treeview);
231 if (gtk_tree_selection_get_selected(selection, &store, &iter))
233 const gchar *track, *codec, *br, *sr, *mix;
234 gchar *s_drc, *s_track, *s_codec, *s_br, *s_sr, *s_mix;
236 // Get the row number
237 treepath = gtk_tree_model_get_path (store, &iter);
238 indices = gtk_tree_path_get_indices (treepath);
240 gtk_tree_path_free(treepath);
241 // find audio settings
243 audio_list = ghb_settings_get_value(ud->settings, "audio_list");
244 if (row >= ghb_array_len(audio_list))
246 asettings = ghb_array_get_nth(audio_list, row);
248 track = ghb_settings_combo_option(asettings, "AudioTrack");
249 codec = ghb_settings_combo_option(asettings, "AudioEncoder");
250 br = ghb_settings_combo_option(asettings, "AudioBitrate");
251 sr = ghb_settings_combo_option(asettings, "AudioSamplerate");
252 mix = ghb_settings_combo_option(asettings, "AudioMixdown");
254 s_track = ghb_settings_get_string(asettings, "AudioTrack");
255 s_codec = ghb_settings_get_string(asettings, "AudioEncoder");
256 s_br = ghb_settings_get_string(asettings, "AudioBitrate");
257 s_sr = ghb_settings_get_string(asettings, "AudioSamplerate");
258 s_mix = ghb_settings_get_string(asettings, "AudioMixdown");
259 drc = ghb_settings_get_double(asettings, "AudioTrackDRCSlider");
261 s_drc = g_strdup("Off");
263 s_drc = g_strdup_printf("%.1f", drc);
265 gtk_list_store_set(GTK_LIST_STORE(store), &iter,
266 // These are displayed in list
273 // These are used to set combo values when a list item is selected
291 audio_codec_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
293 static gint prev_acodec = 0;
294 gint acodec_code, mix_code;
295 GValue *asettings, *gval;
297 g_debug("audio_codec_changed_cb ()");
298 gval = ghb_widget_value(widget);
299 acodec_code = ghb_lookup_combo_int("AudioEncoder", gval);
300 ghb_value_free(gval);
301 if (ghb_audio_is_passthru (prev_acodec) &&
302 !ghb_audio_is_passthru (acodec_code))
304 // Transition from passthru to not, put some audio settings back to
309 titleindex = ghb_settings_combo_int(ud->settings, "title");
310 track = ghb_settings_combo_int(ud->settings, "AudioTrack");
312 ghb_ui_update(ud, "AudioBitrate", ghb_string_value("160"));
313 ghb_ui_update(ud, "AudioSamplerate", ghb_string_value("source"));
314 mix_code = ghb_lookup_combo_int("AudioMixdown", ghb_string_value("dpl2"));
315 mix_code = ghb_get_best_mix( titleindex, track, acodec_code, mix_code);
316 ghb_ui_update(ud, "AudioMixdown", ghb_int64_value(mix_code));
318 ghb_adjust_audio_rate_combos(ud);
319 ghb_grey_combo_options (ud->builder);
320 ghb_check_dependency(ud, widget);
321 prev_acodec = acodec_code;
322 asettings = get_selected_asettings(ud);
323 if (asettings != NULL)
325 ghb_widget_to_setting(asettings, widget);
326 audio_list_refresh_selected(ud);
329 const GValue *audio_list;
330 audio_list = ghb_settings_get_value(ud->settings, "audio_list");
331 if (ghb_ac3_in_audio_list (audio_list))
335 container = ghb_settings_get_string(ud->settings, "FileFormat");
336 if (strcmp(container, "mp4") == 0)
338 ghb_ui_update(ud, "FileFormat", ghb_string_value("m4v"));
346 audio_track_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
350 g_debug("audio_track_changed_cb ()");
351 ghb_adjust_audio_rate_combos(ud);
352 ghb_check_dependency(ud, widget);
353 ghb_grey_combo_options(ud->builder);
354 asettings = get_selected_asettings(ud);
355 if (asettings != NULL)
359 ghb_widget_to_setting(asettings, widget);
360 audio_list_refresh_selected(ud);
361 track = ghb_settings_combo_option(asettings, "AudioTrack");
362 ghb_settings_set_string(asettings, "AudioTrackDescription", track);
368 audio_mix_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
372 g_debug("audio_mix_changed_cb ()");
373 ghb_adjust_audio_rate_combos(ud);
374 ghb_check_dependency(ud, widget);
375 asettings = get_selected_asettings(ud);
376 if (asettings != NULL)
378 ghb_widget_to_setting(asettings, widget);
379 audio_list_refresh_selected(ud);
385 audio_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
389 g_debug("audio_widget_changed_cb ()");
390 ghb_check_dependency(ud, widget);
391 asettings = get_selected_asettings(ud);
392 if (asettings != NULL)
394 ghb_widget_to_setting(asettings, widget);
395 audio_list_refresh_selected(ud);
401 drc_widget_changed_cb(GtkWidget *widget, gdouble val, signal_user_data_t *ud)
407 g_debug("drc_widget_changed_cb ()");
409 label = GTK_LABEL(GHB_WIDGET(ud->builder, "drc_label"));
411 drc = g_strdup_printf("Off");
413 drc = g_strdup_printf("%.1f", val);
414 gtk_label_set_text(label, drc);
416 ghb_check_dependency(ud, widget);
417 asettings = get_selected_asettings(ud);
418 if (asettings != NULL)
420 ghb_widget_to_setting(asettings, widget);
421 audio_list_refresh_selected(ud);
426 // subtitles differ from other settings in that
427 // the selection is updated automaitcally when the title
428 // changes. I don't want the preset selection changed as
429 // would happen for regular settings.
431 subtitle_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
433 const gchar *name = gtk_widget_get_name(widget);
434 g_debug("subtitle_changed_cb () %s", name);
435 ghb_widget_to_setting(ud->settings, widget);
436 ghb_check_dependency(ud, widget);
441 ghb_clear_audio_list(signal_user_data_t *ud)
443 GtkTreeView *treeview;
447 g_debug("clear_audio_list ()");
448 audio_list = ghb_settings_get_value(ud->settings, "audio_list");
449 if (audio_list == NULL)
451 audio_list = ghb_array_value_new(8);
452 ghb_settings_set_value(ud->settings, "audio_list", audio_list);
455 ghb_array_value_reset(audio_list, 8);
456 treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
457 store = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
458 gtk_list_store_clear (store);
462 add_to_audio_list(signal_user_data_t *ud, GValue *settings)
464 GtkTreeView *treeview;
467 GtkTreeSelection *selection;
468 const gchar *track, *codec, *br, *sr, *mix;
469 gchar *s_drc, *s_track, *s_codec, *s_br, *s_sr, *s_mix;
472 g_debug("add_to_audio_list ()");
473 treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
474 selection = gtk_tree_view_get_selection (treeview);
475 store = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
477 track = ghb_settings_combo_option(settings, "AudioTrack");
478 codec = ghb_settings_combo_option(settings, "AudioEncoder");
479 br = ghb_settings_combo_option(settings, "AudioBitrate");
480 sr = ghb_settings_combo_option(settings, "AudioSamplerate");
481 mix = ghb_settings_combo_option(settings, "AudioMixdown");
483 s_track = ghb_settings_get_string(settings, "AudioTrack");
484 s_codec = ghb_settings_get_string(settings, "AudioEncoder");
485 s_br = ghb_settings_get_string(settings, "AudioBitrate");
486 s_sr = ghb_settings_get_string(settings, "AudioSamplerate");
487 s_mix = ghb_settings_get_string(settings, "AudioMixdown");
488 drc = ghb_settings_get_double(settings, "AudioTrackDRCSlider");
490 s_drc = g_strdup("Off");
492 s_drc = g_strdup_printf("%.1f", drc);
495 gtk_list_store_append(store, &iter);
496 gtk_list_store_set(store, &iter,
497 // These are displayed in list
504 // These are used to set combo box values when a list item is selected
512 gtk_tree_selection_select_iter(selection, &iter);
522 audio_list_selection_changed_cb(GtkTreeSelection *selection, signal_user_data_t *ud)
528 g_debug("audio_list_selection_changed_cb ()");
529 if (gtk_tree_selection_get_selected(selection, &store, &iter))
531 const gchar *track, *codec, *bitrate, *sample_rate, *mix;
534 gtk_tree_model_get(store, &iter,
542 ghb_ui_update(ud, "AudioTrack", ghb_string_value(track));
543 ghb_ui_update(ud, "AudioEncoder", ghb_string_value(codec));
544 ghb_ui_update(ud, "AudioBitrate", ghb_string_value(bitrate));
545 ghb_ui_update(ud, "AudioSamplerate", ghb_string_value(sample_rate));
546 ghb_ui_update(ud, "AudioMixdown", ghb_string_value(mix));
547 ghb_ui_update(ud, "AudioTrackDRCSlider", ghb_double_value(drc));
548 widget = GHB_WIDGET (ud->builder, "audio_remove");
549 gtk_widget_set_sensitive(widget, TRUE);
553 widget = GHB_WIDGET (ud->builder, "audio_remove");
554 gtk_widget_set_sensitive(widget, FALSE);
559 audio_add_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
561 // Add the current audio settings to the list.
568 g_debug("audio_add_clicked_cb ()");
569 asettings = ghb_dict_value_new();
570 // Only allow up to 8 audio entries
571 widget = GHB_WIDGET(ud->builder, "AudioTrack");
572 ghb_settings_take_value(asettings, "AudioTrack", ghb_widget_value(widget));
573 widget = GHB_WIDGET(ud->builder, "AudioEncoder");
574 ghb_settings_take_value(asettings, "AudioEncoder", ghb_widget_value(widget));
575 widget = GHB_WIDGET(ud->builder, "AudioBitrate");
576 ghb_settings_take_value(asettings, "AudioBitrate", ghb_widget_value(widget));
577 widget = GHB_WIDGET(ud->builder, "AudioSamplerate");
578 ghb_settings_take_value(asettings, "AudioSamplerate", ghb_widget_value(widget));
579 widget = GHB_WIDGET(ud->builder, "AudioMixdown");
580 ghb_settings_take_value(asettings, "AudioMixdown", ghb_widget_value(widget));
581 widget = GHB_WIDGET(ud->builder, "AudioTrackDRCSlider");
582 ghb_settings_take_value(asettings, "AudioTrackDRCSlider", ghb_widget_value(widget));
583 track = ghb_settings_combo_option(asettings, "AudioTrack");
584 ghb_settings_set_string(asettings, "AudioTrackDescription", track);
586 audio_list = ghb_settings_get_value(ud->settings, "audio_list");
587 if (audio_list == NULL)
589 audio_list = ghb_array_value_new(8);
590 ghb_settings_set_value(ud->settings, "audio_list", audio_list);
592 ghb_array_append(audio_list, asettings);
593 add_to_audio_list(ud, asettings);
594 count = ghb_array_len(audio_list);
597 gtk_widget_set_sensitive(xwidget, FALSE);
602 audio_remove_clicked_cb(GtkWidget *widget, signal_user_data_t *ud)
604 GtkTreeView *treeview;
605 GtkTreePath *treepath;
606 GtkTreeSelection *selection;
608 GtkTreeIter iter, nextIter;
613 g_debug("audio_remove_clicked_cb ()");
614 treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
615 selection = gtk_tree_view_get_selection (treeview);
616 if (gtk_tree_selection_get_selected(selection, &store, &iter))
619 if (!gtk_tree_model_iter_next(store, &nextIter))
622 if (gtk_tree_model_get_iter_first(store, &nextIter))
624 gtk_tree_selection_select_iter (selection, &nextIter);
629 gtk_tree_selection_select_iter (selection, &nextIter);
631 // Get the row number
632 treepath = gtk_tree_model_get_path (store, &iter);
633 indices = gtk_tree_path_get_indices (treepath);
635 gtk_tree_path_free(treepath);
636 // Remove the selected item
637 gtk_list_store_remove (GTK_LIST_STORE(store), &iter);
638 // remove from audio settings list
640 widget = GHB_WIDGET (ud->builder, "audio_add");
641 gtk_widget_set_sensitive(widget, TRUE);
642 audio_list = ghb_settings_get_value(ud->settings, "audio_list");
643 if (row >= ghb_array_len(audio_list))
645 GValue *old = ghb_array_get_nth(audio_list, row);
647 ghb_array_remove(audio_list, row);
652 ghb_set_audio(signal_user_data_t *ud, GValue *settings)
658 GValue *track, *audio, *acodec, *bitrate, *rate, *mix, *drc;
661 g_debug("set_audio");
662 // Clear the audio list
663 ghb_clear_audio_list(ud);
664 button = GHB_WIDGET (ud->builder, "audio_add");
665 alist = ghb_settings_get_value(settings, "audio_list");
667 count = ghb_array_len(alist);
668 for (ii = 0; ii < count; ii++)
670 audio = ghb_array_get_nth(alist, ii);
671 track = ghb_settings_get_value(audio, "AudioTrack");
672 acodec = ghb_settings_get_value(audio, "AudioEncoder");
673 bitrate = ghb_settings_get_value(audio, "AudioBitrate");
674 rate = ghb_settings_get_value(audio, "AudioSamplerate");
675 mix = ghb_settings_get_value(audio, "AudioMixdown");
676 drc = ghb_settings_get_value(audio, "AudioTrackDRCSlider");
677 acodec_code = ghb_lookup_combo_int("AudioEncoder", acodec);
679 if (acodec_code != 0)
682 g_signal_emit_by_name(button, "clicked", ud);
683 ghb_ui_update(ud, "AudioTrack", track);
684 ghb_ui_update(ud, "AudioEncoder", acodec);
685 if (!ghb_audio_is_passthru (acodec_code))
687 // This gets set autimatically if the codec is passthru
688 ghb_ui_update(ud, "AudioBitrate", bitrate);
689 ghb_ui_update(ud, "AudioSamplerate", rate);
690 ghb_ui_update(ud, "AudioMixdown", mix);
692 ghb_ui_update(ud, "AudioTrackDRCSlider", drc);