summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--contrib/ffmpeg/module.defs1
-rw-r--r--contrib/libmkv/A00-update-track-private-data.patch144
-rw-r--r--gtk/src/audiohandler.c255
-rw-r--r--gtk/src/audiohandler.h2
-rw-r--r--gtk/src/callbacks.c12
-rw-r--r--gtk/src/ghb.ui499
-rw-r--r--gtk/src/hb-backend.c66
-rw-r--r--gtk/src/hb-backend.h5
-rw-r--r--gtk/src/internal_defaults.xml4
-rw-r--r--gtk/src/makedeps.py16
-rw-r--r--gtk/src/queuehandler.c86
-rw-r--r--libhb/common.c183
-rw-r--r--libhb/common.h21
-rw-r--r--libhb/encavcodecaudio.c66
-rw-r--r--libhb/encfaac.c4
-rw-r--r--libhb/enclame.c17
-rw-r--r--libhb/encvorbis.c44
-rw-r--r--libhb/internal.h2
-rw-r--r--libhb/muxmkv.c61
-rw-r--r--libhb/muxmp4.c8
-rw-r--r--libhb/platform/macosx/encca_aac.c89
-rw-r--r--libhb/stream.c6
-rw-r--r--libhb/work.c172
-rw-r--r--macosx/Controller.m1
-rw-r--r--macosx/English.lproj/MainMenu.xib1452
-rw-r--r--macosx/HBAudio.m95
-rw-r--r--macosx/HBAudioController.m1
-rwxr-xr-xscripts/manicure.rb4
-rw-r--r--test/test.c165
29 files changed, 1729 insertions, 1752 deletions
diff --git a/contrib/ffmpeg/module.defs b/contrib/ffmpeg/module.defs
index 36c486463..732b7778a 100644
--- a/contrib/ffmpeg/module.defs
+++ b/contrib/ffmpeg/module.defs
@@ -18,6 +18,7 @@ FFMPEG.CONFIGURE.extra = \
--disable-vaapi \
--disable-dxva2 \
--enable-bzlib \
+ --enable-encoder=flac \
--enable-encoder=ac3 \
--enable-encoder=aac \
--enable-encoder=mpeg4 \
diff --git a/contrib/libmkv/A00-update-track-private-data.patch b/contrib/libmkv/A00-update-track-private-data.patch
new file mode 100644
index 000000000..97afcf93c
--- /dev/null
+++ b/contrib/libmkv/A00-update-track-private-data.patch
@@ -0,0 +1,144 @@
+diff --git a/include/libmkv.h b/include/libmkv.h
+index 4bd6f8c..146a91f 100644
+--- a/include/libmkv.h
++++ b/include/libmkv.h
+@@ -216,6 +216,7 @@ struct mk_TrackConfig_s {
+ mk_Writer *mk_createWriter(const char *filename, int64_t timescale,
+ uint8_t vlc_compat);
+ mk_Track *mk_createTrack(mk_Writer *w, mk_TrackConfig *tc);
++int mk_updateTrackPrivateData(mk_Writer *w, mk_Track *track, uint8_t * data, int size );
+ int mk_writeHeader(mk_Writer *w, const char *writingApp);
+ int mk_startFrame(mk_Writer *w, mk_Track *track);
+ int mk_flushFrame(mk_Writer *w, mk_Track *track);
+diff --git a/src/matroska.c b/src/matroska.c
+index f61b6f2..b14fd4c 100644
+--- a/src/matroska.c
++++ b/src/matroska.c
+@@ -171,8 +171,17 @@ int mk_writeHeader(mk_Writer *w, const char *writingApp)
+
+ w->seek_data.tracks = w->root->d_cur - w->segment_ptr;
+
+- if (w->tracks)
+- CHECK(mk_closeContext(w->tracks, 0));
++ if (w->tracks) {
++ mk_Track * tk;
++ int i;
++
++ CHECK(mk_closeContext(w->tracks, &offset));
++ for (i = 0; i < w->num_tracks; i++) {
++ tk = w->tracks_arr[i];
++ if (tk->private_data_size)
++ tk->private_data_ptr += offset;
++ }
++ }
+
+ CHECK(mk_flushContextData(w->root));
+
+@@ -487,12 +496,8 @@ int mk_close(mk_Writer *w)
+
+ for (i = w->num_tracks - 1; i >= 0; i--) {
+ tk = w->tracks_arr[i];
+- w->tracks_arr[i] = NULL;
+- --w->num_tracks;
+ if (mk_flushFrame(w, tk) < 0)
+ ret = -1;
+- free(tk);
+- tk = NULL;
+ }
+
+ if (mk_closeCluster(w) < 0)
+@@ -611,6 +616,24 @@ int mk_close(mk_Writer *w)
+ ret = -1;
+ }
+
++ /* update any track private data that may have changed */
++ for (i = w->num_tracks - 1; i >= 0; i--) {
++ tk = w->tracks_arr[i];
++ if (tk->private_data_size && tk->private_data)
++ {
++ if (mk_seekFile(w, tk->private_data_ptr) < 0)
++ ret = -1;
++ if (mk_writeBin(w->root, MATROSKA_ID_CODECPRIVATE,
++ tk->private_data, tk->private_data_size) < 0 ||
++ mk_flushContextData(w->root) < 0)
++ ret = -1;
++ free(tk->private_data);
++ }
++ w->tracks_arr[i] = NULL;
++ --w->num_tracks;
++ free(tk);
++ }
++
+ if (mk_closeContext(w->root, 0) < 0)
+ ret = -1;
+ mk_destroyContexts(w);
+diff --git a/src/matroska.h b/src/matroska.h
+index 515c5ab..2e1eb2f 100644
+--- a/src/matroska.h
++++ b/src/matroska.h
+@@ -269,6 +269,9 @@ struct mk_Track_s {
+ uint64_t default_duration;
+ mk_TrackType track_type;
+ int64_t prev_cue_pos;
++ uint8_t *private_data;
++ unsigned private_data_size;
++ int64_t private_data_ptr;
+
+ struct {
+ mk_Context *data;
+diff --git a/src/tracks.c b/src/tracks.c
+index d9fc38b..0e224e4 100644
+--- a/src/tracks.c
++++ b/src/tracks.c
+@@ -81,6 +81,8 @@ mk_Track *mk_createTrack(mk_Writer *w, mk_TrackConfig *tc)
+ return NULL;
+ if (tc->codecPrivateSize && (tc->codecPrivate != NULL)) {
+ /* CodecPrivate */
++ track->private_data_size = tc->codecPrivateSize;
++ track->private_data_ptr = ti->d_cur;
+ if (mk_writeBin(ti, MATROSKA_ID_CODECPRIVATE, tc->codecPrivate, tc->codecPrivateSize) < 0)
+ return NULL;
+ }
+@@ -191,17 +193,40 @@ mk_Track *mk_createTrack(mk_Writer *w, mk_TrackConfig *tc)
+ return NULL;
+ }
+
+- if (mk_closeContext(ti, 0) < 0)
++ int64_t offset = 0;
++ if (mk_closeContext(ti, &offset) < 0)
+ return NULL;
++ track->private_data_ptr += offset;
+
+ return track;
+ }
+
++int mk_updateTrackPrivateData(mk_Writer *w, mk_Track *track, uint8_t * data, int size )
++{
++ /* can not write data larger than was previously reserved */
++ if (size > track->private_data_size)
++ return -1;
++
++ if (track->private_data == NULL)
++ track->private_data = calloc(1, track->private_data_size);
++ memcpy(track->private_data, data, size);
++}
++
+ int mk_writeTracks(mk_Writer *w, mk_Context *tracks)
+ {
++ int i;
++ mk_Track * tk;
++ int64_t offset = 0;
++
+ w->seek_data.tracks = w->root->d_cur;
+
+- CHECK(mk_closeContext(w->tracks, 0));
++ CHECK(mk_closeContext(w->tracks, &offset));
++
++ for (i = 0; i < w->num_tracks; i++) {
++ tk = w->tracks_arr[i];
++ if (tk->private_data_size)
++ tk->private_data_ptr += offset;
++ }
+
+ return 0;
+ }
diff --git a/gtk/src/audiohandler.c b/gtk/src/audiohandler.c
index 90256d6cf..13c26e90d 100644
--- a/gtk/src/audiohandler.c
+++ b/gtk/src/audiohandler.c
@@ -175,7 +175,7 @@ ghb_adjust_audio_rate_combos(signal_user_data_t *ud)
bitrate = aconfig->in.bitrate / 1000;
// Set the values for bitrate and samplerate to the input rates
- ghb_set_passthru_bitrate_opts (ud->builder, bitrate);
+ ghb_set_bitrate_opts (ud->builder, bitrate, bitrate, bitrate);
mix = 0;
ghb_ui_update(ud, "AudioMixdown", ghb_int64_value(mix));
select_acodec &= aconfig->in.codec | HB_ACODEC_PASS_FLAG;
@@ -203,7 +203,7 @@ ghb_adjust_audio_rate_combos(signal_user_data_t *ud)
int low, high;
mix = ghb_get_best_mix( aconfig, select_acodec, mix);
hb_get_audio_bitrate_limits(select_acodec, sr, mix, &low, &high);
- ghb_set_default_bitrate_opts (ud->builder, low, high);
+ ghb_set_bitrate_opts (ud->builder, low, high, -1);
}
ghb_ui_update(ud, "AudioBitrate", ghb_int64_value(bitrate));
@@ -250,9 +250,9 @@ ghb_set_pref_audio(gint titleindex, signal_user_data_t *ud)
gint mux;
const GValue *pref_audio;
- const GValue *audio, *drc, *gain;
+ const GValue *audio, *drc, *gain, *enable_qual;
gint acodec, bitrate, mix;
- gdouble rate;
+ gdouble rate, quality;
gint count, ii, list_count;
g_debug("set_pref_audio");
@@ -288,6 +288,8 @@ ghb_set_pref_audio(gint titleindex, signal_user_data_t *ud)
mix = ghb_settings_combo_int(audio, "AudioMixdown");
drc = ghb_settings_get_value(audio, "AudioTrackDRCSlider");
gain = ghb_settings_get_value(audio, "AudioTrackGain");
+ enable_qual = ghb_settings_get_value(audio, "AudioTrackQualityEnable");
+ quality = ghb_settings_get_double(audio, "AudioTrackQuality");
// If there are multiple audios using the same codec, then
// select sequential tracks for each. The hash keeps track
// of the tracks used for each codec.
@@ -324,6 +326,7 @@ ghb_set_pref_audio(gint titleindex, signal_user_data_t *ud)
bitrate = aconfig->in.bitrate / 1000;
bitrate = hb_get_best_audio_bitrate(select_acodec, bitrate,
aconfig->in.samplerate, mix);
+ quality = hb_get_default_audio_quality( select_acodec );
rate = 0;
}
}
@@ -342,6 +345,8 @@ ghb_set_pref_audio(gint titleindex, signal_user_data_t *ud)
ghb_lookup_combo_string("AudioEncoder", ghb_int_value(acodec)));
ghb_settings_set_value(settings, "AudioEncoderActual",
ghb_lookup_acodec_value(select_acodec));
+ ghb_settings_set_value(settings, "AudioTrackQualityEnable", enable_qual);
+ ghb_settings_set_double(settings, "AudioTrackQuality", quality);
// This gets set autimatically if the codec is passthru
ghb_settings_set_string(settings, "AudioBitrate",
ghb_lookup_combo_string("AudioBitrate", ghb_int_value(bitrate)));
@@ -412,7 +417,7 @@ ghb_audio_list_refresh_selected(signal_user_data_t *ud)
if (gtk_tree_selection_get_selected(selection, &store, &iter))
{
const gchar *track, *codec, *br, *sr, *mix;
- gchar *s_drc, *s_gain;
+ gchar *s_drc, *s_gain, *s_quality = NULL;
gint itrack;
gdouble drc, gain;
// Get the row number
@@ -430,7 +435,17 @@ ghb_audio_list_refresh_selected(signal_user_data_t *ud)
track = ghb_settings_combo_option(asettings, "AudioTrack");
itrack = ghb_settings_combo_int(asettings, "AudioTrack");
codec = ghb_settings_combo_option(asettings, "AudioEncoderActual");
- br = ghb_settings_combo_option(asettings, "AudioBitrate");
+ double quality = ghb_settings_get_double(asettings, "AudioTrackQuality");
+ if (ghb_settings_get_boolean(asettings, "AudioTrackQualityEnable") &&
+ quality >= 0)
+ {
+ int codec = ghb_settings_combo_int(asettings, "AudioEncoderActual");
+ s_quality = ghb_format_quality("Q/", codec, quality);
+ }
+ else
+ {
+ br = ghb_settings_combo_option(asettings, "AudioBitrate");
+ }
sr = ghb_settings_combo_option(asettings, "AudioSamplerate");
mix = ghb_settings_combo_option(asettings, "AudioMixdown");
gain = ghb_settings_get_double(asettings, "AudioTrackGain");
@@ -446,7 +461,7 @@ ghb_audio_list_refresh_selected(signal_user_data_t *ud)
// These are displayed in list
0, track,
1, codec,
- 2, br,
+ 2, s_quality ? s_quality : br,
3, sr,
4, mix,
5, s_gain,
@@ -454,6 +469,78 @@ ghb_audio_list_refresh_selected(signal_user_data_t *ud)
-1);
g_free(s_drc);
g_free(s_gain);
+ g_free(s_quality);
+ }
+}
+
+void
+ghb_audio_list_refresh(signal_user_data_t *ud)
+{
+ GtkTreeView *treeview;
+ GtkTreeIter iter;
+ GtkListStore *store;
+ gboolean done;
+ gint row = 0;
+ const GValue *audio_list;
+
+ g_debug("ghb_audio_list_refresh ()");
+ treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
+ store = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
+ if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter))
+ {
+ do
+ {
+ const gchar *track, *codec, *br, *sr, *mix;
+ gchar *s_drc, *s_gain, *s_quality = NULL;
+ gint itrack;
+ gdouble drc, gain;
+ GValue *asettings;
+
+ audio_list = ghb_settings_get_value(ud->settings, "audio_list");
+ if (row >= ghb_array_len(audio_list))
+ return;
+ asettings = ghb_array_get_nth(audio_list, row);
+
+ track = ghb_settings_combo_option(asettings, "AudioTrack");
+ itrack = ghb_settings_combo_int(asettings, "AudioTrack");
+ codec = ghb_settings_combo_option(asettings, "AudioEncoderActual");
+ double quality = ghb_settings_get_double(asettings, "AudioTrackQuality");
+ if (ghb_settings_get_boolean(asettings, "AudioTrackQualityEnable") &&
+ quality >= 0)
+ {
+ int codec = ghb_settings_combo_int(asettings, "AudioEncoderActual");
+ s_quality = ghb_format_quality("Q/", codec, quality);
+ }
+ else
+ {
+ br = ghb_settings_combo_option(asettings, "AudioBitrate");
+ }
+ sr = ghb_settings_combo_option(asettings, "AudioSamplerate");
+ mix = ghb_settings_combo_option(asettings, "AudioMixdown");
+ gain = ghb_settings_get_double(asettings, "AudioTrackGain");
+ s_gain = g_strdup_printf("%.fdB", gain);
+
+ drc = ghb_settings_get_double(asettings, "AudioTrackDRCSlider");
+ if (drc < 1.0)
+ s_drc = g_strdup("Off");
+ else
+ s_drc = g_strdup_printf("%.1f", drc);
+
+ gtk_list_store_set(GTK_LIST_STORE(store), &iter,
+ // These are displayed in list
+ 0, track,
+ 1, codec,
+ 2, s_quality ? s_quality : br,
+ 3, sr,
+ 4, mix,
+ 5, s_gain,
+ 6, s_drc,
+ -1);
+ g_free(s_drc);
+ g_free(s_gain);
+ done = !gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter);
+ row++;
+ } while (!done);
}
}
@@ -467,17 +554,16 @@ audio_codec_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
g_debug("audio_codec_changed_cb ()");
gval = ghb_widget_value(widget);
acodec_code = ghb_lookup_combo_int("AudioEncoder", gval);
+ ghb_value_free(gval);
+
if (block_updates)
{
prev_acodec = acodec_code;
ghb_grey_combo_options (ud);
+ ghb_check_dependency(ud, widget, NULL);
return;
}
- gval = ghb_widget_value(widget);
- acodec_code = ghb_lookup_combo_int("AudioEncoder", gval);
- ghb_value_free(gval);
-
asettings = get_selected_asettings(ud);
if (ghb_audio_is_passthru (prev_acodec) &&
!ghb_audio_is_passthru (acodec_code))
@@ -533,6 +619,21 @@ audio_codec_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
}
ghb_update_destination_extension(ud);
ghb_live_reset(ud);
+
+ float low, high, gran, defval;
+ int dir;
+ hb_get_audio_quality_limits(acodec_code, &low, &high, &gran, &dir);
+ defval = hb_get_default_audio_quality(acodec_code);
+ GtkScaleButton *sb;
+ GtkAdjustment *adj;
+ sb = GTK_SCALE_BUTTON(GHB_WIDGET(ud->builder, "AudioTrackQuality"));
+ adj = gtk_scale_button_get_adjustment(sb);
+ if (dir)
+ {
+ // Quality values are inverted
+ defval = high - defval + low;
+ }
+ gtk_adjustment_configure (adj, defval, low, high, gran, gran * 10, 0);
}
G_MODULE_EXPORT void
@@ -543,6 +644,7 @@ audio_track_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
g_debug("audio_track_changed_cb ()");
if (block_updates)
{
+ ghb_check_dependency(ud, widget, NULL);
ghb_grey_combo_options (ud);
return;
}
@@ -569,7 +671,11 @@ audio_mix_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
GValue *asettings;
g_debug("audio_mix_changed_cb ()");
- if (block_updates) return;
+ if (block_updates)
+ {
+ ghb_check_dependency(ud, widget, NULL);
+ return;
+ }
ghb_adjust_audio_rate_combos(ud);
ghb_check_dependency(ud, widget, NULL);
@@ -588,10 +694,13 @@ audio_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
GValue *asettings;
g_debug("audio_widget_changed_cb ()");
- if (block_updates) return;
+ if (block_updates)
+ {
+ ghb_check_dependency(ud, widget, NULL);
+ return;
+ }
ghb_adjust_audio_rate_combos(ud);
- ghb_check_dependency(ud, widget, NULL);
asettings = get_selected_asettings(ud);
if (asettings != NULL)
{
@@ -605,7 +714,11 @@ G_MODULE_EXPORT void
global_audio_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
{
g_debug("global_audio_widget_changed_cb ()");
- if (block_updates) return;
+ if (block_updates)
+ {
+ ghb_check_dependency(ud, widget, NULL);
+ return;
+ }
ghb_check_dependency(ud, widget, NULL);
ghb_widget_to_setting(ud->settings, widget);
@@ -623,6 +736,64 @@ format_drc_cb(GtkScale *scale, gdouble val, signal_user_data_t *ud)
return g_strdup_printf("%-7.1f", val);
}
+static inline int is_close(float a, float b, float metric)
+{
+ float diff = a - b;
+ diff = (diff > 0) ? diff : -diff;
+ return diff < metric;
+}
+
+char * ghb_format_quality( const char *prefix, int codec, double quality )
+{
+ float low, high, gran;
+ int dir;
+ hb_get_audio_quality_limits(codec, &low, &high, &gran, &dir);
+
+ int digits;
+ float tmp = gran;
+ while (1)
+ {
+ if (is_close(tmp, (int)tmp, gran / 10))
+ break;
+ digits++;
+ tmp *= 10;
+ }
+ return g_strdup_printf("%s%.*f", prefix, digits, quality);
+}
+
+G_MODULE_EXPORT void
+quality_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
+{
+ GValue *asettings;
+
+ g_debug("quality_widget_changed_cb ()");
+
+ ghb_check_dependency(ud, widget, NULL);
+ float low, high, gran;
+ int dir;
+ int codec = ghb_settings_combo_int(ud->settings, "AudioEncoderActual");
+ hb_get_audio_quality_limits(codec, &low, &high, &gran, &dir);
+ double quality = ghb_widget_double(widget);
+ if (dir)
+ {
+ // Quality values are inverted
+ quality = high - quality + low;
+ }
+ char *s_quality = ghb_format_quality("", codec, quality);
+ ghb_ui_update( ud, "AudioTrackQualityValue", ghb_string_value(s_quality));
+ g_free(s_quality);
+
+ if (block_updates) return;
+
+ asettings = get_selected_asettings(ud);
+ if (asettings != NULL)
+ {
+ ghb_settings_set_double(asettings, "AudioTrackQuality", quality);
+ ghb_audio_list_refresh_selected(ud);
+ }
+ ghb_live_reset(ud);
+}
+
G_MODULE_EXPORT void
drc_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
{
@@ -630,8 +801,18 @@ drc_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
g_debug("drc_widget_changed_cb ()");
- if (block_updates) return;
ghb_check_dependency(ud, widget, NULL);
+ if (block_updates) return;
+
+ double drc = ghb_widget_double(widget);
+ char *s_drc;
+ if (drc < 0.99)
+ s_drc = g_strdup("Off");
+ else
+ s_drc = g_strdup_printf("%.1f", drc);
+ ghb_ui_update( ud, "AudioTrackDRCValue", ghb_string_value(s_drc));
+ g_free(s_drc);
+
asettings = get_selected_asettings(ud);
if (asettings != NULL)
{
@@ -656,9 +837,19 @@ gain_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
g_debug("gain_widget_changed_cb ()");
- if (block_updates) return;
ghb_check_dependency(ud, widget, NULL);
+ if (block_updates) return;
asettings = get_selected_asettings(ud);
+
+ int gain = ghb_widget_int(widget);
+ char *s_gain;
+ if ( gain >= 21.0 )
+ s_gain = g_strdup_printf("*11*");
+ else
+ s_gain = g_strdup_printf("%ddB", gain);
+ ghb_ui_update( ud, "AudioTrackGainValue", ghb_string_value(s_gain));
+ g_free(s_gain);
+
if (asettings != NULL)
{
ghb_widget_to_setting(asettings, widget);
@@ -696,7 +887,7 @@ add_to_audio_list(signal_user_data_t *ud, GValue *settings)
GtkListStore *store;
GtkTreeSelection *selection;
const gchar *track, *codec, *br, *sr, *mix;
- gchar *s_drc, *s_gain;
+ gchar *s_drc, *s_gain, *s_quality = NULL;
gint itrack;
gdouble drc;
gdouble gain;
@@ -709,7 +900,17 @@ add_to_audio_list(signal_user_data_t *ud, GValue *settings)
track = ghb_settings_combo_option(settings, "AudioTrack");
itrack = ghb_settings_combo_int(settings, "AudioTrack");
codec = ghb_settings_combo_option(settings, "AudioEncoderActual");
- br = ghb_settings_combo_option(settings, "AudioBitrate");
+ double quality = ghb_settings_get_double(settings, "AudioTrackQuality");
+ if (ghb_settings_get_boolean(settings, "AudioTrackQualityEnable") &&
+ quality >= 0)
+ {
+ int codec = ghb_settings_combo_int(settings, "AudioEncoderActual");
+ s_quality = ghb_format_quality("Q/", codec, quality);
+ }
+ else
+ {
+ br = ghb_settings_combo_option(settings, "AudioBitrate");
+ }
sr = ghb_settings_combo_option(settings, "AudioSamplerate");
mix = ghb_settings_combo_option(settings, "AudioMixdown");
gain = ghb_settings_get_double(settings, "AudioTrackGain");
@@ -726,7 +927,7 @@ add_to_audio_list(signal_user_data_t *ud, GValue *settings)
// These are displayed in list
0, track,
1, codec,
- 2, br,
+ 2, s_quality ? s_quality : br,
3, sr,
4, mix,
5, s_gain,
@@ -735,6 +936,7 @@ add_to_audio_list(signal_user_data_t *ud, GValue *settings)
gtk_tree_selection_select_iter(selection, &iter);
g_free(s_drc);
g_free(s_gain);
+ g_free(s_quality);
}
G_MODULE_EXPORT void
@@ -779,6 +981,8 @@ audio_list_selection_changed_cb(GtkTreeSelection *selection, signal_user_data_t
ghb_ui_update(ud, "AudioMixdown", ghb_settings_get_value(asettings, "AudioMixdown"));
ghb_ui_update(ud, "AudioTrackDRCSlider", ghb_settings_get_value(asettings, "AudioTrackDRCSlider"));
ghb_ui_update(ud, "AudioTrackGain", ghb_settings_get_value(asettings, "AudioTrackGain"));
+ ghb_ui_update(ud, "AudioTrackQuality", ghb_settings_get_value(asettings, "AudioTrackQuality"));
+ ghb_ui_update(ud, "AudioTrackQualityEnable", ghb_settings_get_value(asettings, "AudioTrackQualityEnable"));
block_updates = FALSE;
widget = GHB_WIDGET (ud->builder, "audio_remove");
gtk_widget_set_sensitive(widget, TRUE);
@@ -838,6 +1042,10 @@ audio_add_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
ghb_settings_take_value(asettings, "AudioEncoder", ghb_widget_value(widget));
ghb_settings_set_value(asettings, "AudioEncoderActual",
ghb_settings_get_value(ud->settings, "AudioEncoderActual"));
+ widget = GHB_WIDGET(ud->builder, "AudioTrackQualityEnable");
+ ghb_settings_take_value(asettings, "AudioTrackQualityEnable", ghb_widget_value(widget));
+ widget = GHB_WIDGET(ud->builder, "AudioTrackQuality");
+ ghb_settings_take_value(asettings, "AudioTrackQuality", ghb_widget_value(widget));
widget = GHB_WIDGET(ud->builder, "AudioBitrate");
ghb_settings_take_value(asettings, "AudioBitrate", ghb_widget_value(widget));
widget = GHB_WIDGET(ud->builder, "AudioSamplerate");
@@ -931,7 +1139,8 @@ ghb_set_audio(signal_user_data_t *ud, GValue *settings)
gint acodec_code;
GValue *alist;
- GValue *track, *audio, *acodec, *acodec_actual, *bitrate, *rate, *mix, *drc, *gain;
+ GValue *track, *audio, *acodec, *acodec_actual, *bitrate, *rate,
+ *mix, *drc, *gain, *quality, *enable_quality;
gint count, ii;
g_debug("set_audio");
@@ -946,6 +1155,8 @@ ghb_set_audio(signal_user_data_t *ud, GValue *settings)
track = ghb_settings_get_value(audio, "AudioTrack");
acodec = ghb_settings_get_value(audio, "AudioEncoder");
acodec_actual = ghb_settings_get_value(audio, "AudioEncoderActual");
+ enable_quality = ghb_settings_get_value(audio, "AudioTrackQualityEnable");
+ quality = ghb_settings_get_value(audio, "AudioTrackQuality");
bitrate = ghb_settings_get_value(audio, "AudioBitrate");
rate = ghb_settings_get_value(audio, "AudioSamplerate");
mix = ghb_settings_get_value(audio, "AudioMixdown");
@@ -959,6 +1170,8 @@ ghb_set_audio(signal_user_data_t *ud, GValue *settings)
ghb_settings_set_value(settings, "AudioTrack", track);
ghb_settings_set_value(settings, "AudioEncoder", acodec);
ghb_settings_set_value(settings, "AudioEncoderActual", acodec_actual);
+ ghb_settings_set_value(settings, "AudioTrackQualityEnable", enable_quality);
+ ghb_settings_set_value(settings, "AudioTrackQuality", quality);
// This gets set autimatically if the codec is passthru
ghb_settings_set_value(settings, "AudioBitrate", bitrate);
diff --git a/gtk/src/audiohandler.h b/gtk/src/audiohandler.h
index 88ee306ae..6ecca9983 100644
--- a/gtk/src/audiohandler.h
+++ b/gtk/src/audiohandler.h
@@ -36,5 +36,7 @@ gchar* ghb_get_user_audio_lang(
void ghb_audio_list_refresh_selected(signal_user_data_t *ud);
gint ghb_select_audio_codec(gint mux, hb_audio_config_t *aconfig, gint acodec, gint fallback_acodec, gint copy_mask);
int ghb_get_copy_mask(GValue *settings);
+void ghb_audio_list_refresh(signal_user_data_t *ud);
+char * ghb_format_quality( const char *prefix, int codec, double quality );
#endif // _AUDIOHANDLER_H_
diff --git a/gtk/src/callbacks.c b/gtk/src/callbacks.c
index 7b7b81f52..cce28befd 100644
--- a/gtk/src/callbacks.c
+++ b/gtk/src/callbacks.c
@@ -237,7 +237,6 @@ ghb_check_dependency(
continue;
}
sensitive = dep_check(ud, dep_name, &hide);
- g_free(dep_name);
if (GTK_IS_ACTION(dep_object))
{
gtk_action_set_sensitive(GTK_ACTION(dep_object), sensitive);
@@ -248,13 +247,20 @@ ghb_check_dependency(
gtk_widget_set_sensitive(GTK_WIDGET(dep_object), sensitive);
if (!sensitive && hide)
{
- gtk_widget_hide(GTK_WIDGET(dep_object));
+ if (gtk_widget_get_visible(GTK_WIDGET(dep_object)))
+ {
+ gtk_widget_hide(GTK_WIDGET(dep_object));
+ }
}
else
{
- gtk_widget_show_now(GTK_WIDGET(dep_object));
+ if (!gtk_widget_get_visible(GTK_WIDGET(dep_object)))
+ {
+ gtk_widget_show_now(GTK_WIDGET(dep_object));
+ }
}
}
+ g_free(dep_name);
}
}
diff --git a/gtk/src/ghb.ui b/gtk/src/ghb.ui
index 5ef2664e6..b25120594 100644
--- a/gtk/src/ghb.ui
+++ b/gtk/src/ghb.ui
@@ -288,6 +288,14 @@
<property name="page_size">0</property>
<property name="value">10</property>
</object>
+ <object class="GtkAdjustment" id="audio_quality_adj">
+ <property name="upper">10</property>
+ <property name="lower">0</property>
+ <property name="page_increment">1</property>
+ <property name="step_increment">0.1</property>
+ <property name="page_size">0</property>
+ <property name="value">0.0</property>
+ </object>
<object class="GtkImage" id="subtitle_add_image">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
@@ -2159,6 +2167,22 @@ FFMpeg's and Theora's scale is more linear. These encoders do not have a lossle
</packing>
</child>
<child>
+ <object class="GtkLabel" id="labela6">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes"></property>
+ <property name="use_markup">True</property>
+ </object>
+ <packing>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="left_attach">3</property>
+ <property name="right_attach">3</property>
+ <property name="x_options">GTK_EXPAND</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
<object class="GtkExpander" id="expander1">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
@@ -2169,186 +2193,279 @@ FFMpeg's and Theora's scale is more linear. These encoders do not have a lossle
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="n_rows">4</property>
- <property name="n_columns">5</property>
+ <property name="n_columns">8</property>
<property name="row_spacing">5</property>
<property name="column_spacing">5</property>
<child>
- <object class="GtkLabel" id="audio_name_label">
+ <object class="GtkHBox" id="hbox40">
<property name="visible">True</property>
- <property name="xalign">1</property>
- <property name="label" translatable="yes">Track Name:</property>
- <property name="use_markup">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="spacing">5</property>
+ <child>
+ <object class="GtkLabel" id="labela3">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">Auto Passthru:</property>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="AudioAllowMP3Pass">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip-text" translatable="yes">Enable this if your playback device supports AAC. This permits AAC passthru to be selected when automatic passthru selection is enabled.</property>
+ <property name="label" translatable="yes">MP3</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <signal handler="global_audio_widget_changed_cb" name="toggled"/>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="AudioAllowAACPass">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip-text" translatable="yes">Enable this if your playback device supports AAC. This permits AAC passthru to be selected when automatic passthru selection is enabled.</property>
+ <property name="label" translatable="yes">AAC</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <signal handler="global_audio_widget_changed_cb" name="toggled"/>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="AudioAllowAC3Pass">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip-text" translatable="yes">Enable this if your playback device supports AC-3. This permits AC-3 passthru to be selected when automatic passthru selection is enabled.</property>
+ <property name="label" translatable="yes">AC-3</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <signal handler="global_audio_widget_changed_cb" name="toggled"/>
+ </object>
+ <packing>
+ <property name="position">3</property>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="AudioAllowDTSPass">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip-text" translatable="yes">Enable this if your playback device supports DTS. This permits DTS passthru to be selected when automatic passthru selection is enabled.</property>
+ <property name="label" translatable="yes">DTS</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <signal handler="global_audio_widget_changed_cb" name="toggled"/>
+ </object>
+ <packing>
+ <property name="position">4</property>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="AudioAllowDTSHDPass">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip-text" translatable="yes">Enable this if your playback device supports DTS-HD. This permits DTS-HD passthru to be selected when automatic passthru selection is enabled.</property>
+ <property name="label" translatable="yes">DTS-HD</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <signal handler="global_audio_widget_changed_cb" name="toggled"/>
+ </object>
+ <packing>
+ <property name="position">5</property>
+ <property name="expand">False</property>
+ </packing>
+ </child>
</object>
<packing>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="left_attach">0</property>
- <property name="right_attach">1</property>
+ <property name="right_attach">4</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
- <object class="GtkAlignment" id="alignment25">
+ <object class="GtkLabel" id="labela4">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="xalign">0</property>
- <child>
- <object class="GtkEntry" id="AudioTrackName">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="max_length">40</property>
- <property name="activates_default">True</property>
- <property name="width_chars">20</property>
- <property name="truncate_multiline">True</property>
- <property name="tooltip-text" translatable="yes">Set the audio track name. Players may use this in the audio selection list.</property>
- <signal handler="audio_widget_changed_cb" name="changed"/>
- </object>
- </child>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">Passthru Fallback:</property>
</object>
<packing>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
+ <property name="left_attach">4</property>
+ <property name="right_attach">7</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
- <object class="GtkLabel" id="fill_label1">
+ <object class="GtkComboBox" id="AudioEncoderFallback">
<property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_markup">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip-text" translatable="yes">Set the audio codec to encode with when a suitable track can not be found for audio passthru.</property>
+ <signal handler="global_audio_widget_changed_cb" name="changed"/>
</object>
<packing>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
- <property name="left_attach">2</property>
- <property name="right_attach">3</property>
- <property name="x_options">GTK_FILL|GTK_EXPAND</property>
+ <property name="left_attach">7</property>
+ <property name="right_attach">8</property>
+ <property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
- <object class="GtkLabel" id="sr_label">
+ <object class="GtkHSeparator" id="separator1">
<property name="visible">True</property>
- <property name="xalign">1</property>
- <property name="label" translatable="yes">Sample Rate:</property>
- <property name="use_markup">True</property>
+ <property name="orientation">horizontal</property>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="left_attach">0</property>
- <property name="right_attach">1</property>
+ <property name="right_attach">8</property>
<property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
</packing>
</child>
<child>
- <object class="GtkAlignment" id="alignment34">
+ <object class="GtkAlignment" id="alignment59">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="xalign">0</property>
- <property name="xscale">0</property>
+ <property name="top_padding">8</property>
<child>
- <object class="GtkComboBox" id="AudioSamplerate">
+ <object class="GtkLabel" id="audio_name_label">
<property name="visible">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="tooltip-text" translatable="yes">Set the sample rate of the output audio track.</property>
- <signal handler="audio_widget_changed_cb" name="changed"/>
+ <property name="xalign">0.5</property>
+ <property name="label" translatable="yes">Track Name:</property>
+ <property name="use_markup">True</property>
</object>
</child>
</object>
<packing>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
- <object class="GtkLabel" id="gain_label">
+ <object class="GtkAlignment" id="alignment25">
<property name="visible">True</property>
- <property name="xalign">1</property>
- <property name="label" translatable="yes">Gain:</property>
- <property name="use_markup">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="xalign">0</property>
+ <child>
+ <object class="GtkEntry" id="AudioTrackName">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="max_length">40</property>
+ <property name="activates_default">True</property>
+ <property name="width_chars">20</property>
+ <property name="truncate_multiline">True</property>
+ <property name="tooltip-text" translatable="yes">Set the audio track name. Players may use this in the audio selection list.</property>
+ <signal handler="audio_widget_changed_cb" name="changed"/>
+ </object>
+ </child>
</object>
<packing>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="left_attach">3</property>
- <property name="right_attach">4</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
- <object class="GtkHScale" id="AudioTrackGain">
+ <object class="GtkLabel" id="AudioSamplerateLabel">
<property name="visible">True</property>
- <property name="width-request">150</property>
- <property name="orientation">horizontal</property>
- <property name="adjustment">adjustment35</property>
- <property name="value_pos">right</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="tooltip-markup" translatable="yes">&lt;b&gt;Audio Gain:&lt;/b&gt; Adjust the amplification or attenuation of the output audio track.</property>
- <signal handler="gain_widget_changed_cb" name="value_changed"/>
- <signal name="format_value" handler="format_gain_cb"/>
+ <property name="xalign">0.5</property>
+ <property name="label" translatable="yes">Sample Rate:</property>
+ <property name="use_markup">True</property>
</object>
<packing>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="left_attach">4</property>
- <property name="right_attach">5</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
- <object class="GtkLabel" id="drc_label">
+ <object class="GtkAlignment" id="alignment34">
<property name="visible">True</property>
- <property name="xalign">1</property>
- <property name="label" translatable="yes">Dynamic Range Compression:</property>
- <property name="use_markup">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="xalign">0.5</property>
+ <property name="xscale">0</property>
+ <child>
+ <object class="GtkComboBox" id="AudioSamplerate">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip-text" translatable="yes">Set the sample rate of the output audio track.</property>
+ <signal handler="audio_widget_changed_cb" name="changed"/>
+ </object>
+ </child>
</object>
<packing>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="left_attach">3</property>
- <property name="right_attach">4</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
- <object class="GtkHScale" id="AudioTrackDRCSlider">
+ <object class="GtkLabel" id="AudioTrackGainLabel">
<property name="visible">True</property>
- <property name="width-request">100</property>
- <property name="orientation">horizontal</property>
- <property name="value_pos">right</property>
- <property name="adjustment">adjustment28</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="tooltip-markup" translatable="yes">&lt;b&gt;Dynamic Range Compression:&lt;/b&gt; Adjust the dynamic range of the output audio track.
-
- For source audio that has a wide dynamic range (very loud and very soft sequences), DRC allows you to 'compress' the range by making loud sections softer and soft sections louder.</property>
- <signal handler="drc_widget_changed_cb" name="value_changed"/>
- <signal name="format_value" handler="format_drc_cb"/>
+ <property name="xalign">0.5</property>
+ <property name="label" translatable="yes">Gain:</property>
+ <property name="use_markup">True</property>
</object>
<packing>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="left_attach">4</property>
- <property name="right_attach">5</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
- <object class="GtkHBox" id="hbox40">
+ <object class="GtkHBox" id="hbox34">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="spacing">5</property>
+ <property name="spacing">0</property>
<child>
- <object class="GtkLabel" id="labela3">
+ <object class="GtkScaleButton" id="AudioTrackGain">
<property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="icons">audio-volume-muted
+audio-volume-high
+audio-volume-low
+audio-volume-medium</property>
+ <property name="adjustment">adjustment35</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="xalign">1</property>
- <property name="label" translatable="yes">Auto Passthru:</property>
+ <property name="tooltip-markup" translatable="yes">&lt;b&gt;Audio Gain:&lt;/b&gt; Adjust the amplification or attenuation of the output audio track.</property>
+ <signal handler="gain_widget_changed_cb" name="value_changed"/>
</object>
<packing>
<property name="position">0</property>
@@ -2356,130 +2473,194 @@ FFMpeg's and Theora's scale is more linear. These encoders do not have a lossle
</packing>
</child>
<child>
- <object class="GtkCheckButton" id="AudioAllowMP3Pass">
+ <object class="GtkLabel" id="AudioTrackGainValue">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="tooltip-text" translatable="yes">Enable this if your playback device supports AAC. This permits AAC passthru to be selected when automatic passthru selection is enabled.</property>
- <property name="label" translatable="yes">MP3</property>
- <property name="active">True</property>
- <property name="draw_indicator">True</property>
- <signal handler="global_audio_widget_changed_cb" name="toggled"/>
+ <property name="width_chars">6</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">0dB</property>
+ <property name="use_markup">True</property>
</object>
<packing>
<property name="position">1</property>
<property name="expand">False</property>
</packing>
</child>
+ </object>
+ <packing>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="AudioTrackDRCSliderLabel">
+ <property name="visible">True</property>
+ <property name="xalign">0.5</property>
+ <property name="label" translatable="yes">DRC:</property>
+ <property name="tooltip-markup" translatable="yes">&lt;b&gt;Dynamic Range Compression:&lt;/b&gt; Adjust the dynamic range of the output audio track.
+
+ For source audio that has a wide dynamic range (very loud and very soft sequences), DRC allows you to 'compress' the range by making loud sections softer and soft sections louder.</property>
+ <property name="use_markup">True</property>
+ </object>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="left_attach">3</property>
+ <property name="right_attach">4</property>
+ <property name="x_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="hbox33">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="spacing">0</property>
<child>
- <object class="GtkCheckButton" id="AudioAllowAACPass">
+ <object class="GtkScaleButton" id="AudioTrackDRCSlider">
<property name="visible">True</property>
- <property name="can_focus">True</property>
+ <property name="orientation">vertical</property>
+ <property name="icons">audio-input-microphone</property>
+ <property name="adjustment">adjustment28</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="tooltip-text" translatable="yes">Enable this if your playback device supports AAC. This permits AAC passthru to be selected when automatic passthru selection is enabled.</property>
- <property name="label" translatable="yes">AAC</property>
- <property name="active">True</property>
- <property name="draw_indicator">True</property>
- <signal handler="global_audio_widget_changed_cb" name="toggled"/>
+ <property name="tooltip-markup" translatable="yes">&lt;b&gt;Dynamic Range Compression:&lt;/b&gt; Adjust the dynamic range of the output audio track.
+
+ For source audio that has a wide dynamic range (very loud and very soft sequences), DRC allows you to 'compress' the range by making loud sections softer and soft sections louder.</property>
+ <signal handler="drc_widget_changed_cb" name="value_changed"/>
</object>
<packing>
- <property name="position">2</property>
+ <property name="position">0</property>
<property name="expand">False</property>
</packing>
</child>
<child>
- <object class="GtkCheckButton" id="AudioAllowAC3Pass">
+ <object class="GtkLabel" id="AudioTrackDRCValue">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="tooltip-text" translatable="yes">Enable this if your playback device supports AC-3. This permits AC-3 passthru to be selected when automatic passthru selection is enabled.</property>
- <property name="label" translatable="yes">AC-3</property>
- <property name="active">True</property>
- <property name="draw_indicator">True</property>
- <signal handler="global_audio_widget_changed_cb" name="toggled"/>
+ <property name="width_chars">4</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Off</property>
+ <property name="use_markup">True</property>
</object>
<packing>
- <property name="position">3</property>
+ <property name="position">1</property>
<property name="expand">False</property>
</packing>
</child>
+ </object>
+ <packing>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="left_attach">3</property>
+ <property name="right_attach">4</property>
+ <property name="x_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="AudioTrackQualityEnable">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="label" translatable="yes">Quality:</property>
+ <property name="tooltip-markup" translatable="yes">&lt;b&gt;Quality:&lt;/b&gt; For output codec's that support it, adjust the quality of the output.</property>
+ <property name="active">False</property>
+ <property name="draw_indicator">True</property>
+ <signal handler="audio_widget_changed_cb" name="toggled"/>
+ </object>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="left_attach">4</property>
+ <property name="right_attach">5</property>
+ <property name="x_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="hbox32">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="spacing">0</property>
<child>
- <object class="GtkCheckButton" id="AudioAllowDTSPass">
+ <object class="GtkScaleButton" id="AudioTrackQuality">
<property name="visible">True</property>
- <property name="can_focus">True</property>
+ <property name="orientation">vertical</property>
+ <property name="icons">weather-storm
+weather-clear
+weather-storm
+weather-showers-scattered
+weather-showers
+weather-overcast
+weather-few-clouds
+weather-clear</property>
+ <property name="adjustment">audio_quality_adj</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="tooltip-text" translatable="yes">Enable this if your playback device supports DTS. This permits DTS passthru to be selected when automatic passthru selection is enabled.</property>
- <property name="label" translatable="yes">DTS</property>
- <property name="active">True</property>
- <property name="draw_indicator">True</property>
- <signal handler="global_audio_widget_changed_cb" name="toggled"/>
+ <property name="tooltip-markup" translatable="yes">&lt;b&gt;Quality:&lt;/b&gt; For output codec's that support it, adjust the quality of the output.</property>
+ <signal handler="quality_widget_changed_cb" name="value_changed"/>
</object>
<packing>
- <property name="position">4</property>
+ <property name="position">0</property>
<property name="expand">False</property>
</packing>
</child>
<child>
- <object class="GtkCheckButton" id="AudioAllowDTSHDPass">
+ <object class="GtkLabel" id="AudioTrackQualityValue">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="tooltip-text" translatable="yes">Enable this if your playback device supports DTS-HD. This permits DTS-HD passthru to be selected when automatic passthru selection is enabled.</property>
- <property name="label" translatable="yes">DTS-HD</property>
- <property name="active">True</property>
- <property name="draw_indicator">True</property>
- <signal handler="global_audio_widget_changed_cb" name="toggled"/>
+ <property name="width_chars">4</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">00.0</property>
+ <property name="use_markup">True</property>
</object>
<packing>
- <property name="position">5</property>
+ <property name="position">1</property>
<property name="expand">False</property>
</packing>
</child>
</object>
<packing>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="left_attach">0</property>
- <property name="right_attach">4</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="left_attach">4</property>
+ <property name="right_attach">5</property>
+ <property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
- <object class="GtkLabel" id="labela4">
+ <object class="GtkLabel" id="filler_label0">
<property name="visible">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="xalign">1</property>
- <property name="label" translatable="yes">Passthru Fallback:</property>
+ <property name="label" translatable="yes"></property>
+ <property name="xalign">0</property>
+ <property name="use_markup">True</property>
</object>
<packing>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="x_options">GTK_FILL</property>
+ <property name="left_attach">5</property>
+ <property name="right_attach">8</property>
+ <property name="x_options">GTK_FILL|GTK_EXPAND</property>
</packing>
</child>
<child>
- <object class="GtkComboBox" id="AudioEncoderFallback">
+ <object class="GtkLabel" id="filler_label1">
<property name="visible">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="tooltip-text" translatable="yes">Set the audio codec to encode with when a suitable track can not be found for audio passthru.</property>
- <signal handler="global_audio_widget_changed_cb" name="changed"/>
+ <property name="label" translatable="yes"></property>
+ <property name="xalign">0</property>
+ <property name="use_markup">True</property>
</object>
<packing>
- <property name="top_attach">3</property>
- <property name="bottom_attach">4</property>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="x_options">GTK_FILL</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="left_attach">5</property>
+ <property name="right_attach">8</property>
+ <property name="x_options">GTK_FILL|GTK_EXPAND</property>
</packing>
</child>
</object>
</child>
</object>
<packing>
- <property name="top_attach">0</property>
+ <property name="top_attach">1</property>
<property name="bottom_attach">2</property>
- <property name="left_attach">2</property>
+ <property name="left_attach">0</property>
<property name="right_attach">3</property>
<property name="x_options">GTK_FILL|GTK_EXPAND</property>
<property name="y_options"></property>
@@ -2526,7 +2707,7 @@ FFMpeg's and Theora's scale is more linear. These encoders do not have a lossle
</packing>
</child>
<child>
- <object class="GtkLabel" id="label69">
+ <object class="GtkLabel" id="AudioBitrateLabel">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">Bitrate</property>
@@ -2542,7 +2723,7 @@ FFMpeg's and Theora's scale is more linear. These encoders do not have a lossle
</packing>
</child>
<child>
- <object class="GtkLabel" id="label24">
+ <object class="GtkLabel" id="AudioMixdownLabel">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">Mix</property>
diff --git a/gtk/src/hb-backend.c b/gtk/src/hb-backend.c
index 98a13079d..ea817b7ff 100644
--- a/gtk/src/hb-backend.c
+++ b/gtk/src/hb-backend.c
@@ -3219,21 +3219,30 @@ audio_bitrate_opts_add(GtkBuilder *builder, const gchar *name, gint rate)
g_debug("audio_bitrate_opts_add ()\n");
- if (rate < 8) return;
+ if (rate >= 0 && rate < 8) return;
if (ghb_audio_bitrates[hb_audio_bitrates_count].string)
{
g_free(ghb_audio_bitrates[hb_audio_bitrates_count].string);
}
ghb_audio_bitrates[hb_audio_bitrates_count].rate = rate;
- ghb_audio_bitrates[hb_audio_bitrates_count].string =
- g_strdup_printf("%d", rate);
+ if (rate < 0)
+ {
+ ghb_audio_bitrates[hb_audio_bitrates_count].string =
+ g_strdup_printf("N/A");
+ }
+ else
+ {
+ ghb_audio_bitrates[hb_audio_bitrates_count].string =
+ g_strdup_printf("%d", rate);
+ }
ghb_audio_bitrates_count = hb_audio_bitrates_count + 1;
store = get_combo_box_store(builder, name);
if (!find_combo_item_by_int(GTK_TREE_MODEL(store), rate, &iter))
{
- str = g_strdup_printf ("<small>%d</small>", rate);
+ str = g_strdup_printf ("<small>%s</small>",
+ ghb_audio_bitrates[hb_audio_bitrates_count].string);
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter,
0, str,
@@ -3247,11 +3256,12 @@ audio_bitrate_opts_add(GtkBuilder *builder, const gchar *name, gint rate)
}
static void
-audio_bitrate_opts_clean(
+audio_bitrate_opts_update(
GtkBuilder *builder,
const gchar *name,
gint first_rate,
- gint last_rate)
+ gint last_rate,
+ gint extra_rate)
{
GtkTreeIter iter;
GtkListStore *store;
@@ -3270,12 +3280,14 @@ audio_bitrate_opts_clean(
do
{
gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, 3, &ivalue, -1);
- if (search_rates(
+ if (ivalue != first_rate && ivalue != last_rate &&
+ !(ivalue == extra_rate && extra_rate >= first_rate) &&
+ search_rates(
ghb_audio_bitrates, ivalue, ghb_audio_bitrates_count) < 0)
{
done = !gtk_list_store_remove(store, &iter);
}
- else if (ivalue < first || ivalue > last)
+ else if ((int)ivalue < first || (int)ivalue > last)
{
ii++;
gtk_list_store_set(store, &iter, 1, FALSE, -1);
@@ -3289,6 +3301,8 @@ audio_bitrate_opts_clean(
}
} while (!done);
}
+ if (extra_rate >= first_rate)
+ audio_bitrate_opts_add(builder, name, extra_rate);
}
static void
@@ -3327,18 +3341,13 @@ audio_bitrate_opts_set(GtkBuilder *builder, const gchar *name)
}
void
-ghb_set_passthru_bitrate_opts(GtkBuilder *builder, gint bitrate)
-{
- audio_bitrate_opts_add(builder, "AudioBitrate", bitrate);
-}
-
-void
-ghb_set_default_bitrate_opts(
+ghb_set_bitrate_opts(
GtkBuilder *builder,
gint first_rate,
- gint last_rate)
+ gint last_rate,
+ gint extra_rate)
{
- audio_bitrate_opts_clean(builder, "AudioBitrate", first_rate, last_rate);
+ audio_bitrate_opts_update(builder, "AudioBitrate", first_rate, last_rate, extra_rate);
}
static ghb_status_t hb_status;
@@ -4906,17 +4915,28 @@ add_job(hb_handle_t *h, GValue *js, gint unique_id, gint titleindex)
// Make sure the mixdown is valid and pick a new one if not.
audio.out.mixdown = ghb_get_best_mix(aconfig, audio.out.codec,
audio.out.mixdown);
- audio.out.bitrate =
- ghb_settings_combo_int(asettings, "AudioBitrate");
+ double quality = ghb_settings_get_double(asettings, "AudioTrackQuality");
+ if (ghb_settings_get_boolean(asettings, "AudioTrackQualityEnable") &&
+ quality >= 0)
+ {
+ audio.out.quality = quality;
+ audio.out.bitrate = -1;
+ }
+ else
+ {
+ audio.out.quality = -1;
+ audio.out.bitrate =
+ ghb_settings_combo_int(asettings, "AudioBitrate");
+
+ audio.out.bitrate = hb_get_best_audio_bitrate(
+ audio.out.codec, audio.out.bitrate,
+ audio.out.samplerate, audio.out.mixdown);
+ }
gint srate = ghb_settings_combo_int(asettings, "AudioSamplerate");
if (srate == 0) // 0 is same as source
audio.out.samplerate = aconfig->in.samplerate;
else
audio.out.samplerate = srate;
-
- audio.out.bitrate = hb_get_best_audio_bitrate(
- audio.out.codec, audio.out.bitrate,
- audio.out.samplerate, audio.out.mixdown);
}
// Add it to the jobs audio list
diff --git a/gtk/src/hb-backend.h b/gtk/src/hb-backend.h
index 683ead9c1..4d6f1efa3 100644
--- a/gtk/src/hb-backend.h
+++ b/gtk/src/hb-backend.h
@@ -135,9 +135,8 @@ gboolean ghb_audio_is_passthru(gint acodec);
gboolean ghb_audio_can_passthru(gint acodec);
gint ghb_get_default_acodec(void);
hb_audio_config_t* ghb_get_scan_audio_info(gint titleindex, gint audioindex);
-void ghb_set_passthru_bitrate_opts(GtkBuilder *builder, gint bitrate);
-void ghb_set_default_bitrate_opts(
- GtkBuilder *builder, gint first_rate, gint last_rate);
+void ghb_set_bitrate_opts(
+ GtkBuilder *builder, gint first_rate, gint last_rate, gint extra_rate);
void ghb_grey_combo_options(signal_user_data_t *ud);
void ghb_update_ui_combo_box(
signal_user_data_t *ud, const gchar *name, gint user_data, gboolean all);
diff --git a/gtk/src/internal_defaults.xml b/gtk/src/internal_defaults.xml
index b4d06694d..0a6f65aba 100644
--- a/gtk/src/internal_defaults.xml
+++ b/gtk/src/internal_defaults.xml
@@ -318,6 +318,10 @@
<integer>1</integer>
<key>AudioTrackDescription</key>
<string></string>
+ <key>AudioTrackQualityEnable</key>
+ <false />
+ <key>AudioTrackQuality</key>
+ <real>-1</real>
<key>AudioTrackGain</key>
<real>0</real>
<key>AudioTrackDRCSlider</key>
diff --git a/gtk/src/makedeps.py b/gtk/src/makedeps.py
index a3c3bdf62..d7c2fa762 100644
--- a/gtk/src/makedeps.py
+++ b/gtk/src/makedeps.py
@@ -49,13 +49,25 @@ dep_map = (
DepEntry("VideoEncoder", "x264_tab", "x264", False, True),
DepEntry("VideoEncoder", "lavc_mpeg4_tab", "ffmpeg|ffmpeg2", False, True),
DepEntry("VideoEncoder", "Mp4iPodCompatible", "x264", False, False),
+ DepEntry("AudioTrackQualityEnable", "AudioTrackQuality", "FALSE", True, False),
+ DepEntry("AudioTrackQualityEnable", "AudioTrackQualityValue", "FALSE", True, False),
+ DepEntry("AudioTrackQualityEnable", "AudioBitrateLabel", "TRUE", True, False),
+ DepEntry("AudioTrackQualityEnable", "AudioBitrate", "TRUE", True, False),
+ DepEntry("AudioEncoderActual", "AudioTrackQualityEnable", "lame|vorbis", False, True),
+ DepEntry("AudioEncoderActual", "AudioTrackQuality", "lame|vorbis", False, True),
+ DepEntry("AudioEncoderActual", "AudioTrackQualityValue", "lame|vorbis", False, True),
+ DepEntry("AudioEncoderActual", "AudioBitrateLabel", "copy:mp3|copy:aac|copy:ac3|copy:dts|copy:dtshd", True, False),
DepEntry("AudioEncoderActual", "AudioBitrate", "copy:mp3|copy:aac|copy:ac3|copy:dts|copy:dtshd", True, False),
+ DepEntry("AudioEncoderActual", "AudioSamplerateLabel", "copy:mp3|copy:aac|copy:ac3|copy:dts|copy:dtshd", True, False),
DepEntry("AudioEncoderActual", "AudioSamplerate", "copy:mp3|copy:aac|copy:ac3|copy:dts|copy:dtshd", True, False),
+ DepEntry("AudioEncoderActual", "AudioMixdownLabel", "copy:mp3|copy:aac|copy:ac3|copy:dts|copy:dtshd", True, False),
DepEntry("AudioEncoderActual", "AudioMixdown", "copy:mp3|copy:aac|copy:ac3|copy:dts|copy:dtshd", True, False),
+ DepEntry("AudioEncoderActual", "AudioTrackDRCSliderLabel", "copy:mp3|copy:aac|copy:ac3|copy:dts|copy:dtshd", True, False),
DepEntry("AudioEncoderActual", "AudioTrackDRCSlider", "copy:mp3|copy:aac|copy:ac3|copy:dts|copy:dtshd", True, False),
- DepEntry("AudioEncoderActual", "drc_label", "copy:mp3|copy:aac|copy:ac3|copy:dts|copy:dtshd", True, False),
+ DepEntry("AudioEncoderActual", "AudioTrackDRCValue", "copy:mp3|copy:aac|copy:ac3|copy:dts|copy:dtshd", True, False),
+ DepEntry("AudioEncoderActual", "AudioTrackGainLabel", "copy:mp3|copy:aac|copy:ac3|copy:dts|copy:dtshd", True, False),
DepEntry("AudioEncoderActual", "AudioTrackGain", "copy:mp3|copy:aac|copy:ac3|copy:dts|copy:dtshd", True, False),
- DepEntry("AudioEncoderActual", "gain_label", "copy:mp3|copy:aac|copy:ac3|copy:dts|copy:dtshd", True, False),
+ DepEntry("AudioEncoderActual", "AudioTrackGainValue", "copy:mp3|copy:aac|copy:ac3|copy:dts|copy:dtshd", True, False),
DepEntry("AudioEncoder", "AudioAllowMP3Pass", "copy", False, False),
DepEntry("AudioEncoder", "AudioAllowAACPass", "copy", False, False),
DepEntry("AudioEncoder", "AudioAllowAC3Pass", "copy", False, False),
diff --git a/gtk/src/queuehandler.c b/gtk/src/queuehandler.c
index 6b934c14e..8769ad5b3 100644
--- a/gtk/src/queuehandler.c
+++ b/gtk/src/queuehandler.c
@@ -20,6 +20,7 @@
#include "values.h"
#include "callbacks.h"
#include "presets.h"
+#include "audiohandler.h"
#include "ghb-dvd.h"
G_MODULE_EXPORT void
@@ -400,7 +401,7 @@ add_to_queue_list(signal_user_data_t *ud, GValue *settings, GtkTreeIter *piter)
count = ghb_array_len(audio_list);
for (ii = 0; ii < count; ii++)
{
- gchar *bitrate, *samplerate, *track;
+ gchar *quality = NULL, *samplerate, *track;
const gchar *acodec, *mix;
GValue *asettings;
gdouble sr;
@@ -408,7 +409,19 @@ add_to_queue_list(signal_user_data_t *ud, GValue *settings, GtkTreeIter *piter)
asettings = ghb_array_get_nth(audio_list, ii);
acodec = ghb_settings_combo_option(asettings, "AudioEncoderActual");
- bitrate = ghb_settings_get_string(asettings, "AudioBitrate");
+ double q = ghb_settings_get_double(asettings, "AudioTrackQuality");
+ if (ghb_settings_get_boolean(asettings, "AudioTrackQualityEnable") &&
+ q >= 0)
+ {
+ int codec = ghb_settings_combo_int(asettings, "AudioEncoderActual");
+ quality = ghb_format_quality("Quality: ", codec, q);
+ }
+ else
+ {
+ const char *br;
+ br = ghb_settings_combo_option(asettings, "AudioBitrate");
+ quality = g_strdup_printf("Bitrate: %s", br);
+ }
sr = ghb_settings_get_double(asettings, "AudioSamplerate");
samplerate = ghb_settings_get_string(asettings, "AudioSamplerate");
if ((int)sr == 0)
@@ -429,10 +442,10 @@ add_to_queue_list(signal_user_data_t *ud, GValue *settings, GtkTreeIter *piter)
g_string_append_printf(str, "\t");
g_string_append_printf(str,
- "<small> %s, Encoder: %s, Mixdown: %s, SampleRate: %s, Bitrate: %s</small>\n",
- track, acodec, mix, samplerate, bitrate);
+ "<small> %s, Encoder: %s, Mixdown: %s, SampleRate: %s, %s</small>\n",
+ track, acodec, mix, samplerate, quality);
g_free(track);
- g_free(bitrate);
+ g_free(quality);
g_free(samplerate);
}
@@ -505,67 +518,6 @@ add_to_queue_list(signal_user_data_t *ud, GValue *settings, GtkTreeIter *piter)
g_free(preset);
}
-void
-audio_list_refresh(signal_user_data_t *ud)
-{
- GtkTreeView *treeview;
- GtkTreeIter iter;
- GtkListStore *store;
- gboolean done;
- gint row = 0;
- const GValue *audio_list;
-
- g_debug("ghb_audio_list_refresh ()");
- treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
- store = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
- if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter))
- {
- do
- {
- const gchar *track, *codec, *br, *sr, *mix;
- gchar *s_drc, *s_gain;
- gint itrack;
- gdouble drc, gain;
- GValue *asettings;
-
- audio_list = ghb_settings_get_value(ud->settings, "audio_list");
- if (row >= ghb_array_len(audio_list))
- return;
- asettings = ghb_array_get_nth(audio_list, row);
-
- track = ghb_settings_combo_option(asettings, "AudioTrack");
- itrack = ghb_settings_combo_int(asettings, "AudioTrack");
- codec = ghb_settings_combo_option(asettings, "AudioEncoderActual");
- br = ghb_settings_combo_option(asettings, "AudioBitrate");
- sr = ghb_settings_combo_option(asettings, "AudioSamplerate");
- mix = ghb_settings_combo_option(asettings, "AudioMixdown");
- gain = ghb_settings_get_double(asettings, "AudioTrackGain");
- s_gain = g_strdup_printf("%.fdB", gain);
-
- drc = ghb_settings_get_double(asettings, "AudioTrackDRCSlider");
- if (drc < 1.0)
- s_drc = g_strdup("Off");
- else
- s_drc = g_strdup_printf("%.1f", drc);
-
- gtk_list_store_set(GTK_LIST_STORE(store), &iter,
- // These are displayed in list
- 0, track,
- 1, codec,
- 2, br,
- 3, sr,
- 4, mix,
- 5, s_gain,
- 6, s_drc,
- -1);
- g_free(s_drc);
- g_free(s_gain);
- done = !gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter);
- row++;
- } while (!done);
- }
-}
-
static gboolean
validate_settings(signal_user_data_t *ud)
{
@@ -711,7 +663,7 @@ validate_settings(signal_user_data_t *ud)
{
return FALSE;
}
- audio_list_refresh(ud);
+ ghb_audio_list_refresh(ud);
return TRUE;
}
diff --git a/libhb/common.c b/libhb/common.c
index 5abc9b950..4620602a7 100644
--- a/libhb/common.c
+++ b/libhb/common.c
@@ -75,6 +75,7 @@ hb_encoder_t hb_audio_encoders[] =
{ "MP3 (lame)", "lame", HB_ACODEC_LAME, HB_MUX_MP4|HB_MUX_MKV },
{ "MP3 Passthru", "copy:mp3", HB_ACODEC_MP3_PASS, HB_MUX_MP4|HB_MUX_MKV },
{ "Vorbis (vorbis)", "vorbis", HB_ACODEC_VORBIS, HB_MUX_MKV },
+ { "FLAC (ffmpeg)", "ffflac", HB_ACODEC_FFFLAC, HB_MUX_MKV },
{ "Auto Passthru", "copy", HB_ACODEC_AUTO_PASS, HB_MUX_MP4|HB_MUX_MKV } };
int hb_audio_encoders_count = sizeof( hb_audio_encoders ) /
sizeof( hb_encoder_t );
@@ -211,6 +212,10 @@ int hb_find_closest_audio_bitrate(int bitrate)
int ii;
int result;
+ // Check if bitrate mode was disabled
+ if( bitrate <= 0 )
+ return bitrate;
+
// result is highest rate if none found during search.
// rate returned will always be <= rate asked for.
result = hb_audio_bitrates[0].rate;
@@ -262,8 +267,19 @@ void hb_get_audio_bitrate_limits(uint32_t codec, int samplerate, int mixdown, in
int channels;
channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(mixdown);
- switch (codec)
+ if( codec & HB_ACODEC_PASS_FLAG )
+ {
+ // Bitrates don't apply to "lossless" audio (Passthru, FLAC)
+ *low = *high = -1;
+ return;
+ }
+ switch( codec )
{
+ case HB_ACODEC_FFFLAC:
+ // Bitrates don't apply to "lossless" audio (Passthru, FLAC)
+ *high = *low = -1;
+ break;
+
case HB_ACODEC_AC3:
*low = 32 * channels;
if (samplerate > 24000)
@@ -432,6 +448,9 @@ int hb_get_default_audio_bitrate( uint32_t codec, int samplerate, int mixdown )
int bitrate, channels;
int sr_shift;
+ if( codec & HB_ACODEC_PASS_FLAG )
+ return -1;
+
channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(mixdown);
// Min bitrate is established such that we get good quality
@@ -440,6 +459,10 @@ int hb_get_default_audio_bitrate( uint32_t codec, int samplerate, int mixdown )
switch ( codec )
{
+ case HB_ACODEC_FFFLAC:
+ bitrate = -1;
+ sr_shift = 0;
+ break;
case HB_ACODEC_AC3:
if (channels == 1)
bitrate = 96;
@@ -453,12 +476,156 @@ int hb_get_default_audio_bitrate( uint32_t codec, int samplerate, int mixdown )
break;
default:
bitrate = channels * 80;
+ break;
}
bitrate >>= sr_shift;
bitrate = hb_get_best_audio_bitrate( codec, bitrate, samplerate, mixdown );
return bitrate;
}
+// Get limits and hints for the UIs.
+//
+// granularity sets the minimum step increments that should be used
+// (it's ok to round up to some nice multiple if you like)
+//
+// direction says whether 'low' limit is highest or lowest
+// quality (direction 0 == lowest value is worst quality)
+void hb_get_audio_quality_limits(uint32_t codec, float *low, float *high, float *granularity, int *direction)
+{
+ switch( codec )
+ {
+ case HB_ACODEC_LAME:
+ *direction = 1;
+ *granularity = 0.5;
+ *low = 0.;
+ *high = 10.0;
+ break;
+
+ case HB_ACODEC_VORBIS:
+ *direction = 0;
+ *granularity = 0.05;
+ *low = 0.;
+ *high = 1.0;
+ break;
+
+ case HB_ACODEC_CA_AAC:
+ *direction = 0;
+ *granularity = 9;
+ *low = 0.;
+ *high = 127.0;
+ break;
+
+ default:
+ *direction = 0;
+ *granularity = 1;
+ *low = *high = -1.;
+ break;
+ }
+}
+
+float hb_get_best_audio_quality( uint32_t codec, float quality)
+{
+ float low, high, granularity;
+ int direction;
+
+ hb_get_audio_quality_limits(codec, &low, &high, &granularity, &direction);
+ if (quality > high)
+ quality = high;
+ if (quality < low)
+ quality = low;
+ return quality;
+}
+
+float hb_get_default_audio_quality( uint32_t codec )
+{
+ float quality;
+ switch( codec )
+ {
+ case HB_ACODEC_LAME:
+ quality = 2.;
+ break;
+
+ case HB_ACODEC_VORBIS:
+ quality = .5;
+ break;
+
+ case HB_ACODEC_CA_AAC:
+ quality = 91.;
+ break;
+
+ default:
+ quality = -1.;
+ break;
+ }
+ return quality;
+}
+
+// Get limits and hints for the UIs.
+//
+// granularity sets the minimum step increments that should be used
+// (it's ok to round up to some nice multiple if you like)
+//
+// direction says whether 'low' limit is highest or lowest
+// compression level (direction 0 == lowest value is worst compression level)
+void hb_get_audio_compression_limits(uint32_t codec, float *low, float *high, float *granularity, int *direction)
+{
+ switch( codec )
+ {
+ case HB_ACODEC_FFFLAC:
+ *direction = 0;
+ *granularity = 1;
+ *high = 12;
+ *low = 0;
+ break;
+
+ case HB_ACODEC_LAME:
+ *direction = 1;
+ *granularity = 1;
+ *high = 9;
+ *low = 0;
+ break;
+
+ default:
+ *direction = 0;
+ *granularity = 1;
+ *low = *high = -1;
+ break;
+ }
+}
+
+float hb_get_best_audio_compression( uint32_t codec, float compression)
+{
+ float low, high, granularity;
+ int direction;
+
+ hb_get_audio_compression_limits( codec, &low, &high, &granularity, &direction );
+ if( compression > high )
+ compression = high;
+ if( compression < low )
+ compression = low;
+ return compression;
+}
+
+float hb_get_default_audio_compression( uint32_t codec )
+{
+ float compression;
+ switch( codec )
+ {
+ case HB_ACODEC_FFFLAC:
+ compression = 5;
+ break;
+
+ case HB_ACODEC_LAME:
+ compression = 2;
+ break;
+
+ default:
+ compression = -1;
+ break;
+ }
+ return compression;
+}
+
int hb_get_best_mixdown( uint32_t codec, int layout, int mixdown )
{
@@ -527,7 +694,7 @@ int hb_get_best_mixdown( uint32_t codec, int layout, int mixdown )
}
// return the best that is not greater than the requested mixdown
// 0 means the caller requested the best available mixdown
- if( best_mixdown > mixdown && mixdown != 0 )
+ if( best_mixdown > mixdown && mixdown > 0 )
best_mixdown = mixdown;
return best_mixdown;
@@ -539,6 +706,7 @@ int hb_get_default_mixdown( uint32_t codec, int layout )
switch (codec)
{
// the AC3 encoder defaults to the best mixdown up to 6-channel
+ case HB_ACODEC_FFFLAC:
case HB_ACODEC_AC3:
mixdown = HB_AMIXDOWN_6CH;
break;
@@ -1328,11 +1496,14 @@ void hb_audio_config_init(hb_audio_config_t * audiocfg)
/* Initalize some sensable defaults */
audiocfg->in.track = audiocfg->out.track = 0;
audiocfg->out.codec = HB_ACODEC_FAAC;
- audiocfg->out.bitrate = 128;
- audiocfg->out.samplerate = 44100;
- audiocfg->out.mixdown = HB_AMIXDOWN_DOLBYPLII;
+ audiocfg->out.bitrate = -1;
+ audiocfg->out.quality = -1;
+ audiocfg->out.compression_level = -1;
+ audiocfg->out.samplerate = -1;
+ audiocfg->out.mixdown = -1;
audiocfg->out.dynamic_range_compression = 0;
audiocfg->out.name = NULL;
+
}
/**********************************************************************
@@ -1386,6 +1557,8 @@ int hb_audio_add(const hb_job_t * job, const hb_audio_config_t * audiocfg)
audio->config.out.codec &= ~HB_ACODEC_PASS_FLAG;
audio->config.out.samplerate = audiocfg->out.samplerate;
audio->config.out.bitrate = audiocfg->out.bitrate;
+ audio->config.out.compression_level = audiocfg->out.compression_level;
+ audio->config.out.quality = audiocfg->out.quality;
audio->config.out.dynamic_range_compression = audiocfg->out.dynamic_range_compression;
audio->config.out.mixdown = audiocfg->out.mixdown;
audio->config.out.gain = audiocfg->out.gain;
diff --git a/libhb/common.h b/libhb/common.h
index 2d275978f..65e022880 100644
--- a/libhb/common.h
+++ b/libhb/common.h
@@ -172,6 +172,12 @@ int hb_find_closest_audio_bitrate(int bitrate);
void hb_get_audio_bitrate_limits(uint32_t codec, int samplerate, int mixdown, int *low, int *high);
int hb_get_best_audio_bitrate( uint32_t codec, int bitrate, int samplerate, int mixdown);
int hb_get_default_audio_bitrate( uint32_t codec, int samplerate, int mixdown );
+void hb_get_audio_quality_limits(uint32_t codec, float *low, float *high, float *granularity, int *direction);
+float hb_get_best_audio_quality( uint32_t codec, float quality);
+float hb_get_default_audio_quality( uint32_t codec );
+void hb_get_audio_compression_limits(uint32_t codec, float *low, float *high, float *granularity, int *direction);
+float hb_get_best_audio_compression( uint32_t codec, float compression);
+float hb_get_default_audio_compression( uint32_t codec );
/******************************************************************************
* hb_job_t: settings to be filled by the UI
@@ -332,7 +338,7 @@ struct hb_job_s
/* Audio starts here */
/* Audio Codecs */
-#define HB_ACODEC_MASK 0x000FFF00
+#define HB_ACODEC_MASK 0x001FFF00
#define HB_ACODEC_FAAC 0x00000100
#define HB_ACODEC_LAME 0x00000200
#define HB_ACODEC_VORBIS 0x00000400
@@ -345,7 +351,8 @@ struct hb_job_s
#define HB_ACODEC_FFMPEG 0x00020000
#define HB_ACODEC_DCA_HD 0x00040000
#define HB_ACODEC_MP3 0x00080000
-#define HB_ACODEC_FF_MASK 0x000f0000
+#define HB_ACODEC_FFFLAC 0x00100000
+#define HB_ACODEC_FF_MASK 0x001f0000
#define HB_ACODEC_PASS_FLAG 0x40000000
#define HB_ACODEC_PASS_MASK (HB_ACODEC_MP3 | HB_ACODEC_FFAAC | HB_ACODEC_DCA_HD | HB_ACODEC_AC3 | HB_ACODEC_DCA)
#define HB_ACODEC_AUTO_PASS (HB_ACODEC_PASS_MASK | HB_ACODEC_PASS_FLAG)
@@ -431,10 +438,12 @@ struct hb_audio_config_s
* HB_ACODEC_AC3 means pass-through, then bitrate and samplerate
* are ignored.
*/
- int samplerate; /* Output sample rate (Hz) */
- int samples_per_frame; /* Number of samples per frame */
- int bitrate; /* Output bitrate (kbps) */
- int mixdown; /* The mixdown format to be used for this audio track (see HB_AMIXDOWN_*) */
+ int samplerate; /* Output sample rate (Hz) */
+ int samples_per_frame; /* Number of samples per frame */
+ int bitrate; /* Output bitrate (kbps) */
+ float quality; /* Output quality */
+ float compression_level; /* Output compression level */
+ int mixdown; /* The mixdown format to be used for this audio track (see HB_AMIXDOWN_*) */
double dynamic_range_compression; /* Amount of DRC that gets applied to this track */
double gain; /* Gain in dB. negative is quieter */
char * name; /* Output track name */
diff --git a/libhb/encavcodecaudio.c b/libhb/encavcodecaudio.c
index 92d2e36d6..cf27f0405 100644
--- a/libhb/encavcodecaudio.c
+++ b/libhb/encavcodecaudio.c
@@ -95,7 +95,17 @@ static int encavcodecaInit( hb_work_object_t * w, hb_job_t * job )
break;
}
- context->bit_rate = audio->config.out.bitrate * 1000;
+ if( audio->config.out.bitrate > 0 )
+ context->bit_rate = audio->config.out.bitrate * 1000;
+ else if( audio->config.out.quality >= 0 )
+ {
+ context->global_quality = audio->config.out.quality * FF_QP2LAMBDA;
+ context->flags |= CODEC_FLAG_QSCALE;
+ }
+
+ if( audio->config.out.compression_level >= 0 )
+ context->compression_level = audio->config.out.compression_level;
+
context->sample_rate = audio->config.out.samplerate;
context->channels = pv->out_discrete_channels;
// Try to set format to float. Fallback to whatever is supported.
@@ -120,10 +130,10 @@ static int encavcodecaInit( hb_work_object_t * w, hb_job_t * job )
pv->list = hb_list_init();
- if ( w->codec_param == CODEC_ID_AAC && context->extradata )
+ if ( context->extradata )
{
- memcpy( w->config->aac.bytes, context->extradata, context->extradata_size );
- w->config->aac.length = context->extradata_size;
+ memcpy( w->config->extradata.bytes, context->extradata, context->extradata_size );
+ w->config->extradata.length = context->extradata_size;
}
return 0;
@@ -134,6 +144,19 @@ static int encavcodecaInit( hb_work_object_t * w, hb_job_t * job )
***********************************************************************
*
**********************************************************************/
+// Some encoders (e.g. flac) require a final NULL encode in order to
+// finalize things.
+static void Finalize( hb_work_object_t * w )
+{
+ hb_work_private_t * pv = w->private_data;
+ hb_buffer_t * buf = hb_buffer_init( pv->output_bytes );
+
+ // Finalize with NULL input needed by FLAC to generate md5sum
+ // in context extradata
+ avcodec_encode_audio( pv->context, buf->data, buf->alloc, NULL );
+ hb_buffer_close( &buf );
+}
+
static void encavcodecaClose( hb_work_object_t * w )
{
hb_work_private_t * pv = w->private_data;
@@ -142,6 +165,7 @@ static void encavcodecaClose( hb_work_object_t * w )
{
if( pv->context )
{
+ Finalize( w );
hb_deep_log( 2, "encavcodeca: closing libavcodec" );
if ( pv->context->codec )
avcodec_flush_buffers( pv->context );
@@ -238,6 +262,35 @@ static hb_buffer_t * Encode( hb_work_object_t * w )
return buf;
}
+static hb_buffer_t * Flush( hb_work_object_t * w )
+{
+ hb_work_private_t * pv = w->private_data;
+ hb_buffer_t *first, *buf, *last;
+
+ first = last = buf = Encode( w );
+ while( buf )
+ {
+ last = buf;
+ buf->next = Encode( w );
+ buf = buf->next;
+ }
+
+ if( last )
+ {
+ last->next = hb_buffer_init( pv->output_bytes );
+ buf = last->next;
+ }
+ else
+ {
+ first = buf = hb_buffer_init( pv->output_bytes );
+ }
+ // Finalize with NULL input needed by FLAC to generate md5sum
+ // in context extradata
+ avcodec_encode_audio( pv->context, buf->data, buf->alloc, NULL );
+ buf->size = 0;
+ return first;
+}
+
/***********************************************************************
* Work
***********************************************************************
@@ -252,9 +305,8 @@ static int encavcodecaWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
if ( in->size <= 0 )
{
/* EOF on input - send it downstream & say we're done */
- *buf_out = in;
- *buf_in = NULL;
- return HB_WORK_DONE;
+ *buf_out = Flush( w );
+ return HB_WORK_DONE;
}
if ( pv->context == NULL || pv->context->codec == NULL )
diff --git a/libhb/encfaac.c b/libhb/encfaac.c
index 0ab9124c8..36c69a24d 100644
--- a/libhb/encfaac.c
+++ b/libhb/encfaac.c
@@ -155,8 +155,8 @@ int encfaacInit( hb_work_object_t * w, hb_job_t * job )
*job->die = 1;
return 0;
}
- memcpy( w->config->aac.bytes, bytes, length );
- w->config->aac.length = length;
+ memcpy( w->config->extradata.bytes, bytes, length );
+ w->config->extradata.length = length;
free( bytes );
pv->list = hb_list_init();
diff --git a/libhb/enclame.c b/libhb/enclame.c
index 434aa185e..000e0cef5 100644
--- a/libhb/enclame.c
+++ b/libhb/enclame.c
@@ -51,8 +51,21 @@ int enclameInit( hb_work_object_t * w, hb_job_t * job )
pv->lame = lame_init();
// use ABR
lame_set_scale( pv->lame, 32768.0 );
- lame_set_VBR( pv->lame, vbr_abr );
- lame_set_VBR_mean_bitrate_kbps( pv->lame, audio->config.out.bitrate );
+ if( audio->config.out.compression_level >= 0 )
+ {
+ lame_set_quality( pv->lame, audio->config.out.compression_level );
+ }
+ if( audio->config.out.bitrate > 0 )
+ {
+ lame_set_VBR( pv->lame, vbr_abr );
+ lame_set_VBR_mean_bitrate_kbps( pv->lame, audio->config.out.bitrate );
+ }
+ else if( audio->config.out.quality >= 0 )
+ {
+ lame_set_brate( pv->lame, 0 );
+ lame_set_VBR( pv->lame, vbr_default );
+ lame_set_VBR_quality( pv->lame, audio->config.out.quality );
+ }
lame_set_in_samplerate( pv->lame, audio->config.out.samplerate );
lame_set_out_samplerate( pv->lame, audio->config.out.samplerate );
diff --git a/libhb/encvorbis.c b/libhb/encvorbis.c
index fc186e089..8ac2e1a58 100644
--- a/libhb/encvorbis.c
+++ b/libhb/encvorbis.c
@@ -56,16 +56,6 @@ int encvorbisInit( hb_work_object_t * w, hb_job_t * job )
hb_log( "encvorbis: opening libvorbis" );
- /* 28kbps/channel seems to be the minimum for 6ch vorbis. */
- int min_bitrate = 28 * pv->out_discrete_channels;
- if (pv->out_discrete_channels > 2 && audio->config.out.bitrate < min_bitrate)
- {
- hb_log( "encvorbis: Selected bitrate (%d kbps) too low for %d channel audio.", audio->config.out.bitrate, pv->out_discrete_channels);
- hb_log( "encvorbis: Resetting bitrate to %d kbps", min_bitrate);
- /* Naughty! We shouldn't modify the audio from here. */
- audio->config.out.bitrate = min_bitrate;
- }
-
/* init */
for( i = 0; i < 3; i++ )
{
@@ -74,12 +64,36 @@ int encvorbisInit( hb_work_object_t * w, hb_job_t * job )
memset( w->config->vorbis.headers[i], 0, sizeof( ogg_packet ) );
}
vorbis_info_init( &pv->vi );
- if( vorbis_encode_setup_managed( &pv->vi, pv->out_discrete_channels,
- audio->config.out.samplerate, -1, 1000 * audio->config.out.bitrate, -1 ) )
+
+ if( audio->config.out.bitrate > 0 )
{
- hb_error( "encvorbis: vorbis_encode_setup_managed failed.\n" );
- *job->die = 1;
- return 0;
+ /* 28kbps/channel seems to be the minimum for 6ch vorbis. */
+ int min_bitrate = 28 * pv->out_discrete_channels;
+ if (pv->out_discrete_channels > 2 && audio->config.out.bitrate < min_bitrate)
+ {
+ hb_log( "encvorbis: Selected bitrate (%d kbps) too low for %d channel audio.", audio->config.out.bitrate, pv->out_discrete_channels);
+ hb_log( "encvorbis: Resetting bitrate to %d kbps", min_bitrate);
+ /* Naughty! We shouldn't modify the audio from here. */
+ audio->config.out.bitrate = min_bitrate;
+ }
+
+ if( vorbis_encode_setup_managed( &pv->vi, pv->out_discrete_channels,
+ audio->config.out.samplerate, -1, 1000 * audio->config.out.bitrate, -1 ) )
+ {
+ hb_error( "encvorbis: vorbis_encode_setup_managed failed.\n" );
+ *job->die = 1;
+ return 0;
+ }
+ }
+ else if( audio->config.out.quality >= 0 )
+ {
+ if( vorbis_encode_setup_vbr( &pv->vi, pv->out_discrete_channels,
+ audio->config.out.samplerate, audio->config.out.quality ) )
+ {
+ hb_error( "encvorbis: vorbis_encode_setup_vbr failed.\n" );
+ *job->die = 1;
+ return 0;
+ }
}
if( vorbis_encode_ctl( &pv->vi, OV_ECTL_RATEMANAGE2_SET, NULL ) ||
diff --git a/libhb/internal.h b/libhb/internal.h
index 63220f5cb..be9144821 100644
--- a/libhb/internal.h
+++ b/libhb/internal.h
@@ -307,7 +307,7 @@ union hb_esconfig_u
{
uint8_t bytes[HB_CONFIG_MAX_SIZE];
int length;
- } aac;
+ } extradata;
struct
{
diff --git a/libhb/muxmkv.c b/libhb/muxmkv.c
index 2ec32139d..524ca9d0a 100644
--- a/libhb/muxmkv.c
+++ b/libhb/muxmkv.c
@@ -35,6 +35,19 @@ struct hb_mux_data_s
int sub_format;
};
+static uint8_t * create_flac_header( uint8_t *data, int size )
+{
+ uint8_t * out;
+ uint8_t header[8] = {
+ 0x66, 0x4C, 0x61, 0x43, 0x80, 0x00, 0x00, 0x22
+ };
+
+ out = malloc( size + 8 );
+ memcpy( out, header, 8 );
+ memcpy( out + 8, data, size );
+ return out;
+}
+
/**********************************************************************
* MKVInit
**********************************************************************
@@ -228,12 +241,22 @@ static int MKVInit( hb_mux_object_t * m )
track->codecPrivateSize = cp_size;
}
break;
+ case HB_ACODEC_FFFLAC:
+ if( audio->priv.config.extradata.bytes )
+ {
+ track->codecPrivate = create_flac_header(
+ audio->priv.config.extradata.bytes,
+ audio->priv.config.extradata.length );
+ track->codecPrivateSize = audio->priv.config.extradata.length + 8;
+ }
+ track->codecID = MK_ACODEC_FLAC;
+ break;
case HB_ACODEC_FAAC:
case HB_ACODEC_FFAAC:
case HB_ACODEC_CA_AAC:
case HB_ACODEC_CA_HAAC:
- track->codecPrivate = audio->priv.config.aac.bytes;
- track->codecPrivateSize = audio->priv.config.aac.length;
+ track->codecPrivate = audio->priv.config.extradata.bytes;
+ track->codecPrivateSize = audio->priv.config.extradata.length;
track->codecID = MK_ACODEC_AAC;
break;
default:
@@ -267,7 +290,8 @@ static int MKVInit( hb_mux_object_t * m )
}
// track->defaultDuration = job->arate * 1000;
mux_data->track = mk_createTrack(m->file, track);
- if (audio->config.out.codec == HB_ACODEC_VORBIS && track->codecPrivate != NULL)
+ if ( audio->config.out.codec == HB_ACODEC_VORBIS ||
+ audio->config.out.codec == HB_ACODEC_FFFLAC )
free(track->codecPrivate);
}
@@ -545,6 +569,37 @@ static int MKVEnd( hb_mux_object_t * m )
mk_createTagSimple( m->file, MK_TAG_GENRE, md->genre );
}
+ // Update and track private data that can change during
+ // encode.
+ int i;
+ for( i = 0; i < hb_list_count( title->list_audio ); i++ )
+ {
+ mk_Track * track;
+ hb_audio_t * audio;
+
+ audio = hb_list_item( title->list_audio, i );
+ track = audio->priv.mux_data->track;
+
+ switch (audio->config.out.codec & HB_ACODEC_MASK)
+ {
+ case HB_ACODEC_FFFLAC:
+ if( audio->priv.config.extradata.bytes )
+ {
+ uint8_t *header;
+ header = create_flac_header(
+ audio->priv.config.extradata.bytes,
+ audio->priv.config.extradata.length );
+ mk_updateTrackPrivateData( m->file, track,
+ header,
+ audio->priv.config.extradata.length + 8 );
+ free( header );
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
if( mk_close(m->file) < 0 )
{
hb_error( "Failed to flush the last frame and close the output file, Disk Full?" );
diff --git a/libhb/muxmp4.c b/libhb/muxmp4.c
index 8d93d361a..5234c5a7a 100644
--- a/libhb/muxmp4.c
+++ b/libhb/muxmp4.c
@@ -379,8 +379,8 @@ static int MP4Init( hb_mux_object_t * m )
case HB_ACODEC_DCA_HD:
case HB_ACODEC_DCA:
{
- uint8_t audio_type;
- int samplerate, samples_per_frame, channels, config_len;
+ uint8_t audio_type = MP4_MPEG4_AUDIO_TYPE;
+ int samplerate, samples_per_frame, channels, config_len = 0;
uint8_t *config_bytes = NULL;
switch ( audio->config.out.codec & HB_ACODEC_MASK )
@@ -391,8 +391,8 @@ static int MP4Init( hb_mux_object_t * m )
case HB_ACODEC_CA_HAAC:
{
audio_type = MP4_MPEG4_AUDIO_TYPE;
- config_bytes = audio->priv.config.aac.bytes;
- config_len = audio->priv.config.aac.length;
+ config_bytes = audio->priv.config.extradata.bytes;
+ config_len = audio->priv.config.extradata.length;
} break;
case HB_ACODEC_LAME:
case HB_ACODEC_MP3:
diff --git a/libhb/platform/macosx/encca_aac.c b/libhb/platform/macosx/encca_aac.c
index 35b737e79..35eee4a00 100644
--- a/libhb/platform/macosx/encca_aac.c
+++ b/libhb/platform/macosx/encca_aac.c
@@ -200,33 +200,58 @@ int encCoreAudioInit( hb_work_object_t * w, hb_job_t * job, enum AAC_MODE mode )
AudioConverterSetProperty( pv->converter, kAudioConverterCodecQuality,
sizeof( tmp ), &tmp );
- // set encoder bitrate control mode to constrained variable
- tmp = kAudioCodecBitRateControlMode_VariableConstrained;
- AudioConverterSetProperty( pv->converter, kAudioCodecPropertyBitRateControlMode,
- sizeof( tmp ), &tmp );
-
- // get available bitrates
- AudioValueRange *bitrates;
- ssize_t bitrateCounts;
- err = AudioConverterGetPropertyInfo( pv->converter, kAudioConverterApplicableEncodeBitRates,
- &tmpsiz, NULL);
- bitrates = malloc( tmpsiz );
- err = AudioConverterGetProperty( pv->converter, kAudioConverterApplicableEncodeBitRates,
- &tmpsiz, bitrates);
- bitrateCounts = tmpsiz / sizeof( AudioValueRange );
-
- // set bitrate
- tmp = audio->config.out.bitrate * 1000;
- if( tmp < bitrates[0].mMinimum )
- tmp = bitrates[0].mMinimum;
- if( tmp > bitrates[bitrateCounts-1].mMinimum )
- tmp = bitrates[bitrateCounts-1].mMinimum;
- free( bitrates );
- if( tmp != audio->config.out.bitrate * 1000 )
- hb_log( "encca_aac: sanitizing track %d audio bitrate %d to %"PRIu32"",
- audio->config.out.track, audio->config.out.bitrate, tmp/1000 );
- AudioConverterSetProperty( pv->converter, kAudioConverterEncodeBitRate,
- sizeof( tmp ), &tmp );
+ if( audio->config.out.bitrate > 0 )
+ {
+ // set encoder bitrate control mode to constrained variable
+ tmp = kAudioCodecBitRateControlMode_VariableConstrained;
+ AudioConverterSetProperty( pv->converter, kAudioCodecPropertyBitRateControlMode,
+ sizeof( tmp ), &tmp );
+
+ // get available bitrates
+ AudioValueRange *bitrates;
+ ssize_t bitrateCounts;
+ err = AudioConverterGetPropertyInfo( pv->converter, kAudioConverterApplicableEncodeBitRates,
+ &tmpsiz, NULL);
+ bitrates = malloc( tmpsiz );
+ err = AudioConverterGetProperty( pv->converter, kAudioConverterApplicableEncodeBitRates,
+ &tmpsiz, bitrates);
+ bitrateCounts = tmpsiz / sizeof( AudioValueRange );
+
+ // set bitrate
+ tmp = audio->config.out.bitrate * 1000;
+ if( tmp < bitrates[0].mMinimum )
+ tmp = bitrates[0].mMinimum;
+ if( tmp > bitrates[bitrateCounts-1].mMinimum )
+ tmp = bitrates[bitrateCounts-1].mMinimum;
+ free( bitrates );
+ if( tmp != audio->config.out.bitrate * 1000 )
+ hb_log( "encca_aac: sanitizing track %d audio bitrate %d to %"PRIu32"",
+ audio->config.out.track, audio->config.out.bitrate, tmp/1000 );
+ AudioConverterSetProperty( pv->converter, kAudioConverterEncodeBitRate,
+ sizeof( tmp ), &tmp );
+ }
+ else if( audio->config.out.quality >= 0 )
+ {
+ if( mode != AAC_MODE_LC )
+ {
+ hb_log( "encCoreAudioInit: internal error, VBR set but not applicable" );
+ return 1;
+ }
+ // set encoder bitrate control mode to variable
+ tmp = kAudioCodecBitRateControlMode_Variable;
+ AudioConverterSetProperty( pv->converter, kAudioCodecPropertyBitRateControlMode,
+ sizeof( tmp ), &tmp );
+
+ // set quality
+ tmp = audio->config.out.quality;
+ AudioConverterSetProperty( pv->converter, kAudioCodecPropertySoundQualityForVBR,
+ sizeof( tmp ), &tmp );
+ }
+ else
+ {
+ hb_log( "encCoreAudioInit: internal error, bitrate/quality not set" );
+ return 1;
+ }
// get real input
tmpsiz = sizeof( input );
@@ -272,14 +297,14 @@ int encCoreAudioInit( hb_work_object_t * w, hb_job_t * job, enum AAC_MODE mode )
tmp = HB_CONFIG_MAX_SIZE;
AudioConverterGetProperty( pv->converter,
kAudioConverterCompressionMagicCookie,
- &tmp, w->config->aac.bytes );
+ &tmp, w->config->extradata.bytes );
// CoreAudio returns a complete ESDS, but we only need
// the DecoderSpecific info.
UInt8* buffer = NULL;
- ReadESDSDescExt(w->config->aac.bytes, &buffer, &tmpsiz, 0);
- w->config->aac.length = tmpsiz;
- memmove( w->config->aac.bytes, buffer,
- w->config->aac.length );
+ ReadESDSDescExt(w->config->extradata.bytes, &buffer, &tmpsiz, 0);
+ w->config->extradata.length = tmpsiz;
+ memmove( w->config->extradata.bytes, buffer,
+ w->config->extradata.length );
pv->list = hb_list_init();
pv->buf = NULL;
diff --git a/libhb/stream.c b/libhb/stream.c
index f9200ef63..9f2775a4b 100644
--- a/libhb/stream.c
+++ b/libhb/stream.c
@@ -4923,8 +4923,8 @@ static void add_ffmpeg_audio( hb_title_t *title, hb_stream_t *stream, int id )
else if ( codec->codec_id == CODEC_ID_AAC )
{
int len = MIN(codec->extradata_size, HB_CONFIG_MAX_SIZE);
- memcpy(audio->priv.config.aac.bytes, codec->extradata, len);
- audio->priv.config.aac.length = len;
+ memcpy(audio->priv.config.extradata.bytes, codec->extradata, len);
+ audio->priv.config.extradata.length = len;
audio->config.in.codec = HB_ACODEC_FFAAC;
}
else if ( codec->codec_id == CODEC_ID_MP3 )
@@ -4948,6 +4948,7 @@ static void add_ffmpeg_audio( hb_title_t *title, hb_stream_t *stream, int id )
set_audio_description( stream, audio,
lang_for_code2( tag ? tag->value : "und" ) );
+ audio->config.in.track = id;
hb_list_add( title->list_audio, audio );
}
}
@@ -5127,6 +5128,7 @@ static void add_ffmpeg_subtitle( hb_title_t *title, hb_stream_t *stream, int id
memcpy( subtitle->extradata, codec->extradata, codec->extradata_size );
subtitle->extradata_size = codec->extradata_size;
+ subtitle->track = id;
hb_list_add(title->list_subtitle, subtitle);
}
diff --git a/libhb/work.c b/libhb/work.c
index d8cb7b919..ea05c098f 100644
--- a/libhb/work.c
+++ b/libhb/work.c
@@ -139,6 +139,12 @@ hb_work_object_t * hb_codec_encoder( int codec )
w->codec_param = CODEC_ID_AAC;
return w;
}
+ case HB_ACODEC_FFFLAC:
+ {
+ w = hb_get_work( WORK_ENCAVCODEC_AUDIO );
+ w->codec_param = CODEC_ID_FLAC;
+ return w;
+ }
case HB_ACODEC_AC3:
{
w = hb_get_work( WORK_ENCAVCODEC_AUDIO );
@@ -399,7 +405,15 @@ void hb_display_job_info( hb_job_t * job )
if( hb_audio_encoders[j].encoder == audio->config.out.codec )
{
hb_log( " + encoder: %s", hb_audio_encoders[j].human_readable_name );
- hb_log( " + bitrate: %d kbps, samplerate: %d Hz", audio->config.out.bitrate, audio->config.out.samplerate );
+ if( audio->config.out.bitrate > 0 )
+ hb_log( " + bitrate: %d kbps, samplerate: %d Hz", audio->config.out.bitrate, audio->config.out.samplerate );
+ else if( audio->config.out.quality >= 0 )
+ hb_log( " + quality: %.2f, samplerate: %d Hz", audio->config.out.quality, audio->config.out.samplerate );
+ else if( audio->config.out.samplerate > 0 )
+ hb_log( " + samplerate: %d Hz", audio->config.out.samplerate );
+ if( audio->config.out.compression_level >= 0 )
+ hb_log( " + compression level: %.2f",
+ audio->config.out.compression_level );
break;
}
}
@@ -558,19 +572,19 @@ static void do_job( hb_job_t * job )
free( audio );
continue;
}
- if( !(audio->config.out.codec & HB_ACODEC_PASS_FLAG) &&
- audio->config.out.samplerate > 48000 )
+ if( !(audio->config.out.codec & HB_ACODEC_PASS_FLAG) )
{
- hb_log( "Sample rate %d not supported. Down-sampling to 48kHz.",
- audio->config.out.samplerate );
- audio->config.out.samplerate = 48000;
- }
- if( audio->config.out.codec == HB_ACODEC_AC3 &&
- audio->config.out.bitrate > 640 )
- {
- hb_log( "Bitrate %d not supported. Reducing to 640Kbps.",
- audio->config.out.bitrate );
- audio->config.out.bitrate = 640;
+ if( audio->config.out.samplerate > 48000 )
+ {
+ hb_log( "Sample rate %d not supported. Down-sampling to 48kHz.",
+ audio->config.out.samplerate );
+ audio->config.out.samplerate = 48000;
+ }
+ // if not specified, set to same as input
+ if( audio->config.out.samplerate < 0 )
+ {
+ audio->config.out.samplerate = audio->config.in.samplerate;
+ }
}
if( audio->config.out.codec == HB_ACODEC_CA_HAAC )
{
@@ -598,20 +612,14 @@ static void do_job( hb_job_t * job )
int requested_mixdown = 0;
int requested_mixdown_index = 0;
int best_mixdown = 0;
- int requested_bitrate = 0;
int best_bitrate = 0;
for( i = 0; i < hb_list_count( title->list_audio ); i++ )
{
audio = hb_list_item( title->list_audio, i );
- best_mixdown = hb_get_best_mixdown( audio->config.out.codec,
- audio->config.in.channel_layout, 0 );
-
- /* sense-check the current mixdown options */
-
/* sense-check the requested mixdown */
- if( audio->config.out.mixdown == 0 &&
+ if( audio->config.out.mixdown <= 0 &&
!( audio->config.out.codec & HB_ACODEC_PASS_FLAG ) )
{
/*
@@ -639,12 +647,12 @@ static void do_job( hb_job_t * job )
}
}
- if ( !( audio->config.out.codec & HB_ACODEC_PASS_FLAG ) )
+ best_mixdown = hb_get_best_mixdown( audio->config.out.codec,
+ audio->config.in.channel_layout, 0 );
+
+ if ( audio->config.out.mixdown > best_mixdown )
{
- if ( audio->config.out.mixdown > best_mixdown )
- {
- audio->config.out.mixdown = best_mixdown;
- }
+ audio->config.out.mixdown = best_mixdown;
}
if ( audio->config.out.mixdown != requested_mixdown )
@@ -663,45 +671,99 @@ static void do_job( hb_job_t * job )
}
}
- /* sense-check the current bitrates */
-
- /* sense-check the requested bitrate */
- if( audio->config.out.bitrate == 0 &&
- !( audio->config.out.codec & HB_ACODEC_PASS_FLAG ) )
+ /* sense-check the requested compression level */
+ if( audio->config.out.compression_level < 0 )
{
- /*
- * Bitrate wasn't specified and this is not pass-through,
- * set a default bitrate
- */
- audio->config.out.bitrate = hb_get_default_audio_bitrate( audio->config.out.codec,
- audio->config.out.samplerate,
- audio->config.out.mixdown );
-
- hb_log( "work: bitrate not specified, track %d setting bitrate %d",
- audio->config.out.track, audio->config.out.bitrate );
+ audio->config.out.compression_level =
+ hb_get_default_audio_compression( audio->config.out.codec );
+ if( audio->config.out.compression_level >= 0 )
+ {
+ hb_log( "work: compression level not specified, track %d setting compression level %.2f",
+ audio->config.out.track, audio->config.out.compression_level );
+ }
+ }
+
+ if( audio->config.out.compression_level >= 0 )
+ {
+ float best_compression = hb_get_best_audio_compression(
+ audio->config.out.codec,
+ audio->config.out.compression_level );
+ if( best_compression != audio->config.out.compression_level )
+ {
+ if( best_compression == -1 )
+ {
+ hb_log( "work: compression levels not supported by codec" );
+ }
+ else
+ {
+ hb_log( "work: sanitizing track %d audio compression level %.2f to %.2f",
+ audio->config.out.track,
+ audio->config.out.compression_level,
+ best_compression );
+ }
+ audio->config.out.compression_level = best_compression;
+ }
}
- /* log the requested bitrate */
- requested_bitrate = audio->config.out.bitrate;
- best_bitrate = hb_get_best_audio_bitrate( audio->config.out.codec,
- audio->config.out.bitrate,
- audio->config.out.samplerate,
- audio->config.out.mixdown );
-
- if ( !( audio->config.out.codec & HB_ACODEC_PASS_FLAG ) )
+ /* sense-check the requested quality */
+ if( audio->config.out.quality >= 0 )
{
- if ( audio->config.out.bitrate != best_bitrate )
+ float best_quality = hb_get_best_audio_quality(
+ audio->config.out.codec, audio->config.out.quality );
+ if( best_quality != audio->config.out.quality )
{
- audio->config.out.bitrate = best_bitrate;
+ if( best_quality == -1.0 )
+ {
+ hb_log( "work: quality mode not supported by codec" );
+ }
+ else
+ {
+ hb_log( "work: sanitizing track %d audio quality %.2f to %.2f",
+ audio->config.out.track,
+ audio->config.out.quality,
+ best_quality );
+ }
+ audio->config.out.quality = best_quality;
}
}
- if ( audio->config.out.bitrate != requested_bitrate )
+ /* sense-check the requested bitrate */
+ if( audio->config.out.quality < 0 )
{
- /* log the output bitrate */
- hb_log( "work: sanitizing track %d audio bitrate %d to %d",
- audio->config.out.track, requested_bitrate,
- audio->config.out.bitrate);
+ if( audio->config.out.bitrate <= 0 )
+ {
+ /*
+ * Bitrate wasn't specified and this is not pass-through,
+ * set a default bitrate
+ */
+ audio->config.out.bitrate =
+ hb_get_default_audio_bitrate( audio->config.out.codec,
+ audio->config.out.samplerate,
+ audio->config.out.mixdown );
+
+ if( audio->config.out.bitrate > 0 )
+ {
+ hb_log( "work: bitrate not specified, track %d setting bitrate %d",
+ audio->config.out.track, audio->config.out.bitrate );
+ }
+ }
+
+ /* log the requested bitrate */
+ best_bitrate = hb_get_best_audio_bitrate( audio->config.out.codec,
+ audio->config.out.bitrate,
+ audio->config.out.samplerate,
+ audio->config.out.mixdown );
+
+ if ( audio->config.out.bitrate != best_bitrate &&
+ best_bitrate > 0 )
+ {
+ /* log the output bitrate */
+ hb_log( "work: sanitizing track %d audio bitrate %d to %d",
+ audio->config.out.track,
+ audio->config.out.bitrate,
+ best_bitrate );
+ }
+ audio->config.out.bitrate = best_bitrate;
}
if (audio->config.out.codec == HB_ACODEC_VORBIS)
diff --git a/macosx/Controller.m b/macosx/Controller.m
index 390a0e001..df7770c32 100644
--- a/macosx/Controller.m
+++ b/macosx/Controller.m
@@ -3781,6 +3781,7 @@ bool one_burned = FALSE;
audio->out.gain = [[queueToApply objectForKey: [prefix stringByAppendingString: @"TrackGainSlider"]] floatValue];
prefix = [NSString stringWithFormat: @"JobAudio%d", counter + 1];
audio->out.codec = [[queueToApply objectForKey: [prefix stringByAppendingString: @"Encoder"]] intValue];
+ audio->out.compression_level = hb_get_default_audio_compression(audio->out.codec);
audio->out.mixdown = [[queueToApply objectForKey: [prefix stringByAppendingString: @"Mixdown"]] intValue];
audio->out.bitrate = [[queueToApply objectForKey: [prefix stringByAppendingString: @"Bitrate"]] intValue];
audio->out.samplerate = [[queueToApply objectForKey: [prefix stringByAppendingString: @"Samplerate"]] intValue];
diff --git a/macosx/English.lproj/MainMenu.xib b/macosx/English.lproj/MainMenu.xib
index 6e9fb8a0c..0c0ea86c2 100644
--- a/macosx/English.lproj/MainMenu.xib
+++ b/macosx/English.lproj/MainMenu.xib
@@ -3,17 +3,46 @@
<data>
<int key="IBDocument.SystemTarget">1050</int>
<string key="IBDocument.SystemVersion">10K549</string>
- <string key="IBDocument.InterfaceBuilderVersion">851</string>
+ <string key="IBDocument.InterfaceBuilderVersion">1306</string>
<string key="IBDocument.AppKitVersion">1038.36</string>
<string key="IBDocument.HIToolboxVersion">461.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
- <string key="NS.object.0">851</string>
+ <string key="NS.object.0">1306</string>
</object>
- <object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
+ <object class="NSArray" key="IBDocument.IntegratedClassDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
- <integer value="1209"/>
- <integer value="2"/>
+ <string>NSTabView</string>
+ <string>NSScroller</string>
+ <string>NSMenu</string>
+ <string>NSSliderCell</string>
+ <string>NSButton</string>
+ <string>NSTableHeaderView</string>
+ <string>NSMatrix</string>
+ <string>NSCustomObject</string>
+ <string>NSArrayController</string>
+ <string>NSImageView</string>
+ <string>NSTableView</string>
+ <string>NSCustomView</string>
+ <string>NSSlider</string>
+ <string>NSImageCell</string>
+ <string>NSTextField</string>
+ <string>NSNumberFormatter</string>
+ <string>NSWindowTemplate</string>
+ <string>NSTextFieldCell</string>
+ <string>NSButtonCell</string>
+ <string>NSTableColumn</string>
+ <string>NSBox</string>
+ <string>NSView</string>
+ <string>NSOutlineView</string>
+ <string>NSPopUpButtonCell</string>
+ <string>NSScrollView</string>
+ <string>NSTabViewItem</string>
+ <string>NSProgressIndicator</string>
+ <string>NSUserDefaultsController</string>
+ <string>NSPopUpButton</string>
+ <string>NSMenuItem</string>
+ <string>NSDrawer</string>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -46,7 +75,6 @@
<object class="NSMutableString" key="NSViewClass">
<characters key="NS.bytes">View</characters>
</object>
- <string key="NSWindowContentMaxSize">{1.79769e+308, 1.79769e+308}</string>
<string key="NSWindowContentMinSize">{213, 107}</string>
<object class="NSView" key="NSWindowView" id="168918359">
<reference key="NSNextResponder"/>
@@ -58,6 +86,8 @@
<int key="NSvFlags">264</int>
<string key="NSFrame">{{18, 2}, {711, 28}}</string>
<reference key="NSSuperview" ref="168918359"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="1007421233"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="10523918">
<int key="NSCellFlags">67239424</int>
@@ -95,6 +125,8 @@
<object class="NSPSMatrix" key="NSDrawMatrix"/>
<string key="NSFrame">{{18, -26}, {930, 20}}</string>
<reference key="NSSuperview" ref="168918359"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView"/>
<int key="NSpiFlags">16396</int>
<double key="NSMaxValue">100</double>
</object>
@@ -103,6 +135,8 @@
<int key="NSvFlags">264</int>
<string key="NSFrame">{{13, 28}, {940, 343}}</string>
<reference key="NSSuperview" ref="168918359"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="738554558"/>
<object class="NSMutableArray" key="NSTabViewItems">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSTabViewItem" id="107038816">
@@ -256,9 +290,7 @@
<object class="NSArray" key="dict.sortedKeys" id="0">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
- <object class="NSMutableArray" key="dict.values">
- <bool key="EncodedWithXMLCoder">YES</bool>
- </object>
+ <reference key="dict.values" ref="0"/>
</object>
</object>
<object class="NSDecimalNumberPlaceholder" key="NS.min" id="464006568">
@@ -944,12 +976,16 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<int key="NSvFlags">256</int>
<string key="NSFrameSize">{884, 241}</string>
<reference key="NSSuperview" ref="528259747"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="794651271"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTableHeaderView" key="NSHeaderView" id="146611085">
<reference key="NSNextResponder" ref="230332532"/>
<int key="NSvFlags">256</int>
<string key="NSFrameSize">{884, 17}</string>
<reference key="NSSuperview" ref="230332532"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="528259747"/>
<reference key="NSTableView" ref="792464451"/>
</object>
<object class="_NSCornerView" key="NSCornerView" id="727606062">
@@ -957,6 +993,8 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<int key="NSvFlags">-2147483392</int>
<string key="NSFrame">{{-26, 0}, {16, 17}}</string>
<reference key="NSSuperview" ref="933946879"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="230332532"/>
</object>
<object class="NSMutableArray" key="NSTableColumns">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -1396,6 +1434,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
</object>
<string key="NSFrame">{{1, 17}, {884, 241}}</string>
<reference key="NSSuperview" ref="933946879"/>
+ <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="792464451"/>
<reference key="NSDocView" ref="792464451"/>
<reference key="NSBGColor" ref="355843302"/>
@@ -1406,6 +1445,8 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<int key="NSvFlags">-2147483392</int>
<string key="NSFrame">{{-100, -100}, {15, 206}}</string>
<reference key="NSSuperview" ref="933946879"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="821562152"/>
<reference key="NSTarget" ref="933946879"/>
<string key="NSAction">_doScroller:</string>
<double key="NSCurValue">37</double>
@@ -1416,6 +1457,8 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<int key="NSvFlags">-2147483392</int>
<string key="NSFrame">{{-100, -100}, {685, 15}}</string>
<reference key="NSSuperview" ref="933946879"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="727606062"/>
<int key="NSsFlags">1</int>
<reference key="NSTarget" ref="933946879"/>
<string key="NSAction">_doScroller:</string>
@@ -1430,6 +1473,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
</object>
<string key="NSFrame">{{1, 0}, {884, 17}}</string>
<reference key="NSSuperview" ref="933946879"/>
+ <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="146611085"/>
<reference key="NSDocView" ref="146611085"/>
<reference key="NSBGColor" ref="355843302"/>
@@ -1439,7 +1483,8 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
</object>
<string key="NSFrame">{{17, 17}, {886, 259}}</string>
<reference key="NSSuperview" ref="577274772"/>
- <reference key="NSNextKeyView" ref="528259747"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="496546489"/>
<int key="NSsFlags">530</int>
<reference key="NSVScroller" ref="496546489"/>
<reference key="NSHScroller" ref="821562152"/>
@@ -1453,6 +1498,8 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{16, 282}, {116, 16}}</string>
<reference key="NSSuperview" ref="577274772"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="933946879"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="327570663">
<int key="NSCellFlags">67239424</int>
@@ -1471,10 +1518,14 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
</object>
<string key="NSFrameSize">{920, 305}</string>
<reference key="NSSuperview" ref="738554558"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="883603583"/>
</object>
</object>
<string key="NSFrame">{{10, 25}, {920, 305}}</string>
<reference key="NSSuperview" ref="712502892"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="577274772"/>
</object>
<string key="NSLabel">Audio</string>
<reference key="NSColor" ref="242973447"/>
@@ -2075,7 +2126,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<int key="NSvFlags">256</int>
<string key="NSFrame">{{870, 17}, {15, 242}}</string>
<reference key="NSSuperview" ref="307620967"/>
- <reference key="NSNextKeyView" ref="712502892"/>
<reference key="NSTarget" ref="307620967"/>
<string key="NSAction">_doScroller:</string>
<double key="NSPercent">0.9736842</double>
@@ -2203,6 +2253,8 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{20, 530}, {45, 14}}</string>
<reference key="NSSuperview" ref="168918359"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="854767306"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="121574898">
<int key="NSCellFlags">67239424</int>
@@ -2223,6 +2275,8 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<int key="NSvFlags">264</int>
<string key="NSFrame">{{17, 501}, {35, 14}}</string>
<reference key="NSSuperview" ref="168918359"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="766125203"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="177567437">
<int key="NSCellFlags">67239424</int>
@@ -2239,6 +2293,8 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<int key="NSvFlags">264</int>
<string key="NSFrame">{{55, 501}, {323, 15}}</string>
<reference key="NSSuperview" ref="168918359"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="303369850"/>
<bool key="NSEnabled">YES</bool>
<object class="NSPopUpButtonCell" key="NSCell" id="821198683">
<int key="NSCellFlags">-2076049856</int>
@@ -2291,6 +2347,8 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<int key="NSvFlags">264</int>
<string key="NSFrame">{{483, 500}, {77, 15}}</string>
<reference key="NSSuperview" ref="168918359"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="971754180"/>
<bool key="NSEnabled">YES</bool>
<object class="NSPopUpButtonCell" key="NSCell" id="266952854">
<int key="NSCellFlags">-2076049856</int>
@@ -2328,6 +2386,8 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<int key="NSvFlags">264</int>
<string key="NSFrame">{{385, 498}, {46, 17}}</string>
<reference key="NSSuperview" ref="168918359"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="460320725"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="677126774">
<int key="NSCellFlags">67239424</int>
@@ -2344,6 +2404,8 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<int key="NSvFlags">264</int>
<string key="NSFrame">{{433, 500}, {41, 15}}</string>
<reference key="NSSuperview" ref="168918359"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="482831442"/>
<bool key="NSEnabled">YES</bool>
<object class="NSPopUpButtonCell" key="NSCell" id="567459641">
<int key="NSCellFlags">-2076049856</int>
@@ -2392,6 +2454,8 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<int key="NSvFlags">264</int>
<string key="NSFrame">{{5, 444}, {47, 17}}</string>
<reference key="NSSuperview" ref="168918359"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="186223550"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="834340599">
<int key="NSCellFlags">67239424</int>
@@ -2408,6 +2472,8 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<int key="NSvFlags">264</int>
<string key="NSFrame">{{751, 501}, {57, 14}}</string>
<reference key="NSSuperview" ref="168918359"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="955053416"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="1038625481">
<int key="NSCellFlags">67239424</int>
@@ -2424,6 +2490,8 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<int key="NSvFlags">264</int>
<string key="NSFrame">{{808, 501}, {79, 14}}</string>
<reference key="NSSuperview" ref="168918359"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="138115732"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="362196160">
<int key="NSCellFlags">67239424</int>
@@ -2443,6 +2511,8 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<int key="NSvFlags">264</int>
<string key="NSFrame">{{20, 476}, {70, 14}}</string>
<reference key="NSSuperview" ref="168918359"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="104002862"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="510160694">
<int key="NSCellFlags">67239424</int>
@@ -2459,6 +2529,8 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<int key="NSvFlags">264</int>
<string key="NSFrame">{{76, 388}, {177, 22}}</string>
<reference key="NSSuperview" ref="168918359"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="553453876"/>
<bool key="NSEnabled">YES</bool>
<object class="NSPopUpButtonCell" key="NSCell" id="264217237">
<int key="NSCellFlags">-2076049856</int>
@@ -2505,6 +2577,8 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<int key="NSvFlags">264</int>
<string key="NSFrame">{{755, 440}, {90, 28}}</string>
<reference key="NSSuperview" ref="168918359"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="35106907"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="295879492">
<int key="NSCellFlags">67239424</int>
@@ -2528,6 +2602,8 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<int key="NSvFlags">264</int>
<string key="NSFrame">{{98, 480}, {842, 5}}</string>
<reference key="NSSuperview" ref="168918359"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="1023408378"/>
<string key="NSOffsets">{0, 0}</string>
<object class="NSTextFieldCell" key="NSTitleCell">
<int key="NSCellFlags">67239424</int>
@@ -2550,6 +2626,8 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<int key="NSvFlags">264</int>
<string key="NSFrame">{{70, 530}, {309, 14}}</string>
<reference key="NSSuperview" ref="168918359"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="519699512"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="689580100">
<int key="NSCellFlags">69336641</int>
@@ -2569,6 +2647,8 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<int key="NSvFlags">264</int>
<string key="NSFrame">{{56, 445}, {684, 19}}</string>
<reference key="NSSuperview" ref="168918359"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="210289606"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="988599137">
<int key="NSCellFlags">-1804468671</int>
@@ -2586,6 +2666,8 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<int key="NSvFlags">264</int>
<string key="NSFrame">{{571, 485}, {54, 16}}</string>
<reference key="NSSuperview" ref="168918359"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="978025076"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="371961838">
<int key="NSCellFlags">-1804468671</int>
@@ -2603,6 +2685,8 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<int key="NSvFlags">264</int>
<string key="NSFrame">{{628, 485}, {54, 16}}</string>
<reference key="NSSuperview" ref="168918359"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="453345136"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="506346481">
<int key="NSCellFlags">-1804468671</int>
@@ -2620,6 +2704,8 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<int key="NSvFlags">264</int>
<string key="NSFrame">{{686, 485}, {54, 16}}</string>
<reference key="NSSuperview" ref="168918359"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="164276139"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="778187711">
<int key="NSCellFlags">-1804468671</int>
@@ -2637,6 +2723,8 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<int key="NSvFlags">264</int>
<string key="NSFrame">{{748, 485}, {54, 16}}</string>
<reference key="NSSuperview" ref="168918359"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="10346684"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="1039518079">
<int key="NSCellFlags">-1804468671</int>
@@ -2654,6 +2742,8 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<int key="NSvFlags">264</int>
<string key="NSFrame">{{20, 420}, {96, 14}}</string>
<reference key="NSSuperview" ref="168918359"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="574185541"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="293028864">
<int key="NSCellFlags">67239424</int>
@@ -2670,6 +2760,8 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<int key="NSvFlags">264</int>
<string key="NSFrame">{{294, 424}, {646, 5}}</string>
<reference key="NSSuperview" ref="168918359"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="87961628"/>
<string key="NSOffsets">{0, 0}</string>
<object class="NSTextFieldCell" key="NSTitleCell">
<int key="NSCellFlags">67239424</int>
@@ -2692,6 +2784,8 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<int key="NSvFlags">264</int>
<string key="NSFrame">{{124, 420}, {162, 14}}</string>
<reference key="NSSuperview" ref="168918359"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="151388399"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="488791842">
<int key="NSCellFlags">67239424</int>
@@ -2708,6 +2802,8 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<int key="NSvFlags">264</int>
<string key="NSFrame">{{731, 15}, {218, 14}}</string>
<reference key="NSSuperview" ref="168918359"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="222334056"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="224806210">
<int key="NSCellFlags">67239424</int>
@@ -2724,6 +2820,8 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<int key="NSvFlags">264</int>
<string key="NSFrame">{{21, 393}, {53, 14}}</string>
<reference key="NSSuperview" ref="168918359"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="732193996"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="51600927">
<int key="NSCellFlags">67239424</int>
@@ -2740,6 +2838,8 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{386, 533}, {554, 5}}</string>
<reference key="NSSuperview" ref="168918359"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="806469067"/>
<string key="NSOffsets">{0, 0}</string>
<object class="NSTextFieldCell" key="NSTitleCell">
<int key="NSCellFlags">67239424</int>
@@ -2763,6 +2863,8 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<object class="NSPSMatrix" key="NSDrawMatrix"/>
<string key="NSFrame">{{385, 532}, {562, 12}}</string>
<reference key="NSSuperview" ref="168918359"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="454206717"/>
<int key="NSpiFlags">16648</int>
<double key="NSMaxValue">100</double>
</object>
@@ -2771,6 +2873,8 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<int key="NSvFlags">264</int>
<string key="NSFrame">{{399, 391}, {141, 18}}</string>
<reference key="NSSuperview" ref="168918359"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="921877174"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="832863281">
<int key="NSCellFlags">67239424</int>
@@ -2793,6 +2897,8 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<int key="NSvFlags">264</int>
<string key="NSFrame">{{283, 391}, {102, 18}}</string>
<reference key="NSSuperview" ref="168918359"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="581806074"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="294332300">
<int key="NSCellFlags">67239424</int>
@@ -2815,6 +2921,8 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<int key="NSvFlags">264</int>
<string key="NSFrame">{{541, 391}, {141, 18}}</string>
<reference key="NSSuperview" ref="168918359"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="712502892"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="547085070">
<int key="NSCellFlags">67239424</int>
@@ -2837,6 +2945,8 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<int key="NSvFlags">264</int>
<string key="NSFrame">{{627, 500}, {56, 15}}</string>
<reference key="NSSuperview" ref="168918359"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="398989741"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="138681808">
<int key="NSCellFlags">67239424</int>
@@ -2853,6 +2963,8 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<int key="NSvFlags">264</int>
<string key="NSFrame">{{570, 500}, {57, 15}}</string>
<reference key="NSSuperview" ref="168918359"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="713493964"/>
<bool key="NSEnabled">YES</bool>
<object class="NSPopUpButtonCell" key="NSCell" id="286887304">
<int key="NSCellFlags">-2076049856</int>
@@ -2901,6 +3013,8 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<int key="NSvFlags">264</int>
<string key="NSFrame">{{685, 500}, {57, 15}}</string>
<reference key="NSSuperview" ref="168918359"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="19055068"/>
<bool key="NSEnabled">YES</bool>
<object class="NSPopUpButtonCell" key="NSCell" id="564669343">
<int key="NSCellFlags">-2076049856</int>
@@ -2945,12 +3059,14 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
</object>
</object>
</object>
- <string key="NSFrameSize">{959, 558}</string>
+ <string key="NSFrame">{{7, 11}, {959, 558}}</string>
<reference key="NSSuperview"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="586321835"/>
</object>
<string key="NSScreenRect">{{0, 0}, {1920, 1178}}</string>
<string key="NSMinSize">{213, 129}</string>
- <string key="NSMaxSize">{1.79769e+308, 1.79769e+308}</string>
+ <string key="NSMaxSize">{1e+13, 1e+13}</string>
</object>
<object class="NSMenu" id="840340181">
<string key="NSTitle">MainMenu</string>
@@ -3676,7 +3792,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<object class="NSMutableString" key="NSViewClass">
<characters key="NS.bytes">View</characters>
</object>
- <string key="NSWindowContentMaxSize">{1.79769e+308, 1.79769e+308}</string>
<string key="NSWindowContentMinSize">{213, 107}</string>
<object class="NSView" key="NSWindowView" id="168254512">
<nil key="NSNextResponder"/>
@@ -3761,7 +3876,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
</object>
<string key="NSScreenRect">{{0, 0}, {1920, 1178}}</string>
<string key="NSMinSize">{213, 129}</string>
- <string key="NSMaxSize">{1.79769e+308, 1.79769e+308}</string>
+ <string key="NSMaxSize">{1e+13, 1e+13}</string>
</object>
<object class="NSDrawer" id="972647787">
<nil key="NSNextResponder"/>
@@ -4029,7 +4144,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<object class="NSMutableString" key="NSViewClass">
<characters key="NS.bytes">View</characters>
</object>
- <string key="NSWindowContentMaxSize">{1.79769e+308, 1.79769e+308}</string>
<string key="NSWindowContentMinSize">{338, 232}</string>
<object class="NSView" key="NSWindowView" id="69290042">
<nil key="NSNextResponder"/>
@@ -4444,7 +4558,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
</object>
<string key="NSScreenRect">{{0, 0}, {1920, 1178}}</string>
<string key="NSMinSize">{338, 254}</string>
- <string key="NSMaxSize">{1.79769e+308, 1.79769e+308}</string>
+ <string key="NSMaxSize">{1e+13, 1e+13}</string>
</object>
<object class="NSWindowTemplate" id="687953568">
<int key="NSWindowStyleMask">1</int>
@@ -4458,7 +4572,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<object class="NSMutableString" key="NSViewClass">
<characters key="NS.bytes">View</characters>
</object>
- <string key="NSWindowContentMaxSize">{1.79769e+308, 1.79769e+308}</string>
<string key="NSWindowContentMinSize">{213, 107}</string>
<object class="NSView" key="NSWindowView" id="867624722">
<nil key="NSNextResponder"/>
@@ -4627,7 +4740,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
</object>
<string key="NSScreenRect">{{0, 0}, {1920, 1178}}</string>
<string key="NSMinSize">{213, 129}</string>
- <string key="NSMaxSize">{1.79769e+308, 1.79769e+308}</string>
+ <string key="NSMaxSize">{1e+13, 1e+13}</string>
</object>
<object class="NSCustomObject" id="2258723">
<string key="NSClassName">HBController</string>
@@ -4676,6 +4789,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<string>gain</string>
<string>PassThruEnabled</string>
<string>PassThruDisabled</string>
+ <string>bitrateEnabled</string>
</object>
<bool key="NSEditable">YES</bool>
<object class="_NSManagedProxy" key="_NSManagedProxy"/>
@@ -6152,22 +6266,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
</object>
<object class="IBConnectionRecord">
<object class="IBBindingConnection" key="connection">
- <string key="label">enabled: arrangedObjects.enabled</string>
- <reference key="source" ref="590927656"/>
- <reference key="destination" ref="141316080"/>
- <object class="NSNibBindingConnector" key="connector">
- <reference key="NSSource" ref="590927656"/>
- <reference key="NSDestination" ref="141316080"/>
- <string key="NSLabel">enabled: arrangedObjects.enabled</string>
- <string key="NSBinding">enabled</string>
- <string key="NSKeyPath">arrangedObjects.enabled</string>
- <int key="NSNibBindingConnectorVersion">2</int>
- </object>
- </object>
- <int key="connectionID">5776</int>
- </object>
- <object class="IBConnectionRecord">
- <object class="IBBindingConnection" key="connection">
<string key="label">enabled: arrangedObjects.mixdownEnabled</string>
<reference key="source" ref="1063255"/>
<reference key="destination" ref="141316080"/>
@@ -6184,22 +6282,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
</object>
<object class="IBConnectionRecord">
<object class="IBBindingConnection" key="connection">
- <string key="label">enabled: arrangedObjects.mixdownEnabled</string>
- <reference key="source" ref="596723553"/>
- <reference key="destination" ref="141316080"/>
- <object class="NSNibBindingConnector" key="connector">
- <reference key="NSSource" ref="596723553"/>
- <reference key="NSDestination" ref="141316080"/>
- <string key="NSLabel">enabled: arrangedObjects.mixdownEnabled</string>
- <string key="NSBinding">enabled</string>
- <string key="NSKeyPath">arrangedObjects.mixdownEnabled</string>
- <int key="NSNibBindingConnectorVersion">2</int>
- </object>
- </object>
- <int key="connectionID">5780</int>
- </object>
- <object class="IBConnectionRecord">
- <object class="IBBindingConnection" key="connection">
<string key="label">selectedObject: arrangedObjects.codec</string>
<reference key="source" ref="200958136"/>
<reference key="destination" ref="141316080"/>
@@ -6602,6 +6684,38 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
</object>
<int key="connectionID">5899</int>
</object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">enabled: arrangedObjects.mixdownEnabled</string>
+ <reference key="source" ref="590927656"/>
+ <reference key="destination" ref="141316080"/>
+ <object class="NSNibBindingConnector" key="connector">
+ <reference key="NSSource" ref="590927656"/>
+ <reference key="NSDestination" ref="141316080"/>
+ <string key="NSLabel">enabled: arrangedObjects.mixdownEnabled</string>
+ <string key="NSBinding">enabled</string>
+ <string key="NSKeyPath">arrangedObjects.mixdownEnabled</string>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">5901</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">enabled: arrangedObjects.bitrateEnabled</string>
+ <reference key="source" ref="596723553"/>
+ <reference key="destination" ref="141316080"/>
+ <object class="NSNibBindingConnector" key="connector">
+ <reference key="NSSource" ref="596723553"/>
+ <reference key="NSDestination" ref="141316080"/>
+ <string key="NSLabel">enabled: arrangedObjects.bitrateEnabled</string>
+ <string key="NSBinding">enabled</string>
+ <string key="NSKeyPath">arrangedObjects.bitrateEnabled</string>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">5903</int>
+ </object>
</object>
<object class="IBMutableOrderedSet" key="objectRecords">
<object class="NSArray" key="orderedObjects">
@@ -9669,10 +9783,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<string>1867.IBWindowTemplateEditedContentRect</string>
<string>1867.ImportedFromIB2</string>
<string>1867.editorWindowContentRectSynchronizationRect</string>
- <string>1867.windowTemplate.hasMaxSize</string>
- <string>1867.windowTemplate.hasMinSize</string>
- <string>1867.windowTemplate.maxSize</string>
- <string>1867.windowTemplate.minSize</string>
<string>1868.IBPluginDependency</string>
<string>1868.ImportedFromIB2</string>
<string>1870.IBPluginDependency</string>
@@ -9743,10 +9853,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<string>21.IBWindowTemplateEditedContentRect</string>
<string>21.ImportedFromIB2</string>
<string>21.editorWindowContentRectSynchronizationRect</string>
- <string>21.windowTemplate.hasMaxSize</string>
- <string>21.windowTemplate.hasMinSize</string>
- <string>21.windowTemplate.maxSize</string>
- <string>21.windowTemplate.minSize</string>
<string>2295.IBPluginDependency</string>
<string>2295.ImportedFromIB2</string>
<string>2361.IBPluginDependency</string>
@@ -9796,10 +9902,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<string>2701.IBWindowTemplateEditedContentRect</string>
<string>2701.ImportedFromIB2</string>
<string>2701.editorWindowContentRectSynchronizationRect</string>
- <string>2701.windowTemplate.hasMaxSize</string>
- <string>2701.windowTemplate.hasMinSize</string>
- <string>2701.windowTemplate.maxSize</string>
- <string>2701.windowTemplate.minSize</string>
<string>2702.IBPluginDependency</string>
<string>2702.ImportedFromIB2</string>
<string>2703.IBPluginDependency</string>
@@ -9855,10 +9957,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<string>434.IBWindowTemplateEditedContentRect</string>
<string>434.ImportedFromIB2</string>
<string>434.editorWindowContentRectSynchronizationRect</string>
- <string>434.windowTemplate.hasMaxSize</string>
- <string>434.windowTemplate.hasMinSize</string>
- <string>434.windowTemplate.maxSize</string>
- <string>434.windowTemplate.minSize</string>
<string>435.IBPluginDependency</string>
<string>435.ImportedFromIB2</string>
<string>436.IBPluginDependency</string>
@@ -10326,10 +10424,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<string>{{329, 373}, {338, 318}}</string>
<integer value="1"/>
<string>{{421, 536}, {338, 318}}</string>
- <boolean value="NO"/>
- <integer value="1"/>
- <string>{3.40282e+38, 3.40282e+38}</string>
- <string>{338, 232}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<integer value="1"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
@@ -10400,10 +10494,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<string>{{132, 289}, {959, 558}}</string>
<integer value="1"/>
<string>{{65, 541}, {760, 550}}</string>
- <boolean value="NO"/>
- <integer value="1"/>
- <string>{754, 556}</string>
- <string>{213, 107}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<integer value="1"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
@@ -10460,10 +10550,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<string>{{72, 712}, {392, 144}}</string>
<integer value="1"/>
<string>{{303, 988}, {392, 144}}</string>
- <boolean value="NO"/>
- <integer value="1"/>
- <string>{3.40282e+38, 3.40282e+38}</string>
- <string>{213, 107}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<integer value="1"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
@@ -10519,10 +10605,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<string>{{57, 766}, {300, 233}}</string>
<integer value="1"/>
<string>{{57, 766}, {300, 233}}</string>
- <boolean value="NO"/>
- <integer value="1"/>
- <string>{3.40282e+38, 3.40282e+38}</string>
- <string>{213, 107}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<integer value="1"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
@@ -10802,20 +10884,16 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<object class="NSMutableDictionary" key="unlocalizedProperties">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference key="dict.sortedKeys" ref="0"/>
- <object class="NSMutableArray" key="dict.values">
- <bool key="EncodedWithXMLCoder">YES</bool>
- </object>
+ <reference key="dict.values" ref="0"/>
</object>
<nil key="activeLocalization"/>
<object class="NSMutableDictionary" key="localizations">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference key="dict.sortedKeys" ref="0"/>
- <object class="NSMutableArray" key="dict.values">
- <bool key="EncodedWithXMLCoder">YES</bool>
- </object>
+ <reference key="dict.values" ref="0"/>
</object>
<nil key="sourceID"/>
- <int key="maxID">5899</int>
+ <int key="maxID">5903</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
@@ -10836,7 +10914,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
- <string key="minorKey">HBAudioController.h</string>
+ <string key="minorKey">./Classes/HBAudioController.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
@@ -10881,6 +10959,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<string>openHomepage:</string>
<string>openMainWindow:</string>
<string>openUserGuide:</string>
+ <string>presetSelected:</string>
<string>qualitySliderChanged:</string>
<string>revertPictureSizeToMax:</string>
<string>selectDefaultPreset:</string>
@@ -10894,6 +10973,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<string>showPreferencesWindow:</string>
<string>showPreviewWindow:</string>
<string>showQueueWindow:</string>
+ <string>showScanPanel:</string>
<string>showSourceTitleScanPanel:</string>
<string>startEndFrameValueChanged:</string>
<string>startEndSecValueChanged:</string>
@@ -10961,6 +11041,8 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<string>id</string>
<string>id</string>
<string>id</string>
+ <string>id</string>
+ <string>id</string>
</object>
</object>
<object class="NSMutableDictionary" key="actionInfosByName">
@@ -11002,6 +11084,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<string>openHomepage:</string>
<string>openMainWindow:</string>
<string>openUserGuide:</string>
+ <string>presetSelected:</string>
<string>qualitySliderChanged:</string>
<string>revertPictureSizeToMax:</string>
<string>selectDefaultPreset:</string>
@@ -11015,6 +11098,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<string>showPreferencesWindow:</string>
<string>showPreviewWindow:</string>
<string>showQueueWindow:</string>
+ <string>showScanPanel:</string>
<string>showSourceTitleScanPanel:</string>
<string>startEndFrameValueChanged:</string>
<string>startEndSecValueChanged:</string>
@@ -11167,6 +11251,10 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
+ <string key="name">presetSelected:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ <object class="IBActionInfo">
<string key="name">qualitySliderChanged:</string>
<string key="candidateClassName">id</string>
</object>
@@ -11219,6 +11307,10 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
+ <string key="name">showScanPanel:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ <object class="IBActionInfo">
<string key="name">showSourceTitleScanPanel:</string>
<string key="candidateClassName">id</string>
</object>
@@ -11276,6 +11368,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<string>fFramerateMatrix</string>
<string>fFramerateVfrPfrCell</string>
<string>fLoadChaptersButton</string>
+ <string>fOpenSourceTitleMMenu</string>
<string>fPictureCroppingField</string>
<string>fPictureSizeField</string>
<string>fPresetDrawer</string>
@@ -11338,6 +11431,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<string>fVidTwoPassCheck</string>
<string>fVideoFiltersField</string>
<string>fWindow</string>
+ <string>tableView</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -11361,6 +11455,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<string>NSMatrix</string>
<string>NSButtonCell</string>
<string>NSButton</string>
+ <string>NSMenuItem</string>
<string>NSTextField</string>
<string>NSTextField</string>
<string>NSDrawer</string>
@@ -11423,6 +11518,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<string>NSButton</string>
<string>NSTextField</string>
<string>NSWindow</string>
+ <string>NSTableView</string>
</object>
</object>
<object class="NSMutableDictionary" key="toOneOutletInfosByName">
@@ -11449,6 +11545,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<string>fFramerateMatrix</string>
<string>fFramerateVfrPfrCell</string>
<string>fLoadChaptersButton</string>
+ <string>fOpenSourceTitleMMenu</string>
<string>fPictureCroppingField</string>
<string>fPictureSizeField</string>
<string>fPresetDrawer</string>
@@ -11511,6 +11608,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<string>fVidTwoPassCheck</string>
<string>fVideoFiltersField</string>
<string>fWindow</string>
+ <string>tableView</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -11595,6 +11693,10 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<string key="candidateClassName">NSButton</string>
</object>
<object class="IBToOneOutletInfo">
+ <string key="name">fOpenSourceTitleMMenu</string>
+ <string key="candidateClassName">NSMenuItem</string>
+ </object>
+ <object class="IBToOneOutletInfo">
<string key="name">fPictureCroppingField</string>
<string key="candidateClassName">NSTextField</string>
</object>
@@ -11842,74 +11944,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<string key="name">fWindow</string>
<string key="candidateClassName">NSWindow</string>
</object>
- </object>
- </object>
- <object class="IBClassDescriptionSource" key="sourceIdentifier" id="896678678">
- <string key="majorKey">IBProjectSource</string>
- <string key="minorKey">Controller.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">HBController</string>
- <string key="superclassName">NSObject</string>
- <object class="NSMutableDictionary" key="actions">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="NSArray" key="dict.sortedKeys">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>presetSelected:</string>
- <string>showScanPanel:</string>
- </object>
- <object class="NSMutableArray" key="dict.values">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>id</string>
- <string>id</string>
- </object>
- </object>
- <object class="NSMutableDictionary" key="actionInfosByName">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="NSArray" key="dict.sortedKeys">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>presetSelected:</string>
- <string>showScanPanel:</string>
- </object>
- <object class="NSMutableArray" key="dict.values">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="IBActionInfo">
- <string key="name">presetSelected:</string>
- <string key="candidateClassName">id</string>
- </object>
- <object class="IBActionInfo">
- <string key="name">showScanPanel:</string>
- <string key="candidateClassName">id</string>
- </object>
- </object>
- </object>
- <object class="NSMutableDictionary" key="outlets">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="NSArray" key="dict.sortedKeys">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>fOpenSourceTitleMMenu</string>
- <string>tableView</string>
- </object>
- <object class="NSMutableArray" key="dict.values">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>NSMenuItem</string>
- <string>NSTableView</string>
- </object>
- </object>
- <object class="NSMutableDictionary" key="toOneOutletInfosByName">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="NSArray" key="dict.sortedKeys">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>fOpenSourceTitleMMenu</string>
- <string>tableView</string>
- </object>
- <object class="NSMutableArray" key="dict.values">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="IBToOneOutletInfo">
- <string key="name">fOpenSourceTitleMMenu</string>
- <string key="candidateClassName">NSMenuItem</string>
- </object>
<object class="IBToOneOutletInfo">
<string key="name">tableView</string>
<string key="candidateClassName">NSTableView</string>
@@ -11917,1103 +11951,17 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBUserSource</string>
- <string key="minorKey"/>
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">./Classes/HBController.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">HBPresetsOutlineView</string>
<string key="superclassName">NSOutlineView</string>
- <reference key="sourceIdentifier" ref="896678678"/>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBUserSource</string>
- <string key="minorKey"/>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">SUUpdater</string>
- <string key="superclassName">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBUserSource</string>
- <string key="minorKey"/>
- </object>
- </object>
- </object>
- <object class="NSMutableArray" key="referencedPartialClassDescriptionsV3.2+">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="IBPartialClassDescription">
- <string key="className">NSActionCell</string>
- <string key="superclassName">NSCell</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSActionCell.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSApplication</string>
- <string key="superclassName">NSResponder</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier" id="186343158">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSApplication.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSApplication</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier" id="994302592">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSApplicationScripting.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSApplication</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier" id="329150619">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSColorPanel.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSApplication</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSHelpManager.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSApplication</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSPageLayout.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSApplication</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSUserInterfaceItemSearching.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSArrayController</string>
- <string key="superclassName">NSObjectController</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSArrayController.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSBox</string>
- <string key="superclassName">NSView</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSBox.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSBrowser</string>
- <string key="superclassName">NSControl</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSBrowser.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSButton</string>
- <string key="superclassName">NSControl</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSButton.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSButtonCell</string>
- <string key="superclassName">NSActionCell</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSButtonCell.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSCell</string>
- <string key="superclassName">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSCell.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSControl</string>
- <string key="superclassName">NSView</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier" id="93521313">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSControl.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSController</string>
- <string key="superclassName">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSController.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSDrawer</string>
- <string key="superclassName">NSResponder</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier" id="255346542">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSDrawer.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSFormatter</string>
- <string key="superclassName">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Foundation.framework/Headers/NSFormatter.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSImageCell</string>
- <string key="superclassName">NSCell</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSImageCell.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSImageView</string>
- <string key="superclassName">NSControl</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSImageView.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSMatrix</string>
- <string key="superclassName">NSControl</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSMatrix.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSMenu</string>
- <string key="superclassName">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier" id="662939028">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSMenu.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSMenuItem</string>
- <string key="superclassName">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier" id="955768185">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSMenuItem.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSMenuItemCell</string>
- <string key="superclassName">NSButtonCell</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSMenuItemCell.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSMovieView</string>
- <string key="superclassName">NSView</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSMovieView.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSNumberFormatter</string>
- <string key="superclassName">NSFormatter</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Foundation.framework/Headers/NSNumberFormatter.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSAccessibility.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <reference key="sourceIdentifier" ref="186343158"/>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <reference key="sourceIdentifier" ref="994302592"/>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <reference key="sourceIdentifier" ref="329150619"/>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <reference key="sourceIdentifier" ref="93521313"/>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSDictionaryController.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSDragging.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSFontManager.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSFontPanel.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSKeyValueBinding.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <reference key="sourceIdentifier" ref="662939028"/>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSNibLoading.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier" id="474309511">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSOutlineView.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSPasteboard.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSSavePanel.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier" id="10931481">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSTableView.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSToolbarItem.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier" id="986196456">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSView.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Foundation.framework/Headers/NSArchiver.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Foundation.framework/Headers/NSClassDescription.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Foundation.framework/Headers/NSError.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Foundation.framework/Headers/NSFileManager.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Foundation.framework/Headers/NSKeyValueCoding.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Foundation.framework/Headers/NSKeyValueObserving.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Foundation.framework/Headers/NSKeyedArchiver.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Foundation.framework/Headers/NSObject.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Foundation.framework/Headers/NSObjectScripting.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Foundation.framework/Headers/NSPortCoder.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Foundation.framework/Headers/NSRunLoop.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Foundation.framework/Headers/NSScriptClassDescription.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Foundation.framework/Headers/NSScriptKeyValueCoding.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Foundation.framework/Headers/NSScriptObjectSpecifiers.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Foundation.framework/Headers/NSScriptWhoseTests.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Foundation.framework/Headers/NSThread.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Foundation.framework/Headers/NSURL.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Foundation.framework/Headers/NSURLConnection.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Foundation.framework/Headers/NSURLDownload.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Growl.framework/Headers/GrowlApplicationBridge.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">ImageKit.framework/Headers/IKImageBrowserView.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">ImageKit.framework/Headers/IKSaveOptions.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">ImageKit.framework/Headers/ImageKitDeprecated.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">PDFKit.framework/Headers/PDFDocument.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier" id="654570508">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">PDFKit.framework/Headers/PDFView.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">QTKit.framework/Headers/QTCaptureDecompressedAudioOutput.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">QTKit.framework/Headers/QTCaptureDecompressedVideoOutput.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">QTKit.framework/Headers/QTCaptureFileOutput.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">QTKit.framework/Headers/QTCaptureVideoPreviewOutput.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">QTKit.framework/Headers/QTCaptureView.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">QTKit.framework/Headers/QTMovie.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier" id="281869804">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">QTKit.framework/Headers/QTMovieView.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">QuartzComposer.framework/Headers/QCCompositionParameterView.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">QuartzComposer.framework/Headers/QCCompositionPickerView.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">QuartzFilters.framework/Headers/QuartzFilterManager.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">QuickLookUI.framework/Headers/QLPreviewPanel.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Sparkle.framework/Headers/SUAppcast.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier" id="675455814">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Sparkle.framework/Headers/SUUpdater.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObjectController</string>
- <string key="superclassName">NSController</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSObjectController.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSOutlineView</string>
- <string key="superclassName">NSTableView</string>
- <reference key="sourceIdentifier" ref="474309511"/>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSPanel</string>
- <string key="superclassName">NSWindow</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSPanel.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSPopUpButton</string>
- <string key="superclassName">NSButton</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSPopUpButton.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSPopUpButtonCell</string>
- <string key="superclassName">NSMenuItemCell</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSPopUpButtonCell.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSProgressIndicator</string>
- <string key="superclassName">NSView</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSProgressIndicator.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSResponder</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSInterfaceStyle.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSResponder</string>
- <string key="superclassName">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSResponder.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSScrollView</string>
- <string key="superclassName">NSView</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSScrollView.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSScroller</string>
- <string key="superclassName">NSControl</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSScroller.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSSlider</string>
- <string key="superclassName">NSControl</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSSlider.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSSliderCell</string>
- <string key="superclassName">NSActionCell</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSSliderCell.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSTabView</string>
- <string key="superclassName">NSView</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSTabView.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSTabViewItem</string>
- <string key="superclassName">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSTabViewItem.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSTableColumn</string>
- <string key="superclassName">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSTableColumn.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSTableHeaderView</string>
- <string key="superclassName">NSView</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSTableHeaderView.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSTableView</string>
- <string key="superclassName">NSControl</string>
- <reference key="sourceIdentifier" ref="10931481"/>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSText</string>
- <string key="superclassName">NSView</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSText.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSTextField</string>
- <string key="superclassName">NSControl</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSTextField.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSTextFieldCell</string>
- <string key="superclassName">NSActionCell</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSTextFieldCell.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSUserDefaultsController</string>
- <string key="superclassName">NSController</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSUserDefaultsController.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSView</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSClipView.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSView</string>
- <reference key="sourceIdentifier" ref="955768185"/>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSView</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSRulerView.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSView</string>
- <string key="superclassName">NSResponder</string>
- <reference key="sourceIdentifier" ref="986196456"/>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSWindow</string>
- <reference key="sourceIdentifier" ref="255346542"/>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSWindow</string>
- <string key="superclassName">NSResponder</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSWindow.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSWindow</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSWindowScripting.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">PDFView</string>
- <string key="superclassName">NSView</string>
- <object class="NSMutableDictionary" key="actions">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="NSArray" key="dict.sortedKeys">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>goBack:</string>
- <string>goForward:</string>
- <string>goToFirstPage:</string>
- <string>goToLastPage:</string>
- <string>goToNextPage:</string>
- <string>goToPreviousPage:</string>
- <string>selectAll:</string>
- <string>takeBackgroundColorFrom:</string>
- <string>zoomIn:</string>
- <string>zoomOut:</string>
- </object>
- <object class="NSMutableArray" key="dict.values">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>id</string>
- <string>id</string>
- <string>id</string>
- <string>id</string>
- <string>id</string>
- <string>id</string>
- <string>id</string>
- <string>id</string>
- <string>id</string>
- <string>id</string>
- </object>
- </object>
- <object class="NSMutableDictionary" key="actionInfosByName">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="NSArray" key="dict.sortedKeys">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>goBack:</string>
- <string>goForward:</string>
- <string>goToFirstPage:</string>
- <string>goToLastPage:</string>
- <string>goToNextPage:</string>
- <string>goToPreviousPage:</string>
- <string>selectAll:</string>
- <string>takeBackgroundColorFrom:</string>
- <string>zoomIn:</string>
- <string>zoomOut:</string>
- </object>
- <object class="NSMutableArray" key="dict.values">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="IBActionInfo">
- <string key="name">goBack:</string>
- <string key="candidateClassName">id</string>
- </object>
- <object class="IBActionInfo">
- <string key="name">goForward:</string>
- <string key="candidateClassName">id</string>
- </object>
- <object class="IBActionInfo">
- <string key="name">goToFirstPage:</string>
- <string key="candidateClassName">id</string>
- </object>
- <object class="IBActionInfo">
- <string key="name">goToLastPage:</string>
- <string key="candidateClassName">id</string>
- </object>
- <object class="IBActionInfo">
- <string key="name">goToNextPage:</string>
- <string key="candidateClassName">id</string>
- </object>
- <object class="IBActionInfo">
- <string key="name">goToPreviousPage:</string>
- <string key="candidateClassName">id</string>
- </object>
- <object class="IBActionInfo">
- <string key="name">selectAll:</string>
- <string key="candidateClassName">id</string>
- </object>
- <object class="IBActionInfo">
- <string key="name">takeBackgroundColorFrom:</string>
- <string key="candidateClassName">id</string>
- </object>
- <object class="IBActionInfo">
- <string key="name">zoomIn:</string>
- <string key="candidateClassName">id</string>
- </object>
- <object class="IBActionInfo">
- <string key="name">zoomOut:</string>
- <string key="candidateClassName">id</string>
- </object>
- </object>
- </object>
- <reference key="sourceIdentifier" ref="654570508"/>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">QCView</string>
- <string key="superclassName">NSView</string>
- <object class="NSMutableDictionary" key="actions">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="NSArray" key="dict.sortedKeys">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>play:</string>
- <string>start:</string>
- <string>stop:</string>
- </object>
- <object class="NSMutableArray" key="dict.values">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>id</string>
- <string>id</string>
- <string>id</string>
- </object>
- </object>
- <object class="NSMutableDictionary" key="actionInfosByName">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="NSArray" key="dict.sortedKeys">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>play:</string>
- <string>start:</string>
- <string>stop:</string>
- </object>
- <object class="NSMutableArray" key="dict.values">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="IBActionInfo">
- <string key="name">play:</string>
- <string key="candidateClassName">id</string>
- </object>
- <object class="IBActionInfo">
- <string key="name">start:</string>
- <string key="candidateClassName">id</string>
- </object>
- <object class="IBActionInfo">
- <string key="name">stop:</string>
- <string key="candidateClassName">id</string>
- </object>
- </object>
- </object>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">QuartzComposer.framework/Headers/QCView.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">QTMovieView</string>
- <string key="superclassName">NSView</string>
- <object class="NSMutableDictionary" key="actions">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="NSArray" key="dict.sortedKeys">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>add:</string>
- <string>addScaled:</string>
- <string>copy:</string>
- <string>cut:</string>
- <string>delete:</string>
- <string>gotoBeginning:</string>
- <string>gotoEnd:</string>
- <string>gotoNextSelectionPoint:</string>
- <string>gotoPosterFrame:</string>
- <string>gotoPreviousSelectionPoint:</string>
- <string>paste:</string>
- <string>pause:</string>
- <string>play:</string>
- <string>replace:</string>
- <string>selectAll:</string>
- <string>selectNone:</string>
- <string>stepBackward:</string>
- <string>stepForward:</string>
- <string>trim:</string>
- </object>
- <object class="NSMutableArray" key="dict.values">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>id</string>
- <string>id</string>
- <string>id</string>
- <string>id</string>
- <string>id</string>
- <string>id</string>
- <string>id</string>
- <string>id</string>
- <string>id</string>
- <string>id</string>
- <string>id</string>
- <string>id</string>
- <string>id</string>
- <string>id</string>
- <string>id</string>
- <string>id</string>
- <string>id</string>
- <string>id</string>
- <string>id</string>
- </object>
- </object>
- <object class="NSMutableDictionary" key="actionInfosByName">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="NSArray" key="dict.sortedKeys">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>add:</string>
- <string>addScaled:</string>
- <string>copy:</string>
- <string>cut:</string>
- <string>delete:</string>
- <string>gotoBeginning:</string>
- <string>gotoEnd:</string>
- <string>gotoNextSelectionPoint:</string>
- <string>gotoPosterFrame:</string>
- <string>gotoPreviousSelectionPoint:</string>
- <string>paste:</string>
- <string>pause:</string>
- <string>play:</string>
- <string>replace:</string>
- <string>selectAll:</string>
- <string>selectNone:</string>
- <string>stepBackward:</string>
- <string>stepForward:</string>
- <string>trim:</string>
- </object>
- <object class="NSMutableArray" key="dict.values">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="IBActionInfo">
- <string key="name">add:</string>
- <string key="candidateClassName">id</string>
- </object>
- <object class="IBActionInfo">
- <string key="name">addScaled:</string>
- <string key="candidateClassName">id</string>
- </object>
- <object class="IBActionInfo">
- <string key="name">copy:</string>
- <string key="candidateClassName">id</string>
- </object>
- <object class="IBActionInfo">
- <string key="name">cut:</string>
- <string key="candidateClassName">id</string>
- </object>
- <object class="IBActionInfo">
- <string key="name">delete:</string>
- <string key="candidateClassName">id</string>
- </object>
- <object class="IBActionInfo">
- <string key="name">gotoBeginning:</string>
- <string key="candidateClassName">id</string>
- </object>
- <object class="IBActionInfo">
- <string key="name">gotoEnd:</string>
- <string key="candidateClassName">id</string>
- </object>
- <object class="IBActionInfo">
- <string key="name">gotoNextSelectionPoint:</string>
- <string key="candidateClassName">id</string>
- </object>
- <object class="IBActionInfo">
- <string key="name">gotoPosterFrame:</string>
- <string key="candidateClassName">id</string>
- </object>
- <object class="IBActionInfo">
- <string key="name">gotoPreviousSelectionPoint:</string>
- <string key="candidateClassName">id</string>
- </object>
- <object class="IBActionInfo">
- <string key="name">paste:</string>
- <string key="candidateClassName">id</string>
- </object>
- <object class="IBActionInfo">
- <string key="name">pause:</string>
- <string key="candidateClassName">id</string>
- </object>
- <object class="IBActionInfo">
- <string key="name">play:</string>
- <string key="candidateClassName">id</string>
- </object>
- <object class="IBActionInfo">
- <string key="name">replace:</string>
- <string key="candidateClassName">id</string>
- </object>
- <object class="IBActionInfo">
- <string key="name">selectAll:</string>
- <string key="candidateClassName">id</string>
- </object>
- <object class="IBActionInfo">
- <string key="name">selectNone:</string>
- <string key="candidateClassName">id</string>
- </object>
- <object class="IBActionInfo">
- <string key="name">stepBackward:</string>
- <string key="candidateClassName">id</string>
- </object>
- <object class="IBActionInfo">
- <string key="name">stepForward:</string>
- <string key="candidateClassName">id</string>
- </object>
- <object class="IBActionInfo">
- <string key="name">trim:</string>
- <string key="candidateClassName">id</string>
- </object>
- </object>
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">./Classes/HBPresetsOutlineView.h</string>
</object>
- <reference key="sourceIdentifier" ref="281869804"/>
</object>
<object class="IBPartialClassDescription">
<string key="className">SUUpdater</string>
@@ -13040,7 +11988,10 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<string key="candidateClassName">id</string>
</object>
</object>
- <reference key="sourceIdentifier" ref="675455814"/>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">./Classes/SUUpdater.h</string>
+ </object>
</object>
</object>
</object>
@@ -13055,7 +12006,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<integer value="3000" key="NS.object.0"/>
</object>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
- <string key="IBDocument.LastKnownRelativeProjectPath">../HandBrake.xcodeproj</string>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
<object class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
<bool key="EncodedWithXMLCoder">YES</bool>
diff --git a/macosx/HBAudio.m b/macosx/HBAudio.m
index 10522b3d3..6b9c7a558 100644
--- a/macosx/HBAudio.m
+++ b/macosx/HBAudio.m
@@ -274,7 +274,8 @@ static NSMutableArray *masterBitRateArray = nil;
// Select the proper one
if (shouldSetDefault)
{
- [self setMixdown: [permittedMixdowns dictionaryWithObject: [NSNumber numberWithInt: theDefaultMixdown] matchingKey: keyAudioMixdown]];
+ [self setMixdown: [permittedMixdowns dictionaryWithObject: [NSNumber numberWithInt: theDefaultMixdown]
+ matchingKey: keyAudioMixdown]];
}
if (![self mixdown] || ![permittedMixdowns containsObject: [self mixdown]])
@@ -295,7 +296,6 @@ static NSMutableArray *masterBitRateArray = nil;
unsigned int count = [masterBitRateArray count];
int trackInputBitRate = [[[self track] objectForKey: keyAudioInputBitrate] intValue];
- BOOL limitsToTrackInputBitRate = ([[codec objectForKey: keyAudioCodec] intValue] & HB_ACODEC_PASS_FLAG) ? YES : NO;
int theSampleRate = [[[self sampleRate] objectForKey: keyAudioSamplerate] intValue];
if (0 == theSampleRate) // this means Auto
@@ -308,45 +308,46 @@ static NSMutableArray *masterBitRateArray = nil;
hb_get_audio_bitrate_limits(ourCodec, theSampleRate, ourMixdown, &minBitRate, &maxBitRate);
int theDefaultBitRate = hb_get_default_audio_bitrate(ourCodec, theSampleRate, ourMixdown);
- for (unsigned int i = 0; i < count; i++)
- {
- dict = [masterBitRateArray objectAtIndex: i];
- currentBitRate = [[dict objectForKey: keyAudioBitrate] intValue];
-
- // First ensure the bitrate falls within range of the codec
- shouldAdd = (currentBitRate >= minBitRate && currentBitRate <= maxBitRate);
+ BOOL codecIsPassthru = ([[codec objectForKey: keyAudioCodec] intValue] & HB_ACODEC_PASS_FLAG) ? YES : NO;
+ BOOL codecIsLossless = (theDefaultBitRate == -1) ? YES : NO;
- // Now make sure the mixdown is not limiting us to the track input bitrate
- if (shouldAdd && limitsToTrackInputBitRate)
- {
- if (currentBitRate != trackInputBitRate)
- {
- shouldAdd = NO;
- }
- }
-
- if (shouldAdd)
+ if (codecIsPassthru)
+ {
+ NSDictionary *sourceBitRate = [masterBitRateArray dictionaryWithObject: [NSNumber numberWithInt: trackInputBitRate]
+ matchingKey: keyAudioBitrate];
+ if (!sourceBitRate)
{
- [permittedBitRates addObject: dict];
+ // the source bitrate isn't in the master array - create it
+ sourceBitRate = [NSDictionary dictionaryWithObjectsAndKeys:
+ [NSString stringWithFormat: @"%d", trackInputBitRate], keyAudioBitrateName,
+ [NSNumber numberWithInt: trackInputBitRate], keyAudioBitrate,
+ nil];
}
+ [permittedBitRates addObject: sourceBitRate];
}
-
- // There is a situation where we have a mixdown requirement to match the track input bit rate,
- // but it does not fall into the range the codec supports. Therefore, we force it here.
- if (limitsToTrackInputBitRate && 0 == [permittedBitRates count])
+ else if (codecIsLossless)
{
- NSDictionary *missingBitRate = [masterBitRateArray dictionaryWithObject: [NSNumber numberWithInt: trackInputBitRate] matchingKey: keyAudioBitrate];
- if (!missingBitRate)
+ NSDictionary *bitRateNotApplicable = [NSDictionary dictionaryWithObjectsAndKeys:
+ [NSString stringWithString: @"N/A"], keyAudioBitrateName,
+ [NSNumber numberWithInt: -1], keyAudioBitrate,
+ nil];
+ [permittedBitRates addObject: bitRateNotApplicable];
+ }
+ else
+ {
+ for (unsigned int i = 0; i < count; i++)
{
- // We are in an even worse situation where the requested bit rate does not even exist in the underlying
- // library of supported bitrates. Of course since this value is ignored we can freely make a bogus one
- // for the UI just to make the user a little more aware.
- missingBitRate = [NSDictionary dictionaryWithObjectsAndKeys:
- [NSString stringWithFormat: @"%d", trackInputBitRate], keyAudioBitrateName,
- [NSNumber numberWithInt: trackInputBitRate], keyAudioBitrate,
- nil];
+ dict = [masterBitRateArray objectAtIndex: i];
+ currentBitRate = [[dict objectForKey: keyAudioBitrate] intValue];
+
+ // First ensure the bitrate falls within range of the codec
+ shouldAdd = (currentBitRate >= minBitRate && currentBitRate <= maxBitRate);
+
+ if (shouldAdd)
+ {
+ [permittedBitRates addObject: dict];
+ }
}
- [permittedBitRates addObject: missingBitRate];
}
if (![self enabled])
@@ -479,7 +480,8 @@ static NSMutableArray *masterBitRateArray = nil;
- (void) setTrackFromIndex: (int) aValue
{
- [self setTrack: [self.controller.masterTrackArray dictionaryWithObject: [NSNumber numberWithInt: aValue] matchingKey: keyAudioTrackIndex]];
+ [self setTrack: [self.controller.masterTrackArray dictionaryWithObject: [NSNumber numberWithInt: aValue]
+ matchingKey: keyAudioTrackIndex]];
}
// This returns whether it is able to set the actual codec desired.
@@ -594,12 +596,29 @@ static NSMutableArray *masterBitRateArray = nil;
return retval;
}
+- (BOOL) bitrateEnabled
+
+{
+ BOOL retval = [self enabled];
+
+ if (retval)
+ {
+ int myCodecCodec = [[[self codec] objectForKey: keyAudioCodec] intValue];
+ int myCodecDefaultBitrate = hb_get_default_audio_bitrate(myCodecCodec, 0, 0);
+ if (myCodecDefaultBitrate < 0)
+ {
+ retval = NO;
+ }
+ }
+ return retval;
+}
+
- (BOOL) AC3Enabled
{
BOOL retval = [self enabled];
- if ( retval)
+ if (retval)
{
int myTrackCodec = [[[self track] objectForKey: keyAudioInputCodec] intValue];
int myCodecCodec = [[[self codec] objectForKey: keyAudioCodec] intValue];
@@ -644,6 +663,10 @@ static NSMutableArray *masterBitRateArray = nil;
{
retval = [NSSet setWithObjects: @"track", @"codec", nil];
}
+ else if ([key isEqualToString: @"bitrateEnabled"])
+ {
+ retval = [NSSet setWithObjects: @"track", @"codec", nil];
+ }
else if ([key isEqualToString: @"mixdownEnabled"])
{
retval = [NSSet setWithObjects: @"track", @"mixdown", nil];
diff --git a/macosx/HBAudioController.m b/macosx/HBAudioController.m
index cc1a62165..09cc27f37 100644
--- a/macosx/HBAudioController.m
+++ b/macosx/HBAudioController.m
@@ -163,6 +163,7 @@ NSString *HBMixdownChangedNotification = @"HBMixdownChangedNotification";
/* We go ahead and assign values to our audio->out.<properties> */
audio->out.track = audio->in.track;
audio->out.codec = [[[anAudio codec] objectForKey: keyAudioCodec] intValue];
+ audio->out.compression_level = hb_get_default_audio_compression(audio->out.codec);
audio->out.mixdown = [[[anAudio mixdown] objectForKey: keyAudioMixdown] intValue];
audio->out.bitrate = [[[anAudio bitRate] objectForKey: keyAudioBitrate] intValue];
audio->out.samplerate = [sampleRateToUse intValue];
diff --git a/scripts/manicure.rb b/scripts/manicure.rb
index a732b63bd..039a6c9a6 100755
--- a/scripts/manicure.rb
+++ b/scripts/manicure.rb
@@ -921,8 +921,8 @@ class Display
commandString << "if( !abitrates )\n "
commandString << "{\n "
- commandString << " abitrates = strdup(\"" << audioBitrates
- commandString << "\");\n "
+ commandString << " abitrates = str_split(\"" << audioBitrates
+ commandString << "\", ',');\n "
commandString << "}\n "
commandString << "if( !mixdowns )\n "
diff --git a/test/test.c b/test/test.c
index fac25e8bc..3d217a9a7 100644
--- a/test/test.c
+++ b/test/test.c
@@ -72,7 +72,9 @@ static char * dynamic_range_compression = NULL;
static char * audio_gain = NULL;
static char * atracks = NULL;
static char * arates = NULL;
-static char * abitrates = NULL;
+static char ** abitrates = NULL;
+static char ** aqualities = NULL;
+static char ** acompressions = NULL;
static char * acodec_fallback = NULL;
static char * acodecs = NULL;
static char ** anames = NULL;
@@ -156,6 +158,8 @@ static int HandleEvents( hb_handle_t * h );
static int get_acodec_for_string( char *codec );
static int is_sample_rate_valid(int rate);
+static void str_vfree( char **strv );
+static char** str_split( char *str, char delem );
#ifdef __APPLE_CC__
static char* bsd_name_for_path(char *path);
@@ -356,7 +360,9 @@ int main( int argc, char ** argv )
if( audio_gain ) free( audio_gain );
if( atracks ) free( atracks );
if( arates ) free( arates );
- if( abitrates ) free( abitrates );
+ str_vfree( abitrates );
+ str_vfree( aqualities );
+ str_vfree( acompressions );
if( acodecs ) free( acodecs );
if (native_language ) free (native_language );
if( advanced_opts ) free (advanced_opts );
@@ -590,6 +596,8 @@ static int HandleEvents( hb_handle_t * h )
/* Audio argument string parsing variables */
int acodec = 0;
int abitrate = 0;
+ float aquality = 0;
+ float acompression = 0;
int arate = 0;
int mixdown = HB_AMIXDOWN_DOLBYPLII;
double d_r_c = 0;
@@ -705,7 +713,7 @@ static int HandleEvents( hb_handle_t * h )
}
if( !abitrates )
{
- abitrates = strdup("160,160");
+ abitrates = str_split("160,160", ',');
}
if( !mixdowns )
{
@@ -751,7 +759,7 @@ static int HandleEvents( hb_handle_t * h )
}
if( !abitrates )
{
- abitrates = strdup("160");
+ abitrates = str_split("160", ',');
}
if( !mixdowns )
{
@@ -792,7 +800,7 @@ static int HandleEvents( hb_handle_t * h )
}
if( !abitrates )
{
- abitrates = strdup("128");
+ abitrates = str_split("128", ',');
}
if( !mixdowns )
{
@@ -836,7 +844,7 @@ static int HandleEvents( hb_handle_t * h )
}
if( !abitrates )
{
- abitrates = strdup("160");
+ abitrates = str_split("160", ',');
}
if( !mixdowns )
{
@@ -880,7 +888,7 @@ static int HandleEvents( hb_handle_t * h )
}
if( !abitrates )
{
- abitrates = strdup("160");
+ abitrates = str_split("160", ',');
}
if( !mixdowns )
{
@@ -922,7 +930,7 @@ static int HandleEvents( hb_handle_t * h )
}
if( !abitrates )
{
- abitrates = strdup("160,160");
+ abitrates = str_split("160,160", ',');
}
if( !mixdowns )
{
@@ -970,7 +978,7 @@ static int HandleEvents( hb_handle_t * h )
}
if( !abitrates )
{
- abitrates = strdup("160,160");
+ abitrates = str_split("160,160", ',');
}
if( !mixdowns )
{
@@ -1013,7 +1021,7 @@ static int HandleEvents( hb_handle_t * h )
}
if( !abitrates )
{
- abitrates = strdup("128");
+ abitrates = str_split("128", ',');
}
if( !mixdowns )
{
@@ -1055,7 +1063,7 @@ static int HandleEvents( hb_handle_t * h )
}
if( !abitrates )
{
- abitrates = strdup("128");
+ abitrates = str_split("128", ',');
}
if( !mixdowns )
{
@@ -1099,7 +1107,7 @@ static int HandleEvents( hb_handle_t * h )
}
if( !abitrates )
{
- abitrates = strdup("160");
+ abitrates = str_split("160", ',');
}
if( !mixdowns )
{
@@ -1144,7 +1152,7 @@ static int HandleEvents( hb_handle_t * h )
}
if( !abitrates )
{
- abitrates = strdup("160,160");
+ abitrates = str_split("160,160", ',');
}
if( !mixdowns )
{
@@ -1189,7 +1197,7 @@ static int HandleEvents( hb_handle_t * h )
}
if( !abitrates )
{
- abitrates = strdup("160");
+ abitrates = str_split("160", ',');
}
if( !mixdowns )
{
@@ -1225,7 +1233,7 @@ static int HandleEvents( hb_handle_t * h )
}
if( !abitrates )
{
- abitrates = strdup("160");
+ abitrates = str_split("160", ',');
}
if( !mixdowns )
{
@@ -1757,6 +1765,7 @@ static int HandleEvents( hb_handle_t * h )
/* Audio Codecs */
/* Sample Rate */
+ int auto_sample_rate = 0;
i = 0;
if( arates )
{
@@ -1783,6 +1792,7 @@ static int HandleEvents( hb_handle_t * h )
if ( !strcasecmp( token, "auto" ) )
{
arate = audio->in.samplerate;
+ auto_sample_rate = 1;
}
if (!is_sample_rate_valid(arate))
{
@@ -1806,11 +1816,15 @@ static int HandleEvents( hb_handle_t * h )
/* We have fewer inputs than audio tracks, use default sample rate.
* Unless we only have one input, then use that for all tracks.
*/
- if (i != 1)
- arate = audio->in.samplerate;
+ int use_default = 0;
+ if( i != 1 || auto_sample_rate )
+ use_default = 1;
+
for ( ; i < num_audio_tracks; i++)
{
audio = hb_list_audio_config_item(job->list_audio, i);
+ if( use_default )
+ arate = audio->in.samplerate;
audio->out.samplerate = arate;
}
}
@@ -1840,23 +1854,14 @@ static int HandleEvents( hb_handle_t * h )
token = strtok(NULL, ",");
}
}
- if (i < num_audio_tracks)
+ if (i < num_audio_tracks && i == 1)
{
- /* We have fewer inputs than audio tracks, use the default mixdown for the rest. Unless
- * we only have one input, then use that.
+ /* We have fewer inputs than audio tracks
+ * and we only have one input, then use that.
*/
- int use_default = 0;
- if (i != 1)
- use_default = 1;
-
for (; i < num_audio_tracks; i++)
{
audio = hb_list_audio_config_item(job->list_audio, i);
- if (use_default)
- {
- // Get default for this tracks codec and layout
- mixdown = hb_get_default_mixdown( audio->out.codec, audio->in.channel_layout );
- }
audio->out.mixdown = mixdown;
}
}
@@ -1866,11 +1871,9 @@ static int HandleEvents( hb_handle_t * h )
i = 0;
if( abitrates )
{
- char * token = strtok(abitrates, ",");
- if (token == NULL)
- token = abitrates;
- while ( token != NULL )
+ for ( i = 0; abitrates[i] != NULL && i < num_audio_tracks; i++ )
{
+ char * token = abitrates[i];
abitrate = atoi(token);
audio = hb_list_audio_config_item(job->list_audio, i);
@@ -1884,32 +1887,81 @@ static int HandleEvents( hb_handle_t * h )
{
fprintf(stderr, "Ignoring bitrate %d, no audio tracks\n", abitrate);
}
- token = strtok(NULL, ",");
}
}
- if (i < num_audio_tracks)
+ if (i < num_audio_tracks && i == 1)
{
- /* We have fewer inputs than audio tracks, use the default bitrate
- * for the remaining tracks. Unless we only have one input, then use
+ /* We have fewer inputs than audio tracks,
+ * and we only have one input, use
* that for all tracks.
*/
- int use_default = 0;
- if (i != 1)
- use_default = 1;
+ for (; i < num_audio_tracks; i++)
+ {
+ audio = hb_list_audio_config_item(job->list_audio, i);
+ audio->out.bitrate = abitrate;
+ }
+ }
+ /* Audio Bitrate */
+
+ /* Audio Quality */
+ i = 0;
+ if( aqualities )
+ {
+ for ( i = 0; aqualities[i] != NULL && i < num_audio_tracks; i++ )
+ {
+ char * token = aqualities[i];
+ audio = hb_list_audio_config_item(job->list_audio, i);
+ if( audio == NULL )
+ {
+ fprintf(stderr, "Ignoring quality %.3f, no audio tracks\n", aquality);
+ }
+ else if( *token != 0 )
+ {
+ aquality = atof(token);
+ audio->out.quality = aquality;
+ audio->out.bitrate = -1;
+ }
+ }
+ }
+ if (i < num_audio_tracks && i == 1)
+ {
+ /* We have fewer inputs than audio tracks,
+ * and we only have one input, use
+ * that for all tracks.
+ */
for (; i < num_audio_tracks; i++)
{
audio = hb_list_audio_config_item(job->list_audio, i);
- if (use_default)
+ if( audio->out.bitrate <= 0 )
+ audio->out.quality = aquality;
+ }
+ }
+ /* Audio Quality */
+
+ /* Audio Compression Level */
+ i = 0;
+ if( acompressions )
+ {
+ for ( i = 0; acompressions[i] != NULL && i < num_audio_tracks; i++ )
+ {
+ char * token = acompressions[i];
+ audio = hb_list_audio_config_item(job->list_audio, i);
+ if( audio == NULL )
{
- abitrate = hb_get_default_audio_bitrate(
- audio->out.codec, audio->out.samplerate,
- audio->out.mixdown );
+ fprintf(stderr, "Ignoring compression level %.2f, no audio tracks\n", acompression);
+ }
+ else if( *token != 0 )
+ {
+ acompression = atof(token);
+
+ audio->out.compression_level = acompression;
}
- audio->out.bitrate = abitrate;
}
}
- /* Audio Bitrate */
+ // Compression levels are codec specific values. So don't
+ // try to apply to other tracks.
+ /* Audio Compression Level */
/* Audio DRC */
i = 0;
@@ -2763,6 +2815,12 @@ static void ShowHelp()
" -B, --ab <kb/s> Set audio bitrate(s) (default: depends on the\n"
" selected codec, mixdown and samplerate)\n"
" Separated by commas for more than one audio track.\n"
+ " -Q, --aq <quality> Set audio quality metric (default: depends on the\n"
+ " selected codec)\n"
+ " Separated by commas for more than one audio track.\n"
+ " -C, --ac <compression> Set audio compression metric (default: depends on the\n"
+ " selected codec)\n"
+ " Separated by commas for more than one audio track.\n"
" -6, --mixdown <string> Format(s) for surround sound downmixing\n"
" Separated by commas for more than one audio track.\n"
" (mono/stereo/dpl1/dpl2/6ch, default: up to 6ch for ac3,\n"
@@ -3117,6 +3175,8 @@ static int ParseOptions( int argc, char ** argv )
{ "vb", required_argument, NULL, 'b' },
{ "quality", required_argument, NULL, 'q' },
{ "ab", required_argument, NULL, 'B' },
+ { "aq", required_argument, NULL, 'Q' },
+ { "ac", required_argument, NULL, 'C' },
{ "rate", required_argument, NULL, 'r' },
{ "arate", required_argument, NULL, 'R' },
{ "encopts", required_argument, NULL, 'x' },
@@ -3152,7 +3212,7 @@ static int ParseOptions( int argc, char ** argv )
cur_optind = optind;
c = getopt_long( argc, argv,
- "hv::uC:f:4i:Io:t:c:m::M:a:A:6:s:UF::N:e:E:"
+ "hv::uC:f:4i:Io:t:c:m::M:a:A:6:s:UF::N:e:E:Q:C:"
"2dD:7895gOw:l:n:b:q:S:B:r:R:x:TY:X:Z:z",
long_options, &option_index );
if( c < 0 )
@@ -3524,10 +3584,13 @@ static int ParseOptions( int argc, char ** argv )
vquality = atof( optarg );
break;
case 'B':
- if( optarg != NULL )
- {
- abitrates = strdup( optarg );
- }
+ abitrates = str_split( optarg, ',' );
+ break;
+ case 'Q':
+ aqualities = str_split( optarg, ',' );
+ break;
+ case 'C':
+ acompressions = str_split( optarg, ',' );
break;
case 'x':
advanced_opts = strdup( optarg );