Skip to content

Commit

Permalink
Change from showing amplitudes to showing coefficient length in frequ…
Browse files Browse the repository at this point in the history
…ency response and db scale (amplitude is for showing percentage of overall amplitude for a specific frequency to the whole signal). Added normalize option (on by default) for filter impulse response
  • Loading branch information
Brian Tabone committed Jan 5, 2020
1 parent a61ad11 commit ac399f4
Show file tree
Hide file tree
Showing 11 changed files with 68 additions and 34 deletions.
11 changes: 7 additions & 4 deletions SignalProcessor/Filters/WindowedSyncFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public WindowedSyncFilter()
/// Note this filter kernel assumes samples are normalized by the caller
/// </summary>
/// <returns></returns>
public virtual List<double> ImpulseResponse()
public virtual List<double> ImpulseResponse(bool normalize = true)
{
List<double> impulseResponse;
impulseResponse = new List<double>(FilterLength + 1);
Expand All @@ -54,10 +54,13 @@ public virtual List<double> ImpulseResponse()
normalizationFactor += impulseResponse[impulseResponse.Count - 1];
}

// Normalize for unity gain at DC
for (int idx = 0; idx < impulseResponse.Count; idx++)
if (normalize)
{
impulseResponse[idx] = impulseResponse[idx] / normalizationFactor;
// Normalize for unity gain at DC
for (int idx = 0; idx < impulseResponse.Count; idx++)
{
impulseResponse[idx] = impulseResponse[idx] / normalizationFactor;
}
}

// Spectral inversion
Expand Down
2 changes: 1 addition & 1 deletion SignalProcessor/IWindowedSyncFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ public interface IWindowedSyncFilter
double CutoffFrequencySamplingFrequencyPercentage { get; set; }
int FilterLength { get; set; }

List<double> ImpulseResponse();
List<double> ImpulseResponse(bool normalize = true);
}
}
10 changes: 5 additions & 5 deletions SignalProcessor/SignalProcessor.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<AssemblyVersion>0.1.12.0</AssemblyVersion>
<FileVersion>0.1.12.0</FileVersion>
<PackageReleaseNotes>Stop cacheing impulse response, calculate every time ImpulseResponse is called, to avoid issues with changed parameters and stale impulse response. Callers should call and cache the value when performance is an issue</PackageReleaseNotes>
<AssemblyVersion>0.1.14.0</AssemblyVersion>
<FileVersion>0.1.14.0</FileVersion>
<PackageReleaseNotes>Add option to turn on / off normalization (default to on) for WindowedSyncFilter</PackageReleaseNotes>
<Copyright>2020 Brian Tabone</Copyright>
<Description>Digital Signal Processing (FFT and Correlation)</Description>
<Version>0.1.12</Version>
<Version>0.1.14</Version>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>SignalProcessor.pfx</AssemblyOriginatorKeyFile>
Expand All @@ -17,7 +17,7 @@
<RepositoryUrl>https://github.com/hybridmachine/DSP</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageProjectUrl>https://github.com/hybridmachine/DSP/projects/1</PackageProjectUrl>
<PackageTags>signal processing fft analysis</PackageTags>
<PackageTags>signal processing fft analysis windowedsync</PackageTags>
</PropertyGroup>

<ItemGroup>
Expand Down
6 changes: 3 additions & 3 deletions Signals And Transforms/Models/WorkBook.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public List<double> ConvolvedFilterImpulseResponse()
/// Band reject
/// </summary>
/// <returns></returns>
public List<double> SummedFilterImpulseResponse()
public List<double> SummedFilterImpulseResponse(bool normalize = true)
{
List<double> summedImpulseResponse = null;
foreach (var filter in Filters.Values.Where(filt => filt.IsActive))
Expand All @@ -86,11 +86,11 @@ public List<double> SummedFilterImpulseResponse()
// Page 274 chapter 14 of "The Scientist and Engineer's Guide to Digital Signal Processing"
if (null == summedImpulseResponse)
{
summedImpulseResponse = filter.ImpulseResponse();
summedImpulseResponse = filter.ImpulseResponse(normalize);
}
else
{
List<double> filterImpulseResponse = filter.ImpulseResponse();
List<double> filterImpulseResponse = filter.ImpulseResponse(normalize);

// Ignore any filters that don't have the same filter length
if (filterImpulseResponse.Count == summedImpulseResponse.Count)
Expand Down
27 changes: 18 additions & 9 deletions Signals And Transforms/Properties/Resources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 6 additions & 3 deletions Signals And Transforms/Properties/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,9 @@
<data name="FILTER_CUTOFF_PERCENTAGE" xml:space="preserve">
<value>Sampling Frequency Cutoff %</value>
</data>
<data name="FILTER_DECIBEL_RESPONSE_TITLE" xml:space="preserve">
<value>Frequency Response (db)</value>
</data>
<data name="FILTER_FREQUENCY_RESPONSE_TITLE" xml:space="preserve">
<value>Frequency Response</value>
</data>
Expand All @@ -159,6 +162,9 @@
<data name="FILTER_NAME" xml:space="preserve">
<value>Filter Name</value>
</data>
<data name="FILTER_STEP_RESPONSE_TITLE" xml:space="preserve">
<value>Step Response</value>
</data>
<data name="FILTER_TYPE_HIGH" xml:space="preserve">
<value>High</value>
</data>
Expand Down Expand Up @@ -214,9 +220,6 @@
<data name="SIGNAL_PLOT_TITLE" xml:space="preserve">
<value>Signal</value>
</data>
<data name="STEP_RESPONSE_TITLE" xml:space="preserve">
<value>Step Response</value>
</data>
<data name="WORKBOOK_FILE_EXTENSION" xml:space="preserve">
<value>.stw</value>
</data>
Expand Down
4 changes: 2 additions & 2 deletions Signals And Transforms/SignalsAndTransforms.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@
<HintPath>..\packages\OxyPlot.Wpf.2.0.0\lib\net45\OxyPlot.Wpf.dll</HintPath>
</Reference>
<Reference Include="ReachFramework" />
<Reference Include="SignalProcessor, Version=0.1.12.0, Culture=neutral, PublicKeyToken=9353e2f223b6035d, processorArchitecture=MSIL">
<HintPath>packages\SignalProcessor.0.1.12\lib\netstandard2.0\SignalProcessor.dll</HintPath>
<Reference Include="SignalProcessor, Version=0.1.14.0, Culture=neutral, PublicKeyToken=9353e2f223b6035d, processorArchitecture=MSIL">
<HintPath>packages\SignalProcessor.0.1.14\lib\netstandard2.0\SignalProcessor.dll</HintPath>
</Reference>
<Reference Include="SQLitePCLRaw.batteries_v2, Version=2.0.2.669, Culture=neutral, PublicKeyToken=8226ea5df37bcae9, processorArchitecture=MSIL">
<HintPath>packages\SQLitePCLRaw.bundle_e_sqlite3.2.0.2\lib\net461\SQLitePCLRaw.batteries_v2.dll</HintPath>
Expand Down
19 changes: 14 additions & 5 deletions Signals And Transforms/View Models/FilterViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Threading.Tasks;

Expand All @@ -31,6 +32,8 @@ public FilterViewModel()

public IList<DataPoint> FrequencyResponsePoints { get; private set; }

public IList<DataPoint> DecibelResponsePoints { get; private set; }

public IList<DataPoint> StepResponsePoints { get; private set; }

public event PropertyChangedEventHandler PropertyChanged;
Expand All @@ -50,7 +53,7 @@ public void AddFilter(Filter newFilter)
private List<double> GetStepData(int len)
{
List<double> stepData = new List<double>();
int pointsOn = len / 3; // point at which signal switches from 0 to 1
int pointsOn = len / 2; // point at which signal switches from 0 to 1

for (int idx = 0; idx < len; idx++)
{
Expand All @@ -61,7 +64,7 @@ private List<double> GetStepData(int len)

private void LoadFilterData()
{
List<double> summedFilterData = manager.ActiveWorkBook().SummedFilterImpulseResponse();
List<double> summedFilterData = manager.ActiveWorkBook().SummedFilterImpulseResponse(true);
if (summedFilterData == null || summedFilterData.Count == 0)
{
return;
Expand All @@ -82,12 +85,17 @@ private void LoadFilterData()
Convolution convolver = new Convolution();
List<double> stepResponse = convolver.Convolve(summedFilterData, GetStepData(summedFilterData.Count + 16), ConvolutionType.INPUTSIDE);
FrequencyResponsePoints = new List<DataPoint>(frequencyDomain.FrequencyAmplitudes.Count);
DecibelResponsePoints = new List<DataPoint>(FrequencyResponsePoints.Count);

// Load the frequency response graph data
List<double> values = new List<double>(frequencyDomain.FrequencyAmplitudes.Values);
for (int idx = 0; idx < frequencyDomain.FrequencyAmplitudes.Count; idx++)
// Only scan the first half of the coefficients (up to the Nyquist frequency)
int coefficientMax = (frequencyDomain.FourierCoefficients.Count / 2);
for (int idx = 0; idx < coefficientMax; idx++)
{
FrequencyResponsePoints.Add(new DataPoint((((double)idx + 1.0) / summedFilterData.Count), values[idx]));
double coeffLen = Complex.Abs(frequencyDomain.FourierCoefficients[idx]);
double cuttoffFrequencyPercent = (((double)idx + 1.0) / summedFilterData.Count);
FrequencyResponsePoints.Add(new DataPoint(cuttoffFrequencyPercent, coeffLen));
DecibelResponsePoints.Add(new DataPoint(cuttoffFrequencyPercent, 20 * Math.Log10(coeffLen)));
}

int startingOffset = (summedFilterData.Count / 2);
Expand All @@ -111,6 +119,7 @@ private void LoadFilterData()

NotifyPropertyChanged(nameof(ImpulseResponsePoints));
NotifyPropertyChanged(nameof(FrequencyResponsePoints));
NotifyPropertyChanged(nameof(DecibelResponsePoints));
NotifyPropertyChanged(nameof(StepResponsePoints));
NotifyPropertyChanged(nameof(Filters));
}
Expand Down
10 changes: 9 additions & 1 deletion Signals And Transforms/Views/FilterView.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,22 @@
MarkerType="Square"/>
</oxy:Plot.Series>
</oxy:Plot>
<oxy:Plot x:Name="StepResponsePlot" Grid.Column="0" Grid.Row="1" Margin="5" Title="{x:Static res:Resources.STEP_RESPONSE_TITLE}">
<oxy:Plot x:Name="StepResponsePlot" Grid.Column="0" Grid.Row="1" Margin="5" Title="{x:Static res:Resources.FILTER_STEP_RESPONSE_TITLE}">
<oxy:Plot.Series>
<oxy:LineSeries ItemsSource="{Binding StepResponsePoints}"
Color="Cyan"
MarkerFill="SteelBlue"
MarkerType="Square"/>
</oxy:Plot.Series>
</oxy:Plot>
<oxy:Plot x:Name="DecibelResponsePlot" Grid.Column="1" Grid.Row="1" Margin="5" Title="{x:Static res:Resources.FILTER_DECIBEL_RESPONSE_TITLE}">
<oxy:Plot.Series>
<oxy:LineSeries ItemsSource="{Binding DecibelResponsePoints}"
Color="Cyan"
MarkerFill="SteelBlue"
MarkerType="Square"/>
</oxy:Plot.Series>
</oxy:Plot>
</Grid>
</Grid>
</UserControl>
2 changes: 1 addition & 1 deletion Signals And Transforms/packages.config
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<package id="Microsoft.NetFramework.Analyzers" version="2.9.8" targetFramework="net472" developmentDependency="true" />
<package id="OxyPlot.Core" version="2.0.0" targetFramework="net472" />
<package id="OxyPlot.Wpf" version="2.0.0" targetFramework="net472" />
<package id="SignalProcessor" version="0.1.12" targetFramework="net472" />
<package id="SignalProcessor" version="0.1.14" targetFramework="net472" />
<package id="SQLitePCLRaw.bundle_e_sqlite3" version="2.0.2" targetFramework="net472" />
<package id="SQLitePCLRaw.core" version="2.0.2" targetFramework="net472" />
<package id="SQLitePCLRaw.lib.e_sqlite3" version="2.0.2" targetFramework="net472" />
Expand Down
2 changes: 2 additions & 0 deletions UnitTests/WindowedSyncFilterTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public void LowPassWindowedSyncTest()

List<double> impulseResponse = filter.ImpulseResponse();
List<double> secondImpulseResponseTest = filter.ImpulseResponse();
List<double> non_normalizedResponseTest = filter.ImpulseResponse(false);

// Make sure back to back calls return the same data for the same parameters
for (int idx = 0; idx < impulseResponse.Count; idx++)
Expand All @@ -37,6 +38,7 @@ public void LowPassWindowedSyncTest()

Assert.IsNotNull(impulseResponse);
Assert.IsNotNull(highImpulseResponse);
Assert.IsNotNull(non_normalizedResponseTest);

Assert.IsTrue(impulseResponse.Count == filter.FilterLength + 1);
}
Expand Down

0 comments on commit ac399f4

Please sign in to comment.