From: ritsuka Date: Mon, 4 Aug 2014 07:12:12 +0000 (+0000) Subject: MacGui: Adds a new sheet for audio defaults (presets), uses the same preset keys... X-Git-Tag: 0.10.0~267 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3fdfc2d020d300bee991b4aa5c931bb9e33c3c10;p=handbrake MacGui: Adds a new sheet for audio defaults (presets), uses the same preset keys as the LinGui. The built-in presets still use the languages from the Audio preferences. git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@6264 b64f7644-9d1e-0410-96f1-a4d463321fa5 --- 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 @@ - + - + - - - + + + @@ -59,20 +59,20 @@ - + - + - + - + @@ -198,7 +198,7 @@ - + @@ -208,9 +208,10 @@ - + + @@ -229,7 +230,7 @@ - + @@ -242,7 +243,11 @@ - + + + + + @@ -267,6 +272,9 @@ + + + @@ -280,130 +288,85 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + HBEncoderTrasformer + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + HBEncoderTrasformer + + + + + + + + + + + + + + + + + + + + + + + + + HBMixdownTrasformer + + + + + + + + + + + + + + + + + + + + + + + + + + + HBSampleRateTrasformer + + + + + + Auto + Auto + + + + + + + + + + + + + + + + + + + + + + + + HBIntegerTrasformer + + + + + + None + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + HBIntegerTrasformer + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + HBIntegerTrasformer + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + language + isSelected + + + + + + + + + encoder + mixdown + sampleRate + bitRate + gain + drc + + + + + + + + + + + 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 @@ - + - + @@ -529,7 +529,7 @@ - + @@ -538,7 +538,7 @@ - + @@ -716,7 +716,7 @@ - + @@ -724,17 +724,6 @@ - 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: . + It may be used under the terms of the GNU General Public License. */ + +#import + +@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: . + 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 + +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 + +/** + * 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 = ""; }; 46AB433315F98A2B009C0961 /* DockTextField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DockTextField.h; sourceTree = ""; }; 46AB433415F98A2B009C0961 /* DockTextField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DockTextField.m; sourceTree = ""; }; + A90A0CAD1988D57200DA65CE /* HBAudioTrackPreset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HBAudioTrackPreset.h; sourceTree = ""; }; + A90A0CAE1988D57200DA65CE /* HBAudioTrackPreset.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HBAudioTrackPreset.m; sourceTree = ""; }; A91726E5197291BC00D1AFEF /* HBChapterTitlesController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HBChapterTitlesController.h; sourceTree = ""; }; A91726E6197291BC00D1AFEF /* HBChapterTitlesController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HBChapterTitlesController.m; sourceTree = ""; }; + A932E26B1988334B0047D13E /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = AudioDefaults.xib; sourceTree = ""; }; + A932E26D198833920047D13E /* HBAudioDefaultsController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HBAudioDefaultsController.h; sourceTree = ""; }; + A932E26E198833920047D13E /* HBAudioDefaultsController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HBAudioDefaultsController.m; sourceTree = ""; }; + A932E271198834130047D13E /* HBAudioSettings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HBAudioSettings.h; sourceTree = ""; }; + A932E272198834130047D13E /* HBAudioSettings.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HBAudioSettings.m; sourceTree = ""; }; A93E0ED01972957000FD67FB /* HBVideoController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HBVideoController.h; sourceTree = ""; }; A93E0ED11972957000FD67FB /* HBVideoController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HBVideoController.m; sourceTree = ""; }; A93E0ED61972958C00FD67FB /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = Video.xib; sourceTree = ""; }; @@ -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 = ""; }; + A932E270198833960047D13E /* Audio Defaults */ = { + isa = PBXGroup; + children = ( + A932E26D198833920047D13E /* HBAudioDefaultsController.h */, + A932E26E198833920047D13E /* HBAudioDefaultsController.m */, + ); + name = "Audio Defaults"; + sourceTree = ""; + }; 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 = ""; }; + A932E26A1988334B0047D13E /* AudioDefaults.xib */ = { + isa = PBXVariantGroup; + children = ( + A932E26B1988334B0047D13E /* English */, + ); + name = AudioDefaults.xib; + sourceTree = ""; + }; 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