--- source_files: - Common/DTS.Common/Classes/DSP/ScalerAttribute.cs - Common/DTS.Common/Classes/DSP/DASRestriction.cs - Common/DTS.Common/Classes/DSP/DSPFilterRestriction.cs - Common/DTS.Common/Classes/DSP/IStreamingFilterProfile.cs - Common/DTS.Common/Classes/DSP/StreamingFilterConverter.cs - Common/DTS.Common/Classes/DSP/DSPFilterConverter.cs - Common/DTS.Common/Classes/DSP/StreamingFilterProfile.cs - Common/DTS.Common/Classes/DSP/DSPFilterCollection.cs - Common/DTS.Common/Classes/DSP/StreamingFilterProfileCollection.cs - Common/DTS.Common/Classes/DSP/DSPFilterType.cs generated_at: "2026-04-16T03:17:48.073484+00:00" model: "Qwen/Qwen3-Coder-Next-FP8" schema_version: 1 sha256: "5b580a9c32ce9826" --- # DSP Module Documentation ## 1. Purpose This module provides data structures and utilities for configuring and managing digital signal processing (DSP) filters in the DTS system. It defines filter profiles (`StreamingFilterProfile`, `DSPFilterType`), their restrictions based on hardware type and protocol version (`DASRestriction`, `DSPFilterRestriction`), and collections (`StreamingFilterProfileCollection`, `DSPFilterCollection`) that load filter configurations from XML files. It also includes type converters (`StreamingFilterConverter`, `DSPFilterConverter`) for UI integration (e.g., property grids) and supports both legacy and ratio-based filter rate calculations. The module centralizes DSP filter metadata and logic, enabling consistent filter selection and configuration across the application. ## 2. Public Interface ### Classes - **`ScalerAttribute`** ```csharp [AttributeUsage(AttributeTargets.Enum | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Field, AllowMultiple = false)] public class ScalerAttribute : Attribute ``` - **`Scaler`** (`double`): Stores a scaling factor (e.g., for computing filter cutoff frequencies from sample rates). - **Constructor `ScalerAttribute(double d)`**: Initializes the `Scaler` property with the provided value. - **`DASRestriction`** ```csharp public class DASRestriction ``` - **`DASType`** (`string`): Hardware type string (e.g., `"SLICE6_AIR"`). An empty string means *all* DAS types match. - **`ProtocolVersion`** (`int`): Minimum required protocol version. Values ≤ 0 mean *all* protocol versions match. - **Constructors**: - `DASRestriction()`: Sets `DASType = ""`, `ProtocolVersion = -1`. - `DASRestriction(string dasType, int protocolVersion)`: Initializes with specified values. - **`DSPFilterRestriction`** ```csharp public class DSPFilterRestriction ``` Identical structure and behavior to `DASRestriction` (same properties and constructors). *Note: No functional difference is evident in the source; likely a duplicate or legacy artifact.* - **`StreamingFilterProfile`** ```csharp public class StreamingFilterProfile : IStreamingFilterProfile ``` - **`Ratio`** (`double`): Scaling factor for computing filter cutoff frequency from sample rate (`fc = sps / Ratio`). `double.NaN` indicates no ratio-based calculation. - **`DisplayString`** (`string`), **`DescriptionString`** (`string`), **`EnumValue`** (`int`): Metadata for UI and firmware communication. - **`Restrictions`** (`DASRestriction[]`): Array of hardware/protocol restrictions. - **Constructors**: - `StreamingFilterProfile()`: Default. - `StreamingFilterProfile(StreamingFilterProfileCollection.DefaultProfiles profile, DASRestriction[] restrictions)`: Initializes from a `DefaultProfiles` enum value and restrictions. - `StreamingFilterProfile(string display, string description, int enumValue, double ratio, DASRestriction[] restrictions)`: Direct initialization. - **`GetDSPFilterRate(double sps, string hwType)`** (`double`): Returns the filter cutoff frequency (fc) for given sample rate (`sps`) and hardware type (`hwType`). Returns `double.NaN` if filtering is unsupported or restrictions not met. - For `SLICE6_AIR` with `sps ≥ 20480`, returns `double.NaN`. - For other cases, uses `DSPFilterType.Get6PButterWorthLegacyTable()` and `Ratio` to compute `fc = sps / Ratio` if `Ratio` is valid. - **`ToString()`**: Returns `DisplayString`. - **`DSPFilterType`** ```csharp public class DSPFilterType : IStreamingFilterProfile ``` - **`Ratio`**, **`EnumValue`**, **`DisplayString`**, **`DescriptionString`**, **`Restrictions`**: Same semantics as `StreamingFilterProfile`. - **Constructors**: - `DSPFilterType()`: Default. - `DSPFilterType(DSPFilterCollection.DSPFilterDefaults filter, DASRestriction[] restrictions)`: Initializes from `DSPFilterDefaults` enum value. - `DSPFilterType(int enumValue, string displayString, string descriptionString, double ratio, DASRestriction[] restrictions)`: Direct initialization. - **`GetDSPFilterRate(double sps, string hwType)`** (`double`): Returns `fc` for the legacy 6-pole Butterworth filter (`EnumValue == 13`). Returns `double.NaN` if `EnumValue ≠ 13`, restrictions not met, or hardware unsupported. - **Static Methods**: - **`Get6PButterWorthLegacyTable()`** (`Tuple[]`): Returns the breakpoint table: `[(8000,1280), (5000,610), (2000,366), (1000,120), (500,120), (200,50), (80,15)]`. - **`GetLegacytDSPFilterRate(double sps, string hwType)`** (`double`): Returns `fc` for legacy Butterworth filter using the breakpoint table. Returns `double.NaN` for `SLICE6_AIR` with `sps ≥ 20480`. - **Constants**: - **`S6A_CAP`** (`int = 20480`): Sample rate threshold above which `SLICE6_AIR` falls back to analog filtering. - **`StreamingFilterProfileCollection`** ```csharp public class StreamingFilterProfileCollection : Collection ``` - **`GetCollection()`** (`static`): Singleton accessor. Loads from `"StreamingFilterProfiles.xml"` (creates default file if missing). - **`GetStreamingFilterProfile(string s)`** (`StreamingFilterProfile`): Returns the profile with matching `DisplayString`, or the default (`EnumValue == 13`), or the first item. - **`DefaultProfiles`** enum: Defines profiles with `ScalerAttribute` for `Ratio`: - `Default` (`13`): `Ratio = NaN` (legacy). - `Profile7` (`7`): `Ratio = 4`. - `Profile8` (`8`): `Ratio = 6.4`. - `Profile9` (`9`): `Ratio = 8`. - `Profile10` (`10`): `Ratio = 10`. - **`DEFAULT_VALUE`** (`int = 13`): Enum value for the default profile. - **`DSPFilterCollection`** ```csharp public class DSPFilterCollection : Collection ``` - **`GetDSPFilterCollection()`** (`static`): Singleton accessor. Loads from `"DSPFilters.xml"` (creates default file if missing). - **`GetFilter(string s)`** (`DSPFilterType`): Returns filter with matching `DisplayString`, or `EnumValue == 0` (None), or first item. - **`DSPFilterDefaults`** enum: Defines filter types with `ScalerAttribute` (`Ratio = NaN` for all): - `None` (`0`). - `Butterworth` (`13`). - `FIR` (`14`). - **Constants**: - **`BUTTERWORTH`** (`int = 13`), **`FIR45TAP`** (`int = 14`), **`NONE`** (`int = 0`). ### Converters - **`StreamingFilterConverter`** ```csharp public class StreamingFilterConverter : ArrayConverter ``` - **`Values`** (`StreamingFilterProfile[]`): Cached array of profiles from `StreamingFilterProfileCollection`. - **`CanConvertFrom`**, **`ConvertFrom`**: Supports conversion from `string` (matches `DisplayString`). - **`GetStandardValuesSupported`**, **`GetStandardValuesExclusive`**, **`GetStandardValues`**: Provides standard values (entire collection) for property grids. - **`DSPFilterConverter`** ```csharp public class DSPFilterConverter : ArrayConverter ``` - **`Values`** (`DSPFilterType[]`): Cached array of filters from `DSPFilterCollection`. - **`CanConvertFrom`**, **`ConvertFrom`**: Supports conversion from `string` (matches `DisplayString`). - **`GetStandardValuesSupported`**, **`GetStandardValuesExclusive`**, **`GetStandardValues`**: Provides standard values (entire collection) for property grids. ### Interfaces - **`IStreamingFilterProfile`** ```csharp public interface IStreamingFilterProfile ``` Defines contract for filter profiles: - **`EnumValue`** (`int`), **`DisplayString`** (`string`), **`DescriptionString`** (`string`), **`Restrictions`** (`DASRestriction[]`), **`Ratio`** (`double`). - **`GetDSPFilterRate(double sps, string hwType)`** (`double`): Compute filter cutoff frequency. ## 3. Invariants - **Singleton Collections**: `StreamingFilterProfileCollection.GetCollection()` and `DSPFilterCollection.GetDSPFilterCollection()` are thread-safe singletons (using `lock` and lazy initialization). The XML files (`StreamingFilterProfiles.xml`, `DSPFilters.xml`) are created with defaults if missing. - **Restriction Matching**: A restriction matches if `DASType` is empty (any hardware) or equals `hwType`, and `ProtocolVersion ≤ 0` (any version) or `ProtocolVersion` matches the DAS’s version (exact match implied, though version comparison logic is not in this module). - **Filter Rate Calculation**: - `StreamingFilterProfile.GetDSPFilterRate` uses `Ratio` for ratio-based filters (`Ratio > 0`) and falls back to legacy table lookup (`DSPFilterType.GetLegacytDSPFilterRate`) only if `EnumValue == DEFAULT_VALUE` (13) and `Ratio = NaN`. - `DSPFilterType.GetDSPFilterRate` only supports the Butterworth filter (`EnumValue == 13`). - `SLICE6_AIR` with `sps ≥ 20480` is unsupported for digital filtering (returns `double.NaN`). - **Enum Values**: `DEFAULT_VALUE = 13` (for `StreamingFilterProfileCollection.DefaultProfiles.Default`) and `BUTTERWORTH = 13` (for `DSPFilterCollection.DSPFilterDefaults.Butterworth`) are hardcoded constants. ## 4. Dependencies ### Internal Dependencies - **`DTS.Common.Enums.Hardware`**: Used for `HardwareTypes` (e.g., `SLICE6_AIR`, `SLICE6_AIR_BR`, `SLICE6_AIR_TC`). - **`System.ComponentModel.DataAnnotations`**: Used for `DisplayAttribute` (to extract `Name`/`Description` from enum fields). - **`System.Xml.Serialization`**: Used for XML serialization/deserialization of collections. - **`System.Collections.ObjectModel`**: Base for `Collection`. ### External Dependencies - **XML Files**: - `StreamingFilterProfiles.xml`: Default location for streaming filter profiles. - `DSPFilters.xml`: Default location for DSP filter types. *(Both are created on first access if missing.)* - **UI Frameworks**: `StreamingFilterConverter` and `DSPFilterConverter` depend on `System.ComponentModel` (e.g., `ITypeDescriptorContext`, `StandardValuesCollection`) for property grid integration. ### Inferred Usage - `StreamingFilterProfileCollection` and `DSPFilterCollection` are used by converters and likely by UI components (e.g., dropdowns for filter selection). - `ScalerAttribute` is applied to enums in `StreamingFilterProfileCollection.DefaultProfiles` and `DSPFilterCollection.DSPFilterDefaults` to store scaling factors. ## 5. Gotchas - **Duplicate Classes**: `DASRestriction` and `DSPFilterRestriction` are identical in structure and behavior. The codebase does not clarify if they serve distinct purposes or are redundant. - **`Ratio = NaN` Semantics**: In `StreamingFilterProfile`, `Ratio = NaN` triggers legacy filter rate calculation (via `DSPFilterType.GetLegacytDSPFilterRate`), but only if `EnumValue == DEFAULT_VALUE` (13). This is not obvious from the method name or documentation. - **`GetDSPFilterRate` Inconsistency**: - `StreamingFilterProfile.GetDSPFilterRate` uses `Ratio` for ratio-based filters. - `DSPFilterType.GetDSPFilterRate` *only* supports Butterworth (`EnumValue == 13`) and ignores `Ratio`. This implies `StreamingFilterProfile` is for flexible profiles, while `DSPFilterType` is for legacy filter types. - **Hardware-Specific Logic**: `SLICE6_AIR` has a special case (`sps ≥ 20480` → `double.NaN`) in both `StreamingFilterProfile` and `DSPFilterType`. This is hardcoded and not configurable via XML. - **Protocol Version Matching**: `ProtocolVersion` is stored but never compared against a DAS’s actual version in the provided code. Matching logic is assumed but not implemented here. - **Case Sensitivity**: `GetFilter`/`GetStreamingFilterProfile` use `DisplayString == s` (case-sensitive). UI components may need to handle case normalization. - **Thread Safety**: Singletons use `lock` for initialization, but cached arrays (`Values` in converters) are not reloaded if XML files change at runtime. - **Typo**: Method `GetLegacytDSPFilterRate` (missing 'h' in "Legacy") and `S6A_CAP` (capitalization inconsistency with `SLICE6_AIR` enum values).