summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--macosx/Controller.m120
-rw-r--r--macosx/English.lproj/Audio.xib211
-rw-r--r--macosx/English.lproj/AudioDefaults.xib578
-rw-r--r--macosx/English.lproj/Preferences.xib21
-rw-r--r--macosx/HBAudioController.h17
-rw-r--r--macosx/HBAudioController.m474
-rw-r--r--macosx/HBAudioDefaultsController.h17
-rw-r--r--macosx/HBAudioDefaultsController.m109
-rw-r--r--macosx/HBAudioSettings.h44
-rw-r--r--macosx/HBAudioSettings.m201
-rw-r--r--macosx/HBAudioTrackPreset.h53
-rw-r--r--macosx/HBAudioTrackPreset.m370
-rw-r--r--macosx/HandBrake.xcodeproj/project.pbxproj38
-rw-r--r--macosx/xcconfig/base/os.osx106.xcconfig1
14 files changed, 1723 insertions, 531 deletions
diff --git a/macosx/Controller.m b/macosx/Controller.m
index 195911615..ad0959ca4 100644
--- a/macosx/Controller.m
+++ b/macosx/Controller.m
@@ -14,6 +14,8 @@
#import "DockTextField.h"
#import "HBUtilities.h"
+#import "HBAudioSettings.h"
+
unsigned int maximumNumberOfAllowedAudioTracks = 1024;
NSString *HBContainerChangedNotification = @"HBContainerChangedNotification";
NSString *keyContainerTag = @"keyContainerTag";
@@ -207,7 +209,6 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It
// setup the audio controller
fAudioController = [[HBAudioController alloc] init];
- [fAudioController setHBController: self];
[fAudioView addSubview: [fAudioController view]];
// make sure we automatically resize the controller's view to the current window size
@@ -232,6 +233,8 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It
[[fVideoController view] setFrame: [fVideoView bounds]];
[[fVideoController view] setAutoresizingMask:( NSViewWidthSizable | NSViewHeightSizable )];
+ [fWindow recalculateKeyViewLoop];
+
[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(autoSetM4vExtension:) name: HBMixdownChangedNotification object: nil];
[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(updateMp4Checkboxes:) name: HBVideoEncoderChangedNotification object: nil];
@@ -2599,15 +2602,15 @@ fWorkingCount = 0;
[queueFileJob setObject:[NSNumber numberWithInteger:[fPictureController grayscale]] forKey:@"VideoGrayScale"];
/* Auto Passthru */
- [queueFileJob setObject:@(fAudioController.allowAACPassCheck) forKey: @"AudioAllowAACPass"];
- [queueFileJob setObject:@(fAudioController.allowAC3PassCheck) forKey: @"AudioAllowAC3Pass"];
- [queueFileJob setObject:@(fAudioController.allowDTSHDPassCheck) forKey: @"AudioAllowDTSHDPass"];
- [queueFileJob setObject:@(fAudioController.allowDTSPassCheck) forKey: @"AudioAllowDTSPass"];
- [queueFileJob setObject:@(fAudioController.allowMP3PassCheck) forKey: @"AudioAllowMP3Pass"];
+ [queueFileJob setObject:@(fAudioController.settings.allowAACPassthru) forKey: @"AudioAllowAACPass"];
+ [queueFileJob setObject:@(fAudioController.settings.allowAC3Passthru) forKey: @"AudioAllowAC3Pass"];
+ [queueFileJob setObject:@(fAudioController.settings.allowDTSHDPassthru) forKey: @"AudioAllowDTSHDPass"];
+ [queueFileJob setObject:@(fAudioController.settings.allowDTSPassthru) forKey: @"AudioAllowDTSPass"];
+ [queueFileJob setObject:@(fAudioController.settings.allowMP3Passthru) forKey: @"AudioAllowMP3Pass"];
// just in case we need it for display purposes
- [queueFileJob setObject:fAudioController.audioEncoderFallback forKey: @"AudioEncoderFallback"];
+ [queueFileJob setObject:@(hb_audio_encoder_get_name((int)fAudioController.settings.encoderFallback)) forKey: @"AudioEncoderFallback"];
// actual fallback encoder
- [queueFileJob setObject:@(fAudioController.audioEncoderFallbackTag) forKey: @"JobAudioEncoderFallback"];
+ [queueFileJob setObject:@(fAudioController.settings.encoderFallback) forKey: @"JobAudioEncoderFallback"];
/* Audio */
[fAudioController prepareAudioForQueueFileJob: queueFileJob];
@@ -2900,12 +2903,12 @@ fWorkingCount = 0;
[fVideoController applyVideoSettingsFromQueue:queueToApply];
/* Auto Passthru */
- fAudioController.allowAACPassCheck = [[queueToApply objectForKey:@"AudioAllowAACPass"] boolValue];
- fAudioController.allowAC3PassCheck = [[queueToApply objectForKey:@"AudioAllowAC3Pass"] boolValue];
- fAudioController.allowDTSHDPassCheck = [[queueToApply objectForKey:@"AudioAllowDTSHDPass"] boolValue];
- fAudioController.allowDTSPassCheck = [[queueToApply objectForKey:@"AudioAllowDTSPass"] boolValue];
- fAudioController.allowMP3PassCheck = [[queueToApply objectForKey:@"AudioAllowMP3Pass"] boolValue];
- fAudioController.audioEncoderFallback = [queueToApply objectForKey:@"AudioEncoderFallback"];
+ fAudioController.settings.allowAACPassthru = [[queueToApply objectForKey:@"AudioAllowAACPass"] boolValue];
+ fAudioController.settings.allowAC3Passthru = [[queueToApply objectForKey:@"AudioAllowAC3Pass"] boolValue];
+ fAudioController.settings.allowDTSHDPassthru = [[queueToApply objectForKey:@"AudioAllowDTSHDPass"] boolValue];
+ fAudioController.settings.allowDTSPassthru = [[queueToApply objectForKey:@"AudioAllowDTSPass"] boolValue];
+ fAudioController.settings.allowMP3Passthru = [[queueToApply objectForKey:@"AudioAllowMP3Pass"] boolValue];
+ fAudioController.settings.encoderFallback = [queueToApply objectForKey:@"AudioEncoderFallback"];
/* Audio */
/* Now lets add our new tracks to the audio list here */
@@ -3200,28 +3203,28 @@ fWorkingCount = 0;
/* Auto Passthru */
job->acodec_copy_mask = 0;
- if (fAudioController.allowAACPassCheck)
+ if (fAudioController.settings.allowAACPassthru)
{
job->acodec_copy_mask |= HB_ACODEC_FFAAC;
}
- if (fAudioController.allowAC3PassCheck)
+ if (fAudioController.settings.allowAC3Passthru)
{
job->acodec_copy_mask |= HB_ACODEC_AC3;
}
- if (fAudioController.allowDTSHDPassCheck)
+ if (fAudioController.settings.allowDTSHDPassthru)
{
job->acodec_copy_mask |= HB_ACODEC_DCA_HD;
}
- if (fAudioController.allowDTSPassCheck)
+ if (fAudioController.settings.allowDTSPassthru)
{
job->acodec_copy_mask |= HB_ACODEC_DCA;
}
- if (fAudioController.allowMP3PassCheck)
+ if (fAudioController.settings.allowMP3Passthru)
{
job->acodec_copy_mask |= HB_ACODEC_MP3;
}
- job->acodec_fallback = (int)fAudioController.audioEncoderFallbackTag;
-
+ job->acodec_fallback = fAudioController.settings.encoderFallback;
+
/* Audio tracks and mixdowns */
[fAudioController prepareAudioForJobPreview: job];
@@ -5264,66 +5267,8 @@ return YES;
/* Set the state of ipod compatible with Mp4iPodCompatible. Only for x264*/
[fDstMp4iPodFileCheck setState:[[chosenPreset objectForKey:@"Mp4iPodCompatible"] intValue]];
- /* Video quality */
-
-
- /* Auto Passthru: if the preset has Auto Passthru fields, use them.
- * Otherwise assume every passthru is allowed and the fallback is AC3 */
-
- id tempObject;
- if ((tempObject = [chosenPreset objectForKey:@"AudioAllowAACPass"]) != nil)
- {
- fAudioController.allowAACPassCheck = [tempObject boolValue];
- }
- else
- {
- fAudioController.allowAACPassCheck = YES;
- }
- if ((tempObject = [chosenPreset objectForKey:@"AudioAllowAC3Pass"]) != nil)
- {
- fAudioController.allowAC3PassCheck = [tempObject boolValue];
- }
- else
- {
- fAudioController.allowAC3PassCheck = YES;
- }
- if ((tempObject = [chosenPreset objectForKey:@"AudioAllowDTSHDPass"]) != nil)
- {
- fAudioController.allowDTSHDPassCheck = [tempObject boolValue];
- }
- else
- {
- fAudioController.allowDTSHDPassCheck = YES;
- }
- if ((tempObject = [chosenPreset objectForKey:@"AudioAllowDTSPass"]) != nil)
- {
- fAudioController.allowDTSPassCheck= [tempObject boolValue];
- }
- else
- {
- fAudioController.allowDTSPassCheck = YES;
- }
- if ((tempObject = [chosenPreset objectForKey:@"AudioAllowMP3Pass"]) != nil)
- {
- fAudioController.allowMP3PassCheck = [tempObject boolValue];
- }
- else
- {
- fAudioController.allowAACPassCheck = YES;
- }
- if ((tempObject = [chosenPreset objectForKey:@"AudioEncoderFallback"]) != nil)
- {
- // map legacy encoder names via libhb
- strValue = hb_audio_encoder_sanitize_name([tempObject UTF8String]);
- fAudioController.audioEncoderFallback = [NSString stringWithFormat:@"%s", strValue];
- }
- else
- {
- fAudioController.audioEncoderFallbackTag = HB_ACODEC_AC3;
- }
-
/* Audio */
- [fAudioController addTracksFromPreset: chosenPreset];
+ [fAudioController applySettingsFromPreset: chosenPreset];
/*Subtitles*/
[fSubtitlesViewController applySettingsFromPreset:chosenPreset];
@@ -5798,21 +5743,8 @@ return YES;
[preset setObject:[fPictureController decombCustomString] forKey:@"PictureDecombCustom"];
[preset setObject:[NSNumber numberWithInteger:[fPictureController grayscale]] forKey:@"VideoGrayScale"];
- /* Auto Pasthru */
- [preset setObject:@(fAudioController.allowAACPassCheck) forKey: @"AudioAllowAACPass"];
- [preset setObject:@(fAudioController.allowAC3PassCheck) forKey: @"AudioAllowAC3Pass"];
- [preset setObject:@(fAudioController.allowDTSHDPassCheck) forKey: @"AudioAllowDTSHDPass"];
- [preset setObject:@(fAudioController.allowDTSPassCheck) forKey: @"AudioAllowDTSPass"];
- [preset setObject:@(fAudioController.allowMP3PassCheck) forKey: @"AudioAllowMP3Pass"];
- [preset setObject:fAudioController.audioEncoderFallback forKey: @"AudioEncoderFallback"];
-
/* Audio */
- NSMutableArray *audioListArray = [[NSMutableArray alloc] init];
- [fAudioController prepareAudioForPreset: audioListArray];
-
-
- [preset setObject:[NSMutableArray arrayWithArray: audioListArray] forKey:@"AudioList"];
- [audioListArray release];
+ [fAudioController.settings prepareAudioForPreset:preset];
/* Subtitles */
[fSubtitlesViewController prepareSubtitlesForPreset:preset];
diff --git a/macosx/English.lproj/Audio.xib b/macosx/English.lproj/Audio.xib
index 0f293b92b..68d58e5e6 100644
--- a/macosx/English.lproj/Audio.xib
+++ b/macosx/English.lproj/Audio.xib
@@ -1,16 +1,16 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="5056" systemVersion="13E28" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="5056" systemVersion="13F7" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
<dependencies>
- <deployment version="1060" identifier="macosx"/>
+ <deployment version="1060" defaultVersion="1090" identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="5056"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="HBAudioController">
<connections>
- <outlet property="fAddAllTracksButton" destination="RrJ-Eh-L2L" id="BCF-iF-18K"/>
- <outlet property="fAudioAutoPassthruBox" destination="a33-g2-ZGw" id="5hu-Ft-LJh"/>
- <outlet property="fAudioFallbackPopUp" destination="99G-ev-xSL" id="QJV-Hh-29K"/>
+ <outlet property="configureDefaults" destination="vFP-nq-IQg" id="EFe-IR-Cyn"/>
<outlet property="fTableView" destination="LlC-ua-mth" id="NvM-yh-c0L"/>
+ <outlet property="reloadDefaults" destination="wcL-rL-aYS" id="R78-R5-U0p"/>
+ <outlet property="trackPopup" destination="jrP-M5-2Rq" id="Avl-Cd-Th2"/>
<outlet property="view" destination="LOv-5G-86T" id="qyT-Z6-lCU"/>
</connections>
</customObject>
@@ -59,20 +59,20 @@
<autoresizingMask key="autoresizingMask"/>
<subviews>
<scrollView autohidesScrollers="YES" horizontalLineScroll="27" horizontalPageScroll="10" verticalLineScroll="27" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" id="uE3-SE-Oss">
- <rect key="frame" x="20" y="20" width="886" height="258"/>
+ <rect key="frame" x="20" y="20" width="886" height="266"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<clipView key="contentView" id="RfG-9v-Rts">
- <rect key="frame" x="1" y="17" width="884" height="240"/>
+ <rect key="frame" x="1" y="17" width="884" height="248"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="firstColumnOnly" columnReordering="NO" multipleSelection="NO" autosaveColumns="NO" typeSelect="NO" rowHeight="25" headerView="GLD-lI-qeh" id="LlC-ua-mth">
- <rect key="frame" x="0.0" y="0.0" width="884" height="240"/>
+ <rect key="frame" x="0.0" y="0.0" width="887" height="248"/>
<autoresizingMask key="autoresizingMask"/>
<size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
<tableColumns>
- <tableColumn identifier="track" editable="NO" width="323" minWidth="40" maxWidth="1000" id="gRu-la-4i7">
+ <tableColumn identifier="track" editable="NO" width="322" minWidth="40" maxWidth="1000" id="gRu-la-4i7">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Track">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
@@ -198,7 +198,7 @@
<binding destination="rzb-Si-Kpf" name="enabled" keyPath="arrangedObjects.bitrateEnabled" id="eNf-Cc-xL3"/>
</connections>
</tableColumn>
- <tableColumn identifier="gain" width="32" minWidth="10" maxWidth="3.4028234663852886e+38" id="psI-ue-Jsr">
+ <tableColumn identifier="gain" width="36" minWidth="10" maxWidth="3.4028234663852886e+38" id="psI-ue-Jsr">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="center" title="Gain">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
@@ -208,9 +208,10 @@
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
<connections>
<binding destination="rzb-Si-Kpf" name="enabled" keyPath="arrangedObjects.PassThruDisabled" id="AY4-98-DiI"/>
- <binding destination="rzb-Si-Kpf" name="value" keyPath="arrangedObjects.gain" id="duy-eI-ylW">
+ <binding destination="rzb-Si-Kpf" name="value" keyPath="arrangedObjects.gain" id="T1e-LK-znD">
<dictionary key="options">
<bool key="NSCreatesSortDescriptor" value="NO"/>
+ <bool key="NSValidatesImmediately" value="YES"/>
</dictionary>
</binding>
</connections>
@@ -229,7 +230,7 @@
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
<connections>
<binding destination="rzb-Si-Kpf" name="enabled" keyPath="arrangedObjects.PassThruDisabled" id="L5Z-ZJ-Zjq"/>
- <binding destination="rzb-Si-Kpf" name="value" keyPath="arrangedObjects.gain" id="5rW-UE-Okz"/>
+ <binding destination="rzb-Si-Kpf" name="value" keyPath="arrangedObjects.gain" id="gkE-Na-A2j"/>
</connections>
</tableColumn>
<tableColumn identifier="drc" width="35" minWidth="10" maxWidth="3.4028229999999999e+38" id="whw-Me-VIU">
@@ -242,7 +243,11 @@
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
<connections>
<binding destination="rzb-Si-Kpf" name="enabled" keyPath="arrangedObjects.DRCEnabled" id="uRE-B4-yzg"/>
- <binding destination="rzb-Si-Kpf" name="value" keyPath="arrangedObjects.drc" id="sNI-Mo-CR4"/>
+ <binding destination="rzb-Si-Kpf" name="value" keyPath="arrangedObjects.drc" id="Not-zD-uE1">
+ <dictionary key="options">
+ <bool key="NSValidatesImmediately" value="YES"/>
+ </dictionary>
+ </binding>
</connections>
</tableColumn>
<tableColumn identifier="drctext" editable="NO" width="27" minWidth="10" maxWidth="3.4028229999999999e+38" id="ASp-Mc-vG6">
@@ -267,6 +272,9 @@
</connections>
</tableColumn>
</tableColumns>
+ <connections>
+ <outlet property="menu" destination="hyy-qd-qpe" id="e5W-aS-mPB"/>
+ </connections>
</tableView>
</subviews>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
@@ -280,130 +288,85 @@
<autoresizingMask key="autoresizingMask"/>
</scroller>
<tableHeaderView key="headerView" id="GLD-lI-qeh">
- <rect key="frame" x="0.0" y="0.0" width="884" height="17"/>
+ <rect key="frame" x="0.0" y="0.0" width="887" height="17"/>
<autoresizingMask key="autoresizingMask"/>
</tableHeaderView>
</scrollView>
- <button verticalHuggingPriority="750" id="RrJ-Eh-L2L">
- <rect key="frame" x="19" y="286" width="116" height="16"/>
+ <button appearanceType="aqua" verticalHuggingPriority="750" id="vFP-nq-IQg">
+ <rect key="frame" x="113" y="288" width="130" height="28"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
- <buttonCell key="cell" type="push" title="Add All Tracks" bezelStyle="rounded" alignment="center" controlSize="mini" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Pea-7O-Egc">
+ <buttonCell key="cell" type="push" title="Configure Defaults" bezelStyle="rounded" alignment="center" controlSize="small" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="aYF-d5-Ya6">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
- <font key="font" metaFont="miniSystem"/>
+ <font key="font" metaFont="smallSystem"/>
</buttonCell>
<connections>
- <action selector="addAllAudioTracks:" target="-2" id="NRm-JM-JdU"/>
+ <action selector="showSettingsSheet:" target="-2" id="D9K-M3-zHd"/>
</connections>
</button>
- <box autoresizesSubviews="NO" title="Auto Passthru" borderType="line" titlePosition="noTitle" id="a33-g2-ZGw">
- <rect key="frame" x="355" y="283" width="554" height="31"/>
- <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
- <view key="contentView">
- <rect key="frame" x="1" y="1" width="552" height="29"/>
- <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
- <subviews>
- <button id="Lnr-Em-Qds">
- <rect key="frame" x="85" y="8" width="41" height="18"/>
- <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
- <buttonCell key="cell" type="check" title="MP3" bezelStyle="regularSquare" imagePosition="left" alignment="left" controlSize="mini" state="on" inset="2" id="9TA-KC-mKS">
- <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
- <font key="font" metaFont="miniSystem"/>
- </buttonCell>
- <connections>
- <binding destination="-2" name="value" keyPath="allowMP3PassCheck" id="IPJ-MO-N8F"/>
- </connections>
- </button>
- <button id="gvb-gb-zkx">
- <rect key="frame" x="130" y="8" width="47" height="18"/>
- <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
- <buttonCell key="cell" type="check" title="AAC" bezelStyle="regularSquare" imagePosition="left" alignment="left" controlSize="mini" state="on" inset="2" id="IZd-DC-Dgb">
- <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
- <font key="font" metaFont="miniSystem"/>
- </buttonCell>
- <connections>
- <binding destination="-2" name="value" keyPath="allowAACPassCheck" id="UuF-C6-vAP"/>
- </connections>
- </button>
- <button id="hnY-nd-77u">
- <rect key="frame" x="179" y="8" width="47" height="18"/>
- <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
- <buttonCell key="cell" type="check" title="AC3" bezelStyle="regularSquare" imagePosition="left" alignment="left" controlSize="mini" state="on" inset="2" id="PcA-Yj-Whc">
- <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
- <font key="font" metaFont="miniSystem"/>
- </buttonCell>
- <connections>
- <binding destination="-2" name="value" keyPath="allowAC3PassCheck" id="bQl-JB-ZXP"/>
- </connections>
- </button>
- <button id="bi9-FH-BU2">
- <rect key="frame" x="226" y="8" width="48" height="18"/>
- <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
- <buttonCell key="cell" type="check" title="DTS" bezelStyle="regularSquare" imagePosition="left" alignment="left" controlSize="mini" state="on" inset="2" id="rxe-CG-Ey2">
- <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
- <font key="font" metaFont="miniSystem"/>
- </buttonCell>
- <connections>
- <binding destination="-2" name="value" keyPath="allowDTSPassCheck" id="qKH-AD-3yn"/>
- </connections>
- </button>
- <button id="iUD-cU-Knx">
- <rect key="frame" x="271" y="8" width="58" height="18"/>
- <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
- <buttonCell key="cell" type="check" title="DTS-HD" bezelStyle="regularSquare" imagePosition="left" alignment="left" controlSize="mini" state="on" inset="2" id="PmO-7W-pdS">
- <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
- <font key="font" metaFont="miniSystem"/>
- </buttonCell>
- <connections>
- <binding destination="-2" name="value" keyPath="allowDTSHDPassCheck" id="aZw-P3-f2B"/>
- </connections>
- </button>
- <popUpButton verticalHuggingPriority="750" id="99G-ev-xSL">
- <rect key="frame" x="442" y="8" width="100" height="15"/>
- <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
- <popUpButtonCell key="cell" type="push" title="AC3 (ffmpeg)" bezelStyle="rounded" alignment="left" controlSize="mini" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="qzR-fg-NCZ" id="2Vr-5R-7Hv">
- <behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
- <font key="font" metaFont="miniSystem"/>
- <menu key="menu" title="OtherViews" id="XzU-yN-JEw">
- <items>
- <menuItem title="AC3 (ffmpeg)" state="on" id="qzR-fg-NCZ"/>
- <menuItem title="Item 2" id="6IV-I9-V13"/>
- <menuItem title="Item 3" id="yQk-cI-cGz"/>
- </items>
- </menu>
- </popUpButtonCell>
- </popUpButton>
- <textField verticalHuggingPriority="750" id="VwW-C9-yo0">
- <rect key="frame" x="2" y="-7" width="78" height="28"/>
- <autoresizingMask key="autoresizingMask" flexibleMinY="YES"/>
- <textFieldCell key="cell" controlSize="mini" sendsActionOnEndEditing="YES" alignment="right" title="Auto Passthru:" id="a6J-IC-jTh">
- <font key="font" metaFont="miniSystem"/>
- <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
- <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
- </textFieldCell>
- </textField>
- <textField verticalHuggingPriority="750" id="1wu-8Y-6ed">
- <rect key="frame" x="354" y="7" width="86" height="14"/>
- <autoresizingMask key="autoresizingMask" flexibleMinY="YES"/>
- <textFieldCell key="cell" controlSize="mini" sendsActionOnEndEditing="YES" alignment="right" title="Passthru Fallback:" id="zhf-eR-FDa">
- <font key="font" metaFont="miniSystem"/>
- <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
- <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
- </textFieldCell>
- </textField>
- </subviews>
- </view>
- <color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/>
- <color key="fillColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
+ <button appearanceType="aqua" verticalHuggingPriority="750" id="wcL-rL-aYS">
+ <rect key="frame" x="241" y="288" width="116" height="28"/>
+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+ <buttonCell key="cell" type="push" title="Reload Defaults" bezelStyle="rounded" alignment="center" controlSize="small" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="q2P-Tg-cBJ">
+ <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+ <font key="font" metaFont="smallSystem"/>
+ </buttonCell>
<connections>
- <binding destination="ee3-5O-TtC" name="hidden" keyPath="values.ShowAdvancedOptsForAutoPassthru" id="v2a-z2-nLA">
- <dictionary key="options">
- <string key="NSValueTransformerName">NSNegateBoolean</string>
- </dictionary>
- </binding>
+ <action selector="reloadDefaults:" target="-2" id="k9I-I9-T2U"/>
</connections>
- </box>
+ </button>
+ <popUpButton appearanceType="aqua" verticalHuggingPriority="750" id="jrP-M5-2Rq">
+ <rect key="frame" x="17" y="291" width="88" height="22"/>
+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+ <popUpButtonCell key="cell" type="push" title="Track" bezelStyle="rounded" alignment="left" controlSize="small" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" pullsDown="YES" id="AoT-G9-aA4">
+ <behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
+ <font key="font" metaFont="smallSystem"/>
+ <menu key="menu" title="OtherViews" id="Vxo-66-Mrx">
+ <items>
+ <menuItem title="Track" state="on" hidden="YES" id="Pfh-Bc-83k"/>
+ <menuItem title="Add All" id="AMA-Ul-v2f">
+ <connections>
+ <action selector="addAllAudioTracks:" target="-2" id="8LO-bD-Fjy"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="CCk-3A-ULa"/>
+ <menuItem title="Remove All" id="YlA-ue-5oE">
+ <connections>
+ <action selector="removeAll:" target="-2" id="Hbr-n5-nOt"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </popUpButtonCell>
+ </popUpButton>
</subviews>
</view>
<userDefaultsController representsSharedInstance="YES" id="ee3-5O-TtC"/>
+ <menu id="hyy-qd-qpe">
+ <items>
+ <menuItem title="Add All" id="HM0-a4-pm5">
+ <attributedString key="attributedTitle"/>
+ <connections>
+ <action selector="addAllAudioTracks:" target="-2" id="V4d-pG-lsJ"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="fKl-2Z-8aX"/>
+ <menuItem title="Remove All" id="fqs-Q8-hNY">
+ <connections>
+ <action selector="removeAll:" target="-2" id="E7c-dN-4dY"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="CjR-R1-IBg"/>
+ <menuItem title="Reload Defaults" id="sq7-Ux-T6D">
+ <connections>
+ <action selector="reloadDefaults:" target="-2" id="7JX-ub-E5y"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Configure Defaults…" id="TK6-fY-4Sk">
+ <connections>
+ <action selector="showSettingsSheet:" target="-2" id="Q8y-a8-pV6"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
</objects>
</document>
diff --git a/macosx/English.lproj/AudioDefaults.xib b/macosx/English.lproj/AudioDefaults.xib
new file mode 100644
index 000000000..69460a0ca
--- /dev/null
+++ b/macosx/English.lproj/AudioDefaults.xib
@@ -0,0 +1,578 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="5056" systemVersion="13F7" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
+ <dependencies>
+ <deployment defaultVersion="1090" identifier="macosx"/>
+ <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="5056"/>
+ </dependencies>
+ <objects>
+ <customObject id="-2" userLabel="File's Owner" customClass="HBAudioDefaultsController">
+ <connections>
+ <outlet property="TracksController" destination="I6S-EX-Dvu" id="kKd-rp-1eh"/>
+ <outlet property="showAllButton" destination="QAt-5X-NBT" id="3IW-6r-piX"/>
+ <outlet property="tableController" destination="ZBe-aP-wvq" id="HBN-Z2-bbo"/>
+ <outlet property="tracksController" destination="I6S-EX-Dvu" id="oEz-8a-ef7"/>
+ <outlet property="window" destination="kwM-lz-5lG" id="rob-Fo-JhL"/>
+ </connections>
+ </customObject>
+ <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
+ <customObject id="-3" userLabel="Application" customClass="NSObject"/>
+ <window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" showsToolbarButton="NO" visibleAtLaunch="NO" animationBehavior="default" id="kwM-lz-5lG">
+ <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
+ <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
+ <rect key="contentRect" x="175" y="825" width="813" height="442"/>
+ <rect key="screenRect" x="0.0" y="0.0" width="2560" height="1418"/>
+ <value key="minSize" type="size" width="813" height="397"/>
+ <value key="maxSize" type="size" width="813" height="600"/>
+ <view key="contentView" id="ZP2-Cp-K5w">
+ <rect key="frame" x="0.0" y="0.0" width="813" height="442"/>
+ <autoresizingMask key="autoresizingMask"/>
+ <subviews>
+ <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" id="fPg-3n-1TN">
+ <rect key="frame" x="10" y="406" width="145" height="14"/>
+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+ <textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Track Selection Behavior:" id="GbM-vm-RC2">
+ <font key="font" metaFont="smallSystem"/>
+ <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+ <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
+ </textFieldCell>
+ </textField>
+ <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" id="Jsz-Er-bsF">
+ <rect key="frame" x="10" y="382" width="145" height="14"/>
+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+ <textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Languages:" id="mAT-Jp-SG1">
+ <font key="font" metaFont="smallSystem"/>
+ <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+ <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
+ </textFieldCell>
+ </textField>
+ <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" id="Hqz-Lw-gAu">
+ <rect key="frame" x="430" y="261" width="115" height="14"/>
+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+ <textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Options:" id="NJl-q3-zXL">
+ <font key="font" metaFont="smallSystem"/>
+ <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+ <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
+ </textFieldCell>
+ </textField>
+ <popUpButton verticalHuggingPriority="750" id="oiD-QI-wly">
+ <rect key="frame" x="158" y="401" width="252" height="22"/>
+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+ <popUpButtonCell key="cell" type="push" title="None" bezelStyle="rounded" alignment="left" controlSize="small" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="mvw-Hg-JFM" id="21e-KY-8TR">
+ <behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
+ <font key="font" metaFont="smallSystem"/>
+ <menu key="menu" title="OtherViews" id="Kwy-lU-VuU">
+ <items>
+ <menuItem title="None" state="on" id="mvw-Hg-JFM"/>
+ <menuItem title="First Matching Selected Languages" id="jDd-Ji-7Sm"/>
+ <menuItem title="All Matching Selected Languages" id="GZP-q7-SYy"/>
+ </items>
+ </menu>
+ </popUpButtonCell>
+ <connections>
+ <binding destination="-2" name="selectedIndex" keyPath="self.settings.trackSelectionBehavior" id="sKn-Mr-Hce"/>
+ <outlet property="nextKeyView" destination="Of7-71-Ci6" id="jgQ-nK-YLu"/>
+ </connections>
+ </popUpButton>
+ <button id="uF5-6E-EIe">
+ <rect key="frame" x="548" y="259" width="255" height="18"/>
+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+ <string key="toolTip">Only the primary audio track will be encoded with the full encoder list. All other secondary audio output tracks will be encoded with first encoder only.</string>
+ <buttonCell key="cell" type="check" title="Use only first encoder for secondary audio" bezelStyle="regularSquare" imagePosition="left" controlSize="small" state="on" inset="2" id="66v-2g-DHn">
+ <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
+ <font key="font" metaFont="smallSystem"/>
+ </buttonCell>
+ <connections>
+ <binding destination="-2" name="value" keyPath="self.settings.secondaryEncoderMode" id="Umc-CV-pJy"/>
+ <outlet property="nextKeyView" destination="r4m-GO-aN3" id="nUp-Ow-ZFS"/>
+ </connections>
+ </button>
+ <scrollView autohidesScrollers="YES" horizontalLineScroll="16" horizontalPageScroll="10" verticalLineScroll="16" verticalPageScroll="10" usesPredominantAxisScrolling="NO" id="aTC-39-h6S">
+ <rect key="frame" x="161" y="261" width="246" height="135"/>
+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+ <clipView key="contentView" id="TdE-Sh-NcS">
+ <rect key="frame" x="1" y="1" width="244" height="133"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+ <subviews>
+ <tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" alternatingRowBackgroundColors="YES" columnReordering="NO" columnResizing="NO" autosaveColumns="NO" rowHeight="14" id="Of7-71-Ci6">
+ <rect key="frame" x="0.0" y="0.0" width="244" height="133"/>
+ <autoresizingMask key="autoresizingMask"/>
+ <size key="intercellSpacing" width="3" height="2"/>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ <color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
+ <tableColumns>
+ <tableColumn identifier="checkBox" width="20" minWidth="20" maxWidth="20" id="G44-XP-6xE">
+ <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left">
+ <font key="font" metaFont="smallSystem"/>
+ <color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
+ <color key="backgroundColor" white="0.33333298560000002" alpha="1" colorSpace="calibratedWhite"/>
+ </tableHeaderCell>
+ <buttonCell key="dataCell" type="check" bezelStyle="regularSquare" imagePosition="left" controlSize="small" lineBreakMode="truncatingMiddle" inset="2" id="6by-yL-8VC">
+ <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
+ <font key="font" metaFont="smallSystem"/>
+ </buttonCell>
+ <tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
+ <connections>
+ <binding destination="ZBe-aP-wvq" name="value" keyPath="arrangedObjects.isSelected" id="fRp-oC-H6C"/>
+ </connections>
+ </tableColumn>
+ <tableColumn identifier="name" width="210" minWidth="10" maxWidth="2000" id="IJ6-jx-Nba">
+ <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left">
+ <font key="font" metaFont="smallSystem"/>
+ <color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
+ <color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
+ </tableHeaderCell>
+ <textFieldCell key="dataCell" controlSize="small" lineBreakMode="truncatingMiddle" alignment="left" title="Text Cell" id="lY3-CN-AmZ">
+ <font key="font" metaFont="smallSystem"/>
+ <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+ <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
+ </textFieldCell>
+ <tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
+ <connections>
+ <binding destination="ZBe-aP-wvq" name="value" keyPath="arrangedObjects.language" id="y6d-Rn-DIv"/>
+ </connections>
+ </tableColumn>
+ </tableColumns>
+ <connections>
+ <binding destination="ZBe-aP-wvq" name="content" keyPath="arrangedObjects" id="ak7-UG-Fqe"/>
+ <outlet property="dataSource" destination="ZBe-aP-wvq" id="Xy6-f7-IyO"/>
+ <outlet property="delegate" destination="ZBe-aP-wvq" id="Q25-uc-GVY"/>
+ </connections>
+ </tableView>
+ </subviews>
+ <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
+ </clipView>
+ <scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="YES" id="bXf-U5-ogz">
+ <rect key="frame" x="1" y="118" width="244" height="16"/>
+ <autoresizingMask key="autoresizingMask"/>
+ </scroller>
+ <scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="BWM-rq-VTg">
+ <autoresizingMask key="autoresizingMask"/>
+ </scroller>
+ <connections>
+ <outlet property="nextKeyView" destination="QAt-5X-NBT" id="u00-fZ-W1s"/>
+ </connections>
+ </scrollView>
+ <button verticalHuggingPriority="750" id="QAt-5X-NBT">
+ <rect key="frame" x="161" y="231" width="71" height="23"/>
+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+ <buttonCell key="cell" type="smallSquare" title="Show All" bezelStyle="smallSquare" imagePosition="overlaps" alignment="center" controlSize="small" borderStyle="border" inset="3" id="PiQ-bA-7P1">
+ <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
+ <font key="font" metaFont="smallSystem"/>
+ </buttonCell>
+ <connections>
+ <action selector="edit:" target="-2" id="13y-nD-hEj"/>
+ <outlet property="nextKeyView" destination="vUx-OV-W5T" id="fma-A5-pRA"/>
+ </connections>
+ </button>
+ <button verticalHuggingPriority="750" id="sC2-52-liU">
+ <rect key="frame" x="744" y="14" width="54" height="28"/>
+ <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
+ <buttonCell key="cell" type="push" title="Done" bezelStyle="rounded" alignment="center" controlSize="small" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="kDe-1L-VkD">
+ <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+ <font key="font" metaFont="smallSystem"/>
+ <string key="keyEquivalent" base64-UTF8="YES">
+DQ
+</string>
+ </buttonCell>
+ <connections>
+ <action selector="done:" target="-2" id="Rdg-PN-7l6"/>
+ <outlet property="nextKeyView" destination="oiD-QI-wly" id="1gO-sY-HNE"/>
+ </connections>
+ </button>
+ <button id="vUx-OV-W5T">
+ <rect key="frame" x="548" y="404" width="151" height="18"/>
+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+ <string key="toolTip">Enable this if your playback device supports MP3. This permits MP3 passthru to be selected when automatic passthru selecion is enabled.</string>
+ <buttonCell key="cell" type="check" title="MP3" bezelStyle="regularSquare" imagePosition="left" alignment="left" controlSize="small" state="on" inset="2" id="sdZ-Rx-JoG">
+ <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
+ <font key="font" metaFont="smallSystem"/>
+ </buttonCell>
+ <connections>
+ <binding destination="-2" name="value" keyPath="self.settings.allowMP3Passthru" id="rVF-G7-BYA"/>
+ <outlet property="nextKeyView" destination="fzd-MO-xaB" id="1fb-a1-B25"/>
+ </connections>
+ </button>
+ <button id="fzd-MO-xaB">
+ <rect key="frame" x="548" y="386" width="151" height="18"/>
+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+ <string key="toolTip">Enable this if your playback device supports AAC. This permits AAC passthru to be selected when automatic passthru selecion is enabled.</string>
+ <buttonCell key="cell" type="check" title="AAC" bezelStyle="regularSquare" imagePosition="left" alignment="left" controlSize="small" state="on" inset="2" id="cUX-iP-UAs">
+ <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
+ <font key="font" metaFont="smallSystem"/>
+ </buttonCell>
+ <connections>
+ <binding destination="-2" name="value" keyPath="self.settings.allowAACPassthru" id="nsQ-cP-JyI"/>
+ <outlet property="nextKeyView" destination="fgl-Ev-ELt" id="Exn-Wt-M4D"/>
+ </connections>
+ </button>
+ <button id="fgl-Ev-ELt">
+ <rect key="frame" x="548" y="368" width="151" height="18"/>
+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+ <string key="toolTip">Enable this if your playback device supports AC3. This permits AC3 passthru to be selected when automatic passthru selecion is enabled.</string>
+ <buttonCell key="cell" type="check" title="AC3" bezelStyle="regularSquare" imagePosition="left" alignment="left" controlSize="small" state="on" inset="2" id="VnE-3R-bUf">
+ <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
+ <font key="font" metaFont="smallSystem"/>
+ </buttonCell>
+ <connections>
+ <binding destination="-2" name="value" keyPath="self.settings.allowAC3Passthru" id="Aig-Ok-RyG"/>
+ <outlet property="nextKeyView" destination="E93-Md-aWa" id="Yv5-Xs-mbs"/>
+ </connections>
+ </button>
+ <button id="E93-Md-aWa">
+ <rect key="frame" x="548" y="350" width="151" height="18"/>
+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+ <string key="toolTip">Enable this if your playback device supports DTS. This permits DTS passthru to be selected when automatic passthru selecion is enabled.</string>
+ <buttonCell key="cell" type="check" title="DTS" bezelStyle="regularSquare" imagePosition="left" alignment="left" controlSize="small" state="on" inset="2" id="8mC-Wx-myL">
+ <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
+ <font key="font" metaFont="smallSystem"/>
+ </buttonCell>
+ <connections>
+ <binding destination="-2" name="value" keyPath="self.settings.allowDTSPassthru" id="IWX-ek-0Bd"/>
+ <outlet property="nextKeyView" destination="IxI-o9-jMs" id="sBB-lF-vtE"/>
+ </connections>
+ </button>
+ <button id="IxI-o9-jMs">
+ <rect key="frame" x="548" y="332" width="151" height="18"/>
+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+ <string key="toolTip">Enable this if your playback device supports DTS-HD. This permits DTS-HD passthru to be selected when automatic passthru selecion is enabled.</string>
+ <buttonCell key="cell" type="check" title="DTS-HD" bezelStyle="regularSquare" imagePosition="left" alignment="left" controlSize="small" state="on" inset="2" id="LX6-kc-5vq">
+ <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
+ <font key="font" metaFont="smallSystem"/>
+ </buttonCell>
+ <connections>
+ <binding destination="-2" name="value" keyPath="self.settings.allowDTSHDPassthru" id="w77-9v-vIh"/>
+ <outlet property="nextKeyView" destination="LdN-Cx-ZJY" id="rAA-cB-Ma5"/>
+ </connections>
+ </button>
+ <textField verticalHuggingPriority="750" id="l4i-pd-Cbk">
+ <rect key="frame" x="430" y="406" width="115" height="14"/>
+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+ <textFieldCell key="cell" controlSize="small" sendsActionOnEndEditing="YES" alignment="right" title="Auto Passthru:" id="s6s-EH-5CB">
+ <font key="font" metaFont="smallSystem"/>
+ <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+ <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
+ </textFieldCell>
+ </textField>
+ <popUpButton toolTip="Set the audio codec to encode with when a suitable track can not be found for audio passthru." verticalHuggingPriority="750" id="LdN-Cx-ZJY">
+ <rect key="frame" x="548" y="285" width="152" height="22"/>
+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+ <popUpButtonCell key="cell" type="push" title="Item" bezelStyle="rounded" alignment="left" controlSize="small" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="UJy-A2-Bb1" id="OqD-Tf-29c">
+ <behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
+ <font key="font" metaFont="smallSystem"/>
+ <menu key="menu" title="OtherViews" id="PtB-Wp-B9X">
+ <items>
+ <menuItem title="Item" state="on" id="UJy-A2-Bb1"/>
+ </items>
+ </menu>
+ </popUpButtonCell>
+ <connections>
+ <binding destination="-2" name="content" keyPath="self.settings.audioEncoderFallbacks" id="cP2-Bo-45S"/>
+ <binding destination="-2" name="selectedValue" keyPath="self.settings.encoderFallback" previousBinding="cP2-Bo-45S" id="njJ-qO-UAy">
+ <dictionary key="options">
+ <string key="NSValueTransformerName">HBEncoderTrasformer</string>
+ </dictionary>
+ </binding>
+ <outlet property="nextKeyView" destination="uF5-6E-EIe" id="gaK-Cr-XA9"/>
+ </connections>
+ </popUpButton>
+ <textField verticalHuggingPriority="750" id="Tth-IR-7cU">
+ <rect key="frame" x="430" y="290" width="115" height="14"/>
+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+ <textFieldCell key="cell" controlSize="small" sendsActionOnEndEditing="YES" alignment="right" title="Passthru Fallback:" id="AQe-Sg-Qgh">
+ <font key="font" metaFont="smallSystem"/>
+ <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+ <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
+ </textFieldCell>
+ </textField>
+ <scrollView autohidesScrollers="YES" horizontalLineScroll="27" horizontalPageScroll="10" verticalLineScroll="27" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" id="dWE-zD-izv">
+ <rect key="frame" x="20" y="46" width="773" height="144"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+ <clipView key="contentView" id="ocp-4z-kPU">
+ <rect key="frame" x="1" y="17" width="771" height="126"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+ <subviews>
+ <tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="firstColumnOnly" columnReordering="NO" multipleSelection="NO" autosaveColumns="NO" typeSelect="NO" rowHeight="25" headerView="X9E-z1-8Hv" id="r4m-GO-aN3">
+ <rect key="frame" x="0.0" y="0.0" width="771" height="126"/>
+ <autoresizingMask key="autoresizingMask"/>
+ <size key="intercellSpacing" width="3" height="2"/>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ <color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
+ <tableColumns>
+ <tableColumn identifier="codec" width="275" minWidth="10" maxWidth="3.4028229999999999e+38" id="LuF-er-YPm">
+ <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Codec">
+ <font key="font" metaFont="smallSystem"/>
+ <color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
+ <color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
+ </tableHeaderCell>
+ <popUpButtonCell key="dataCell" type="push" bezelStyle="rounded" alignment="left" controlSize="small" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" arrowPosition="arrowAtCenter" preferredEdge="maxY" id="eC3-fz-8ff">
+ <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+ <font key="font" metaFont="smallSystem"/>
+ <menu key="menu" title="OtherViews" id="vJx-U4-Kqn">
+ <items>
+ <menuItem title="Pop Up" id="L04-Mv-X9t"/>
+ </items>
+ </menu>
+ </popUpButtonCell>
+ <tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
+ <connections>
+ <binding destination="I6S-EX-Dvu" name="selectedValue" keyPath="arrangedObjects.encoder" previousBinding="3FH-yz-dQp" id="fdo-7w-Lke">
+ <dictionary key="options">
+ <string key="NSValueTransformerName">HBEncoderTrasformer</string>
+ </dictionary>
+ </binding>
+ <binding destination="I6S-EX-Dvu" name="content" keyPath="arrangedObjects.encoders" id="3FH-yz-dQp"/>
+ </connections>
+ </tableColumn>
+ <tableColumn identifier="mixdown" width="146" minWidth="10" maxWidth="3.4028229999999999e+38" id="569-7O-ycq">
+ <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Mixdown">
+ <font key="font" metaFont="smallSystem"/>
+ <color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
+ <color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
+ </tableHeaderCell>
+ <popUpButtonCell key="dataCell" type="push" title="Pop Up" bezelStyle="rounded" alignment="left" controlSize="small" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" arrowPosition="arrowAtCenter" preferredEdge="maxY" selectedItem="JZe-ew-UW6" id="U3S-VF-Osh">
+ <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+ <font key="font" metaFont="smallSystem"/>
+ <menu key="menu" title="OtherViews" id="iFd-Xx-1fd">
+ <items>
+ <menuItem title="Pop Up" state="on" id="JZe-ew-UW6"/>
+ </items>
+ </menu>
+ </popUpButtonCell>
+ <tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
+ <connections>
+ <binding destination="I6S-EX-Dvu" name="selectedValue" keyPath="arrangedObjects.mixdown" previousBinding="M17-dt-S1h" id="jRj-iF-7Dx">
+ <dictionary key="options">
+ <string key="NSValueTransformerName">HBMixdownTrasformer</string>
+ </dictionary>
+ </binding>
+ <binding destination="I6S-EX-Dvu" name="enabled" keyPath="arrangedObjects.mixdownEnabled" id="QcL-GI-fNW"/>
+ <binding destination="I6S-EX-Dvu" name="content" keyPath="arrangedObjects.mixdowns" id="M17-dt-S1h"/>
+ </connections>
+ </tableColumn>
+ <tableColumn identifier="samplerate" width="110" minWidth="10" maxWidth="3.4028229999999999e+38" id="NfI-qX-NGY">
+ <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Samplerate">
+ <font key="font" metaFont="smallSystem"/>
+ <color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
+ <color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
+ </tableHeaderCell>
+ <popUpButtonCell key="dataCell" type="push" title="Pop Up" bezelStyle="rounded" alignment="left" controlSize="small" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" arrowPosition="arrowAtCenter" preferredEdge="maxY" selectedItem="kkp-zN-T9L" id="XOK-j0-7l5">
+ <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+ <font key="font" metaFont="smallSystem"/>
+ <menu key="menu" title="OtherViews" id="IMI-0m-Flq">
+ <items>
+ <menuItem title="Pop Up" state="on" id="kkp-zN-T9L"/>
+ </items>
+ </menu>
+ </popUpButtonCell>
+ <tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
+ <connections>
+ <binding destination="I6S-EX-Dvu" name="enabled" keyPath="arrangedObjects.mixdownEnabled" id="yMS-bS-lfu"/>
+ <binding destination="I6S-EX-Dvu" name="selectedValue" keyPath="arrangedObjects.sampleRate" previousBinding="ynD-oN-CKW" id="4g4-Uc-Hrq">
+ <dictionary key="options">
+ <string key="NSValueTransformerName">HBSampleRateTrasformer</string>
+ </dictionary>
+ </binding>
+ <binding destination="I6S-EX-Dvu" name="content" keyPath="arrangedObjects.samplerates" id="ynD-oN-CKW">
+ <dictionary key="options">
+ <bool key="NSInsertsNullPlaceholder" value="YES"/>
+ <string key="NSNoSelectionPlaceholder">Auto</string>
+ <string key="NSNullPlaceholder">Auto</string>
+ </dictionary>
+ </binding>
+ </connections>
+ </tableColumn>
+ <tableColumn identifier="bitrate" width="97" minWidth="10" maxWidth="3.4028229999999999e+38" id="hKf-1o-HNE">
+ <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Bitrate">
+ <font key="font" metaFont="smallSystem"/>
+ <color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
+ <color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
+ </tableHeaderCell>
+ <popUpButtonCell key="dataCell" type="push" title="Pop Up" bezelStyle="rounded" alignment="left" controlSize="small" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" arrowPosition="arrowAtCenter" preferredEdge="maxY" selectedItem="EO9-ri-g0o" id="Fzr-Fz-SdB">
+ <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+ <font key="font" metaFont="smallSystem"/>
+ <menu key="menu" title="OtherViews" id="6Qt-Y4-vCG">
+ <items>
+ <menuItem title="Pop Up" state="on" id="EO9-ri-g0o"/>
+ </items>
+ </menu>
+ </popUpButtonCell>
+ <tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
+ <connections>
+ <binding destination="I6S-EX-Dvu" name="selectedValue" keyPath="arrangedObjects.bitRate" previousBinding="Soq-ZJ-4KR" id="tw7-Kl-He8">
+ <dictionary key="options">
+ <string key="NSValueTransformerName">HBIntegerTrasformer</string>
+ </dictionary>
+ </binding>
+ <binding destination="I6S-EX-Dvu" name="enabled" keyPath="arrangedObjects.bitrateEnabled" id="31K-Op-hHw"/>
+ <binding destination="I6S-EX-Dvu" name="content" keyPath="arrangedObjects.bitrates" id="Soq-ZJ-4KR">
+ <dictionary key="options">
+ <string key="NSNoSelectionPlaceholder">None</string>
+ </dictionary>
+ </binding>
+ </connections>
+ </tableColumn>
+ <tableColumn identifier="gain" width="34" minWidth="10" maxWidth="3.4028234663852886e+38" id="sef-2z-RiQ">
+ <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="center" title="Gain">
+ <font key="font" metaFont="smallSystem"/>
+ <color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
+ <color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
+ </tableHeaderCell>
+ <sliderCell key="dataCell" controlSize="small" continuous="YES" state="on" alignment="left" minValue="-5" maxValue="16" doubleValue="0.25" tickMarkPosition="above" numberOfTickMarks="21" allowsTickMarkValuesOnly="YES" sliderType="circular" id="nEH-R2-7WW"/>
+ <tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
+ <connections>
+ <binding destination="I6S-EX-Dvu" name="value" keyPath="arrangedObjects.gain" id="8lj-8n-vWu">
+ <dictionary key="options">
+ <bool key="NSValidatesImmediately" value="YES"/>
+ </dictionary>
+ </binding>
+ <binding destination="I6S-EX-Dvu" name="enabled" keyPath="arrangedObjects.passThruDisabled" id="RnT-tA-tlH"/>
+ </connections>
+ </tableColumn>
+ <tableColumn identifier="gainText" width="25" minWidth="10" maxWidth="3.4028234663852886e+38" id="8iJ-ka-Oti">
+ <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left">
+ <font key="font" metaFont="smallSystem"/>
+ <color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
+ <color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
+ </tableHeaderCell>
+ <textFieldCell key="dataCell" controlSize="small" lineBreakMode="truncatingTail" selectable="YES" editable="YES" alignment="left" title="Text Cell" id="OHv-wE-adq">
+ <font key="font" metaFont="smallSystem"/>
+ <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+ <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
+ </textFieldCell>
+ <tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
+ <connections>
+ <binding destination="I6S-EX-Dvu" name="value" keyPath="arrangedObjects.gain" id="3I5-Lc-Tqe">
+ <dictionary key="options">
+ <string key="NSValueTransformerName">HBIntegerTrasformer</string>
+ </dictionary>
+ </binding>
+ <binding destination="I6S-EX-Dvu" name="enabled" keyPath="arrangedObjects.passThruDisabled" id="JZi-cA-lcC"/>
+ </connections>
+ </tableColumn>
+ <tableColumn identifier="drc" width="35" minWidth="10" maxWidth="3.4028229999999999e+38" id="wPN-ex-1CZ">
+ <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="center" title="DRC">
+ <font key="font" metaFont="smallSystem"/>
+ <color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
+ <color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
+ </tableHeaderCell>
+ <sliderCell key="dataCell" controlSize="small" continuous="YES" state="on" alignment="left" maxValue="4" tickMarkPosition="below" numberOfTickMarks="16" allowsTickMarkValuesOnly="YES" sliderType="circular" id="say-2a-x5G"/>
+ <tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
+ <connections>
+ <binding destination="I6S-EX-Dvu" name="value" keyPath="arrangedObjects.drc" id="4cX-g9-eBy">
+ <dictionary key="options">
+ <bool key="NSValidatesImmediately" value="YES"/>
+ </dictionary>
+ </binding>
+ <binding destination="I6S-EX-Dvu" name="enabled" keyPath="arrangedObjects.passThruDisabled" id="q8u-5E-Adj"/>
+ </connections>
+ </tableColumn>
+ <tableColumn identifier="drctext" editable="NO" width="25" minWidth="10" maxWidth="3.4028229999999999e+38" id="eLM-kL-FjB">
+ <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left">
+ <font key="font" metaFont="smallSystem"/>
+ <color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
+ <color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
+ </tableHeaderCell>
+ <textFieldCell key="dataCell" controlSize="small" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" title="Text" id="a4J-LK-c3P">
+ <font key="font" metaFont="smallSystem"/>
+ <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+ <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
+ </textFieldCell>
+ <tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
+ <connections>
+ <binding destination="I6S-EX-Dvu" name="value" keyPath="arrangedObjects.drc" id="KdR-3K-LXL">
+ <dictionary key="options">
+ <bool key="NSConditionallySetsEditable" value="YES"/>
+ <string key="NSValueTransformerName">HBIntegerTrasformer</string>
+ </dictionary>
+ </binding>
+ <binding destination="I6S-EX-Dvu" name="enabled" keyPath="arrangedObjects.passThruDisabled" id="IIO-pS-nND"/>
+ </connections>
+ </tableColumn>
+ </tableColumns>
+ <connections>
+ <binding destination="I6S-EX-Dvu" name="content" keyPath="arrangedObjects" id="let-yi-XDX"/>
+ <binding destination="I6S-EX-Dvu" name="selectionIndexes" keyPath="selectionIndexes" previousBinding="let-yi-XDX" id="zy7-Dz-cEh"/>
+ </connections>
+ </tableView>
+ </subviews>
+ <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
+ </clipView>
+ <scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="YES" id="MQZ-cv-4yN">
+ <rect key="frame" x="-100" y="-100" width="685" height="15"/>
+ <autoresizingMask key="autoresizingMask"/>
+ </scroller>
+ <scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" doubleValue="1" horizontal="NO" id="F0o-6a-EMC">
+ <rect key="frame" x="-100" y="-100" width="15" height="206"/>
+ <autoresizingMask key="autoresizingMask"/>
+ </scroller>
+ <tableHeaderView key="headerView" id="X9E-z1-8Hv">
+ <rect key="frame" x="0.0" y="0.0" width="771" height="17"/>
+ <autoresizingMask key="autoresizingMask"/>
+ </tableHeaderView>
+ <connections>
+ <outlet property="nextKeyView" destination="N4q-sT-WgW" id="6gC-Nj-s8x"/>
+ </connections>
+ </scrollView>
+ <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" id="RtZ-Cz-5mG">
+ <rect key="frame" x="18" y="198" width="205" height="14"/>
+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+ <textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Audio Encoder Settings:" id="007-WM-RmC">
+ <font key="font" metaFont="smallSystem"/>
+ <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+ <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
+ </textFieldCell>
+ </textField>
+ <segmentedControl appearanceType="aqua" verticalHuggingPriority="750" id="N4q-sT-WgW">
+ <rect key="frame" x="18" y="19" width="54" height="20"/>
+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+ <segmentedCell key="cell" controlSize="small" borderStyle="border" alignment="left" style="rounded" trackingMode="momentary" id="otA-K4-TxM">
+ <font key="font" metaFont="smallSystem"/>
+ <segments>
+ <segment image="NSAddTemplate" width="24">
+ <nil key="label"/>
+ </segment>
+ <segment image="NSRemoveTemplate" width="23" tag="1">
+ <nil key="label"/>
+ </segment>
+ </segments>
+ </segmentedCell>
+ <connections>
+ <action selector="addTrack:" target="-2" id="vsd-5z-3e3"/>
+ <outlet property="nextKeyView" destination="sC2-52-liU" id="mmR-bd-cFG"/>
+ </connections>
+ </segmentedControl>
+ </subviews>
+ </view>
+ <connections>
+ <outlet property="initialFirstResponder" destination="oiD-QI-wly" id="Vxi-xi-P0d"/>
+ </connections>
+ </window>
+ <arrayController objectClassName="HBLang" id="ZBe-aP-wvq" userLabel="Languages Table Controller" customClass="HBLanguageArrayController">
+ <declaredKeys>
+ <string>language</string>
+ <string>isSelected</string>
+ </declaredKeys>
+ <connections>
+ <binding destination="-2" name="contentArray" keyPath="languagesList.languagesArray" id="vKV-y3-Zbg"/>
+ <outlet property="tableView" destination="Of7-71-Ci6" id="IBV-kN-tPc"/>
+ </connections>
+ </arrayController>
+ <arrayController objectClassName="HBAudioTrackPreset" id="I6S-EX-Dvu" userLabel="Tracks Controller">
+ <declaredKeys>
+ <string>encoder</string>
+ <string>mixdown</string>
+ <string>sampleRate</string>
+ <string>bitRate</string>
+ <string>gain</string>
+ <string>drc</string>
+ </declaredKeys>
+ <connections>
+ <binding destination="-2" name="contentArray" keyPath="self.settings.tracksArray" id="oDO-aQ-oZJ"/>
+ </connections>
+ </arrayController>
+ </objects>
+ <resources>
+ <image name="NSAddTemplate" width="8" height="8"/>
+ <image name="NSRemoveTemplate" width="8" height="8"/>
+ </resources>
+</document>
diff --git a/macosx/English.lproj/Preferences.xib b/macosx/English.lproj/Preferences.xib
index 45bbe218b..e49e83a90 100644
--- a/macosx/English.lproj/Preferences.xib
+++ b/macosx/English.lproj/Preferences.xib
@@ -347,11 +347,11 @@
</subviews>
</customView>
<customView id="235" userLabel="Audio">
- <rect key="frame" x="0.0" y="0.0" width="500" height="120"/>
+ <rect key="frame" x="0.0" y="0.0" width="500" height="88"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<comboBox verticalHuggingPriority="750" id="253">
- <rect key="frame" x="203" y="79" width="247" height="22"/>
+ <rect key="frame" x="203" y="47" width="247" height="22"/>
<autoresizingMask key="autoresizingMask"/>
<comboBoxCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" title="English" drawsBackground="YES" numberOfVisibleItems="10" id="316">
<font key="font" metaFont="smallSystem"/>
@@ -529,7 +529,7 @@
</connections>
</comboBox>
<textField verticalHuggingPriority="750" id="252">
- <rect key="frame" x="18" y="83" width="179" height="14"/>
+ <rect key="frame" x="18" y="51" width="179" height="14"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" controlSize="small" sendsActionOnEndEditing="YES" alignment="right" title="Native Language:" id="315">
<font key="font" metaFont="smallSystem"/>
@@ -538,7 +538,7 @@
</textFieldCell>
</textField>
<comboBox verticalHuggingPriority="750" id="508">
- <rect key="frame" x="203" y="48" width="247" height="22"/>
+ <rect key="frame" x="203" y="16" width="247" height="22"/>
<autoresizingMask key="autoresizingMask"/>
<comboBoxCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" numberOfVisibleItems="10" id="511">
<font key="font" metaFont="smallSystem"/>
@@ -716,7 +716,7 @@
</connections>
</comboBox>
<textField verticalHuggingPriority="750" id="509">
- <rect key="frame" x="52" y="52" width="145" height="14"/>
+ <rect key="frame" x="52" y="20" width="145" height="14"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" controlSize="small" sendsActionOnEndEditing="YES" alignment="right" title="Alternate Language:" id="510">
<font key="font" metaFont="smallSystem"/>
@@ -724,17 +724,6 @@
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
- <button id="qUZ-Do-FyO">
- <rect key="frame" x="128" y="17" width="321" height="18"/>
- <autoresizingMask key="autoresizingMask"/>
- <buttonCell key="cell" type="check" title="Show advanced options for Auto Passthru" bezelStyle="regularSquare" imagePosition="left" alignment="left" controlSize="small" inset="2" id="3OI-w6-b9U">
- <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
- <font key="font" metaFont="smallSystem"/>
- </buttonCell>
- <connections>
- <binding destination="61" name="value" keyPath="values.ShowAdvancedOptsForAutoPassthru" id="sMO-Tw-x6f"/>
- </connections>
- </button>
</subviews>
</customView>
<customView id="236" userLabel="Advanced">
diff --git a/macosx/HBAudioController.h b/macosx/HBAudioController.h
index 959bdc63a..64928aba5 100644
--- a/macosx/HBAudioController.h
+++ b/macosx/HBAudioController.h
@@ -15,10 +15,11 @@ extern NSString *keyAudioInputSampleRate;
extern NSString *keyAudioInputCodec;
extern NSString *keyAudioInputCodecParam;
extern NSString *keyAudioInputChannelLayout;
+
extern NSString *HBMixdownChangedNotification;
@class HBAudio;
-
+@class HBAudioSettings;
/**
* HBAudioController
*
@@ -29,23 +30,15 @@ extern NSString *HBMixdownChangedNotification;
@property (nonatomic, readonly, retain) NSArray *masterTrackArray;
@property (nonatomic, readonly) NSDictionary *noneTrack;
-@property(nonatomic, readwrite) BOOL allowAACPassCheck;
-@property(nonatomic, readwrite) BOOL allowAC3PassCheck;
-@property(nonatomic, readwrite) BOOL allowDTSHDPassCheck;
-@property(nonatomic, readwrite) BOOL allowDTSPassCheck;
-@property(nonatomic, readwrite) BOOL allowMP3PassCheck;
-
-@property(nonatomic, readwrite, assign) NSString *audioEncoderFallback;
-@property(nonatomic, readwrite) NSInteger audioEncoderFallbackTag;
+@property(nonatomic, readonly) HBAudioSettings *settings;
- (void) enableUI: (BOOL) b;
-- (void) setHBController: (id) aController;
+
+- (void)applySettingsFromPreset:(NSDictionary *)preset;
- (void) prepareAudioForQueueFileJob: (NSMutableDictionary *) aDict;
- (void) prepareAudioForJobPreview: (hb_job_t *) aJob;
-- (void) prepareAudioForPreset: (NSMutableArray *) anArray;
- (void) addTracksFromQueue: (NSMutableDictionary *) aQueue;
-- (void) addTracksFromPreset: (NSMutableDictionary *) aPreset;
- (BOOL) anyCodecMatches: (int) aCodecValue;
- (void) settingTrackToNone: (HBAudio *) newNoneTrack;
diff --git a/macosx/HBAudioController.m b/macosx/HBAudioController.m
index 98026c770..e694dd3bb 100644
--- a/macosx/HBAudioController.m
+++ b/macosx/HBAudioController.m
@@ -8,7 +8,11 @@
#import "HBAudioController.h"
#import "Controller.h"
#import "HBAudio.h"
+#import "HBAudioSettings.h"
+#import "HBAudioDefaultsController.h"
+#import "HBAudioTrackPreset.h"
#import "hb.h"
+#include "lang.h"
NSString *keyAudioTrackIndex = @"keyAudioTrackIndex";
NSString *keyAudioTrackName = @"keyAudioTrackName";
@@ -17,33 +21,32 @@ NSString *keyAudioInputSampleRate = @"keyAudioInputSampleRate";
NSString *keyAudioInputCodec = @"keyAudioInputCodec";
NSString *keyAudioInputCodecParam = @"keyAudioInputCodecParam";
NSString *keyAudioInputChannelLayout = @"keyAudioInputChannelLayout";
+NSString *keyAudioTrackLanguageIsoCode = @"keyAudioTrackLanguageIsoCode";
+
NSString *HBMixdownChangedNotification = @"HBMixdownChangedNotification";
@interface HBAudioController () {
- /* New Audio Auto Passthru box */
- IBOutlet NSBox * fAudioAutoPassthruBox;
- IBOutlet NSPopUpButton * fAudioFallbackPopUp;
-
IBOutlet NSTableView * fTableView;
- IBOutlet NSButton * fAddAllTracksButton;
- id myController;
NSMutableArray * audioArray; // the configured audio information
NSArray * masterTrackArray; // the master list of audio tracks from the title
NSDictionary * noneTrack; // this represents no audio track selection
- NSNumber * videoContainerTag; // initially is the default HB_MUX_MP4
}
-@property (nonatomic, readwrite, retain) NSArray *masterTrackArray;
-@property (nonatomic, retain) NSNumber *videoContainerTag;
+@property (assign) IBOutlet NSPopUpButton *trackPopup;
+@property (assign) IBOutlet NSButton *configureDefaults;
+@property (assign) IBOutlet NSButton *reloadDefaults;
+@property (nonatomic, readwrite) BOOL enabled;
-- (void) addAllTracksFromPreset: (NSMutableDictionary *) aPreset;
-- (IBAction) addAllAudioTracks: (id) sender;
-- (void) addNewAudioTrack;
+@property (nonatomic, readwrite, retain) NSArray *masterTrackArray;
+@property (nonatomic, retain) NSNumber *videoContainerTag; // initially is the default HB_MUX_MP4
-@end // interface HBAudioController
+// Defaults
+@property (nonatomic, readwrite, retain) HBAudioDefaultsController *defaultsController;
+@property (nonatomic, readwrite, retain) HBAudioSettings *settings;
+@end
@implementation HBAudioController
@@ -54,26 +57,6 @@ NSString *HBMixdownChangedNotification = @"HBMixdownChangedNotification";
@synthesize noneTrack;
@synthesize videoContainerTag;
-- (NSString *)audioEncoderFallback
-{
- return [[fAudioFallbackPopUp selectedItem] title];
-}
-
-- (void)setAudioEncoderFallback:(NSString *)string
-{
- [fAudioFallbackPopUp selectItemWithTitle:string];
-}
-
-- (NSInteger)audioEncoderFallbackTag
-{
- return [[fAudioFallbackPopUp selectedItem] tag];
-}
-
-- (void)setAudioEncoderFallbackTag:(NSInteger)tag
-{
- [fAudioFallbackPopUp selectItemWithTag:tag];
-}
-
- (instancetype)init
{
self = [super initWithNibName:@"Audio" bundle:nil];
@@ -81,6 +64,11 @@ NSString *HBMixdownChangedNotification = @"HBMixdownChangedNotification";
{
[self setVideoContainerTag: [NSNumber numberWithInt: HB_MUX_MP4]];
audioArray = [[NSMutableArray alloc] init];
+
+ /* register that we are interested in changes made to the video container */
+ NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
+ [center addObserver: self selector: @selector(containerChanged:) name: HBContainerChangedNotification object: nil];
+ [center addObserver: self selector: @selector(titleChanged:) name: HBTitleChangedNotification object: nil];
}
return self;
}
@@ -96,38 +84,29 @@ NSString *HBMixdownChangedNotification = @"HBMixdownChangedNotification";
[super dealloc];
}
-- (void) setHBController: (id) aController
-
+- (IBAction)addAllAudioTracks:(id)sender
{
- NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
- myController = aController;
-
- /* register that we are interested in changes made to the video container */
- [center addObserver: self selector: @selector(containerChanged:) name: HBContainerChangedNotification object: aController];
- [center addObserver: self selector: @selector(titleChanged:) name: HBTitleChangedNotification object: aController];
+ [self addTracksFromDefaults:YES];
}
-- (void) _clearAudioArray
-
+- (IBAction)removeAll:(id)sender
{
- while (0 < [self countOfAudioArray])
- {
- [self removeObjectFromAudioArrayAtIndex: 0];
- }
+ [self _clearAudioArray];
+ [self switchingTrackFromNone:nil];
}
-
-- (IBAction) addAllAudioTracks: (id) sender
+- (void)enableUI:(BOOL)b
{
- [self addAllTracksFromPreset:[myController selectedPreset]];
- return;
+ self.enabled = b;
+ [fTableView setEnabled:b];
+ [self.trackPopup setEnabled:b];
+ [self.configureDefaults setEnabled:b];
+ [self.reloadDefaults setEnabled:b];
}
-- (void)enableUI:(BOOL)b
+- (BOOL)validateUserInterfaceItem:(id < NSValidatedUserInterfaceItem >)anItem
{
- [fTableView setEnabled:b];
- [fAddAllTracksButton setEnabled:b];
- [fAudioFallbackPopUp setEnabled:b];
+ return self.enabled;
}
#pragma mark -
@@ -232,32 +211,6 @@ NSString *HBMixdownChangedNotification = @"HBMixdownChangedNotification";
}
}
-- (void) prepareAudioForPreset: (NSMutableArray *) anArray
-
-{
- NSUInteger audioArrayCount = [self countOfAudioArray];
- NSUInteger i;
-
- for (i = 0; i < audioArrayCount; i++)
- {
- HBAudio *anAudio = [self objectInAudioArrayAtIndex: i];
- if ([anAudio enabled])
- {
- NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithCapacity: 7];
- [dict setObject: [[anAudio track] objectForKey: keyAudioTrackIndex] forKey: @"AudioTrack"];
- [dict setObject: [[anAudio track] objectForKey: keyAudioTrackName] forKey: @"AudioTrackDescription"];
- [dict setObject: [[anAudio codec] objectForKey: keyAudioCodecName] forKey: @"AudioEncoder"];
- [dict setObject: [[anAudio mixdown] objectForKey: keyAudioMixdownName] forKey: @"AudioMixdown"];
- [dict setObject: [[anAudio sampleRate] objectForKey: keyAudioSampleRateName] forKey: @"AudioSamplerate"];
- [dict setObject: [[anAudio bitRate] objectForKey: keyAudioBitrateName] forKey: @"AudioBitrate"];
- [dict setObject: [anAudio drc] forKey: @"AudioTrackDRCSlider"];
- [dict setObject: [anAudio gain] forKey: @"AudioTrackGainSlider"];
- [anArray addObject: dict];
- [dict release];
- }
- }
-}
-
- (void) addTracksFromQueue: (NSMutableDictionary *) aQueue
{
@@ -294,52 +247,37 @@ NSString *HBMixdownChangedNotification = @"HBMixdownChangedNotification";
[self switchingTrackFromNone: nil]; // see if we need to add one to the list
}
-// This routine takes the preset and will return the value for the key AudioList
-// if it exists, otherwise it creates an array from the data in the present.
-- (NSArray *) _presetAudioArrayFromPreset: (NSMutableDictionary *) aPreset
-
+- (void)applySettingsFromPreset:(NSDictionary *)preset
{
- NSArray *retval = [aPreset objectForKey: @"AudioList"];
+ self.settings = [[[HBAudioSettings alloc] init] autorelease];
+ [self.settings applySettingsFromPreset:preset];
+ [self.settings validateEncoderFallbackForVideoContainer:[self.videoContainerTag intValue]];
+
+ [self addTracksFromDefaults:NO];
+}
- if (!retval)
+- (void) _clearAudioArray
+{
+ while (0 < [self countOfAudioArray])
{
- int maximumNumberOfAllowedAudioTracks = [HBController maximumNumberOfAllowedAudioTracks];
- NSString *base;
- NSMutableArray *whatToUse = [NSMutableArray array];
- for (unsigned int i = 1; i <= maximumNumberOfAllowedAudioTracks; i++)
- {
- base = [NSString stringWithFormat: @"Audio%d", i];
- if (nil != [aPreset objectForKey: [base stringByAppendingString: @"Track"]])
- {
- [whatToUse addObject: [NSDictionary dictionaryWithObjectsAndKeys:
- [aPreset objectForKey: [base stringByAppendingString: @"Encoder"]], @"AudioEncoder",
- [aPreset objectForKey: [base stringByAppendingString: @"Mixdown"]], @"AudioMixdown",
- [aPreset objectForKey: [base stringByAppendingString: @"Samplerate"]], @"AudioSamplerate",
- [aPreset objectForKey: [base stringByAppendingString: @"Bitrate"]], @"AudioBitrate",
- [aPreset objectForKey: [base stringByAppendingString: @"TrackDRCSlider"]], @"AudioTrackDRCSlider",
- [aPreset objectForKey: [base stringByAppendingString: @"TrackGainSlider"]], @"AudioTrackGainSlider",
- nil]];
- }
- }
- retval = whatToUse;
+ [self removeObjectFromAudioArrayAtIndex: 0];
}
- return retval;
}
-// This uses the templateAudioArray from the preset to create the audios for the specified trackIndex
-- (void) _processPresetAudioArray: (NSArray *) templateAudioArray forTrack: (unsigned int) trackIndex andType: (int) aType
+/**
+ * Uses the templateAudioArray from the preset to create the audios for the specified trackIndex.
+ *
+ * @param templateAudioArray the track template.
+ * @param trackIndex the index of the source track.
+ * @param firstOnly use only the first track of the template or all.
+ */
+- (void) _processPresetAudioArray: (NSArray *) templateAudioArray forTrack: (NSUInteger) trackIndex firstOnly: (BOOL) firstOnly
{
- NSEnumerator *enumerator = [templateAudioArray objectEnumerator];
- NSMutableDictionary *dict;
- NSString *key;
int maximumNumberOfAllowedAudioTracks = [HBController maximumNumberOfAllowedAudioTracks];
- while (nil != (dict = [enumerator nextObject]))
+ for (HBAudioTrackPreset *preset in templateAudioArray)
{
- // copy the dictionary since we may need to alter it
- dict = [NSMutableDictionary dictionaryWithDictionary:dict];
-
if ([self countOfAudioArray] < maximumNumberOfAllowedAudioTracks)
{
BOOL fallenBack = NO;
@@ -347,62 +285,63 @@ NSString *HBMixdownChangedNotification = @"HBMixdownChangedNotification";
[newAudio setController: self];
[self insertObject: newAudio inAudioArrayAtIndex: [self countOfAudioArray]];
[newAudio setVideoContainerTag: [self videoContainerTag]];
- [newAudio setTrackFromIndex: trackIndex];
+ [newAudio setTrackFromIndex: (int)trackIndex];
+
+ const char *name = hb_audio_encoder_get_name(preset.encoder);
+ NSString *audioEncoder = nil;
- // map legacy encoder names via libhb
- key = [dict objectForKey:@"AudioEncoder"];
- if (key != nil)
+ // Check if we need to use a fallback
+ if (name)
{
- const char *name;
- // passthru fallbacks
- if ([key hasSuffix:@"Passthru"] &&
- ![newAudio setCodecFromName:key])
+ audioEncoder = @(name);
+ if (preset.encoder & HB_ACODEC_PASS_FLAG &&
+ ![newAudio setCodecFromName:audioEncoder])
{
int passthru, fallback;
fallenBack = YES;
- passthru = hb_audio_encoder_get_from_name([key UTF8String]);
+ passthru = hb_audio_encoder_get_from_name([audioEncoder UTF8String]);
fallback = hb_audio_encoder_get_fallback_for_passthru(passthru);
name = hb_audio_encoder_get_name(fallback);
+
+ // If we couldn't find an encoder for the passthru format
+ // fall back to the selected encoder fallback
+ if (name == NULL)
+ {
+ name = hb_audio_encoder_get_name(self.settings.encoderFallback);
+ }
}
else
{
- name = hb_audio_encoder_sanitize_name([key UTF8String]);
+ name = hb_audio_encoder_sanitize_name([audioEncoder UTF8String]);
}
- [dict setObject:[NSString stringWithFormat:@"%s", name]
- forKey:@"AudioEncoder"];
- }
-
- // If our preset does not contain a drc or gain value set it to a default of 0.0
- if (![dict objectForKey: @"AudioTrackDRCSlider"])
- {
- [dict setObject:[NSNumber numberWithFloat:0.0] forKey:@"AudioTrackDRCSlider"];
- }
- if (![dict objectForKey: @"AudioTrackGainSlider"])
- {
- [dict setObject:[NSNumber numberWithFloat:0.0] forKey:@"AudioTrackGainSlider"];
- }
-
- // map legacy mixdowns via libhb
- key = [dict objectForKey: @"AudioMixdown"];
- if (key != nil)
- {
- [dict setObject:[NSString stringWithFormat:@"%s",
- hb_mixdown_sanitize_name([key UTF8String])]
- forKey:@"AudioMixdown"];
+ audioEncoder = @(name);
}
// If our preset wants us to support a codec that the track does not support, instead
// of changing the codec we remove the audio instead.
- if ([newAudio setCodecFromName: [dict objectForKey: @"AudioEncoder"]])
+ if ([newAudio setCodecFromName:audioEncoder])
{
- [newAudio setMixdownFromName: [dict objectForKey: @"AudioMixdown"]];
- [newAudio setSampleRateFromName: [dict objectForKey: @"AudioSamplerate"]];
+ const char *mixdown = hb_mixdown_get_name(preset.mixdown);
+ if (mixdown)
+ {
+ [newAudio setMixdownFromName: @(mixdown)];
+ }
+
+ const char *sampleRateName = hb_audio_samplerate_get_name(preset.sampleRate);
+ if (!sampleRateName)
+ {
+ [newAudio setSampleRateFromName: @"Auto"];
+ }
+ else
+ {
+ [newAudio setSampleRateFromName: @(sampleRateName)];
+ }
if (!fallenBack)
{
- [newAudio setBitRateFromName: [dict objectForKey: @"AudioBitrate"]];
+ [newAudio setBitRateFromName: [NSString stringWithFormat:@"%d", preset.bitRate]];
}
- [newAudio setDrc: [dict objectForKey: @"AudioTrackDRCSlider"]];
- [newAudio setGain: [dict objectForKey: @"AudioTrackGainSlider"]];
+ [newAudio setDrc: @(preset.drc)];
+ [newAudio setGain: @(preset.gain)];
}
else
{
@@ -410,130 +349,103 @@ NSString *HBMixdownChangedNotification = @"HBMixdownChangedNotification";
}
[newAudio release];
}
+
+ if (firstOnly)
+ {
+ break;
+ }
}
}
-// This matches the FIRST track with the specified prefix, otherwise it uses the defaultIfNotFound value
-- (unsigned int) _trackWithTitlePrefix: (NSString *) prefix defaultIfNotFound: (unsigned int) defaultIfNotFound
-
+/**
+ * Matches the source audio tracks with the specific language iso code.
+ *
+ * @param isoCode the iso code to match.
+ * @param selectOnlyFirst whether to match only the first track for the iso code.
+ *
+ * @return a NSIndexSet with the index of the matched tracks.
+ */
+- (NSIndexSet *) _tracksWithISOCode: (NSString *) isoCode selectOnlyFirst: (BOOL) selectOnlyFirst
{
- unsigned int retval = defaultIfNotFound;
- NSUInteger count = [masterTrackArray count];
- NSString *languageTitle;
- BOOL found = NO;
-
+ NSMutableIndexSet *indexes = [NSMutableIndexSet indexSet];
+
// We search for the prefix noting that our titles have the format %d: %s where the %s is the prefix
- for (unsigned int i = 1; i < count && !found; i++) // Note that we skip the "None" track
- {
- languageTitle = [[masterTrackArray objectAtIndex: i] objectForKey: keyAudioTrackName];
- if ([[languageTitle substringFromIndex: [languageTitle rangeOfString: @" "].location + 1] hasPrefix: prefix])
+ [masterTrackArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
+ if (idx) // Note that we skip the "None" track
{
- retval = i;
- found = YES;
+ if ([isoCode isEqualToString:@"und"] || [obj[keyAudioTrackLanguageIsoCode] isEqualToString:isoCode])
+ {
+ [indexes addIndex:idx];
+
+ if (selectOnlyFirst)
+ {
+ *stop = YES;
+ }
+ }
}
- }
- return retval;
-}
+ }];
-// When we add a track and we do not have a preset to use for the track we use
-// this bogus preset to do the dirty work.
-- (NSMutableDictionary *) _defaultPreset
+ return indexes;
+}
+- (void) _processPresetAudioArray: (NSArray *) templateAudioArray forTracks: (NSIndexSet *) trackIndexes firstOnly: (BOOL) firstOnly
{
- static NSMutableDictionary *retval = nil;
-
- if (!retval)
- {
- retval = [[NSMutableDictionary dictionaryWithObjectsAndKeys:
- [NSArray arrayWithObject:
- [NSDictionary dictionaryWithObjectsAndKeys:
- [NSNumber numberWithInt: 1], @"AudioTrack",
- @"AAC (CoreAudio)", @"AudioEncoder",
- @"Dolby Pro Logic II", @"AudioMixdown",
- @"Auto", @"AudioSamplerate",
- @"160", @"AudioBitrate",
- [NSNumber numberWithFloat: 0.0], @"AudioTrackDRCSlider",
- [NSNumber numberWithFloat: 0.0], @"AudioTrackGainSlider",
- nil]], @"AudioList", nil] retain];
- }
- return retval;
+ __block BOOL firsTrack = firstOnly;
+ [trackIndexes enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
+ // Add the track
+ [self _processPresetAudioArray: self.settings.tracksArray forTrack:idx firstOnly:firsTrack];
+ firsTrack = self.settings.secondaryEncoderMode ? YES : NO;
+ }];
}
-- (void) addTracksFromPreset: (NSMutableDictionary *) aPreset allTracks: (BOOL) allTracks
+- (void) addTracksFromDefaults: (BOOL) allTracks
{
- id whatToUse = [self _presetAudioArrayFromPreset: aPreset];
- NSMutableArray *tracksToAdd = [[NSMutableArray alloc] init];
+ BOOL firstTrack = NO;
+ NSMutableIndexSet *tracksAdded = [NSMutableIndexSet indexSet];
+ NSMutableIndexSet *tracksToAdd = [NSMutableIndexSet indexSet];
- NSArray* preferredLanguages = [NSArray arrayWithObjects:
- [[NSUserDefaults standardUserDefaults] stringForKey: @"DefaultLanguage"],
- [[NSUserDefaults standardUserDefaults] stringForKey: @"AlternateLanguage"],
- nil];
+ // Reinitialize the configured list of audio tracks
+ [self _clearAudioArray];
- // Add tracks of Default and Alternate Language by name
- for(id languageName in preferredLanguages)
+ if (self.settings.trackSelectionBehavior != HBAudioTrackSelectionBehaviorNone)
{
- int trackNumber = [self _trackWithTitlePrefix: languageName defaultIfNotFound: 0];
-
- if(trackNumber > 0 && [tracksToAdd indexOfObject:[NSNumber numberWithInt:trackNumber]] == NSNotFound)
+ // Add tracks of Default and Alternate Language by name
+ for (NSString *languageISOCode in self.settings.trackSelectionLanguages)
{
- [tracksToAdd addObject:[NSNumber numberWithInt:trackNumber]];
+ NSMutableIndexSet *tracksIndexes = [[self _tracksWithISOCode: languageISOCode
+ selectOnlyFirst: self.settings.trackSelectionBehavior == HBAudioTrackSelectionBehaviorFirst] mutableCopy];
+ [tracksIndexes removeIndexes:tracksAdded];
+ if (tracksIndexes.count)
+ {
+ [self _processPresetAudioArray:self.settings.tracksArray forTracks:tracksIndexes firstOnly:firstTrack];
+ firstTrack = self.settings.secondaryEncoderMode ? YES : NO;
+ [tracksAdded addIndexes:tracksIndexes];
+ }
+ [tracksIndexes release];
}
- }
- // If no preferred Language was found, add standard track 1
- if([tracksToAdd count] == 0)
- {
- [tracksToAdd addObject:[NSNumber numberWithInt:1]];
+ // If no preferred Language was found, add standard track 1
+ if (tracksAdded.count == 0 && masterTrackArray.count > 1)
+ {
+ [tracksToAdd addIndex:1];
+ }
}
// If all tracks should be added, add all track numbers that are not yet processed
if (allTracks)
{
- NSUInteger count = [masterTrackArray count];
- for (unsigned int i = 1; i < count; i++)
- {
- NSNumber *trackNumber = [NSNumber numberWithInt:i];
- if([tracksToAdd indexOfObject:trackNumber] == NSNotFound)
- {
- [tracksToAdd addObject:trackNumber];
- }
- }
+ [tracksToAdd addIndexesInRange:NSMakeRange(1, masterTrackArray.count - 1)];
+ [tracksToAdd removeIndexes:tracksAdded];
}
-
- // Reinitialize the configured list of audio tracks
- [self _clearAudioArray];
- for(id trackNumber in tracksToAdd)
+ if (tracksToAdd.count)
{
- [self _processPresetAudioArray: whatToUse forTrack:[trackNumber intValue] andType: [[aPreset objectForKey: @"Type"] intValue]];
+ [self _processPresetAudioArray:self.settings.tracksArray forTracks:tracksToAdd firstOnly:firstTrack];
}
- [tracksToAdd release];
-}
-
-- (void) _ensureAtLeastOneNonEmptyTrackExists
-{
- NSUInteger count = [self countOfAudioArray];
- if (0 == count || ![[self objectInAudioArrayAtIndex: 0] enabled])
- {
- [self addTracksFromPreset: [self _defaultPreset] allTracks: NO];
- }
- [self switchingTrackFromNone: nil]; // this ensures there is a None track at the end of the list
-}
-
-- (void) addTracksFromPreset: (NSMutableDictionary *) aPreset
-
-{
- [self addTracksFromPreset: aPreset allTracks: NO];
- [self _ensureAtLeastOneNonEmptyTrackExists];
-}
-
-- (void) addAllTracksFromPreset: (NSMutableDictionary *) aPreset
-
-{
- [self addTracksFromPreset: aPreset allTracks: YES];
- [self _ensureAtLeastOneNonEmptyTrackExists];
+ // Add an None item
+ [self switchingTrackFromNone: nil];
}
- (BOOL) anyCodecMatches: (int) aCodecValue
@@ -630,37 +542,9 @@ NSString *HBMixdownChangedNotification = @"HBMixdownChangedNotification";
[audioObject setVideoContainerTag: [self videoContainerTag]];
}
- /* Update the Auto Passthru Fallback Codec Popup */
- /* lets get the tag of the currently selected item first so we might reset it later */
-
- int selectedAutoPassthruFallbackEncoderTag = (int)[[fAudioFallbackPopUp selectedItem] tag];
-
- [fAudioFallbackPopUp removeAllItems];
- for (const hb_encoder_t *audio_encoder = hb_audio_encoder_get_next(NULL);
- audio_encoder != NULL;
- audio_encoder = hb_audio_encoder_get_next(audio_encoder))
- {
- if ((audio_encoder->codec & HB_ACODEC_PASS_FLAG) == 0 &&
- (audio_encoder->muxers & [[self videoContainerTag] integerValue]))
- {
- NSMenuItem *menuItem = [[fAudioFallbackPopUp menu] addItemWithTitle:[NSString stringWithUTF8String:audio_encoder->name]
- action:nil
- keyEquivalent:@""];
- [menuItem setTag:audio_encoder->codec];
- }
- }
-
- /* if we have a previously selected auto passthru fallback encoder tag, then try to select it */
- if (selectedAutoPassthruFallbackEncoderTag)
- {
- selectedAutoPassthruFallbackEncoderTag = [fAudioFallbackPopUp selectItemWithTag:selectedAutoPassthruFallbackEncoderTag];
- }
- /* if we had no previous fallback selected OR if selection failed
- * select the default fallback encoder (AC3) */
- if (!selectedAutoPassthruFallbackEncoderTag)
- {
- [fAudioFallbackPopUp selectItemWithTag:HB_ACODEC_AC3];
- }
+ // Update the Auto Passthru Fallback Codec Popup
+ // lets get the tag of the currently selected item first so we might reset it later
+ [self.settings validateEncoderFallbackForVideoContainer:[self.videoContainerTag intValue]];
}
- (void) titleChanged: (NSNotification *) aNotification
@@ -670,6 +554,9 @@ NSString *HBMixdownChangedNotification = @"HBMixdownChangedNotification";
NSData *theData = [notDict objectForKey: keyTitleTag];
hb_title_t *title = NULL;
+ // Reinitialize the configured list of audio tracks
+ [self _clearAudioArray];
+
[theData getBytes: &title length: sizeof(title)];
if (title)
{
@@ -697,22 +584,41 @@ NSString *HBMixdownChangedNotification = @"HBMixdownChangedNotification";
[NSNumber numberWithInt: audio->in.codec], keyAudioInputCodec,
[NSNumber numberWithInt: audio->in.codec_param], keyAudioInputCodecParam,
[NSNumber numberWithUnsignedLongLong: audio->in.channel_layout], keyAudioInputChannelLayout,
+ @(audio->lang.iso639_2), keyAudioTrackLanguageIsoCode,
nil]];
}
self.masterTrackArray = newTrackArray;
+ [self switchingTrackFromNone: nil]; // this ensures there is a None track at the end of the list
}
else
{
self.masterTrackArray = nil;
}
- // Reinitialize the configured list of audio tracks
- [self _clearAudioArray];
+}
- if (![myController hasValidPresetSelected])
- {
- [self _ensureAtLeastOneNonEmptyTrackExists];
- }
+#pragma mark - Defaults
+
+- (IBAction)showSettingsSheet:(id)sender
+{
+ self.defaultsController = [[[HBAudioDefaultsController alloc] initWithSettings:self.settings] autorelease];
+ self.defaultsController.delegate = self;
+
+ [NSApp beginSheet:[self.defaultsController window]
+ modalForWindow:[[self view] window]
+ modalDelegate:self
+ didEndSelector:NULL
+ contextInfo:NULL];
+}
+
+- (void)sheetDidEnd
+{
+ self.defaultsController = nil;
+}
+
+- (IBAction)reloadDefaults:(id)sender
+{
+ [self addTracksFromDefaults:NO];
}
#pragma mark -
diff --git a/macosx/HBAudioDefaultsController.h b/macosx/HBAudioDefaultsController.h
new file mode 100644
index 000000000..c592ea6eb
--- /dev/null
+++ b/macosx/HBAudioDefaultsController.h
@@ -0,0 +1,17 @@
+/* HBAudioDefaultsController.h $
+
+ This file is part of the HandBrake source code.
+ Homepage: <http://handbrake.fr/>.
+ It may be used under the terms of the GNU General Public License. */
+
+#import <Cocoa/Cocoa.h>
+
+@class HBAudioSettings;
+
+@interface HBAudioDefaultsController : NSWindowController
+
+- (instancetype)initWithSettings:(HBAudioSettings *)settings;
+
+@property (nonatomic, readwrite, assign) id delegate;
+
+@end
diff --git a/macosx/HBAudioDefaultsController.m b/macosx/HBAudioDefaultsController.m
new file mode 100644
index 000000000..2dfefc292
--- /dev/null
+++ b/macosx/HBAudioDefaultsController.m
@@ -0,0 +1,109 @@
+/* HBAudioDefaultsController.m $
+
+ This file is part of the HandBrake source code.
+ Homepage: <http://handbrake.fr/>.
+ It may be used under the terms of the GNU General Public License. */
+
+#import "HBAudioDefaultsController.h"
+#import "HBAudioSettings.h"
+#import "HBLanguagesSelection.h"
+
+static void *HBAudioDefaultsContex = &HBAudioDefaultsContex;
+
+@interface HBAudioDefaultsController ()
+
+@property (nonatomic, readonly) HBAudioSettings *settings;
+
+@property (nonatomic, readonly) HBLanguagesSelection *languagesList;
+@property (assign) IBOutlet HBLanguageArrayController *tableController;
+@property (assign) IBOutlet NSButton *showAllButton;
+
+@property (assign) IBOutlet NSArrayController *tracksController;
+
+@end
+
+@implementation HBAudioDefaultsController
+
+- (instancetype)initWithSettings:(HBAudioSettings *)settings
+{
+ self = [super initWithWindowNibName:@"AudioDefaults"];
+ if (self)
+ {
+ _settings = [settings retain];
+ _languagesList = [[HBLanguagesSelection alloc] initWithLanguages:_settings.trackSelectionLanguages];
+ }
+ return self;
+}
+
+- (void)windowDidLoad
+{
+ [self addObserver:self forKeyPath:@"tableController.showSelectedOnly" options:0 context:HBAudioDefaultsContex];
+
+ if (self.settings.trackSelectionLanguages.count)
+ {
+ self.tableController.showSelectedOnly = YES;
+ }
+}
+
+- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
+{
+ if (context == HBAudioDefaultsContex)
+ {
+ if ([keyPath isEqualToString:@"tableController.showSelectedOnly"])
+ {
+ [self.showAllButton setState:!self.tableController.showSelectedOnly];
+ }
+ }
+ else
+ {
+ [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
+ }
+}
+
+- (IBAction)edit:(id)sender
+{
+ self.tableController.showSelectedOnly = !self.tableController.showSelectedOnly;
+}
+
+- (IBAction)addTrack:(id)sender
+{
+ if ([sender selectedSegment])
+ {
+ if ([[self.tracksController arrangedObjects] count] && self.tracksController.selectionIndex != NSNotFound)
+ {
+ [self.tracksController removeObjectAtArrangedObjectIndex:self.tracksController.selectionIndex];
+ }
+ }
+ else
+ {
+ [self.tracksController add:sender];
+ }
+}
+
+- (IBAction)done:(id)sender
+{
+ [[self window] orderOut:nil];
+ [NSApp endSheet:[self window]];
+
+ [self.settings.trackSelectionLanguages removeAllObjects];
+ [self.settings.trackSelectionLanguages addObjectsFromArray:self.languagesList.selectedLanguages];
+
+ if ([self.delegate respondsToSelector:@selector(sheetDidEnd)])
+ {
+ [self.delegate performSelector:@selector(sheetDidEnd)];
+ }
+}
+
+- (void)dealloc
+{
+ [_settings release];
+ [_languagesList release];
+
+ @try {
+ [self removeObserver:self forKeyPath:@"tableController.showSelectedOnly"];
+ } @catch (NSException * __unused exception) {}
+
+ [super dealloc];
+}
+
+@end
diff --git a/macosx/HBAudioSettings.h b/macosx/HBAudioSettings.h
new file mode 100644
index 000000000..f0ee3ced6
--- /dev/null
+++ b/macosx/HBAudioSettings.h
@@ -0,0 +1,44 @@
+//
+// HBAudioSettings.h
+// HandBrake
+//
+// Created by Damiano Galassi on 29/07/14.
+//
+//
+
+#import <Foundation/Foundation.h>
+
+typedef NS_ENUM(NSUInteger, HBAudioTrackSelectionBehavior) {
+ HBAudioTrackSelectionBehaviorNone,
+ HBAudioTrackSelectionBehaviorFirst,
+ HBAudioTrackSelectionBehaviorAll,
+};
+
+/**
+ * HBAudioSettings
+ * Stores the audio defaults settings.
+ */
+@interface HBAudioSettings : NSObject
+
+@property (nonatomic, readwrite) HBAudioTrackSelectionBehavior trackSelectionBehavior;
+@property (nonatomic, readwrite, retain) NSMutableArray *trackSelectionLanguages;
+
+@property (nonatomic, readwrite, retain) NSMutableArray *tracksArray;
+
+@property(nonatomic, readwrite) BOOL allowAACPassthru;
+@property(nonatomic, readwrite) BOOL allowAC3Passthru;
+@property(nonatomic, readwrite) BOOL allowDTSHDPassthru;
+@property(nonatomic, readwrite) BOOL allowDTSPassthru;
+@property(nonatomic, readwrite) BOOL allowMP3Passthru;
+
+@property(nonatomic, readwrite) int encoderFallback;
+@property(nonatomic, readwrite) BOOL secondaryEncoderMode;
+
+@property(nonatomic, readonly) NSArray *audioEncoderFallbacks;
+
+- (void)applySettingsFromPreset:(NSDictionary *)preset;
+- (void)prepareAudioForPreset:(NSMutableDictionary *)preset;
+
+- (void)validateEncoderFallbackForVideoContainer:(int)container;
+
+@end
diff --git a/macosx/HBAudioSettings.m b/macosx/HBAudioSettings.m
new file mode 100644
index 000000000..654012b8d
--- /dev/null
+++ b/macosx/HBAudioSettings.m
@@ -0,0 +1,201 @@
+//
+// HBAudioSettings.m
+// HandBrake
+//
+// Created by Damiano Galassi on 29/07/14.
+//
+//
+
+#import "HBAudioSettings.h"
+#import "HBAudioTrackPreset.h"
+#import "hb.h"
+#import "lang.h"
+
+@interface HBAudioSettings ()
+
+@property (nonatomic, readwrite) int container;
+
+@end
+
+@implementation HBAudioSettings
+
+- (instancetype)init
+{
+ self = [super init];
+ if (self) {
+ _encoderFallback = HB_ACODEC_AC3;
+ _trackSelectionLanguages = [[NSMutableArray alloc] init];
+ _tracksArray = [[NSMutableArray alloc] init];
+ _trackSelectionBehavior = HBAudioTrackSelectionBehaviorFirst;
+ _container = HB_MUX_MKV;
+ }
+ return self;
+}
+
+- (void)dealloc
+{
+ [_trackSelectionLanguages release];
+ [_tracksArray release];
+ [super dealloc];
+}
+
+- (NSArray *)audioEncoderFallbacks
+{
+ NSMutableArray *fallbacks = [[NSMutableArray alloc] init];
+ for (const hb_encoder_t *audio_encoder = hb_audio_encoder_get_next(NULL);
+ audio_encoder != NULL;
+ audio_encoder = hb_audio_encoder_get_next(audio_encoder))
+ {
+ if ((audio_encoder->codec & HB_ACODEC_PASS_FLAG) == 0 &&
+ (audio_encoder->muxers & self.container))
+ {
+ [fallbacks addObject:@(audio_encoder->name)];
+ }
+ }
+ return [fallbacks autorelease];
+}
+
+- (void)applySettingsFromPreset:(NSDictionary *)preset
+{
+ // Track selection behavior
+ if ([preset[@"AudioTrackSelectionBehavior"] isEqualToString:@"first"])
+ {
+ self.trackSelectionBehavior = HBAudioTrackSelectionBehaviorFirst;
+ }
+ else if ([preset[@"AudioTrackSelectionBehavior"] isEqualToString:@"all"])
+ {
+ self.trackSelectionBehavior = HBAudioTrackSelectionBehaviorAll;
+ }
+ else if ([preset[@"AudioTrackSelectionBehavior"] isEqualToString:@"none"])
+ {
+ self.trackSelectionBehavior = HBAudioTrackSelectionBehaviorNone;
+ }
+ else
+ {
+ // Keep the previous behavior for the old presets
+ self.trackSelectionBehavior = HBAudioTrackSelectionBehaviorFirst;
+ }
+ self.trackSelectionLanguages = [NSMutableArray arrayWithArray:preset[@"AudioLanguageList"]];
+
+ // If the preset is one of the built in, set some additional options
+ if ([preset[@"Type"] intValue] == 0)
+ {
+ self.trackSelectionBehavior = HBAudioTrackSelectionBehaviorFirst;
+ if (self.trackSelectionLanguages.count == 0)
+ {
+ if ([[NSUserDefaults standardUserDefaults] stringForKey:@"DefaultLanguage"])
+ {
+ iso639_lang_t *lang = lang_for_english([[[NSUserDefaults standardUserDefaults] stringForKey:@"DefaultLanguage"] UTF8String]);
+ [self.trackSelectionLanguages addObject:@(lang->iso639_2)];
+ }
+ if ([[NSUserDefaults standardUserDefaults] stringForKey:@"AlternateLanguage"])
+ {
+ iso639_lang_t *lang = lang_for_english([[[NSUserDefaults standardUserDefaults] stringForKey:@"AlternateLanguage"] UTF8String]);
+ [self.trackSelectionLanguages addObject:@(lang->iso639_2)];
+ }
+ }
+ }
+
+ // Passthru settings
+ self.allowAACPassthru = [preset[@"AudioAllowAACPass"] boolValue];
+ self.allowAC3Passthru = [preset[@"AudioAllowAC3Pass"] boolValue];
+ self.allowDTSHDPassthru = [preset[@"AudioAllowDTSHDPass"] boolValue];
+ self.allowDTSPassthru= [preset[@"AudioAllowDTSPass"] boolValue];
+ self.allowMP3Passthru = [preset[@"AudioAllowMP3Pass"] boolValue];
+
+ self.secondaryEncoderMode = [preset[@"AudioSecondaryEncoderMode"] boolValue];
+
+ if (preset[@"AudioEncoderFallback"])
+ {
+ // map legacy encoder names via libhb
+ const char *strValue = hb_audio_encoder_sanitize_name([preset[@"AudioEncoderFallback"] UTF8String]);
+ self.encoderFallback = hb_audio_encoder_get_from_name(strValue);
+ }
+
+ for (NSDictionary *track in preset[@"AudioList"])
+ {
+ HBAudioTrackPreset *newTrack = [[HBAudioTrackPreset alloc] init];
+ newTrack.encoder = hb_audio_encoder_get_from_name([track[@"AudioEncoder"] UTF8String]);
+ newTrack.mixdown = hb_mixdown_get_from_name([track[@"AudioMixdown"] UTF8String]);
+ newTrack.sampleRate = [track[@"AudioSamplerate"] intValue];
+ newTrack.bitRate = [track[@"AudioBitrate"] intValue];
+
+ newTrack.drc = [track[@"AudioTrackDRCSlider"] intValue];
+ newTrack.gain = [track[@"AudioTrackGainSlider"] intValue];
+ [self.tracksArray addObject:newTrack];
+ [newTrack release];
+ }
+}
+
+- (void)prepareAudioForPreset:(NSMutableDictionary *)preset
+{
+ // Track selection behavior
+ if (self.trackSelectionBehavior == HBAudioTrackSelectionBehaviorFirst)
+ {
+ preset[@"AudioTrackSelectionBehavior"] = @"first";
+ }
+ else if (self.trackSelectionBehavior == HBAudioTrackSelectionBehaviorAll)
+ {
+ preset[@"AudioTrackSelectionBehavior"] = @"all";
+ }
+ else
+ {
+ preset[@"AudioTrackSelectionBehavior"] = @"none";
+ }
+ preset[@"AudioLanguageList"] = self.trackSelectionLanguages;
+
+ // Passthru settings
+ preset[@"AudioAllowAACPass"] = @(self.allowAACPassthru);
+ preset[@"AudioAllowAC3Pass"] = @(self.allowAC3Passthru);
+ preset[@"AudioAllowDTSHDPass"] = @(self.allowDTSHDPassthru);
+ preset[@"AudioAllowDTSPass"] = @(self.allowDTSPassthru);
+ preset[@"AudioAllowMP3Pass"] = @(self.allowMP3Passthru);
+
+ preset[@"AudioEncoderFallback"] = @(hb_audio_encoder_get_name(self.encoderFallback));
+
+ preset[@"AudioSecondaryEncoderMode"] = @(self.secondaryEncoderMode);
+
+ NSMutableArray *audioList = [[NSMutableArray alloc] init];
+
+ for (HBAudioTrackPreset *track in self.tracksArray)
+ {
+ NSDictionary *newTrack = @{@"AudioEncoder": @(hb_audio_encoder_get_name(track.encoder)),
+ @"AudioMixdown": @(hb_mixdown_get_name(track.mixdown)),
+ @"AudioSamplerate": @(track.sampleRate),
+ @"AudioBitrate": @(track.bitRate),
+ @"AudioTrackDRCSlider": @(track.drc),
+ @"AudioTrackGainSlider": @(track.gain)};
+
+ [audioList addObject:newTrack];
+ }
+
+ preset[@"AudioList"] = audioList;
+ [audioList release];
+}
+
+- (void)validateEncoderFallbackForVideoContainer:(int)container
+{
+ BOOL isValid = NO;
+ for (const hb_encoder_t *audio_encoder = hb_audio_encoder_get_next(NULL);
+ audio_encoder != NULL;
+ audio_encoder = hb_audio_encoder_get_next(audio_encoder))
+ {
+ if (audio_encoder->muxers & container)
+ {
+ if (audio_encoder->codec == self.encoderFallback)
+ {
+ isValid = YES;
+ break;
+ }
+ }
+ }
+
+ if (!isValid)
+ {
+ self.encoderFallback = HB_ACODEC_AC3;
+ }
+
+ self.container = container;
+}
+
+@end
diff --git a/macosx/HBAudioTrackPreset.h b/macosx/HBAudioTrackPreset.h
new file mode 100644
index 000000000..49abe9820
--- /dev/null
+++ b/macosx/HBAudioTrackPreset.h
@@ -0,0 +1,53 @@
+//
+// HBAudioEncoder.h
+// HandBrake
+//
+// Created by Damiano Galassi on 30/07/14.
+//
+//
+
+#import <Foundation/Foundation.h>
+
+/**
+ * HBAudioTrackPreset
+ * a KVO enabled class used in the Audio Defaults panels,
+ * automatically validates the values.
+ */
+@interface HBAudioTrackPreset : NSObject
+
+/**
+ * track properties.
+ */
+@property (nonatomic, readwrite) int encoder;
+@property (nonatomic, readwrite) int mixdown;
+@property (nonatomic, readwrite) int sampleRate;
+@property (nonatomic, readwrite) int bitRate;
+
+@property (nonatomic, readwrite) int gain;
+@property (nonatomic, readwrite) int drc;
+
+/**
+ * Arrays of possible options for the track properties.
+ */
+@property (nonatomic, readonly) NSArray *encoders;
+@property (nonatomic, readonly) NSArray *mixdowns;
+@property (nonatomic, readonly) NSArray *samplerates;
+@property (nonatomic, readonly) NSArray *bitrates;
+
+@end
+
+/**
+ * A series of value trasformers to bridge the libhb enums
+ * to the textual rapresentations used in the interface.
+ */
+@interface HBEncoderTrasformer : NSValueTransformer
+@end
+
+@interface HBMixdownTrasformer : NSValueTransformer
+@end
+
+@interface HBSampleRateTrasformer : NSValueTransformer
+@end
+
+@interface HBIntegerTrasformer : NSValueTransformer
+@end \ No newline at end of file
diff --git a/macosx/HBAudioTrackPreset.m b/macosx/HBAudioTrackPreset.m
new file mode 100644
index 000000000..9f91c3ab8
--- /dev/null
+++ b/macosx/HBAudioTrackPreset.m
@@ -0,0 +1,370 @@
+//
+// HBAudioEncoder.m
+// HandBrake
+//
+// Created by Damiano Galassi on 30/07/14.
+//
+//
+
+#import "HBAudioTrackPreset.h"
+#include "hb.h"
+
+#define DEFAULT_SAMPLERATE 48000
+
+static void *HBAudioEncoderContex = &HBAudioEncoderContex;
+
+@implementation HBAudioTrackPreset
+
+- (instancetype)init
+{
+ self = [super init];
+ if (self) {
+ // defaults settings
+ _encoder = HB_ACODEC_CA_AAC;
+ _sampleRate = 0;
+ _bitRate = 160;
+ _mixdown = HB_AMIXDOWN_DOLBYPLII;
+
+ // add a serie of observers to keep the tracks properties in a valid state.
+ [self addObserver:self forKeyPath:@"encoder" options:0 context:HBAudioEncoderContex];
+ [self addObserver:self forKeyPath:@"mixdown" options:0 context:HBAudioEncoderContex];
+ [self addObserver:self forKeyPath:@"sampleRate" options:0 context:HBAudioEncoderContex];
+ }
+ return self;
+}
+
+- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
+{
+ if (context == HBAudioEncoderContex)
+ {
+ // Validate the settings
+ if ([keyPath isEqualToString:@"encoder"])
+ {
+ [self validateMixdown];
+ [self validateBitrate];
+ }
+ else if ([keyPath isEqualToString:@"mixdown"] || [keyPath isEqualToString:@"sampleRate"])
+ {
+ [self validateBitrate];
+ }
+ }
+ else
+ {
+ [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
+ }
+}
+
+#pragma mark -
+#pragma mark Validation
+
+/**
+ * Validates the mixdown property.
+ */
+- (void)validateMixdown
+{
+ if (!hb_mixdown_has_codec_support(self.mixdown, self.encoder))
+ {
+ self.mixdown = hb_mixdown_get_default(self.encoder, 0);
+ }
+}
+
+- (void)validateBitrate
+{
+ int minBitRate = 0;
+ int maxBitRate = 0;
+
+ int sampleRate = self.sampleRate ? self.sampleRate : DEFAULT_SAMPLERATE;
+
+ hb_audio_bitrate_get_limits(self.encoder, sampleRate, self.mixdown, &minBitRate, &maxBitRate);
+
+ if (self.bitRate < minBitRate || self.bitRate > maxBitRate)
+ {
+ self.bitRate = maxBitRate;
+ }
+}
+
+- (BOOL)mixdownEnabled
+{
+ BOOL retval = YES;
+
+ if (self.mixdown == HB_AMIXDOWN_NONE)
+ {
+ // "None" mixdown (passthru)
+ retval = NO;
+ }
+
+ return retval;
+}
+
+- (BOOL)bitrateEnabled
+{
+ BOOL retval = YES;
+
+ int myCodecDefaultBitrate = hb_audio_bitrate_get_default(self.encoder, 0, 0);
+ if (myCodecDefaultBitrate < 0)
+ {
+ retval = NO;
+ }
+ return retval;
+}
+
+- (BOOL)passThruDisabled
+{
+ BOOL retval = YES;
+
+ if (self.encoder & HB_ACODEC_PASS_FLAG)
+ {
+ retval = NO;
+ }
+
+ return retval;
+}
+
+// Because we have indicated that the binding for the drc validates immediately we can implement the
+// key value binding method to ensure the drc stays in our accepted range.
+- (BOOL)validateDrc:(id *)ioValue error:(NSError *)outError
+{
+ BOOL retval = YES;
+
+ if (nil != *ioValue)
+ {
+ if (0.0 < [*ioValue floatValue] && 1.0 > [*ioValue floatValue])
+ {
+ *ioValue = @(1.0);
+ }
+ }
+
+ return retval;
+}
+
+// Because we have indicated that the binding for the gain validates immediately we can implement the
+// key value binding method to ensure the gain stays in our accepted range.
+
+- (BOOL)validateGain:(id *)ioValue error:(NSError *)outError
+{
+ BOOL retval = YES;
+
+ if (nil != *ioValue)
+ {
+ if (0.0 < [*ioValue floatValue] && 1.0 > [*ioValue floatValue])
+ {
+ *ioValue = @(0.0);
+ }
+ }
+
+ return retval;
+}
+
+- (void)dealloc
+{
+ // Remove the KVO observers before deallocing the instance.
+ [self removeObserver:self forKeyPath:@"encoder"];
+ [self removeObserver:self forKeyPath:@"mixdown"];
+ [self removeObserver:self forKeyPath:@"sampleRate"];
+
+ [super dealloc];
+}
+
+#pragma mark - Options
+
+- (NSArray *)encoders
+{
+ NSMutableArray *encoders = [[NSMutableArray alloc] init];
+ for (const hb_encoder_t *audio_encoder = hb_audio_encoder_get_next(NULL);
+ audio_encoder != NULL;
+ audio_encoder = hb_audio_encoder_get_next(audio_encoder))
+ {
+ [encoders addObject:@(audio_encoder->name)];
+ }
+ return [encoders autorelease];
+}
+
+- (NSArray *)mixdowns
+{
+ NSMutableArray *mixdowns = [[NSMutableArray alloc] init];
+ for (const hb_mixdown_t *mixdown = hb_mixdown_get_next(NULL);
+ mixdown != NULL;
+ mixdown = hb_mixdown_get_next(mixdown))
+ {
+ if (hb_mixdown_has_codec_support(mixdown->amixdown, self.encoder))
+ {
+ [mixdowns addObject:@(mixdown->name)];
+ }
+ }
+ return [mixdowns autorelease];
+}
+
+- (NSArray *)samplerates
+{
+ NSMutableArray *samplerates = [[NSMutableArray alloc] init];
+ for (const hb_rate_t *audio_samplerate = hb_audio_samplerate_get_next(NULL);
+ audio_samplerate != NULL;
+ audio_samplerate = hb_audio_samplerate_get_next(audio_samplerate))
+ {
+ [samplerates addObject:@(audio_samplerate->name)];
+ }
+ return [samplerates autorelease];
+}
+
+- (NSArray *)bitrates
+{
+ int minBitRate = 0;
+ int maxBitRate = 0;
+
+ // If the samplerate is "Auto" pass a fake sampleRate to get the bitrates
+ int sampleRate = self.sampleRate ? self.sampleRate : DEFAULT_SAMPLERATE;
+
+ hb_audio_bitrate_get_limits(self.encoder, sampleRate, self.mixdown, &minBitRate, &maxBitRate);
+
+ NSMutableArray *bitrates = [[NSMutableArray alloc] init];
+ for (const hb_rate_t *audio_bitrate = hb_audio_bitrate_get_next(NULL);
+ audio_bitrate != NULL;
+ audio_bitrate = hb_audio_bitrate_get_next(audio_bitrate))
+ {
+ if (audio_bitrate->rate >= minBitRate && audio_bitrate->rate <= maxBitRate)
+ {
+ [bitrates addObject:@(audio_bitrate->name)];
+ }
+ }
+ return [bitrates autorelease];
+}
+
++ (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key
+{
+ NSSet *retval = nil;
+
+ // Tell KVO to reaload the *enabled keyPaths
+ // after a change to encoder.
+ if ([key isEqualToString:@"bitrateEnabled"] ||
+ [key isEqualToString:@"passThruDisabled"] ||
+ [key isEqualToString:@"mixdownEnabled"])
+ {
+ retval = [NSSet setWithObjects:@"encoder", nil];
+ }
+
+ return retval;
+}
+
+@end
+
+#pragma mark - Value Trasformers
+
+@implementation HBEncoderTrasformer
+
++ (Class)transformedValueClass
+{
+ return [NSString class];
+}
+
+- (id)transformedValue:(id)value
+{
+ const char *name = hb_audio_encoder_get_name([value intValue]);
+ if (name)
+ {
+ return @(name);
+ }
+ else
+ {
+ return nil;
+ }
+}
+
++ (BOOL)allowsReverseTransformation
+{
+ return YES;
+}
+
+- (id)reverseTransformedValue:(id)value
+{
+ return @(hb_audio_encoder_get_from_name([value UTF8String]));
+}
+
+@end
+
+@implementation HBMixdownTrasformer
+
++ (Class)transformedValueClass
+{
+ return [NSString class];
+}
+
+- (id)transformedValue:(id)value
+{
+ const char *name = hb_mixdown_get_name([value intValue]);
+ if (name)
+ {
+ return @(name);
+ }
+ else
+ {
+ return nil;
+ }
+}
+
++ (BOOL)allowsReverseTransformation
+{
+ return YES;
+}
+
+- (id)reverseTransformedValue:(id)value
+{
+ return @(hb_mixdown_get_from_name([value UTF8String]));
+}
+
+@end
+
+@implementation HBSampleRateTrasformer
+
++ (Class)transformedValueClass
+{
+ return [NSString class];
+}
+
+- (id)transformedValue:(id)value
+{
+ const char *name = hb_audio_samplerate_get_name([value intValue]);
+ if (name)
+ {
+ return @(name);
+ }
+ else
+ {
+ return nil;
+ }
+}
+
++ (BOOL)allowsReverseTransformation
+{
+ return YES;
+}
+
+- (id)reverseTransformedValue:(id)value
+{
+ return @(hb_audio_samplerate_get_from_name([value UTF8String]));
+}
+
+@end
+
+@implementation HBIntegerTrasformer
+
++ (Class)transformedValueClass
+{
+ return [NSString class];
+}
+
+- (id)transformedValue:(id)value
+{
+ return [value stringValue];
+}
+
++ (BOOL)allowsReverseTransformation
+{
+ return YES;
+}
+
+- (id)reverseTransformedValue:(id)value
+{
+ return @([value intValue]);
+}
+
+@end
diff --git a/macosx/HandBrake.xcodeproj/project.pbxproj b/macosx/HandBrake.xcodeproj/project.pbxproj
index 25409b195..9bae27c06 100644
--- a/macosx/HandBrake.xcodeproj/project.pbxproj
+++ b/macosx/HandBrake.xcodeproj/project.pbxproj
@@ -116,7 +116,11 @@
27D6C77314B102DA00B785E4 /* libxml2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 27D6C74014B102DA00B785E4 /* libxml2.a */; };
3490BCB41614CF8D002A5AD7 /* HandBrake.icns in Resources */ = {isa = PBXBuildFile; fileRef = 3490BCB31614CF8D002A5AD7 /* HandBrake.icns */; };
46AB433515F98A2B009C0961 /* DockTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = 46AB433415F98A2B009C0961 /* DockTextField.m */; };
+ A90A0CAF1988D57200DA65CE /* HBAudioTrackPreset.m in Sources */ = {isa = PBXBuildFile; fileRef = A90A0CAE1988D57200DA65CE /* HBAudioTrackPreset.m */; };
A91726E7197291BC00D1AFEF /* HBChapterTitlesController.m in Sources */ = {isa = PBXBuildFile; fileRef = A91726E6197291BC00D1AFEF /* HBChapterTitlesController.m */; };
+ A932E26C1988334B0047D13E /* AudioDefaults.xib in Resources */ = {isa = PBXBuildFile; fileRef = A932E26A1988334B0047D13E /* AudioDefaults.xib */; };
+ A932E26F198833920047D13E /* HBAudioDefaultsController.m in Sources */ = {isa = PBXBuildFile; fileRef = A932E26E198833920047D13E /* HBAudioDefaultsController.m */; };
+ A932E273198834130047D13E /* HBAudioSettings.m in Sources */ = {isa = PBXBuildFile; fileRef = A932E272198834130047D13E /* HBAudioSettings.m */; };
A93E0ED31972957000FD67FB /* HBVideoController.m in Sources */ = {isa = PBXBuildFile; fileRef = A93E0ED11972957000FD67FB /* HBVideoController.m */; };
A93E0ED71972958C00FD67FB /* Video.xib in Resources */ = {isa = PBXBuildFile; fileRef = A93E0ED51972958C00FD67FB /* Video.xib */; };
A98C29C41977B10600AF5DED /* HBLanguagesSelection.m in Sources */ = {isa = PBXBuildFile; fileRef = A98C29C31977B10600AF5DED /* HBLanguagesSelection.m */; };
@@ -316,8 +320,15 @@
3490BCB31614CF8D002A5AD7 /* HandBrake.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = HandBrake.icns; sourceTree = "<group>"; };
46AB433315F98A2B009C0961 /* DockTextField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DockTextField.h; sourceTree = "<group>"; };
46AB433415F98A2B009C0961 /* DockTextField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DockTextField.m; sourceTree = "<group>"; };
+ A90A0CAD1988D57200DA65CE /* HBAudioTrackPreset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HBAudioTrackPreset.h; sourceTree = "<group>"; };
+ A90A0CAE1988D57200DA65CE /* HBAudioTrackPreset.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HBAudioTrackPreset.m; sourceTree = "<group>"; };
A91726E5197291BC00D1AFEF /* HBChapterTitlesController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HBChapterTitlesController.h; sourceTree = "<group>"; };
A91726E6197291BC00D1AFEF /* HBChapterTitlesController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HBChapterTitlesController.m; sourceTree = "<group>"; };
+ A932E26B1988334B0047D13E /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = AudioDefaults.xib; sourceTree = "<group>"; };
+ A932E26D198833920047D13E /* HBAudioDefaultsController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HBAudioDefaultsController.h; sourceTree = "<group>"; };
+ A932E26E198833920047D13E /* HBAudioDefaultsController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HBAudioDefaultsController.m; sourceTree = "<group>"; };
+ A932E271198834130047D13E /* HBAudioSettings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HBAudioSettings.h; sourceTree = "<group>"; };
+ A932E272198834130047D13E /* HBAudioSettings.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HBAudioSettings.m; sourceTree = "<group>"; };
A93E0ED01972957000FD67FB /* HBVideoController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HBVideoController.h; sourceTree = "<group>"; };
A93E0ED11972957000FD67FB /* HBVideoController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HBVideoController.m; sourceTree = "<group>"; };
A93E0ED61972958C00FD67FB /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = Video.xib; sourceTree = "<group>"; };
@@ -655,6 +666,7 @@
273F217E14ADDDA10021BE6D /* MainMenu.xib */,
A93E0ED51972958C00FD67FB /* Video.xib */,
A9F2EB6D196F12C800066546 /* Audio.xib */,
+ A932E26A1988334B0047D13E /* AudioDefaults.xib */,
A9DC6C54196F0517002AE6B4 /* Subtitles.xib */,
A9C0DB83197E7B0000DF55B3 /* SubtitlesDefaults.xib */,
273F217A14ADDDA10021BE6D /* AdvancedView.xib */,
@@ -721,13 +733,26 @@
name = "Products (external)";
sourceTree = "<group>";
};
+ A932E270198833960047D13E /* Audio Defaults */ = {
+ isa = PBXGroup;
+ children = (
+ A932E26D198833920047D13E /* HBAudioDefaultsController.h */,
+ A932E26E198833920047D13E /* HBAudioDefaultsController.m */,
+ );
+ name = "Audio Defaults";
+ sourceTree = "<group>";
+ };
A98C29C51977C00000AF5DED /* Model */ = {
isa = PBXGroup;
children = (
273F20A114ADBE670021BE6D /* HBPresets.h */,
273F20A214ADBE670021BE6D /* HBPresets.m */,
+ A932E271198834130047D13E /* HBAudioSettings.h */,
+ A932E272198834130047D13E /* HBAudioSettings.m */,
A9F4728B1976BAA70009EC65 /* HBSubtitlesSettings.h */,
A9F4728C1976BAA70009EC65 /* HBSubtitlesSettings.m */,
+ A90A0CAD1988D57200DA65CE /* HBAudioTrackPreset.h */,
+ A90A0CAE1988D57200DA65CE /* HBAudioTrackPreset.m */,
A98C29C21977B10600AF5DED /* HBLanguagesSelection.h */,
A98C29C31977B10600AF5DED /* HBLanguagesSelection.m */,
);
@@ -765,6 +790,7 @@
273F209214ADBE670021BE6D /* HBAudio.m */,
273F209314ADBE670021BE6D /* HBAudioController.h */,
273F209414ADBE670021BE6D /* HBAudioController.m */,
+ A932E270198833960047D13E /* Audio Defaults */,
A9DC6C4F196F04F6002AE6B4 /* HBSubtitlesController.h */,
A9DC6C50196F04F6002AE6B4 /* HBSubtitlesController.m */,
A9F472851976B7AA0009EC65 /* Subtitles Defaults */,
@@ -908,6 +934,7 @@
273F216A14ADCBF80021BE6D /* RevealPressed.png in Resources */,
273F218A14ADDDA10021BE6D /* AdvancedView.xib in Resources */,
273F218B14ADDDA10021BE6D /* InfoPlist.strings in Resources */,
+ A932E26C1988334B0047D13E /* AudioDefaults.xib in Resources */,
273F218C14ADDDA10021BE6D /* MainMenu.xib in Resources */,
273F218D14ADDDA10021BE6D /* OutputPanel.xib in Resources */,
273F218E14ADDDA10021BE6D /* PicturePreview.xib in Resources */,
@@ -970,6 +997,7 @@
buildActionMask = 2147483647;
files = (
A98C29C41977B10600AF5DED /* HBLanguagesSelection.m in Sources */,
+ A932E273198834130047D13E /* HBAudioSettings.m in Sources */,
A9AA447A1970664A00D7DEFC /* HBUtilities.m in Sources */,
273F20AC14ADBE670021BE6D /* Controller.m in Sources */,
273F20AD14ADBE670021BE6D /* HBAdvancedController.m in Sources */,
@@ -987,10 +1015,12 @@
273F20B614ADBE670021BE6D /* HBPresets.m in Sources */,
273F20B714ADBE670021BE6D /* HBPreviewController.m in Sources */,
A9D1E41718262364002F6424 /* HBPreviewGenerator.m in Sources */,
+ A90A0CAF1988D57200DA65CE /* HBAudioTrackPreset.m in Sources */,
273F20B814ADBE670021BE6D /* HBQueueController.mm in Sources */,
273F20BA14ADBE670021BE6D /* PictureController.m in Sources */,
273F20BE14ADC09F0021BE6D /* main.mm in Sources */,
A91726E7197291BC00D1AFEF /* HBChapterTitlesController.m in Sources */,
+ A932E26F198833920047D13E /* HBAudioDefaultsController.m in Sources */,
46AB433515F98A2B009C0961 /* DockTextField.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -1075,6 +1105,14 @@
name = Queue.xib;
sourceTree = "<group>";
};
+ A932E26A1988334B0047D13E /* AudioDefaults.xib */ = {
+ isa = PBXVariantGroup;
+ children = (
+ A932E26B1988334B0047D13E /* English */,
+ );
+ name = AudioDefaults.xib;
+ sourceTree = "<group>";
+ };
A93E0ED51972958C00FD67FB /* Video.xib */ = {
isa = PBXVariantGroup;
children = (
diff --git a/macosx/xcconfig/base/os.osx106.xcconfig b/macosx/xcconfig/base/os.osx106.xcconfig
index 978cae0d6..2d42c9356 100644
--- a/macosx/xcconfig/base/os.osx106.xcconfig
+++ b/macosx/xcconfig/base/os.osx106.xcconfig
@@ -1,3 +1,2 @@
-SDKROOT = macosx10.6
MACOSX_DEPLOYMENT_TARGET = 10.6
CLANG_LINK_OBJC_RUNTIME = NO