OSCAR-code/sleepyhead/SleepLib/event.cpp
Sean Stangl 9dbe702a40 Standardize project modelines and include license and copyright.
Signed-off-by: Mark Watkins <jedimark@users.sourceforge.net>
2014-04-10 13:29:53 +10:00

326 lines
7.7 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
*
* SleepLib Event Class Implementation
*
* Copyright (c) 2011-2014 Mark Watkins <jedimark@users.sourceforge.net>
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of the Linux
* distribution for more details. */
#include <QDebug>
#include "event.h"
EventList::EventList(EventListType et,EventDataType gain, EventDataType offset, EventDataType min, EventDataType max,double rate,bool second_field)
:m_type(et),m_gain(gain),m_offset(offset),m_min(min),m_max(max),m_rate(rate),m_second_field(second_field)
{
m_first=m_last=0;
m_count=0;
if (min==max) { // Update Min & Max unless forceably set here..
m_update_minmax=true;
m_min2=m_min=999999999;
m_max2=m_max=-999999999;
} else {
m_update_minmax=false;
}
m_data.reserve(2048);
// Reserve a few to increase performace??
}
EventList::~EventList()
{
}
void EventList::clear()
{
m_min2=m_min=999999999;
m_max2=m_max=-999999999;
m_update_minmax=true;
m_first=m_last=0;
m_count=0;
m_data.clear();
m_data2.clear();
m_time.clear();
}
qint64 EventList::time(quint32 i)
{
if (m_type==EVL_Event) {
return m_first+qint64(m_time[i]);
}
return m_first+qint64((EventDataType(i)*m_rate));
}
EventDataType EventList::data(quint32 i)
{
return EventDataType(m_data[i])*m_gain;
}
EventDataType EventList::data2(quint32 i)
{
return EventDataType(m_data2[i]);
}
void EventList::AddEvent(qint64 time, EventStoreType data)
{
m_data.push_back(data);
// Apply gain & offset
EventDataType val=EventDataType(data)*m_gain; // ignoring m_offset
if (m_update_minmax) {
if (m_count==0) {
m_max=m_min=val;
} else {
if (m_min>val) m_min=val;
if (m_max<val) m_max=val;
}
}
if (!m_first) {
m_first=time;
m_last=time;
}
if (m_first>time) {
// Crud.. Update all the previous records
// This really shouldn't happen.
qint32 t=(m_first-time);
for (quint32 i=0;i<m_count;i++) {
m_time[i]-=t;
}
m_first=time;
}
if (m_last < time)
m_last=time;
quint32 t=(time-m_first);
m_time.push_back(t);
m_count++;
}
void EventList::AddEvent(qint64 time, EventStoreType data, EventStoreType data2)
{
// Apply gain & offset
m_data.push_back(data);
if (m_second_field) {
m_data2.push_back(data2);
if (m_min2>data2) m_min2=data2;
if (m_max2<data2) m_max2=data2;
}
EventDataType val=EventDataType(data)*m_gain+m_offset;
if (m_update_minmax) {
if (m_min>val) m_min=val;
if (m_max<val) m_max=val;
}
if (!m_first) {
m_first=time;
m_last=time;
}
if (m_first>time) {
// Crud.. Update all the previous records
// This really shouldn't happen.
qint32 t=(m_first-time);
for (quint32 i=0;i<m_count;i++) {
m_time[i]-=t;
}
m_first=time;
}
if (m_last < time)
m_last=time;
quint32 t=(time-m_first);
m_time.push_back(t);
m_count++;
}
// Adds a consecutive waveform chunk
void EventList::AddWaveform(qint64 start, qint16 * data, int recs, qint64 duration)
{
if (m_type!=EVL_Waveform) {
qWarning() << "Attempted to add waveform data to non-waveform object";
return;
}
if (!m_rate) {
qWarning() << "Attempted to add waveform without setting sample rate";
return;
}
qint64 last=start+duration;
if (!m_first) {
m_first=start;
m_last=last;
}
if (m_last>start) {
//qWarning() << "Attempted to add waveform with previous timestamp";
// return;
// technically start should equal m_last+1 sample.. check this too.
}
if (m_last<last) {
m_last=last;
}
// TODO: Check waveform chunk really is contiguos
//double rate=duration/recs;
//realloc buffers.
int r=m_count;
m_count+=recs;
m_data.resize(m_count);
EventStoreType *edata=m_data.data();
EventStoreType raw;
qint16 * ep=data+recs;
qint16 * sp;
EventStoreType * dp=&edata[r];
if (m_update_minmax) {
register EventDataType min=m_min,max=m_max,val,gain=m_gain;
//if (m_offset;
for (sp=data; sp<ep; sp++) {
*dp++=raw=*sp;
val=EventDataType(*sp)*gain+m_offset;
if (min > val) min=val;
if (max < val) max=val;
}
m_min=min;
m_max=max;
} else {
//register EventDataType val,gain=m_gain;
for (sp=data; sp < ep; sp++) {
*dp++=raw=*sp;
//val=EventDataType(raw)*gain;
}
}
}
void EventList::AddWaveform(qint64 start, unsigned char * data, int recs, qint64 duration)
{
if (m_type!=EVL_Waveform) {
qWarning() << "Attempted to add waveform data to non-waveform object";
return;
}
if (!m_rate) {
qWarning() << "Attempted to add waveform without setting sample rate";
return;
}
// duration=recs*rate;
qint64 last=start+duration;
if (!m_first) {
m_first=start;
m_last=last;
}
if (m_last>start) {
//qWarning() << "Attempted to add waveform with previous timestamp";
// return;
// technically start should equal m_last+1 sample.. check this too.
}
if (m_last<last) {
m_last=last;
}
// TODO: Check waveform chunk really is contiguos
//realloc buffers.
int r=m_count;
m_count+=recs;
m_data.resize(m_count);
EventStoreType *edata=m_data.data();
EventStoreType raw;
EventDataType val;
unsigned char * sp;
unsigned char * ep=data+recs;
EventStoreType * dp=&edata[r];
if (m_update_minmax) {
// ignoring m_offset
for (sp=data; sp < ep; sp++) {
raw=*sp;
val=EventDataType(raw)*m_gain;
if (m_min>val) m_min=val;
if (m_max<val) m_max=val;
*dp++=raw;
}
} else {
for (sp=data; sp < ep; sp++) {
raw=*sp;
val=EventDataType(raw)*m_gain;
*dp++=raw;
}
}
}
void EventList::AddWaveform(qint64 start, char * data, int recs, qint64 duration)
{
if (m_type!=EVL_Waveform) {
qWarning() << "Attempted to add waveform data to non-waveform object";
return;
}
if (!m_rate) {
qWarning() << "Attempted to add waveform without setting sample rate";
return;
}
// duration=recs*rate;
qint64 last=start+duration;
if (!m_first) {
m_first=start;
m_last=last;
} else {
if (m_last>start) {
//qWarning() << "Attempted to add waveform with previous timestamp";
//return;
// technically start should equal m_last+1 sample.. check this too.
}
if (m_last<last) {
m_last=last;
}
}
// TODO: Check waveform chunk really is contiguos
//realloc buffers.
int r=m_count;
m_count+=recs;
m_data.resize(m_count);
EventStoreType *edata=m_data.data();
EventStoreType raw;
EventDataType val;
char * sp;
char * ep=data+recs;
EventStoreType * dp=&edata[r];
if (m_update_minmax) {
for (sp=data; sp < ep; sp++) {
raw=*sp;
val=EventDataType(val)*m_gain+m_offset;
if (m_min>val) m_min=val;
if (m_max<val) m_max=val;
*dp++=raw;
}
} else {
for (sp=data; sp < ep; sp++) {
raw=*sp;
val=EventDataType(val)*m_gain+m_offset;
*dp++=raw;
}
}
}