diff options
-rw-r--r-- | macosx/HBAudio.h | 25 | ||||
-rw-r--r-- | macosx/HBAudio.m | 990 | ||||
-rw-r--r-- | macosx/HBAudioController.h | 14 | ||||
-rw-r--r-- | macosx/HBAudioController.m | 782 |
4 files changed, 963 insertions, 848 deletions
diff --git a/macosx/HBAudio.h b/macosx/HBAudio.h index 618bd2430..65655a3a6 100644 --- a/macosx/HBAudio.h +++ b/macosx/HBAudio.h @@ -21,18 +21,18 @@ extern NSString *keyAudioBitrate; @interface HBAudio : NSObject { - NSDictionary *track; - NSDictionary *codec; - NSDictionary *mixdown; - NSDictionary *sampleRate; - NSDictionary *bitRate; - NSNumber *drc; - NSNumber *gain; - NSNumber *videoContainerTag; - HBAudioController *controller; - NSMutableArray *codecs; - NSMutableArray *mixdowns; - NSMutableArray *bitRates; + NSDictionary * track; + NSDictionary * codec; + NSDictionary * mixdown; + NSDictionary * sampleRate; + NSDictionary * bitRate; + NSNumber * drc; + NSNumber * gain; + NSNumber * videoContainerTag; + HBAudioController * controller; + NSMutableArray * codecs; + NSMutableArray * mixdowns; + NSMutableArray * bitRates; } @property (nonatomic, retain) NSDictionary *track; @@ -58,4 +58,3 @@ extern NSString *keyAudioBitrate; - (void) setBitRateFromName: (NSString *) aValue; @end - diff --git a/macosx/HBAudio.m b/macosx/HBAudio.m index ba684a3ca..194d4dd16 100644 --- a/macosx/HBAudio.m +++ b/macosx/HBAudio.m @@ -35,22 +35,28 @@ static NSMutableArray *masterBitRateArray = nil; - (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]) && nil == retval) { - if (nil != (aValue = [dict objectForKey: aKey]) && YES == [aValue isEqual: anObject]) { - retval = dict; - } - } - return retval; + NSDictionary *retval = nil; + NSEnumerator *enumerator = reverse ? [self reverseObjectEnumerator] : [self objectEnumerator]; + NSDictionary *dict; + id aValue; + + while (nil != (dict = [enumerator nextObject]) && nil == retval) + { + if (nil != (aValue = [dict objectForKey: aKey]) && YES == [aValue isEqual: anObject]) + { + retval = dict; + } + } + return retval; } - (NSDictionary *) dictionaryWithObject: (id) anObject matchingKey: (NSString *) aKey -{ return [self dictionaryWithObject: anObject matchingKey: aKey reverse: NO]; } +{ + return [self dictionaryWithObject: anObject matchingKey: aKey reverse: NO]; +} - (NSDictionary *) lastDictionaryWithObject: (id) anObject matchingKey: (NSString *) aKey -{ return [self dictionaryWithObject: anObject matchingKey: aKey reverse: YES]; } +{ + return [self dictionaryWithObject: anObject matchingKey: aKey reverse: YES]; +} @end @@ -62,332 +68,368 @@ static NSMutableArray *masterBitRateArray = nil; + (void) load { - if ([HBAudio class] == self) { - int i; - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - NSDictionary *dict; - - masterCodecArray = [[NSMutableArray alloc] init]; // knowingly leaked - [masterCodecArray addObject: [NSDictionary dictionaryWithObjectsAndKeys: - NSLocalizedString(@"AAC (CoreAudio)", @"AAC (CoreAudio)"), keyAudioCodecName, - [NSNumber numberWithInt: HB_ACODEC_CA_AAC], keyAudioCodec, - [NSNumber numberWithBool: YES], keyAudioMP4, - [NSNumber numberWithBool: YES], keyAudioMKV, - [NSNumber numberWithBool: NO], keyAudioMustMatchTrack, - nil]]; - if (encca_haac_available()) { - [masterCodecArray addObject: [NSDictionary dictionaryWithObjectsAndKeys: - NSLocalizedString(@"HE-AAC (CoreAudio)", @"HE-AAC (CoreAudio)"), keyAudioCodecName, - [NSNumber numberWithInt: HB_ACODEC_CA_HAAC], keyAudioCodec, - [NSNumber numberWithBool: YES], keyAudioMP4, - [NSNumber numberWithBool: YES], keyAudioMKV, - [NSNumber numberWithBool: NO], keyAudioMustMatchTrack, - nil]]; - } - [masterCodecArray addObject: [NSDictionary dictionaryWithObjectsAndKeys: - NSLocalizedString(@"AAC (ffmpeg)", @"AAC (ffmpeg)"), keyAudioCodecName, - [NSNumber numberWithInt: HB_ACODEC_FFAAC], keyAudioCodec, - [NSNumber numberWithBool: YES], keyAudioMP4, - [NSNumber numberWithBool: YES], keyAudioMKV, - [NSNumber numberWithBool: NO], keyAudioMustMatchTrack, - nil]]; - [masterCodecArray addObject: [NSDictionary dictionaryWithObjectsAndKeys: - NSLocalizedString(@"AAC (faac)", @"AAC (faac)"), keyAudioCodecName, - [NSNumber numberWithInt: HB_ACODEC_FAAC], keyAudioCodec, - [NSNumber numberWithBool: YES], keyAudioMP4, - [NSNumber numberWithBool: YES], keyAudioMKV, - [NSNumber numberWithBool: NO], keyAudioMustMatchTrack, - nil]]; - [masterCodecArray addObject: [NSDictionary dictionaryWithObjectsAndKeys: - NSLocalizedString(@"MP3 (lame)", @"MP3 (lame)"), keyAudioCodecName, - [NSNumber numberWithInt: HB_ACODEC_LAME], keyAudioCodec, - [NSNumber numberWithBool: YES], keyAudioMP4, - [NSNumber numberWithBool: YES], keyAudioMKV, - [NSNumber numberWithBool: NO], keyAudioMustMatchTrack, - nil]]; - [masterCodecArray addObject: [NSDictionary dictionaryWithObjectsAndKeys: - NSLocalizedString(@"AC3 Passthru", @"AC3 Passthru"), keyAudioCodecName, - [NSNumber numberWithInt: HB_ACODEC_AC3_PASS], keyAudioCodec, - [NSNumber numberWithBool: YES], keyAudioMP4, - [NSNumber numberWithBool: YES], keyAudioMKV, - [NSNumber numberWithInt: HB_ACODEC_AC3], keyAudioMustMatchTrack, - nil]]; - [masterCodecArray addObject: [NSDictionary dictionaryWithObjectsAndKeys: - NSLocalizedString(@"AC3", @"AC3"), keyAudioCodecName, - [NSNumber numberWithInt: HB_ACODEC_AC3], keyAudioCodec, - [NSNumber numberWithBool: YES], keyAudioMP4, - [NSNumber numberWithBool: YES], keyAudioMKV, - [NSNumber numberWithBool: NO], keyAudioMustMatchTrack, - nil]]; - [masterCodecArray addObject: [NSDictionary dictionaryWithObjectsAndKeys: - NSLocalizedString(@"DTS Passthru", @"DTS Passthru"), keyAudioCodecName, - [NSNumber numberWithInt: HB_ACODEC_DCA_PASS], keyAudioCodec, - [NSNumber numberWithBool: NO], keyAudioMP4, - [NSNumber numberWithBool: YES], keyAudioMKV, - [NSNumber numberWithInt: HB_ACODEC_DCA], keyAudioMustMatchTrack, - nil]]; - [masterCodecArray addObject: [NSDictionary dictionaryWithObjectsAndKeys: - NSLocalizedString(@"Vorbis (vorbis)", @"Vorbis (vorbis)"), keyAudioCodecName, - [NSNumber numberWithInt: HB_ACODEC_VORBIS], keyAudioCodec, - [NSNumber numberWithBool: NO], keyAudioMP4, - [NSNumber numberWithBool: YES], keyAudioMKV, - [NSNumber numberWithBool: NO], keyAudioMustMatchTrack, - nil]]; - - masterMixdownArray = [[NSMutableArray alloc] init]; // knowingly leaked - [masterMixdownArray addObject: [NSDictionary dictionaryWithObjectsAndKeys: - NSLocalizedString(@"AC3 Passthru", @"AC3 Passthru"), keyAudioMixdownName, - [NSNumber numberWithInt: HB_ACODEC_AC3_PASS], keyAudioMixdown, - nil]]; - [masterMixdownArray addObject: [NSDictionary dictionaryWithObjectsAndKeys: - NSLocalizedString(@"DTS Passthru", @"DTS Passthru"), keyAudioMixdownName, - [NSNumber numberWithInt: HB_ACODEC_DCA_PASS], keyAudioMixdown, - nil]]; - for (i = 0; i < hb_audio_mixdowns_count; i++) { - [masterMixdownArray addObject: [NSDictionary dictionaryWithObjectsAndKeys: - [NSString stringWithUTF8String: hb_audio_mixdowns[i].human_readable_name], keyAudioMixdownName, - [NSNumber numberWithInt: hb_audio_mixdowns[i].amixdown], keyAudioMixdown, - nil]]; - } - - // 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. - masterSampleRateArray = [[NSMutableArray alloc] init]; // knowingly leaked - [masterSampleRateArray addObject: [NSDictionary dictionaryWithObjectsAndKeys: - NSLocalizedString(@"Auto", @"Auto"), keyAudioSampleRateName, - [NSNumber numberWithInt: 0], keyAudioSamplerate, - nil]]; - for (i = 0; i < hb_audio_rates_count; i++) { - [masterSampleRateArray addObject: [NSDictionary dictionaryWithObjectsAndKeys: - [NSString stringWithUTF8String: hb_audio_rates[i].string], keyAudioSampleRateName, - [NSNumber numberWithInt: hb_audio_rates[i].rate], keyAudioSamplerate, - nil]]; - } - - masterBitRateArray = [[NSMutableArray alloc] init]; // knowingly leaked - for (i = 0; i < hb_audio_bitrates_count; i++) { - dict = [NSDictionary dictionaryWithObjectsAndKeys: - [NSString stringWithUTF8String: hb_audio_bitrates[i].string], keyAudioBitrateName, - [NSNumber numberWithInt: hb_audio_bitrates[i].rate], keyAudioBitrate, - nil]; - [masterBitRateArray addObject: dict]; - } - - [pool release]; - } - return; + if ([HBAudio class] == self) + { + int i; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSDictionary *dict; + + masterCodecArray = [[NSMutableArray alloc] init]; // knowingly leaked + [masterCodecArray addObject: [NSDictionary dictionaryWithObjectsAndKeys: + NSLocalizedString(@"AAC (CoreAudio)", @"AAC (CoreAudio)"), keyAudioCodecName, + [NSNumber numberWithInt: HB_ACODEC_CA_AAC], keyAudioCodec, + [NSNumber numberWithBool: YES], keyAudioMP4, + [NSNumber numberWithBool: YES], keyAudioMKV, + [NSNumber numberWithBool: NO], keyAudioMustMatchTrack, + nil]]; + if (encca_haac_available()) + { + [masterCodecArray addObject: [NSDictionary dictionaryWithObjectsAndKeys: + NSLocalizedString(@"HE-AAC (CoreAudio)", @"HE-AAC (CoreAudio)"), keyAudioCodecName, + [NSNumber numberWithInt: HB_ACODEC_CA_HAAC], keyAudioCodec, + [NSNumber numberWithBool: YES], keyAudioMP4, + [NSNumber numberWithBool: YES], keyAudioMKV, + [NSNumber numberWithBool: NO], keyAudioMustMatchTrack, + nil]]; + } + [masterCodecArray addObject: [NSDictionary dictionaryWithObjectsAndKeys: + NSLocalizedString(@"AAC (ffmpeg)", @"AAC (ffmpeg)"), keyAudioCodecName, + [NSNumber numberWithInt: HB_ACODEC_FFAAC], keyAudioCodec, + [NSNumber numberWithBool: YES], keyAudioMP4, + [NSNumber numberWithBool: YES], keyAudioMKV, + [NSNumber numberWithBool: NO], keyAudioMustMatchTrack, + nil]]; + [masterCodecArray addObject: [NSDictionary dictionaryWithObjectsAndKeys: + NSLocalizedString(@"AAC (faac)", @"AAC (faac)"), keyAudioCodecName, + [NSNumber numberWithInt: HB_ACODEC_FAAC], keyAudioCodec, + [NSNumber numberWithBool: YES], keyAudioMP4, + [NSNumber numberWithBool: YES], keyAudioMKV, + [NSNumber numberWithBool: NO], keyAudioMustMatchTrack, + nil]]; + [masterCodecArray addObject: [NSDictionary dictionaryWithObjectsAndKeys: + NSLocalizedString(@"MP3 (lame)", @"MP3 (lame)"), keyAudioCodecName, + [NSNumber numberWithInt: HB_ACODEC_LAME], keyAudioCodec, + [NSNumber numberWithBool: YES], keyAudioMP4, + [NSNumber numberWithBool: YES], keyAudioMKV, + [NSNumber numberWithBool: NO], keyAudioMustMatchTrack, + nil]]; + [masterCodecArray addObject: [NSDictionary dictionaryWithObjectsAndKeys: + NSLocalizedString(@"AC3 Passthru", @"AC3 Passthru"), keyAudioCodecName, + [NSNumber numberWithInt: HB_ACODEC_AC3_PASS], keyAudioCodec, + [NSNumber numberWithBool: YES], keyAudioMP4, + [NSNumber numberWithBool: YES], keyAudioMKV, + [NSNumber numberWithInt: HB_ACODEC_AC3], keyAudioMustMatchTrack, + nil]]; + [masterCodecArray addObject: [NSDictionary dictionaryWithObjectsAndKeys: + NSLocalizedString(@"AC3", @"AC3"), keyAudioCodecName, + [NSNumber numberWithInt: HB_ACODEC_AC3], keyAudioCodec, + [NSNumber numberWithBool: YES], keyAudioMP4, + [NSNumber numberWithBool: YES], keyAudioMKV, + [NSNumber numberWithBool: NO], keyAudioMustMatchTrack, + nil]]; + [masterCodecArray addObject: [NSDictionary dictionaryWithObjectsAndKeys: + NSLocalizedString(@"DTS Passthru", @"DTS Passthru"), keyAudioCodecName, + [NSNumber numberWithInt: HB_ACODEC_DCA_PASS], keyAudioCodec, + [NSNumber numberWithBool: NO], keyAudioMP4, + [NSNumber numberWithBool: YES], keyAudioMKV, + [NSNumber numberWithInt: HB_ACODEC_DCA], keyAudioMustMatchTrack, + nil]]; + [masterCodecArray addObject: [NSDictionary dictionaryWithObjectsAndKeys: + NSLocalizedString(@"Vorbis (vorbis)", @"Vorbis (vorbis)"), keyAudioCodecName, + [NSNumber numberWithInt: HB_ACODEC_VORBIS], keyAudioCodec, + [NSNumber numberWithBool: NO], keyAudioMP4, + [NSNumber numberWithBool: YES], keyAudioMKV, + [NSNumber numberWithBool: NO], keyAudioMustMatchTrack, + nil]]; + + masterMixdownArray = [[NSMutableArray alloc] init]; // knowingly leaked + [masterMixdownArray addObject: [NSDictionary dictionaryWithObjectsAndKeys: + NSLocalizedString(@"AC3 Passthru", @"AC3 Passthru"), keyAudioMixdownName, + [NSNumber numberWithInt: HB_ACODEC_AC3_PASS], keyAudioMixdown, + nil]]; + [masterMixdownArray addObject: [NSDictionary dictionaryWithObjectsAndKeys: + NSLocalizedString(@"DTS Passthru", @"DTS Passthru"), keyAudioMixdownName, + [NSNumber numberWithInt: HB_ACODEC_DCA_PASS], keyAudioMixdown, + nil]]; + for (i = 0; i < hb_audio_mixdowns_count; i++) + { + [masterMixdownArray addObject: [NSDictionary dictionaryWithObjectsAndKeys: + [NSString stringWithUTF8String: hb_audio_mixdowns[i].human_readable_name], keyAudioMixdownName, + [NSNumber numberWithInt: hb_audio_mixdowns[i].amixdown], keyAudioMixdown, + nil]]; + } + + // 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. + masterSampleRateArray = [[NSMutableArray alloc] init]; // knowingly leaked + [masterSampleRateArray addObject: [NSDictionary dictionaryWithObjectsAndKeys: + NSLocalizedString(@"Auto", @"Auto"), keyAudioSampleRateName, + [NSNumber numberWithInt: 0], keyAudioSamplerate, + nil]]; + for (i = 0; i < hb_audio_rates_count; i++) + { + [masterSampleRateArray addObject: [NSDictionary dictionaryWithObjectsAndKeys: + [NSString stringWithUTF8String: hb_audio_rates[i].string], keyAudioSampleRateName, + [NSNumber numberWithInt: hb_audio_rates[i].rate], keyAudioSamplerate, + nil]]; + } + + masterBitRateArray = [[NSMutableArray alloc] init]; // knowingly leaked + for (i = 0; i < hb_audio_bitrates_count; i++) + { + dict = [NSDictionary dictionaryWithObjectsAndKeys: + [NSString stringWithUTF8String: hb_audio_bitrates[i].string], keyAudioBitrateName, + [NSNumber numberWithInt: hb_audio_bitrates[i].rate], keyAudioBitrate, + nil]; + [masterBitRateArray addObject: dict]; + } + + [pool release]; + } + return; } -// Ensure the list of codecs is accurate -// Update the current value of codec based on the revised list +// Ensure the list of codecs is accurate +// Update the current value of codec based on the revised list - (void) updateCodecs { - NSMutableArray *permittedCodecs = [NSMutableArray array]; - unsigned int count = [masterCodecArray count]; - NSDictionary *dict; - NSString *keyThatAllows = nil; - - // Determine which key we use to see which codecs are permitted - switch ([videoContainerTag intValue]) { - case HB_MUX_MP4: - keyThatAllows = keyAudioMP4; - break; - case HB_MUX_MKV: - keyThatAllows = keyAudioMKV; - break; - default: - keyThatAllows = @"error condition"; - break; - } - - // First get a list of the permitted codecs based on the internal rules - if (nil != track && YES == [self enabled]) { - BOOL goodToAdd; - - for (unsigned int i = 0; i < count; i++) { - dict = [masterCodecArray objectAtIndex: i]; - - // First make sure only codecs permitted by the container are here - goodToAdd = [[dict objectForKey: keyThatAllows] boolValue]; - - // 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 (YES == [[dict objectForKey: keyAudioMustMatchTrack] boolValue]) { - if ([[dict objectForKey: keyAudioMustMatchTrack] intValue] != [[[self track] objectForKey: keyAudioInputCodec] intValue]) { - goodToAdd = NO; - } - } - - if (YES == goodToAdd) { - [permittedCodecs addObject: dict]; - } - } - } - - // Now make sure the permitted list and the actual ones matches - [self setCodecs: permittedCodecs]; - - // Ensure our codec is on the list of permitted codecs - if (nil == [self codec] || NO == [permittedCodecs containsObject: [self codec]]) { - if (0 < [permittedCodecs count]) { - [self setCodec: [permittedCodecs objectAtIndex: 0]]; // This should be defaulting to Core Audio - } - else { - [self setCodec: nil]; - } - } - - return; + NSMutableArray *permittedCodecs = [NSMutableArray array]; + unsigned int count = [masterCodecArray count]; + NSDictionary *dict; + NSString *keyThatAllows = nil; + + // Determine which key we use to see which codecs are permitted + switch ([videoContainerTag intValue]) + { + case HB_MUX_MP4: + keyThatAllows = keyAudioMP4; + break; + case HB_MUX_MKV: + keyThatAllows = keyAudioMKV; + break; + default: + keyThatAllows = @"error condition"; + break; + } + + // First get a list of the permitted codecs based on the internal rules + if (nil != track && YES == [self enabled]) + { + BOOL goodToAdd; + + for (unsigned int i = 0; i < count; i++) + { + dict = [masterCodecArray objectAtIndex: i]; + + // First make sure only codecs permitted by the container are here + goodToAdd = [[dict objectForKey: keyThatAllows] boolValue]; + + // 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 (YES == [[dict objectForKey: keyAudioMustMatchTrack] boolValue]) + { + if ([[dict objectForKey: keyAudioMustMatchTrack] intValue] != [[[self track] objectForKey: keyAudioInputCodec] intValue]) + { + goodToAdd = NO; + } + } + + if (YES == goodToAdd) + { + [permittedCodecs addObject: dict]; + } + } + } + + // Now make sure the permitted list and the actual ones matches + [self setCodecs: permittedCodecs]; + + // Ensure our codec is on the list of permitted codecs + if (nil == [self codec] || NO == [permittedCodecs containsObject: [self codec]]) + { + if (0 < [permittedCodecs count]) + { + [self setCodec: [permittedCodecs objectAtIndex: 0]]; // This should be defaulting to Core Audio + } + else + { + [self setCodec: nil]; + } + } + + return; } - (void) updateMixdowns: (BOOL) shouldSetDefault { - NSMutableArray *permittedMixdowns = [NSMutableArray array]; - NSDictionary *dict; - BOOL shouldAdd; - int currentMixdown; - - unsigned int count = [masterMixdownArray count]; - int codecCodec = [[codec objectForKey: keyAudioCodec] intValue]; - int channelLayout = [[track objectForKey: keyAudioInputChannelLayout] intValue]; - int theDefaultMixdown = hb_get_default_mixdown(codecCodec, channelLayout); - int theBestMixdown = hb_get_best_mixdown(codecCodec, channelLayout, 0); - - for (unsigned int i = 0; i < count; i++) { - dict = [masterMixdownArray objectAtIndex: i]; - currentMixdown = [[dict objectForKey: keyAudioMixdown] intValue]; - - // Basically with the way the mixdowns are stored, the assumption from the libhb point of view - // currently is that all mixdowns from the best down to mono are supported. - if (currentMixdown <= theBestMixdown) { - shouldAdd = YES; - } else if (0 == theBestMixdown && codecCodec == currentMixdown) { - // 0 means passthrough, add the current mixdown if it matches the passthrough codec - shouldAdd = YES; - } else { - shouldAdd = NO; - } - - if (YES == shouldAdd) { - [permittedMixdowns addObject: dict]; - } - } - - if (0 == theDefaultMixdown) { - // a mixdown of 0 means passthrough - theDefaultMixdown = codecCodec; - } - - if (NO == [self enabled]) { - permittedMixdowns = nil; - } - - // Now make sure the permitted list and the actual ones matches - [self setMixdowns: permittedMixdowns]; - - // Select the proper one - if (YES == shouldSetDefault) { - [self setMixdown: [permittedMixdowns dictionaryWithObject: [NSNumber numberWithInt: theDefaultMixdown] matchingKey: keyAudioMixdown]]; - } - - if (nil == [self mixdown] || NO == [permittedMixdowns containsObject: [self mixdown]]) { - [self setMixdown: [permittedMixdowns lastObject]]; - } - - return; + NSMutableArray *permittedMixdowns = [NSMutableArray array]; + NSDictionary *dict; + BOOL shouldAdd; + int currentMixdown; + + unsigned int count = [masterMixdownArray count]; + int codecCodec = [[codec objectForKey: keyAudioCodec] intValue]; + int channelLayout = [[track objectForKey: keyAudioInputChannelLayout] intValue]; + int theDefaultMixdown = hb_get_default_mixdown(codecCodec, channelLayout); + int theBestMixdown = hb_get_best_mixdown(codecCodec, channelLayout, 0); + + for (unsigned int i = 0; i < count; i++) + { + dict = [masterMixdownArray objectAtIndex: i]; + currentMixdown = [[dict objectForKey: keyAudioMixdown] intValue]; + + // Basically with the way the mixdowns are stored, the assumption from the libhb point of view + // currently is that all mixdowns from the best down to mono are supported. + if (currentMixdown <= theBestMixdown) + { + shouldAdd = YES; + } + else if (0 == theBestMixdown && codecCodec == currentMixdown) + { + // 0 means passthrough, add the current mixdown if it matches the passthrough codec + shouldAdd = YES; + } + else + { + shouldAdd = NO; + } + + if (YES == shouldAdd) + { + [permittedMixdowns addObject: dict]; + } + } + + if (0 == theDefaultMixdown) + { + // a mixdown of 0 means passthrough + theDefaultMixdown = codecCodec; + } + + if (NO == [self enabled]) + { + permittedMixdowns = nil; + } + + // Now make sure the permitted list and the actual ones matches + [self setMixdowns: permittedMixdowns]; + + // Select the proper one + if (YES == shouldSetDefault) + { + [self setMixdown: [permittedMixdowns dictionaryWithObject: [NSNumber numberWithInt: theDefaultMixdown] matchingKey: keyAudioMixdown]]; + } + + if (nil == [self mixdown] || NO == [permittedMixdowns containsObject: [self mixdown]]) + { + [self setMixdown: [permittedMixdowns lastObject]]; + } + + return; } - (void) updateBitRates: (BOOL) shouldSetDefault { - NSMutableArray *permittedBitRates = [NSMutableArray array]; - NSDictionary *dict; - int minBitRate; - int maxBitRate; - int currentBitRate; - BOOL shouldAdd; - - unsigned int count = [masterBitRateArray count]; - int trackInputBitRate = [[[self track] objectForKey: keyAudioInputBitrate] intValue]; - BOOL limitsToTrackInputBitRate = ([[codec objectForKey: keyAudioCodec] intValue] & HB_ACODEC_PASS_FLAG) ? YES : NO; - int theSampleRate = [[[self sampleRate] objectForKey: keyAudioSamplerate] intValue]; - - if (0 == theSampleRate) { // this means Auto - theSampleRate = [[[self track] objectForKey: keyAudioInputSampleRate] intValue]; - } - - int ourCodec = [[codec objectForKey: keyAudioCodec] intValue]; - int ourMixdown = [[[self mixdown] objectForKey: keyAudioMixdown] intValue]; - hb_get_audio_bitrate_limits(ourCodec, theSampleRate, ourMixdown, &minBitRate, &maxBitRate); - int theDefaultBitRate = hb_get_default_audio_bitrate(ourCodec, theSampleRate, ourMixdown); - - for (unsigned int i = 0; i < count; i++) { - dict = [masterBitRateArray objectAtIndex: i]; - currentBitRate = [[dict objectForKey: keyAudioBitrate] intValue]; - - // First ensure the bitrate falls within range of the codec - shouldAdd = (currentBitRate >= minBitRate && currentBitRate <= maxBitRate); - - // Now make sure the mixdown is not limiting us to the track input bitrate - if (YES == shouldAdd && YES == limitsToTrackInputBitRate) { - if (currentBitRate != trackInputBitRate) { - shouldAdd = NO; - } - } - - if (YES == shouldAdd) { - [permittedBitRates addObject: dict]; - } - } - - // There is a situation where we have a mixdown requirement to match the track input bit rate, - // but it does not fall into the range the codec supports. Therefore, we force it here. - if (YES == limitsToTrackInputBitRate && 0 == [permittedBitRates count]) { - NSDictionary *missingBitRate = [masterBitRateArray dictionaryWithObject: [NSNumber numberWithInt: trackInputBitRate] matchingKey: keyAudioBitrate]; - if (nil == missingBitRate) { - // We are in an even worse situation where the requested bit rate does not even exist in the underlying - // library of supported bitrates. Of course since this value is ignored we can freely make a bogus one - // for the UI just to make the user a little more aware. - missingBitRate = [NSDictionary dictionaryWithObjectsAndKeys: - [NSString stringWithFormat: @"%d", trackInputBitRate], keyAudioBitrateName, - [NSNumber numberWithInt: trackInputBitRate], keyAudioBitrate, - nil]; - } - [permittedBitRates addObject: missingBitRate]; - } - - if (NO == [self enabled]) { - permittedBitRates = nil; - } - - // Make sure we are updated with the permitted list - [self setBitRates: permittedBitRates]; - - // Select the proper one - if (YES == shouldSetDefault) { - [self setBitRateFromName: [NSString stringWithFormat:@"%d", theDefaultBitRate]]; - } - - if (nil == [self bitRate] || NO == [permittedBitRates containsObject: [self bitRate]]) { - [self setBitRate: [permittedBitRates lastObject]]; - } - - return; + NSMutableArray *permittedBitRates = [NSMutableArray array]; + NSDictionary *dict; + int minBitRate; + int maxBitRate; + int currentBitRate; + BOOL shouldAdd; + + unsigned int count = [masterBitRateArray count]; + int trackInputBitRate = [[[self track] objectForKey: keyAudioInputBitrate] intValue]; + BOOL limitsToTrackInputBitRate = ([[codec objectForKey: keyAudioCodec] intValue] & HB_ACODEC_PASS_FLAG) ? YES : NO; + int theSampleRate = [[[self sampleRate] objectForKey: keyAudioSamplerate] intValue]; + + if (0 == theSampleRate) // this means Auto + { + theSampleRate = [[[self track] objectForKey: keyAudioInputSampleRate] intValue]; + } + + int ourCodec = [[codec objectForKey: keyAudioCodec] intValue]; + int ourMixdown = [[[self mixdown] objectForKey: keyAudioMixdown] intValue]; + hb_get_audio_bitrate_limits(ourCodec, theSampleRate, ourMixdown, &minBitRate, &maxBitRate); + int theDefaultBitRate = hb_get_default_audio_bitrate(ourCodec, theSampleRate, ourMixdown); + + for (unsigned int i = 0; i < count; i++) + { + dict = [masterBitRateArray objectAtIndex: i]; + currentBitRate = [[dict objectForKey: keyAudioBitrate] intValue]; + + // First ensure the bitrate falls within range of the codec + shouldAdd = (currentBitRate >= minBitRate && currentBitRate <= maxBitRate); + + // Now make sure the mixdown is not limiting us to the track input bitrate + if (YES == shouldAdd && YES == limitsToTrackInputBitRate) + { + if (currentBitRate != trackInputBitRate) + { + shouldAdd = NO; + } + } + + if (YES == shouldAdd) + { + [permittedBitRates addObject: dict]; + } + } + + // There is a situation where we have a mixdown requirement to match the track input bit rate, + // but it does not fall into the range the codec supports. Therefore, we force it here. + if (YES == limitsToTrackInputBitRate && 0 == [permittedBitRates count]) + { + NSDictionary *missingBitRate = [masterBitRateArray dictionaryWithObject: [NSNumber numberWithInt: trackInputBitRate] matchingKey: keyAudioBitrate]; + if (nil == missingBitRate) + { + // We are in an even worse situation where the requested bit rate does not even exist in the underlying + // library of supported bitrates. Of course since this value is ignored we can freely make a bogus one + // for the UI just to make the user a little more aware. + missingBitRate = [NSDictionary dictionaryWithObjectsAndKeys: + [NSString stringWithFormat: @"%d", trackInputBitRate], keyAudioBitrateName, + [NSNumber numberWithInt: trackInputBitRate], keyAudioBitrate, + nil]; + } + [permittedBitRates addObject: missingBitRate]; + } + + if (NO == [self enabled]) + { + permittedBitRates = nil; + } + + // Make sure we are updated with the permitted list + [self setBitRates: permittedBitRates]; + + // Select the proper one + if (YES == shouldSetDefault) + { + [self setBitRateFromName: [NSString stringWithFormat:@"%d", theDefaultBitRate]]; + } + + if (nil == [self bitRate] || NO == [permittedBitRates containsObject: [self bitRate]]) + { + [self setBitRate: [permittedBitRates lastObject]]; + } + + return; } - (id) init { - if (self = [super init]) { - [self addObserver: self forKeyPath: @"videoContainerTag" options: 0 context: NULL]; - [self addObserver: self forKeyPath: @"track" options: NSKeyValueObservingOptionOld context: NULL]; - [self addObserver: self forKeyPath: @"codec" options: 0 context: NULL]; - [self addObserver: self forKeyPath: @"mixdown" options: 0 context: NULL]; - [self addObserver: self forKeyPath: @"sampleRate" options: 0 context: NULL]; - } - return self; + if (self = [super init]) + { + [self addObserver: self forKeyPath: @"videoContainerTag" options: 0 context: NULL]; + [self addObserver: self forKeyPath: @"track" options: NSKeyValueObservingOptionOld context: NULL]; + [self addObserver: self forKeyPath: @"codec" options: 0 context: NULL]; + [self addObserver: self forKeyPath: @"mixdown" options: 0 context: NULL]; + [self addObserver: self forKeyPath: @"sampleRate" options: 0 context: NULL]; + } + return self; } #pragma mark - @@ -407,29 +449,32 @@ static NSMutableArray *masterBitRateArray = nil; @synthesize mixdowns; @synthesize bitRates; -- (NSArray *) sampleRates { return masterSampleRateArray; } +- (NSArray *) sampleRates +{ + return masterSampleRateArray; +} - (void) dealloc { - [self removeObserver: self forKeyPath: @"videoContainerTag"]; - [self removeObserver: self forKeyPath: @"track"]; - [self removeObserver: self forKeyPath: @"codec"]; - [self removeObserver: self forKeyPath: @"mixdown"]; - [self removeObserver: self forKeyPath: @"sampleRate"]; - [self setTrack: nil]; - [self setCodec: nil]; - [self setMixdown: nil]; - [self setSampleRate: nil]; - [self setBitRate: nil]; - [self setDrc: nil]; + [self removeObserver: self forKeyPath: @"videoContainerTag"]; + [self removeObserver: self forKeyPath: @"track"]; + [self removeObserver: self forKeyPath: @"codec"]; + [self removeObserver: self forKeyPath: @"mixdown"]; + [self removeObserver: self forKeyPath: @"sampleRate"]; + [self setTrack: nil]; + [self setCodec: nil]; + [self setMixdown: nil]; + [self setSampleRate: nil]; + [self setBitRate: nil]; + [self setDrc: nil]; [self setGain: nil]; - [self setVideoContainerTag: nil]; - [self setCodecs: nil]; - [self setMixdowns: nil]; - [self setBitRates: nil]; - [super dealloc]; - return; + [self setVideoContainerTag: nil]; + [self setCodecs: nil]; + [self setMixdowns: nil]; + [self setBitRates: nil]; + [super dealloc]; + return; } #pragma mark - @@ -438,36 +483,45 @@ static NSMutableArray *masterBitRateArray = nil; - (void) observeValueForKeyPath: (NSString *) keyPath ofObject: (id) object change: (NSDictionary *) change context: (void *) context { - if (YES == [keyPath isEqualToString: @"videoContainerTag"]) { - [self updateCodecs]; - } - else if (YES == [keyPath isEqualToString: @"track"]) { - if (nil != [self track]) { - [self updateCodecs]; - [self updateMixdowns: YES]; - if (YES == [self enabled]) { - [self setSampleRate: [[self sampleRates] objectAtIndex: 0]]; // default to Auto - } - if (YES == [[controller noneTrack] isEqual: [change objectForKey: NSKeyValueChangeOldKey]]) { - [controller switchingTrackFromNone: self]; - } - if (YES == [[controller noneTrack] isEqual: [self track]]) { - [controller settingTrackToNone: self]; - } - } - } - else if (YES == [keyPath isEqualToString: @"codec"]) { - [self updateMixdowns: YES]; - [self updateBitRates: YES]; - } - else if (YES == [keyPath isEqualToString: @"mixdown"]) { - [self updateBitRates: YES]; - [[NSNotificationCenter defaultCenter] postNotificationName: HBMixdownChangedNotification object: self]; - } - else if (YES == [keyPath isEqualToString: @"sampleRate"]) { - [self updateBitRates: NO]; - } - return; + if (YES == [keyPath isEqualToString: @"videoContainerTag"]) + { + [self updateCodecs]; + } + else if (YES == [keyPath isEqualToString: @"track"]) + { + if (nil != [self track]) + { + [self updateCodecs]; + [self updateMixdowns: YES]; + if (YES == [self enabled]) + { + [self setSampleRate: [[self sampleRates] objectAtIndex: 0]]; // default to Auto + } + if (YES == [[controller noneTrack] isEqual: [change objectForKey: NSKeyValueChangeOldKey]]) + { + [controller switchingTrackFromNone: self]; + } + if (YES == [[controller noneTrack] isEqual: [self track]]) + { + [controller settingTrackToNone: self]; + } + } + } + else if (YES == [keyPath isEqualToString: @"codec"]) + { + [self updateMixdowns: YES]; + [self updateBitRates: YES]; + } + else if (YES == [keyPath isEqualToString: @"mixdown"]) + { + [self updateBitRates: YES]; + [[NSNotificationCenter defaultCenter] postNotificationName: HBMixdownChangedNotification object: self]; + } + else if (YES == [keyPath isEqualToString: @"sampleRate"]) + { + [self updateBitRates: NO]; + } + return; } #pragma mark - @@ -476,88 +530,96 @@ static NSMutableArray *masterBitRateArray = nil; - (void) setTrackFromIndex: (int) aValue { - [self setTrack: [self.controller.masterTrackArray dictionaryWithObject: [NSNumber numberWithInt: aValue] matchingKey: keyAudioTrackIndex]]; + [self setTrack: [self.controller.masterTrackArray dictionaryWithObject: [NSNumber numberWithInt: aValue] matchingKey: keyAudioTrackIndex]]; } -// This returns whether it is able to set the actual codec desired. +// This returns whether it is able to set the actual codec desired. - (BOOL) setCodecFromName: (NSString *) aValue { - NSDictionary *dict = [[self codecs] dictionaryWithObject: aValue matchingKey: keyAudioCodecName]; - - if (nil != dict) { - [self setCodec: dict]; - } - return (nil != dict); + NSDictionary *dict = [[self codecs] dictionaryWithObject: aValue matchingKey: keyAudioCodecName]; + + if (nil != dict) + { + [self setCodec: dict]; + } + return (nil != dict); } - (void) setMixdownFromName: (NSString *) aValue { - NSDictionary *dict = [[self mixdowns] dictionaryWithObject: aValue matchingKey: keyAudioMixdownName]; + NSDictionary *dict = [[self mixdowns] dictionaryWithObject: aValue matchingKey: keyAudioMixdownName]; - if (nil != dict) { - [self setMixdown: dict]; - } - return; + if (nil != dict) + { + [self setMixdown: dict]; + } + return; } - (void) setSampleRateFromName: (NSString *) aValue { - NSDictionary *dict = [[self sampleRates] dictionaryWithObject: aValue matchingKey: keyAudioSampleRateName]; - - if (nil != dict) { - [self setSampleRate: dict]; - } - return; + NSDictionary *dict = [[self sampleRates] dictionaryWithObject: aValue matchingKey: keyAudioSampleRateName]; + + if (nil != dict) + { + [self setSampleRate: dict]; + } + return; } - (void) setBitRateFromName: (NSString *) aValue { - NSDictionary *dict = [[self bitRates] dictionaryWithObject: aValue matchingKey: keyAudioBitrateName]; - - if (nil != dict) { - [self setBitRate: dict]; - } - return; + NSDictionary *dict = [[self bitRates] dictionaryWithObject: aValue matchingKey: keyAudioBitrateName]; + + if (nil != dict) + { + [self setBitRate: dict]; + } + return; } #pragma mark - #pragma mark Validation -// 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. +// 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 = [NSNumber numberWithFloat: 1.0]; - } - } - - return retval; + BOOL retval = YES; + + if (nil != *ioValue) + { + if (0.0 < [*ioValue floatValue] && 1.0 > [*ioValue floatValue]) + { + *ioValue = [NSNumber numberWithFloat: 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. - +// 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 = [NSNumber numberWithFloat: 0.0]; - } - } - - return retval; + BOOL retval = YES; + + if (nil != *ioValue) + { + if (0.0 < [*ioValue floatValue] && 1.0 > [*ioValue floatValue]) + { + *ioValue = [NSNumber numberWithFloat: 0.0]; + } + } + + return retval; } #pragma mark - @@ -566,70 +628,80 @@ static NSMutableArray *masterBitRateArray = nil; - (BOOL) enabled { - return (nil != track) ? (NO == [track isEqual: [controller noneTrack]]) : NO; + return (nil != track) ? (NO == [track isEqual: [controller noneTrack]]) : NO; } - (BOOL) mixdownEnabled { - BOOL retval = [self enabled]; - - if (YES == retval) { - int myMixdown = [[[self mixdown] objectForKey: keyAudioMixdown] intValue]; - if (HB_ACODEC_AC3_PASS == myMixdown || HB_ACODEC_DCA_PASS == myMixdown) { - retval = NO; - } - } - return retval; + BOOL retval = [self enabled]; + + if (YES == retval) + { + int myMixdown = [[[self mixdown] objectForKey: keyAudioMixdown] intValue]; + if (HB_ACODEC_AC3_PASS == myMixdown || HB_ACODEC_DCA_PASS == myMixdown) + { + retval = NO; + } + } + return retval; } - (BOOL) AC3Enabled { - BOOL retval = [self enabled]; - - if (YES == retval) { - int myTrackCodec = [[[self track] objectForKey: keyAudioInputCodec] intValue]; - int myCodecCodec = [[[self codec] objectForKey: keyAudioCodec] intValue]; - if (HB_ACODEC_AC3 != myTrackCodec || HB_ACODEC_AC3_PASS == myCodecCodec) { - retval = NO; - } - } - return retval; + BOOL retval = [self enabled]; + + if (YES == retval) + { + int myTrackCodec = [[[self track] objectForKey: keyAudioInputCodec] intValue]; + int myCodecCodec = [[[self codec] objectForKey: keyAudioCodec] intValue]; + if (HB_ACODEC_AC3 != myTrackCodec || HB_ACODEC_AC3_PASS == myCodecCodec) + { + retval = NO; + } + } + return retval; } - (BOOL) PassThruDisabled { - BOOL retval = [self enabled]; - - if (YES == retval) { - int myCodecCodec = [[[self codec] objectForKey: keyAudioCodec] intValue]; - if (HB_ACODEC_AC3_PASS == myCodecCodec || HB_ACODEC_DCA_PASS == myCodecCodec) { - retval = NO; - } - } - return retval; + BOOL retval = [self enabled]; + + if (YES == retval) + { + int myCodecCodec = [[[self codec] objectForKey: keyAudioCodec] intValue]; + if (HB_ACODEC_AC3_PASS == myCodecCodec || HB_ACODEC_DCA_PASS == myCodecCodec) + { + retval = NO; + } + } + return retval; } + (NSSet *) keyPathsForValuesAffectingValueForKey: (NSString *) key { - NSSet *retval = nil; - - if (YES == [key isEqualToString: @"enabled"]) { - retval = [NSSet setWithObjects: @"track", nil]; - } - else if (YES == [key isEqualToString: @"PassThruDisabled"]) { - retval = [NSSet setWithObjects: @"track", @"codec", nil]; - } - else if (YES == [key isEqualToString: @"AC3Enabled"]) { - retval = [NSSet setWithObjects: @"track", @"codec", nil]; - } - else if (YES == [key isEqualToString: @"mixdownEnabled"]) { - retval = [NSSet setWithObjects: @"track", @"mixdown", nil]; - } - return retval; + NSSet *retval = nil; + + if (YES == [key isEqualToString: @"enabled"]) + { + retval = [NSSet setWithObjects: @"track", nil]; + } + else if (YES == [key isEqualToString: @"PassThruDisabled"]) + { + retval = [NSSet setWithObjects: @"track", @"codec", nil]; + } + else if (YES == [key isEqualToString: @"AC3Enabled"]) + { + retval = [NSSet setWithObjects: @"track", @"codec", nil]; + } + else if (YES == [key isEqualToString: @"mixdownEnabled"]) + { + retval = [NSSet setWithObjects: @"track", @"mixdown", nil]; + } + return retval; } @end diff --git a/macosx/HBAudioController.h b/macosx/HBAudioController.h index a998b446d..69c1d501a 100644 --- a/macosx/HBAudioController.h +++ b/macosx/HBAudioController.h @@ -20,13 +20,13 @@ extern NSString *HBMixdownChangedNotification; @interface HBAudioController : NSObject - { - 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 - } +{ + 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, readonly, retain) NSArray *masterTrackArray; @property (nonatomic, readonly) NSDictionary *noneTrack; diff --git a/macosx/HBAudioController.m b/macosx/HBAudioController.m index 9aabe2536..b604fcc87 100644 --- a/macosx/HBAudioController.m +++ b/macosx/HBAudioController.m @@ -38,44 +38,46 @@ NSString *HBMixdownChangedNotification = @"HBMixdownChangedNotification"; - (id) init { - if (self = [super init]) { - [self setVideoContainerTag: [NSNumber numberWithInt: HB_MUX_MP4]]; - audioArray = [[NSMutableArray alloc] init]; - } - return self; + if (self = [super init]) + { + [self setVideoContainerTag: [NSNumber numberWithInt: HB_MUX_MP4]]; + audioArray = [[NSMutableArray alloc] init]; + } + return self; } - (void) dealloc { - [[NSNotificationCenter defaultCenter] removeObserver: self]; - [masterTrackArray release]; - [noneTrack release]; - [audioArray release]; - [self setVideoContainerTag: nil]; - [super dealloc]; - return; + [[NSNotificationCenter defaultCenter] removeObserver: self]; + [masterTrackArray release]; + [noneTrack release]; + [audioArray release]; + [self setVideoContainerTag: nil]; + [super dealloc]; + return; } - (void) setHBController: (id) aController { - NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; - myController = aController; + 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]; - return; + /* 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]; + return; } - (void) _clearAudioArray { - while (0 < [self countOfAudioArray]) { - [self removeObjectFromAudioArrayAtIndex: 0]; - } - return; + while (0 < [self countOfAudioArray]) + { + [self removeObjectFromAudioArrayAtIndex: 0]; + } + return; } #pragma mark - @@ -84,22 +86,24 @@ NSString *HBMixdownChangedNotification = @"HBMixdownChangedNotification"; - (void) prepareAudioForQueueFileJob: (NSMutableDictionary *) aDict { - unsigned int audioArrayCount = [self countOfAudioArray]; - for (unsigned int counter = 0; counter < audioArrayCount; counter++) { - HBAudio *anAudio = [self objectInAudioArrayAtIndex: counter]; - if (YES == [anAudio enabled]) { - NSString *prefix = [NSString stringWithFormat: @"Audio%d", counter + 1]; - NSNumber *sampleRateToUse = (0 == [[[anAudio sampleRate] objectForKey: keyAudioSamplerate] intValue]) ? - [[anAudio track] objectForKey: keyAudioInputSampleRate] : - [[anAudio sampleRate] objectForKey: keyAudioSamplerate]; - - [aDict setObject: [[anAudio track] objectForKey: keyAudioTrackIndex] forKey: [prefix stringByAppendingString: @"Track"]]; - [aDict setObject: [[anAudio track] objectForKey: keyAudioTrackName] forKey: [prefix stringByAppendingString: @"TrackDescription"]]; - [aDict setObject: [[anAudio codec] objectForKey: keyAudioCodecName] forKey: [prefix stringByAppendingString: @"Encoder"]]; - [aDict setObject: [[anAudio mixdown] objectForKey: keyAudioMixdownName] forKey: [prefix stringByAppendingString: @"Mixdown"]]; - [aDict setObject: [[anAudio sampleRate] objectForKey: keyAudioSampleRateName] forKey: [prefix stringByAppendingString: @"Samplerate"]]; - [aDict setObject: [[anAudio bitRate] objectForKey: keyAudioBitrateName] forKey: [prefix stringByAppendingString: @"Bitrate"]]; - + unsigned int audioArrayCount = [self countOfAudioArray]; + for (unsigned int counter = 0; counter < audioArrayCount; counter++) + { + HBAudio *anAudio = [self objectInAudioArrayAtIndex: counter]; + if (YES == [anAudio enabled]) + { + NSString *prefix = [NSString stringWithFormat: @"Audio%d", counter + 1]; + NSNumber *sampleRateToUse = (0 == [[[anAudio sampleRate] objectForKey: keyAudioSamplerate] intValue]) ? + [[anAudio track] objectForKey: keyAudioInputSampleRate] : + [[anAudio sampleRate] objectForKey: keyAudioSamplerate]; + + [aDict setObject: [[anAudio track] objectForKey: keyAudioTrackIndex] forKey: [prefix stringByAppendingString: @"Track"]]; + [aDict setObject: [[anAudio track] objectForKey: keyAudioTrackName] forKey: [prefix stringByAppendingString: @"TrackDescription"]]; + [aDict setObject: [[anAudio codec] objectForKey: keyAudioCodecName] forKey: [prefix stringByAppendingString: @"Encoder"]]; + [aDict setObject: [[anAudio mixdown] objectForKey: keyAudioMixdownName] forKey: [prefix stringByAppendingString: @"Mixdown"]]; + [aDict setObject: [[anAudio sampleRate] objectForKey: keyAudioSampleRateName] forKey: [prefix stringByAppendingString: @"Samplerate"]]; + [aDict setObject: [[anAudio bitRate] objectForKey: keyAudioBitrateName] forKey: [prefix stringByAppendingString: @"Bitrate"]]; + // output is not passthru so apply gain if (HB_ACODEC_AC3_PASS != [[[anAudio codec] objectForKey: keyAudioCodec] intValue] && HB_ACODEC_DCA_PASS != [[[anAudio codec] objectForKey: keyAudioCodec] intValue]) { @@ -108,339 +112,369 @@ NSString *HBMixdownChangedNotification = @"HBMixdownChangedNotification"; else { // output is passthru - the Gain dial is disabled so don't apply its value - [aDict setObject: [NSNumber numberWithInt:0] forKey: [prefix stringByAppendingString: @"TrackGainSlider"]]; + [aDict setObject: [NSNumber numberWithInt:0] forKey: [prefix stringByAppendingString: @"TrackGainSlider"]]; } - - if ((HB_ACODEC_AC3 == [[[anAudio track] objectForKey: keyAudioInputCodec] intValue]) && - (HB_ACODEC_AC3_PASS != [[[anAudio codec] objectForKey: keyAudioCodec] intValue])) { - [aDict setObject: [anAudio drc] forKey: [prefix stringByAppendingString: @"TrackDRCSlider"]]; - } - else { - // source isn't AC3 or output is passthru - the DRC dial is disabled so don't apply its value - [aDict setObject: [NSNumber numberWithInt:0] forKey: [prefix stringByAppendingString: @"TrackDRCSlider"]]; - } - - prefix = [NSString stringWithFormat: @"JobAudio%d", counter + 1]; - [aDict setObject: [[anAudio codec] objectForKey: keyAudioCodec] forKey: [prefix stringByAppendingString: @"Encoder"]]; - [aDict setObject: [[anAudio mixdown] objectForKey: keyAudioMixdown] forKey: [prefix stringByAppendingString: @"Mixdown"]]; - [aDict setObject: sampleRateToUse forKey: [prefix stringByAppendingString: @"Samplerate"]]; - [aDict setObject: [[anAudio bitRate] objectForKey: keyAudioBitrate] forKey: [prefix stringByAppendingString: @"Bitrate"]]; - } - } - return; + + if ((HB_ACODEC_AC3 == [[[anAudio track] objectForKey: keyAudioInputCodec] intValue]) && + (HB_ACODEC_AC3_PASS != [[[anAudio codec] objectForKey: keyAudioCodec] intValue])) + { + [aDict setObject: [anAudio drc] forKey: [prefix stringByAppendingString: @"TrackDRCSlider"]]; + } + else + { + // source isn't AC3 or output is passthru - the DRC dial is disabled so don't apply its value + [aDict setObject: [NSNumber numberWithInt:0] forKey: [prefix stringByAppendingString: @"TrackDRCSlider"]]; + } + + prefix = [NSString stringWithFormat: @"JobAudio%d", counter + 1]; + [aDict setObject: [[anAudio codec] objectForKey: keyAudioCodec] forKey: [prefix stringByAppendingString: @"Encoder"]]; + [aDict setObject: [[anAudio mixdown] objectForKey: keyAudioMixdown] forKey: [prefix stringByAppendingString: @"Mixdown"]]; + [aDict setObject: sampleRateToUse forKey: [prefix stringByAppendingString: @"Samplerate"]]; + [aDict setObject: [[anAudio bitRate] objectForKey: keyAudioBitrate] forKey: [prefix stringByAppendingString: @"Bitrate"]]; + } + } + return; } - (void) prepareAudioForJob: (hb_job_t *) aJob { - unsigned int i; - - // First clear out any audio tracks in the job currently + unsigned int i; + + // First clear out any audio tracks in the job currently int audiotrack_count = hb_list_count(aJob->list_audio); for(i = 0; i < audiotrack_count; i++) + { hb_audio_t *temp_audio = (hb_audio_t *) hb_list_item(aJob->list_audio, 0); hb_list_rem(aJob->list_audio, temp_audio); } - // Now add audio tracks based on the current settings - unsigned int audioArrayCount = [self countOfAudioArray]; - for (i = 0; i < audioArrayCount; i++) { - HBAudio *anAudio = [self objectInAudioArrayAtIndex: i]; - if (YES == [anAudio enabled]) { - NSNumber *sampleRateToUse = (0 == [[[anAudio sampleRate] objectForKey: keyAudioSamplerate] intValue]) ? - [[anAudio track] objectForKey: keyAudioInputSampleRate] : - [[anAudio sampleRate] objectForKey: keyAudioSamplerate]; - - hb_audio_config_t *audio = (hb_audio_config_t *) calloc(1, sizeof(*audio)); - hb_audio_config_init(audio); - audio->in.track = [[[anAudio track] objectForKey: keyAudioTrackIndex] intValue] - 1; - /* We go ahead and assign values to our audio->out.<properties> */ - audio->out.track = audio->in.track; - audio->out.codec = [[[anAudio codec] objectForKey: keyAudioCodec] intValue]; - audio->out.mixdown = [[[anAudio mixdown] objectForKey: keyAudioMixdown] intValue]; - audio->out.bitrate = [[[anAudio bitRate] objectForKey: keyAudioBitrate] intValue]; - audio->out.samplerate = [sampleRateToUse intValue]; - audio->out.dynamic_range_compression = [[anAudio drc] floatValue]; + // Now add audio tracks based on the current settings + unsigned int audioArrayCount = [self countOfAudioArray]; + for (i = 0; i < audioArrayCount; i++) + { + HBAudio *anAudio = [self objectInAudioArrayAtIndex: i]; + if (YES == [anAudio enabled]) + { + NSNumber *sampleRateToUse = (0 == [[[anAudio sampleRate] objectForKey: keyAudioSamplerate] intValue]) ? + [[anAudio track] objectForKey: keyAudioInputSampleRate] : + [[anAudio sampleRate] objectForKey: keyAudioSamplerate]; + + hb_audio_config_t *audio = (hb_audio_config_t *) calloc(1, sizeof(*audio)); + hb_audio_config_init(audio); + audio->in.track = [[[anAudio track] objectForKey: keyAudioTrackIndex] intValue] - 1; + /* We go ahead and assign values to our audio->out.<properties> */ + audio->out.track = audio->in.track; + audio->out.codec = [[[anAudio codec] objectForKey: keyAudioCodec] intValue]; + audio->out.mixdown = [[[anAudio mixdown] objectForKey: keyAudioMixdown] intValue]; + audio->out.bitrate = [[[anAudio bitRate] objectForKey: keyAudioBitrate] intValue]; + audio->out.samplerate = [sampleRateToUse intValue]; + audio->out.dynamic_range_compression = [[anAudio drc] floatValue]; audio->out.gain = [[anAudio gain] floatValue]; - - hb_audio_add(aJob, audio); - free(audio); - } - } - return; + + hb_audio_add(aJob, audio); + free(audio); + } + } + return; } - (void) prepareAudioForPreset: (NSMutableArray *) anArray { - unsigned int audioArrayCount = [self countOfAudioArray]; - unsigned int i; - - for (i = 0; i < audioArrayCount; i++) { - HBAudio *anAudio = [self objectInAudioArrayAtIndex: i]; - if (YES == [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"]; + unsigned int audioArrayCount = [self countOfAudioArray]; + unsigned int i; + + for (i = 0; i < audioArrayCount; i++) + { + HBAudio *anAudio = [self objectInAudioArrayAtIndex: i]; + if (YES == [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]; - } - } - return; + [anArray addObject: dict]; + [dict release]; + } + } + return; } - (void) addTracksFromQueue: (NSMutableDictionary *) aQueue { - NSString *base; - int value; - int maximumNumberOfAllowedAudioTracks = [HBController maximumNumberOfAllowedAudioTracks]; - - // Reinitialize the configured list of audio tracks - [self _clearAudioArray]; - - // The following is the pattern to follow, but with Audio%dTrack being the key to seek... - // Can we assume that there will be no skip in the data? - for (unsigned int i = 1; i <= maximumNumberOfAllowedAudioTracks; i++) { - base = [NSString stringWithFormat: @"Audio%d", i]; - value = [[aQueue objectForKey: [base stringByAppendingString: @"Track"]] intValue]; - if (0 < value) { - HBAudio *newAudio = [[HBAudio alloc] init]; - [newAudio setController: self]; - [self insertObject: newAudio inAudioArrayAtIndex: [self countOfAudioArray]]; - [newAudio setVideoContainerTag: [self videoContainerTag]]; - [newAudio setTrackFromIndex: value]; - [newAudio setCodecFromName: [aQueue objectForKey: [base stringByAppendingString: @"Encoder"]]]; - [newAudio setMixdownFromName: [aQueue objectForKey: [base stringByAppendingString: @"Mixdown"]]]; - [newAudio setSampleRateFromName: [aQueue objectForKey: [base stringByAppendingString: @"Samplerate"]]]; - [newAudio setBitRateFromName: [aQueue objectForKey: [base stringByAppendingString: @"Bitrate"]]]; - [newAudio setDrc: [aQueue objectForKey: [base stringByAppendingString: @"TrackDRCSlider"]]]; + NSString *base; + int value; + int maximumNumberOfAllowedAudioTracks = [HBController maximumNumberOfAllowedAudioTracks]; + + // Reinitialize the configured list of audio tracks + [self _clearAudioArray]; + + // The following is the pattern to follow, but with Audio%dTrack being the key to seek... + // Can we assume that there will be no skip in the data? + for (unsigned int i = 1; i <= maximumNumberOfAllowedAudioTracks; i++) + { + base = [NSString stringWithFormat: @"Audio%d", i]; + value = [[aQueue objectForKey: [base stringByAppendingString: @"Track"]] intValue]; + if (0 < value) + { + HBAudio *newAudio = [[HBAudio alloc] init]; + [newAudio setController: self]; + [self insertObject: newAudio inAudioArrayAtIndex: [self countOfAudioArray]]; + [newAudio setVideoContainerTag: [self videoContainerTag]]; + [newAudio setTrackFromIndex: value]; + [newAudio setCodecFromName: [aQueue objectForKey: [base stringByAppendingString: @"Encoder"]]]; + [newAudio setMixdownFromName: [aQueue objectForKey: [base stringByAppendingString: @"Mixdown"]]]; + [newAudio setSampleRateFromName: [aQueue objectForKey: [base stringByAppendingString: @"Samplerate"]]]; + [newAudio setBitRateFromName: [aQueue objectForKey: [base stringByAppendingString: @"Bitrate"]]]; + [newAudio setDrc: [aQueue objectForKey: [base stringByAppendingString: @"TrackDRCSlider"]]]; [newAudio setGain: [aQueue objectForKey: [base stringByAppendingString: @"TrackGainSlider"]]]; - [newAudio release]; - } - } + [newAudio release]; + } + } + + [self switchingTrackFromNone: nil]; // see if we need to add one to the list - [self switchingTrackFromNone: nil]; // see if we need to add one to the list - - return; + return; } -// 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. +// 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 { - NSArray *retval = [aPreset objectForKey: @"AudioList"]; - - if (nil == retval) { - 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", + NSArray *retval = [aPreset objectForKey: @"AudioList"]; + + if (nil == retval) + { + 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; - } - return retval; + nil]]; + } + } + retval = whatToUse; + } + return retval; } -// This uses the templateAudioArray from the preset to create the audios for the specified trackIndex +// 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 { - NSEnumerator *enumerator = [templateAudioArray objectEnumerator]; - NSMutableDictionary *dict; - NSString *key; - int maximumNumberOfAllowedAudioTracks = [HBController maximumNumberOfAllowedAudioTracks]; - - while (nil != (dict = [enumerator nextObject])) { - if ([self countOfAudioArray] < maximumNumberOfAllowedAudioTracks) { - BOOL fallenBack = NO; - HBAudio *newAudio = [[HBAudio alloc] init]; - [newAudio setController: self]; - [self insertObject: newAudio inAudioArrayAtIndex: [self countOfAudioArray]]; - [newAudio setVideoContainerTag: [self videoContainerTag]]; - [newAudio setTrackFromIndex: trackIndex]; - key = [dict objectForKey: @"AudioEncoder"]; - if (0 == aType && - YES == [[NSUserDefaults standardUserDefaults] boolForKey: @"UseCoreAudio"] && - YES == [key isEqualToString: @"AAC (faac)"] - ) { - key = @"AAC (CoreAudio)"; - } - if (YES == [[NSUserDefaults standardUserDefaults] boolForKey: @"AC3PassthruDefaultsToAC3"] && - YES == [key isEqualToString: @"AC3 Passthru"]) { - if (NO == [newAudio setCodecFromName: key]) { - key = @"AC3"; - fallenBack = YES; - } - } + NSEnumerator *enumerator = [templateAudioArray objectEnumerator]; + NSMutableDictionary *dict; + NSString *key; + int maximumNumberOfAllowedAudioTracks = [HBController maximumNumberOfAllowedAudioTracks]; + + while (nil != (dict = [enumerator nextObject])) + { + if ([self countOfAudioArray] < maximumNumberOfAllowedAudioTracks) + { + BOOL fallenBack = NO; + HBAudio *newAudio = [[HBAudio alloc] init]; + [newAudio setController: self]; + [self insertObject: newAudio inAudioArrayAtIndex: [self countOfAudioArray]]; + [newAudio setVideoContainerTag: [self videoContainerTag]]; + [newAudio setTrackFromIndex: trackIndex]; + key = [dict objectForKey: @"AudioEncoder"]; + if (0 == aType && + YES == [[NSUserDefaults standardUserDefaults] boolForKey: @"UseCoreAudio"] && + YES == [key isEqualToString: @"AAC (faac)"]) + { + key = @"AAC (CoreAudio)"; + } + if (YES == [[NSUserDefaults standardUserDefaults] boolForKey: @"AC3PassthruDefaultsToAC3"] && + YES == [key isEqualToString: @"AC3 Passthru"]) + { + if (NO == [newAudio setCodecFromName: key]) + { + key = @"AC3"; + fallenBack = YES; + } + } // 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"]; } - - // 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 (YES == [newAudio setCodecFromName: key]) { - [newAudio setMixdownFromName: [dict objectForKey: @"AudioMixdown"]]; - [newAudio setSampleRateFromName: [dict objectForKey: @"AudioSamplerate"]]; - if (NO == fallenBack) { - [newAudio setBitRateFromName: [dict objectForKey: @"AudioBitrate"]]; - } - [newAudio setDrc: [dict objectForKey: @"AudioTrackDRCSlider"]]; + + // 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 (YES == [newAudio setCodecFromName: key]) + { + [newAudio setMixdownFromName: [dict objectForKey: @"AudioMixdown"]]; + [newAudio setSampleRateFromName: [dict objectForKey: @"AudioSamplerate"]]; + if (NO == fallenBack) + { + [newAudio setBitRateFromName: [dict objectForKey: @"AudioBitrate"]]; + } + [newAudio setDrc: [dict objectForKey: @"AudioTrackDRCSlider"]]; [newAudio setGain: [dict objectForKey: @"AudioTrackGainSlider"]]; - } - else { - [self removeObjectFromAudioArrayAtIndex: [self countOfAudioArray] - 1]; - } - [newAudio release]; - } - } - return; + } + else + { + [self removeObjectFromAudioArrayAtIndex: [self countOfAudioArray] - 1]; + } + [newAudio release]; + } + } + return; } -// This matches the FIRST track with the specified prefix, otherwise it uses the defaultIfNotFound value +// This matches the FIRST track with the specified prefix, otherwise it uses the defaultIfNotFound value - (unsigned int) _trackWithTitlePrefix: (NSString *) prefix defaultIfNotFound: (unsigned int) defaultIfNotFound { - unsigned int retval = defaultIfNotFound; - int count = [masterTrackArray count]; - NSString *languageTitle; - BOOL found = NO; - - // 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 && NO == found; i++) { // Note that we skip the "None" track - languageTitle = [[masterTrackArray objectAtIndex: i] objectForKey: keyAudioTrackName]; - if (YES == [[languageTitle substringFromIndex: [languageTitle rangeOfString: @" "].location + 1] hasPrefix: prefix]) { - retval = i; - found = YES; - } - } - return retval; + unsigned int retval = defaultIfNotFound; + int count = [masterTrackArray count]; + NSString *languageTitle; + BOOL found = NO; + + // 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 && NO == found; i++) // Note that we skip the "None" track + { + languageTitle = [[masterTrackArray objectAtIndex: i] objectForKey: keyAudioTrackName]; + if (YES == [[languageTitle substringFromIndex: [languageTitle rangeOfString: @" "].location + 1] hasPrefix: prefix]) + { + retval = i; + found = 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. +// 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 { - static NSMutableDictionary *retval = nil; - - if (nil == retval) { - retval = [[NSMutableDictionary dictionaryWithObjectsAndKeys: - [NSArray arrayWithObject: - [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithInt: 1], @"AudioTrack", - @"AAC (faac)", @"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; + static NSMutableDictionary *retval = nil; + + if (nil == retval) + { + retval = [[NSMutableDictionary dictionaryWithObjectsAndKeys: + [NSArray arrayWithObject: + [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithInt: 1], @"AudioTrack", + @"AAC (faac)", @"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; } - (void) addTracksFromPreset: (NSMutableDictionary *) aPreset allTracks: (BOOL) allTracks { - id whatToUse = [self _presetAudioArrayFromPreset: aPreset]; - NSString *preferredLanguageName = [[NSUserDefaults standardUserDefaults] stringForKey: @"DefaultLanguage"]; - int preferredLanguage = [self _trackWithTitlePrefix: preferredLanguageName defaultIfNotFound: 1]; - - // Reinitialize the configured list of audio tracks - [self _clearAudioArray]; - - [self _processPresetAudioArray: whatToUse forTrack: preferredLanguage andType: [[aPreset objectForKey: @"Type"] intValue]]; - if (YES == allTracks) { - unsigned int count = [masterTrackArray count]; - for (unsigned int i = 1; i < count; i++) { - if (i != preferredLanguage) { - [self _processPresetAudioArray: whatToUse forTrack: i andType: [[aPreset objectForKey: @"Type"] intValue]]; - } - } - } - - return; + id whatToUse = [self _presetAudioArrayFromPreset: aPreset]; + NSString *preferredLanguageName = [[NSUserDefaults standardUserDefaults] stringForKey: @"DefaultLanguage"]; + int preferredLanguage = [self _trackWithTitlePrefix: preferredLanguageName defaultIfNotFound: 1]; + + // Reinitialize the configured list of audio tracks + [self _clearAudioArray]; + + [self _processPresetAudioArray: whatToUse forTrack: preferredLanguage andType: [[aPreset objectForKey: @"Type"] intValue]]; + if (YES == allTracks) + { + unsigned int count = [masterTrackArray count]; + for (unsigned int i = 1; i < count; i++) + { + if (i != preferredLanguage) + { + [self _processPresetAudioArray: whatToUse forTrack: i andType: [[aPreset objectForKey: @"Type"] intValue]]; + } + } + } + + return; } - (void) _ensureAtLeastOneNonEmptyTrackExists { - int count = [self countOfAudioArray]; - if (0 == count || NO == [[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 - return; + int count = [self countOfAudioArray]; + if (0 == count || NO == [[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 + return; } - (void) addTracksFromPreset: (NSMutableDictionary *) aPreset { - [self addTracksFromPreset: aPreset allTracks: NO]; - [self _ensureAtLeastOneNonEmptyTrackExists]; - return; + [self addTracksFromPreset: aPreset allTracks: NO]; + [self _ensureAtLeastOneNonEmptyTrackExists]; + return; } - (void) addAllTracksFromPreset: (NSMutableDictionary *) aPreset { - [self addTracksFromPreset: aPreset allTracks: YES]; - [self _ensureAtLeastOneNonEmptyTrackExists]; - return; + [self addTracksFromPreset: aPreset allTracks: YES]; + [self _ensureAtLeastOneNonEmptyTrackExists]; + return; } - (BOOL) anyCodecMatches: (int) aCodecValue { - BOOL retval = NO; - unsigned int audioArrayCount = [self countOfAudioArray]; - for (unsigned int i = 0; i < audioArrayCount && NO == retval; i++) { - HBAudio *anAudio = [self objectInAudioArrayAtIndex: i]; - if (YES == [anAudio enabled] && aCodecValue == [[[anAudio codec] objectForKey: keyAudioCodec] intValue]) { - retval = YES; - } - } - return retval; + BOOL retval = NO; + unsigned int audioArrayCount = [self countOfAudioArray]; + for (unsigned int i = 0; i < audioArrayCount && NO == retval; i++) + { + HBAudio *anAudio = [self objectInAudioArrayAtIndex: i]; + if (YES == [anAudio enabled] && aCodecValue == [[[anAudio codec] objectForKey: keyAudioCodec] intValue]) + { + retval = YES; + } + } + return retval; } - (void) addNewAudioTrack { - HBAudio *newAudio = [[HBAudio alloc] init]; - [newAudio setController: self]; - [self insertObject: newAudio inAudioArrayAtIndex: [self countOfAudioArray]]; - [newAudio setVideoContainerTag: [self videoContainerTag]]; - [newAudio setTrack: noneTrack]; - [newAudio setDrc: [NSNumber numberWithFloat: 0.0]]; + HBAudio *newAudio = [[HBAudio alloc] init]; + [newAudio setController: self]; + [self insertObject: newAudio inAudioArrayAtIndex: [self countOfAudioArray]]; + [newAudio setVideoContainerTag: [self videoContainerTag]]; + [newAudio setTrack: noneTrack]; + [newAudio setDrc: [NSNumber numberWithFloat: 0.0]]; [newAudio setGain: [NSNumber numberWithFloat: 0.0]]; - [newAudio release]; - return; + [newAudio release]; + return; } #pragma mark - @@ -449,105 +483,115 @@ NSString *HBMixdownChangedNotification = @"HBMixdownChangedNotification"; - (void) settingTrackToNone: (HBAudio *) 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 = [audioArray indexOfObject: newNoneTrack]; - - if (NSNotFound != index && index < [self countOfAudioArray] - 1) { - [self removeObjectFromAudioArrayAtIndex: index]; - } - [self switchingTrackFromNone: nil]; // see if we need to add one to the list - return; + // 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 = [audioArray indexOfObject: newNoneTrack]; + + if (NSNotFound != index && index < [self countOfAudioArray] - 1) + { + [self removeObjectFromAudioArrayAtIndex: index]; + } + [self switchingTrackFromNone: nil]; // see if we need to add one to the list + return; } - (void) switchingTrackFromNone: (HBAudio *) noLongerNoneTrack { - int count = [self countOfAudioArray]; - BOOL needToAdd = NO; - int maximumNumberOfAllowedAudioTracks = [HBController maximumNumberOfAllowedAudioTracks]; - - // If there is no last track that is None and we are less than our maximum number of permitted tracks, we add one. - if (count < maximumNumberOfAllowedAudioTracks) { - if (0 < count) { - HBAudio *lastAudio = [self objectInAudioArrayAtIndex: count - 1]; - if (YES == [lastAudio enabled]) { - needToAdd = YES; - } - } - else { - needToAdd = YES; - } - } - - if (YES == needToAdd) { - [self addNewAudioTrack]; - } - return; + int count = [self countOfAudioArray]; + BOOL needToAdd = NO; + int maximumNumberOfAllowedAudioTracks = [HBController maximumNumberOfAllowedAudioTracks]; + + // If there is no last track that is None and we are less than our maximum number of permitted tracks, we add one. + if (count < maximumNumberOfAllowedAudioTracks) + { + if (0 < count) + { + HBAudio *lastAudio = [self objectInAudioArrayAtIndex: count - 1]; + if (YES == [lastAudio enabled]) + { + needToAdd = YES; + } + } + else + { + needToAdd = YES; + } + } + + if (YES == needToAdd) + { + [self addNewAudioTrack]; + } + return; } -// This gets called whenever the video container changes. +// This gets called whenever the video container changes. - (void) containerChanged: (NSNotification *) aNotification { - NSDictionary *notDict = [aNotification userInfo]; + NSDictionary *notDict = [aNotification userInfo]; - [self setVideoContainerTag: [notDict objectForKey: keyContainerTag]]; + [self setVideoContainerTag: [notDict objectForKey: keyContainerTag]]; - // Update each of the instances because this value influences possible settings. - NSEnumerator *enumerator = [audioArray objectEnumerator]; - HBAudio *audioObject; + // Update each of the instances because this value influences possible settings. + NSEnumerator *enumerator = [audioArray objectEnumerator]; + HBAudio *audioObject; - while (nil != (audioObject = [enumerator nextObject])) { - [audioObject setVideoContainerTag: [self videoContainerTag]]; - } - return; + while (nil != (audioObject = [enumerator nextObject])) + { + [audioObject setVideoContainerTag: [self videoContainerTag]]; + } + return; } - (void) titleChanged: (NSNotification *) aNotification { - NSDictionary *notDict = [aNotification userInfo]; - NSData *theData = [notDict objectForKey: keyTitleTag]; - hb_title_t *title = NULL; - - [theData getBytes: &title length: sizeof(title)]; - if (title) { - hb_audio_config_t *audio; - hb_list_t *list = title->list_audio; - int i, count = hb_list_count(list); - - // Reinitialize the master list of available audio tracks from this title - NSMutableArray *newTrackArray = [NSMutableArray array]; - [noneTrack release]; - noneTrack = [[NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithInt: 0], keyAudioTrackIndex, - NSLocalizedString(@"None", @"None"), keyAudioTrackName, - [NSNumber numberWithInt: 0], keyAudioInputCodec, - nil] retain]; - [newTrackArray addObject: noneTrack]; - for (i = 0; i < count; i++) { - audio = (hb_audio_config_t *) hb_list_audio_config_item(list, i); - [newTrackArray addObject: [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithInt: i + 1], keyAudioTrackIndex, - [NSString stringWithFormat: @"%d: %s", i, audio->lang.description], keyAudioTrackName, - [NSNumber numberWithInt: audio->in.bitrate / 1000], keyAudioInputBitrate, - [NSNumber numberWithInt: audio->in.samplerate], keyAudioInputSampleRate, - [NSNumber numberWithInt: audio->in.codec], keyAudioInputCodec, - [NSNumber numberWithInt: audio->in.channel_layout], keyAudioInputChannelLayout, - nil]]; - } - self.masterTrackArray = newTrackArray; - } - - // Reinitialize the configured list of audio tracks - [self _clearAudioArray]; - - if (NO == [myController hasValidPresetSelected]) { - [self _ensureAtLeastOneNonEmptyTrackExists]; - } - return; + NSDictionary *notDict = [aNotification userInfo]; + NSData *theData = [notDict objectForKey: keyTitleTag]; + hb_title_t *title = NULL; + + [theData getBytes: &title length: sizeof(title)]; + if (title) + { + hb_audio_config_t *audio; + hb_list_t *list = title->list_audio; + int i, count = hb_list_count(list); + + // Reinitialize the master list of available audio tracks from this title + NSMutableArray *newTrackArray = [NSMutableArray array]; + [noneTrack release]; + noneTrack = [[NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithInt: 0], keyAudioTrackIndex, + NSLocalizedString(@"None", @"None"), keyAudioTrackName, + [NSNumber numberWithInt: 0], keyAudioInputCodec, + nil] retain]; + [newTrackArray addObject: noneTrack]; + for (i = 0; i < count; i++) + { + audio = (hb_audio_config_t *) hb_list_audio_config_item(list, i); + [newTrackArray addObject: [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithInt: i + 1], keyAudioTrackIndex, + [NSString stringWithFormat: @"%d: %s", i, audio->lang.description], keyAudioTrackName, + [NSNumber numberWithInt: audio->in.bitrate / 1000], keyAudioInputBitrate, + [NSNumber numberWithInt: audio->in.samplerate], keyAudioInputSampleRate, + [NSNumber numberWithInt: audio->in.codec], keyAudioInputCodec, + [NSNumber numberWithInt: audio->in.channel_layout], keyAudioInputChannelLayout, + nil]]; + } + self.masterTrackArray = newTrackArray; + } + + // Reinitialize the configured list of audio tracks + [self _clearAudioArray]; + + if (NO == [myController hasValidPresetSelected]) + { + [self _ensureAtLeastOneNonEmptyTrackExists]; + } + return; } #pragma mark - @@ -556,27 +600,27 @@ NSString *HBMixdownChangedNotification = @"HBMixdownChangedNotification"; - (unsigned int) countOfAudioArray { - return [audioArray count]; + return [audioArray count]; } - (HBAudio *) objectInAudioArrayAtIndex: (unsigned int) index { - return [audioArray objectAtIndex: index]; + return [audioArray objectAtIndex: index]; } - (void) insertObject: (HBAudio *) audioObject inAudioArrayAtIndex: (unsigned int) index; { - [audioArray insertObject: audioObject atIndex: index]; - return; + [audioArray insertObject: audioObject atIndex: index]; + return; } - (void) removeObjectFromAudioArrayAtIndex: (unsigned int) index { - [audioArray removeObjectAtIndex: index]; - return; + [audioArray removeObjectAtIndex: index]; + return; } @end |