181 lines
12 KiB
Markdown
181 lines
12 KiB
Markdown
|
|
---
|
|||
|
|
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<int, int>[]`): 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<StreamingFilterProfile>
|
|||
|
|
```
|
|||
|
|
- **`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<DSPFilterType>
|
|||
|
|
```
|
|||
|
|
- **`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<T>`.
|
|||
|
|
|
|||
|
|
### 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).
|