forked from dzamkov/MD-old
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDiscreteSignal.cs
138 lines (123 loc) · 4.19 KB
/
DiscreteSignal.cs
1
2
3
4
5
6
7
8
9
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
using System;
using System.Collections.Generic;
namespace MD
{
/// <summary>
/// A static, finite, ordered collection of data.
/// </summary>
/// <typeparam name="TSample">The type of an element in the signal.</typeparam>
public abstract class DiscreteSignal<TSample>
{
/// <summary>
/// Gets the size of this signal in samples.
/// </summary>
public abstract int Size { get; }
/// <summary>
/// Reads a sample from the specified index of this signal.
/// </summary>
public abstract TSample Read(int Index);
/// <summary>
/// Gets a feed for this signal at the specified offset.
/// </summary>
public virtual DiscreteFeed<TSample> GetFeed(int Offset)
{
return DiscreteFeed<TSample>.Create<DiscreteSignal<TSample>>(this, Offset);
}
}
/// <summary>
/// A discrete signal with multiple related channels.
/// </summary>
public abstract class MultiDiscreteSignal<TSample> : DiscreteSignal<TSample[]>
{
/// <summary>
/// Gets the amount of channels in this signal.
/// </summary>
public abstract int Channels { get; }
/// <summary>
/// Gets a signal for one of the channels in this signal.
/// </summary>
public virtual DiscreteSignal<TSample> GetChannel(int Channel)
{
return new _Channel<MultiDiscreteSignal<TSample>>(this, Channel);
}
private class _Channel<TSignal> : DiscreteSignal<TSample>
where TSignal : MultiDiscreteSignal<TSample>
{
public _Channel(TSignal Source, int Channel)
{
this._Source = Source;
this._ChannelIndex = Channel;
}
public override int Size
{
get
{
return this._Source.Size;
}
}
public override TSample Read(int Index)
{
return this._Source.Read(Index)[this._ChannelIndex];
}
private int _ChannelIndex;
private TSignal _Source;
}
}
/// <summary>
/// A representation of a discrete signal that can only be read in one direction.
/// </summary>
public abstract class DiscreteFeed<TSample>
{
/// <summary>
/// Returns true and reads a sample from the data, or returns false to indicate no more data
/// to read.
/// </summary>
public abstract bool Read(ref TSample Data);
/// <summary>
/// Reads data to an array. Returns how many samples were read, which will only be lower than amount
/// if the given section intersects the end of the feed.
/// </summary>
public virtual int Read(TSample[] Data, int Offset, int Amount)
{
int amountread = 0;
TSample samp = default(TSample);
while (Amount > 0 && this.Read(ref samp))
{
Data[Offset] = samp;
Amount--;
Offset++;
amountread++;
}
return amountread;
}
/// <summary>
/// Creates a feed by reading data from the given signal.
/// </summary>
public static DiscreteFeed<TSample> Create<TSignal>(TSignal Signal, int Offset)
where TSignal : DiscreteSignal<TSample>
{
return new _SignalFeed<TSignal>(Signal, Offset);
}
private class _SignalFeed<TSignal> : DiscreteFeed<TSample>
where TSignal : DiscreteSignal<TSample>
{
public _SignalFeed(TSignal Source, int Offset)
{
this._Source = Source;
this._Offset = Offset;
}
public override bool Read(ref TSample Data)
{
if (this._Offset < this._Source.Size)
{
Data = this._Source.Read(this._Offset);
this._Offset++;
return true;
}
return false;
}
private int _Offset;
private TSignal _Source;
}
}
}