init
This commit is contained in:
31
Common/DTS.Common/Classes/DSP/DASRestriction.cs
Normal file
31
Common/DTS.Common/Classes/DSP/DASRestriction.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
namespace DTS.Common.Classes.DSP
|
||||
{
|
||||
/// <summary>
|
||||
/// this is a restriction on who can use this filter
|
||||
/// </summary>
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Minor Code Smell", "S101:Types should be named in PascalCase", Justification = "Acronym")]
|
||||
public class DASRestriction
|
||||
{
|
||||
/// <summary>
|
||||
/// the Hardware_Type string value for the das (e.g. SLICE6_AIR, etc)
|
||||
/// empty string means all das
|
||||
/// </summary>
|
||||
public string DASType { get; set; }
|
||||
/// <summary>
|
||||
/// the protocol version for that das (<=0 means all protocol versions will work)
|
||||
/// </summary>
|
||||
public int ProtocolVersion { get; set; }
|
||||
|
||||
public DASRestriction()
|
||||
{
|
||||
DASType = string.Empty;
|
||||
ProtocolVersion = -1;
|
||||
}
|
||||
|
||||
public DASRestriction(string dasType, int protocolVersion)
|
||||
{
|
||||
DASType = dasType;
|
||||
ProtocolVersion = protocolVersion;
|
||||
}
|
||||
}
|
||||
}
|
||||
115
Common/DTS.Common/Classes/DSP/DSPFilterCollection.cs
Normal file
115
Common/DTS.Common/Classes/DSP/DSPFilterCollection.cs
Normal file
@@ -0,0 +1,115 @@
|
||||
using DTS.Common.Enums.Hardware;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace DTS.Common.Classes.DSP
|
||||
{
|
||||
/// <summary>
|
||||
/// collection for all dsp filters
|
||||
/// </summary>
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Minor Code Smell", "S101:Types should be named in PascalCase", Justification = "Acronym")]
|
||||
public class DSPFilterCollection : Collection<DSPFilterType>
|
||||
{
|
||||
private static readonly object MyLock = new object();
|
||||
private static DSPFilterCollection _instance = null;
|
||||
public static DSPFilterCollection GetDSPFilterCollection()
|
||||
{
|
||||
lock (MyLock)
|
||||
{
|
||||
if (null != _instance) { return _instance; }
|
||||
WriteDefaultFileIfMissing(DSP_FILTER_XML_FILE);
|
||||
_instance = ReadFile(DSP_FILTER_XML_FILE);
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
private const string DSP_FILTER_XML_FILE = "DSPFilters.xml";
|
||||
|
||||
private DSPFilterCollection(DSPFilterType[] filters)
|
||||
{
|
||||
foreach (var filter in filters) { Add(filter); }
|
||||
}
|
||||
public DSPFilterCollection() { }
|
||||
|
||||
public const int BUTTERWORTH = 13;
|
||||
public const int FIR45TAP = 14;
|
||||
public const int NONE = 0;
|
||||
|
||||
public enum DSPFilterDefaults
|
||||
{
|
||||
[Display(Name ="None", Description = "Default and legacy setting for streaming")]
|
||||
[Scaler(double.NaN)]
|
||||
None = NONE,
|
||||
[Display(Name = "6th IIR Butterworth", Description = "6 - pole IIR Butterworth Low Pass")]
|
||||
[Scaler(double.NaN)]
|
||||
Butterworth = BUTTERWORTH,
|
||||
[Display(Name = "45-Tap FIR", Description = "finite impulse response filter with 45 taps")]
|
||||
[Scaler(double.NaN)]
|
||||
FIR = FIR45TAP
|
||||
}
|
||||
|
||||
private static DSPFilterCollection CreateDefaultCollection()
|
||||
{
|
||||
var list = new List<DSPFilterType>
|
||||
{
|
||||
new DSPFilterType(DSPFilterDefaults.None, new DASRestriction[] { new DASRestriction() }),
|
||||
new DSPFilterType(DSPFilterDefaults.Butterworth, new DASRestriction[]
|
||||
{
|
||||
new DASRestriction(HardwareTypes.SLICE6_AIR.ToString(), 28),
|
||||
new DASRestriction(HardwareTypes.SLICE6_AIR_BR.ToString(), -1),
|
||||
new DASRestriction(HardwareTypes.SLICE6_AIR_TC.ToString(), -1)
|
||||
}),
|
||||
new DSPFilterType(DSPFilterDefaults.FIR, new DASRestriction[]
|
||||
{
|
||||
new DASRestriction(HardwareTypes.SLICE6_AIR.ToString(), 28),
|
||||
new DASRestriction(HardwareTypes.SLICE6_AIR_BR.ToString(), -1),
|
||||
new DASRestriction(HardwareTypes.SLICE6_AIR_TC.ToString(), -1)
|
||||
})
|
||||
};
|
||||
|
||||
var collection = new DSPFilterCollection(list.ToArray());
|
||||
return collection;
|
||||
}
|
||||
|
||||
private static void WriteDefaultFileIfMissing(string filePath)
|
||||
{
|
||||
if (File.Exists(filePath)) { return; }
|
||||
var collection = CreateDefaultCollection();
|
||||
|
||||
var serializer = new XmlSerializer(typeof(DSPFilterCollection));
|
||||
var settings = new XmlWriterSettings() { Indent = true };
|
||||
|
||||
using (var writer = XmlWriter.Create(filePath, settings))
|
||||
{
|
||||
serializer.Serialize(writer, collection);
|
||||
}
|
||||
}
|
||||
|
||||
private static DSPFilterCollection ReadFile(string filePath)
|
||||
{
|
||||
var deserializer = new XmlSerializer(typeof(DSPFilterCollection));
|
||||
using (var fs = new FileStream(filePath, FileMode.Open))
|
||||
{
|
||||
var cs = (DSPFilterCollection)deserializer.Deserialize(fs);
|
||||
return cs;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// returns the matching filter, or None if not found, or if none isn't found then the first entry
|
||||
/// </summary>
|
||||
/// <param name="s"></param>
|
||||
/// <returns></returns>
|
||||
public DSPFilterType GetFilter(string s)
|
||||
{
|
||||
var match = Items.FirstOrDefault(x => x.DisplayString == s);
|
||||
if (null != match) { return match; }
|
||||
match = Items.FirstOrDefault(x => x.EnumValue == 0);
|
||||
if (null != match) { return match; }
|
||||
return Items[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
70
Common/DTS.Common/Classes/DSP/DSPFilterConverter.cs
Normal file
70
Common/DTS.Common/Classes/DSP/DSPFilterConverter.cs
Normal file
@@ -0,0 +1,70 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
|
||||
namespace DTS.Common.Classes.DSP
|
||||
{
|
||||
/// <summary>
|
||||
/// this converter is used to display DSPFilterCollection in a property grid
|
||||
/// </summary>
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Minor Code Smell", "S101:Types should be named in PascalCase", Justification = "Acronym")]
|
||||
public class DSPFilterConverter : ArrayConverter
|
||||
{
|
||||
private DSPFilterCollection _collection = null;
|
||||
private static readonly object MyLock = new object();
|
||||
private DSPFilterType[] _values = null;
|
||||
private DSPFilterCollection GetCollection()
|
||||
{
|
||||
lock (MyLock)
|
||||
{
|
||||
if (null == _collection)
|
||||
{
|
||||
_collection = DSPFilterCollection.GetDSPFilterCollection();
|
||||
}
|
||||
return _collection;
|
||||
}
|
||||
}
|
||||
public DSPFilterType [] Values
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (MyLock)
|
||||
{
|
||||
if (null == _values)
|
||||
{
|
||||
var collection = GetCollection();
|
||||
|
||||
var array = new DSPFilterType[collection.Count];
|
||||
collection.CopyTo(array, 0);
|
||||
_values = array;
|
||||
}
|
||||
}
|
||||
return _values;
|
||||
}
|
||||
}
|
||||
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
|
||||
{
|
||||
if (sourceType == typeof(string)) { return true; }
|
||||
return base.CanConvertFrom(context, sourceType);
|
||||
}
|
||||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
||||
{
|
||||
var result = Array.Find(Values, x => x.DisplayString == (string)value);
|
||||
if (result != null) { return result; }
|
||||
return base.ConvertFrom(context, culture, value);
|
||||
}
|
||||
public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
|
||||
{
|
||||
var collection = GetCollection();
|
||||
return new StandardValuesCollection(collection);
|
||||
}
|
||||
}
|
||||
}
|
||||
31
Common/DTS.Common/Classes/DSP/DSPFilterRestriction.cs
Normal file
31
Common/DTS.Common/Classes/DSP/DSPFilterRestriction.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
namespace DTS.Common.Classes.DSP
|
||||
{
|
||||
/// <summary>
|
||||
/// this is a restriction on who can use this filter
|
||||
/// </summary>
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Minor Code Smell", "S101:Types should be named in PascalCase", Justification = "Acronym")]
|
||||
public class DSPFilterRestriction
|
||||
{
|
||||
/// <summary>
|
||||
/// the Hardware_Type string value for the das (e.g. SLICE6_AIR, etc)
|
||||
/// empty string means all das
|
||||
/// </summary>
|
||||
public string DASType { get; set; }
|
||||
/// <summary>
|
||||
/// the protocol version for that das (<=0 means all protocol versions will work)
|
||||
/// </summary>
|
||||
public int ProtocolVersion { get; set; }
|
||||
|
||||
public DSPFilterRestriction()
|
||||
{
|
||||
DASType = string.Empty;
|
||||
ProtocolVersion = -1;
|
||||
}
|
||||
|
||||
public DSPFilterRestriction(string dasType, int protocolVersion)
|
||||
{
|
||||
DASType = dasType;
|
||||
ProtocolVersion = protocolVersion;
|
||||
}
|
||||
}
|
||||
}
|
||||
121
Common/DTS.Common/Classes/DSP/DSPFilterType.cs
Normal file
121
Common/DTS.Common/Classes/DSP/DSPFilterType.cs
Normal file
@@ -0,0 +1,121 @@
|
||||
using DTS.Common.Enums.Hardware;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace DTS.Common.Classes.DSP
|
||||
{
|
||||
/// <summary>
|
||||
/// see IStreamingFilterProfile for more information
|
||||
/// </summary>
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Minor Code Smell", "S101:Types should be named in PascalCase", Justification = "Acronym")]
|
||||
public class DSPFilterType : IStreamingFilterProfile
|
||||
{
|
||||
public double Ratio { get; set; }
|
||||
public int EnumValue { get; set; }
|
||||
public string DisplayString { get; set; }
|
||||
public string DescriptionString { get; set; }
|
||||
private readonly List<DASRestriction> _restrictions = new List<DASRestriction>();
|
||||
public DASRestriction[] Restrictions { get => _restrictions.ToArray(); set { _restrictions.Clear(); _restrictions.AddRange(value); } }
|
||||
|
||||
public DSPFilterType() { }
|
||||
public DSPFilterType(DSPFilterCollection.DSPFilterDefaults filter, DASRestriction[] restrictions)
|
||||
{
|
||||
GetProfileValues(filter, out var displayName, out var description, out var enumValue, out var ratio);
|
||||
Initialize(enumValue, displayName, description, ratio, restrictions);
|
||||
}
|
||||
public DSPFilterType(int enumValue, string displayString, string descriptionString, double ratio, DASRestriction[] restrictions)
|
||||
{
|
||||
Initialize(enumValue, displayString, descriptionString, ratio, restrictions);
|
||||
}
|
||||
private void Initialize(int enumValue, string displayString, string descriptionString, double ratio, DASRestriction[] restrictions)
|
||||
{
|
||||
EnumValue = enumValue;
|
||||
DisplayString = displayString;
|
||||
DescriptionString = descriptionString;
|
||||
Restrictions = restrictions;
|
||||
Ratio = ratio;
|
||||
}
|
||||
public override string ToString()
|
||||
{
|
||||
return DisplayString;
|
||||
}
|
||||
public static void GetProfileValues(DSPFilterCollection.DSPFilterDefaults filter, out string displayName, out string description, out int enumValue,
|
||||
out double ratio)
|
||||
{
|
||||
displayName = string.Empty;
|
||||
description = string.Empty;
|
||||
enumValue = -1;
|
||||
ratio = -1;
|
||||
|
||||
var enumType = typeof(DSPFilterCollection.DSPFilterDefaults);
|
||||
var memberInfos = enumType.GetMember(filter.ToString());
|
||||
var enumValueMemberInfo = Array.Find(memberInfos, m => m.DeclaringType == enumType);
|
||||
var valueAttributes = enumValueMemberInfo.GetCustomAttributes(typeof(DisplayAttribute), false);
|
||||
|
||||
enumValue = (int)filter;
|
||||
description = ((DisplayAttribute)valueAttributes[0]).GetDescription();
|
||||
displayName = ((DisplayAttribute)valueAttributes[0]).GetName();
|
||||
|
||||
valueAttributes = enumValueMemberInfo.GetCustomAttributes(typeof(ScalerAttribute), false);
|
||||
ratio = ((ScalerAttribute)valueAttributes[0]).Scaler;
|
||||
}
|
||||
/// <summary>
|
||||
/// this is the table of breakpoints and corresponding fC for S6A/br
|
||||
/// </summary>
|
||||
private static readonly List<Tuple<int, int>> _6PButterWorthTable = new List<Tuple<int, int>>
|
||||
(
|
||||
new[]
|
||||
{
|
||||
new Tuple<int,int>(8000, 1280),
|
||||
new Tuple<int,int>(5000, 610),
|
||||
new Tuple<int,int>(2000, 366),
|
||||
new Tuple<int,int>(1000, 120),
|
||||
new Tuple<int,int>(500,120),
|
||||
new Tuple<int,int>(200,50),
|
||||
new Tuple<int,int>(80,15)
|
||||
}
|
||||
);
|
||||
/// <summary>
|
||||
/// returns an array of breakpoints and fC for S6A and S6A-BR legacy butterworth digital filter
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static Tuple<int, int>[] Get6PButterWorthLegacyTable() { return _6PButterWorthTable.ToArray(); }
|
||||
/// <summary>
|
||||
/// this is the cap of SPS where S6A will fall back on AAF
|
||||
/// </summary>
|
||||
public const int S6A_CAP = 20480;
|
||||
/// <summary>
|
||||
/// returns the fC given a hardware type, and the legacy 6P butterworth filter
|
||||
/// double.NaN means the filter is not supported
|
||||
/// </summary>
|
||||
/// <param name="sps"></param>
|
||||
/// <param name="hwType"></param>
|
||||
/// <returns></returns>
|
||||
public static double GetLegacytDSPFilterRate(double sps, string hwType)
|
||||
{
|
||||
//if we have legacy then we need the sample rate, if it's >8k s6abr then Fc
|
||||
if (hwType == HardwareTypes.SLICE6_AIR.ToString() && sps >= S6A_CAP) { return double.NaN; }
|
||||
|
||||
var array = Get6PButterWorthLegacyTable();
|
||||
Array.Sort(array, (x, y) => { return y.Item1.CompareTo(x.Item1); });
|
||||
foreach (var entry in array)
|
||||
{
|
||||
if (sps >= entry.Item1) { return entry.Item2; }
|
||||
}
|
||||
return double.NaN;
|
||||
}
|
||||
/// <summary>
|
||||
/// returns a filter rate given the current digital filter profile and sps and hardware type
|
||||
/// </summary>
|
||||
/// <param name="sps"></param>
|
||||
/// <param name="hwType"></param>
|
||||
/// <returns></returns>
|
||||
public double GetDSPFilterRate(double sps, string hwType)
|
||||
{
|
||||
if (EnumValue != DSPFilterCollection.BUTTERWORTH) { return double.NaN; }
|
||||
if (!Array.Exists(Restrictions, x => x.DASType == hwType || string.IsNullOrEmpty(x.DASType))) { return double.NaN; }
|
||||
return GetLegacytDSPFilterRate(sps, hwType);
|
||||
}
|
||||
}
|
||||
}
|
||||
34
Common/DTS.Common/Classes/DSP/IStreamingFilterProfile.cs
Normal file
34
Common/DTS.Common/Classes/DSP/IStreamingFilterProfile.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
namespace DTS.Common.Classes.DSP
|
||||
{
|
||||
public interface IStreamingFilterProfile
|
||||
{
|
||||
/// <summary>
|
||||
/// the byte/enum value to send to the firmware for this filter type
|
||||
/// </summary>
|
||||
int EnumValue { get; set; }
|
||||
/// <summary>
|
||||
/// the display string for this filter
|
||||
/// </summary>
|
||||
string DisplayString { get; set; }
|
||||
/// <summary>
|
||||
/// description string for this filter
|
||||
/// </summary>
|
||||
string DescriptionString { get; set; }
|
||||
/// <summary>
|
||||
/// any restrictions on what das can use this filter
|
||||
/// </summary>
|
||||
DASRestriction[] Restrictions { get; set; }
|
||||
/// <summary>
|
||||
/// if this profile uses a ratio, then the ratio of sps to fC
|
||||
/// </summary>
|
||||
double Ratio { get; set; }
|
||||
/// <summary>
|
||||
/// returns the fC given the hardware type and the sample rate
|
||||
/// returns null if digital filtering isn't used in this combination
|
||||
/// </summary>
|
||||
/// <param name="sps"></param>
|
||||
/// <param name="hwType"></param>
|
||||
/// <returns></returns>
|
||||
double GetDSPFilterRate(double sps, string hwType);
|
||||
}
|
||||
}
|
||||
18
Common/DTS.Common/Classes/DSP/ScalerAttribute.cs
Normal file
18
Common/DTS.Common/Classes/DSP/ScalerAttribute.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
|
||||
namespace DTS.Common.Classes.DSP
|
||||
{
|
||||
/// <summary>
|
||||
/// generic attribute to store doubles, so for say scalers or ratios
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Enum | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Field, AllowMultiple = false)]
|
||||
public class ScalerAttribute : Attribute
|
||||
{
|
||||
public double Scaler { get; set; }
|
||||
|
||||
public ScalerAttribute(double d)
|
||||
{
|
||||
Scaler = d;
|
||||
}
|
||||
}
|
||||
}
|
||||
70
Common/DTS.Common/Classes/DSP/StreamingFilterConverter.cs
Normal file
70
Common/DTS.Common/Classes/DSP/StreamingFilterConverter.cs
Normal file
@@ -0,0 +1,70 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
|
||||
namespace DTS.Common.Classes.DSP
|
||||
{
|
||||
/// <summary>
|
||||
/// this converter is used for displaying StreamingFilterCollection/array in property grids
|
||||
/// </summary>
|
||||
public class StreamingFilterConverter : ArrayConverter
|
||||
{
|
||||
private StreamingFilterProfileCollection _collection = null;
|
||||
private static readonly object MyLock = new object();
|
||||
private StreamingFilterProfile[] _values = null;
|
||||
private StreamingFilterProfileCollection GetCollection()
|
||||
{
|
||||
lock (MyLock)
|
||||
{
|
||||
if (null == _collection)
|
||||
{
|
||||
_collection = StreamingFilterProfileCollection.GetCollection();
|
||||
}
|
||||
return _collection;
|
||||
}
|
||||
}
|
||||
public StreamingFilterProfile[] Values
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (MyLock)
|
||||
{
|
||||
if (null == _values)
|
||||
{
|
||||
var collection = GetCollection();
|
||||
|
||||
var array = new StreamingFilterProfile[collection.Count];
|
||||
collection.CopyTo(array, 0);
|
||||
_values = array;
|
||||
}
|
||||
}
|
||||
return _values;
|
||||
}
|
||||
}
|
||||
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
|
||||
{
|
||||
if (sourceType == typeof(string)) { return true; }
|
||||
return base.CanConvertFrom(context, sourceType);
|
||||
}
|
||||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
||||
{
|
||||
var result = Array.Find(Values, x => x.DisplayString == (string)value);
|
||||
if (result != null) { return result; }
|
||||
return base.ConvertFrom(context, culture, value);
|
||||
}
|
||||
|
||||
public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
|
||||
{
|
||||
var collection = GetCollection();
|
||||
return new StandardValuesCollection(collection);
|
||||
}
|
||||
}
|
||||
}
|
||||
82
Common/DTS.Common/Classes/DSP/StreamingFilterProfile.cs
Normal file
82
Common/DTS.Common/Classes/DSP/StreamingFilterProfile.cs
Normal file
@@ -0,0 +1,82 @@
|
||||
using DTS.Common.Enums.Hardware;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace DTS.Common.Classes.DSP
|
||||
{
|
||||
public class StreamingFilterProfile : IStreamingFilterProfile
|
||||
{
|
||||
public double Ratio { get; set; }
|
||||
public string DisplayString { get; set; }
|
||||
public string DescriptionString { get; set; }
|
||||
public int EnumValue { get; set; }
|
||||
private readonly List<DASRestriction> _restrictions = new List<DASRestriction>();
|
||||
public DASRestriction[] Restrictions { get => _restrictions.ToArray(); set { _restrictions.Clear(); _restrictions.AddRange(value); } }
|
||||
public StreamingFilterProfile() { }
|
||||
public StreamingFilterProfile(StreamingFilterProfileCollection.DefaultProfiles profile, DASRestriction[] restrictions)
|
||||
{
|
||||
GetProfileValues(profile, out var displayName, out var description, out var enumValue, out var ratio);
|
||||
Initialize(displayName, description, enumValue, ratio, restrictions);
|
||||
}
|
||||
public StreamingFilterProfile(string display, string description, int enumValue, double ratio, DASRestriction[] restrictions)
|
||||
{
|
||||
Initialize(display, description, enumValue, ratio, restrictions);
|
||||
}
|
||||
private void Initialize(string display, string description, int enumValue, double ratio, DASRestriction[] restrictions)
|
||||
{
|
||||
DisplayString = display;
|
||||
DescriptionString = description;
|
||||
EnumValue = enumValue;
|
||||
Restrictions = restrictions;
|
||||
Ratio = ratio;
|
||||
}
|
||||
public override string ToString()
|
||||
{
|
||||
return DisplayString;
|
||||
}
|
||||
public static void GetProfileValues(StreamingFilterProfileCollection.DefaultProfiles profile, out string displayName, out string description, out int enumValue,
|
||||
out double ratio)
|
||||
{
|
||||
displayName = string.Empty;
|
||||
description = string.Empty;
|
||||
enumValue = -1;
|
||||
ratio = -1;
|
||||
|
||||
var enumType = typeof(StreamingFilterProfileCollection.DefaultProfiles);
|
||||
var memberInfos = enumType.GetMember(profile.ToString());
|
||||
var enumValueMemberInfo = Array.Find(memberInfos, m => m.DeclaringType == enumType);
|
||||
var valueAttributes = enumValueMemberInfo.GetCustomAttributes(typeof(DisplayAttribute), false);
|
||||
|
||||
enumValue = (int)profile;
|
||||
description = ((DisplayAttribute)valueAttributes[0]).GetDescription();
|
||||
displayName = ((DisplayAttribute)valueAttributes[0]).GetName();
|
||||
|
||||
valueAttributes = enumValueMemberInfo.GetCustomAttributes(typeof(ScalerAttribute), false);
|
||||
ratio = ((ScalerAttribute)valueAttributes[0]).Scaler;
|
||||
}
|
||||
|
||||
public double GetDSPFilterRate(double sps, string hwType)
|
||||
{
|
||||
//if we have legacy then we need the sample rate, if it's >8k s6abr then Fc
|
||||
if (hwType == HardwareTypes.SLICE6_AIR.ToString() && sps >= DSPFilterType.S6A_CAP) { return double.NaN; }
|
||||
|
||||
if (!Array.Exists(Restrictions, x => x.DASType == hwType || string.IsNullOrEmpty(x.DASType))) { return double.NaN; }
|
||||
|
||||
if (EnumValue == StreamingFilterProfileCollection.DEFAULT_VALUE)
|
||||
{
|
||||
return DSPFilterType.GetLegacytDSPFilterRate(sps, hwType);
|
||||
}
|
||||
else if (double.IsNaN(Ratio)) { return double.NaN; }
|
||||
|
||||
|
||||
var array = DSPFilterType.Get6PButterWorthLegacyTable();
|
||||
Array.Sort(array, (x, y) => { return y.Item1.CompareTo(x.Item1); });
|
||||
foreach (var entry in array)
|
||||
{
|
||||
if (sps >= entry.Item1) { return sps / Ratio; }
|
||||
}
|
||||
return double.NaN;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
using DTS.Common.Enums.Hardware;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace DTS.Common.Classes.DSP
|
||||
{
|
||||
public class StreamingFilterProfileCollection : Collection<StreamingFilterProfile>
|
||||
{
|
||||
private static readonly object MyLock = new object();
|
||||
private static StreamingFilterProfileCollection _instance = null;
|
||||
public static StreamingFilterProfileCollection GetCollection()
|
||||
{
|
||||
lock (MyLock)
|
||||
{
|
||||
if (null != _instance) { return _instance; }
|
||||
WriteDefaultFileIfMissing(FILTER_PROFILES_XML_FILE);
|
||||
_instance = ReadFile(FILTER_PROFILES_XML_FILE);
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
private const string FILTER_PROFILES_XML_FILE = "StreamingFilterProfiles.xml";
|
||||
|
||||
private StreamingFilterProfileCollection(StreamingFilterProfile[] filters)
|
||||
{
|
||||
foreach (var filter in filters) { Add(filter); }
|
||||
}
|
||||
public StreamingFilterProfileCollection() { }
|
||||
|
||||
public enum DefaultProfiles
|
||||
{
|
||||
[Display(Name ="Default (Mixed)", Description = "6 pole butterworth legacy or default", Order = DEFAULT_VALUE)]
|
||||
[Scaler(double.NaN)]
|
||||
Default = DEFAULT_VALUE,
|
||||
|
||||
[Display(Name ="Sample rate / 4", Description = "based on sample rate")]
|
||||
[Scaler(4)]
|
||||
Profile7 = 7,
|
||||
|
||||
[Display(Name = "Sample rate / 6.4", Description = "based on sample rate")]
|
||||
[Scaler(6.4)]
|
||||
Profile8 = 8,
|
||||
|
||||
[Display(Name = "Sample rate / 8", Description = "based on sample rate")]
|
||||
[Scaler(8)]
|
||||
Profile9 = 9,
|
||||
|
||||
[Display(Name = "Sample rate / 10", Description = "based on sample rate")]
|
||||
[Scaler(10)]
|
||||
Profile10 = 10
|
||||
}
|
||||
|
||||
private static StreamingFilterProfileCollection CreateDefaultCollection()
|
||||
{
|
||||
var list = new List<StreamingFilterProfile>
|
||||
{
|
||||
new StreamingFilterProfile(DefaultProfiles.Default, new[] { new DASRestriction(string.Empty, -1) }),
|
||||
new StreamingFilterProfile(DefaultProfiles.Profile7, new[]
|
||||
{
|
||||
new DASRestriction(HardwareTypes.SLICE6_AIR_BR.ToString(), 50), new DASRestriction(HardwareTypes.SLICE6_AIR.ToString(), 51), new DASRestriction(HardwareTypes.SLICE6_AIR_TC.ToString(), 0)
|
||||
}),
|
||||
new StreamingFilterProfile(DefaultProfiles.Profile8, new[]
|
||||
{
|
||||
new DASRestriction(HardwareTypes.SLICE6_AIR_BR.ToString(), 50), new DASRestriction(HardwareTypes.SLICE6_AIR.ToString(), 51), new DASRestriction(HardwareTypes.SLICE6_AIR_TC.ToString(), 0)
|
||||
}),
|
||||
new StreamingFilterProfile(DefaultProfiles.Profile9, new[]
|
||||
{
|
||||
new DASRestriction(HardwareTypes.SLICE6_AIR_BR.ToString(), 50), new DASRestriction(HardwareTypes.SLICE6_AIR.ToString(), 51), new DASRestriction(HardwareTypes.SLICE6_AIR_TC.ToString(), 0)
|
||||
}),
|
||||
new StreamingFilterProfile(DefaultProfiles.Profile10, new[]
|
||||
{
|
||||
new DASRestriction(HardwareTypes.SLICE6_AIR_BR.ToString(), 50), new DASRestriction(HardwareTypes.SLICE6_AIR.ToString(), 51), new DASRestriction(HardwareTypes.SLICE6_AIR_TC.ToString(), 0)
|
||||
})
|
||||
};
|
||||
var collection = new StreamingFilterProfileCollection(list.ToArray());
|
||||
return collection;
|
||||
}
|
||||
|
||||
private static void WriteDefaultFileIfMissing(string filePath)
|
||||
{
|
||||
if (File.Exists(filePath)) { return; }
|
||||
var collection = CreateDefaultCollection();
|
||||
|
||||
var serializer = new XmlSerializer(typeof(StreamingFilterProfileCollection));
|
||||
var settings = new XmlWriterSettings() { Indent = true };
|
||||
|
||||
using (var writer = XmlWriter.Create(filePath, settings))
|
||||
{
|
||||
serializer.Serialize(writer, collection);
|
||||
}
|
||||
}
|
||||
|
||||
private static StreamingFilterProfileCollection ReadFile(string filePath)
|
||||
{
|
||||
var deserializer = new XmlSerializer(typeof(StreamingFilterProfileCollection));
|
||||
using (var fs = new FileStream(filePath, FileMode.Open))
|
||||
{
|
||||
var cs = (StreamingFilterProfileCollection)deserializer.Deserialize(fs);
|
||||
return cs;
|
||||
}
|
||||
}
|
||||
public const int DEFAULT_VALUE = 13;
|
||||
public StreamingFilterProfile GetStreamingFilterProfile(string s)
|
||||
{
|
||||
var match = Items.FirstOrDefault(x => x.DisplayString == s);
|
||||
if (null != match) { return match; }
|
||||
match = Items.FirstOrDefault(x => x.EnumValue == DEFAULT_VALUE);
|
||||
if (null != match) { return match; }
|
||||
return Items[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user