├── .gitattributes ├── .gitignore ├── DspSharp.DynamicInterop ├── App.config ├── DspSharp.DynamicInterop.csproj ├── DynamicInterop.cs ├── Program.cs └── Properties │ └── AssemblyInfo.cs ├── DspSharp.sln ├── DspSharp.sln.DotSettings ├── DspSharp ├── Algorithms │ ├── ComplexVectors.cs │ ├── CubicSpline │ │ ├── CubicSpline.cs │ │ └── TriDiagonalMatrix.cs │ ├── Experimental.cs │ ├── Fft.cs │ ├── FrequencyDomain.cs │ ├── IFftProvider.cs │ ├── Interpolation.cs │ ├── Mathematic.cs │ ├── SignalGenerators.cs │ ├── Statistics.cs │ ├── TimeDomain.cs │ ├── Unsafe.cs │ ├── VectorArithmeticC.cs │ ├── VectorArithmeticD.cs │ ├── VectorConversions.cs │ ├── VectorFunctions.cs │ └── VectorOperations.cs ├── AudioSource │ ├── BufferCompletedEventArgs.cs │ ├── BufferCompletedEventHandler.cs │ ├── FilterStreamer.cs │ └── IAudioSource.cs ├── Buffers │ ├── BufferSwitchEventArgs.cs │ ├── CircularArray.cs │ ├── CircularBlockBuffer.cs │ ├── CircularBuffer.cs │ └── DoubleBlockBuffer.cs ├── DspSharp.Interop.dll ├── DspSharp.csproj ├── DspSharp.csproj.DotSettings ├── Exceptions │ └── SamplerateMismatchException.cs ├── Extensions │ ├── FilterExtensions.cs │ ├── SignalExtensions.cs │ ├── SpectrumExtensions.cs │ └── Utilities.cs ├── Filter │ ├── ChangeEventHandler.cs │ ├── FilterBase.cs │ ├── FilterChangedEventArgs.cs │ ├── FilterFactory │ │ ├── FilterFactory.cs │ │ └── FilterTypes.cs │ ├── FilterSet.cs │ ├── FiniteFilter.cs │ ├── FiniteFilterSet.cs │ ├── IFilter.cs │ ├── IFiniteFilter.cs │ ├── ISignalBasedFilter.cs │ ├── LtiFilters │ │ ├── Fir │ │ │ ├── Convolver.cs │ │ │ ├── CorrectingFilter.cs │ │ │ ├── CustomConvolver.cs │ │ │ └── FirFilter.cs │ │ ├── Iir │ │ │ ├── Biquad.cs │ │ │ ├── ButterworthFilter.cs │ │ │ ├── CustomIirFilter.cs │ │ │ ├── IIRFilter.cs │ │ │ └── SecondOrderPrototpyeFilter.cs │ │ └── Primitive │ │ │ ├── DelayFilter.cs │ │ │ ├── DiracFilter.cs │ │ │ ├── GainFilter.cs │ │ │ ├── InvertFilter.cs │ │ │ └── ZeroFilter.cs │ └── NonlinearFilters │ │ ├── AwgnFilter.cs │ │ ├── CustomFilter.cs │ │ ├── CustomFiniteFilter.cs │ │ └── DistortionFilter.cs ├── PropertyTools.dll ├── Series │ ├── ConstantSeries.cs │ ├── CustomSeries.cs │ ├── FftSeries.cs │ ├── ISeries.cs │ ├── SeriesBase.cs │ ├── SeriesUtil.cs │ └── UniformSeries.cs ├── Signal │ ├── BaseImplementations │ │ ├── EnumerableSignal.cs │ │ ├── FiniteSignal.cs │ │ ├── InfiniteSignal.cs │ │ ├── SignalBase.cs │ │ └── SyntheticSignal.cs │ ├── Interfaces │ │ ├── IEnumerableSignal.cs │ │ ├── IFiniteSignal.cs │ │ ├── ISignal.cs │ │ └── ISyntheticSignal.cs │ ├── SignalTypes │ │ ├── Dirac.cs │ │ ├── IdealHighpass.cs │ │ ├── IdealLowpass.cs │ │ ├── LogSweep.cs │ │ ├── Sinc.cs │ │ ├── Sinus.cs │ │ └── WhiteNoise.cs │ └── Windows │ │ ├── Window.cs │ │ ├── WindowModes.cs │ │ └── WindowTypes.cs ├── Spectrum │ ├── FftSpectrum.cs │ ├── IFftSpectrum.cs │ ├── ISpectrum.cs │ └── Spectrum.cs └── Utilities │ ├── Collections │ ├── Extensions.cs │ ├── IObservableList.cs │ ├── IReadOnlyObservableList.cs │ ├── ISortedObservableList.cs │ ├── ObservableList.cs │ ├── ObservableSortedDictionary.cs │ ├── ReadOnlyObservableList.cs │ └── SortedObservableList.cs │ ├── HashHelper.cs │ └── Observable.cs ├── DspSharpAsio ├── ASIODriver.cs ├── ASIODriverExt.cs ├── ASIOStructures.cs ├── Asio64Bit.cs ├── AsioCallbacks.cs ├── AsioChannelInfo.cs ├── AsioDriverCapability.cs ├── AsioDriverExt.cd ├── AsioError.cs ├── AsioFillBufferCallback.cs ├── AsioMessageSelector.cs ├── AsioSampleType.cs ├── DspSharpAsio.csproj ├── Properties │ └── AssemblyInfo.cs └── SampleTypeConverter.cs ├── DspSharpDemo ├── App.config ├── App.xaml ├── App.xaml.cs ├── DspSharpDemo.csproj ├── EnumCombo.cs ├── EnumToStringConverter.cs ├── IListItemConverter.cs ├── LocalPropertyGridControlFactory.cs ├── MainWindow.xaml ├── MainWindow.xaml.cs ├── MultiSelectBehaviours.cs ├── PerformanceHelper.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── RelayCommand.cs ├── SignalFactory │ ├── AvailableSignals.cs │ ├── CommonSignalConfig.cs │ ├── DialogClose.cs │ ├── DiracFactory.cs │ ├── FileFrequencyResponseFactory.cs │ ├── FileImpulseResponseFactory.cs │ ├── IdealHighpassFactory.cs │ ├── IdealLowpassFactory.cs │ ├── LogSweepFactory.cs │ ├── SignalDialog.xaml │ ├── SignalDialog.xaml.cs │ ├── SignalFactory.cs │ ├── SignalFactoryFactory.cs │ ├── SincFactory.cs │ ├── SinusFactory.cs │ ├── ViewModel.cs │ ├── WhiteNoiseFactory.cs │ └── WindowFactory.cs ├── TwoListSynchronizer.cs ├── ViewModel.cs └── packages.config ├── DspSharpFftw ├── ComplexFftPlan.cs ├── DspSharp.Interop.dll ├── DspSharpFftw.csproj ├── FftPlan.cs ├── FftwDirection.cs ├── FftwFlags.cs ├── FftwInterop.cs ├── FftwKind.cs ├── FftwProvider.cs ├── ForwardRealFftPlan.cs ├── InverseRealFftPlan.cs ├── Pointers │ └── ManagedPointer.cs ├── RealFftPlan.cs ├── libfftw3-3-32.dll └── libfftw3-3-64.dll ├── DspSharpPlot ├── App.config ├── App.xaml ├── App.xaml.cs ├── Axes │ ├── AmplitudeAxis.cs │ ├── DefaultAxis.cs │ ├── FrequencyAxis.cs │ ├── GroupDelayAxis.cs │ ├── ImpulseResponseAxis.cs │ ├── PhaseAxis.cs │ └── SampleAxis.cs ├── DspSharpPlot.csproj ├── DspSharpPlot.csproj.DotSettings ├── FilterPlot.csproj.DotSettings ├── FilterPlot.nuspec ├── Graphs │ └── ImpulseResponseGraph.cs ├── Plot.cs ├── PlotServer │ ├── IPlotContract.cs │ ├── ITestContract.cs │ └── PlotServer.cs ├── PlotWindow.xaml ├── PlotWindow.xaml.cs ├── PlotWindowViewModel.cs ├── Plots │ ├── FinitePlot.cs │ ├── IXCanBeLogarithmic.cs │ ├── IYCanBeLogarithmic.cs │ ├── ImpulseResponsePlot.cs │ ├── MagnitudePlot.cs │ ├── PhasePlot.cs │ ├── SignalPlot.cs │ └── SpectrumPlot.cs ├── Program.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings └── packages.config ├── DspSharpTest ├── AlgorithmTest.cs ├── CircularBuffersTest.cs ├── ComplexVectorTests.cs ├── DspSharpTest.csproj ├── FftTest.cs ├── FilterAssert.cs ├── MlsTest.cs ├── Properties │ └── AssemblyInfo.cs ├── TestFrequencyDomainAlgorithms.cs ├── TestInterpolation.cs ├── TestMathematicAlgorithms.cs ├── TestSignalGenerators.cs ├── TestStatistics.cs ├── TestTimeDomainAlgorithms.cs ├── TestVectorArithmeticC.cs ├── TestVectorArithmeticD.cs ├── TestVectorFunctions.cs ├── TestVectorOperations.cs ├── UnsafeAlgorithmsTest.cs └── packages.config ├── LICENSE.txt ├── README.md └── licenses ├── CPOL.txt ├── GPL.txt ├── MIT.txt └── Ms-PL.txt /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /DspSharp.DynamicInterop/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /DspSharp.DynamicInterop/DspSharp.DynamicInterop.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {74829BDE-ED15-489C-A29E-09C260F38F3A} 8 | Exe 9 | Properties 10 | DspSharp.DynamicInterop 11 | DspSharp.DynamicInterop 12 | v4.6.2 13 | 512 14 | true 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 61 | -------------------------------------------------------------------------------- /DspSharp.DynamicInterop/Program.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | namespace DspSharp.DynamicInterop 8 | { 9 | class Program 10 | { 11 | static void Main(string[] args) 12 | { 13 | DynamicInterop.Generate(); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /DspSharp.DynamicInterop/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System.Reflection; 8 | using System.Runtime.InteropServices; 9 | 10 | // General Information about an assembly is controlled through the following 11 | // set of attributes. Change these attribute values to modify the information 12 | // associated with an assembly. 13 | 14 | [assembly: AssemblyTitle("DynamicInterop")] 15 | [assembly: AssemblyDescription("")] 16 | [assembly: AssemblyConfiguration("")] 17 | [assembly: AssemblyCompany("")] 18 | [assembly: AssemblyProduct("DynamicInterop")] 19 | [assembly: AssemblyCopyright("Copyright © 2017")] 20 | [assembly: AssemblyTrademark("")] 21 | [assembly: AssemblyCulture("")] 22 | 23 | // Setting ComVisible to false makes the types in this assembly not visible 24 | // to COM components. If you need to access a type in this assembly from 25 | // COM, set the ComVisible attribute to true on that type. 26 | 27 | [assembly: ComVisible(false)] 28 | 29 | // The following GUID is for the ID of the typelib if this project is exposed to COM 30 | 31 | [assembly: Guid("74829bde-ed15-489c-a29e-09c260f38f3a")] 32 | 33 | // Version information for an assembly consists of the following four values: 34 | // 35 | // Major Version 36 | // Minor Version 37 | // Build Number 38 | // Revision 39 | // 40 | // You can specify all the values or you can default the Build and Revision Numbers 41 | // by using the '*' as shown below: 42 | // [assembly: AssemblyVersion("1.0.*")] 43 | 44 | [assembly: AssemblyVersion("1.0.0.0")] 45 | [assembly: AssemblyFileVersion("1.0.0.0")] -------------------------------------------------------------------------------- /DspSharp/Algorithms/FrequencyDomain.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jonarw/DspSharp/f1b987ec1b5c21f572b9a1e409c661925f4d7455/DspSharp/Algorithms/FrequencyDomain.cs -------------------------------------------------------------------------------- /DspSharp/AudioSource/BufferCompletedEventArgs.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System; 8 | using System.Collections.Generic; 9 | 10 | namespace DspSharp.AudioSource 11 | { 12 | public class BufferCompletedEventArgs : EventArgs 13 | { 14 | public BufferCompletedEventArgs(IReadOnlyList inputs, IReadOnlyList outputs) 15 | { 16 | this.Inputs = inputs; 17 | this.Outputs = outputs; 18 | } 19 | 20 | public IReadOnlyList Inputs { get; } 21 | public IReadOnlyList Outputs { get; } 22 | } 23 | } -------------------------------------------------------------------------------- /DspSharp/AudioSource/BufferCompletedEventHandler.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | namespace DspSharp.AudioSource 8 | { 9 | public delegate void BufferCompletedEventHandler(IAudioSource sender, BufferCompletedEventArgs e); 10 | } -------------------------------------------------------------------------------- /DspSharp/AudioSource/FilterStreamer.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System; 8 | using System.Collections.Generic; 9 | using DspSharp.Algorithms; 10 | using DspSharp.Filter; 11 | 12 | namespace DspSharp.AudioSource 13 | { 14 | public class FilterStreamer 15 | { 16 | private readonly IFilter _filter; 17 | 18 | public FilterStreamer(IFilter filter) 19 | { 20 | this._filter = filter; 21 | this.StreamEnumerator = filter.Process(this.Stream).GetEnumerator(); 22 | } 23 | 24 | private IReadOnlyList CurrentBlock { get; set; } 25 | 26 | private IEnumerable Stream 27 | { 28 | get 29 | { 30 | while (true) 31 | { 32 | foreach (var d in this.CurrentBlock) 33 | { 34 | yield return d; 35 | } 36 | } 37 | // ReSharper disable once IteratorNeverReturns 38 | } 39 | } 40 | 41 | private IEnumerator StreamEnumerator { get; } 42 | 43 | public void InputBlock(IEnumerable block) 44 | { 45 | this.CurrentBlock = block.ToReadOnlyList(); 46 | } 47 | 48 | public double[] OutputBlock() 49 | { 50 | if (this.CurrentBlock == null) 51 | throw new InvalidOperationException(); 52 | 53 | return this.GetBlock(); 54 | } 55 | 56 | public double[] StreamBlock(IEnumerable block) 57 | { 58 | this.InputBlock(block); 59 | return this.GetBlock(); 60 | } 61 | 62 | private double[] GetBlock() 63 | { 64 | lock (this.StreamEnumerator) 65 | { 66 | var ret = new double[this.CurrentBlock.Count]; 67 | 68 | for (var i = 0; i < this.CurrentBlock.Count; i++) 69 | { 70 | this.StreamEnumerator.MoveNext(); 71 | ret[i] = this.StreamEnumerator.Current; 72 | } 73 | 74 | return ret; 75 | } 76 | } 77 | } 78 | } -------------------------------------------------------------------------------- /DspSharp/AudioSource/IAudioSource.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | namespace DspSharp.AudioSource 8 | { 9 | public interface IAudioSource 10 | { 11 | int BlockSize { get; } 12 | event BufferCompletedEventHandler BufferCompleted; 13 | } 14 | } -------------------------------------------------------------------------------- /DspSharp/Buffers/BufferSwitchEventArgs.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System; 8 | 9 | namespace DspSharp.Buffers 10 | { 11 | /// 12 | /// Represents event data for a BufferSwitchEvent. 13 | /// 14 | /// 15 | public unsafe class BufferSwitchEventArgs : EventArgs 16 | { 17 | /// 18 | /// Initializes a new instance of the class. 19 | /// 20 | /// The new work buffer after the buffer switch. 21 | /// The new input buffer after the buffer switch. 22 | public BufferSwitchEventArgs(byte* newWorkBuffer, byte* newInputBuffer) 23 | { 24 | this.NewWorkBuffer = newWorkBuffer; 25 | this.NewInputBuffer = newInputBuffer; 26 | } 27 | 28 | /// 29 | /// Gets or sets a value indicating whether the buffer switch operation should be canceled. In that case, the buffers 30 | /// will not be switched; the will continue its operation overwriting the current 31 | /// input block. 32 | /// 33 | public bool Cancel { get; set; } 34 | 35 | /// 36 | /// Gets the new input buffer (after the buffer switch). 37 | /// 38 | public byte* NewInputBuffer { get; } 39 | 40 | /// 41 | /// Gets the new work buffer (after the buffer switch). 42 | /// 43 | public byte* NewWorkBuffer { get; } 44 | } 45 | } -------------------------------------------------------------------------------- /DspSharp/Buffers/CircularArray.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System; 8 | using System.Collections.Generic; 9 | using System.Linq; 10 | 11 | namespace DspSharp.Buffers 12 | { 13 | public class CircularArray 14 | { 15 | public CircularArray(IReadOnlyList items) 16 | { 17 | this.Items = items.ToArray(); 18 | this.Length = this.Items.Length; 19 | } 20 | 21 | public int Length { get; } 22 | 23 | public int Position { get; private set; } 24 | private T[] Items { get; } 25 | 26 | public T[] GetRange(int count) 27 | { 28 | var ret = new T[count]; 29 | 30 | if (count + this.Position < this.Length) 31 | { 32 | Array.Copy(this.Items, this.Position, ret, 0, count); 33 | this.Position += count; 34 | } 35 | else 36 | { 37 | var tmp = this.Length - this.Position; 38 | Array.Copy(this.Items, this.Position, ret, 0, tmp); 39 | this.PeriodCompleted?.Invoke(this, EventArgs.Empty); 40 | 41 | while (count - tmp > this.Length) 42 | { 43 | Array.Copy(this.Items, 0, ret, tmp, this.Length); 44 | tmp += this.Length; 45 | this.PeriodCompleted?.Invoke(this, EventArgs.Empty); 46 | } 47 | 48 | Array.Copy(this.Items, 0, ret, tmp, count - tmp); 49 | this.Position = count - tmp; 50 | } 51 | 52 | return ret; 53 | } 54 | 55 | public T GetValue() 56 | { 57 | var ret = this.Items[this.Position++]; 58 | 59 | if (this.Position > this.Items.Length) 60 | { 61 | this.Position -= this.Items.Length; 62 | this.PeriodCompleted?.Invoke(this, EventArgs.Empty); 63 | } 64 | 65 | return ret; 66 | } 67 | 68 | public event EventHandler PeriodCompleted; 69 | } 70 | } -------------------------------------------------------------------------------- /DspSharp/DspSharp.Interop.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jonarw/DspSharp/f1b987ec1b5c21f572b9a1e409c661925f4d7455/DspSharp/DspSharp.Interop.dll -------------------------------------------------------------------------------- /DspSharp/DspSharp.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard1.3;net45;net46 5 | True 6 | 0.1.8-pre 7 | Jonathan Arweck 8 | 9 | DspSharp - Digital Audio Signal Processing in C# 10 | © 2017 Jonathan Arweck 11 | https://github.com/Jonarw/DspSharp/blob/dev/LICENSE.txt 12 | https://github.com/Jonarw/DspSharp/ 13 | audio signal processing dsp filter fir iir 14 | 15 | 16 | 17 | True 18 | 0.1.8.0 19 | 0.1.8.0 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | DspSharp.Interop.dll 30 | 31 | 32 | PropertyTools.dll 33 | 34 | 35 | 36 | 37 | 38 | true 39 | PreserveNewest 40 | 41 | 42 | true 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /DspSharp/DspSharp.csproj.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | False 3 | True 4 | True 5 | False 6 | True 7 | True 8 | True 9 | True 10 | True 11 | False -------------------------------------------------------------------------------- /DspSharp/Exceptions/SamplerateMismatchException.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System; 8 | 9 | namespace DspSharp.Exceptions 10 | { 11 | public class SamplerateMismatchException : Exception 12 | { 13 | } 14 | } -------------------------------------------------------------------------------- /DspSharp/Extensions/FilterExtensions.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using DspSharp.Algorithms; 8 | using DspSharp.Filter; 9 | using DspSharp.Signal; 10 | 11 | namespace DspSharp.Extensions 12 | { 13 | /// 14 | /// Provides static extension for the IFilter interface. 15 | /// 16 | public static class FilterExtensions 17 | { 18 | /// 19 | /// Computes the impulse response of the filter. 20 | /// 21 | /// The filter. 22 | /// The impulse response. 23 | public static IEnumerableSignal GetImpulseResponse(this IFilter filter) 24 | { 25 | return new EnumerableSignal(filter.Process(1.0.ToEnumerable()), filter.Samplerate); 26 | } 27 | 28 | public static IFilter Chain(this IFilter filter1, IFilter filter2) 29 | { 30 | var set = filter1 as FilterSet; 31 | if (set != null) 32 | set.Filters.Add(filter2); 33 | else 34 | { 35 | set = new FilterSet(filter1.Samplerate); 36 | set.Filters.Add(filter1); 37 | set.Filters.Add(filter2); 38 | } 39 | 40 | return set; 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /DspSharp/Extensions/SpectrumExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using DspSharp.Algorithms; 3 | using DspSharp.Spectrum; 4 | 5 | namespace DspSharp.Extensions 6 | { 7 | public static class SpectrumExtensions 8 | { 9 | public static IFftSpectrum Multiply(this IFftSpectrum spectrum1, IFftSpectrum spectrum2) 10 | { 11 | if (spectrum1 == null) 12 | throw new ArgumentNullException(nameof(spectrum1)); 13 | if (spectrum2 == null) 14 | throw new ArgumentNullException(nameof(spectrum2)); 15 | if (!spectrum1.Frequencies.Equals(spectrum2.Frequencies)) 16 | throw new ArgumentException(); 17 | 18 | return new FftSpectrum(spectrum1.Frequencies, spectrum1.Values.Multiply(spectrum2.Values).ToReadOnlyList()); 19 | } 20 | 21 | public static IFftSpectrum Divide(this IFftSpectrum spectrum1, IFftSpectrum spectrum2) 22 | { 23 | if (spectrum1 == null) 24 | throw new ArgumentNullException(nameof(spectrum1)); 25 | if (spectrum2 == null) 26 | throw new ArgumentNullException(nameof(spectrum2)); 27 | if (!spectrum1.Frequencies.Equals(spectrum2.Frequencies)) 28 | throw new ArgumentException(); 29 | 30 | return new FftSpectrum(spectrum1.Frequencies, spectrum1.Values.Divide(spectrum2.Values).ToReadOnlyList()); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /DspSharp/Extensions/Utilities.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System.Collections.Generic; 8 | using System.Linq; 9 | 10 | namespace DspSharp.Extensions 11 | { 12 | public static class Utilities 13 | { 14 | /// 15 | /// Determines whether the collection is null or contains no elements. 16 | /// 17 | /// The IEnumerable type. 18 | /// The enumerable, which may be null or empty. 19 | /// 20 | /// true if the IEnumerable is null or empty; otherwise, false. 21 | /// 22 | public static bool IsNullOrEmpty(this IEnumerable enumerable) 23 | { 24 | if (enumerable == null) 25 | return true; 26 | 27 | var collection = enumerable as ICollection; 28 | if (collection != null) 29 | return collection.Count < 1; 30 | 31 | return !enumerable.Any(); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /DspSharp/Filter/ChangeEventHandler.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | namespace DspSharp.Filter 8 | { 9 | public delegate void ChangeEventHandler(IFilter sender, FilterChangedEventArgs e); 10 | } -------------------------------------------------------------------------------- /DspSharp/Filter/FilterChangedEventArgs.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System; 8 | 9 | namespace DspSharp.Filter 10 | { 11 | public class FilterChangedEventArgs : EventArgs 12 | { 13 | } 14 | } -------------------------------------------------------------------------------- /DspSharp/Filter/FilterFactory/FilterFactory.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System; 8 | using DspSharp.Filter.LtiFilters.Fir; 9 | using DspSharp.Filter.LtiFilters.Iir; 10 | using DspSharp.Filter.LtiFilters.Primitive; 11 | using DspSharp.Filter.NonlinearFilters; 12 | using DspSharp.Signal; 13 | using DspSharp.Utilities.Collections; 14 | 15 | namespace DspSharp.Filter 16 | { 17 | /// 18 | /// Provides a static function from creating new filter objects. 19 | /// 20 | public static class FilterFactory 21 | { 22 | /// 23 | /// Creates a new filter object of the specified filter type. 24 | /// 25 | /// The filter type. 26 | /// The samplerate. 27 | /// The available signals for all filters that are based on existing signals. 28 | /// 29 | /// null 30 | public static IFilter CreateFilter( 31 | FilterTypes type, 32 | double samplerate, 33 | IReadOnlyObservableList availableSignals = null) 34 | { 35 | if (type == FilterTypes.Distortion) 36 | return new DistortionFilter(samplerate); 37 | 38 | if (type == FilterTypes.Biquad) 39 | return new BiquadFilter(samplerate); 40 | 41 | if (type == FilterTypes.CustomConvolver) 42 | return new CustomConvolver(samplerate) {AvailableSignals = availableSignals}; 43 | 44 | if (type == FilterTypes.Correcting) 45 | return new CorrectingFilter(samplerate); 46 | 47 | if (type == FilterTypes.Delay) 48 | return new DelayFilter(samplerate); 49 | 50 | if (type == FilterTypes.Dirac) 51 | return new DiracFilter(samplerate); 52 | 53 | if (type == FilterTypes.Fir) 54 | return new FirFilter(samplerate); 55 | 56 | if (type == FilterTypes.Gain) 57 | return new GainFilter(samplerate); 58 | 59 | if (type == FilterTypes.Iir) 60 | return new IirFilter(samplerate); 61 | 62 | if (type == FilterTypes.Invert) 63 | return new InvertFilter(samplerate); 64 | 65 | if (type == FilterTypes.Zero) 66 | return new ZeroFilter(samplerate); 67 | 68 | throw new ArgumentOutOfRangeException(nameof(type), type, null); 69 | } 70 | } 71 | } -------------------------------------------------------------------------------- /DspSharp/Filter/FilterFactory/FilterTypes.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System.ComponentModel; 8 | 9 | namespace DspSharp.Filter 10 | { 11 | /// 12 | /// Enumerates the available filter types. 13 | /// 14 | public enum FilterTypes 15 | { 16 | [Description("distortion")] Distortion, 17 | [Description("biquad")] Biquad, 18 | [Description("convolver (custom signal)")] CustomConvolver, 19 | [Description("correcting (experimental)")] Correcting, 20 | [Description("delay")] Delay, 21 | [Description("dirac")] Dirac, 22 | [Description("fir highpass/lowpass")] Fir, 23 | [Description("simple gain")] Gain, 24 | [Description("IIR filter with custom coefficients")] Iir, 25 | [Description("inverter")] Invert, 26 | [Description("muter")] Zero 27 | } 28 | } -------------------------------------------------------------------------------- /DspSharp/Filter/FilterSet.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System.Collections.Generic; 8 | using System.Collections.Specialized; 9 | using System.Linq; 10 | using DspSharp.Utilities.Collections; 11 | 12 | namespace DspSharp.Filter 13 | { 14 | /// 15 | /// Represents a set of filters which are applied in succession. 16 | /// 17 | /// 18 | public class FilterSet : FilterBase 19 | { 20 | private readonly IObservableList _Filters = new ObservableList(); 21 | 22 | /// 23 | /// Initializes a new instance of the class. 24 | /// 25 | /// The samplerate. 26 | public FilterSet(double samplerate) : base(samplerate) 27 | { 28 | this._Filters.CollectionChanged += this.FilterCollectionChanged; 29 | } 30 | 31 | /// 32 | /// Gets the contained filters. 33 | /// 34 | public IList Filters => this._Filters; 35 | 36 | /// 37 | /// Gets a value indicating whether this instance has infinite impulse response. 38 | /// 39 | /// 40 | /// true if this instance has an infinite impulse response; otherwise, false. 41 | /// 42 | public override bool HasInfiniteImpulseResponse => this.Filters.Any(f => f.HasInfiniteImpulseResponse); 43 | 44 | protected override bool HasEffectOverride => this.Filters.Count > 0; 45 | 46 | /// 47 | /// Processes the specified signal. 48 | /// 49 | /// The signal. 50 | /// 51 | /// The processed signal. 52 | /// 53 | public override IEnumerable ProcessOverride(IEnumerable signal) 54 | { 55 | foreach (var filter in this.Filters) 56 | { 57 | signal = filter.Process(signal); 58 | } 59 | 60 | return signal; 61 | } 62 | 63 | private void FilterCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) 64 | { 65 | this.RaiseChangedEvent(); 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /DspSharp/Filter/FiniteFilter.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System.Collections.Generic; 8 | using DspSharp.Algorithms; 9 | 10 | namespace DspSharp.Filter 11 | { 12 | /// 13 | /// Represents a filter with a finite impulse response. 14 | /// 15 | /// 16 | /// 17 | public abstract class FiniteFilter : FilterBase, IFiniteFilter 18 | { 19 | /// 20 | /// Initializes a new instance of the class. 21 | /// 22 | /// The samplerate. 23 | protected FiniteFilter(double samplerate) : base(samplerate) 24 | { 25 | } 26 | 27 | /// 28 | /// Gets a value indicating whether this instance has infinite impulse response. 29 | /// 30 | /// 31 | /// true if this instance has an infinite impulse response; otherwise, false. 32 | /// 33 | public sealed override bool HasInfiniteImpulseResponse => false; 34 | 35 | public IReadOnlyList Process(IReadOnlyList input) 36 | { 37 | return this.HasEffect ? this.ProcessOverride(input) : input; 38 | } 39 | 40 | /// 41 | /// Processes the specified sequence. 42 | /// 43 | /// The sequence. 44 | /// 45 | public IReadOnlyList ProcessOverride(IReadOnlyList input) 46 | { 47 | return this.ProcessOverride((IEnumerable)input).ToReadOnlyList(); 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /DspSharp/Filter/FiniteFilterSet.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System.Collections.Generic; 8 | using System.Collections.Specialized; 9 | using DspSharp.Utilities.Collections; 10 | 11 | namespace DspSharp.Filter 12 | { 13 | /// 14 | /// Represents a set of finite filters which are applied in succession. 15 | /// 16 | /// 17 | public class FiniteFilterSet : FiniteFilter 18 | { 19 | private readonly IObservableList _Filters = new ObservableList(); 20 | 21 | public FiniteFilterSet(double samplerate) : base(samplerate) 22 | { 23 | this._Filters.CollectionChanged += this.FilterCollectionChanged; 24 | } 25 | 26 | /// 27 | /// Gets the contained filters. 28 | /// 29 | public IList Filters => this._Filters; 30 | 31 | /// 32 | /// Specifies whether the filter object has an effect or not. 33 | /// 34 | protected override bool HasEffectOverride => this.Filters.Count > 0; 35 | 36 | /// 37 | /// Processes the specified sequence. 38 | /// 39 | /// The sequence. 40 | /// 41 | public override IEnumerable ProcessOverride(IEnumerable input) 42 | { 43 | foreach (var filter in this.Filters) 44 | { 45 | input = filter.Process(input); 46 | } 47 | 48 | return input; 49 | } 50 | 51 | private void FilterCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) 52 | { 53 | this.RaiseChangedEvent(); 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /DspSharp/Filter/IFilter.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System.Collections.Generic; 8 | using System.ComponentModel; 9 | 10 | namespace DspSharp.Filter 11 | { 12 | /// 13 | /// Describes a digital filter. 14 | /// 15 | /// 16 | public interface IFilter : INotifyPropertyChanged 17 | { 18 | /// 19 | /// Gets a value indicating whether this instance has an infinite impulse response. 20 | /// 21 | bool HasInfiniteImpulseResponse { get; } 22 | 23 | /// 24 | /// Gets the samplerate. 25 | /// 26 | double Samplerate { get; } 27 | 28 | /// 29 | /// Processes the specified input. 30 | /// 31 | /// The input. 32 | IEnumerable Process(IEnumerable input); 33 | } 34 | } -------------------------------------------------------------------------------- /DspSharp/Filter/IFiniteFilter.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System.Collections.Generic; 8 | 9 | namespace DspSharp.Filter 10 | { 11 | /// 12 | /// Describes a digital filter with a finite impulse response. 13 | /// 14 | /// 15 | public interface IFiniteFilter : IFilter 16 | { 17 | /// 18 | /// Processes the specified input. 19 | /// 20 | /// The input. 21 | IReadOnlyList Process(IReadOnlyList input); 22 | } 23 | } -------------------------------------------------------------------------------- /DspSharp/Filter/ISignalBasedFilter.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using DspSharp.Signal; 8 | using DspSharp.Utilities.Collections; 9 | 10 | namespace DspSharp.Filter 11 | { 12 | /// 13 | /// Describes a filter that uses a predefined signal from a list of available signals. 14 | /// 15 | public interface ISignalBasedFilter 16 | { 17 | /// 18 | /// Gets or sets the available signals. 19 | /// 20 | IReadOnlyObservableList AvailableSignals { get; set; } 21 | } 22 | } -------------------------------------------------------------------------------- /DspSharp/Filter/LtiFilters/Fir/Convolver.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System.Collections.Generic; 8 | using DspSharp.Algorithms; 9 | 10 | namespace DspSharp.Filter.LtiFilters.Fir 11 | { 12 | /// 13 | /// Base class for all filters that can be described by their impulse response. 14 | /// 15 | /// 16 | public abstract class Convolver : FiniteFilter 17 | { 18 | protected Convolver(double samplerate) : base(samplerate) 19 | { 20 | this.Name = "Convolver"; 21 | } 22 | 23 | public abstract IReadOnlyList ImpulseResponse { get; } 24 | 25 | protected override bool HasEffectOverride 26 | { 27 | get 28 | { 29 | if (this.ImpulseResponse == null) 30 | return false; 31 | 32 | return true; 33 | } 34 | } 35 | 36 | public override IEnumerable ProcessOverride(IEnumerable signal) 37 | { 38 | return TimeDomain.Convolve(signal, this.ImpulseResponse); 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /DspSharp/Filter/LtiFilters/Iir/CustomIirFilter.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace DspSharp.Filter.LtiFilters.Iir 4 | { 5 | public class CustomIirFilter : IirFilter 6 | { 7 | public CustomIirFilter(double samplerate, IEnumerable a, IEnumerable b) : base(samplerate) 8 | { 9 | base.SetCoefficients(a, b); 10 | } 11 | 12 | public CustomIirFilter(double samplerate) : base(samplerate) 13 | { 14 | } 15 | 16 | public new void SetCoefficients(IEnumerable a, IEnumerable b) 17 | { 18 | base.SetCoefficients(a, b); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /DspSharp/Filter/LtiFilters/Primitive/DelayFilter.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System; 8 | using System.Collections.Generic; 9 | using System.Linq; 10 | using DspSharp.Algorithms; 11 | using PropertyTools.DataAnnotations; 12 | 13 | namespace DspSharp.Filter.LtiFilters.Primitive 14 | { 15 | /// 16 | /// Represents a filter with a constant group delay and no effects otherwise. 17 | /// 18 | public class DelayFilter : FiniteFilter 19 | { 20 | private double _delay; 21 | private int _SampleDelay; 22 | 23 | public DelayFilter(double samplerate) : base(samplerate) 24 | { 25 | this.Name = "delay filter"; 26 | } 27 | 28 | /// 29 | /// True if is not 0, false otherwise. 30 | /// 31 | protected override bool HasEffectOverride 32 | { 33 | get 34 | { 35 | if (this.SampleDelay == 0) 36 | return false; 37 | return true; 38 | } 39 | } 40 | 41 | public override IEnumerable ProcessOverride(IEnumerable signal) 42 | { 43 | return SignalGenerators.GetZeros(this.SampleDelay).Concat(signal); 44 | } 45 | 46 | /// 47 | /// Gets or sets the delay of the in integer samples. 48 | /// 49 | [Category("delay")] 50 | [DisplayName("delay in samples")] 51 | public int SampleDelay 52 | { 53 | get { return Convert.ToInt32(this.Delay * this.Samplerate); } 54 | set 55 | { 56 | if (!this.SetField(ref this._SampleDelay, value)) 57 | return; 58 | 59 | this.Delay = value / this.Samplerate; 60 | this.RaiseChangedEvent(); 61 | } 62 | } 63 | 64 | /// 65 | /// Gets the delay of the in seconds. 66 | /// 67 | [DisplayName("delay in seconds")] 68 | public double Delay 69 | { 70 | get { return this._delay; } 71 | private set { this.SetField(ref this._delay, value); } 72 | } 73 | } 74 | } -------------------------------------------------------------------------------- /DspSharp/Filter/LtiFilters/Primitive/DiracFilter.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System.Collections.Generic; 8 | 9 | namespace DspSharp.Filter.LtiFilters.Primitive 10 | { 11 | /// 12 | /// A filter with a transfer function of 1. 13 | /// 14 | public class DiracFilter : FiniteFilter 15 | { 16 | public DiracFilter(double samplerate) : base(samplerate) 17 | { 18 | this.Name = "Dirac Filter"; 19 | } 20 | 21 | /// 22 | /// Returns false. 23 | /// 24 | protected override bool HasEffectOverride => false; 25 | 26 | public override IEnumerable ProcessOverride(IEnumerable signal) 27 | { 28 | return signal; 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /DspSharp/Filter/LtiFilters/Primitive/GainFilter.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System.Collections.Generic; 8 | using DspSharp.Algorithms; 9 | using PropertyTools.DataAnnotations; 10 | 11 | namespace DspSharp.Filter.LtiFilters.Primitive 12 | { 13 | /// 14 | /// Represents a filter with a constant gain and no effects otherwise. 15 | /// 16 | public class GainFilter : FiniteFilter 17 | { 18 | private double _Gain = 1; 19 | 20 | public GainFilter(double samplerate) : base(samplerate) 21 | { 22 | this.Name = "Gain Filter"; 23 | } 24 | 25 | /// 26 | /// True if is not 1, false otherwise. 27 | /// 28 | protected override bool HasEffectOverride 29 | { 30 | get 31 | { 32 | if (this.Gain == 1) 33 | return false; 34 | 35 | return true; 36 | } 37 | } 38 | 39 | public override IEnumerable ProcessOverride(IEnumerable signal) 40 | { 41 | return signal.Multiply(this.Gain); 42 | } 43 | 44 | /// 45 | /// Gets or sets the linear gain factor of the . 46 | /// 47 | [Category("Gain Filter")] 48 | [DisplayName("Gain")] 49 | public double Gain 50 | { 51 | get { return this._Gain; } 52 | set { this.SetField(ref this._Gain, value); } 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /DspSharp/Filter/LtiFilters/Primitive/InvertFilter.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System.Collections.Generic; 8 | using DspSharp.Algorithms; 9 | 10 | namespace DspSharp.Filter.LtiFilters.Primitive 11 | { 12 | /// 13 | /// A filter with a transfer function of -1. 14 | /// 15 | public class InvertFilter : FiniteFilter 16 | { 17 | public InvertFilter(double samplerate) : base(samplerate) 18 | { 19 | this.Name = "invert filter"; 20 | } 21 | 22 | /// 23 | /// Returns true. 24 | /// 25 | protected override bool HasEffectOverride => true; 26 | 27 | public override IEnumerable ProcessOverride(IEnumerable signal) 28 | { 29 | return signal.Negate(); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /DspSharp/Filter/LtiFilters/Primitive/ZeroFilter.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System.Collections.Generic; 8 | using System.Linq; 9 | 10 | namespace DspSharp.Filter.LtiFilters.Primitive 11 | { 12 | /// 13 | /// Represents a filter with a constant gain and no effects otherwise. 14 | /// 15 | public class ZeroFilter : FiniteFilter 16 | { 17 | public ZeroFilter(double samplerate) : base(samplerate) 18 | { 19 | this.Name = "Zero Filter"; 20 | } 21 | 22 | /// 23 | /// Returns true. 24 | /// 25 | protected override bool HasEffectOverride => true; 26 | 27 | public override IEnumerable ProcessOverride(IEnumerable signal) 28 | { 29 | return signal.Select(d => 0.0); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /DspSharp/Filter/NonlinearFilters/AwgnFilter.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System; 8 | using System.Collections.Generic; 9 | using DspSharp.Algorithms; 10 | using PropertyTools.DataAnnotations; 11 | 12 | namespace DspSharp.Filter.NonlinearFilters 13 | { 14 | /// 15 | /// Represents a filter that adds white Gaussian noise to a signal. 16 | /// 17 | /// 18 | public class AwgnFilter : FiniteFilter 19 | { 20 | private double _Sigma; 21 | private double _Variance; 22 | 23 | /// 24 | /// Initializes a new instance of the class. 25 | /// 26 | /// The samplerate. 27 | public AwgnFilter(double samplerate) : base(samplerate) 28 | { 29 | this.Variance = .1; 30 | } 31 | 32 | /// 33 | /// Specifies whether the filter object has an effect or not. 34 | /// 35 | protected override bool HasEffectOverride => true; 36 | 37 | /// 38 | /// Processes the specified sequence. 39 | /// 40 | /// The sequence. 41 | /// 42 | public override IEnumerable ProcessOverride(IEnumerable input) 43 | { 44 | return input.Add(SignalGenerators.WhiteNoise().Multiply(this.Sigma)); 45 | } 46 | 47 | [Category("Noise Configuration")] 48 | [DisplayName("Variance")] 49 | public double Variance 50 | { 51 | get { return this._Variance; } 52 | set 53 | { 54 | this.SetField(ref this._Variance, value); 55 | this._Sigma = Math.Sqrt(this.Variance); 56 | this.RaisePropertyChanged(nameof(this.Sigma)); 57 | } 58 | } 59 | 60 | [DisplayName("Sigma")] 61 | public double Sigma 62 | { 63 | get { return this._Sigma; } 64 | set 65 | { 66 | this.SetField(ref this._Sigma, value); 67 | this._Variance = Math.Pow(this.Sigma, 2); 68 | this.RaisePropertyChanged(nameof(this.Variance)); 69 | } 70 | } 71 | } 72 | } -------------------------------------------------------------------------------- /DspSharp/Filter/NonlinearFilters/CustomFilter.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System; 8 | using System.Collections.Generic; 9 | 10 | namespace DspSharp.Filter.NonlinearFilters 11 | { 12 | /// 13 | /// Represents a filter that is based on a custom filter function. 14 | /// 15 | /// 16 | public class CustomFilter : FilterBase 17 | { 18 | /// 19 | /// Initializes a new instance of the class. 20 | /// 21 | /// The samplerate. 22 | /// The filter function. 23 | public CustomFilter(double samplerate, Func, IEnumerable> filterFunction) 24 | : base(samplerate) 25 | { 26 | this.FilterFunction = filterFunction; 27 | } 28 | 29 | /// 30 | /// Gets the filter function. 31 | /// 32 | public Func, IEnumerable> FilterFunction { get; } 33 | 34 | /// 35 | /// Specifies whether the filter object has an effect or not. 36 | /// 37 | protected override bool HasEffectOverride => true; 38 | 39 | /// 40 | /// Processes the specified signal. 41 | /// 42 | /// The signal. 43 | /// 44 | /// The processed signal. 45 | /// 46 | public override IEnumerable ProcessOverride(IEnumerable signal) 47 | { 48 | return this.FilterFunction(signal); 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /DspSharp/Filter/NonlinearFilters/CustomFiniteFilter.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System; 8 | using System.Collections.Generic; 9 | 10 | namespace DspSharp.Filter.NonlinearFilters 11 | { 12 | /// 13 | /// Represents a filter that is based on a custom finite filter function. 14 | /// 15 | /// 16 | public class CustomFiniteFilter : FiniteFilter 17 | { 18 | /// 19 | /// Initializes a new instance of the class. 20 | /// 21 | /// The samplerate. 22 | /// The filter function. 23 | public CustomFiniteFilter(double samplerate, Func, IEnumerable> filterFunction) 24 | : base(samplerate) 25 | { 26 | this.FilterFunction = filterFunction; 27 | } 28 | 29 | /// 30 | /// Gets the filter function. 31 | /// 32 | public Func, IEnumerable> FilterFunction { get; } 33 | 34 | /// 35 | /// Specifies whether the filter object has an effect or not. 36 | /// 37 | protected override bool HasEffectOverride => true; 38 | 39 | /// 40 | /// Processes the specified sequence. 41 | /// 42 | /// The sequence. 43 | /// 44 | public override IEnumerable ProcessOverride(IEnumerable input) 45 | { 46 | return this.FilterFunction(input); 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /DspSharp/Filter/NonlinearFilters/DistortionFilter.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System; 8 | using System.Collections.Generic; 9 | using System.Linq; 10 | 11 | namespace DspSharp.Filter.NonlinearFilters 12 | { 13 | /// 14 | /// Represents a filter with non-linear distortions, useful for testing other algorithms. 15 | /// 16 | /// 17 | public class DistortionFilter : FiniteFilter 18 | { 19 | public DistortionFilter(double samplerate) : base(samplerate) 20 | { 21 | } 22 | 23 | /// 24 | /// Specifies whether the filter object has an effect or not. 25 | /// 26 | protected override bool HasEffectOverride => true; 27 | 28 | /// 29 | /// Processes the override. 30 | /// 31 | /// The signal. 32 | /// 33 | public override IEnumerable ProcessOverride(IEnumerable signal) 34 | { 35 | return signal.Select(d => d < 0 ? -Math.Log(1 - d) : Math.Log(1 + Math.Sqrt(d)) ); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /DspSharp/PropertyTools.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jonarw/DspSharp/f1b987ec1b5c21f572b9a1e409c661925f4d7455/DspSharp/PropertyTools.dll -------------------------------------------------------------------------------- /DspSharp/Series/ConstantSeries.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using DspSharp.Algorithms; 8 | 9 | namespace DspSharp.Series 10 | { 11 | /// 12 | /// Special kind of series that only has one point. Used for constant frequency 13 | /// responses. 14 | /// 15 | public class ConstantSeries : SeriesBase 16 | { 17 | /// 18 | /// Initializes a new instance of the class. 19 | /// 20 | /// The frequency at which the constant value should be evaluated. 21 | public ConstantSeries(double frequency = 1000) : base(frequency.ToEnumerable(), false) 22 | { 23 | this.Frequency = frequency; 24 | } 25 | 26 | /// 27 | /// Gets the frequency at which the constant value should be evaluated. 28 | /// 29 | public double Frequency { get; } 30 | 31 | public override int Length => 1; 32 | 33 | /// 34 | /// Compares the to an other for equality. 35 | /// 36 | /// The other . 37 | /// True if the other object is a not null and a , false otherwise. 38 | public override bool Equals(ISeries other) 39 | { 40 | if (other == null) 41 | return false; 42 | return this.Equals(other as ConstantSeries); 43 | } 44 | 45 | /// 46 | /// Compares the to an other . 47 | /// 48 | /// The other . 49 | /// True if the other is not null, false otherwise. 50 | public bool Equals(ConstantSeries other) 51 | { 52 | if (other == null) 53 | return false; 54 | 55 | if (other.Frequency != this.Frequency) 56 | return false; 57 | 58 | return true; 59 | } 60 | 61 | /// 62 | /// Computes the Hashcode for the . 63 | /// 64 | /// The Hashcode. 65 | public override int GetHashCode() 66 | { 67 | return this.Frequency.GetHashCode(); 68 | } 69 | } 70 | } -------------------------------------------------------------------------------- /DspSharp/Series/ISeries.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System; 8 | using System.Collections.Generic; 9 | 10 | namespace DspSharp.Series 11 | { 12 | /// 13 | /// Defines methods and properties used to interface a series of values. 14 | /// 15 | public interface ISeries : IEquatable 16 | { 17 | /// 18 | /// True for a logarithmic series. 19 | /// 20 | bool IsLogarithmic { get; } 21 | 22 | int Length { get; } 23 | 24 | IReadOnlyList Values { get; } 25 | 26 | /// 27 | /// Computes the Hashcode for the object. 28 | /// 29 | /// The Hashcode. 30 | int GetHashCode(); 31 | } 32 | } -------------------------------------------------------------------------------- /DspSharp/Series/SeriesBase.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System.Collections.Generic; 8 | using DspSharp.Algorithms; 9 | 10 | namespace DspSharp.Series 11 | { 12 | public abstract class SeriesBase : ISeries 13 | { 14 | protected SeriesBase(IEnumerable source, bool logarithmic) 15 | { 16 | this.Values = source.ToReadOnlyList(); 17 | this.IsLogarithmic = logarithmic; 18 | } 19 | 20 | public abstract bool Equals(ISeries other); 21 | 22 | public bool IsLogarithmic { get; } 23 | 24 | public abstract int Length { get; } 25 | 26 | public IReadOnlyList Values { get; } 27 | } 28 | } -------------------------------------------------------------------------------- /DspSharp/Series/SeriesUtil.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System.Linq; 8 | 9 | namespace DspSharp.Series 10 | { 11 | /// 12 | /// Provides methods for operating on objects. 13 | /// 14 | public sealed class SeriesUtil 15 | { 16 | /// 17 | /// Computes the union of two objects, which contains every value in either of the source series 18 | /// exactly once. 19 | /// 20 | /// The first source series. 21 | /// The second source series. 22 | /// A new object containing the result. 23 | public static ISeries Merge(ISeries s1, ISeries s2) 24 | { 25 | if (s1.Equals(s2)) 26 | return s1; 27 | var values = s1.Values.Union(s2.Values).OrderBy(m => m); 28 | 29 | return new CustomSeries(values, s1.IsLogarithmic && s2.IsLogarithmic); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /DspSharp/Signal/BaseImplementations/SignalBase.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System.Collections.Generic; 8 | using DspSharp.Algorithms; 9 | using DspSharp.Utilities; 10 | using PropertyTools.DataAnnotations; 11 | 12 | namespace DspSharp.Signal 13 | { 14 | /// 15 | /// Base class for all signals. 16 | /// 17 | /// 18 | /// 19 | public abstract class SignalBase : ISignal 20 | { 21 | /// 22 | /// Initializes a new instance of the class. 23 | /// 24 | /// The sample rate. 25 | protected SignalBase(double sampleRate) 26 | { 27 | this.SampleRate = sampleRate; 28 | } 29 | 30 | /// 31 | /// Gets a section of the signal in time domain. 32 | /// 33 | /// The start of the section. 34 | /// The length of the section. 35 | /// 36 | /// The specified section. 37 | /// 38 | public abstract IEnumerable GetWindowedSamples(int start, int length); 39 | 40 | public IFiniteSignal GetWindowedSignal(int start, int length) 41 | { 42 | return new FiniteSignal(this.GetWindowedSamples(start, length).ToReadOnlyList(), this.SampleRate); 43 | } 44 | 45 | [Category("general")] 46 | [DisplayName("display name")] 47 | public string DisplayName { get; set; } 48 | 49 | [DisplayName("sample rate")] 50 | public double SampleRate { get; } 51 | } 52 | } -------------------------------------------------------------------------------- /DspSharp/Signal/BaseImplementations/SyntheticSignal.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using DspSharp.Spectrum; 8 | 9 | namespace DspSharp.Signal 10 | { 11 | /// 12 | /// Represents a digital signal representable in time domain with a known and analytically calculable spectrum. 13 | /// 14 | /// 15 | /// 16 | public abstract class SyntheticSignal : InfiniteSignal, ISyntheticSignal 17 | { 18 | /// 19 | /// Initializes a new instance of the class. 20 | /// 21 | /// The sample function. 22 | /// The sample rate. 23 | protected SyntheticSignal(TimeDomainFunc sampleFunction, double sampleRate) : base(sampleFunction, sampleRate) 24 | { 25 | this.DisplayName = "synthetic signal"; 26 | } 27 | 28 | /// 29 | /// Initializes a new instance of the class. 30 | /// 31 | /// The time domain range function. 32 | /// The sample rate. 33 | protected SyntheticSignal(TimeDomainRangeFunc timeDomainFunction, double sampleRate) 34 | : base(timeDomainFunction, sampleRate) 35 | { 36 | this.DisplayName = "synthetic signal"; 37 | } 38 | 39 | /// 40 | /// Gets the spectrum. 41 | /// 42 | public abstract ISpectrum Spectrum { get; } 43 | } 44 | } -------------------------------------------------------------------------------- /DspSharp/Signal/Interfaces/IEnumerableSignal.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System.Collections.Generic; 8 | using DspSharp.Spectrum; 9 | 10 | namespace DspSharp.Signal 11 | { 12 | /// 13 | /// Describes a digital signal that is representable in time domain with a fixed starting time. The signal can still be 14 | /// infinitely long in the positive direction, but not in the negative direction. 15 | /// 16 | public interface IEnumerableSignal : ISignal 17 | { 18 | /// 19 | /// Gets the signal in time domain. 20 | /// 21 | IEnumerable Signal { get; } 22 | 23 | /// 24 | /// Gets the start time of the signal. 25 | /// 26 | int Start { get; } 27 | 28 | /// 29 | /// Computes the spectrum. 30 | /// 31 | /// Length of the FFT used to compute the spectrum. 32 | /// The spectrum. 33 | IFftSpectrum GetSpectrum(int fftLength); 34 | } 35 | } -------------------------------------------------------------------------------- /DspSharp/Signal/Interfaces/IFiniteSignal.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System.Collections.Generic; 8 | using DspSharp.Spectrum; 9 | 10 | namespace DspSharp.Signal 11 | { 12 | /// 13 | /// Describes a digital signal that is representable in time domain with a finite number of time samples. 14 | /// 15 | public interface IFiniteSignal : IEnumerableSignal 16 | { 17 | /// 18 | /// Gets the length. 19 | /// 20 | int Length { get; } 21 | 22 | /// 23 | /// Gets the signal. 24 | /// 25 | new IReadOnlyList Signal { get; } 26 | 27 | /// 28 | /// Gets the spectrum. 29 | /// 30 | IFftSpectrum Spectrum { get; } 31 | 32 | /// 33 | /// Gets the index of the sample following the last sample. 34 | /// 35 | int Stop { get; } 36 | 37 | /// 38 | /// Gets the sample at the specified time. 39 | /// 40 | /// The time. 41 | /// The sample. 42 | double GetSample(int time); 43 | } 44 | } -------------------------------------------------------------------------------- /DspSharp/Signal/Interfaces/ISignal.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System.Collections.Generic; 8 | 9 | namespace DspSharp.Signal 10 | { 11 | /// 12 | /// Describes an arbitrary digital signal representable in time domain. 13 | /// 14 | public interface ISignal 15 | { 16 | /// 17 | /// Gets or sets the name. 18 | /// 19 | string DisplayName { get; set; } 20 | 21 | /// 22 | /// Gets the sample rate. 23 | /// 24 | double SampleRate { get; } 25 | 26 | /// 27 | /// Gets a section of the signal in time domain. 28 | /// 29 | /// The start of the section. 30 | /// The length of the section. 31 | /// The specified section. 32 | IEnumerable GetWindowedSamples(int start, int length); 33 | 34 | /// 35 | /// Gets a section of the signal in time domain. 36 | /// 37 | /// The start of the section. 38 | /// The length of the section. 39 | /// The specified section. 40 | IFiniteSignal GetWindowedSignal(int start, int length); 41 | } 42 | } -------------------------------------------------------------------------------- /DspSharp/Signal/Interfaces/ISyntheticSignal.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using DspSharp.Spectrum; 8 | 9 | namespace DspSharp.Signal 10 | { 11 | /// 12 | /// Describes a digital signal representable in time domain with a known and analytically calculable spectrum. 13 | /// 14 | public interface ISyntheticSignal : ISignal 15 | { 16 | /// 17 | /// Gets the spectrum. 18 | /// 19 | ISpectrum Spectrum { get; } 20 | } 21 | } -------------------------------------------------------------------------------- /DspSharp/Signal/SignalTypes/Dirac.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using DspSharp.Algorithms; 8 | using PropertyTools.DataAnnotations; 9 | 10 | namespace DspSharp.Signal 11 | { 12 | /// 13 | /// Represents a scaled dirac pulse. 14 | /// 15 | public class Dirac : FiniteSignal 16 | { 17 | /// 18 | /// Initializes a new instance of the class. 19 | /// 20 | /// The sample rate. 21 | /// The gain. 22 | public Dirac(double sampleRate, double gain = 1) : base(new[] {gain}.ToReadOnlyList(), sampleRate) 23 | { 24 | this.Gain = gain; 25 | this.DisplayName = "dirac, gain = " + gain; 26 | } 27 | 28 | [Category("dirac")] 29 | [DisplayName("gain")] 30 | public double Gain { get; } 31 | } 32 | } -------------------------------------------------------------------------------- /DspSharp/Signal/SignalTypes/IdealHighpass.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System; 8 | using System.Numerics; 9 | using DspSharp.Algorithms; 10 | using DspSharp.Series; 11 | using DspSharp.Spectrum; 12 | using PropertyTools.DataAnnotations; 13 | 14 | namespace DspSharp.Signal 15 | { 16 | /// 17 | /// Represents an ideal sinc-based highpass. 18 | /// 19 | /// 20 | public class IdealHighpass : SyntheticSignal 21 | { 22 | /// 23 | /// Initializes a new instance of the class. 24 | /// 25 | /// The sample rate. 26 | /// The corner frequency. 27 | /// 28 | public IdealHighpass(double sampleRate, double fc) 29 | : base(time => (time == 0 ? 1.0 : 0.0) - Mathematic.Sinc(2 * fc * time / sampleRate) * (2 * fc / sampleRate), sampleRate 30 | ) 31 | { 32 | if ((fc < 0) || (fc > sampleRate / 2)) 33 | throw new Exception(); 34 | 35 | this.Fc = fc; 36 | var frequencies = new CustomSeries(new[] {0, 20, fc, fc, sampleRate / 2}); 37 | this.Spectrum = new Spectrum.Spectrum(frequencies, new Complex[] {0, 0, 0, 1, 1}); 38 | this.DisplayName = "ideal highpass, fc = " + fc; 39 | } 40 | 41 | /// 42 | /// Gets the spectrum. 43 | /// 44 | public override ISpectrum Spectrum { get; } 45 | 46 | [Category("ideal highpass")] 47 | [DisplayName("cutoff frequency")] 48 | public double Fc { get; } 49 | } 50 | } -------------------------------------------------------------------------------- /DspSharp/Signal/SignalTypes/IdealLowpass.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System; 8 | using System.Numerics; 9 | using DspSharp.Algorithms; 10 | using DspSharp.Series; 11 | using DspSharp.Spectrum; 12 | using PropertyTools.DataAnnotations; 13 | 14 | namespace DspSharp.Signal 15 | { 16 | /// 17 | /// Represents an ideal sinc-based Lowpass. 18 | /// 19 | /// 20 | public class IdealLowpass : SyntheticSignal 21 | { 22 | /// 23 | /// Initializes a new instance of the class. 24 | /// 25 | /// The sample rate. 26 | /// The corner frequency. 27 | /// 28 | public IdealLowpass(double sampleRate, double fc) 29 | : base(time => Mathematic.Sinc(2 * fc * time / sampleRate) * (2 * fc / sampleRate), sampleRate) 30 | { 31 | if ((fc < 0) || (fc > sampleRate / 2)) 32 | throw new Exception(); 33 | 34 | this.Fc = fc; 35 | var frequencies = new CustomSeries(new[] {0, 20, fc, fc, sampleRate / 2}); 36 | this.Spectrum = new Spectrum.Spectrum(frequencies, new Complex[] {1, 1, 1, 0, 0}); 37 | this.DisplayName = "ideal lowpass, fc = " + fc; 38 | } 39 | 40 | /// 41 | /// Gets the spectrum. 42 | /// 43 | public override ISpectrum Spectrum { get; } 44 | 45 | [Category("ideal lowpass")] 46 | [DisplayName("cutoff frequency")] 47 | public double Fc { get; } 48 | } 49 | } -------------------------------------------------------------------------------- /DspSharp/Signal/SignalTypes/LogSweep.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using DspSharp.Algorithms; 8 | using PropertyTools.DataAnnotations; 9 | 10 | namespace DspSharp.Signal 11 | { 12 | /// 13 | /// Represents a logarithmic sine sweep. 14 | /// 15 | public class LogSweep : FiniteSignal 16 | { 17 | /// 18 | /// Initializes a new instance of the Class. 19 | /// 20 | /// The start frequency. 21 | /// The stop frequency. 22 | /// The length in seconds. 23 | /// The samplerate. 24 | public LogSweep(double from, double to, double length, double samplerate) 25 | : base(SignalGenerators.LogSweep(from, to, length, samplerate).ToReadOnlyList(), samplerate) 26 | { 27 | this.From = from; 28 | this.To = to; 29 | this.DisplayName = "logarithmic sweep"; 30 | } 31 | 32 | [Category("logarithmic sweep")] 33 | [DisplayName("start frequency")] 34 | public double From { get; } 35 | 36 | [DisplayName("stop frequency")] 37 | public double To { get; } 38 | } 39 | } -------------------------------------------------------------------------------- /DspSharp/Signal/SignalTypes/Sinc.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System; 8 | using System.Numerics; 9 | using DspSharp.Algorithms; 10 | using DspSharp.Series; 11 | using DspSharp.Spectrum; 12 | using PropertyTools.DataAnnotations; 13 | 14 | namespace DspSharp.Signal 15 | { 16 | /// 17 | /// Represents a Sinc (sin(pi*x) / (pi*x)) pulse. 18 | /// 19 | /// 20 | public class Sinc : SyntheticSignal 21 | { 22 | /// 23 | /// Initializes a new instance of the class. 24 | /// 25 | /// The sample rate. 26 | /// The frequency. 27 | /// 28 | public Sinc(double sampleRate, double frequency) 29 | : base(time => Mathematic.Sinc(frequency * time / sampleRate), sampleRate) 30 | { 31 | this.Frequency = frequency; 32 | if ((frequency < 0) || (frequency > sampleRate / 2)) 33 | throw new Exception(); 34 | 35 | var frequencies = new CustomSeries(new[] {0, frequency, frequency, sampleRate / 2}); 36 | this.Spectrum = new Spectrum.Spectrum(frequencies, new Complex[] {1 / (2 * frequency), 1 / (2 * frequency), 0, 0}); 37 | this.DisplayName = "sinc, f = " + frequency; 38 | } 39 | 40 | /// 41 | /// Gets the spectrum. 42 | /// 43 | public override ISpectrum Spectrum { get; } 44 | 45 | [Category("sinc")] 46 | [DisplayName("frequency")] 47 | public double Frequency { get; } 48 | } 49 | } -------------------------------------------------------------------------------- /DspSharp/Signal/SignalTypes/Sinus.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System; 8 | using System.Numerics; 9 | using DspSharp.Series; 10 | using DspSharp.Spectrum; 11 | using PropertyTools.DataAnnotations; 12 | 13 | namespace DspSharp.Signal 14 | { 15 | /// 16 | /// Represents a sine wave. 17 | /// 18 | /// 19 | public class Sinus : SyntheticSignal 20 | { 21 | /// 22 | /// Initializes a new instance of the class. 23 | /// 24 | /// The sample rate. 25 | /// The frequency. 26 | /// The phase offset in radians. 27 | /// 28 | public Sinus(double sampleRate, double frequency, double phaseOffset = 0) 29 | : base(time => Math.Sin(2 * Math.PI * time * frequency / sampleRate + phaseOffset), sampleRate) 30 | { 31 | this.Frequency = frequency; 32 | this.PhaseOffset = phaseOffset; 33 | if ((frequency < 0) || (frequency > sampleRate / 2)) 34 | throw new Exception(); 35 | 36 | var frequencies = new CustomSeries(new[] {0, frequency, frequency, frequency, sampleRate / 2}); 37 | this.Spectrum = new Spectrum.Spectrum(frequencies, new Complex[] {0, 0, double.PositiveInfinity, 0, 0}); 38 | this.DisplayName = "sinus, f = " + frequency; 39 | } 40 | 41 | /// 42 | /// Gets the spectrum. 43 | /// 44 | public override ISpectrum Spectrum { get; } 45 | 46 | [Category("sinus")] 47 | [DisplayName("frequency")] 48 | public double Frequency { get; } 49 | 50 | [DisplayName("phase offset")] 51 | public double PhaseOffset { get; } 52 | } 53 | } -------------------------------------------------------------------------------- /DspSharp/Signal/Windows/WindowModes.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System.ComponentModel; 8 | 9 | namespace DspSharp.Signal.Windows 10 | { 11 | /// 12 | /// Enumerates the available window modes. 13 | /// 14 | public enum WindowModes 15 | { 16 | /// 17 | /// Symmetric window (starting with 0, then rising towards 1, then declining towards 0) 18 | /// 19 | [Description("symmetric")] Symmetric, 20 | 21 | /// 22 | /// Causal window (starting with 1, then declining). 23 | /// 24 | [Description("causal")] Causal, 25 | 26 | /// 27 | /// Anti-causal window (starting with 0, then rising towards 1) 28 | /// 29 | [Description("anti-causal")] AntiCausal 30 | } 31 | } -------------------------------------------------------------------------------- /DspSharp/Signal/Windows/WindowTypes.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System.ComponentModel; 8 | 9 | namespace DspSharp.Signal.Windows 10 | { 11 | /// 12 | /// Enumeration of all supported window types. 13 | /// 14 | public enum WindowTypes 15 | { 16 | /// 17 | /// The rectangular window. 18 | /// 19 | [Description("rectangular")] Rectangular, 20 | 21 | /// 22 | /// The Hann window. 23 | /// 24 | [Description("Hann")] Hann, 25 | 26 | /// 27 | /// The Hamming window. 28 | /// 29 | [Description("Hamming")] Hamming, 30 | 31 | /// 32 | /// The triangular window. 33 | /// 34 | [Description("triangular")] Triangular, 35 | 36 | /// 37 | /// The Welch window. 38 | /// 39 | [Description("Welch")] Welch, 40 | 41 | /// 42 | /// The Blackman window. 43 | /// 44 | [Description("Blackman")] Blackman, 45 | 46 | /// 47 | /// The Blackman-Harris window. 48 | /// 49 | [Description("Blackman-Harris")] BlackmanHarris, 50 | 51 | /// 52 | /// The Kaiser window with alpha=2. 53 | /// 54 | [Description("Kaiser, alpha = 2")] KaiserAlpha2, 55 | 56 | /// 57 | /// The Kaiser window with alpha=3. 58 | /// 59 | [Description("Kaiser, alpha = 3")] KaiserAlpha3 60 | } 61 | } -------------------------------------------------------------------------------- /DspSharp/Spectrum/IFftSpectrum.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System.Collections.Generic; 8 | using DspSharp.Series; 9 | 10 | namespace DspSharp.Spectrum 11 | { 12 | public interface IFftSpectrum : ISpectrum 13 | { 14 | new FftSeries Frequencies { get; } 15 | IReadOnlyList GetTimeDomainSignal(); 16 | } 17 | } -------------------------------------------------------------------------------- /DspSharp/Spectrum/ISpectrum.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System.Collections.Generic; 8 | using System.Numerics; 9 | using DspSharp.Series; 10 | 11 | namespace DspSharp.Spectrum 12 | { 13 | /// 14 | /// Describes the spectrum of a digital signal. 15 | /// 16 | public interface ISpectrum 17 | { 18 | /// 19 | /// Gets the frequencies where the spectrum is defined. 20 | /// 21 | ISeries Frequencies { get; } 22 | 23 | /// 24 | /// Gets the group delay. 25 | /// 26 | IReadOnlyList GroupDelay { get; } 27 | 28 | /// 29 | /// Gets the magnitude. 30 | /// 31 | IReadOnlyList Magnitude { get; } 32 | 33 | /// 34 | /// Gets the phase. 35 | /// 36 | IReadOnlyList Phase { get; } 37 | 38 | /// 39 | /// Gets the complex values. 40 | /// 41 | IReadOnlyList Values { get; } 42 | 43 | /// 44 | /// Gets the value at the specified frequency. 45 | /// 46 | /// The frequency. 47 | /// 48 | Complex GetValue(double frequency); 49 | } 50 | } -------------------------------------------------------------------------------- /DspSharp/Utilities/Collections/Extensions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | 4 | namespace DspSharp.Utilities.Collections 5 | { 6 | public static class Extensions 7 | { 8 | private static readonly IDictionary> OfTypeDictionary = 9 | new Dictionary>(); 10 | 11 | public static int IndexOf(this IEnumerable enumerable, T element, IEqualityComparer comparer = null) 12 | { 13 | int i = 0; 14 | comparer = comparer ?? EqualityComparer.Default; 15 | foreach (var currentElement in enumerable) 16 | { 17 | if (comparer.Equals(currentElement, element)) 18 | return i; 19 | 20 | i++; 21 | } 22 | 23 | return -1; 24 | } 25 | 26 | public static IObservableList OfTypeObservable(this IObservableList source) 27 | { 28 | IList typelist; 29 | if (OfTypeDictionary.ContainsKey(source)) 30 | typelist = OfTypeDictionary[source]; 31 | else 32 | { 33 | typelist = new List(); 34 | OfTypeDictionary.Add(source, typelist); 35 | } 36 | 37 | var list = typelist.OfType>().FirstOrDefault(); 38 | if (list != null) 39 | return list; 40 | 41 | var ret = new ObservableList(); 42 | source.CollectionChanged += (sender, e) => ret.Reset(source.OfType()); 43 | ret.Reset(source.OfType()); 44 | typelist.Add(ret); 45 | return ret; 46 | } 47 | 48 | public static IReadOnlyObservableList ToReadOnlyObservableList(this IObservableList input) 49 | { 50 | return new ReadOnlyObservableList(input); 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /DspSharp/Utilities/Collections/IObservableList.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using System.Collections.Specialized; 4 | using System.ComponentModel; 5 | 6 | namespace DspSharp.Utilities.Collections 7 | { 8 | public interface IObservableList : IList, INotifyCollectionChanged, INotifyPropertyChanged 9 | { 10 | } 11 | 12 | /// 13 | /// Describes an observable list. 14 | /// 15 | /// 16 | /// 17 | /// 18 | /// 19 | public interface IObservableList : IList, INotifyPropertyChanged, INotifyCollectionChanged 20 | { 21 | /// 22 | /// Adds the range of specified items. 23 | /// 24 | /// The items. 25 | void AddRange(IEnumerable items); 26 | 27 | /// 28 | /// Occurs when a property of an item in the collection has changed. 29 | /// 30 | event PropertyChangedEventHandler ItemPropertyChanged; 31 | 32 | /// 33 | /// Moves an item to the specified index. 34 | /// 35 | /// The item. 36 | /// The new index of the item after moving. 37 | void MoveItem(T item, int newIndex); 38 | 39 | /// 40 | /// Removes the range of specified items. 41 | /// 42 | /// The items. 43 | void RemoveRange(IEnumerable items); 44 | 45 | /// 46 | /// Resets the the list with the specified new items. 47 | /// 48 | /// The new items. 49 | void Reset(IEnumerable newItems); 50 | } 51 | } -------------------------------------------------------------------------------- /DspSharp/Utilities/Collections/IReadOnlyObservableList.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Collections.Specialized; 3 | using System.ComponentModel; 4 | 5 | namespace DspSharp.Utilities.Collections 6 | { 7 | public interface IReadOnlyObservableList : IReadOnlyList, INotifyPropertyChanged, INotifyCollectionChanged 8 | { 9 | /// 10 | /// Occurs when a property of an item in the collection has changed. 11 | /// 12 | event PropertyChangedEventHandler ItemPropertyChanged; 13 | } 14 | } -------------------------------------------------------------------------------- /DspSharp/Utilities/Collections/ISortedObservableList.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace DspSharp.Utilities.Collections 5 | { 6 | public interface ISortedObservableList : IObservableList 7 | { 8 | IComparer Comparer { get; } 9 | Func KeyFunction { get; } 10 | //void Remove(TValue item); 11 | //void Add(TValue item); 12 | //void AddRange(IEnumerable items); 13 | //void RemoveRange(IEnumerable items); 14 | //void Reset(IEnumerable items); 15 | //void Clear(); 16 | } 17 | } -------------------------------------------------------------------------------- /DspSharp/Utilities/Collections/ReadOnlyObservableList.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using System.Collections.Specialized; 4 | using System.ComponentModel; 5 | 6 | namespace DspSharp.Utilities.Collections 7 | { 8 | public class ReadOnlyObservableList : IReadOnlyObservableList 9 | { 10 | public ReadOnlyObservableList(IObservableList list) 11 | { 12 | this.List = list; 13 | } 14 | 15 | private IObservableList List { get; } 16 | 17 | IEnumerator IEnumerable.GetEnumerator() 18 | { 19 | return ((IEnumerable)this.List).GetEnumerator(); 20 | } 21 | 22 | public IEnumerator GetEnumerator() 23 | { 24 | return this.List.GetEnumerator(); 25 | } 26 | 27 | public event NotifyCollectionChangedEventHandler CollectionChanged 28 | { 29 | add => this.List.CollectionChanged += value; 30 | remove => this.List.CollectionChanged -= value; 31 | } 32 | 33 | public event PropertyChangedEventHandler PropertyChanged 34 | { 35 | add => this.List.PropertyChanged += value; 36 | remove => this.List.PropertyChanged -= value; 37 | } 38 | 39 | public int Count => this.List.Count; 40 | 41 | public T this[int index] => this.List[index]; 42 | 43 | public event PropertyChangedEventHandler ItemPropertyChanged 44 | { 45 | add => this.List.ItemPropertyChanged += value; 46 | remove => this.List.ItemPropertyChanged -= value; 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /DspSharpAsio/Asio64Bit.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 NAudio contributors, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System.Runtime.InteropServices; 8 | 9 | namespace DspSharpAsio 10 | { 11 | /// 12 | /// ASIO 64 bit value 13 | /// Unfortunately the ASIO API was implemented it before compiler supported consistently 64 bit 14 | /// integer types. By using the structure the data layout on a little-endian system like the 15 | /// Intel x86 architecture will result in a "non native" storage of the 64 bit data. The most 16 | /// significant 32 bit are stored first in memory, the least significant bits are stored in the 17 | /// higher memory space. However each 32 bit is stored in the native little-endian fashion 18 | /// 19 | [StructLayout(LayoutKind.Sequential, Pack = 4)] 20 | public struct Asio64Bit 21 | { 22 | /// 23 | /// most significant bits (Bits 32..63) 24 | /// 25 | public uint hi; 26 | 27 | /// 28 | /// least significant bits (Bits 0..31) 29 | /// 30 | public uint lo; 31 | 32 | // TODO: IMPLEMENT AN EASY WAY TO CONVERT THIS TO double AND long 33 | } 34 | } -------------------------------------------------------------------------------- /DspSharpAsio/AsioChannelInfo.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 NAudio contributors, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System.Runtime.InteropServices; 8 | 9 | namespace DspSharpAsio 10 | { 11 | /// 12 | /// ASIO Channel Info 13 | /// 14 | [StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Ansi)] 15 | public struct AsioChannelInfo 16 | { 17 | /// 18 | /// on input, channel index 19 | /// 20 | public int channel; 21 | 22 | /// 23 | /// Is Input 24 | /// 25 | public bool isInput; 26 | 27 | /// 28 | /// Is Active 29 | /// 30 | public bool isActive; 31 | 32 | /// 33 | /// Channel Info 34 | /// 35 | public int channelGroup; 36 | 37 | /// 38 | /// ASIO Sample Type 39 | /// 40 | [MarshalAs(UnmanagedType.U4)] public AsioSampleType type; 41 | 42 | /// 43 | /// Name 44 | /// 45 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string name; 46 | } 47 | } -------------------------------------------------------------------------------- /DspSharpAsio/AsioDriverCapability.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 NAudio contributors, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | namespace DspSharpAsio 8 | { 9 | /// 10 | /// ASIODriverCapability holds all the information from the AsioDriver. 11 | /// Use ASIODriverExt to get the Capabilities 12 | /// 13 | public class AsioDriverCapability 14 | { 15 | /// 16 | /// Buffer Granularity 17 | /// 18 | public int BufferGranularity; 19 | 20 | /// 21 | /// Buffer Maximum Size 22 | /// 23 | public int BufferMaxSize; 24 | 25 | /// 26 | /// Buffer Minimum Size 27 | /// 28 | public int BufferMinSize; 29 | 30 | /// 31 | /// Buffer Preferred Size 32 | /// 33 | public int BufferPreferredSize; 34 | 35 | /// 36 | /// Drive Name 37 | /// 38 | public string DriverName; 39 | 40 | /// 41 | /// Input Channel Info 42 | /// 43 | public AsioChannelInfo[] InputChannelInfos; 44 | 45 | /// 46 | /// Input Latency 47 | /// 48 | public int InputLatency; 49 | 50 | /// 51 | /// Number of Input Channels 52 | /// 53 | public int NbInputChannels; 54 | 55 | /// 56 | /// Number of Output Channels 57 | /// 58 | public int NbOutputChannels; 59 | 60 | /// 61 | /// Output Channel Info 62 | /// 63 | public AsioChannelInfo[] OutputChannelInfos; 64 | 65 | /// 66 | /// Output Latency 67 | /// 68 | public int OutputLatency; 69 | 70 | /// 71 | /// Sample Rate 72 | /// 73 | public double SampleRate; 74 | } 75 | } -------------------------------------------------------------------------------- /DspSharpAsio/AsioDriverExt.cd: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 26 | 27 | AABARDAAUGAAAAADCAACAAACYAhBgAIQIACACAAAAAE= 28 | ASIODriverExt.cs 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /DspSharpAsio/AsioError.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 NAudio contributors, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | namespace DspSharpAsio 8 | { 9 | /// 10 | /// ASIO Error Codes 11 | /// 12 | public enum AsioError 13 | { 14 | /// 15 | /// This value will be returned whenever the call succeeded 16 | /// 17 | ASE_OK = 0, 18 | 19 | /// 20 | /// unique success return value for ASIOFuture calls 21 | /// 22 | ASE_SUCCESS = 0x3f4847a0, 23 | 24 | /// 25 | /// hardware input or output is not present or available 26 | /// 27 | ASE_NotPresent = -1000, 28 | 29 | /// 30 | /// hardware is malfunctioning (can be returned by any ASIO function) 31 | /// 32 | ASE_HWMalfunction, 33 | 34 | /// 35 | /// input parameter invalid 36 | /// 37 | ASE_InvalidParameter, 38 | 39 | /// 40 | /// hardware is in a bad mode or used in a bad mode 41 | /// 42 | ASE_InvalidMode, 43 | 44 | /// 45 | /// hardware is not running when sample position is inquired 46 | /// 47 | ASE_SPNotAdvancing, 48 | 49 | /// 50 | /// sample clock or rate cannot be determined or is not present 51 | /// 52 | ASE_NoClock, 53 | 54 | /// 55 | /// not enough memory for completing the request 56 | /// 57 | ASE_NoMemory 58 | } 59 | } -------------------------------------------------------------------------------- /DspSharpAsio/AsioFillBufferCallback.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 NAudio contributors, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System; 8 | 9 | namespace DspSharpAsio 10 | { 11 | /// 12 | /// Callback used by the AsioDriverExt to get wave data 13 | /// 14 | public delegate void AsioFillBufferCallback(IntPtr[] inputChannels, IntPtr[] outputChannels); 15 | } -------------------------------------------------------------------------------- /DspSharpAsio/AsioMessageSelector.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 NAudio contributors, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | namespace DspSharpAsio 8 | { 9 | /// 10 | /// ASIO Message Selector 11 | /// 12 | public enum AsioMessageSelector 13 | { 14 | /// 15 | /// selector in <value>, returns 1L if supported, 16 | /// 17 | kAsioSelectorSupported = 1, 18 | 19 | /// 20 | /// returns engine (host) asio implementation version, 21 | /// 22 | kAsioEngineVersion, 23 | 24 | /// 25 | /// request driver reset. if accepted, this 26 | /// 27 | kAsioResetRequest, 28 | 29 | /// 30 | /// not yet supported, will currently always return 0L. 31 | /// 32 | kAsioBufferSizeChange, 33 | 34 | /// 35 | /// the driver went out of sync, such that 36 | /// 37 | kAsioResyncRequest, 38 | 39 | /// 40 | /// the drivers latencies have changed. The engine 41 | /// 42 | kAsioLatenciesChanged, 43 | 44 | /// 45 | /// if host returns true here, it will expect the 46 | /// 47 | kAsioSupportsTimeInfo, 48 | 49 | /// 50 | /// supports timecode 51 | /// 52 | kAsioSupportsTimeCode, 53 | 54 | /// 55 | /// unused - value: number of commands, message points to mmc commands 56 | /// 57 | kAsioMMCCommand, 58 | 59 | /// 60 | /// kAsioSupportsXXX return 1 if host supports this 61 | /// 62 | kAsioSupportsInputMonitor, 63 | 64 | /// 65 | /// unused and undefined 66 | /// 67 | kAsioSupportsInputGain, 68 | 69 | /// 70 | /// unused and undefined 71 | /// 72 | kAsioSupportsInputMeter, 73 | 74 | /// 75 | /// unused and undefined 76 | /// 77 | kAsioSupportsOutputGain, 78 | 79 | /// 80 | /// unused and undefined 81 | /// 82 | kAsioSupportsOutputMeter, 83 | 84 | /// 85 | /// driver detected an overload 86 | /// 87 | kAsioOverload 88 | } 89 | } -------------------------------------------------------------------------------- /DspSharpAsio/DspSharpAsio.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net45;net46 5 | True 6 | 0.1.0-pre 7 | Jonathan Arweck 8 | 9 | DspSharpAsio - ASIO Support for DspSharp 10 | © 2017 Jonathan Arweck 11 | https://github.com/Jonarw/DspSharp/blob/dev/LICENSE.txt 12 | https://github.com/Jonarw/DspSharp/ 13 | audio signal processing dsp filter fir iir asio 14 | 15 | 16 | 17 | True 18 | 0.1.0.0 19 | 0.1.0.0 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /DspSharpAsio/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System.Runtime.InteropServices; 8 | 9 | // Setting ComVisible to false makes the types in this assembly not visible 10 | // to COM components. If you need to access a type in this assembly from 11 | // COM, set the ComVisible attribute to true on that type. 12 | 13 | [assembly: ComVisible(false)] 14 | 15 | // The following GUID is for the ID of the typelib if this project is exposed to COM 16 | 17 | [assembly: Guid("8420c3e2-ca65-44a1-bbc7-f259751fae9c")] 18 | 19 | -------------------------------------------------------------------------------- /DspSharpAsio/SampleTypeConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace DspSharpAsio 5 | { 6 | public static class AsioSampleTypeExtensions 7 | { 8 | public static int GetSize(this AsioSampleType sampleType) 9 | { 10 | return SampleTypeConverter.SizeOf(sampleType); 11 | } 12 | } 13 | 14 | public static unsafe class SampleTypeConverter 15 | { 16 | public static IReadOnlyList SupportedSampleFormats { get; } = 17 | new List {AsioSampleType.Int32LSB, AsioSampleType.Float32LSB}.AsReadOnly(); 18 | 19 | public static int SizeOf(AsioSampleType sampleType) 20 | { 21 | if (sampleType == AsioSampleType.Int32LSB) 22 | return sizeof(int); 23 | if (sampleType == AsioSampleType.Float32LSB) 24 | return sizeof(float); 25 | 26 | throw new NotSupportedException(); 27 | } 28 | 29 | public static void ConvertFrom(AsioSampleType sampleType, void* input, double* output, int length) 30 | { 31 | if (sampleType == AsioSampleType.Int32LSB) 32 | { 33 | var intinput = (int*)input; 34 | 35 | for (int i = 0; i < length; i++) 36 | { 37 | *(output + i) = *(intinput + i) / 2147483648d; 38 | } 39 | } 40 | else if (sampleType == AsioSampleType.Float32LSB) 41 | { 42 | var floatinput = (float*)input; 43 | 44 | for (int i = 0; i < length; i++) 45 | { 46 | output[i] = floatinput[i]; 47 | } 48 | } 49 | else 50 | throw new NotSupportedException(); 51 | 52 | } 53 | 54 | public static void ConvertTo(AsioSampleType sampleType, double* input, void* output, int length) 55 | { 56 | if (sampleType == AsioSampleType.Int32LSB) 57 | { 58 | var intoutput = (int*)output; 59 | 60 | for (int i = 0; i < length; i++) 61 | { 62 | *(intoutput + i) = (int)(Math.Max(Math.Min(*(input + i), 8388607.0d / 8388608.0d), -1) * 2147483648d); 63 | } 64 | } 65 | else if (sampleType == AsioSampleType.Float32LSB) 66 | { 67 | var floatoutput = (float*)output; 68 | 69 | for (int i = 0; i < length; i++) 70 | { 71 | floatoutput[i] = (float)input[i]; 72 | } 73 | } 74 | else 75 | throw new NotSupportedException(); 76 | 77 | } 78 | } 79 | } -------------------------------------------------------------------------------- /DspSharpDemo/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /DspSharpDemo/App.xaml: -------------------------------------------------------------------------------- 1 |  5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /DspSharpDemo/App.xaml.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System.Windows; 8 | 9 | namespace DspSharpDemo 10 | { 11 | /// 12 | /// Interaction logic for App.xaml 13 | /// 14 | public partial class App : Application 15 | { 16 | } 17 | } -------------------------------------------------------------------------------- /DspSharpDemo/EnumCombo.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System; 8 | using System.Linq; 9 | using System.Windows; 10 | using System.Windows.Controls; 11 | 12 | namespace DspSharpDemo 13 | { 14 | /// 15 | /// Enhanced ComboBox for displaying quantities in various units. 16 | /// 17 | /// 18 | public class EnumCombo : ComboBox 19 | { 20 | /// 21 | /// The value property. 22 | /// 23 | public static readonly DependencyProperty EnumProperty = DependencyProperty.Register( 24 | "Enum", 25 | typeof(Type), 26 | typeof(EnumCombo), 27 | new FrameworkPropertyMetadata( 28 | null, 29 | FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, 30 | EnumPropertyChanged)); 31 | 32 | /// 33 | /// Gets the available units. 34 | /// 35 | public Type Enum 36 | { 37 | get { return (Type)this.GetValue(EnumProperty); } 38 | set { this.SetValue(EnumProperty, value); } 39 | } 40 | 41 | private static void EnumPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 42 | { 43 | var ec = (EnumCombo)d; 44 | var value = (Type)e.NewValue; 45 | if (value == null) 46 | { 47 | ec.ItemsSource = Enumerable.Empty(); 48 | return; 49 | } 50 | 51 | ec.ItemsSource = System.Enum.GetValues(value).Cast().Select(en => new EnumItem(EnumToStringConverter.GetEnumDescription(en), en)); 52 | ec.DisplayMemberPath = "DisplayName"; 53 | ec.SelectedValuePath = "Enum"; 54 | } 55 | 56 | public struct EnumItem 57 | { 58 | public EnumItem(string displayName, Enum @enum) 59 | { 60 | this.DisplayName = displayName; 61 | this.Enum = @enum; 62 | } 63 | 64 | public string DisplayName { get; } 65 | public Enum Enum { get; } 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /DspSharpDemo/EnumToStringConverter.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System; 8 | using System.ComponentModel; 9 | using System.Globalization; 10 | using System.Linq; 11 | using System.Reflection; 12 | using DspSharp.Algorithms; 13 | 14 | namespace DspSharpDemo 15 | { 16 | public class EnumToStringConverter : TypeConverter 17 | { 18 | public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) 19 | { 20 | return sourceType == typeof(Enum); 21 | } 22 | 23 | public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) 24 | { 25 | return destinationType == typeof(string); 26 | } 27 | 28 | public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) 29 | { 30 | if (!(destinationType == typeof(string))) 31 | throw new ArgumentException("Can only convert to string.", nameof(destinationType)); 32 | 33 | if (!value.GetType().IsEnum) 34 | throw new ArgumentException("Can only convert an instance of Enum.", nameof(value)); 35 | 36 | return GetEnumDescription((Enum)value); 37 | } 38 | 39 | public static string GetEnumDescription(Enum value) 40 | { 41 | FieldInfo fi = value.GetType().GetField(value.ToString()); 42 | 43 | var attributes = fi.GetCustomAttributes(false); 44 | var d1 = attributes.OfType().ToReadOnlyList(); 45 | 46 | if (d1.Count > 0) 47 | return d1[0].Description; 48 | 49 | var d2 = attributes.OfType().ToReadOnlyList(); 50 | 51 | if (d2.Count > 0) 52 | return d2[0].Description; 53 | 54 | return value.ToString(); 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /DspSharpDemo/IListItemConverter.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | namespace DspSharpDemo 8 | { 9 | /// 10 | /// Converts items in the Master list to Items in the target list, and back again. 11 | /// 12 | public interface IListItemConverter 13 | { 14 | /// 15 | /// Converts the specified master list item. 16 | /// 17 | /// The master list item. 18 | /// The result of the conversion. 19 | object Convert(object masterListItem); 20 | 21 | /// 22 | /// Converts the specified target list item. 23 | /// 24 | /// The target list item. 25 | /// The result of the conversion. 26 | object ConvertBack(object targetListItem); 27 | } 28 | } -------------------------------------------------------------------------------- /DspSharpDemo/LocalPropertyGridControlFactory.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System.Collections.ObjectModel; 8 | using System.Windows; 9 | using System.Windows.Controls; 10 | using System.Windows.Controls.Primitives; 11 | using System.Windows.Input; 12 | using PropertyTools.Wpf; 13 | 14 | namespace DspSharpDemo 15 | { 16 | /// 17 | /// Slightly adapted PropertyControlFactory that creates appropriate controls for enums. 18 | /// 19 | public class LocalPropertyGridControlFactory : PropertyGridControlFactory 20 | { 21 | public override FrameworkElement CreateControl(PropertyItem pi, PropertyControlFactoryOptions options) 22 | { 23 | if ((pi.ItemsSourceDescriptor != null) || (pi.ItemsSource != null)) 24 | return this.CreateComboBoxControl(pi); 25 | 26 | if (pi.Is(typeof(Collection))) 27 | return this.CreateListControl(pi); 28 | 29 | if (pi.Is(typeof(ICommand))) 30 | return this.CreateCommandControl(pi); 31 | 32 | return base.CreateControl(pi, options); 33 | } 34 | 35 | protected virtual FrameworkElement CreateCommandControl(PropertyItem property) 36 | { 37 | var c = new Button(); 38 | c.SetBinding(ButtonBase.CommandProperty, property.CreateBinding()); 39 | return c; 40 | } 41 | 42 | protected override FrameworkElement CreateEnumControl(PropertyItem property, PropertyControlFactoryOptions options) 43 | { 44 | var enumType = TypeHelper.GetEnumType(property.Descriptor.PropertyType); 45 | 46 | var c = new EnumCombo {Enum = enumType}; 47 | c.SetBinding(Selector.SelectedValueProperty, property.CreateBinding()); 48 | return c; 49 | } 50 | 51 | protected virtual FrameworkElement CreateListControl(PropertyItem property) 52 | { 53 | var c = new ListBox(); 54 | c.SetBinding(ItemsControl.ItemsSourceProperty, property.CreateBinding()); 55 | return c; 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /DspSharpDemo/MainWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System.Windows; 8 | 9 | namespace DspSharpDemo 10 | { 11 | /// 12 | /// Interaction logic for MainWindow.xaml 13 | /// 14 | public partial class MainWindow : Window 15 | { 16 | public MainWindow() 17 | { 18 | this.InitializeComponent(); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /DspSharpDemo/PerformanceHelper.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System; 8 | using System.Diagnostics; 9 | using System.Threading; 10 | 11 | namespace DspSharpDemo 12 | { 13 | public static class PerformanceHelper 14 | { 15 | public static void Bench(Action func, double benchtime = 1000, bool silentmode = false, string description = "") 16 | { 17 | int iterations = 1; 18 | double elapsed; 19 | 20 | while ((elapsed = Profile(iterations, func).TotalMilliseconds) < benchtime * 0.1) 21 | { 22 | iterations *= 10; 23 | } 24 | 25 | iterations = Convert.ToInt32(iterations * benchtime / elapsed); 26 | 27 | double timeperaction = Profile(iterations, func).TotalMilliseconds / iterations; 28 | 29 | if (!silentmode) 30 | { 31 | Console.Write(description); 32 | Console.WriteLine(" Time per action {0} ns", timeperaction * 1000); 33 | } 34 | } 35 | 36 | public static TimeSpan Profile(int iterations, Action func, bool silentmode = true, string description = "") 37 | { 38 | //Run at highest priority to minimize fluctuations caused by other processes/threads 39 | Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.High; 40 | Thread.CurrentThread.Priority = ThreadPriority.Highest; 41 | 42 | // warm up 43 | func(); 44 | 45 | var watch = new Stopwatch(); 46 | 47 | // clean up 48 | GC.Collect(); 49 | GC.WaitForPendingFinalizers(); 50 | GC.Collect(); 51 | 52 | watch.Start(); 53 | for (int i = 0; i < iterations; i++) 54 | { 55 | func(); 56 | } 57 | watch.Stop(); 58 | 59 | if (!silentmode) 60 | { 61 | Console.Write(description); 62 | Console.WriteLine(" Time Elapsed {0} ns", watch.Elapsed.TotalMilliseconds * 1000); 63 | } 64 | return watch.Elapsed; 65 | } 66 | } 67 | } -------------------------------------------------------------------------------- /DspSharpDemo/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System.Reflection; 8 | using System.Runtime.InteropServices; 9 | using System.Windows; 10 | 11 | // General Information about an assembly is controlled through the following 12 | // set of attributes. Change these attribute values to modify the information 13 | // associated with an assembly. 14 | 15 | [assembly: AssemblyTitle("FilterTest")] 16 | [assembly: AssemblyDescription("")] 17 | [assembly: AssemblyConfiguration("")] 18 | [assembly: AssemblyCompany("")] 19 | [assembly: AssemblyProduct("FilterTest")] 20 | [assembly: AssemblyCopyright("Copyright © 2016")] 21 | [assembly: AssemblyTrademark("")] 22 | [assembly: AssemblyCulture("")] 23 | 24 | // Setting ComVisible to false makes the types in this assembly not visible 25 | // to COM components. If you need to access a type in this assembly from 26 | // COM, set the ComVisible attribute to true on that type. 27 | 28 | [assembly: ComVisible(false)] 29 | 30 | //In order to begin building localizable applications, set 31 | //CultureYouAreCodingWith in your .csproj file 32 | //inside a . For example, if you are using US english 33 | //in your source files, set the to en-US. Then uncomment 34 | //the NeutralResourceLanguage attribute below. Update the "en-US" in 35 | //the line below to match the UICulture setting in the project file. 36 | 37 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] 38 | 39 | [assembly: ThemeInfo( 40 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located 41 | //(used if a resource is not found in the page, 42 | // or application resource dictionaries) 43 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located 44 | //(used if a resource is not found in the page, 45 | // app, or any theme specific resource dictionaries) 46 | )] 47 | 48 | // Version information for an assembly consists of the following four values: 49 | // 50 | // Major Version 51 | // Minor Version 52 | // Build Number 53 | // Revision 54 | // 55 | // You can specify all the values or you can default the Build and Revision Numbers 56 | // by using the '*' as shown below: 57 | // [assembly: AssemblyVersion("1.0.*")] 58 | 59 | [assembly: AssemblyVersion("1.0.0.0")] 60 | [assembly: AssemblyFileVersion("1.0.0.0")] -------------------------------------------------------------------------------- /DspSharpDemo/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace DspSharpDemo.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /DspSharpDemo/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /DspSharpDemo/RelayCommand.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System; 8 | using System.Diagnostics; 9 | using System.Windows.Input; 10 | 11 | namespace DspSharpDemo 12 | { 13 | /// 14 | /// A command whose sole purpose is to 15 | /// relay its functionality to other 16 | /// objects by invoking delegates. The 17 | /// default return value for the CanExecute 18 | /// method is 'true'. 19 | /// 20 | public class RelayCommand : ICommand 21 | { 22 | readonly Predicate _canExecute; 23 | 24 | readonly Action _execute; 25 | 26 | /// 27 | /// Creates a new command that can always execute. 28 | /// 29 | /// The execution logic. 30 | public RelayCommand(Action execute) 31 | : this(execute, null) 32 | { 33 | } 34 | 35 | /// 36 | /// Creates a new command. 37 | /// 38 | /// The execution logic. 39 | /// The execution status logic. 40 | public RelayCommand(Action execute, Predicate canExecute) 41 | { 42 | if (execute == null) 43 | throw new ArgumentNullException(nameof(execute)); 44 | 45 | this._execute = execute; 46 | this._canExecute = canExecute; 47 | } 48 | 49 | [DebuggerStepThrough] 50 | public bool CanExecute(object parameters) 51 | { 52 | return this._canExecute?.Invoke(parameters) ?? true; 53 | } 54 | 55 | public event EventHandler CanExecuteChanged 56 | { 57 | add { CommandManager.RequerySuggested += value; } 58 | remove { CommandManager.RequerySuggested -= value; } 59 | } 60 | 61 | public void Execute(object parameters) 62 | { 63 | this._execute(parameters); 64 | } 65 | } 66 | } -------------------------------------------------------------------------------- /DspSharpDemo/SignalFactory/AvailableSignals.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System.ComponentModel; 8 | 9 | namespace DspSharpDemo.SignalFactory 10 | { 11 | public enum AvailableSignals 12 | { 13 | [Description("sine wave")] Sine, 14 | [Description("sinc pulse")] Sinc, 15 | [Description("white noise")] WhiteNoise, 16 | [Description("ideal highpass")] IdealHighpass, 17 | [Description("ideal lowpass")] IdealLowpass, 18 | [Description("dirac pulse")] Dirac, 19 | [Description("logarithmic sine sweep")] LogSweep, 20 | [Description("window function")] Window, 21 | [Description("impulse response from file")] FileImpulseResponse, 22 | [Description("frequency response from file")] FileFrequencyResponse 23 | } 24 | } -------------------------------------------------------------------------------- /DspSharpDemo/SignalFactory/CommonSignalConfig.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using DspSharp.Utilities; 8 | using PropertyTools.DataAnnotations; 9 | 10 | namespace DspSharpDemo.SignalFactory 11 | { 12 | public class CommonSignalConfig : Observable 13 | { 14 | private AvailableSignals _SignalType; 15 | 16 | [DisplayName("select signal:")] 17 | [Category("signal type")] 18 | [SortIndex(0)] 19 | public AvailableSignals SignalType 20 | { 21 | get { return this._SignalType; } 22 | set { this.SetField(ref this._SignalType, value); } 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /DspSharpDemo/SignalFactory/DialogClose.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System.Windows; 8 | 9 | namespace DspSharpDemo.SignalFactory 10 | { 11 | public static class DialogCloser 12 | { 13 | public static readonly DependencyProperty DialogResultProperty = 14 | DependencyProperty.RegisterAttached( 15 | "DialogResult", 16 | typeof(bool?), 17 | typeof(DialogCloser), 18 | new PropertyMetadata(DialogResultChanged)); 19 | 20 | private static bool startup; 21 | 22 | public static void SetDialogResult(Window target, bool? value) 23 | { 24 | target.SetValue(DialogResultProperty, value); 25 | } 26 | 27 | private static void DialogResultChanged( 28 | DependencyObject d, 29 | DependencyPropertyChangedEventArgs e) 30 | { 31 | var window = d as Window; 32 | if ((window != null) && startup) 33 | { 34 | window.DialogResult = e.NewValue as bool?; 35 | startup = false; 36 | return; 37 | } 38 | 39 | startup = true; 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /DspSharpDemo/SignalFactory/DiracFactory.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using DspSharp.Signal; 8 | using PropertyTools.DataAnnotations; 9 | 10 | namespace DspSharpDemo.SignalFactory 11 | { 12 | public class DiracFactory : SignalFactory 13 | { 14 | private double _Gain = 1; 15 | 16 | public override ISignal CreateSignal() 17 | { 18 | return new Dirac(this.SampleRate, this.Gain); 19 | } 20 | 21 | [DisplayName("gain factor")] 22 | [Category("dirac settings")] 23 | [SortIndex(2)] 24 | public double Gain 25 | { 26 | get { return this._Gain; } 27 | set { this.SetField(ref this._Gain, value); } 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /DspSharpDemo/SignalFactory/FileImpulseResponseFactory.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System; 8 | using System.Collections.Generic; 9 | using System.Globalization; 10 | using System.IO; 11 | using DspSharp.Signal; 12 | using PropertyTools.DataAnnotations; 13 | 14 | namespace DspSharpDemo.SignalFactory 15 | { 16 | public class FileImpulseResponseFactory : SignalFactory 17 | { 18 | private string _FileName; 19 | 20 | public override ISignal CreateSignal() 21 | { 22 | try 23 | { 24 | var fi = new FileInfo(this.FileName); 25 | if (!fi.Exists) 26 | return null; 27 | } 28 | catch (Exception) 29 | { 30 | return null; 31 | } 32 | 33 | var file = File.ReadLines(this.FileName); 34 | 35 | var signal = new List(); 36 | 37 | foreach (var line in file) 38 | { 39 | var fields = line.Split(','); 40 | 41 | double ret; 42 | if (!double.TryParse(fields[0], NumberStyles.Any, CultureInfo.InvariantCulture, out ret)) 43 | continue; 44 | 45 | if (fields.Length == 1) 46 | signal.Add(ret); 47 | else 48 | { 49 | if (fields.Length == 2) 50 | { 51 | if (!double.TryParse(fields[1], NumberStyles.Any, CultureInfo.InvariantCulture, out ret)) 52 | continue; 53 | 54 | signal.Add(ret); 55 | } 56 | } 57 | } 58 | 59 | return new FiniteSignal(signal, this.SampleRate, this.TimeOffset); 60 | } 61 | 62 | [DisplayName("impulse response path")] 63 | [InputFilePath("txt", "*.txt-files|*.txt|*.csv-files|*.csv")] 64 | public string FileName 65 | { 66 | get { return this._FileName; } 67 | set { this.SetField(ref this._FileName, value); } 68 | } 69 | } 70 | } -------------------------------------------------------------------------------- /DspSharpDemo/SignalFactory/IdealHighpassFactory.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using DspSharp.Signal; 8 | using PropertyTools.DataAnnotations; 9 | 10 | namespace DspSharpDemo.SignalFactory 11 | { 12 | public class IdealHighpassFactory : SignalFactory 13 | { 14 | private double _Frequency = 1000; 15 | 16 | public override ISignal CreateSignal() 17 | { 18 | return new IdealHighpass(this.SampleRate, this.Frequency); 19 | } 20 | 21 | [DisplayName("cutoff frequency [Hz]")] 22 | [Category("ideal highpass settings")] 23 | [SortIndex(2)] 24 | public double Frequency 25 | { 26 | get { return this._Frequency; } 27 | set { this.SetField(ref this._Frequency, value); } 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /DspSharpDemo/SignalFactory/IdealLowpassFactory.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using DspSharp.Signal; 8 | using PropertyTools.DataAnnotations; 9 | 10 | namespace DspSharpDemo.SignalFactory 11 | { 12 | public class IdealLowpassFactory : SignalFactory 13 | { 14 | private double _Frequency = 1000; 15 | 16 | public override ISignal CreateSignal() 17 | { 18 | return new IdealLowpass(this.SampleRate, this.Frequency); 19 | } 20 | 21 | [DisplayName("cutoff frequency [Hz]")] 22 | [Category("ideal highpass settings")] 23 | [SortIndex(2)] 24 | public double Frequency 25 | { 26 | get { return this._Frequency; } 27 | set { this.SetField(ref this._Frequency, value); } 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /DspSharpDemo/SignalFactory/LogSweepFactory.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using DspSharp.Signal; 8 | using PropertyTools.DataAnnotations; 9 | 10 | namespace DspSharpDemo.SignalFactory 11 | { 12 | public class LogSweepFactory : SignalFactory 13 | { 14 | private double _Length = 1; 15 | private double _StartFrequency = 20; 16 | private double _StopFrequency = 20000; 17 | 18 | public override ISignal CreateSignal() 19 | { 20 | return new LogSweep(this.StartFrequency, this.StopFrequency, this.Length, this.SampleRate); 21 | } 22 | 23 | [DisplayName("length [seconds]")] 24 | [Category("logsweep settings")] 25 | [SortIndex(4)] 26 | public double Length 27 | { 28 | get { return this._Length; } 29 | set { this.SetField(ref this._Length, value); } 30 | } 31 | 32 | [DisplayName("start frequency [Hz]")] 33 | [Category("logsweep settings")] 34 | [SortIndex(2)] 35 | public double StartFrequency 36 | { 37 | get { return this._StartFrequency; } 38 | set { this.SetField(ref this._StartFrequency, value); } 39 | } 40 | 41 | [DisplayName("stop frequency [Hz]")] 42 | [Category("logsweep settings")] 43 | [SortIndex(3)] 44 | public double StopFrequency 45 | { 46 | get { return this._StopFrequency; } 47 | set { this.SetField(ref this._StopFrequency, value); } 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /DspSharpDemo/SignalFactory/SignalDialog.xaml: -------------------------------------------------------------------------------- 1 |  13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 27 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /DspSharpDemo/SignalFactory/SignalDialog.xaml.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System.Windows; 8 | using System.Windows.Data; 9 | using DspSharp.Signal; 10 | 11 | namespace DspSharpDemo.SignalFactory 12 | { 13 | /// 14 | /// Interaction logic for SignalDialog.xaml 15 | /// 16 | public partial class SignalDialog : Window 17 | { 18 | public static DependencyProperty CreatedSignalProperty = DependencyProperty.Register( 19 | "CreatedSignal", 20 | typeof(ISignal), 21 | typeof(SignalDialog), 22 | new PropertyMetadata()); 23 | 24 | public SignalDialog(double samplerate) 25 | { 26 | this.InitializeComponent(); 27 | this.DataContext = new ViewModel(samplerate); 28 | var binding = new Binding(nameof(ViewModel.CreatedSignal)) {Source = this.DataContext}; 29 | this.SetBinding(CreatedSignalProperty, binding); 30 | } 31 | 32 | public ISignal CreatedSignal 33 | { 34 | get { return (ISignal)this.GetValue(CreatedSignalProperty); } 35 | set { this.SetValue(CreatedSignalProperty, value); } 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /DspSharpDemo/SignalFactory/SignalFactory.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System.Collections.Generic; 8 | using DspSharp; 9 | using DspSharp.Filter; 10 | using DspSharp.Signal; 11 | using DspSharp.Utilities; 12 | using PropertyTools.DataAnnotations; 13 | 14 | namespace DspSharpDemo.SignalFactory 15 | { 16 | public abstract class SignalFactory : Observable 17 | { 18 | private double _SampleRate = 44100; 19 | 20 | private int _TimeOffset; 21 | 22 | [Browsable(false)] 23 | public IReadOnlyList AvailableSampleRates { get; } = FilterBase.DefaultSampleRates; 24 | 25 | [ItemsSourceProperty(nameof(AvailableSampleRates))] 26 | //[DisplayName("sample rate")] 27 | [Category("basic settings")] 28 | [ReadOnly(true)] 29 | [SortIndex(0)] 30 | public double SampleRate 31 | { 32 | get { return this._SampleRate; } 33 | set { this.SetField(ref this._SampleRate, value); } 34 | } 35 | 36 | public abstract ISignal CreateSignal(); 37 | 38 | [DisplayName("sample offset")] 39 | [Category("basic settings")] 40 | [SortIndex(1)] 41 | public int TimeOffset 42 | { 43 | get { return this._TimeOffset; } 44 | set { this.SetField(ref this._TimeOffset, value); } 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /DspSharpDemo/SignalFactory/SignalFactoryFactory.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System; 8 | 9 | namespace DspSharpDemo.SignalFactory 10 | { 11 | public static class SignalFactoryFactory 12 | { 13 | public static SignalFactory CreateSignalFactory(AvailableSignals type, double samplerate) 14 | { 15 | if (type == AvailableSignals.Sine) 16 | return new SinusFactory {SampleRate = samplerate}; 17 | if (type == AvailableSignals.Sinc) 18 | return new SincFactory {SampleRate = samplerate}; 19 | if (type == AvailableSignals.WhiteNoise) 20 | return new WhiteNoiseFactory {SampleRate = samplerate}; 21 | if (type == AvailableSignals.IdealHighpass) 22 | return new IdealHighpassFactory {SampleRate = samplerate}; 23 | if (type == AvailableSignals.IdealLowpass) 24 | return new IdealLowpassFactory {SampleRate = samplerate}; 25 | if (type == AvailableSignals.Dirac) 26 | return new DiracFactory {SampleRate = samplerate}; 27 | if (type == AvailableSignals.LogSweep) 28 | return new LogSweepFactory {SampleRate = samplerate}; 29 | if (type == AvailableSignals.Window) 30 | return new WindowFactory {SampleRate = samplerate}; 31 | if (type == AvailableSignals.FileImpulseResponse) 32 | return new FileImpulseResponseFactory {SampleRate = samplerate}; 33 | if (type == AvailableSignals.FileFrequencyResponse) 34 | return new FileFrequencyResponseFactory {SampleRate = samplerate}; 35 | throw new ArgumentOutOfRangeException(nameof(type), type, null); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /DspSharpDemo/SignalFactory/SincFactory.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using DspSharp.Signal; 8 | using PropertyTools.DataAnnotations; 9 | 10 | namespace DspSharpDemo.SignalFactory 11 | { 12 | public class SincFactory : SignalFactory 13 | { 14 | private double _Frequency = 1000; 15 | 16 | public override ISignal CreateSignal() 17 | { 18 | return new Sinc(this.SampleRate, this.Frequency); 19 | } 20 | 21 | [DisplayName("frequency [Hz]")] 22 | [Category("sinc settings")] 23 | [SortIndex(2)] 24 | public double Frequency 25 | { 26 | get { return this._Frequency; } 27 | set { this.SetField(ref this._Frequency, value); } 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /DspSharpDemo/SignalFactory/SinusFactory.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using DspSharp.Signal; 8 | using PropertyTools.DataAnnotations; 9 | 10 | namespace DspSharpDemo.SignalFactory 11 | { 12 | public class SinusFactory : SignalFactory 13 | { 14 | private double _Frequency = 1000; 15 | private double _Phase; 16 | 17 | public override ISignal CreateSignal() 18 | { 19 | return new Sinus(this.SampleRate, this.Frequency, this.Phase); 20 | } 21 | 22 | [DisplayName("frequency [Hz]")] 23 | [Category("sinus settings")] 24 | [SortIndex(2)] 25 | public double Frequency 26 | { 27 | get { return this._Frequency; } 28 | set { this.SetField(ref this._Frequency, value); } 29 | } 30 | 31 | [DisplayName("phase offset [rad]")] 32 | [Category("sinus settings")] 33 | [SortIndex(3)] 34 | public double Phase 35 | { 36 | get { return this._Phase; } 37 | set { this.SetField(ref this._Phase, value); } 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /DspSharpDemo/SignalFactory/WhiteNoiseFactory.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using DspSharp.Signal; 8 | using PropertyTools.DataAnnotations; 9 | 10 | namespace DspSharpDemo.SignalFactory 11 | { 12 | public class WhiteNoiseFactory : SignalFactory 13 | { 14 | private double _Mean; 15 | private double _Variance = 1; 16 | 17 | public override ISignal CreateSignal() 18 | { 19 | return new WhiteNoise(this.SampleRate, this.Mean, this.Variance); 20 | } 21 | 22 | [DisplayName("mean")] 23 | [Category("white noise settings")] 24 | [SortIndex(2)] 25 | public double Mean 26 | { 27 | get { return this._Mean; } 28 | set { this.SetField(ref this._Mean, value); } 29 | } 30 | 31 | [DisplayName("variance")] 32 | [Category("white noise settings")] 33 | [SortIndex(3)] 34 | public double Variance 35 | { 36 | get { return this._Variance; } 37 | set { this.SetField(ref this._Variance, value); } 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /DspSharpDemo/SignalFactory/WindowFactory.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using DspSharp.Signal; 8 | using DspSharp.Signal.Windows; 9 | using PropertyTools.DataAnnotations; 10 | 11 | namespace DspSharpDemo.SignalFactory 12 | { 13 | public class WindowFactory : SignalFactory 14 | { 15 | private bool _CustomStart; 16 | private int _Length = 1024; 17 | private WindowModes _Mode = WindowModes.Symmetric; 18 | private int _Start; 19 | private WindowTypes _type = WindowTypes.Hann; 20 | 21 | public override ISignal CreateSignal() 22 | { 23 | if (this.CustomStart) 24 | return new Window(this.Type, this.Start, this.Length, this.SampleRate, this.Mode); 25 | 26 | return new Window(this.Type, this.Length, this.SampleRate, this.Mode); 27 | } 28 | 29 | [DisplayName("custom window start time")] 30 | [Category("window settings")] 31 | [SortIndex(5)] 32 | public bool CustomStart 33 | { 34 | get { return this._CustomStart; } 35 | set { this.SetField(ref this._CustomStart, value); } 36 | } 37 | 38 | [DisplayName("window length")] 39 | [Category("window settings")] 40 | [SortIndex(3)] 41 | public int Length 42 | { 43 | get { return this._Length; } 44 | set { this.SetField(ref this._Length, value); } 45 | } 46 | 47 | [DisplayName("window mode")] 48 | [Category("window settings")] 49 | [SortIndex(4)] 50 | public WindowModes Mode 51 | { 52 | get { return this._Mode; } 53 | set { this.SetField(ref this._Mode, value); } 54 | } 55 | 56 | [DisplayName("default window start time")] 57 | [Category("window settings")] 58 | [SortIndex(6)] 59 | [EnableBy(nameof(CustomStart))] 60 | public int Start 61 | { 62 | get { return this._Start; } 63 | set { this.SetField(ref this._Start, value); } 64 | } 65 | 66 | [DisplayName("window type")] 67 | [Category("window settings")] 68 | [SortIndex(2)] 69 | public WindowTypes Type 70 | { 71 | get { return this._type; } 72 | set { this.SetField(ref this._type, value); } 73 | } 74 | } 75 | } -------------------------------------------------------------------------------- /DspSharpDemo/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /DspSharpFftw/DspSharp.Interop.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jonarw/DspSharp/f1b987ec1b5c21f572b9a1e409c661925f4d7455/DspSharpFftw/DspSharp.Interop.dll -------------------------------------------------------------------------------- /DspSharpFftw/DspSharpFftw.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard1.3;net45;net46 5 | True 6 | 0.1.3-pre 7 | Jonathan Arweck 8 | 9 | FFTW-based FFT support for DspSharp 10 | © 2017 Jonathan Arweck 11 | https://github.com/Jonarw/DspSharp/blob/dev/LICENSE.txt 12 | https://github.com/Jonarw/DspSharp/ 13 | audio signal processing dsp fft fftw 14 | 15 | 16 | 17 | True 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | DspSharp.Interop.dll 31 | 32 | 33 | 34 | 35 | 36 | true 37 | PreserveNewest 38 | 39 | 40 | PreserveNewest 41 | 42 | 43 | PreserveNewest 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /DspSharpFftw/FftPlan.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using DspSharp.Algorithms; 8 | 9 | namespace DspSharpFftw 10 | { 11 | public abstract unsafe class FftPlan 12 | { 13 | protected FftPlan(int fftLength, void* plan) 14 | { 15 | this.FftLength = fftLength; 16 | this.Plan = plan; 17 | FftwInterop.ExportWisdom(); 18 | } 19 | 20 | public int FftLength { get; } 21 | public void* Plan { get; } 22 | 23 | public abstract void ExecuteUnsafe(void* input, void* output, NormalizationKind normalization); 24 | 25 | ~FftPlan() 26 | { 27 | FftwInterop.DestroyPlan(this.Plan); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /DspSharpFftw/FftwDirection.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | namespace DspSharpFftw 8 | { 9 | /// 10 | /// Defines direction of operation 11 | /// 12 | public enum FftwDirection 13 | { 14 | /// 15 | /// Computes a regular DFT 16 | /// 17 | Forward = -1, 18 | 19 | /// 20 | /// Computes the inverse DFT 21 | /// 22 | Backward = 1 23 | } 24 | } -------------------------------------------------------------------------------- /DspSharpFftw/FftwKind.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | namespace DspSharpFftw 8 | { 9 | /// 10 | /// Kinds of real-to-real transforms 11 | /// 12 | public enum FftwRealToRealKind : uint 13 | { 14 | RealToHalfComplex = 0, 15 | HalfComplexToReal = 1, 16 | DiscreteHartleyTransform = 2, 17 | DiscreteCosineTransform1 = 3, 18 | DiscreteCosineTransform2 = 4, 19 | DiscreteCosineTransform3 = 5, 20 | DiscreteCosineTransform4 = 6, 21 | DiscreteSineTransform1 = 7, 22 | DiscreteSineTransform2 = 8, 23 | DiscreteSineTransform3 = 9, 24 | DiscreteSineTransform4 = 10 25 | } 26 | } -------------------------------------------------------------------------------- /DspSharpFftw/RealFftPlan.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | namespace DspSharpFftw 8 | { 9 | /// 10 | /// Handles the creating of an fftw plan and the associated memory blocks. 11 | /// 12 | public abstract unsafe class RealFftPlan : FftPlan 13 | { 14 | /// 15 | /// Initializes a new instance of the base class . 16 | /// 17 | /// The FFT lenght the plan is used for. 18 | /// 19 | protected RealFftPlan(int fftLength, CreateRealPlanDelegate createPlanDelegate) 20 | : base(fftLength, CreatePlan(fftLength, createPlanDelegate)) 21 | { 22 | this.SpectrumLength = (this.FftLength >> 1) + 1; 23 | } 24 | 25 | public int SpectrumLength { get; } 26 | 27 | private static void* CreatePlan(int fftLength, CreateRealPlanDelegate createPlanDelegate) 28 | { 29 | var spectrumLength = (fftLength >> 1) + 1; 30 | 31 | var pInput = (void*)0; 32 | var pOutput = (void*)0; 33 | try 34 | { 35 | // make both memory blocks the same size for simplicity (16 bytes are wasted) 36 | pInput = FftwInterop.Malloc(spectrumLength * 2 * sizeof(double)); 37 | pOutput = FftwInterop.Malloc(spectrumLength * 2 * sizeof(double)); 38 | 39 | return createPlanDelegate(fftLength, pInput, pOutput, FftwFlags.Measure | FftwFlags.DestroyInput); 40 | } 41 | finally 42 | { 43 | // free arrays used for planning - we won't ever call fftw_execute 44 | FftwInterop.Free(pInput); 45 | FftwInterop.Free(pOutput); 46 | } 47 | } 48 | 49 | protected delegate void* CreateRealPlanDelegate(int fftLength, void* pInput, void* pOutput, FftwFlags flags); 50 | } 51 | } -------------------------------------------------------------------------------- /DspSharpFftw/libfftw3-3-32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jonarw/DspSharp/f1b987ec1b5c21f572b9a1e409c661925f4d7455/DspSharpFftw/libfftw3-3-32.dll -------------------------------------------------------------------------------- /DspSharpFftw/libfftw3-3-64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jonarw/DspSharp/f1b987ec1b5c21f572b9a1e409c661925f4d7455/DspSharpFftw/libfftw3-3-64.dll -------------------------------------------------------------------------------- /DspSharpPlot/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /DspSharpPlot/App.xaml: -------------------------------------------------------------------------------- 1 |  4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /DspSharpPlot/App.xaml.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System.Windows; 8 | 9 | namespace DspSharpPlot 10 | { 11 | /// 12 | /// Interaction logic for App.xaml 13 | /// 14 | public partial class App : Application 15 | { 16 | } 17 | } -------------------------------------------------------------------------------- /DspSharpPlot/Axes/AmplitudeAxis.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | namespace DspSharpPlot.Axes 8 | { 9 | /// 10 | /// Represents an amplitude axis (dB). 11 | /// 12 | /// 13 | public class AmplitudeAxis : DefaultAxis 14 | { 15 | /// 16 | /// Initializes a new instance of the class. 17 | /// 18 | public AmplitudeAxis() 19 | { 20 | this.Title = "Magnitude [dB]"; 21 | //Me.Zoom(-50, 50) 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /DspSharpPlot/Axes/DefaultAxis.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using OxyPlot; 8 | using OxyPlot.Axes; 9 | 10 | namespace DspSharpPlot.Axes 11 | { 12 | /// 13 | /// Extends for custom value initializations. 14 | /// 15 | /// 16 | public class DefaultAxis : LinearAxis 17 | { 18 | /// 19 | /// Initializes a new instance of the class. 20 | /// 21 | public DefaultAxis() 22 | { 23 | this.MajorGridlineStyle = LineStyle.Solid; 24 | this.MinorGridlineStyle = LineStyle.Solid; 25 | this.MajorGridlineThickness = 2; 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /DspSharpPlot/Axes/FrequencyAxis.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using OxyPlot; 8 | using OxyPlot.Axes; 9 | 10 | namespace DspSharpPlot.Axes 11 | { 12 | /// 13 | /// Extends for custom value initializations. 14 | /// 15 | /// 16 | public class FrequencyAxis : LogarithmicAxis 17 | { 18 | /// 19 | /// Initializes a new instance of the class. 20 | /// 21 | public FrequencyAxis() 22 | { 23 | this.MajorGridlineStyle = LineStyle.Solid; 24 | this.Title = "Frequency [Hz]"; 25 | this.MinorGridlineStyle = LineStyle.Solid; 26 | this.Base = 10; 27 | //Me.IsZoomEnabled = False 28 | //Me.IsPanEnabled = False 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /DspSharpPlot/Axes/GroupDelayAxis.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | namespace DspSharpPlot.Axes 8 | { 9 | /// 10 | /// Represents a group delay axis (ms). 11 | /// 12 | /// 13 | public class GroupDelayAxis : DefaultAxis 14 | { 15 | /// 16 | /// Initializes a new instance of the class. 17 | /// 18 | public GroupDelayAxis() 19 | { 20 | this.Title = "Group Delay [ms]"; 21 | //Me.Zoom(0, 50) 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /DspSharpPlot/Axes/ImpulseResponseAxis.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | namespace DspSharpPlot.Axes 8 | { 9 | /// 10 | /// Represents a linear scaled axis without unit for impulse responses. 11 | /// 12 | /// 13 | public sealed class ImpulseResponseAxis : DefaultAxis 14 | { 15 | /// 16 | /// Initializes a new instance of the class. 17 | /// 18 | public ImpulseResponseAxis() 19 | { 20 | this.Title = "Value"; 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /DspSharpPlot/Axes/PhaseAxis.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System; 8 | 9 | namespace DspSharpPlot.Axes 10 | { 11 | /// 12 | /// Represents a phase axis (degree). 13 | /// 14 | /// 15 | public class PhaseAxis : DefaultAxis 16 | { 17 | /// 18 | /// Initializes a new instance of the class. 19 | /// 20 | public PhaseAxis() 21 | { 22 | this.Minimum = -Math.PI; 23 | this.Maximum = Math.PI; 24 | this.FormatAsFractions = true; 25 | this.FractionUnit = Math.PI; 26 | this.FractionUnitSymbol = "π"; 27 | this.Title = "Phase [rad]"; 28 | this.IsPanEnabled = false; 29 | this.IsZoomEnabled = false; 30 | this.MajorStep = Math.PI / 2; 31 | this.MinorStep = Math.PI / 4; 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /DspSharpPlot/Axes/SampleAxis.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | namespace DspSharpPlot.Axes 8 | { 9 | /// 10 | /// Represents a sample axis. 11 | /// 12 | /// 13 | public sealed class SampleAxis : DefaultAxis 14 | { 15 | /// 16 | /// Initializes a new instance of the class. 17 | /// 18 | public SampleAxis() 19 | { 20 | this.Title = "Time [samples]"; 21 | this.MinimumMajorStep = 1; 22 | this.MinimumMinorStep = 1; 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /DspSharpPlot/DspSharpPlot.csproj.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | True -------------------------------------------------------------------------------- /DspSharpPlot/FilterPlot.csproj.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | True -------------------------------------------------------------------------------- /DspSharpPlot/FilterPlot.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Dsp.Audio.Plot 5 | 0.1-unstable001 6 | FilterPlot 7 | Jonarw 8 | Jonarw 9 | https://github.com/Jonarw/filter/blob/develop/LICENSE.txt 10 | https://github.com/Jonarw/filter/tree/develop/FilterPlot 11 | false 12 | Tools for plotting signals created by Filter. 13 | First release 14 | Copyright 2017 15 | plot dsp audio signal processing filter 16 | 17 | -------------------------------------------------------------------------------- /DspSharpPlot/PlotServer/IPlotContract.cs: -------------------------------------------------------------------------------- 1 | using System.ServiceModel; 2 | 3 | namespace DspSharpPlot.PlotServer 4 | { 5 | [ServiceContract] 6 | public interface IPlotContract 7 | { 8 | [OperationContract] 9 | void Plot(double[] x, double[] y); 10 | } 11 | } -------------------------------------------------------------------------------- /DspSharpPlot/PlotServer/ITestContract.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using System.ServiceModel; 4 | using System.ServiceModel.Description; 5 | using DspSharp.Algorithms; 6 | 7 | namespace DspSharpPlot.PlotServer 8 | { 9 | public class PlotClient : ClientBase 10 | { 11 | public PlotClient() : base(new ServiceEndpoint(ContractDescription.GetContract(typeof(IPlotContract)), 12 | new NetNamedPipeBinding(), new EndpointAddress("net.pipe://localhost/DspSharp/PlotService"))) 13 | { 14 | } 15 | 16 | public void Plot(double[] x, double[] y) 17 | { 18 | this.Channel.Plot(x, y); 19 | } 20 | } 21 | 22 | public static class PlotClientExtensions 23 | { 24 | private static PlotClient Client { get; } = new PlotClient(); 25 | 26 | public static void Plot(this IEnumerable y, IEnumerable x) 27 | { 28 | Client.Plot(x.ToArrayOptimized(), y.ToArrayOptimized()); 29 | } 30 | 31 | public static void Plot(this IEnumerable y) 32 | { 33 | var yarray = y.ToArrayOptimized(); 34 | Client.Plot(Enumerable.Range(0, yarray.Length).Select(i => (double)i).ToArray(), yarray); 35 | } 36 | 37 | public static unsafe void Plot(double* x, double* y, int length) 38 | { 39 | var xarray = Unsafe.ToManagedArray(x, length); 40 | var yarray = Unsafe.ToManagedArray(y, length); 41 | Client.Plot(xarray, yarray); 42 | } 43 | 44 | public static unsafe void Plot(double* y, int length) 45 | { 46 | var xarray = Enumerable.Range(0, length).Select(i => (double)i).ToArray(); 47 | var yarray = Unsafe.ToManagedArray(y, length); 48 | Client.Plot(xarray, yarray); 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /DspSharpPlot/PlotServer/PlotServer.cs: -------------------------------------------------------------------------------- 1 | namespace DspSharpPlot.PlotServer 2 | { 3 | public class PlotServer : IPlotContract 4 | { 5 | public void Plot(double[] x, double[] y) 6 | { 7 | DspSharpPlotExtensions.Plot(y, x); 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /DspSharpPlot/PlotWindow.xaml: -------------------------------------------------------------------------------- 1 |  10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /DspSharpPlot/PlotWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | 3 | namespace DspSharpPlot 4 | { 5 | /// 6 | /// Interaction logic for PlotWindow.xaml 7 | /// 8 | public partial class PlotWindow : Window 9 | { 10 | public PlotWindow() 11 | { 12 | this.InitializeComponent(); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /DspSharpPlot/PlotWindowViewModel.cs: -------------------------------------------------------------------------------- 1 | using DspSharp; 2 | using DspSharp.Utilities; 3 | 4 | namespace DspSharpPlot 5 | { 6 | public class PlotWindowViewModel : Observable 7 | { 8 | private DspSharpPlotter _Plotter; 9 | 10 | public DspSharpPlotter Plotter 11 | { 12 | get => this._Plotter; 13 | set => this.SetField(ref this._Plotter, value); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /DspSharpPlot/Plots/FinitePlot.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | -------------------------------------------------------------------------------- /DspSharpPlot/Plots/IXCanBeLogarithmic.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | namespace DspSharpPlot 8 | { 9 | public interface IXCanBeLogarithmic 10 | { 11 | bool XLogarithmic { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /DspSharpPlot/Plots/IYCanBeLogarithmic.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | namespace DspSharpPlot 8 | { 9 | public interface IYCanBeLogarithmic 10 | { 11 | bool YLogarithmic { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /DspSharpPlot/Plots/MagnitudePlot.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System.Collections.Generic; 8 | using DspSharp.Algorithms; 9 | using DspSharp.Spectrum; 10 | using DspSharpPlot.Axes; 11 | using OxyPlot.Axes; 12 | 13 | namespace DspSharpPlot 14 | { 15 | public class MagnitudePlot : SpectrumPlot 16 | { 17 | public MagnitudePlot() 18 | { 19 | this.DisplayName = "magnitude"; 20 | } 21 | 22 | public override Axis YAxis { get; } = new AmplitudeAxis(); 23 | 24 | protected override IEnumerable GetYValues(ISpectrum spectrum) 25 | { 26 | return FrequencyDomain.LinearToDb(spectrum.Magnitude, -1000); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /DspSharpPlot/Plots/PhasePlot.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System.Collections.Generic; 8 | using DspSharp.Spectrum; 9 | using DspSharpPlot.Axes; 10 | using OxyPlot.Axes; 11 | 12 | namespace DspSharpPlot 13 | { 14 | public class PhasePlot : SpectrumPlot 15 | { 16 | public PhasePlot() 17 | { 18 | this.DisplayName = "phase"; 19 | } 20 | 21 | public override Axis YAxis { get; } = new PhaseAxis(); 22 | 23 | protected override IEnumerable GetYValues(ISpectrum spectrum) 24 | { 25 | return spectrum.Phase; 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /DspSharpPlot/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ServiceModel; 3 | using DspSharpPlot.PlotServer; 4 | 5 | namespace DspSharpPlot 6 | { 7 | internal class Program 8 | { 9 | static void Main(string[] args) 10 | { 11 | var serviceHost = new ServiceHost(typeof(PlotServer.PlotServer), new Uri("net.pipe://localhost/DspSharp")); 12 | var binding = new NetNamedPipeBinding(); 13 | serviceHost.AddServiceEndpoint(typeof(IPlotContract), binding, "PlotService"); 14 | serviceHost.Open(); 15 | 16 | Console.WriteLine("ServiceHost running. Press Return to Exit"); 17 | foreach (var serviceEndpoint in serviceHost.Description.Endpoints) 18 | { 19 | Console.WriteLine(serviceEndpoint.ListenUri.AbsoluteUri); 20 | } 21 | Console.ReadLine(); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /DspSharpPlot/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System.Reflection; 8 | using System.Runtime.InteropServices; 9 | using System.Windows; 10 | 11 | // General Information about an assembly is controlled through the following 12 | // set of attributes. Change these attribute values to modify the information 13 | // associated with an assembly. 14 | 15 | [assembly: AssemblyTitle("FilterPlot")] 16 | [assembly: AssemblyDescription("")] 17 | [assembly: AssemblyConfiguration("")] 18 | [assembly: AssemblyCompany("")] 19 | [assembly: AssemblyProduct("FilterPlot")] 20 | [assembly: AssemblyCopyright("Copyright © 2016")] 21 | [assembly: AssemblyTrademark("")] 22 | [assembly: AssemblyCulture("")] 23 | 24 | // Setting ComVisible to false makes the types in this assembly not visible 25 | // to COM components. If you need to access a type in this assembly from 26 | // COM, set the ComVisible attribute to true on that type. 27 | 28 | [assembly: ComVisible(false)] 29 | 30 | //In order to begin building localizable applications, set 31 | //CultureYouAreCodingWith in your .csproj file 32 | //inside a . For example, if you are using US english 33 | //in your source files, set the to en-US. Then uncomment 34 | //the NeutralResourceLanguage attribute below. Update the "en-US" in 35 | //the line below to match the UICulture setting in the project file. 36 | 37 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] 38 | 39 | [assembly: ThemeInfo( 40 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located 41 | //(used if a resource is not found in the page, 42 | // or application resource dictionaries) 43 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located 44 | //(used if a resource is not found in the page, 45 | // app, or any theme specific resource dictionaries) 46 | )] 47 | 48 | // Version information for an assembly consists of the following four values: 49 | // 50 | // Major Version 51 | // Minor Version 52 | // Build Number 53 | // Revision 54 | // 55 | // You can specify all the values or you can default the Build and Revision Numbers 56 | // by using the '*' as shown below: 57 | // [assembly: AssemblyVersion("1.0.*")] 58 | 59 | [assembly: AssemblyVersion("1.0.0.0")] 60 | [assembly: AssemblyFileVersion("1.0.0.0")] -------------------------------------------------------------------------------- /DspSharpPlot/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace DspSharpPlot.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /DspSharpPlot/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /DspSharpPlot/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /DspSharpTest/AlgorithmTest.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System; 8 | using System.Collections.Generic; 9 | using DspSharp.Algorithms; 10 | using Microsoft.VisualStudio.TestTools.UnitTesting; 11 | using MSTestExtensions; 12 | 13 | namespace DspSharpTest 14 | { 15 | [TestClass] 16 | public class AlgorithmTest 17 | { 18 | [TestMethod] 19 | public void TestCircularShift() 20 | { 21 | var x = new[] {1.0, 2, 3, 4, 5, 6, 7, 8}; 22 | 23 | var output = x.CircularShift(0).ToReadOnlyList(); 24 | DspAssert.ListsAreEqual(x, output); 25 | 26 | output = x.CircularShift(-2).ToReadOnlyList(); 27 | DspAssert.ListsAreEqual(new[] {7, 8, 1.0, 2, 3, 4, 5, 6}, output); 28 | 29 | output = x.CircularShift(2).ToReadOnlyList(); 30 | DspAssert.ListsAreEqual(new[] {3, 4, 5, 6, 7, 8, 1.0, 2}, output); 31 | 32 | Assert.IsTrue(new List().CircularShift(2).ToReadOnlyList().Count == 0); 33 | ThrowsAssert.Throws(() => VectorOperations.CircularShift(null, 2).ToReadOnlyList()); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /DspSharpTest/MlsTest.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System; 8 | using System.Linq; 9 | using DspSharp.Algorithms; 10 | using Microsoft.VisualStudio.TestTools.UnitTesting; 11 | using MSTestExtensions; 12 | 13 | namespace DspSharpTest 14 | { 15 | [TestClass] 16 | public class MlsTest 17 | { 18 | [TestMethod] 19 | public void TestMlsLowOrders() 20 | { 21 | for (int i = 2; i < 21; i++) 22 | { 23 | var sequence = SignalGenerators.Mls(i); 24 | 25 | Assert.IsTrue(sequence.Count() == Math.Pow(2, i) - 1); 26 | } 27 | 28 | ThrowsAssert.Throws(() => SignalGenerators.Mls(1).ToReadOnlyList()); 29 | ThrowsAssert.Throws(() => SignalGenerators.Mls(SignalGenerators.MlsFeedbackTaps.Count).ToReadOnlyList()); 30 | } 31 | 32 | //[TestMethod] 33 | public void TestMlsHighOrders() 34 | { 35 | for (int i = 21; i < SignalGenerators.MlsFeedbackTaps.Count; i++) 36 | { 37 | var sequence = SignalGenerators.Mls(i); 38 | 39 | Assert.IsTrue(sequence.Count() == Math.Pow(2, i) - 1); 40 | } 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /DspSharpTest/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System.Reflection; 8 | using System.Runtime.InteropServices; 9 | 10 | // General Information about an assembly is controlled through the following 11 | // set of attributes. Change these attribute values to modify the information 12 | // associated with an assembly. 13 | 14 | [assembly: AssemblyTitle("FilterTest")] 15 | [assembly: AssemblyDescription("")] 16 | [assembly: AssemblyConfiguration("")] 17 | [assembly: AssemblyCompany("")] 18 | [assembly: AssemblyProduct("FilterTest")] 19 | [assembly: AssemblyCopyright("Copyright © 2017")] 20 | [assembly: AssemblyTrademark("")] 21 | [assembly: AssemblyCulture("")] 22 | 23 | // Setting ComVisible to false makes the types in this assembly not visible 24 | // to COM components. If you need to access a type in this assembly from 25 | // COM, set the ComVisible attribute to true on that type. 26 | 27 | [assembly: ComVisible(false)] 28 | 29 | // The following GUID is for the ID of the typelib if this project is exposed to COM 30 | 31 | [assembly: Guid("f2939b79-68b6-4477-b716-5ccf11c0fddb")] 32 | 33 | // Version information for an assembly consists of the following four values: 34 | // 35 | // Major Version 36 | // Minor Version 37 | // Build Number 38 | // Revision 39 | // 40 | // You can specify all the values or you can default the Build and Revision Numbers 41 | // by using the '*' as shown below: 42 | // [assembly: AssemblyVersion("1.0.*")] 43 | 44 | [assembly: AssemblyVersion("1.0.0.0")] 45 | [assembly: AssemblyFileVersion("1.0.0.0")] -------------------------------------------------------------------------------- /DspSharpTest/TestStatistics.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System; 8 | using DspSharp.Algorithms; 9 | using Microsoft.VisualStudio.TestTools.UnitTesting; 10 | 11 | namespace DspSharpTest 12 | { 13 | [TestClass] 14 | public class TestStatistics 15 | { 16 | [TestMethod] 17 | public void TestStandardDeviation() 18 | { 19 | double[] x = 20 | { 21 | 0.757740130578333, 22 | 0.743132468124916, 23 | 0.392227019534168, 24 | 0.655477890177557, 25 | 0.171186687811562, 26 | 0.706046088019609, 27 | 0.031832846377421, 28 | 0.276922984960890, 29 | 0.046171390631154, 30 | 0.097131781235848, 31 | }; 32 | 33 | Assert.AreEqual(0.302433511410605, x.StandardDeviation(Statistics.NormalisationMode.Sample), 1e-13); 34 | Assert.AreEqual(0.286913621046010, x.StandardDeviation(Statistics.NormalisationMode.Population), 1e-13); 35 | } 36 | 37 | [TestMethod] 38 | public void TestVariance() 39 | { 40 | double[] x = 41 | { 42 | 0.757740130578333, 43 | 0.743132468124916, 44 | 0.392227019534168, 45 | 0.655477890177557, 46 | 0.171186687811562, 47 | 0.706046088019609, 48 | 0.031832846377421, 49 | 0.276922984960890, 50 | 0.046171390631154, 51 | 0.097131781235848, 52 | }; 53 | 54 | Assert.AreEqual(0.091466028824149, x.Variance(Statistics.NormalisationMode.Sample), 1e-13); 55 | Assert.AreEqual(0.082319425941734, x.Variance(Statistics.NormalisationMode.Population), 1e-13); 56 | } 57 | 58 | [TestMethod] 59 | public void TestMean() 60 | { 61 | double[] x = 62 | { 63 | 0.757740130578333, 64 | 0.743132468124916, 65 | 0.392227019534168, 66 | 0.655477890177557, 67 | 0.171186687811562, 68 | 0.706046088019609, 69 | 0.031832846377421, 70 | 0.276922984960890, 71 | 0.046171390631154, 72 | 0.097131781235848, 73 | }; 74 | 75 | Assert.AreEqual(0.387786928745146, x.Mean(), 1e-13); 76 | } 77 | } 78 | } -------------------------------------------------------------------------------- /DspSharpTest/TestVectorFunctions.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using DspSharp.Algorithms; 8 | using Microsoft.VisualStudio.TestTools.UnitTesting; 9 | 10 | namespace DspSharpTest 11 | { 12 | [TestClass] 13 | public class TestVectorFunctions 14 | { 15 | private readonly double[] input = {5, 6, 1, 100, 2, 3}; 16 | 17 | [TestMethod] 18 | public void TestMaxIndex() 19 | { 20 | Assert.AreEqual(this.input.MaxIndex(), 3); 21 | } 22 | 23 | [TestMethod] 24 | public void TestMinIndex() 25 | { 26 | Assert.AreEqual(this.input.MinIndex(), 2); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /DspSharpTest/UnsafeAlgorithmsTest.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2017 Jonathan Arweck, see LICENSE.txt for license information 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using DspSharp.Algorithms; 8 | using Microsoft.VisualStudio.TestTools.UnitTesting; 9 | 10 | namespace DspSharpTest 11 | { 12 | [TestClass] 13 | public unsafe class UnsafeAlgorithmsTest 14 | { 15 | [TestMethod] 16 | public void TestUnsafeDoubleManaged() 17 | { 18 | double[] s = {1d, 2, 3, 4, 5}; 19 | var t = new double[5]; 20 | 21 | Unsafe.Memcpy(t, s); 22 | DspAssert.ListsAreReasonablyClose(t, s); 23 | 24 | Unsafe.Memset(t); 25 | DspAssert.ListsAreReasonablyClose(t, new[] {0d, 0, 0, 0, 0}); 26 | 27 | Unsafe.Memcpy(t, s, 3); 28 | DspAssert.ListsAreReasonablyClose(t, new[] {1d, 2, 3, 0, 0}); 29 | 30 | Unsafe.Memset(s, 0, 2); 31 | DspAssert.ListsAreReasonablyClose(s, new[] {0d, 0, 3, 4, 5}); 32 | } 33 | 34 | [TestMethod] 35 | public void TestUnsafeDoubleUnManaged() 36 | { 37 | for (int i = 0; i < 1000; i++) 38 | { 39 | double[] s = {1d, 2, 3, 4, 5}; 40 | double* ps = Unsafe.MallocD(5); 41 | Unsafe.Memcpy(ps, s); 42 | 43 | DspAssert.ListsAreReasonablyClose(Unsafe.ToManagedArray(ps, 5), s); 44 | 45 | Unsafe.Memset(ps, 0, 2); 46 | DspAssert.ListsAreReasonablyClose(Unsafe.ToManagedArray(ps, 5), new[] {0d, 0, 3, 4, 5}); 47 | 48 | Unsafe.Memset(ps, 0, 5); 49 | Unsafe.Memcpy(ps, s, 2); 50 | DspAssert.ListsAreReasonablyClose(Unsafe.ToManagedArray(ps, 5), new[] {1d, 2, 0, 0, 0}); 51 | 52 | double* pt = Unsafe.MallocD(5); 53 | Unsafe.Memset(pt, 0, 5); 54 | Unsafe.Memcpy(ps, s); 55 | Unsafe.Memcpy(pt, ps, 2); 56 | Unsafe.Memcpy(pt + 3, ps + 2, 2); 57 | DspAssert.ListsAreReasonablyClose(Unsafe.ToManagedArray(pt, 5), new[] {1d, 2, 0, 3, 4}); 58 | 59 | Unsafe.Memcpy(s, pt); 60 | DspAssert.ListsAreReasonablyClose(s, new[] {1d, 2, 0, 3, 4}); 61 | 62 | Unsafe.Free(pt); 63 | Unsafe.Free(ps); 64 | } 65 | } 66 | } 67 | } -------------------------------------------------------------------------------- /DspSharpTest/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright 2017 Jonathan Arweck 2 | 3 | The DspSharp project and all of its components are licensed under the MIT license. 4 | For terms and conditions, see licenses/MIT.txt. 5 | 6 | DspSharpFftw uses the FFTW library. 7 | The GPL applies. For terms and conditions, see licenses/GPL.txt. 8 | For more information, visit http://www.fftw.org/ 9 | 10 | DspSharpAsio uses the ASIO wrapper from the NAudio project. 11 | The Ms-PL applies. For terms and conditions, see licenses/Ms-PL.txt. 12 | For more information, visit https://github.com/naudio/NAudio 13 | 14 | DspSharp uses the CubicSpline and TriDiagonalMatrix classes by Ryan Seghers. 15 | The CPOL applies. For terms and conditions, see licenses/CPOL.txt. 16 | For more information, visit https://www.codeproject.com/Articles/560163/Csharp-Cubic-Spline-Interpolation 17 | 18 | DspSharp uses PropertyTools. 19 | The MIT license applies. For terms and conditions, see licenses/MIT.txt. 20 | For more information, visit https://github.com/objorke/PropertyTools 21 | 22 | DspSharpPlot uses OxyPlot. 23 | The MIT license applies. For terms and conditions, see licenses/MIT.txt. 24 | For more information, visit https://github.com/oxyplot/oxyplot -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DspSharp 2 | API for digital signal processing in C#. 3 | 4 | ## Binaries 5 | DspSharp on nuget: https://www.nuget.org/packages/DspSharp/ 6 | 7 | DspSharpFftw on nuget: https://www.nuget.org/packages/DspSharpFftw/ 8 | 9 | DspSharpAsio on nuget: https://www.nuget.org/packages/DspSharpAsio/ 10 | 11 | ## Features 12 | ### DspSharp 13 | #### Algorithms 14 | - standard vector operations (addition, multiplication...) 15 | - special vector operations (shift...) 16 | - window synthesis (Hann, Blackman...) 17 | - some mathematical functions (root finding, modified bessel function) 18 | - fast fourier transform, using fftw as backend 19 | - fast convolution, cross correlation 20 | - evaluation of coefficient-based zero/pole filters 21 | - synthesis of standard signals 22 | - signal interpolation 23 | - signal analysis (group delay...) 24 | 25 | #### signal / filter model 26 | Provides an object-oriented programming model for signals and filters. 27 | 28 | ### DspSharpFftw 29 | C# Wrapper for the fftw library. 30 | 31 | ### DspSharpAsio 32 | ASIO interface. 33 | -------------------------------------------------------------------------------- /licenses/CPOL.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jonarw/DspSharp/f1b987ec1b5c21f572b9a1e409c661925f4d7455/licenses/CPOL.txt -------------------------------------------------------------------------------- /licenses/GPL.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jonarw/DspSharp/f1b987ec1b5c21f572b9a1e409c661925f4d7455/licenses/GPL.txt -------------------------------------------------------------------------------- /licenses/MIT.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. -------------------------------------------------------------------------------- /licenses/Ms-PL.txt: -------------------------------------------------------------------------------- 1 | Microsoft Public License (Ms-PL) 2 | 3 | This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software. 4 | 5 | 1. Definitions 6 | 7 | The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law. 8 | 9 | A "contribution" is the original software, or any additions or changes to the software. 10 | 11 | A "contributor" is any person that distributes its contribution under this license. 12 | 13 | "Licensed patents" are a contributor's patent claims that read directly on its contribution. 14 | 15 | 2. Grant of Rights 16 | 17 | (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. 18 | 19 | (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software. 20 | 21 | 3. Conditions and Limitations 22 | 23 | (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks. 24 | 25 | (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically. 26 | 27 | (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software. 28 | 29 | (D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. 30 | 31 | (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement. --------------------------------------------------------------------------------