From d5bcce8f440245352742d35422fe913eb013bbbd Mon Sep 17 00:00:00 2001 From: sr55 Date: Sat, 8 Sep 2012 17:46:28 +0000 Subject: WinGui: Implement hb_get_audio_bitrate_limits() in the Windows UI to provide only valid bitrate options. Also disabled the bitrate selection control for flac. git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@4938 b64f7644-9d1e-0410-96f1-a4d463321fa5 --- .../Converters/Audio/AudioBitrateConverter.cs | 200 +++++++++++++++++---- 1 file changed, 163 insertions(+), 37 deletions(-) (limited to 'win/CS/HandBrakeWPF/Converters/Audio/AudioBitrateConverter.cs') diff --git a/win/CS/HandBrakeWPF/Converters/Audio/AudioBitrateConverter.cs b/win/CS/HandBrakeWPF/Converters/Audio/AudioBitrateConverter.cs index 89016071e..28bbf81ac 100644 --- a/win/CS/HandBrakeWPF/Converters/Audio/AudioBitrateConverter.cs +++ b/win/CS/HandBrakeWPF/Converters/Audio/AudioBitrateConverter.cs @@ -22,6 +22,22 @@ namespace HandBrakeWPF.Converters.Audio /// public class AudioBitrateConverter : IValueConverter { + /// + /// The samplerates. + /// + readonly Dictionary samplerates = new Dictionary + { + { 8, 8000 }, + { 11.025, 11025 }, + { 12, 12000 }, + { 16, 16000 }, + { 22.05, 22050 }, + { 24, 24000 }, + { 32, 32000 }, + { 44.1, 44100 }, + { 48, 48000 } + }; + /// /// Converts source values to a value for the binding target. The data binding engine calls this method when it propagates the values from source bindings to the binding target. /// @@ -43,58 +59,46 @@ namespace HandBrakeWPF.Converters.Audio public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { // Base set of bitrates available. - List bitrates = new List { 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 448, 640, 768 }; + List bitrates = new List { 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 448, 640, 768, 960, 1152, 1344, 1536 }; int max = 160; + int low = 32; AudioTrack track = value as AudioTrack; if (track != null) { - int channels = this.GetChannelCount(track.MixDown); + int samplerate = this.GetBestSampleRate(track); + int srShift = this.GetSamplerateShift(samplerate); + int lfeCount = this.GetLowFreqChannelCount(track.MixDown); + int channels = this.GetChannelCount(track.MixDown) - lfeCount; - double samplerate = 48; // Default - - if (!track.SampleRate.Equals(0.0d)) - { - samplerate = track.SampleRate; - } - else if (track.ScannedTrack != null && track.ScannedTrack.SampleRate != 0) - { - samplerate = track.ScannedTrack.SampleRate / 1000d; - } - switch (track.Encoder) { case AudioEncoder.Faac: + low = (channels + lfeCount) * 32; + max = (channels + lfeCount) * (192 >> srShift); + break; case AudioEncoder.ffaac: - if (samplerate > 24) - { - max = 160 * channels; - if (max > 768) - { - max = 768; - } - } - else - { - max = 96 * channels; - if (max > 480) - { - max = 480; - } - } + low = ((channels + lfeCount) * 32); + max = ((channels + lfeCount) * + ((192 + (64 * ((samplerate << srShift) >= 44100 ? 1 : 0))) + >> srShift)); break; case AudioEncoder.Lame: - max = samplerate > 24 ? 320 : 160; + low = 8 + (24 * (srShift < 1 ? 1 : 0) ); + max = 64 + (96 * (srShift < 2 ? 1 : 0)) + (160 * (srShift < 1 ? 1 : 0)); break; case AudioEncoder.Vorbis: - max = samplerate > 24 - ? (channels > 2 - ? 128 * channels - : (track.SampleRate > 32 ? 224 * channels : 160 * channels)) - : 80 * this.GetChannelCount(track.MixDown); + low = (channels + lfeCount) * (14 + + (8 * (srShift < 2 ? 1 : 0)) + + (6 * (srShift < 1 ? 1 : 0))); + max = (channels + lfeCount) * (32 + + (54 * (srShift < 2 ? 1 : 0)) + + (104 * (srShift < 1 ? 1 : 0)) + + (50 * (samplerate >= 44100 ? 1 : 0))); break; case AudioEncoder.Ac3: + low = 224 * channels / 5; max = samplerate > 24 ? 640 : 320; break; case AudioEncoder.Ac3Passthrough: @@ -104,7 +108,7 @@ namespace HandBrakeWPF.Converters.Audio case AudioEncoder.Mp3Passthru: case AudioEncoder.Passthrough: case AudioEncoder.ffflac: - max = 768; // Since we don't care, just set it to the max. + max = 1536; // Since we don't care, just set it to the max. break; default: max = 768; @@ -112,13 +116,18 @@ namespace HandBrakeWPF.Converters.Audio } // Bring the bitrate down in-line with the max. + if (track.Bitrate < low) + { + track.Bitrate = low; + } + if (track.Bitrate > max) { track.Bitrate = max; } } - return bitrates.Where(bitrate => bitrate <= max); + return bitrates.Where(bitrate => bitrate <= max && bitrate >= low); } /// @@ -152,7 +161,124 @@ namespace HandBrakeWPF.Converters.Audio } } + /// + /// The get low freq channel count. + /// + /// + /// The mixdown. + /// + /// + /// The System.Int32. + /// + private int GetLowFreqChannelCount(Mixdown mixdown) + { + switch (mixdown) + { + case Mixdown.FivePoint1Channels: + case Mixdown.SixPoint1Channels: + case Mixdown.SevenPoint1Channels: + case Mixdown.Five_2_LFE: + return 1; + default: + return 0; + } + } + + /// + /// The get samplerate shift. + /// + /// + /// The samplerate. + /// + /// + /// The System.Int32. + /// + private int GetSamplerateShift(int samplerate) + { + /* sr_shift: 0 -> 48000, 44100, 32000 Hz + * 1 -> 24000, 22050, 16000 Hz + * 2 -> 12000, 11025, 8000 Hz + * + * also, since samplerates are sanitized downwards: + * + * (samplerate < 32000) implies (samplerate <= 24000) + */ + return ((samplerate < 16000) ? 2 : (samplerate < 32000) ? 1 : 0); + } + + /// + /// The get best sample rate. + /// + /// + /// The track. + /// + /// + /// The System.Double. + /// + private int GetBestSampleRate(AudioTrack track) + { + int samplerate = 48000; // Default to 48 + + // Try get the users selected sample rate + if (!track.SampleRate.Equals(0.0d)) + { + samplerate = this.samplerates[track.SampleRate]; + } + else if (track.ScannedTrack != null && track.ScannedTrack.SampleRate != 0) // If it's auto, try get the source + { + samplerate = track.ScannedTrack.SampleRate; + } + + // THen Sanitize to make sure it's valid + int bestSamplerate; + if ((samplerate < 32000) && (track.Encoder == AudioEncoder.Ac3)) + { + // AC-3 < 32 kHz suffers from poor hardware compatibility + bestSamplerate = 32000; + } + else + { + bestSamplerate = samplerate; + foreach (KeyValuePair item in this.samplerates) + { + // valid samplerate + if (bestSamplerate.Equals(item.Value)) + break; + // samplerate is higher than the next valid samplerate, + // or lower than the lowest valid samplerate + if (bestSamplerate > item.Value && bestSamplerate < this.samplerates.First().Value) + { + bestSamplerate = item.Value; + break; + } + } + } + + return bestSamplerate; + } + + /// + /// The convert back. + /// + /// + /// The value. + /// + /// + /// The target type. + /// + /// + /// The parameter. + /// + /// + /// The culture. + /// + /// + /// The System.Object. + /// + /// + /// We don't use this. + /// public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); -- cgit v1.2.3