TDiscreteDataSequence.h
Go to the documentation of this file.
1 #ifndef imeas_TDiscreteDataSequence_included
2 #define imeas_TDiscreteDataSequence_included
3 
4 
5 // STL includes
6 #include <cstring>
7 
8 // Qt includes
9 #include <QtCore/QtGlobal>
10 #if QT_VERSION >= 0x050000
11 #include <QtCore/QtMath>
12 #else
13 #include <QtCore/qmath.h>
14 #endif
15 
16 // ACF includes
17 #include <istd/CChangeNotifier.h>
18 #include <istd/TOptDelPtr.h>
19 #include <istd/TSmartPtr.h>
20 #include <iser/IArchive.h>
21 #include <iser/CArchiveTag.h>
22 
24 
25 
26 namespace imeas
27 {
28 
29 
30 template <typename Element>
32 {
33 public:
35 
36  // reimplemented (imeas::IDiscreteDataSequence)
37  virtual bool CreateDiscreteSequence(
38  int samplesCount,
39  void* dataPtr,
40  bool releaseFlag,
41  int sampleDiff,
42  int channelDiff,
43  int sampleDepth,
44  int channelsCount = 1);
45  virtual bool CreateDiscreteSequenceWithInfo(
47  int samplesCount,
48  void* dataPtr,
49  bool releaseFlag,
50  int sampleDiff,
51  int channelDiff,
52  int sampleDepth,
53  int channelsCount = 1);
54 
55  virtual int GetSampleDepth() const;
56  virtual quint32 GetDiscreteSample(int position, int channel = 0) const;
57  virtual bool SetDiscreteSample(int position, int channel, quint32 sample);
58 
59  // reimplemented (imeas::IDataSequence)
60  virtual bool CreateSequence(int samplesCount, int channelsCount = 1);
61  virtual bool CreateSequenceWithInfo(
63  int samplesCount = -1,
64  int channelsCount = -1);
65  virtual const IDataSequenceInfo* GetSequenceInfo() const;
66  virtual bool IsEmpty() const;
67  virtual void ResetSequence();
68  virtual int GetSamplesCount() const;
69  virtual int GetChannelsCount() const;
70  virtual double GetSample(int index, int channel = 0) const;
71  virtual void SetSample(int index, int channel, double value);
72 
73  // reimplemented (iser::ISerializable)
74  virtual bool Serialize(iser::IArchive& archive);
75 
76  // reimplemented (istd::IChangeable)
77  virtual bool CopyFrom(const istd::IChangeable& object, CompatibilityMode mode = CM_WITHOUT_REFS);
78 
79 private:
80  istd::TOptDelPtr<Element, true> m_sampleBuffer;
81 
82  int m_allocatedElementsCount;
83  int m_samplesCount;
84  int m_channelsCount;
85  int m_sampleDiff;
86  int m_channelDiff;
87  double m_normFactor;
88 
90 };
91 
92 
93 // public methods
94 
95 template <typename Element>
97 : m_allocatedElementsCount(0),
98  m_samplesCount(0),
99  m_channelsCount(0),
100  m_sampleDiff(0),
101  m_channelDiff(0)
102 {
103  m_normFactor = qPow(2.0, double(sizeof(Element) * 8)) - 1;
104 }
105 
106 
107 // reimplemented (imeas::IDiscreteDataSequence)
108 
109 template <typename Element>
111  int samplesCount,
112  void* dataPtr,
113  bool releaseFlag,
114  int sampleDiff,
115  int channelDiff,
116  int sampleDepth,
117  int channelsCount)
118 {
119  if (sampleDepth != sizeof(Element) * 8){
120  return false;
121  }
122 
123  m_sampleBuffer.SetPtr((Element*)dataPtr, releaseFlag);
124 
125  m_allocatedElementsCount = 0;
126  m_samplesCount = samplesCount;
127  m_channelsCount = channelsCount;
128  m_sampleDiff = (sampleDiff != 0) ? sampleDiff : int(channelsCount * sizeof(Element));
129  m_channelDiff = (channelDiff != 0) ? channelDiff: sizeof(Element);
130 
131  return true;
132 }
133 
134 
135 template <typename Element>
138  int samplesCount,
139  void* dataPtr,
140  bool releaseFlag,
141  int sampleDiff,
142  int channelDiff,
143  int sampleDepth,
144  int channelsCount)
145 {
146  m_sequenceInfoPtr = infoPtr;
147 
148  return CreateDiscreteSequence(samplesCount, dataPtr, releaseFlag, sampleDiff, channelDiff, sampleDepth, channelsCount);
149 }
150 
151 
152 template <typename Element>
154 {
155  return sizeof(Element) * 8;
156 }
157 
158 
159 template <typename Element>
160 quint32 TDiscreteDataSequence<Element>::GetDiscreteSample(int position, int channel) const
161 {
162  const Element& element = *(const Element*)((const quint8*)m_sampleBuffer.GetPtr() + position * m_sampleDiff + channel * m_channelDiff);
163 
164  return element;
165 }
166 
167 
168 template <typename Element>
169 bool TDiscreteDataSequence<Element>::SetDiscreteSample(int position, int channel, quint32 sample)
170 {
171  Element& element = *(Element*)((quint8*)m_sampleBuffer.GetPtr() + position * m_sampleDiff + channel * m_channelDiff);
172 
173  element = Element(sample);
174 
175  return true;
176 }
177 
178 
179 // reimplemented (imeas::IDataSequence)
180 
181 template <typename Element>
182 bool TDiscreteDataSequence<Element>::CreateSequence(int samplesCount, int channelsCount)
183 {
184  if (m_sequenceInfoPtr.IsValid()){
185  int flags = m_sequenceInfoPtr->GetSequenceInfoFlags();
186 
187  if (samplesCount < 0){
188  samplesCount = m_sequenceInfoPtr->GetDefaultSamplesCount();
189  }
190  else if (((flags & IDataSequenceInfo::SIF_SAMPLES_COUNT_FIXED) != 0) && (samplesCount != m_sequenceInfoPtr->GetDefaultSamplesCount())){
191  return false;
192  }
193 
194  if (channelsCount < 0){
195  channelsCount = m_sequenceInfoPtr->GetDefaultChannelsCount();
196  }
197  else if (((flags & IDataSequenceInfo::SIF_CHANNELS_COUNT_FIXED) != 0) && (channelsCount != m_sequenceInfoPtr->GetDefaultChannelsCount())){
198  return false;
199  }
200  }
201 
202  if ((samplesCount < 0) || (channelsCount < 0)){
203  return false;
204  }
205 
206  int elementsCount = samplesCount * channelsCount;
207  if ( (elementsCount > m_allocatedElementsCount) ||
208  (elementsCount * 2 < m_allocatedElementsCount)){
209  m_sampleBuffer.SetPtr(new Element[elementsCount], true);
210  m_allocatedElementsCount = elementsCount;
211  }
212 
213  m_samplesCount = samplesCount;
214  m_channelsCount = channelsCount;
215  m_sampleDiff = channelsCount * sizeof(Element);
216  m_channelDiff = sizeof(Element);
217 
218  return true;
219 }
220 
221 
222 template <typename Element>
225  int samplesCount,
226  int channelsCount)
227 {
228  m_sequenceInfoPtr = infoPtr;
229 
230  return CreateSequence(samplesCount, channelsCount);
231 }
232 
233 
234 template <typename Element>
236 {
237  return m_sequenceInfoPtr.GetPtr();
238 }
239 
240 
241 template <typename Element>
243 {
244  return m_samplesCount <= 0;
245 }
246 
247 
248 template <typename Element>
250 {
251  m_allocatedElementsCount = 0;
252  m_sampleBuffer.Reset();
253  m_samplesCount = 0;
254  m_channelsCount = 0;
255 }
256 
257 
258 template <typename Element>
260 {
261  return m_samplesCount;
262 }
263 
264 
265 template <typename Element>
267 {
268  return m_channelsCount;
269 }
270 
271 
272 template <typename Element>
273 double TDiscreteDataSequence<Element>::GetSample(int index, int channel) const
274 {
275  const Element& element = *(const Element*)((const quint8*)m_sampleBuffer.GetPtr() + index * m_sampleDiff + channel * m_channelDiff);
276 
277  return double(element) / m_normFactor;
278 }
279 
280 
281 template <typename Element>
282 void TDiscreteDataSequence<Element>::SetSample(int index, int channel, double value)
283 {
284  Element& element = *(Element*)((quint8*)m_sampleBuffer.GetPtr() + index * m_sampleDiff + channel * m_channelDiff);
285 
286  element = Element(value * m_normFactor - I_BIG_EPSILON);
287 }
288 
289 
290 // reimplemented (iser::ISerializable)
291 
292 template <typename Element>
294 {
295  static iser::CArchiveTag channelsCountTag("ChannelsCount", "Number of channels", iser::CArchiveTag::TT_LEAF);
296  static iser::CArchiveTag samplesListTag("SampleList", "List of sample values", iser::CArchiveTag::TT_MULTIPLE);
297  static iser::CArchiveTag channelsTag("Channels", "List of sample values", iser::CArchiveTag::TT_GROUP, &samplesListTag);
298 
299  bool retVal = true;
300 
301  int channelsCount = GetChannelsCount();
302  retVal = retVal && archive.BeginTag(channelsCountTag);
303  retVal = retVal && archive.Process(channelsCount);
304  retVal = retVal && archive.EndTag(channelsCountTag);
305 
306  int samplesCount = GetSamplesCount();
307 
308  retVal = retVal && archive.BeginMultiTag(samplesListTag, channelsTag, samplesCount);
309 
310  if (!retVal){
311  return false;
312  }
313 
314  bool isStoring = archive.IsStoring();
315 
316  istd::CChangeNotifier notifier(archive.IsStoring()? NULL: this);
317  Q_UNUSED(notifier);
318 
319  if (isStoring){
320  for (int i = 0; i < samplesCount; ++i){
321  retVal = retVal && archive.BeginTag(channelsTag);
322  for (int channelIndex = 0; channelIndex < channelsCount; ++channelIndex){
323  Element sample = Element(GetDiscreteSample(i, channelIndex));
324 
325  retVal = retVal && archive.Process(sample);
326  }
327  retVal = retVal && archive.EndTag(channelsTag);
328  }
329  }
330  else{
331  if ((samplesCount < 0) || (channelsCount < 0) || !CreateSequence(samplesCount, channelsCount)){
332  return false;
333  }
334 
335  for (int i = 0; i < samplesCount; ++i){
336  retVal = retVal && archive.BeginTag(channelsTag);
337  for (int channelIndex = 0; channelIndex < channelsCount; ++channelIndex){
338  Element sample = 0;
339 
340  retVal = retVal && archive.Process(sample);
341 
342  SetDiscreteSample(i, channelIndex, sample);
343  }
344  retVal = retVal && archive.EndTag(channelsTag);
345  }
346  }
347 
348  retVal = retVal && archive.EndTag(samplesListTag);
349 
350  return retVal;
351 }
352 
353 
354 // reimplemented (istd::IChangeable)
355 
356 template <typename Element>
357 bool TDiscreteDataSequence<Element>::CopyFrom(const istd::IChangeable& object, CompatibilityMode /*mode*/)
358 {
359  const IDataSequence* sequencePtr = dynamic_cast<const IDataSequence*>(&object);
360  if (sequencePtr != NULL){
361  const TDiscreteDataSequence<Element>* nativeSequencePtr = dynamic_cast<const TDiscreteDataSequence<Element>*>(sequencePtr);
362  if ( (nativeSequencePtr != NULL) &&
363  (nativeSequencePtr->m_channelDiff == sizeof(Element)) &&
364  (nativeSequencePtr->m_sampleDiff == int(nativeSequencePtr->m_channelsCount * sizeof(Element)))){
365  m_samplesCount = nativeSequencePtr->m_samplesCount;
366  m_channelsCount = nativeSequencePtr->m_channelsCount;
367  m_sampleDiff = sizeof(Element) * m_channelsCount;
368  m_channelDiff = sizeof(Element);
369 
370  m_allocatedElementsCount = m_samplesCount * m_channelsCount;
371  if (m_allocatedElementsCount > 0){
372  m_sampleBuffer.SetPtr(new Element[m_allocatedElementsCount], true);
373  if (m_sampleBuffer.IsValid()){
374  std::memcpy( m_sampleBuffer.GetPtr(),
375  nativeSequencePtr->m_sampleBuffer.GetPtr(),
376  m_allocatedElementsCount * sizeof(Element));
377  }
378  else{
379  ResetSequence();
380 
381  return false;
382  }
383  }
384  else{
385  m_sampleBuffer.Reset();
386  }
387 
388  }
389  else{
390  int samplesCount = sequencePtr->GetSamplesCount();
391  int channelsCount = sequencePtr->GetChannelsCount();
392 
393  Q_ASSERT(samplesCount >= 0);
394  Q_ASSERT(channelsCount >= 0);
395 
396  if (!CreateSequence(samplesCount, channelsCount)){
397  return false;
398  }
399 
400  for (int sampleIndex = 0; sampleIndex < samplesCount; ++sampleIndex){
401  for (int channelIndex = 0; channelIndex < channelsCount; ++channelIndex){
402  double sample = sequencePtr->GetSample(sampleIndex, channelIndex);
403 
404  SetSample(sampleIndex, channelIndex, sample);
405  }
406  }
407  }
408 
409  return true;
410  }
411 
412  return false;
413 }
414 
415 
420 
421 
422 } // namespace imeas
423 
424 
425 #endif // !imeas_TDiscreteDataSequence_included
426 
427 
TDiscreteDataSequence< quint8 > CSimpleSamplesSequence8
virtual int GetChannelsCount() const =0
Get number of channels.
TDiscreteDataSequence< quint32 > CSimpleSamplesSequence32
virtual int GetSamplesCount() const =0
Get size of this raster sequence.
virtual bool CreateSequence(int samplesCount, int channelsCount=1)
Create container for sample sequence with specified number of samples, channels and sample depth...
virtual int GetSampleDepth() const
Get number of bits used to represent single sample.
TDiscreteDataSequence< quint16 > CSimpleSamplesSequence16
virtual double GetSample(int index, int channel=0) const
Get sample value at specified index.
virtual bool CreateDiscreteSequence(int samplesCount, void *dataPtr, bool releaseFlag, int sampleDiff, int channelDiff, int sampleDepth, int channelsCount=1)
Create container for sample sequence using external samples buffer.
virtual bool CopyFrom(const istd::IChangeable &object, CompatibilityMode mode=CM_WITHOUT_REFS)
virtual const IDataSequenceInfo * GetSequenceInfo() const
Get additional information about this sequence.
virtual void SetSample(int index, int channel, double value)
Set sample value at specified index.
virtual double GetSample(int index, int channel=0) const =0
Get sample value at specified index.
virtual bool BeginMultiTag(const CArchiveTag &tag, const CArchiveTag &subTag, int &count)=0
General definition of sequence contains discrete sample values in regular time grid.
virtual bool SetDiscreteSample(int position, int channel, quint32 sample)
Set discrete sample at specified position.
virtual bool Serialize(iser::IArchive &archive)
virtual bool IsEmpty() const
Return true if this sequence has no sample.
Stores additional data sequence data used to interpret samples value correctly.
#define NULL
virtual bool CreateDiscreteSequenceWithInfo(const istd::TTransPtr< const IDataSequenceInfo > &infoPtr, int samplesCount, void *dataPtr, bool releaseFlag, int sampleDiff, int channelDiff, int sampleDepth, int channelsCount=1)
Create container for sample sequence with additional sequence info using external samples buffer...
TDiscreteDataSequence< quint64 > CSimpleSamplesSequence64
Number of channels is fixed by this info object.
General definition of sequence contains samples in regular time grid.
Definition: IDataSequence.h:20
virtual void ResetSequence()
Reset this sequence.
virtual int GetSamplesCount() const
Get size of this raster sequence.
Number of samples is fixed by this info object.
virtual quint32 GetDiscreteSample(int position, int channel=0) const
Get discrete sample at specified position.
virtual int GetChannelsCount() const
Get number of channels.
virtual bool CreateSequenceWithInfo(const istd::TTransPtr< const IDataSequenceInfo > &infoPtr, int samplesCount=-1, int channelsCount=-1)
Create sequence and set the info object.

© 2007-2017 Witold Gantzke and Kirill Lepskiy