122 lines
5.6 KiB
Plaintext
122 lines
5.6 KiB
Plaintext
|
|
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);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|