Files
DP44/enriched-qwen3-coder-next/Common/DTS.Common/Classes/DSP.md

181 lines
12 KiB
Markdown
Raw Normal View History

2026-04-17 14:55:32 -04:00
---
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 DASs 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 DASs 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).