summaryrefslogtreecommitdiffstats
path: root/macosx
diff options
context:
space:
mode:
Diffstat (limited to 'macosx')
-rw-r--r--macosx/English.lproj/Audio.xib142
-rw-r--r--macosx/HBAudio.h6
-rw-r--r--macosx/HBAudio.m455
-rw-r--r--macosx/HBAudioTrack.h65
-rw-r--r--macosx/HBAudioTrack.m761
-rw-r--r--macosx/HBAudioTrackPreset.h16
-rw-r--r--macosx/HBAudioTrackPreset.m143
-rw-r--r--macosx/HBAudioTransformers.h25
-rw-r--r--macosx/HBAudioTransformers.m143
-rw-r--r--macosx/HBJob+HBJobConversion.m28
-rw-r--r--macosx/HBJob+UIAdditions.m66
-rw-r--r--macosx/HandBrake.xcodeproj/project.pbxproj8
12 files changed, 866 insertions, 992 deletions
diff --git a/macosx/English.lproj/Audio.xib b/macosx/English.lproj/Audio.xib
index ff7a77e8e..d24db6cb9 100644
--- a/macosx/English.lproj/Audio.xib
+++ b/macosx/English.lproj/Audio.xib
@@ -1,9 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="10117" systemVersion="16A238m" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11198.2" systemVersion="16A313a" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
- <development version="7000" identifier="xcode"/>
- <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="10117"/>
+ <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11198.2"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="HBAudioController">
@@ -13,32 +12,7 @@
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
- <arrayController preservesSelection="NO" avoidsEmptySelection="NO" id="rzb-Si-Kpf">
- <declaredKeys>
- <string>tracks</string>
- <string>tracks.keyAudioTrackName</string>
- <string>track</string>
- <string>enabled</string>
- <string>mixdownEnabled</string>
- <string>drc</string>
- <string>codecs</string>
- <string>codecs.keyAudioCodecName</string>
- <string>codec</string>
- <string>mixdowns</string>
- <string>mixdowns.keyAudioMixdownName</string>
- <string>mixdown</string>
- <string>sampleRates</string>
- <string>sampleRates.keyAudioSampleRateName</string>
- <string>sampleRate</string>
- <string>bitRates</string>
- <string>bitRates.keyAudioBitrateName</string>
- <string>bitRate</string>
- <string>DRCEnabled</string>
- <string>gain</string>
- <string>PassThruEnabled</string>
- <string>PassThruDisabled</string>
- <string>bitrateEnabled</string>
- </declaredKeys>
+ <arrayController objectClassName="HBAudioTrack" preservesSelection="NO" avoidsEmptySelection="NO" id="rzb-Si-Kpf">
<connections>
<binding destination="-2" name="contentArray" keyPath="self.audio.tracks" id="W0u-41-zX4"/>
</connections>
@@ -148,9 +122,8 @@
<menu key="menu" id="hXU-xc-dxL"/>
</popUpButtonCell>
<connections>
- <binding destination="wJH-tU-zL6" name="content" keyPath="objectValue.masterTrackArray" id="pvQ-pN-TdG"/>
- <binding destination="wJH-tU-zL6" name="contentValues" keyPath="objectValue.masterTrackArray.keyAudioTrackName" previousBinding="pvQ-pN-TdG" id="Wec-Fo-DSj"/>
- <binding destination="wJH-tU-zL6" name="selectedObject" keyPath="objectValue.track" previousBinding="Wec-Fo-DSj" id="Qoy-ym-QWQ"/>
+ <binding destination="wJH-tU-zL6" name="selectedIndex" keyPath="objectValue.sourceTrackIdx" previousBinding="LnY-7P-b37" id="CWi-rR-r7Y"/>
+ <binding destination="wJH-tU-zL6" name="content" keyPath="objectValue.sourceTracksArray" id="LnY-7P-b37"/>
</connections>
</popUpButton>
</subviews>
@@ -190,10 +163,13 @@
</connections>
</popUpButtonCell>
<connections>
- <binding destination="8ed-5g-y6e" name="selectedObject" keyPath="objectValue.codec" previousBinding="cvm-Mj-Drh" id="sEl-p7-19g"/>
- <binding destination="8ed-5g-y6e" name="content" keyPath="objectValue.codecs" id="pxN-GH-Dfr"/>
- <binding destination="8ed-5g-y6e" name="contentValues" keyPath="objectValue.codecs.keyAudioCodecName" previousBinding="pxN-GH-Dfr" id="cvm-Mj-Drh"/>
- <binding destination="8ed-5g-y6e" name="enabled" keyPath="objectValue.enabled" id="V0U-a3-ZBW"/>
+ <binding destination="8ed-5g-y6e" name="selectedValue" keyPath="objectValue.encoder" previousBinding="Ojx-pY-iTj" id="aRL-2h-rz1">
+ <dictionary key="options">
+ <string key="NSValueTransformerName">HBEncoderTransformer</string>
+ </dictionary>
+ </binding>
+ <binding destination="8ed-5g-y6e" name="content" keyPath="objectValue.encoders" id="Ojx-pY-iTj"/>
+ <binding destination="8ed-5g-y6e" name="enabled" keyPath="objectValue.isEnabled" id="hNs-V2-g3t"/>
</connections>
</popUpButton>
</subviews>
@@ -230,10 +206,21 @@
<menu key="menu" id="5Ha-Of-SJF"/>
</popUpButtonCell>
<connections>
- <binding destination="JWs-Gl-4kd" name="selectedObject" keyPath="objectValue.mixdown" previousBinding="mrr-Rw-0Km" id="fAC-AG-TmT"/>
- <binding destination="JWs-Gl-4kd" name="enabled" keyPath="objectValue.mixdownEnabled" id="anJ-dk-glQ"/>
+ <binding destination="JWs-Gl-4kd" name="enabled" keyPath="objectValue.isEnabled" id="tgd-cw-Xvj"/>
+ <binding destination="JWs-Gl-4kd" name="selectedValue" keyPath="objectValue.mixdown" previousBinding="N2w-i8-sMD" id="0hr-bn-M8A">
+ <dictionary key="options">
+ <string key="NSValueTransformerName">HBMixdownTransformer</string>
+ </dictionary>
+ </binding>
+ <binding destination="JWs-Gl-4kd" name="enabled2" keyPath="objectValue.mixdownEnabled" previousBinding="tgd-cw-Xvj" id="cYM-fO-KQf">
+ <dictionary key="options">
+ <integer key="NSMultipleValuesPlaceholder" value="-1"/>
+ <integer key="NSNoSelectionPlaceholder" value="-1"/>
+ <integer key="NSNotApplicablePlaceholder" value="-1"/>
+ <integer key="NSNullPlaceholder" value="-1"/>
+ </dictionary>
+ </binding>
<binding destination="JWs-Gl-4kd" name="content" keyPath="objectValue.mixdowns" id="N2w-i8-sMD"/>
- <binding destination="JWs-Gl-4kd" name="contentValues" keyPath="objectValue.mixdowns.keyAudioMixdownName" previousBinding="N2w-i8-sMD" id="mrr-Rw-0Km"/>
</connections>
</popUpButton>
</subviews>
@@ -270,10 +257,22 @@
<menu key="menu" id="phf-E4-JNn"/>
</popUpButtonCell>
<connections>
- <binding destination="iQl-Lr-pqe" name="enabled" keyPath="objectValue.mixdownEnabled" id="7np-q0-yTV"/>
- <binding destination="iQl-Lr-pqe" name="selectedObject" keyPath="objectValue.sampleRate" previousBinding="lhu-ag-YDS" id="2BU-o2-PJ0"/>
+ <binding destination="iQl-Lr-pqe" name="enabled" keyPath="objectValue.isEnabled" id="XCQ-bF-dAC"/>
+ <binding destination="iQl-Lr-pqe" name="enabled2" keyPath="objectValue.mixdownEnabled" previousBinding="XCQ-bF-dAC" id="apI-pR-y7v">
+ <dictionary key="options">
+ <integer key="NSMultipleValuesPlaceholder" value="-1"/>
+ <integer key="NSNoSelectionPlaceholder" value="-1"/>
+ <integer key="NSNotApplicablePlaceholder" value="-1"/>
+ <integer key="NSNullPlaceholder" value="-1"/>
+ </dictionary>
+ </binding>
+ <binding destination="iQl-Lr-pqe" name="selectedValue" keyPath="objectValue.sampleRate" previousBinding="Q5x-J9-u3J" id="hlm-8l-ATk">
+ <dictionary key="options">
+ <string key="NSNullPlaceholder">Auto</string>
+ <string key="NSValueTransformerName">HBSampleRateTransformer</string>
+ </dictionary>
+ </binding>
<binding destination="iQl-Lr-pqe" name="content" keyPath="objectValue.sampleRates" id="Q5x-J9-u3J"/>
- <binding destination="iQl-Lr-pqe" name="contentValues" keyPath="objectValue.sampleRates.keyAudioSampleRateName" previousBinding="Q5x-J9-u3J" id="lhu-ag-YDS"/>
</connections>
</popUpButton>
</subviews>
@@ -310,10 +309,21 @@
<menu key="menu" id="DFY-hE-Hi6"/>
</popUpButtonCell>
<connections>
- <binding destination="Acc-Cw-PLD" name="selectedObject" keyPath="objectValue.bitRate" previousBinding="cgA-Y3-ucA" id="9OJ-Wp-j0I"/>
+ <binding destination="Acc-Cw-PLD" name="selectedValue" keyPath="objectValue.bitRate" previousBinding="S0T-S3-WF5" id="y8e-kU-Kay">
+ <dictionary key="options">
+ <string key="NSValueTransformerName">HBIntegerTransformer</string>
+ </dictionary>
+ </binding>
<binding destination="Acc-Cw-PLD" name="content" keyPath="objectValue.bitRates" id="S0T-S3-WF5"/>
- <binding destination="Acc-Cw-PLD" name="contentValues" keyPath="objectValue.bitRates.keyAudioBitrateName" previousBinding="S0T-S3-WF5" id="cgA-Y3-ucA"/>
- <binding destination="Acc-Cw-PLD" name="enabled" keyPath="objectValue.bitrateEnabled" id="woZ-ZV-ZQJ"/>
+ <binding destination="Acc-Cw-PLD" name="enabled2" keyPath="objectValue.bitrateEnabled" previousBinding="vzn-iK-rgP" id="7aV-gO-WvY">
+ <dictionary key="options">
+ <integer key="NSMultipleValuesPlaceholder" value="-1"/>
+ <integer key="NSNoSelectionPlaceholder" value="-1"/>
+ <integer key="NSNotApplicablePlaceholder" value="-1"/>
+ <integer key="NSNullPlaceholder" value="-1"/>
+ </dictionary>
+ </binding>
+ <binding destination="Acc-Cw-PLD" name="enabled" keyPath="objectValue.isEnabled" id="vzn-iK-rgP"/>
</connections>
</popUpButton>
</subviews>
@@ -351,24 +361,40 @@
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
- <binding destination="wfV-Pi-jHd" name="enabled" keyPath="objectValue.PassThruDisabled" id="NnK-Vf-hM6"/>
<binding destination="wfV-Pi-jHd" name="value" keyPath="objectValue.gain" id="7hD-ql-cNT">
<dictionary key="options">
<bool key="NSValidatesImmediately" value="YES"/>
</dictionary>
</binding>
+ <binding destination="wfV-Pi-jHd" name="enabled" keyPath="objectValue.isEnabled" id="OrM-Yv-Fs0"/>
+ <binding destination="wfV-Pi-jHd" name="enabled2" keyPath="objectValue.passThruDisabled" previousBinding="OrM-Yv-Fs0" id="d6m-q5-unj">
+ <dictionary key="options">
+ <integer key="NSMultipleValuesPlaceholder" value="-1"/>
+ <integer key="NSNoSelectionPlaceholder" value="-1"/>
+ <integer key="NSNotApplicablePlaceholder" value="-1"/>
+ <integer key="NSNullPlaceholder" value="-1"/>
+ </dictionary>
+ </binding>
</connections>
</textField>
<slider horizontalHuggingPriority="750" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="gtC-MM-esd">
<rect key="frame" x="3" y="2" width="22" height="22"/>
<sliderCell key="cell" controlSize="small" continuous="YES" alignment="left" minValue="-5" maxValue="16" doubleValue="0.25" numberOfTickMarks="21" allowsTickMarkValuesOnly="YES" sliderType="circular" id="BBQ-FP-aQN"/>
<connections>
- <binding destination="wfV-Pi-jHd" name="enabled" keyPath="objectValue.PassThruDisabled" id="Wz3-ZW-SLi"/>
<binding destination="wfV-Pi-jHd" name="value" keyPath="objectValue.gain" id="bKN-kD-NjJ">
<dictionary key="options">
<bool key="NSValidatesImmediately" value="YES"/>
</dictionary>
</binding>
+ <binding destination="wfV-Pi-jHd" name="enabled" keyPath="objectValue.isEnabled" id="7nL-Mg-i86"/>
+ <binding destination="wfV-Pi-jHd" name="enabled2" keyPath="objectValue.passThruDisabled" previousBinding="7nL-Mg-i86" id="y1g-gJ-0g6">
+ <dictionary key="options">
+ <integer key="NSMultipleValuesPlaceholder" value="-1"/>
+ <integer key="NSNoSelectionPlaceholder" value="-1"/>
+ <integer key="NSNotApplicablePlaceholder" value="-1"/>
+ <integer key="NSNullPlaceholder" value="-1"/>
+ </dictionary>
+ </binding>
</connections>
</slider>
</subviews>
@@ -403,12 +429,20 @@
<rect key="frame" x="3" y="1" width="22" height="22"/>
<sliderCell key="cell" controlSize="small" continuous="YES" alignment="left" maxValue="4" numberOfTickMarks="16" allowsTickMarkValuesOnly="YES" sliderType="circular" id="nII-CW-aWc"/>
<connections>
- <binding destination="RMf-U7-5Td" name="enabled" keyPath="objectValue.DRCEnabled" id="tzk-tB-jEf"/>
+ <binding destination="RMf-U7-5Td" name="enabled2" keyPath="objectValue.drcEnabled" previousBinding="UGi-Kk-MwK" id="dVM-pa-gKf">
+ <dictionary key="options">
+ <integer key="NSMultipleValuesPlaceholder" value="-1"/>
+ <integer key="NSNoSelectionPlaceholder" value="-1"/>
+ <integer key="NSNotApplicablePlaceholder" value="-1"/>
+ <integer key="NSNullPlaceholder" value="-1"/>
+ </dictionary>
+ </binding>
<binding destination="RMf-U7-5Td" name="value" keyPath="objectValue.drc" id="GxO-He-2yi">
<dictionary key="options">
<bool key="NSValidatesImmediately" value="YES"/>
</dictionary>
</binding>
+ <binding destination="RMf-U7-5Td" name="enabled" keyPath="objectValue.isEnabled" id="UGi-Kk-MwK"/>
</connections>
</slider>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="yPh-4R-HRQ">
@@ -420,12 +454,20 @@
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
- <binding destination="RMf-U7-5Td" name="enabled" keyPath="objectValue.DRCEnabled" id="FS6-ca-Kmi"/>
+ <binding destination="RMf-U7-5Td" name="enabled2" keyPath="objectValue.drcEnabled" previousBinding="Vv3-g9-exh" id="lY2-Z2-4bl">
+ <dictionary key="options">
+ <integer key="NSMultipleValuesPlaceholder" value="-1"/>
+ <integer key="NSNoSelectionPlaceholder" value="-1"/>
+ <integer key="NSNotApplicablePlaceholder" value="-1"/>
+ <integer key="NSNullPlaceholder" value="-1"/>
+ </dictionary>
+ </binding>
<binding destination="RMf-U7-5Td" name="value" keyPath="objectValue.drc" id="f0P-bz-w9a">
<dictionary key="options">
<bool key="NSValidatesImmediately" value="YES"/>
</dictionary>
</binding>
+ <binding destination="RMf-U7-5Td" name="enabled" keyPath="objectValue.isEnabled" id="Vv3-g9-exh"/>
</connections>
</textField>
</subviews>
@@ -478,7 +520,7 @@
<constraint firstAttribute="bottom" secondItem="Yzu-Rk-hTv" secondAttribute="bottom" constant="20" symbolic="YES" id="uil-Nm-DIV"/>
<constraint firstItem="jrP-M5-2Rq" firstAttribute="baseline" secondItem="vFP-nq-IQg" secondAttribute="baseline" id="y3i-kl-lge"/>
</constraints>
- <point key="canvasLocation" x="730" y="-14"/>
+ <point key="canvasLocation" x="557" y="-38"/>
</view>
<menu id="hyy-qd-qpe">
<items>
diff --git a/macosx/HBAudio.h b/macosx/HBAudio.h
index 045970e6a..d56f59d16 100644
--- a/macosx/HBAudio.h
+++ b/macosx/HBAudio.h
@@ -19,7 +19,9 @@ extern NSString *HBAudioChangedNotification;
- (instancetype)initWithTitle:(HBTitle *)title;
-@property (nonatomic, readonly) NSMutableArray *tracks;
+@property (nonatomic, readonly) NSMutableArray<NSDictionary *> *sourceTracks;
+@property (nonatomic, readonly) NSMutableArray<HBAudioTrack *> *tracks;
+
@property (nonatomic, readwrite) HBAudioDefaults *defaults;
- (void)addAllTracks;
@@ -27,8 +29,6 @@ extern NSString *HBAudioChangedNotification;
- (void)reloadDefaults;
- (BOOL)anyCodecMatches:(int)codec;
-- (void)settingTrackToNone:(HBAudioTrack *)newNoneTrack;
-- (void)switchingTrackFromNone:(nullable HBAudioTrack *)noLongerNoneTrack;
@property (nonatomic, readwrite) int container;
@property (nonatomic, readwrite, weak, nullable) NSUndoManager *undo;
diff --git a/macosx/HBAudio.m b/macosx/HBAudio.m
index 8f8872777..81936d790 100644
--- a/macosx/HBAudio.m
+++ b/macosx/HBAudio.m
@@ -15,13 +15,11 @@
#include "hb.h"
+#define NONE_TRACK_INDEX 0
+
NSString *HBAudioChangedNotification = @"HBAudioChangedNotification";
@interface HBAudio () <HBAudioTrackDataSource, HBAudioTrackDelegate>
-
-@property (nonatomic, readonly, strong) NSDictionary *noneTrack;
-@property (nonatomic, readonly, strong) NSArray *masterTrackArray; // the master list of audio tracks from the title
-
@end
@implementation HBAudio
@@ -33,192 +31,172 @@ NSString *HBAudioChangedNotification = @"HBAudioChangedNotification";
{
_container = HB_MUX_MP4;
+ _sourceTracks = [title.audioTracks mutableCopy];
_tracks = [[NSMutableArray alloc] init];
_defaults = [[HBAudioDefaults alloc] init];
- _noneTrack = @{keyAudioTrackIndex: @0,
- keyAudioTrackName: NSLocalizedString(@"None", @"None"),
- keyAudioInputCodec: @0};
-
- NSMutableArray *sourceTracks = [NSMutableArray array];
- [sourceTracks addObject:_noneTrack];
- [sourceTracks addObjectsFromArray:title.audioTracks];
- _masterTrackArray = [sourceTracks copy];
-
- [self switchingTrackFromNone: nil]; // this ensures there is a None track at the end of the list
+ // Add the none and foreign track to the source array
+ NSDictionary *none = @{keyAudioTrackName: NSLocalizedString(@"None", nil)};
+ [_sourceTracks insertObject:none atIndex:0];
}
return self;
}
-- (void)addAllTracks
+#pragma mark - Data Source
+
+- (NSDictionary<NSString *, id> *)sourceTrackAtIndex:(NSUInteger)idx;
{
- [self addTracksFromDefaults:YES];
+ return self.sourceTracks[idx];
}
-- (void)removeAll
+- (NSArray<NSString *> *)sourceTracksArray
{
- [self _clearAudioArray];
- [self switchingTrackFromNone:nil];
+ NSMutableArray *sourceNames = [NSMutableArray array];
+
+ for (NSDictionary *track in self.sourceTracks)
+ {
+ [sourceNames addObject:track[keyAudioTrackName]];
+ }
+
+ return sourceNames;
}
-- (void)reloadDefaults
+#pragma mark - Delegate
+
+- (void)track:(HBAudioTrack *)track didChangeSourceFrom:(NSUInteger)oldSourceIdx;
{
- [self addTracksFromDefaults:NO];
+ // If the source was changed to None, remove the track
+ if (track.sourceTrackIdx == NONE_TRACK_INDEX)
+ {
+ NSUInteger idx = [self.tracks indexOfObject:track];
+ [self removeObjectFromTracksAtIndex:idx];
+ }
+ // Else add a new None track
+ else if (oldSourceIdx == NONE_TRACK_INDEX)
+ {
+ [self addNoneTrack];
+ }
}
-- (void)_clearAudioArray
+- (void)addNoneTrack
+{
+ HBAudioTrack *track = [self trackFromSourceTrackIndex:NONE_TRACK_INDEX];
+ [self addTrack:track];
+}
+
+#pragma mark - Public methods
+
+- (void)addAllTracks
{
- while (0 < [self countOfTracks])
+ while (self.countOfTracks)
{
- [self removeObjectFromTracksAtIndex: 0];
+ [self removeObjectFromTracksAtIndex:0];
+ }
+
+ // Add the remainings tracks
+ for (NSUInteger idx = 1; idx < self.sourceTracksArray.count; idx++) {
+ [self addTrack:[self trackFromSourceTrackIndex:idx]];
}
+
+ [self addNoneTrack];
}
-/**
- * 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
+- (void)removeAll
{
- for (HBAudioTrackPreset *preset in templateAudioArray)
+ while (self.countOfTracks)
{
- BOOL fallenBack = NO;
- HBAudioTrack *newAudio = [[HBAudioTrack alloc] init];
- [newAudio setDataSource:self];
- [newAudio setDelegate:self];
- [self insertObject: newAudio inTracksAtIndex: [self countOfTracks]];
- [newAudio setContainer:self.container];
- [newAudio setTrackFromIndex: (int)trackIndex];
- [newAudio setUndo:self.undo];
+ [self removeObjectFromTracksAtIndex:0];
+ }
+ [self addNoneTrack];
+}
- const char *name = hb_audio_encoder_get_name(preset.encoder);
- NSString *audioEncoder = nil;
+- (void)reloadDefaults
+{
+ [self addTracksFromDefaults];
+}
- // Check if we need to use a fallback
- if (name)
+- (void)setContainer:(int)container
+{
+ _container = container;
+ if (!(self.undo.isUndoing || self.undo.isRedoing))
+ {
+ for (HBAudioTrack *track in self.tracks)
{
- audioEncoder = @(name);
- if (preset.encoder & HB_ACODEC_PASS_FLAG &&
- ![newAudio setCodecFromName:audioEncoder])
- {
- int passthru, fallback;
- fallenBack = YES;
- 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.defaults.encoderFallback);
- }
- }
- else
- {
- name = hb_audio_encoder_sanitize_name([audioEncoder UTF8String]);
- }
- audioEncoder = @(name);
+ track.container = container;
}
- // 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:audioEncoder])
- {
- const char *mixdown = hb_mixdown_get_name(preset.mixdown);
- if (mixdown)
- {
- [newAudio setMixdownFromName: @(mixdown)];
- }
+ // Update the Auto Passthru Fallback Codec Popup
+ // lets get the tag of the currently selected item first so we might reset it later
+ [self.defaults validateEncoderFallbackForVideoContainer:container];
- const char *sampleRateName = hb_audio_samplerate_get_name(preset.sampleRate);
- if (!sampleRateName)
- {
- [newAudio setSampleRateFromName: @"Auto"];
- }
- else
- {
- [newAudio setSampleRateFromName: @(sampleRateName)];
- }
- if (!fallenBack)
- {
- [newAudio setBitRateFromName: [NSString stringWithFormat:@"%d", preset.bitRate]];
- }
- [newAudio setDrc:preset.drc];
- [newAudio setGain:preset.gain];
- }
- else
- {
- [self removeObjectFromTracksAtIndex: [self countOfTracks] - 1];
- }
+ //[self validatePassthru];
+ }
+}
- if (firstOnly)
- {
- break;
- }
+- (void)setUndo:(NSUndoManager *)undo
+{
+ _undo = undo;
+ for (HBAudioTrack *track in self.tracks)
+ {
+ track.undo = undo;
+ }
+ self.defaults.undo = undo;
+}
+
+- (void)setDefaults:(HBAudioDefaults *)defaults
+{
+ if (defaults != _defaults)
+ {
+ [[self.undo prepareWithInvocationTarget:self] setDefaults:_defaults];
}
+ _defaults = defaults;
+ _defaults.undo = self.undo;
}
/**
- * Matches the source audio tracks with the specific language iso code.
+ * Convenience method to add a track to tracks array.
*
- * @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.
+ * @param track the track to add.
*/
-- (NSIndexSet *)_tracksWithISOCode:(NSString *)isoCode selectOnlyFirst:(BOOL)selectOnlyFirst
+- (void)addTrack:(HBAudioTrack *)newTrack
{
- NSMutableIndexSet *indexes = [NSMutableIndexSet indexSet];
-
- // We search for the prefix noting that our titles have the format %d: %s where the %s is the prefix
- [self.masterTrackArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
- if (idx) // Note that we skip the "None" track
- {
- if ([isoCode isEqualToString:@"und"] || [obj[keyAudioTrackLanguageIsoCode] isEqualToString:isoCode])
- {
- [indexes addIndex:idx];
-
- if (selectOnlyFirst)
- {
- *stop = YES;
- }
- }
- }
- }];
-
- return indexes;
+ [self insertObject:newTrack inTracksAtIndex:[self countOfTracks]];
}
-- (void)_processPresetAudioArray:(NSArray *)templateAudioArray forTracks:(NSIndexSet *)trackIndexes firstOnly:(BOOL)firstOnly
+/**
+ * Creates a new track dictionary from a source track.
+ *
+ * @param index the index of the source track in the sourceTracks array
+ */
+- (HBAudioTrack *)trackFromSourceTrackIndex:(NSInteger)index
{
- __block BOOL firsTrack = firstOnly;
- [trackIndexes enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
- // Add the track
- [self _processPresetAudioArray: self.defaults.tracksArray forTrack:idx firstOnly:firsTrack];
- firsTrack = self.defaults.secondaryEncoderMode ? YES : NO;
- }];
+ HBAudioTrack *track = [[HBAudioTrack alloc] initWithTrackIdx:index container:self.container dataSource:self delegate:self];
+ track.undo = self.undo;
+ return track;
}
-- (void)addTracksFromDefaults:(BOOL)allTracks
+#pragma mark - Defaults
+
+- (void)addTracksFromDefaults
{
BOOL firstTrack = NO;
+ BOOL allTracks = NO;
NSMutableIndexSet *tracksAdded = [NSMutableIndexSet indexSet];
NSMutableIndexSet *tracksToAdd = [NSMutableIndexSet indexSet];
// Reinitialize the configured list of audio tracks
- [self _clearAudioArray];
+ while (self.countOfTracks)
+ {
+ [self removeObjectFromTracksAtIndex:0];
+ }
if (self.defaults.trackSelectionBehavior != HBAudioTrackSelectionBehaviorNone)
{
// Add tracks of Default and Alternate Language by name
for (NSString *languageISOCode in self.defaults.trackSelectionLanguages)
{
- NSMutableIndexSet *tracksIndexes = [[self _tracksWithISOCode: languageISOCode
- selectOnlyFirst: self.defaults.trackSelectionBehavior == HBAudioTrackSelectionBehaviorFirst] mutableCopy];
+ NSMutableIndexSet *tracksIndexes = [[self _tracksWithISOCode:languageISOCode
+ selectOnlyFirst:self.defaults.trackSelectionBehavior == HBAudioTrackSelectionBehaviorFirst] mutableCopy];
[tracksIndexes removeIndexes:tracksAdded];
if (tracksIndexes.count)
{
@@ -229,7 +207,7 @@ NSString *HBAudioChangedNotification = @"HBAudioChangedNotification";
}
// If no preferred Language was found, add standard track 1
- if (tracksAdded.count == 0 && self.masterTrackArray.count > 1)
+ if (tracksAdded.count == 0 && self.sourceTracks.count > 1)
{
[tracksToAdd addIndex:1];
}
@@ -238,7 +216,7 @@ NSString *HBAudioChangedNotification = @"HBAudioChangedNotification";
// If all tracks should be added, add all track numbers that are not yet processed
if (allTracks)
{
- [tracksToAdd addIndexesInRange:NSMakeRange(1, self.masterTrackArray.count - 1)];
+ [tracksToAdd addIndexesInRange:NSMakeRange(1, self.sourceTracks.count - 1)];
[tracksToAdd removeIndexes:tracksAdded];
}
@@ -248,119 +226,131 @@ NSString *HBAudioChangedNotification = @"HBAudioChangedNotification";
}
// Add an None item
- [self switchingTrackFromNone: nil];
+ [self addNoneTrack];
}
-- (BOOL)anyCodecMatches:(int)codec
+/**
+ * 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
{
- BOOL retval = NO;
- NSUInteger audioArrayCount = [self countOfTracks];
- for (NSUInteger i = 0; i < audioArrayCount && !retval; i++)
+ for (HBAudioTrackPreset *preset in templateAudioArray)
{
- HBAudioTrack *anAudio = [self objectInTracksAtIndex: i];
- if ([anAudio enabled] && codec == [[anAudio codec][keyAudioCodec] intValue])
- {
- retval = YES;
- }
- }
- return retval;
-}
-
-- (void)addNewAudioTrack
-{
- HBAudioTrack *newAudio = [[HBAudioTrack alloc] init];
- [newAudio setDataSource:self];
- [newAudio setDelegate:self];
- [self insertObject:newAudio inTracksAtIndex:[self countOfTracks]];
- [newAudio setContainer:self.container];
- [newAudio setTrack: self.noneTrack];
- [newAudio setUndo:self.undo];
-}
+ HBAudioTrack *newAudio = [[HBAudioTrack alloc] initWithTrackIdx:trackIndex
+ container:self.container
+ dataSource:self
+ delegate:self];
+ [newAudio setUndo:self.undo];
-#pragma mark -
-#pragma mark Notification Handling
+ [self insertObject:newAudio inTracksAtIndex:[self countOfTracks]];
-- (void)settingTrackToNone:(HBAudioTrack *)newNoneTrack
-{
- // If this is not the last track in the array we need to remove it. We then need to see if a new
- // one needs to be added (in the case when we were at maximum count and this switching makes it
- // so we are no longer at maximum.
- NSUInteger index = [self.tracks indexOfObject: newNoneTrack];
+ int inputCodec = [self.sourceTracks[trackIndex][keyAudioInputCodec] intValue];
+ int outputCodec = preset.encoder;
- if (NSNotFound != index && index < [self countOfTracks] - 1)
- {
- [self removeObjectFromTracksAtIndex: index];
- }
- [self switchingTrackFromNone: nil]; // see if we need to add one to the list
-}
+ // Check if we need to use a fallback
+ if (preset.encoder & HB_ACODEC_PASS_FLAG && !(preset.encoder & inputCodec & HB_ACODEC_PASS_MASK))
+ {
+ outputCodec = hb_audio_encoder_get_fallback_for_passthru(outputCodec);
+
+ // If we couldn't find an encoder for the passthru format
+ // fall back to the selected encoder fallback
+ if (outputCodec == HB_ACODEC_INVALID)
+ {
+ outputCodec = self.defaults.encoderFallback;
+ }
+ }
+
+ int supportedMuxers = hb_audio_encoder_get_from_codec(outputCodec)->muxers;
+
+ // 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 (supportedMuxers & self.container)
+ {
+ newAudio.drc = preset.drc;
+ newAudio.gain = preset.gain;
+ newAudio.mixdown = preset.mixdown;
+ newAudio.sampleRate = preset.sampleRate;
+ newAudio.bitRate = preset.bitRate;
+ newAudio.encoder = outputCodec;
+ }
+ else
+ {
+ [self removeObjectFromTracksAtIndex:[self countOfTracks] - 1];
+ }
-- (void)switchingTrackFromNone:(HBAudioTrack *)noLongerNoneTrack
-{
- NSUInteger count = [self countOfTracks];
- BOOL needToAdd = NO;
- // If there is no last track that is None we add one.
- if (0 < count)
- {
- HBAudioTrack *lastAudio = [self objectInTracksAtIndex: count - 1];
- if ([lastAudio enabled])
+ if (firstOnly)
{
- needToAdd = YES;
+ break;
}
}
- else
- {
- needToAdd = YES;
- }
-
- if (needToAdd)
- {
- [self addNewAudioTrack];
- }
}
-// This gets called whenever the video container changes.
-- (void)setContainer:(int)container
+/**
+ * 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
{
- _container = container;
+ NSMutableIndexSet *indexes = [NSMutableIndexSet indexSet];
- if (!(self.undo.isUndoing || self.undo.isRedoing))
- {
- // Update each of the instances because this value influences possible settings.
- for (HBAudioTrack *audioObject in self.tracks)
+ [self.sourceTracks enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
+ if (idx) // Note that we skip the "None" track
{
- audioObject.container = container;
+ if ([isoCode isEqualToString:@"und"] || [obj[keyAudioTrackLanguageIsoCode] isEqualToString:isoCode])
+ {
+ [indexes addIndex:idx];
+
+ if (selectOnlyFirst)
+ {
+ *stop = YES;
+ }
+ }
}
+ }];
- // Update the Auto Passthru Fallback Codec Popup
- // lets get the tag of the currently selected item first so we might reset it later
- [self.defaults validateEncoderFallbackForVideoContainer:container];
- }
+ return indexes;
}
-- (void)setUndo:(NSUndoManager *)undo
+- (void)_processPresetAudioArray:(NSArray<HBAudioTrackPreset *> *)templateAudioArray forTracks:(NSIndexSet *)trackIndexes firstOnly:(BOOL)firstOnly
{
- _undo = undo;
- for (HBAudioTrack *track in self.tracks)
- {
- track.undo = undo;
- }
- self.defaults.undo = undo;
+ __block BOOL firstTrack = firstOnly;
+ [trackIndexes enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
+ // Add the track
+ [self _processPresetAudioArray: self.defaults.tracksArray forTrack:idx firstOnly:firstTrack];
+ firstTrack = self.defaults.secondaryEncoderMode ? YES : NO;
+ }];
}
-- (void)setDefaults:(HBAudioDefaults *)defaults
+- (BOOL)anyCodecMatches:(int)codec
{
- if (defaults != _defaults)
+ BOOL retval = NO;
+ NSUInteger audioArrayCount = [self countOfTracks];
+ for (NSUInteger i = 0; i < audioArrayCount && !retval; i++)
{
- [[self.undo prepareWithInvocationTarget:self] setDefaults:_defaults];
+ HBAudioTrack *anAudio = [self objectInTracksAtIndex: i];
+ if (anAudio.isEnabled && codec == anAudio.encoder)
+ {
+ retval = YES;
+ }
}
- _defaults = defaults;
- _defaults.undo = self.undo;
+ return retval;
}
-- (void)mixdownChanged
+#pragma mark -
+#pragma mark Notification Handling
+
+- (void)encoderChanged
{
- [[NSNotificationCenter defaultCenter] postNotificationName: HBAudioChangedNotification object: self];
+ [[NSNotificationCenter defaultCenter] postNotificationName:HBAudioChangedNotification object:self];
}
#pragma mark - NSCopying
@@ -372,17 +362,13 @@ NSString *HBAudioChangedNotification = @"HBAudioChangedNotification";
if (copy)
{
copy->_container = _container;
-
- copy->_noneTrack = [_noneTrack copy];
- copy->_masterTrackArray = [_masterTrackArray copy];
+ copy->_sourceTracks = [_sourceTracks mutableCopy];
copy->_tracks = [[NSMutableArray alloc] init];
[_tracks enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if (idx < _tracks.count)
{
- HBAudioTrack *trackCopy = [obj copy];
- trackCopy.dataSource = copy;
- trackCopy.delegate = copy;
+ id trackCopy = [obj copy];
[copy->_tracks addObject:trackCopy];
}
}];
@@ -402,14 +388,11 @@ NSString *HBAudioChangedNotification = @"HBAudioChangedNotification";
- (void)encodeWithCoder:(NSCoder *)coder
{
- [coder encodeInt:1 forKey:@"HBAudioVersion"];
+ [coder encodeInt:2 forKey:@"HBAudioVersion"];
encodeInt(_container);
-
- encodeObject(_noneTrack);
- encodeObject(_masterTrackArray);
+ encodeObject(_sourceTracks);
encodeObject(_tracks);
-
encodeObject(_defaults);
}
@@ -418,9 +401,7 @@ NSString *HBAudioChangedNotification = @"HBAudioChangedNotification";
self = [super init];
decodeInt(_container);
-
- decodeObject(_noneTrack, NSDictionary);
- decodeObject(_masterTrackArray, NSArray);
+ decodeObject(_sourceTracks, NSMutableArray);
decodeObject(_tracks, NSMutableArray);
for (HBAudioTrack *track in _tracks)
@@ -444,13 +425,13 @@ NSString *HBAudioChangedNotification = @"HBAudioChangedNotification";
- (void)applyPreset:(HBPreset *)preset
{
[self.defaults applyPreset:preset];
- [self addTracksFromDefaults:NO];
+ [self addTracksFromDefaults];
}
#pragma mark -
#pragma mark KVC
-- (NSUInteger) countOfTracks
+- (NSUInteger)countOfTracks
{
return self.tracks.count;
}
diff --git a/macosx/HBAudioTrack.h b/macosx/HBAudioTrack.h
index c259812e8..b0a5e0bea 100644
--- a/macosx/HBAudioTrack.h
+++ b/macosx/HBAudioTrack.h
@@ -22,51 +22,50 @@ extern NSString *keyAudioInputCodecParam;
extern NSString *keyAudioInputChannelLayout;
extern NSString *keyAudioTrackLanguageIsoCode;
-extern NSString *keyAudioCodecName;
-extern NSString *keyAudioSampleRateName;
-extern NSString *keyAudioBitrateName;
-extern NSString *keyAudioMixdownName;
-extern NSString *keyAudioCodec;
-extern NSString *keyAudioMixdown;
-extern NSString *keyAudioSamplerate;
-extern NSString *keyAudioBitrate;
-
@protocol HBAudioTrackDataSource <NSObject>
-- (NSDictionary *)noneTrack;
-- (NSArray *)masterTrackArray;
+- (NSDictionary<NSString *, id> *)sourceTrackAtIndex:(NSUInteger)idx;
+- (NSArray<NSString *> *)sourceTracksArray;
@end
@protocol HBAudioTrackDelegate <NSObject>
-- (void)settingTrackToNone:(HBAudioTrack *)newNoneTrack;
-- (void)switchingTrackFromNone:(HBAudioTrack *)noLongerNoneTrack;
-- (void)mixdownChanged;
+- (void)track:(HBAudioTrack *)track didChangeSourceFrom:(NSUInteger)oldSourceIdx;
+- (void)encoderChanged;
@end
@interface HBAudioTrack : NSObject <NSSecureCoding, NSCopying>
-@property (nonatomic, strong) NSDictionary *track;
-@property (nonatomic, strong, nullable) NSDictionary *codec;
-@property (nonatomic, strong, nullable) NSDictionary *mixdown;
-@property (nonatomic, strong, nullable) NSDictionary *sampleRate;
-@property (nonatomic, strong, nullable) NSDictionary *bitRate;
-@property (nonatomic) double drc;
-@property (nonatomic) double gain;
-@property (nonatomic) int container;
+- (instancetype)initWithTrackIdx:(NSUInteger)index
+ container:(int)container
+ dataSource:(id<HBAudioTrackDataSource>)dataSource
+ delegate:(id<HBAudioTrackDelegate>)delegate;
+
+/// The index of the source in the data source tracks array.
+@property (nonatomic, readwrite) NSUInteger sourceTrackIdx;
+@property (nonatomic, readwrite) int container;
@property (nonatomic, weak, nullable) id<HBAudioTrackDataSource> dataSource;
@property (nonatomic, weak, nullable) id<HBAudioTrackDelegate> delegate;
-@property (nonatomic, readonly) NSArray *codecs;
-@property (nonatomic, readonly) NSArray *mixdowns;
-@property (nonatomic, readonly) NSArray *sampleRates;
-@property (nonatomic, readonly) NSArray *bitRates;
-@property (nonatomic, readonly) BOOL enabled;
-
-- (void) setTrackFromIndex: (int) aValue;
-- (BOOL) setCodecFromName: (nullable NSString *) aValue;
-- (void) setMixdownFromName: (NSString *) aValue;
-- (void) setSampleRateFromName: (NSString *) aValue;
-- (void) setBitRateFromName: (NSString *) aValue;
+/**
+ * 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) double gain;
+@property (nonatomic, readwrite) double drc;
+
+@property (nonatomic, readonly, getter=isEnabled) BOOL enabled;
+
+/**
+ * Arrays of possible options for the track properties.
+ */
+@property (nonatomic, readonly) NSArray<NSString *> *encoders;
+@property (nonatomic, readonly) NSArray<NSString *> *mixdowns;
+@property (nonatomic, readonly) NSArray<NSString *> *sampleRates;
+@property (nonatomic, readonly) NSArray<NSString *> *bitRates;
@property (nonatomic, readwrite, weak, nullable) NSUndoManager *undo;
diff --git a/macosx/HBAudioTrack.m b/macosx/HBAudioTrack.m
index 1c998cc4f..9e93eab5d 100644
--- a/macosx/HBAudioTrack.m
+++ b/macosx/HBAudioTrack.m
@@ -19,339 +19,95 @@ NSString *keyAudioInputCodecParam = @"keyAudioInputCodecParam";
NSString *keyAudioInputChannelLayout = @"keyAudioInputChannelLayout";
NSString *keyAudioTrackLanguageIsoCode = @"keyAudioTrackLanguageIsoCode";
-NSString *keyAudioCodecName = @"keyAudioCodecName";
-NSString *keyAudioSupportedMuxers = @"keyAudioSupportedMuxers";
-NSString *keyAudioSampleRateName = @"keyAudioSampleRateName";
-NSString *keyAudioBitrateName = @"keyAudioBitrateName";
-NSString *keyAudioMustMatchTrack = @"keyAudioMustMatchTrack";
-NSString *keyAudioMixdownName = @"keyAudioMixdownName";
-
-NSString *keyAudioCodec = @"codec";
-NSString *keyAudioMixdown = @"mixdown";
-NSString *keyAudioSamplerate = @"samplerate";
-NSString *keyAudioBitrate = @"bitrate";
-
-static NSMutableArray *masterCodecArray = nil;
-static NSMutableArray *masterMixdownArray = nil;
-static NSMutableArray *masterBitRateArray = nil;
-
-@interface NSArray (HBAudioSupport)
-- (NSDictionary *) dictionaryWithObject: (id) anObject matchingKey: (NSString *) aKey;
-- (NSDictionary *) lastDictionaryWithObject: (id) anObject matchingKey: (NSString *) aKey;
-@end
-@implementation NSArray (HBAudioSupport)
-- (NSDictionary *) dictionaryWithObject: (id) anObject matchingKey: (NSString *) aKey reverse: (BOOL) reverse
-{
- NSDictionary *retval = nil;
- NSEnumerator *enumerator = reverse ? [self reverseObjectEnumerator] : [self objectEnumerator];
- NSDictionary *dict;
- id aValue;
-
- while (nil != (dict = [enumerator nextObject]) && !retval)
- {
- if (nil != (aValue = dict[aKey]) && [aValue isEqual: anObject])
- {
- retval = dict;
- }
- }
- return retval;
-}
-- (NSDictionary *) dictionaryWithObject: (id) anObject matchingKey: (NSString *) aKey
-{
- return [self dictionaryWithObject: anObject matchingKey: aKey reverse: NO];
-}
-- (NSDictionary *) lastDictionaryWithObject: (id) anObject matchingKey: (NSString *) aKey
-{
- return [self dictionaryWithObject: anObject matchingKey: aKey reverse: YES];
-}
-
-@end
+#define DEFAULT_SAMPLERATE 48000
@interface HBAudioTrack ()
-
-@property (nonatomic, readwrite) NSArray *codecs;
-@property (nonatomic, readwrite) NSArray *mixdowns;
-@property (nonatomic, readwrite) NSArray *bitRates;
-
+@property (nonatomic, readwrite) BOOL validating;
@end
@implementation HBAudioTrack
-#pragma mark -
-#pragma mark Object Setup
-
-+ (void)initialize
+- (instancetype)init
{
- if ([HBAudioTrack class] == self)
+ self = [super init];
+ if (self)
{
- masterCodecArray = [[NSMutableArray alloc] init]; // knowingly leaked
- 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))
- {
- id audioMustMatchTrack;
- if ((audio_encoder->codec & HB_ACODEC_PASS_FLAG) &&
- (audio_encoder->codec != HB_ACODEC_AUTO_PASS))
- {
- audioMustMatchTrack = @(audio_encoder->codec &
- ~HB_ACODEC_PASS_FLAG);
- }
- else
- {
- audioMustMatchTrack = @NO;
- }
- [masterCodecArray addObject:@{keyAudioCodecName: @(audio_encoder->name),
- keyAudioCodec: @(audio_encoder->codec),
- keyAudioSupportedMuxers: @(audio_encoder->muxers),
- keyAudioMustMatchTrack: audioMustMatchTrack}];
- }
-
- masterMixdownArray = [[NSMutableArray alloc] init]; // knowingly leaked
- for (const hb_mixdown_t *mixdown = hb_mixdown_get_next(NULL);
- mixdown != NULL;
- mixdown = hb_mixdown_get_next(mixdown))
- {
- [masterMixdownArray addObject:@{keyAudioMixdownName: @(mixdown->name),
- keyAudioMixdown: @(mixdown->amixdown)}];
- }
-
- masterBitRateArray = [[NSMutableArray alloc] init]; // knowingly leaked
- 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))
- {
- [masterBitRateArray addObject:@{keyAudioBitrateName: @(audio_bitrate->name),
- keyAudioBitrate: @(audio_bitrate->rate)}];
- }
+ // Defaults settings
+ _encoder = HB_ACODEC_CA_AAC;
+ _container = HB_MUX_MKV;
+ _sampleRate = 0;
+ _bitRate = 160;
+ _mixdown = HB_AMIXDOWN_DOLBYPLII;
}
+ return self;
}
-// Ensure the list of codecs is accurate
-// Update the current value of codec based on the revised list
-- (void) updateCodecs
+- (instancetype)initWithTrackIdx:(NSUInteger)index
+ container:(int)container
+ dataSource:(id<HBAudioTrackDataSource>)dataSource
+ delegate:(id<HBAudioTrackDelegate>)delegate;
{
- NSMutableArray *permittedCodecs = [NSMutableArray array];
- NSUInteger count = [masterCodecArray count];
- NSDictionary *dict;
-
- // First get a list of the permitted codecs based on the internal rules
- if (nil != self.track && self.enabled)
+ self = [super init];
+ if (self)
{
- BOOL goodToAdd;
-
- for (unsigned int i = 0; i < count; i++)
- {
- dict = masterCodecArray[i];
-
- // First make sure only codecs permitted by the container are here
- goodToAdd = !!([dict[keyAudioSupportedMuxers] intValue] & self.container);
+ _dataSource = dataSource;
+ _sourceTrackIdx = index;
+ _container = container;
- // Now we make sure if DTS or AC3 is not available in the track it is not put in the codec list, but in a general way
- if ([dict[keyAudioMustMatchTrack] boolValue])
- {
- if ([dict[keyAudioMustMatchTrack] intValue] != [self.track[keyAudioInputCodec] intValue])
- {
- goodToAdd = NO;
- }
- }
+ [self validateSettings];
- if (goodToAdd)
- {
- [permittedCodecs addObject: dict];
- }
- }
+ _delegate = delegate;
}
- // Now make sure the permitted list and the actual ones matches
- [self setCodecs: permittedCodecs];
+ return self;
+}
- // Ensure our codec is on the list of permitted codecs
- if (!self.codec || ![permittedCodecs containsObject: self.codec])
+- (void)validateSettings
+{
+ if (_sourceTrackIdx)
{
- if (0 < [permittedCodecs count])
+ if (self.encoder == 0)
{
- self.codec = permittedCodecs[0]; // This should be defaulting to Core Audio
+ self.encoder = HB_ACODEC_CA_AAC;
+ self.bitRate = 160;
}
else
{
- self.codec = nil;
+ self.encoder = [self sanatizeEncoderValue:self.encoder];
}
}
-}
-
-- (void)updateMixdowns:(BOOL)shouldSetDefault
-{
- NSMutableArray *permittedMixdowns = [NSMutableArray array];
- NSDictionary *dict;
- int currentMixdown;
-
- unsigned long long channelLayout = [self.track[keyAudioInputChannelLayout] unsignedLongLongValue];
- NSUInteger count = [masterMixdownArray count];
- int codecCodec = [self.codec[keyAudioCodec] intValue];
- int theDefaultMixdown = hb_mixdown_get_default(codecCodec, channelLayout);
-
- for (unsigned int i = 0; i < count; i++)
- {
- dict = masterMixdownArray[i];
- currentMixdown = [dict[keyAudioMixdown] intValue];
-
- if (hb_mixdown_is_supported(currentMixdown, codecCodec, channelLayout))
- {
- [permittedMixdowns addObject: dict];
- }
- }
-
- if (!self.enabled)
- {
- permittedMixdowns = nil;
- }
-
- // Now make sure the permitted list and the actual ones matches
- self.mixdowns = permittedMixdowns;
-
- // Select the proper one
- if (shouldSetDefault)
- {
- self.mixdown = [permittedMixdowns dictionaryWithObject: @(theDefaultMixdown)
- matchingKey: keyAudioMixdown];
- }
-
- if (!self.mixdown || ![permittedMixdowns containsObject: self.mixdown])
+ else
{
- self.mixdown = [permittedMixdowns lastObject];
+ self.encoder = 0;
+ self.mixdown = 0;
+ self.sampleRate = 0;
+ self.bitRate = -1;
}
}
-- (void)validateSamplerate
-{
- int codec = [self.codec[keyAudioCodec] intValue];
- int samplerate = [self.sampleRate[keyAudioSamplerate] intValue];
+#pragma mark - Track properties
- if (codec & HB_ACODEC_PASS_FLAG)
- {
- [self setSampleRateFromName:@"Auto"];
- }
- else if (samplerate)
- {
- samplerate = hb_audio_samplerate_find_closest(samplerate, codec);
- [self setSampleRateFromName:@(hb_audio_samplerate_get_name(samplerate))];
- }
-}
-
-- (void)updateBitRates:(BOOL)shouldSetDefault
+- (void)setSourceTrackIdx:(NSUInteger)sourceTrackIdx
{
- NSMutableArray *permittedBitRates = [NSMutableArray array];
- NSDictionary *dict;
- int minBitRate;
- int maxBitRate;
- int currentBitRate;
- BOOL shouldAdd;
-
- NSUInteger count = [masterBitRateArray count];
- int trackInputBitRate = [self.track[keyAudioInputBitrate] intValue];
- int theSampleRate = [self.sampleRate[keyAudioSamplerate] intValue];
-
- if (0 == theSampleRate) // this means Auto
+ if (sourceTrackIdx != _sourceTrackIdx)
{
- theSampleRate = [self.track[keyAudioInputSampleRate] intValue];
+ [[self.undo prepareWithInvocationTarget:self] setSourceTrackIdx:_sourceTrackIdx];
}
- int ourCodec = [self.codec[keyAudioCodec] intValue];
- int ourMixdown = [self.mixdown[keyAudioMixdown] intValue];
- int theDefaultBitRate = hb_audio_bitrate_get_default(ourCodec, theSampleRate, ourMixdown);
- hb_audio_bitrate_get_limits(ourCodec, theSampleRate, ourMixdown, &minBitRate, &maxBitRate);
-
- BOOL codecIsPassthru = ([self.codec[keyAudioCodec] intValue] & HB_ACODEC_PASS_FLAG) ? YES : NO;
- BOOL codecIsLossless = (theDefaultBitRate == -1) ? YES : NO;
-
- if (codecIsPassthru)
- {
- NSDictionary *sourceBitRate = [masterBitRateArray dictionaryWithObject: @(trackInputBitRate)
- matchingKey: keyAudioBitrate];
- if (!sourceBitRate)
- {
- // the source bitrate isn't in the master array - create it
- sourceBitRate = @{keyAudioBitrateName: [NSString stringWithFormat: @"%d", trackInputBitRate],
- keyAudioBitrate: @(trackInputBitRate)};
- }
- [permittedBitRates addObject: sourceBitRate];
- }
- else if (codecIsLossless)
- {
- NSDictionary *bitRateNotApplicable = @{keyAudioBitrateName: @"N/A",
- keyAudioBitrate: @-1};
- [permittedBitRates addObject: bitRateNotApplicable];
- }
- else
- {
- for (unsigned int i = 0; i < count; i++)
- {
- dict = masterBitRateArray[i];
- currentBitRate = [dict[keyAudioBitrate] intValue];
-
- // First ensure the bitrate falls within range of the codec
- shouldAdd = (currentBitRate >= minBitRate && currentBitRate <= maxBitRate);
-
- if (shouldAdd)
- {
- [permittedBitRates addObject: dict];
- }
- }
- }
-
- if (!self.enabled)
- {
- permittedBitRates = nil;
- }
-
- // Make sure we are updated with the permitted list
- self.bitRates = permittedBitRates;
-
- // Select the proper one
- if (shouldSetDefault)
- {
- [self setBitRateFromName: [NSString stringWithFormat:@"%d", theDefaultBitRate]];
- }
+ NSUInteger oldIdx = _sourceTrackIdx;
+ _sourceTrackIdx = sourceTrackIdx;
- if (!self.bitRate || ![permittedBitRates containsObject: self.bitRate])
+ if (!(self.undo.isUndoing || self.undo.isRedoing))
{
- self.bitRate = [permittedBitRates lastObject];
- }
-}
-
-#pragma mark -
-#pragma mark Accessors
+ [self validateSettings];
-- (NSArray *)sampleRates
-{
- NSMutableArray *samplerates = [[NSMutableArray alloc] init];
-
- /*
- * Note that for the Auto value we use 0 for the sample rate because our controller will give back the track's
- * input sample rate when it finds this 0 value as the selected sample rate. We do this because the input
- * sample rate depends on the track, which means it depends on the title, so cannot be nicely set up here.
- */
- [samplerates addObject:@{keyAudioSampleRateName: @"Auto",
- keyAudioSamplerate: @0}];
-
- int codec = [self.codec[keyAudioCodec] intValue];
- 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))
- {
- int rate = audio_samplerate->rate;
- if (rate == hb_audio_samplerate_find_closest(rate, codec))
+ if (oldIdx != sourceTrackIdx)
{
- [samplerates addObject:@{keyAudioSampleRateName: @(audio_samplerate->name),
- keyAudioSamplerate: @(rate)}];
+ [self.delegate track:self didChangeSourceFrom:oldIdx];
}
}
- return samplerates;
}
-#pragma mark -
-#pragma mark Setters
-
- (void)setContainer:(int)container
{
if (container != _container)
@@ -362,54 +118,33 @@ static NSMutableArray *masterBitRateArray = nil;
if (!(self.undo.isUndoing || self.undo.isRedoing))
{
- [self updateCodecs];
- }
-}
-
-- (void)setTrack:(NSDictionary *)track
-{
- if (track != _track)
- {
- [[self.undo prepareWithInvocationTarget:self] setTrack:_track];
- }
- NSDictionary *oldValue = _track;
- _track = track;
- if (nil != _track && !(self.undo.isUndoing || self.undo.isRedoing))
- {
- [self updateCodecs];
- [self updateMixdowns: YES];
- if (self.enabled)
- {
- self.sampleRate = self.sampleRates[0]; // default to Auto
- }
- if ([self.dataSource.noneTrack isEqual: oldValue])
- {
- [self.delegate switchingTrackFromNone: self];
- }
- if ([self.dataSource.noneTrack isEqual: self.track])
+ if (self.encoder)
{
- [self.delegate settingTrackToNone: self];
+ self.encoder = [self sanatizeEncoderValue:self.encoder];
}
}
}
-- (void)setCodec:(NSDictionary *)codec
+- (void)setEncoder:(int)encoder
{
- if (codec != _codec)
+ if (encoder != _encoder)
{
- [[self.undo prepareWithInvocationTarget:self] setCodec:_codec];
+ [[self.undo prepareWithInvocationTarget:self] setEncoder:_encoder];
}
- _codec = codec;
+ _encoder = encoder;
- if (!(self.undo.isUndoing || self.undo.isRedoing))
+ if (!(self.undo.isUndoing || self.undo.isRedoing) && !self.validating)
{
- [self validateSamplerate];
- [self updateMixdowns:YES];
- [self updateBitRates:YES];
+ self.validating = YES;
+ [self.delegate encoderChanged];
+ self.mixdown = [self sanatizeMixdownValue:self.mixdown];
+ self.sampleRate = [self sanatizeSamplerateValue:self.sampleRate];
+ self.bitRate = [self sanatizeBitrateValue:self.bitRate];
+ self.validating = NO;
}
}
-- (void)setMixdown:(NSDictionary *)mixdown
+- (void)setMixdown:(int)mixdown
{
if (mixdown != _mixdown)
{
@@ -417,14 +152,15 @@ static NSMutableArray *masterBitRateArray = nil;
}
_mixdown = mixdown;
- if (!(self.undo.isUndoing || self.undo.isRedoing))
+ if (!(self.undo.isUndoing || self.undo.isRedoing) && !self.validating)
{
- [self updateBitRates:YES];
- [self.delegate mixdownChanged];
+ self.validating = YES;
+ self.bitRate = [self sanatizeBitrateValue:self.bitRate];
+ self.validating = NO;
}
}
-- (void)setSampleRate:(NSDictionary *)sampleRate
+- (void)setSampleRate:(int)sampleRate
{
if (sampleRate != _sampleRate)
{
@@ -432,13 +168,15 @@ static NSMutableArray *masterBitRateArray = nil;
}
_sampleRate = sampleRate;
- if (!(self.undo.isUndoing || self.undo.isRedoing))
+ if (!(self.undo.isUndoing || self.undo.isRedoing) && !self.validating)
{
- [self updateBitRates: NO];
+ self.validating = YES;
+ self.bitRate = [self sanatizeBitrateValue:self.bitRate];
+ self.validating = NO;
}
}
-- (void)setBitRate:(NSDictionary *)bitRate
+- (void)setBitRate:(int)bitRate
{
if (bitRate != _bitRate)
{
@@ -447,15 +185,6 @@ static NSMutableArray *masterBitRateArray = nil;
_bitRate = bitRate;
}
-- (void)setDrc:(double)drc
-{
- if (drc != _drc)
- {
- [[self.undo prepareWithInvocationTarget:self] setDrc:_drc];
- }
- _drc = drc;
-}
-
- (void)setGain:(double)gain
{
if (gain != _gain)
@@ -465,140 +194,235 @@ static NSMutableArray *masterBitRateArray = nil;
_gain = gain;
}
-#pragma mark -
-#pragma mark Special Setters
-
-- (void)setTrackFromIndex:(int)aValue
+// 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 * __autoreleasing *)outError
{
- self.track = [self.dataSource.masterTrackArray dictionaryWithObject: @(aValue)
- matchingKey: keyAudioTrackIndex];
+ BOOL retval = YES;
+
+ if (nil != *ioValue)
+ {
+ if ([*ioValue intValue] < -20)
+ {
+ *ioValue = @(-20);
+ }
+ else if ([*ioValue intValue] > 20)
+ {
+ *ioValue = @20;
+ }
+ }
+
+ return retval;
}
-// This returns whether it is able to set the actual codec desired.
-- (BOOL)setCodecFromName:(NSString *)aValue
+- (void)setDrc:(double)drc
{
- NSDictionary *dict = [self.codecs dictionaryWithObject: aValue matchingKey: keyAudioCodecName];
- if (nil != dict)
+ if (drc != _drc)
{
- self.codec = dict;
+ [[self.undo prepareWithInvocationTarget:self] setDrc:_drc];
}
- return (nil != dict);
+ _drc = drc;
}
-- (void)setMixdownFromName:(NSString *)aValue
+#pragma mark - Validation
+
+- (int)sanatizeEncoderValue:(int)proposedEncoder
{
- NSDictionary *dict = [self.mixdowns dictionaryWithObject: aValue matchingKey: keyAudioMixdownName];
- if (nil != dict)
+ if (proposedEncoder)
+ {
+ NSDictionary *sourceTrack = [_dataSource sourceTrackAtIndex:_sourceTrackIdx];
+ int inputCodec = [sourceTrack[keyAudioInputCodec] intValue];
+
+ hb_encoder_t *proposedEncoderInfo = hb_audio_encoder_get_from_codec(proposedEncoder);
+
+ if (proposedEncoderInfo && proposedEncoderInfo->muxers & self.container)
+ {
+ // If the codec is passthru, see if the new source supports it.
+ if (proposedEncoderInfo->codec & HB_ACODEC_PASS_FLAG)
+ {
+ if ((proposedEncoderInfo->codec & inputCodec & HB_ACODEC_PASS_MASK))
+ {
+ return proposedEncoder;
+ }
+ }
+ else
+ {
+ return proposedEncoder;
+ }
+ }
+
+ return HB_ACODEC_CA_AAC;
+ }
+ else
{
- self.mixdown = dict;
+ return proposedEncoder;
}
}
-- (void)setSampleRateFromName:(NSString *)aValue
+- (int)sanatizeMixdownValue:(int)proposedMixdown
{
- NSDictionary *dict = [self.sampleRates dictionaryWithObject: aValue matchingKey: keyAudioSampleRateName];
- if (nil != dict)
+ NSDictionary *sourceTrack = [_dataSource sourceTrackAtIndex:_sourceTrackIdx];
+ unsigned long long channelLayout = [sourceTrack[keyAudioInputChannelLayout] unsignedLongLongValue];
+
+ if (!hb_mixdown_is_supported(proposedMixdown, self.encoder, channelLayout))
{
- self.sampleRate = dict;
+ return hb_mixdown_get_default(self.encoder, channelLayout);
}
+ return proposedMixdown;
}
-- (void)setBitRateFromName:(NSString *)aValue
+- (int)sanatizeSamplerateValue:(int)proposedSamplerate
{
- NSDictionary *dict = [self.bitRates dictionaryWithObject: aValue matchingKey: keyAudioBitrateName];
- if (nil != dict)
+ if (self.encoder & HB_ACODEC_PASS_FLAG)
+ {
+ return 0; // Auto (same as source)
+ }
+ else if (proposedSamplerate)
{
- self.bitRate = dict;
+ return hb_audio_samplerate_find_closest(proposedSamplerate, self.encoder);
}
+ return proposedSamplerate;
}
-- (void)setCodecs:(NSArray *)codecs
+- (int)sanatizeBitrateValue:(int)proposedBitrate
{
- if (codecs != _codecs)
+ if (self.encoder & HB_ACODEC_PASS_FLAG)
{
- [[self.undo prepareWithInvocationTarget:self] setCodecs:_codecs];
+ return -1;
+ }
+ else if (proposedBitrate == -1) // switching from passthru
+ {
+ return hb_audio_bitrate_get_default(self.encoder,
+ self.sampleRate ? self.sampleRate : DEFAULT_SAMPLERATE,
+ self.mixdown);
+ }
+ else
+ {
+ return hb_audio_bitrate_get_best(self.encoder, proposedBitrate, self.sampleRate, self.mixdown);
}
- _codecs = codecs;
}
-- (void)setMixdowns:(NSArray *)mixdowns
+#pragma mark - Options
+
+- (NSArray<NSString *> *)encoders
{
- if (mixdowns != _mixdowns)
+ NSMutableArray<NSString *> *encoders = [[NSMutableArray alloc] init];
+
+ NSDictionary *sourceTrack = [_dataSource sourceTrackAtIndex:_sourceTrackIdx];
+ int inputCodec = [sourceTrack[keyAudioInputCodec] intValue];
+
+ 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))
{
- [[self.undo prepareWithInvocationTarget:self] setMixdowns:_mixdowns];
+ if (audio_encoder->muxers & self.container)
+ {
+ if (audio_encoder->codec & HB_ACODEC_PASS_FLAG)
+ {
+ // If the codec is passthru, show only the supported ones.
+ if ((audio_encoder->codec & inputCodec & HB_ACODEC_PASS_MASK))
+ {
+ [encoders addObject:@(audio_encoder->name)];
+ }
+ }
+ else
+ {
+ [encoders addObject:@(audio_encoder->name)];
+ }
+ }
}
- _mixdowns = mixdowns;
+ return encoders;
}
-- (void)setBitRates:(NSArray *)bitRates
+- (NSArray<NSString *> *)mixdowns
{
- if (bitRates != _bitRates)
+ NSMutableArray<NSString *> *mixdowns = [[NSMutableArray alloc] init];
+
+ NSDictionary *sourceTrack = [_dataSource sourceTrackAtIndex:_sourceTrackIdx];
+ unsigned long long channelLayout = [sourceTrack[keyAudioInputChannelLayout] unsignedLongLongValue];
+
+ for (const hb_mixdown_t *mixdown = hb_mixdown_get_next(NULL);
+ mixdown != NULL;
+ mixdown = hb_mixdown_get_next(mixdown))
{
- [[self.undo prepareWithInvocationTarget:self] setBitRates:_bitRates];
+ if (hb_mixdown_is_supported(mixdown->amixdown, self.encoder, channelLayout))
+ {
+ [mixdowns addObject:@(mixdown->name)];
+ }
}
- _bitRates = bitRates;
+ return mixdowns;
}
-#pragma mark -
-#pragma mark Validation
-
-// 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 * __autoreleasing *)outError
+- (NSArray<NSString *> *)sampleRates
{
- BOOL retval = YES;
+ NSMutableArray<NSString *> *sampleRates = [[NSMutableArray alloc] init];
+ [sampleRates addObject:@"Auto"];
- if (nil != *ioValue)
+ 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))
{
- if ([*ioValue intValue] < -20)
+ int rate = audio_samplerate->rate;
+ if (rate == hb_audio_samplerate_find_closest(rate, self.encoder))
{
- *ioValue = @(-20);
+ [sampleRates addObject:@(audio_samplerate->name)];
}
- else if ([*ioValue intValue] > 20)
+ }
+ return sampleRates;
+}
+
+- (NSArray<NSString *> *)bitRates
+{
+ int minBitRate = 0;
+ int maxBitRate = 0;
+
+ hb_audio_bitrate_get_limits(self.encoder, self.sampleRate, self.mixdown, &minBitRate, &maxBitRate);
+
+ NSMutableArray<NSString *> *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)
{
- *ioValue = @20;
+ [bitRates addObject:@(audio_bitrate->name)];
}
}
-
- return retval;
+ return bitRates;
}
-#pragma mark - Bindings Support
+#pragma mark - KVO UI Additions
-- (NSArray *)masterTrackArray
+- (NSArray *)sourceTracksArray
{
- return self.dataSource.masterTrackArray;
+ return [self.dataSource sourceTracksArray];
}
-- (BOOL)enabled
+- (BOOL)isEnabled
{
- return (nil != self.track) ? (![self.track isEqual: self.dataSource.noneTrack]) : NO;
+ return self.sourceTrackIdx != 0;
}
- (BOOL)mixdownEnabled
{
- BOOL retval = self.enabled;
+ BOOL retval = self.isEnabled;
- if (retval)
+ if (retval && self.mixdown == HB_AMIXDOWN_NONE)
{
- int myMixdown = [self.mixdown[keyAudioMixdown] intValue];
- if (myMixdown == HB_AMIXDOWN_NONE)
- {
- // "None" mixdown (passthru)
- retval = NO;
- }
+ // "None" mixdown (passthru)
+ retval = NO;
}
+
return retval;
}
- (BOOL)bitrateEnabled
{
- BOOL retval = self.enabled;
+ BOOL retval = self.isEnabled;
if (retval)
{
- int myCodecCodec = [self.codec[keyAudioCodec] intValue];
- int myCodecDefaultBitrate = hb_audio_bitrate_get_default(myCodecCodec, 0, 0);
+ int myCodecDefaultBitrate = hb_audio_bitrate_get_default(self.encoder, 0, 0);
if (myCodecDefaultBitrate < 0)
{
retval = NO;
@@ -607,16 +431,17 @@ static NSMutableArray *masterBitRateArray = nil;
return retval;
}
-- (BOOL)DRCEnabled
+- (BOOL)drcEnabled
{
- BOOL retval = self.enabled;
+ BOOL retval = self.isEnabled;
if (retval)
{
- int myTrackParam = [self.track[keyAudioInputCodecParam] intValue];
- int myTrackCodec = [self.track[keyAudioInputCodec] intValue];
- int myCodecCodec = [self.codec[keyAudioCodec] intValue];
- if (!hb_audio_can_apply_drc(myTrackCodec, myTrackParam, myCodecCodec))
+ NSDictionary *sourceTrack = [_dataSource sourceTrackAtIndex:_sourceTrackIdx];
+
+ int inputCodec = [sourceTrack[keyAudioInputCodec] intValue];
+ int inputCodecParam = [sourceTrack[keyAudioInputCodecParam] intValue];
+ if (!hb_audio_can_apply_drc(inputCodec, inputCodecParam, self.encoder))
{
retval = NO;
}
@@ -624,52 +449,46 @@ static NSMutableArray *masterBitRateArray = nil;
return retval;
}
-- (BOOL)PassThruDisabled
+- (BOOL)passThruDisabled
{
- BOOL retval = self.enabled;
+ BOOL retval = YES;
- if (retval)
+ if (self.encoder & HB_ACODEC_PASS_FLAG)
{
- int myCodecCodec = [self.codec[keyAudioCodec] intValue];
- if (myCodecCodec & HB_ACODEC_PASS_FLAG)
- {
- retval = NO;
- }
+ retval = NO;
}
+
return retval;
}
-- (void)setNilValueForKey:(NSString *)key
-{
- if ([key isEqualToString:@"drc"] || [key isEqualToString:@"gain"])
- {
- [self setValue:@0 forKey:key];
- }
-}
+#pragma mark - KVO
+ (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key
{
NSSet *retval = nil;
- if ([key isEqualToString:@"enabled"])
+ if ([key isEqualToString:@"bitrateEnabled"] ||
+ [key isEqualToString:@"passThruDisabled"] ||
+ [key isEqualToString:@"mixdownEnabled"])
{
- retval = [NSSet setWithObjects:@"track", nil];
+ retval = [NSSet setWithObjects:@"encoder", nil];
}
- else if ([key isEqualToString:@"PassThruDisabled"])
+ else if ([key isEqualToString:@"mixdowns"] ||
+ [key isEqualToString:@"drcEnabled"])
{
- retval = [NSSet setWithObjects:@"track", @"codec", nil];
+ retval = [NSSet setWithObjects:@"sourceTrackIdx", @"encoder", nil];
}
- else if ([key isEqualToString:@"DRCEnabled"])
+ else if ([key isEqualToString:@"sampleRates"])
{
- retval = [NSSet setWithObjects:@"track", @"codec", nil];
+ retval = [NSSet setWithObjects:@"encoder", @"mixdown", nil];
}
- else if ([key isEqualToString:@"bitrateEnabled"])
+ else if ([key isEqualToString:@"bitRates"])
{
- retval = [NSSet setWithObjects:@"track", @"codec", nil];
+ retval = [NSSet setWithObjects:@"encoder", @"mixdown", @"sampleRate", nil];
}
- else if ([key isEqualToString:@"mixdownEnabled"])
+ else if ([key isEqualToString:@"encoders"])
{
- retval = [NSSet setWithObjects:@"track", @"mixdown", nil];
+ retval = [NSSet setWithObjects:@"container", @"sourceTrackIdx", nil];
}
else
{
@@ -679,6 +498,14 @@ static NSMutableArray *masterBitRateArray = nil;
return retval;
}
+- (void)setNilValueForKey:(NSString *)key
+{
+ if ([key isEqualToString:@"drc"] || [key isEqualToString:@"gain"])
+ {
+ [self setValue:@0 forKey:key];
+ }
+}
+
#pragma mark - NSCopying
- (instancetype)copyWithZone:(NSZone *)zone
@@ -687,18 +514,16 @@ static NSMutableArray *masterBitRateArray = nil;
if (copy)
{
- copy->_track = [_track copy];
- copy->_codec = [_codec copy];
- copy->_mixdown = [_mixdown copy];
- copy->_sampleRate = [_sampleRate copy];
- copy->_bitRate = [_bitRate copy];
- copy->_drc = _drc;
- copy->_gain = _gain;
+ copy->_sourceTrackIdx = _sourceTrackIdx;
copy->_container = _container;
- copy->_codecs = [_codecs copy];
- copy->_mixdowns = [_mixdowns copy];
- copy->_bitRates = [_bitRates copy];
+ copy->_encoder = _encoder;
+ copy->_mixdown = _mixdown;
+ copy->_sampleRate = _sampleRate;
+ copy->_bitRate = _bitRate;
+
+ copy->_gain = _gain;
+ copy->_drc = _drc;
}
return copy;
@@ -713,38 +538,34 @@ static NSMutableArray *masterBitRateArray = nil;
- (void)encodeWithCoder:(NSCoder *)coder
{
- [coder encodeInt:2 forKey:@"HBAudioTrackVersion"];
+ [coder encodeInt:3 forKey:@"HBAudioTrackVersion"];
- encodeObject(_track);
- encodeObject(_codec);
- encodeObject(_mixdown);
- encodeObject(_sampleRate);
- encodeObject(_bitRate);
- encodeDouble(_drc);
- encodeDouble(_gain);
+ encodeInteger(_sourceTrackIdx);
encodeInt(_container);
- encodeObject(_codecs);
- encodeObject(_mixdowns);
- encodeObject(_bitRates);
+ encodeInt(_encoder);
+ encodeInt(_mixdown);
+ encodeInt(_sampleRate);
+ encodeInt(_bitRate);
+
+ encodeDouble(_gain);
+ encodeDouble(_drc);
}
- (instancetype)initWithCoder:(NSCoder *)decoder
{
self = [super init];
- decodeObject(_track, NSDictionary);
- decodeObject(_codec, NSDictionary);
- decodeObject(_mixdown, NSDictionary);
- decodeObject(_sampleRate, NSDictionary);
- decodeObject(_bitRate, NSDictionary);
- decodeDouble(_drc);
- decodeDouble(_gain);
+ decodeInteger(_sourceTrackIdx);
decodeInt(_container);
- decodeObject(_codecs, NSMutableArray);
- decodeObject(_mixdowns, NSMutableArray);
- decodeObject(_bitRates, NSArray);
+ decodeInt(_encoder);
+ decodeInt(_mixdown);
+ decodeInt(_sampleRate);
+ decodeInt(_bitRate);
+
+ decodeDouble(_gain);
+ decodeDouble(_drc);
return self;
}
diff --git a/macosx/HBAudioTrackPreset.h b/macosx/HBAudioTrackPreset.h
index 1acd14a20..7f3b4a8f4 100644
--- a/macosx/HBAudioTrackPreset.h
+++ b/macosx/HBAudioTrackPreset.h
@@ -42,19 +42,3 @@ NS_ASSUME_NONNULL_BEGIN
@end
NS_ASSUME_NONNULL_END
-
-/**
- * A series of value trasformers to bridge the libhb enums
- * to the textual rapresentations used in the interface.
- */
-@interface HBEncoderTransformer : NSValueTransformer
-@end
-
-@interface HBMixdownTransformer : NSValueTransformer
-@end
-
-@interface HBSampleRateTransformer : NSValueTransformer
-@end
-
-@interface HBIntegerTransformer : NSValueTransformer
-@end \ No newline at end of file
diff --git a/macosx/HBAudioTrackPreset.m b/macosx/HBAudioTrackPreset.m
index 254a83aae..0e2e66a4c 100644
--- a/macosx/HBAudioTrackPreset.m
+++ b/macosx/HBAudioTrackPreset.m
@@ -10,8 +10,6 @@
#define DEFAULT_SAMPLERATE 48000
-static void *HBAudioEncoderContex = &HBAudioEncoderContex;
-
@interface HBAudioTrackPreset ()
@property (nonatomic, readwrite) int container;
@@ -257,6 +255,8 @@ static void *HBAudioEncoderContex = &HBAudioEncoderContex;
- (NSArray<NSString *> *)sampleRates
{
NSMutableArray<NSString *> *sampleRates = [[NSMutableArray alloc] init];
+ [sampleRates addObject:@"Auto"];
+
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))
@@ -294,7 +294,7 @@ static void *HBAudioEncoderContex = &HBAudioEncoderContex;
{
NSSet *retval = nil;
- // Tell KVO to reaload the *enabled keyPaths
+ // Tell KVO to reload the *enabled keyPaths
// after a change to encoder.
if ([key isEqualToString:@"bitrateEnabled"] ||
[key isEqualToString:@"passThruDisabled"] ||
@@ -306,6 +306,10 @@ static void *HBAudioEncoderContex = &HBAudioEncoderContex;
{
retval = [NSSet setWithObjects:@"encoder", nil];
}
+ else if ([key isEqualToString:@"sampleRates"])
+ {
+ retval = [NSSet setWithObjects:@"encoder", @"mixdown", nil];
+ }
else if ([key isEqualToString:@"bitRates"])
{
retval = [NSSet setWithObjects:@"encoder", @"mixdown", @"sampleRate", nil];
@@ -388,136 +392,3 @@ static void *HBAudioEncoderContex = &HBAudioEncoderContex;
}
@end
-
-#pragma mark - Value Trasformers
-
-@implementation HBEncoderTransformer
-
-+ (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 HBMixdownTransformer
-
-+ (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 HBSampleRateTransformer
-
-+ (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
-{
- int sampleRate = hb_audio_samplerate_get_from_name([value UTF8String]);
- if (sampleRate < 0)
- {
- sampleRate = 0;
- }
- return @(sampleRate);
-}
-
-@end
-
-@implementation HBIntegerTransformer
-
-+ (Class)transformedValueClass
-{
- return [NSString class];
-}
-
-- (id)transformedValue:(id)value
-{
- // treat -1 as a special invalid value
- // e.g. passthru has no bitrate since we have no source
- if ([value intValue] == -1)
- {
- return @"N/A";
- }
- return [value stringValue];
-}
-
-+ (BOOL)allowsReverseTransformation
-{
- return YES;
-}
-
-- (id)reverseTransformedValue:(id)value
-{
- return @([value intValue]);
-}
-
-@end
diff --git a/macosx/HBAudioTransformers.h b/macosx/HBAudioTransformers.h
new file mode 100644
index 000000000..eefaddadc
--- /dev/null
+++ b/macosx/HBAudioTransformers.h
@@ -0,0 +1,25 @@
+//
+// HBAudioTransformers.h
+// HandBrake
+//
+// Created by Damiano Galassi on 26/08/2016.
+//
+//
+
+#import <Foundation/Foundation.h>
+
+/**
+ * A series of value trasformers to bridge the libhb enums
+ * to the textual rapresentations used in the interface.
+ */
+@interface HBEncoderTransformer : NSValueTransformer
+@end
+
+@interface HBMixdownTransformer : NSValueTransformer
+@end
+
+@interface HBSampleRateTransformer : NSValueTransformer
+@end
+
+@interface HBIntegerTransformer : NSValueTransformer
+@end
diff --git a/macosx/HBAudioTransformers.m b/macosx/HBAudioTransformers.m
new file mode 100644
index 000000000..4a4adec09
--- /dev/null
+++ b/macosx/HBAudioTransformers.m
@@ -0,0 +1,143 @@
+//
+// HBAudioTransformers.m
+// HandBrake
+//
+// Created by Damiano Galassi on 26/08/2016.
+//
+//
+
+#import "HBAudioTransformers.h"
+#include "hb.h"
+
+#pragma mark - Value Trasformers
+
+@implementation HBEncoderTransformer
+
++ (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 HBMixdownTransformer
+
++ (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 HBSampleRateTransformer
+
++ (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
+{
+ int sampleRate = hb_audio_samplerate_get_from_name([value UTF8String]);
+ if (sampleRate < 0)
+ {
+ sampleRate = 0;
+ }
+ return @(sampleRate);
+}
+
+@end
+
+@implementation HBIntegerTransformer
+
++ (Class)transformedValueClass
+{
+ return [NSString class];
+}
+
+- (id)transformedValue:(id)value
+{
+ // treat -1 as a special invalid value
+ // e.g. passthru has no bitrate since we have no source
+ if ([value intValue] == -1)
+ {
+ return @"N/A";
+ }
+ return [value stringValue];
+}
+
++ (BOOL)allowsReverseTransformation
+{
+ return YES;
+}
+
+- (id)reverseTransformedValue:(id)value
+{
+ return @([value intValue]);
+}
+
+@end
diff --git a/macosx/HBJob+HBJobConversion.m b/macosx/HBJob+HBJobConversion.m
index d26e2cea0..e90ccfd6c 100644
--- a/macosx/HBJob+HBJobConversion.m
+++ b/macosx/HBJob+HBJobConversion.m
@@ -345,29 +345,31 @@
// Now lets add our new tracks to the audio list here
for (HBAudioTrack *audioTrack in self.audio.tracks)
{
- if (audioTrack.enabled)
+ if (audioTrack.isEnabled)
{
hb_audio_config_t *audio = (hb_audio_config_t *)calloc(1, sizeof(*audio));
hb_audio_config_init(audio);
- NSNumber *sampleRateToUse = ([audioTrack.sampleRate[keyAudioSamplerate] intValue] == 0 ?
- audioTrack.track[keyAudioInputSampleRate] :
- audioTrack.sampleRate[keyAudioSamplerate]);
+ NSDictionary *inputTrack = self.audio.sourceTracks[audioTrack.sourceTrackIdx];
- audio->in.track = [audioTrack.track[keyAudioTrackIndex] intValue] -1;
+ int sampleRateToUse = (audioTrack.sampleRate == 0 ?
+ [inputTrack[keyAudioInputSampleRate] intValue] :
+ audioTrack.sampleRate);
+
+ audio->in.track = (int)audioTrack.sourceTrackIdx - 1;
// We go ahead and assign values to our audio->out.<properties>
audio->out.track = audio->in.track;
- audio->out.codec = [audioTrack.codec[keyAudioCodec] intValue];
+ audio->out.codec = audioTrack.encoder;
audio->out.compression_level = hb_audio_compression_get_default(audio->out.codec);
- audio->out.mixdown = [audioTrack.mixdown[keyAudioMixdown] intValue];
+ audio->out.mixdown = audioTrack.mixdown;
audio->out.normalize_mix_level = 0;
- audio->out.bitrate = [audioTrack.bitRate[keyAudioBitrate] intValue];
- audio->out.samplerate = [sampleRateToUse intValue];
+ audio->out.bitrate = audioTrack.bitRate;
+ audio->out.samplerate = sampleRateToUse;
audio->out.dither_method = hb_audio_dither_get_default();
// output is not passthru so apply gain
- if (!([[audioTrack codec][keyAudioCodec] intValue] & HB_ACODEC_PASS_FLAG))
+ if (!(audioTrack.encoder & HB_ACODEC_PASS_FLAG))
{
audio->out.gain = audioTrack.gain;
}
@@ -377,9 +379,9 @@
audio->out.gain = 0;
}
- if (hb_audio_can_apply_drc([audioTrack.track[keyAudioInputCodec] intValue],
- [audioTrack.track[keyAudioInputCodecParam] intValue],
- [audioTrack.codec[keyAudioCodec] intValue]))
+ if (hb_audio_can_apply_drc([inputTrack[keyAudioInputCodec] intValue],
+ [inputTrack[keyAudioInputCodecParam] intValue],
+ audioTrack.encoder))
{
audio->out.dynamic_range_compression = audioTrack.drc;
}
diff --git a/macosx/HBJob+UIAdditions.m b/macosx/HBJob+UIAdditions.m
index 829f47300..865cad7d8 100644
--- a/macosx/HBJob+UIAdditions.m
+++ b/macosx/HBJob+UIAdditions.m
@@ -190,23 +190,25 @@ static NSDictionary *shortHeightAttr;
for (HBAudioTrack *audioTrack in self.audio.tracks)
{
- if (audioTrack.enabled)
+ if (audioTrack.isEnabled)
{
- audioCodecSummary = [NSString stringWithFormat: @"%@", audioTrack.codec[keyAudioCodecName]];
- NSNumber *drc = @(audioTrack.drc);
- NSNumber *gain = @(audioTrack.gain);
- NSString *detailString = [NSString stringWithFormat: @"%@ Encoder: %@ Mixdown: %@ SampleRate: %@(khz) Bitrate: %@(kbps), DRC: %@, Gain: %@",
- audioTrack.track[keyAudioTrackName],
- audioTrack.codec[keyAudioCodecName],
- audioTrack.mixdown[keyAudioMixdownName],
- audioTrack.sampleRate[keyAudioSampleRateName],
- audioTrack.bitRate[keyAudioBitrateName],
- (0.0 < [drc floatValue]) ? (NSObject *)drc : (NSObject *)@"Off",
- (0.0 != [gain floatValue]) ? (NSObject *)gain : (NSObject *)@"Off"
+ const char *codecName = hb_audio_encoder_get_name(audioTrack.encoder);
+ const char *mixdownName = hb_mixdown_get_name(audioTrack.mixdown);
+ const char *sampleRateName = audioTrack.sampleRate ? hb_audio_samplerate_get_name(audioTrack.sampleRate) : "Auto";
+
+ audioCodecSummary = [NSString stringWithFormat: @"%@", @(codecName)];
+ NSString *detailString = [NSString stringWithFormat: @"%@ Encoder: %@, Mixdown: %@, SampleRate: %@ khz, Bitrate: %d kbps, DRC: %@, Gain: %@",
+ self.audio.sourceTracks[audioTrack.sourceTrackIdx][keyAudioTrackName],
+ @(codecName),
+ @(mixdownName),
+ @(sampleRateName),
+ audioTrack.bitRate,
+ (0.0 < audioTrack.drc) ? @(audioTrack.drc) : NSLocalizedString(@"Off", nil),
+ (0.0 != audioTrack.gain) ? @(audioTrack.gain) : NSLocalizedString(@"Off", nil)
];
[audioDetails addObject: detailString];
// check if we have an Auto Passthru output track
- if ([audioTrack.codec[keyAudioCodecName] isEqualToString: @"Auto Passthru"])
+ if ([@(codecName) isEqualToString: @"Auto Passthru"])
{
autoPassthruPresent = YES;
}
@@ -459,32 +461,28 @@ static NSDictionary *shortHeightAttr;
}
// Ninth Line Subtitle Details
- int i = 0;
for (HBSubtitlesTrack *track in self.subtitles.tracks)
{
// Ignore the none track.
- if (i == self.subtitles.tracks.count - 1)
+ if (track.isEnabled)
{
- continue;
- }
-
- /* remember that index 0 of Subtitles can contain "Foreign Audio Search*/
- [finalString appendString: @"Subtitle: " withAttributes:detailBoldAttr];
- [finalString appendString: self.subtitles.sourceTracks[track.sourceTrackIdx][@"keySubTrackName"] withAttributes:detailAttr];
- if (track.forcedOnly)
- {
- [finalString appendString: @" - Forced Only" withAttributes:detailAttr];
- }
- if (track.burnedIn)
- {
- [finalString appendString: @" - Burned In" withAttributes:detailAttr];
- }
- if (track.def)
- {
- [finalString appendString: @" - Default" withAttributes:detailAttr];
+ // remember that index 0 of Subtitles can contain "Foreign Audio Search
+ [finalString appendString: @"Subtitle: " withAttributes:detailBoldAttr];
+ [finalString appendString: self.subtitles.sourceTracks[track.sourceTrackIdx][@"keySubTrackName"] withAttributes:detailAttr];
+ if (track.forcedOnly)
+ {
+ [finalString appendString: @" - Forced Only" withAttributes:detailAttr];
+ }
+ if (track.burnedIn)
+ {
+ [finalString appendString: @" - Burned In" withAttributes:detailAttr];
+ }
+ if (track.def)
+ {
+ [finalString appendString: @" - Default" withAttributes:detailAttr];
+ }
+ [finalString appendString:@"\n" withAttributes:detailAttr];
}
- [finalString appendString:@"\n" withAttributes:detailAttr];
- i++;
}
}
diff --git a/macosx/HandBrake.xcodeproj/project.pbxproj b/macosx/HandBrake.xcodeproj/project.pbxproj
index 0964e5b73..c6fd4ce65 100644
--- a/macosx/HandBrake.xcodeproj/project.pbxproj
+++ b/macosx/HandBrake.xcodeproj/project.pbxproj
@@ -171,6 +171,8 @@
A91CE2FC1C7DB99D0068F46F /* HBPreset.h in Headers */ = {isa = PBXBuildFile; fileRef = A9CF25F21990D64E0023F727 /* HBPreset.h */; settings = {ATTRIBUTES = (Public, ); }; };
A91CE2FD1C7DB99D0068F46F /* HBMutablePreset.h in Headers */ = {isa = PBXBuildFile; fileRef = A96CD1741BCC5F9100F372F1 /* HBMutablePreset.h */; settings = {ATTRIBUTES = (Public, ); }; };
A91CE2FE1C7DB99D0068F46F /* HBTreeNode.h in Headers */ = {isa = PBXBuildFile; fileRef = A9D488A31996270300E9B1BA /* HBTreeNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A91F97351D7B2A4E00D82DCE /* HBAudioTransformers.h in Headers */ = {isa = PBXBuildFile; fileRef = A91F97331D7B2A4E00D82DCE /* HBAudioTransformers.h */; };
+ A91F97361D7B2A4E00D82DCE /* HBAudioTransformers.m in Sources */ = {isa = PBXBuildFile; fileRef = A91F97341D7B2A4E00D82DCE /* HBAudioTransformers.m */; };
A92268781A6E555500A8D5C5 /* HBAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = A92268771A6E555500A8D5C5 /* HBAppDelegate.m */; };
A922687B1A6E569B00A8D5C5 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = A92268791A6E569B00A8D5C5 /* MainWindow.xib */; };
A932E26C1988334B0047D13E /* AudioDefaults.xib in Resources */ = {isa = PBXBuildFile; fileRef = A932E26A1988334B0047D13E /* AudioDefaults.xib */; };
@@ -412,6 +414,8 @@
A91CE2CF1C7DABCE0068F46F /* libbz2.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libbz2.tbd; path = usr/lib/libbz2.tbd; sourceTree = SDKROOT; };
A91CE2D11C7DABDA0068F46F /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; };
A91CE2D31C7DABE40068F46F /* libiconv.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libiconv.tbd; path = usr/lib/libiconv.tbd; sourceTree = SDKROOT; };
+ A91F97331D7B2A4E00D82DCE /* HBAudioTransformers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HBAudioTransformers.h; sourceTree = "<group>"; };
+ A91F97341D7B2A4E00D82DCE /* HBAudioTransformers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HBAudioTransformers.m; sourceTree = "<group>"; };
A92268761A6E555500A8D5C5 /* HBAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HBAppDelegate.h; sourceTree = "<group>"; };
A92268771A6E555500A8D5C5 /* HBAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HBAppDelegate.m; sourceTree = "<group>"; };
A922687A1A6E569B00A8D5C5 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = MainWindow.xib; sourceTree = "<group>"; };
@@ -1120,6 +1124,8 @@
A932E272198834130047D13E /* HBAudioDefaults.m */,
A90A0CAD1988D57200DA65CE /* HBAudioTrackPreset.h */,
A90A0CAE1988D57200DA65CE /* HBAudioTrackPreset.m */,
+ A91F97331D7B2A4E00D82DCE /* HBAudioTransformers.h */,
+ A91F97341D7B2A4E00D82DCE /* HBAudioTransformers.m */,
);
name = Audio;
sourceTree = "<group>";
@@ -1252,6 +1258,7 @@
A91CE2FC1C7DB99D0068F46F /* HBPreset.h in Headers */,
A91CE2FD1C7DB99D0068F46F /* HBMutablePreset.h in Headers */,
A98B8E241C7DD2A200B810C9 /* HBPresetCoding.h in Headers */,
+ A91F97351D7B2A4E00D82DCE /* HBAudioTransformers.h in Headers */,
A91CE2FE1C7DB99D0068F46F /* HBTreeNode.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -1525,6 +1532,7 @@
A91CE27F1C7DA7320068F46F /* HBTitle.m in Sources */,
A91CE2821C7DA7320068F46F /* HBJob.m in Sources */,
A91CE2841C7DA7320068F46F /* HBJob+HBJobConversion.m in Sources */,
+ A91F97361D7B2A4E00D82DCE /* HBAudioTransformers.m in Sources */,
A91CE2861C7DA7320068F46F /* HBRange.m in Sources */,
A91CE2881C7DA7320068F46F /* HBVideo.m in Sources */,
A91CE28A1C7DA7320068F46F /* HBPicture.m in Sources */,