summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjstebbins <[email protected]>2011-10-12 20:19:33 +0000
committerjstebbins <[email protected]>2011-10-12 20:19:33 +0000
commit9d95d88d5a05abf6086ab474c0aa2583a9da6345 (patch)
tree5ff672576f6efacb2f03a36b85a88a8b2d3e85e1
parentd41d9e0d88a689a11fe0978d4e415b89e72c2e62 (diff)
Add flac + quality + compression level support
Adds flac audio to cli, lingui, and macgui Adds quality and compression level options to cli Adds quality option to lingui Quality option works for vorbis and lame git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@4281 b64f7644-9d1e-0410-96f1-a4d463321fa5
-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 );