/* SleepLib Event Class Implementation Copyright (c)2011 Mark Watkins <jedimark@users.sourceforge.net> License: GPL */ #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() { } 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_min>val) m_min=val; else 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; 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; } } }