2011-06-26 08:30:44 +00:00
/*
SleepLib PRS1 Loader Implementation
Author : Mark Watkins < jedimark64 @ users . sourceforge . net >
License : GPL
*/
2011-07-30 00:36:31 +00:00
# include <QApplication>
2011-06-26 08:30:44 +00:00
# include <QString>
# include <QDateTime>
# include <QDir>
# include <QFile>
# include <QMessageBox>
# include <QProgressBar>
2011-07-01 10:10:44 +00:00
# include <QDebug>
2011-07-27 09:21:53 +00:00
# include <cmath>
2011-06-26 08:30:44 +00:00
# include "prs1_loader.h"
# include "SleepLib/session.h"
2011-07-10 14:23:07 +00:00
const int PRS1_MAGIC_NUMBER = 2 ;
const int PRS1_SUMMARY_FILE = 1 ;
const int PRS1_EVENT_FILE = 2 ;
const int PRS1_WAVEFORM_FILE = 5 ;
2011-06-26 08:30:44 +00:00
//********************************************************************************************
/// IMPORTANT!!!
//********************************************************************************************
// Please INCREMENT the prs1_data_version in prs1_loader.h when making changes to this loader
// that change loader behaviour or modify channels.
//********************************************************************************************
extern QProgressBar * qprogress ;
map < int , QString > ModelMap ;
PRS1 : : PRS1 ( Profile * p , MachineID id ) : CPAP ( p , id )
{
m_class = prs1_class_name ;
properties [ " Brand " ] = " Philips Respironics " ;
properties [ " Model " ] = " System One " ;
//SleepFlags= { CPAP_RERA, PRS1_VSnore2, CPAP_FlowLimit, CPAP_Hypopnea, CPAP_Obstructive, CPAP_ClearAirway, CPAP_CSR };
}
PRS1 : : ~ PRS1 ( )
{
}
PRS1Loader : : PRS1Loader ( )
{
2011-07-27 09:21:53 +00:00
m_buffer = NULL ;
2011-06-26 08:30:44 +00:00
}
PRS1Loader : : ~ PRS1Loader ( )
{
for ( map < QString , Machine * > : : iterator i = PRS1List . begin ( ) ; i ! = PRS1List . end ( ) ; i + + ) {
delete i - > second ;
}
}
Machine * PRS1Loader : : CreateMachine ( QString serial , Profile * profile )
{
2011-07-24 16:34:53 +00:00
if ( ! profile )
return NULL ;
2011-07-01 10:10:44 +00:00
qDebug ( ) < < " Create Machine " < < serial ;
2011-06-26 08:30:44 +00:00
vector < Machine * > ml = profile - > GetMachines ( MT_CPAP ) ;
bool found = false ;
for ( vector < Machine * > : : iterator i = ml . begin ( ) ; i ! = ml . end ( ) ; i + + ) {
if ( ( ( * i ) - > GetClass ( ) = = " PRS1 " ) & & ( ( * i ) - > properties [ " Serial " ] = = serial ) ) {
PRS1List [ serial ] = * i ; //static_cast<CPAP *>(*i);
found = true ;
break ;
}
}
if ( found ) return PRS1List [ serial ] ;
//assert(PRS1List.find(serial)==PRS1List.end())
Machine * m = new PRS1 ( profile , 0 ) ;
PRS1List [ serial ] = m ;
profile - > AddMachine ( m ) ;
m - > properties [ " Serial " ] = serial ;
return m ;
}
bool isdigit ( QChar c )
{
if ( ( c > = ' 0 ' ) & & ( c < = ' 9 ' ) ) return true ;
return false ;
}
2011-07-15 13:30:41 +00:00
int PRS1Loader : : Open ( QString & path , Profile * profile )
2011-06-26 08:30:44 +00:00
{
QString newpath ;
QString pseries = " P-Series " ;
if ( path . endsWith ( " / " + pseries ) ) {
newpath = path ;
} else {
newpath = path + " / " + pseries ;
}
QDir dir ( newpath ) ;
if ( ( ! dir . exists ( ) | | ! dir . isReadable ( ) ) )
return 0 ;
2011-07-27 09:21:53 +00:00
2011-07-22 13:46:17 +00:00
//qDebug() << "PRS1Loader::Open newpath=" << newpath;
2011-06-26 08:30:44 +00:00
dir . setFilter ( QDir : : NoDotAndDotDot | QDir : : Dirs | QDir : : Files | QDir : : Hidden | QDir : : NoSymLinks ) ;
dir . setSorting ( QDir : : Name ) ;
QFileInfoList flist = dir . entryInfoList ( ) ;
list < QString > SerialNumbers ;
list < QString > : : iterator sn ;
for ( int i = 0 ; i < flist . size ( ) ; i + + ) {
QFileInfo fi = flist . at ( i ) ;
QString filename = fi . fileName ( ) ;
if ( ( filename [ 0 ] = = ' P ' ) & & ( isdigit ( filename [ 1 ] ) ) & & ( isdigit ( filename [ 2 ] ) ) ) {
SerialNumbers . push_back ( filename ) ;
} else if ( filename . toLower ( ) = = " last.txt " ) { // last.txt points to the current serial number
QString file = fi . canonicalFilePath ( ) ;
QFile f ( file ) ;
if ( ! fi . isReadable ( ) ) {
2011-07-01 10:10:44 +00:00
qDebug ( ) < < " PRS1Loader: last.txt exists but I couldn't read it! " ;
2011-06-26 08:30:44 +00:00
continue ;
}
if ( ! f . open ( QIODevice : : ReadOnly ) ) {
2011-07-01 10:10:44 +00:00
qDebug ( ) < < " PRS1Loader: last.txt exists but I couldn't open it! " ;
2011-06-26 08:30:44 +00:00
continue ;
}
last = f . readLine ( 64 ) ;
last = last . trimmed ( ) ;
f . close ( ) ;
}
}
if ( SerialNumbers . empty ( ) ) return 0 ;
2011-07-27 09:21:53 +00:00
m_buffer = new unsigned char [ max_load_buffer_size ] ; //allocate once and reuse.
2011-06-26 08:30:44 +00:00
Machine * m ;
for ( sn = SerialNumbers . begin ( ) ; sn ! = SerialNumbers . end ( ) ; sn + + ) {
QString s = * sn ;
m = CreateMachine ( s , profile ) ;
try {
if ( m ) OpenMachine ( m , newpath + " / " + ( * sn ) , profile ) ;
} catch ( OneTypePerDay e ) {
profile - > DelMachine ( m ) ;
PRS1List . erase ( s ) ;
QMessageBox : : warning ( NULL , " Import Error " , " This Machine Record cannot be imported in this profile. \n The Day records overlap with already existing content. " , QMessageBox : : Ok ) ;
delete m ;
}
}
2011-07-27 09:21:53 +00:00
delete [ ] m_buffer ;
2011-06-26 08:30:44 +00:00
return PRS1List . size ( ) ;
}
2011-07-15 13:30:41 +00:00
2011-06-26 08:30:44 +00:00
bool PRS1Loader : : ParseProperties ( Machine * m , QString filename )
{
QFile f ( filename ) ;
if ( ! f . open ( QIODevice : : ReadOnly ) )
return false ;
QString line ;
map < QString , QString > prop ;
QString s = f . readLine ( ) ;
QChar sep = ' = ' ;
QString key , value ;
while ( ! f . atEnd ( ) ) {
key = s . section ( sep , 0 , 0 ) ; //BeforeFirst(sep);
if ( key = = s ) continue ;
value = s . section ( sep , 1 ) . trimmed ( ) ; //AfterFirst(sep).Strip();
if ( value = = s ) continue ;
prop [ key ] = value ;
s = f . readLine ( ) ;
}
bool ok ;
2011-07-11 01:58:51 +00:00
QString pt = prop [ " ProductType " ] ;
int i = pt . toInt ( & ok , 0 ) ;
2011-06-26 08:30:44 +00:00
if ( ok ) {
if ( ModelMap . find ( i ) ! = ModelMap . end ( ) ) {
m - > properties [ " SubModel " ] = ModelMap [ i ] ;
}
}
if ( prop [ " SerialNumber " ] ! = m - > properties [ " Serial " ] ) {
2011-07-01 10:10:44 +00:00
qDebug ( ) < < " Serial Number in PRS1 properties.txt doesn't match directory structure " ;
2011-06-26 08:30:44 +00:00
} else prop . erase ( " SerialNumber " ) ; // already got it stored.
for ( map < QString , QString > : : iterator i = prop . begin ( ) ; i ! = prop . end ( ) ; i + + ) {
m - > properties [ i - > first ] = i - > second ;
}
f . close ( ) ;
return true ;
}
int PRS1Loader : : OpenMachine ( Machine * m , QString path , Profile * profile )
{
2011-07-01 10:10:44 +00:00
qDebug ( ) < < " Opening PRS1 " < < path ;
2011-06-26 08:30:44 +00:00
QDir dir ( path ) ;
if ( ! dir . exists ( ) | | ( ! dir . isReadable ( ) ) )
return false ;
dir . setFilter ( QDir : : NoDotAndDotDot | QDir : : Dirs | QDir : : Files | QDir : : Hidden | QDir : : NoSymLinks ) ;
dir . setSorting ( QDir : : Name ) ;
QFileInfoList flist = dir . entryInfoList ( ) ;
QString filename ;
if ( qprogress ) qprogress - > setValue ( 0 ) ;
list < QString > paths ;
for ( int i = 0 ; i < flist . size ( ) ; i + + ) {
QFileInfo fi = flist . at ( i ) ;
filename = fi . fileName ( ) ;
if ( ( filename [ 0 ] . toLower ( ) = = ' p ' ) & & ( isdigit ( filename [ 1 ] ) ) ) {
paths . push_back ( fi . canonicalFilePath ( ) ) ;
} else if ( filename . toLower ( ) = = " properties.txt " ) {
ParseProperties ( m , fi . canonicalFilePath ( ) ) ;
} else if ( filename . toLower ( ) = = " e " ) {
// don't really give a crap about .004 files yet.
}
//if (qprogress) qprogress->Pulse();
}
SessionID session ;
long ext ;
typedef vector < QString > StringList ;
map < SessionID , StringList > sessfiles ;
int size = paths . size ( ) ;
int cnt = 0 ;
bool ok ;
for ( list < QString > : : iterator p = paths . begin ( ) ; p ! = paths . end ( ) ; p + + ) {
dir . setPath ( * p ) ;
if ( ! dir . exists ( ) | | ! dir . isReadable ( ) ) continue ;
flist = dir . entryInfoList ( ) ;
for ( int i = 0 ; i < flist . size ( ) ; i + + ) {
QFileInfo fi = flist . at ( i ) ;
2011-07-03 09:13:54 +00:00
QString ext_s = fi . fileName ( ) . section ( " . " , - 1 ) ;
QString session_s = fi . fileName ( ) . section ( " . " , 0 , - 2 ) ;
2011-06-26 08:30:44 +00:00
ext = ext_s . toLong ( & ok ) ;
if ( ! ok ) continue ;
session = session_s . toLong ( & ok ) ;
if ( ! ok ) continue ;
if ( sessfiles [ session ] . capacity ( ) = = 0 ) sessfiles [ session ] . resize ( 3 ) ;
if ( ext = = 1 ) {
sessfiles [ session ] [ 0 ] = fi . canonicalFilePath ( ) ;
} else if ( ext = = 2 ) {
sessfiles [ session ] [ 1 ] = fi . canonicalFilePath ( ) ;
} else if ( ext = = 5 ) {
sessfiles [ session ] [ 2 ] = fi . canonicalFilePath ( ) ;
}
cnt + + ;
2011-06-30 10:56:22 +00:00
if ( qprogress ) qprogress - > setValue ( ( float ( cnt ) / float ( size ) * 33.0 ) ) ;
2011-07-30 00:36:31 +00:00
QApplication : : processEvents ( ) ;
2011-06-26 08:30:44 +00:00
}
}
size = sessfiles . size ( ) ;
if ( size = = 0 )
return 0 ;
cnt = 0 ;
for ( map < SessionID , StringList > : : iterator s = sessfiles . begin ( ) ; s ! = sessfiles . end ( ) ; s + + ) {
session = s - > first ;
cnt + + ;
2011-06-30 10:56:22 +00:00
if ( qprogress ) qprogress - > setValue ( 33.0 + ( float ( cnt ) / float ( size ) * 33.0 ) ) ;
2011-07-30 00:36:31 +00:00
QApplication : : processEvents ( ) ;
2011-06-26 08:30:44 +00:00
if ( m - > SessionExists ( session ) ) continue ;
if ( s - > second [ 0 ] . isEmpty ( ) ) continue ;
Session * sess = new Session ( m , session ) ;
if ( ! OpenSummary ( sess , s - > second [ 0 ] ) ) {
2011-07-20 16:48:21 +00:00
//qWarning() << "PRS1Loader: Dodgy summary file " << s->second[0];
2011-06-26 08:30:44 +00:00
2011-07-22 13:46:17 +00:00
delete sess ;
continue ;
2011-06-26 08:30:44 +00:00
}
//sess->SetSessionID(sess->start().GetTicks());
if ( ! s - > second [ 1 ] . isEmpty ( ) ) {
if ( ! OpenEvents ( sess , s - > second [ 1 ] ) ) {
2011-07-01 10:10:44 +00:00
qWarning ( ) < < " PRS1Loader: Couldn't open event file " < < s - > second [ 1 ] ;
2011-06-26 08:30:44 +00:00
}
}
if ( ! s - > second [ 2 ] . isEmpty ( ) ) {
if ( ! OpenWaveforms ( sess , s - > second [ 2 ] ) ) {
2011-07-01 10:10:44 +00:00
qWarning ( ) < < " PRS1Loader: Couldn't open event file " < < s - > second [ 2 ] ;
2011-06-26 08:30:44 +00:00
}
}
const double ignore_thresh = 300.0 / 3600.0 ; // Ignore useless sessions under 5 minute
if ( sess - > hours ( ) < = ignore_thresh ) {
2011-07-27 09:21:53 +00:00
qDebug ( ) < < " Ignoring short session " < < session < < " which is only " < < ( sess - > hours ( ) * 60.0 ) < < " minute(s) long " ;
2011-06-26 08:30:44 +00:00
delete sess ;
continue ;
}
2011-07-27 09:21:53 +00:00
sess - > summary [ CPAP_Obstructive ] = sess - > count ( CPAP_Obstructive ) ;
sess - > summary [ CPAP_Hypopnea ] = sess - > count ( CPAP_Hypopnea ) ;
sess - > summary [ CPAP_ClearAirway ] = sess - > count ( CPAP_ClearAirway ) ;
sess - > summary [ CPAP_RERA ] = sess - > count ( CPAP_RERA ) ;
sess - > summary [ CPAP_FlowLimit ] = sess - > count ( CPAP_FlowLimit ) ;
sess - > summary [ CPAP_VSnore ] = sess - > count ( CPAP_VSnore ) ;
2011-06-26 08:30:44 +00:00
2011-07-27 09:21:53 +00:00
sess - > summary [ CPAP_CSR ] = sess - > sum ( CPAP_CSR ) ;
sess - > summary [ CPAP_Snore ] = sess - > sum ( CPAP_Snore ) ;
2011-06-26 08:30:44 +00:00
2011-07-27 09:21:53 +00:00
if ( sess - > count ( CPAP_IAP ) > 0 ) {
2011-07-12 12:43:10 +00:00
//sess->summary[CPAP_Mode]!=MODE_ASV)
2011-06-26 08:30:44 +00:00
sess - > summary [ CPAP_Mode ] = MODE_BIPAP ;
2011-07-12 12:43:10 +00:00
2011-07-27 09:21:53 +00:00
sess - > summary [ BIPAP_PSAverage ] = sess - > weighted_avg ( CPAP_PS ) ;
sess - > summary [ BIPAP_PSMin ] = sess - > min ( CPAP_PS ) ;
sess - > summary [ BIPAP_PSMax ] = sess - > max ( CPAP_PS ) ;
2011-07-12 12:43:10 +00:00
2011-06-26 08:30:44 +00:00
if ( sess - > summary [ CPAP_PressureReliefType ] . toInt ( ) ! = PR_NONE ) {
sess - > summary [ CPAP_PressureReliefType ] = PR_BIFLEX ;
}
2011-07-27 09:21:53 +00:00
sess - > summary [ CPAP_PressureMedian ] = ( sess - > avg ( CPAP_EAP ) + sess - > avg ( CPAP_IAP ) ) / 2.0 ;
sess - > summary [ CPAP_PressureAverage ] = ( sess - > weighted_avg ( CPAP_IAP ) + sess - > weighted_avg ( CPAP_EAP ) ) / 2.0 ;
sess - > summary [ CPAP_PressureMinAchieved ] = sess - > min ( CPAP_IAP ) ;
sess - > summary [ CPAP_PressureMaxAchieved ] = sess - > max ( CPAP_EAP ) ;
sess - > summary [ BIPAP_EAPAverage ] = sess - > weighted_avg ( CPAP_EAP ) ;
sess - > summary [ BIPAP_EAPMin ] = sess - > min ( CPAP_EAP ) ;
sess - > summary [ BIPAP_EAPMax ] = sess - > max ( CPAP_EAP ) ;
sess - > summary [ BIPAP_IAPAverage ] = sess - > weighted_avg ( CPAP_IAP ) ;
sess - > summary [ BIPAP_IAPMin ] = sess - > min ( CPAP_IAP ) ;
sess - > summary [ BIPAP_IAPMax ] = sess - > max ( CPAP_IAP ) ;
2011-06-26 08:30:44 +00:00
} else {
2011-07-27 09:21:53 +00:00
sess - > summary [ CPAP_PressureMedian ] = sess - > weighted_avg ( CPAP_Pressure ) ;
sess - > summary [ CPAP_PressureAverage ] = sess - > weighted_avg ( CPAP_Pressure ) ;
sess - > summary [ CPAP_PressureMinAchieved ] = sess - > min ( CPAP_Pressure ) ;
sess - > summary [ CPAP_PressureMaxAchieved ] = sess - > max ( CPAP_Pressure ) ;
2011-06-26 08:30:44 +00:00
if ( sess - > summary . find ( CPAP_PressureMin ) = = sess - > summary . end ( ) ) {
sess - > summary [ CPAP_BrokenSummary ] = true ;
2011-07-03 02:43:50 +00:00
//sess->set_last(sess->first());
2011-06-26 08:30:44 +00:00
if ( sess - > summary [ CPAP_PressureMinAchieved ] = = sess - > summary [ CPAP_PressureMaxAchieved ] ) {
sess - > summary [ CPAP_Mode ] = MODE_CPAP ;
} else {
sess - > summary [ CPAP_Mode ] = MODE_UNKNOWN ;
}
sess - > summary [ CPAP_PressureReliefType ] = PR_UNKNOWN ;
}
}
if ( sess - > summary [ CPAP_Mode ] = = MODE_CPAP ) {
sess - > summary [ CPAP_PressureAverage ] = sess - > summary [ CPAP_PressureMin ] ;
sess - > summary [ CPAP_PressureMax ] = sess - > summary [ CPAP_PressureMin ] ;
}
2011-07-27 09:21:53 +00:00
sess - > summary [ CPAP_LeakMinimum ] = sess - > min ( CPAP_Leak ) ;
sess - > summary [ CPAP_LeakMaximum ] = sess - > max ( CPAP_Leak ) ; // should be merged..
sess - > summary [ CPAP_LeakMedian ] = sess - > avg ( CPAP_Leak ) ;
sess - > summary [ CPAP_LeakAverage ] = sess - > weighted_avg ( CPAP_Leak ) ;
2011-06-26 08:30:44 +00:00
2011-07-27 09:21:53 +00:00
sess - > summary [ CPAP_SnoreMinimum ] = sess - > min ( CPAP_Snore ) ;
sess - > summary [ CPAP_SnoreMaximum ] = sess - > max ( CPAP_Snore ) ;
sess - > summary [ CPAP_SnoreMedian ] = sess - > avg ( CPAP_Snore ) ;
sess - > summary [ CPAP_SnoreAverage ] = sess - > weighted_avg ( CPAP_Snore ) ;
2011-06-26 08:30:44 +00:00
//Printf(sess->start().Format()+wxT(" avgsummary=%.3f avgmine=%.3f\n"),sess->summary[CPAP_PressureAverage].GetDouble(),sess->weighted_avg_event_field(CPAP_Pressure,0));
sess - > SetChanged ( true ) ;
2011-07-22 13:46:17 +00:00
m - > AddSession ( sess , profile ) ;
2011-06-26 08:30:44 +00:00
}
QString s ;
s . sprintf ( " %i " , prs1_data_version ) ;
m - > properties [ " DataVersion " ] = s ;
2011-07-22 13:46:17 +00:00
m - > Save ( ) ; // Save any new sessions to disk in our format */
2011-06-26 08:30:44 +00:00
if ( qprogress ) qprogress - > setValue ( 100 ) ;
2011-07-30 00:36:31 +00:00
2011-07-22 13:46:17 +00:00
//qDebug() << "OpenMachine Done";
2011-06-26 08:30:44 +00:00
return true ;
}
bool PRS1Loader : : OpenSummary ( Session * session , QString filename )
{
2011-07-18 02:33:25 +00:00
int size , seconds , br , htype , version , sequence ;
2011-07-02 14:35:50 +00:00
qint64 timestamp ;
2011-06-26 08:30:44 +00:00
unsigned char header [ 24 ] ;
unsigned char ext , sum ;
2011-07-01 10:10:44 +00:00
//qDebug() << "Opening PRS1 Summary " << filename;
2011-06-26 08:30:44 +00:00
QFile f ( filename ) ;
2011-07-10 14:23:07 +00:00
2011-06-26 08:30:44 +00:00
if ( ! f . open ( QIODevice : : ReadOnly ) )
return false ;
if ( ! f . exists ( ) )
return false ;
int hl = 16 ;
br = f . read ( ( char * ) header , hl ) ;
2011-07-10 14:23:07 +00:00
if ( header [ 0 ] ! = PRS1_MAGIC_NUMBER )
2011-06-26 08:30:44 +00:00
return false ;
sequence = size = timestamp = seconds = ext = 0 ;
sequence = ( header [ 10 ] < < 24 ) | ( header [ 9 ] < < 16 ) | ( header [ 8 ] < < 8 ) | header [ 7 ] ;
timestamp = ( header [ 14 ] < < 24 ) | ( header [ 13 ] < < 16 ) | ( header [ 12 ] < < 8 ) | header [ 11 ] ;
size = ( header [ 2 ] < < 8 ) | header [ 1 ] ;
ext = header [ 6 ] ;
2011-07-10 14:23:07 +00:00
htype = header [ 3 ] ; // 00 = normal // 01=waveform // could be a bool?
version = header [ 4 ] ;
2011-07-18 02:33:25 +00:00
sequence = sequence ;
version = version ; // don't need it here?
htype = htype ; // shut the warning up.. this is useless.
2011-07-10 14:23:07 +00:00
if ( ext ! = PRS1_SUMMARY_FILE )
2011-06-26 08:30:44 +00:00
return false ;
size - = ( hl + 2 ) ;
2011-07-10 14:23:07 +00:00
// Calculate header checksum and compare to verify header
2011-06-26 08:30:44 +00:00
sum = 0 ;
for ( int i = 0 ; i < hl - 1 ; i + + ) sum + = header [ i ] ;
if ( sum ! = header [ hl - 1 ] )
return false ;
if ( size < = 19 ) {
2011-07-20 16:48:21 +00:00
// qDebug() << "Ignoring short session file " << filename;
2011-06-26 08:30:44 +00:00
return false ;
}
2011-07-02 14:35:50 +00:00
qint64 date = timestamp * 1000 ;
2011-06-26 08:30:44 +00:00
2011-07-10 14:23:07 +00:00
//memset(m_buffer,0,size);
2011-06-26 08:30:44 +00:00
unsigned char * buffer = m_buffer ;
br = f . read ( ( char * ) buffer , size ) ;
if ( br < size ) {
return false ;
}
if ( size < 0x30 )
return true ;
session - > set_first ( date ) ;
2011-07-10 14:23:07 +00:00
2011-06-26 08:30:44 +00:00
double max ;
session - > summary [ CPAP_PressureMin ] = ( double ) buffer [ 0x03 ] / 10.0 ;
session - > summary [ CPAP_PressureMax ] = max = ( double ) buffer [ 0x04 ] / 10.0 ;
2011-07-10 14:23:07 +00:00
int offset = 0 ;
if ( buffer [ 0x05 ] ! = 0 ) { // This is a time value for ASV stuff
// non zero adds extra fields..
offset = 4 ;
}
session - > summary [ CPAP_RampTime ] = ( int ) buffer [ offset + 0x06 ] ; // Minutes. Convert to seconds/hours here?
session - > summary [ CPAP_RampStartingPressure ] = ( double ) buffer [ offset + 0x07 ] / 10.0 ;
2011-06-26 08:30:44 +00:00
if ( max > 0 ) { // Ignoring bipap until I see some more data.
session - > summary [ CPAP_Mode ] = ( int ) MODE_APAP ;
} else session - > summary [ CPAP_Mode ] = ( int ) MODE_CPAP ;
// This is incorrect..
2011-07-10 14:23:07 +00:00
if ( buffer [ offset + 0x08 ] & 0x80 ) { // Flex Setting
if ( buffer [ offset + 0x08 ] & 0x08 ) {
2011-06-26 08:30:44 +00:00
if ( max > 0 ) session - > summary [ CPAP_PressureReliefType ] = ( int ) PR_AFLEX ;
else session - > summary [ CPAP_PressureReliefType ] = ( int ) PR_CFLEXPLUS ;
} else session - > summary [ CPAP_PressureReliefType ] = ( int ) PR_CFLEX ;
} else session - > summary [ CPAP_PressureReliefType ] = ( int ) PR_NONE ;
2011-07-10 14:23:07 +00:00
session - > summary [ CPAP_PressureReliefSetting ] = ( int ) buffer [ offset + 0x08 ] & 3 ;
session - > summary [ CPAP_HumidifierSetting ] = ( int ) buffer [ offset + 0x09 ] & 0x0f ;
session - > summary [ CPAP_HumidifierStatus ] = ( buffer [ offset + 0x09 ] & 0x80 ) = = 0x80 ;
session - > summary [ PRS1_SystemLockStatus ] = ( buffer [ offset + 0x0a ] & 0x80 ) = = 0x80 ;
session - > summary [ PRS1_SystemResistanceStatus ] = ( buffer [ offset + 0x0a ] & 0x40 ) = = 0x40 ;
session - > summary [ PRS1_SystemResistanceSetting ] = ( int ) buffer [ offset + 0x0a ] & 7 ;
session - > summary [ PRS1_HoseDiameter ] = ( int ) ( ( buffer [ offset + 0x0a ] & 0x08 ) ? 15 : 22 ) ;
session - > summary [ PRS1_AutoOff ] = ( buffer [ offset + 0x0c ] & 0x10 ) = = 0x10 ;
session - > summary [ PRS1_MaskAlert ] = ( buffer [ offset + 0x0c ] & 0x08 ) = = 0x08 ;
session - > summary [ PRS1_ShowAHI ] = ( buffer [ offset + 0x0c ] & 0x04 ) = = 0x04 ;
2011-07-21 02:17:43 +00:00
unsigned duration = buffer [ offset + 0x14 ] | ( buffer [ 0x15 ] < < 8 ) ;
2011-06-26 08:30:44 +00:00
session - > summary [ CPAP_Duration ] = ( int ) duration ;
2011-07-01 10:10:44 +00:00
//qDebug() << "ID: " << session->session() << " " << duration;
2011-07-02 14:35:50 +00:00
//float hours=float(duration)/3600.0;
//session->set_hours(hours);
2011-07-10 14:23:07 +00:00
if ( ! duration )
return false ;
2011-07-03 02:43:50 +00:00
session - > set_last ( date + qint64 ( duration ) * 1000L ) ;
2011-06-26 08:30:44 +00:00
2011-07-10 14:23:07 +00:00
session - > summary [ CPAP_PressureMinAchieved ] = buffer [ offset + 0x16 ] / 10.0 ;
session - > summary [ CPAP_PressureMaxAchieved ] = buffer [ offset + 0x17 ] / 10.0 ;
session - > summary [ CPAP_PressureAverage ] = buffer [ offset + 0x18 ] / 10.0 ;
session - > summary [ CPAP_PressurePercentValue ] = buffer [ offset + 0x19 ] / 10.0 ;
2011-06-26 08:30:44 +00:00
session - > summary [ CPAP_PressurePercentName ] = 90.0 ;
if ( max = = 0 ) {
session - > summary [ CPAP_PressureAverage ] = session - > summary [ CPAP_PressureMin ] ;
}
2011-07-21 02:17:43 +00:00
/*/if (size==0x4d) {
2011-06-26 08:30:44 +00:00
2011-07-10 14:23:07 +00:00
session - > summary [ CPAP_Obstructive ] = ( int ) buffer [ offset + 0x1C ] | ( buffer [ offset + 0x1D ] < < 8 ) ;
session - > summary [ CPAP_ClearAirway ] = ( int ) buffer [ offset + 0x20 ] | ( buffer [ offset + 0x21 ] < < 8 ) ;
session - > summary [ CPAP_Hypopnea ] = ( int ) buffer [ offset + 0x2A ] | ( buffer [ offset + 0x2B ] < < 8 ) ;
session - > summary [ CPAP_RERA ] = ( int ) buffer [ offset + 0x2E ] | ( buffer [ offset + 0x2F ] < < 8 ) ;
session - > summary [ CPAP_FlowLimit ] = ( int ) buffer [ offset + 0x30 ] | ( buffer [ offset + 0x31 ] < < 8 ) ;
2011-07-21 02:17:43 +00:00
} */
2011-06-26 08:30:44 +00:00
return true ;
}
2011-07-10 14:23:07 +00:00
// v2 event parser.
2011-07-18 02:33:25 +00:00
bool PRS1Loader : : Parse002 ( Session * session , unsigned char * buffer , int size , qint64 timestamp )
2011-06-26 08:30:44 +00:00
{
MachineCode Codes [ ] = {
PRS1_Unknown00 , PRS1_Unknown01 , CPAP_Pressure , CPAP_EAP , PRS1_PressurePulse , CPAP_RERA , CPAP_Obstructive , CPAP_ClearAirway ,
PRS1_Unknown08 , PRS1_Unknown09 , CPAP_Hypopnea , PRS1_Unknown0B , CPAP_FlowLimit , CPAP_VSnore , PRS1_Unknown0E , CPAP_CSR , PRS1_Unknown10 ,
CPAP_Leak , PRS1_Unknown12
} ;
int ncodes = sizeof ( Codes ) / sizeof ( MachineCode ) ;
2011-07-27 09:21:53 +00:00
EventList * Code [ 0x20 ] = { NULL } ;
2011-07-10 14:23:07 +00:00
EventDataType data [ 10 ] ;
2011-06-26 08:30:44 +00:00
2011-07-27 09:21:53 +00:00
session - > UpdateFirst ( timestamp ) ;
2011-07-18 02:33:25 +00:00
//qint64 start=timestamp;
2011-07-02 14:35:50 +00:00
qint64 t = timestamp ;
qint64 tt ;
2011-06-26 08:30:44 +00:00
int pos = 0 ;
int cnt = 0 ;
2011-07-18 02:33:25 +00:00
short delta ; //,duration;
2011-06-26 08:30:44 +00:00
while ( pos < size ) {
2011-07-10 14:23:07 +00:00
unsigned char code = buffer [ pos + + ] ;
if ( code > = ncodes ) {
qDebug ( ) < < " Illegal PRS1 code " < < hex < < int ( code ) < < " appeared at " < < hex < < pos + 16 ;
return false ;
}
2011-07-20 16:01:31 +00:00
//if (code==0xe) {
// pos+=2;
//} else
2011-06-26 08:30:44 +00:00
if ( code ! = 0x12 ) {
2011-07-20 16:01:31 +00:00
//delta=buffer[pos];
2011-07-18 02:33:25 +00:00
//duration=buffer[pos+1];
2011-07-20 16:01:31 +00:00
delta = buffer [ pos + 1 ] < < 8 | buffer [ pos ] ;
2011-06-26 08:30:44 +00:00
pos + = 2 ;
2011-07-20 16:01:31 +00:00
//QDateTime d=QDateTime::fromMSecsSinceEpoch(t);
//qDebug()<< d.toString("yyyy-MM-dd HH:mm:ss") << ": " << hex << pos+15 << " " << hex << int(code) << int(delta);
2011-07-02 14:35:50 +00:00
t + = delta * 1000 ;
2011-06-26 08:30:44 +00:00
}
2011-07-27 09:21:53 +00:00
//MachineCode cpapcode=Codes[(int)code];
2011-07-02 14:35:50 +00:00
tt = t ;
2011-06-26 08:30:44 +00:00
cnt + + ;
2011-07-18 02:33:25 +00:00
//int fc=0;
2011-06-26 08:30:44 +00:00
switch ( code ) {
2011-07-27 09:21:53 +00:00
case 0x00 : // Unknown 00
if ( ! Code [ 0 ] ) {
Code [ 0 ] = new EventList ( PRS1_Unknown00 , EVL_Event ) ;
session - > eventlist [ PRS1_Unknown00 ] . push_back ( Code [ 0 ] ) ;
}
Code [ 0 ] - > AddEvent ( t , buffer [ pos + + ] ) ;
2011-07-10 14:23:07 +00:00
break ;
2011-07-27 09:21:53 +00:00
case 0x01 : // Unknown
if ( ! Code [ 1 ] ) {
Code [ 1 ] = new EventList ( PRS1_Unknown01 , EVL_Event ) ;
session - > eventlist [ PRS1_Unknown01 ] . push_back ( Code [ 1 ] ) ;
}
Code [ 1 ] - > AddEvent ( t , 0 ) ;
2011-07-10 14:23:07 +00:00
break ;
2011-06-26 08:30:44 +00:00
case 0x02 : // Pressure
2011-07-27 09:21:53 +00:00
if ( ! Code [ 2 ] ) {
Code [ 2 ] = new EventList ( CPAP_Pressure , EVL_Event , 0.1 ) ;
session - > eventlist [ CPAP_Pressure ] . push_back ( Code [ 2 ] ) ;
}
Code [ 2 ] - > AddEvent ( t , buffer [ pos + + ] ) ;
2011-06-26 08:30:44 +00:00
break ;
2011-07-12 12:43:10 +00:00
case 0x03 : // BIPAP Pressure
2011-07-27 09:21:53 +00:00
if ( ! Code [ 3 ] ) {
Code [ 3 ] = new EventList ( CPAP_EAP , EVL_Event , 0.1 ) ;
session - > eventlist [ CPAP_EAP ] . push_back ( Code [ 3 ] ) ;
Code [ 4 ] = new EventList ( CPAP_IAP , EVL_Event , 0.1 ) ;
session - > eventlist [ CPAP_IAP ] . push_back ( Code [ 4 ] ) ;
Code [ 5 ] = new EventList ( CPAP_PS , EVL_Event , 0.1 ) ;
session - > eventlist [ CPAP_PS ] . push_back ( Code [ 5 ] ) ;
}
Code [ 3 ] - > AddEvent ( t , data [ 0 ] = buffer [ pos + + ] ) ;
Code [ 4 ] - > AddEvent ( t , data [ 1 ] = buffer [ pos + + ] ) ;
Code [ 5 ] - > AddEvent ( t , data [ 1 ] - data [ 0 ] ) ;
2011-07-12 12:43:10 +00:00
break ;
2011-06-26 08:30:44 +00:00
case 0x04 : // Pressure Pulse
2011-07-27 09:21:53 +00:00
if ( ! Code [ 6 ] ) {
Code [ 6 ] = new EventList ( PRS1_PressurePulse , EVL_Event ) ;
session - > eventlist [ PRS1_PressurePulse ] . push_back ( Code [ 6 ] ) ;
}
Code [ 6 ] - > AddEvent ( t , buffer [ pos + + ] ) ;
2011-07-20 16:01:31 +00:00
//qDebug() << hex << data[0];
2011-06-26 08:30:44 +00:00
break ;
case 0x05 : // RERA
2011-07-27 09:21:53 +00:00
data [ 0 ] = buffer [ pos + + ] ;
tt - = data [ 0 ] * 1000 ; // Subtract Time Offset
if ( ! Code [ 7 ] ) {
Code [ 7 ] = new EventList ( CPAP_RERA , EVL_Event ) ;
session - > eventlist [ CPAP_RERA ] . push_back ( Code [ 7 ] ) ;
}
Code [ 7 ] - > AddEvent ( tt , data [ 0 ] ) ;
break ;
2011-06-26 08:30:44 +00:00
case 0x06 : // Obstructive Apoanea
2011-07-27 09:21:53 +00:00
data [ 0 ] = buffer [ pos + + ] ;
tt - = data [ 0 ] * 1000 ; // Subtract Time Offset
if ( ! Code [ 8 ] ) {
Code [ 8 ] = new EventList ( CPAP_Obstructive , EVL_Event ) ;
session - > eventlist [ CPAP_Obstructive ] . push_back ( Code [ 8 ] ) ;
}
Code [ 8 ] - > AddEvent ( tt , data [ 0 ] ) ;
break ;
2011-06-26 08:30:44 +00:00
case 0x07 : // Clear Airway
2011-07-27 09:21:53 +00:00
data [ 0 ] = buffer [ pos + + ] ;
tt - = data [ 0 ] * 1000 ; // Subtract Time Offset
if ( ! Code [ 9 ] ) {
Code [ 9 ] = new EventList ( CPAP_ClearAirway , EVL_Event ) ;
session - > eventlist [ CPAP_ClearAirway ] . push_back ( Code [ 9 ] ) ;
}
Code [ 9 ] - > AddEvent ( tt , data [ 0 ] ) ;
break ;
2011-07-12 12:43:10 +00:00
case 0x0a : // Hypopnea
2011-07-27 09:21:53 +00:00
data [ 0 ] = buffer [ pos + + ] ;
tt - = data [ 0 ] * 1000 ; // Subtract Time Offset
if ( ! Code [ 10 ] ) {
Code [ 10 ] = new EventList ( CPAP_Hypopnea , EVL_Event ) ;
session - > eventlist [ CPAP_Hypopnea ] . push_back ( Code [ 10 ] ) ;
}
Code [ 10 ] - > AddEvent ( tt , data [ 0 ] ) ;
break ;
2011-06-26 08:30:44 +00:00
case 0x0c : // Flow Limitation
2011-07-10 14:23:07 +00:00
data [ 0 ] = buffer [ pos + + ] ;
tt - = data [ 0 ] * 1000 ; // Subtract Time Offset
2011-07-27 09:21:53 +00:00
if ( ! Code [ 11 ] ) {
Code [ 11 ] = new EventList ( CPAP_FlowLimit , EVL_Event ) ;
session - > eventlist [ CPAP_FlowLimit ] . push_back ( Code [ 11 ] ) ;
}
Code [ 11 ] - > AddEvent ( tt , data [ 0 ] ) ;
2011-06-26 08:30:44 +00:00
break ;
2011-07-27 09:21:53 +00:00
case 0x0b : // Hypopnea related code
2011-07-11 05:46:12 +00:00
data [ 0 ] = buffer [ pos + + ] ;
data [ 1 ] = buffer [ pos + + ] ;
2011-07-27 09:21:53 +00:00
if ( ! Code [ 12 ] ) {
Code [ 12 ] = new EventList ( PRS1_Unknown0B , EVL_Event ) ;
session - > eventlist [ PRS1_Unknown0B ] . push_back ( Code [ 12 ] ) ;
}
// FIXME
Code [ 12 ] - > AddEvent ( t , data [ 0 ] ) ;
2011-07-11 05:46:12 +00:00
break ;
2011-06-26 08:30:44 +00:00
case 0x0d : // Vibratory Snore
2011-07-27 09:21:53 +00:00
if ( ! Code [ 13 ] ) {
Code [ 13 ] = new EventList ( CPAP_VSnore , EVL_Event ) ;
session - > eventlist [ CPAP_VSnore ] . push_back ( Code [ 13 ] ) ;
}
Code [ 13 ] - > AddEvent ( t , 0 ) ;
2011-06-26 08:30:44 +00:00
break ;
2011-07-27 09:21:53 +00:00
case 0x11 : // Leak Rate & Snore Graphs
2011-06-26 08:30:44 +00:00
data [ 0 ] = buffer [ pos + + ] ;
data [ 1 ] = buffer [ pos + + ] ;
2011-07-27 09:21:53 +00:00
if ( ! Code [ 14 ] ) {
Code [ 14 ] = new EventList ( CPAP_Leak , EVL_Event ) ;
session - > eventlist [ CPAP_Leak ] . push_back ( Code [ 14 ] ) ;
Code [ 15 ] = new EventList ( CPAP_Snore , EVL_Event ) ;
session - > eventlist [ CPAP_Snore ] . push_back ( Code [ 15 ] ) ;
}
Code [ 14 ] - > AddEvent ( t , data [ 0 ] ) ;
Code [ 15 ] - > AddEvent ( t , data [ 1 ] ) ;
2011-07-10 14:23:07 +00:00
if ( data [ 1 ] > 0 ) {
2011-07-27 09:21:53 +00:00
if ( ! Code [ 16 ] ) {
Code [ 16 ] = new EventList ( PRS1_VSnore2 , EVL_Event ) ;
session - > eventlist [ PRS1_VSnore2 ] . push_back ( Code [ 16 ] ) ;
}
Code [ 16 ] - > AddEvent ( t , data [ 1 ] ) ;
2011-06-26 08:30:44 +00:00
}
break ;
case 0x0e : // Unknown
2011-07-20 16:01:31 +00:00
data [ 0 ] = ( ( char * ) buffer ) [ pos + + ] ;
2011-07-15 10:01:28 +00:00
data [ 1 ] = buffer [ pos + + ] ; //(buffer[pos+1] << 8) | buffer[pos];
//data[0]/=10.0;
//pos+=2;
2011-07-10 14:23:07 +00:00
data [ 2 ] = buffer [ pos + + ] ;
2011-07-27 09:21:53 +00:00
if ( ! Code [ 17 ] ) {
Code [ 17 ] = new EventList ( PRS1_Unknown0E , EVL_Event ) ;
session - > eventlist [ PRS1_Unknown0E ] . push_back ( Code [ 17 ] ) ;
}
Code [ 17 ] - > AddEvent ( t , data [ 0 ] ) ;
2011-07-20 16:01:31 +00:00
//qDebug() << hex << data[0] << data[1] << data[2];
2011-07-27 09:21:53 +00:00
//session->AddEvent(new Event(t,cpapcode, 0, data, 3));
2011-07-15 10:01:28 +00:00
//tt-=data[1]*1000;
//session->AddEvent(new Event(t,CPAP_CSR, data, 2));
2011-07-10 14:23:07 +00:00
break ;
2011-06-26 08:30:44 +00:00
case 0x10 : // Unknown
data [ 0 ] = buffer [ pos + + ] ; // << 8) | buffer[pos];
data [ 1 ] = buffer [ pos + + ] ;
data [ 2 ] = buffer [ pos + + ] ;
2011-07-27 09:21:53 +00:00
if ( ! Code [ 20 ] ) {
Code [ 20 ] = new EventList ( PRS1_Unknown10 , EVL_Event ) ;
session - > eventlist [ PRS1_Unknown10 ] . push_back ( Code [ 20 ] ) ;
}
Code [ 20 ] - > AddEvent ( t , data [ 0 ] ) ;
2011-06-26 08:30:44 +00:00
break ;
case 0x0f : // Cheyne Stokes Respiration
data [ 0 ] = buffer [ pos + 1 ] < < 8 | buffer [ pos ] ;
pos + = 2 ;
data [ 1 ] = buffer [ pos + + ] ;
2011-07-02 14:35:50 +00:00
tt - = data [ 1 ] * 1000 ;
2011-07-27 09:21:53 +00:00
if ( ! Code [ 23 ] ) {
Code [ 23 ] = new EventList ( CPAP_CSR , EVL_Event ) ;
session - > eventlist [ CPAP_CSR ] . push_back ( Code [ 23 ] ) ;
}
Code [ 23 ] - > AddEvent ( tt , data [ 0 ] ) ;
2011-06-26 08:30:44 +00:00
break ;
case 0x12 : // Summary
data [ 0 ] = buffer [ pos + + ] ;
data [ 1 ] = buffer [ pos + + ] ;
data [ 2 ] = buffer [ pos + 1 ] < < 8 | buffer [ pos ] ;
pos + = 2 ;
2011-07-27 09:21:53 +00:00
if ( ! Code [ 24 ] ) {
Code [ 24 ] = new EventList ( PRS1_Unknown12 , EVL_Event ) ;
session - > eventlist [ PRS1_Unknown12 ] . push_back ( Code [ 24 ] ) ;
}
Code [ 24 ] - > AddEvent ( t , data [ 0 ] ) ;
2011-06-26 08:30:44 +00:00
break ;
default :
// ERROR!!!
2011-07-10 14:23:07 +00:00
qWarning ( ) < < " Some new fandangled PRS1 code detected " < < hex < < int ( code ) < < " at " < < pos + 15 ;
2011-07-03 11:49:47 +00:00
return false ;
2011-06-26 08:30:44 +00:00
}
}
2011-07-27 09:21:53 +00:00
session - > UpdateLast ( t ) ;
2011-06-26 08:30:44 +00:00
return true ;
}
2011-07-18 02:33:25 +00:00
bool PRS1Loader : : Parse002ASV ( Session * session , unsigned char * buffer , int size , qint64 timestamp )
2011-07-10 14:23:07 +00:00
{
MachineCode Codes [ ] = {
2011-07-27 09:21:53 +00:00
PRS1_Unknown00 , PRS1_Unknown01 , CPAP_Pressure , CPAP_EAP , PRS1_PressurePulse , CPAP_Obstructive ,
CPAP_ClearAirway , CPAP_Hypopnea , PRS1_Unknown08 , CPAP_FlowLimit , PRS1_Unknown0A , CPAP_CSR ,
PRS1_Unknown0C , CPAP_VSnore , PRS1_Unknown0E , PRS1_Unknown0F , PRS1_Unknown10 ,
2011-07-10 14:23:07 +00:00
CPAP_Leak , PRS1_Unknown12
} ;
int ncodes = sizeof ( Codes ) / sizeof ( MachineCode ) ;
2011-07-27 09:21:53 +00:00
EventList * Code [ 0x20 ] = { NULL } ;
//for (int i=0;i<0x20;i++) Code[i]=NULL;
session - > UpdateFirst ( timestamp ) ;
2011-07-10 14:23:07 +00:00
EventDataType data [ 10 ] ;
2011-07-18 02:33:25 +00:00
//qint64 start=timestamp;
2011-07-10 14:23:07 +00:00
qint64 t = timestamp ;
qint64 tt ;
int pos = 0 ;
int cnt = 0 ;
2011-07-18 02:33:25 +00:00
short delta ; //,duration;
2011-07-10 16:20:51 +00:00
QDateTime d ;
2011-07-10 14:23:07 +00:00
while ( pos < size ) {
unsigned char code = buffer [ pos + + ] ;
if ( code > = ncodes ) {
qDebug ( ) < < " Illegal PRS1 code " < < hex < < int ( code ) < < " appeared at " < < hex < < pos + 16 ;
return false ;
}
2011-07-10 16:20:51 +00:00
//QDateTime d=QDateTime::fromMSecsSinceEpoch(t);
//qDebug()<< d.toString("yyyy-MM-dd HH:mm:ss") << ": " << hex << pos+15 << " " << hex << int(code) ;
2011-07-19 16:44:03 +00:00
if ( code = = 0 ) {
} else
2011-07-10 14:23:07 +00:00
if ( code ! = 0x12 ) {
delta = buffer [ pos ] ;
2011-07-18 02:33:25 +00:00
//duration=buffer[pos+1];
2011-07-10 14:23:07 +00:00
//delta=buffer[pos+1] << 8 | buffer[pos];
pos + = 2 ;
t + = delta * 1000 ;
}
MachineCode cpapcode = Codes [ ( int ) code ] ;
2011-07-18 02:33:25 +00:00
//EventDataType PS;
2011-07-10 14:23:07 +00:00
tt = t ;
cnt + + ;
int fc = 0 ;
2011-07-27 09:21:53 +00:00
2011-07-10 14:23:07 +00:00
switch ( code ) {
2011-07-10 16:20:51 +00:00
case 0x00 : // Unknown (ASV Pressure value)
2011-07-10 14:23:07 +00:00
// offset?
data [ 0 ] = buffer [ pos + + ] ;
fc + + ;
2011-07-10 16:20:51 +00:00
if ( ! buffer [ pos - 1 ] ) { // WTH???
2011-07-10 14:23:07 +00:00
data [ 1 ] = buffer [ pos + + ] ;
fc + + ;
}
if ( ! buffer [ pos - 1 ] ) {
data [ 2 ] = buffer [ pos + + ] ;
fc + + ;
}
break ;
2011-07-27 09:21:53 +00:00
case 0x01 : // Unknown
if ( ! Code [ 1 ] ) {
Code [ 1 ] = new EventList ( cpapcode , EVL_Event , 0.1 ) ;
session - > eventlist [ cpapcode ] . push_back ( Code [ 1 ] ) ;
}
Code [ 1 ] - > AddEvent ( t , 0 ) ;
break ;
2011-07-10 14:23:07 +00:00
case 0x02 : // Pressure
2011-07-27 09:21:53 +00:00
data [ 0 ] = buffer [ pos + + ] ;
if ( ! Code [ 2 ] ) {
Code [ 2 ] = new EventList ( cpapcode , EVL_Event , 0.1 ) ;
session - > eventlist [ cpapcode ] . push_back ( Code [ 2 ] ) ;
}
Code [ 2 ] - > AddEvent ( t , data [ 0 ] ) ;
2011-07-10 14:23:07 +00:00
break ;
case 0x04 : // Pressure Pulse
data [ 0 ] = buffer [ pos + + ] ;
2011-07-27 09:21:53 +00:00
if ( ! Code [ 3 ] ) {
Code [ 3 ] = new EventList ( cpapcode , EVL_Event ) ;
session - > eventlist [ cpapcode ] . push_back ( Code [ 3 ] ) ;
}
Code [ 3 ] - > AddEvent ( t , data [ 0 ] ) ;
2011-07-10 14:23:07 +00:00
break ;
case 0x05 :
2011-07-27 09:21:53 +00:00
data [ 0 ] = buffer [ pos + + ] ;
tt - = data [ 0 ] * 1000 ; // Subtract Time Offset
if ( ! Code [ 4 ] ) {
Code [ 4 ] = new EventList ( cpapcode , EVL_Event ) ;
session - > eventlist [ cpapcode ] . push_back ( Code [ 4 ] ) ;
}
Code [ 4 ] - > AddEvent ( tt , data [ 0 ] ) ;
break ;
2011-07-10 14:23:07 +00:00
case 0x06 :
2011-07-27 09:21:53 +00:00
data [ 0 ] = buffer [ pos + + ] ;
tt - = data [ 0 ] * 1000 ; // Subtract Time Offset
if ( ! Code [ 5 ] ) {
Code [ 5 ] = new EventList ( cpapcode , EVL_Event ) ;
session - > eventlist [ cpapcode ] . push_back ( Code [ 5 ] ) ;
}
Code [ 5 ] - > AddEvent ( tt , data [ 0 ] ) ;
break ;
2011-07-10 14:23:07 +00:00
case 0x07 :
2011-07-27 09:21:53 +00:00
data [ 0 ] = buffer [ pos + + ] ;
tt - = data [ 0 ] * 1000 ; // Subtract Time Offset
if ( ! Code [ 6 ] ) {
Code [ 6 ] = new EventList ( cpapcode , EVL_Event ) ;
session - > eventlist [ cpapcode ] . push_back ( Code [ 6 ] ) ;
}
Code [ 6 ] - > AddEvent ( tt , data [ 0 ] ) ;
break ;
case 0x08 : // ASV Codes
data [ 0 ] = buffer [ pos + + ] ;
tt - = data [ 0 ] * 1000 ; // Subtract Time Offset
if ( ! Code [ 10 ] ) {
Code [ 10 ] = new EventList ( cpapcode , EVL_Event ) ;
session - > eventlist [ cpapcode ] . push_back ( Code [ 10 ] ) ;
}
Code [ 10 ] - > AddEvent ( tt , data [ 0 ] ) ;
break ;
case 0x09 : // ASV Codes
data [ 0 ] = buffer [ pos + + ] ;
tt - = data [ 0 ] * 1000 ; // Subtract Time Offset
if ( ! Code [ 11 ] ) {
Code [ 11 ] = new EventList ( cpapcode , EVL_Event ) ;
session - > eventlist [ cpapcode ] . push_back ( Code [ 11 ] ) ;
}
Code [ 11 ] - > AddEvent ( tt , data [ 0 ] ) ;
break ;
case 0x0a :
data [ 0 ] = buffer [ pos + + ] ;
tt - = data [ 0 ] * 1000 ; // Subtract Time Offset
if ( ! Code [ 7 ] ) {
Code [ 7 ] = new EventList ( cpapcode , EVL_Event ) ;
session - > eventlist [ cpapcode ] . push_back ( Code [ 7 ] ) ;
}
Code [ 7 ] - > AddEvent ( tt , data [ 0 ] ) ;
break ;
2011-07-10 14:23:07 +00:00
case 0x0c :
data [ 0 ] = buffer [ pos + + ] ;
tt - = data [ 0 ] * 1000 ; // Subtract Time Offset
2011-07-27 09:21:53 +00:00
if ( ! Code [ 8 ] ) {
Code [ 8 ] = new EventList ( cpapcode , EVL_Event ) ;
session - > eventlist [ cpapcode ] . push_back ( Code [ 8 ] ) ;
}
Code [ 8 ] - > AddEvent ( tt , data [ 0 ] ) ;
2011-07-10 14:23:07 +00:00
break ;
2011-07-27 09:21:53 +00:00
2011-07-10 14:23:07 +00:00
case 0x0b : // Cheyne Stokes
data [ 0 ] = ( ( unsigned char * ) buffer ) [ pos + 1 ] < < 8 | ( ( unsigned char * ) buffer ) [ pos ] ;
2011-07-27 09:21:53 +00:00
//data[0]*=2;
2011-07-10 14:23:07 +00:00
pos + = 2 ;
data [ 1 ] = ( ( unsigned char * ) buffer ) [ pos ] ; //|buffer[pos+1] << 8
pos + = 1 ;
//tt-=delta;
tt - = data [ 1 ] * 1000 ;
2011-07-27 09:21:53 +00:00
if ( ! Code [ 9 ] ) {
Code [ 9 ] = new EventList ( cpapcode , EVL_Event , 2.0 ) ;
session - > eventlist [ cpapcode ] . push_back ( Code [ 9 ] ) ;
}
Code [ 9 ] - > AddEvent ( tt , data [ 0 ] ) ;
//session->AddEvent(new Event(tt,cpapcode, data[0], data, 2));
2011-07-10 14:23:07 +00:00
break ;
case 0x0d : // All the other ASV graph stuff.
2011-07-27 09:21:53 +00:00
if ( ! Code [ 12 ] ) {
Code [ 12 ] = new EventList ( CPAP_IAP , EVL_Event , 0.1 ) ;
session - > eventlist [ CPAP_IAP ] . push_back ( Code [ 12 ] ) ;
Code [ 13 ] = new EventList ( CPAP_IAPLO , EVL_Event , 0.1 ) ;
session - > eventlist [ CPAP_IAPLO ] . push_back ( Code [ 13 ] ) ;
Code [ 14 ] = new EventList ( CPAP_IAPHI , EVL_Event , 0.1 ) ;
session - > eventlist [ CPAP_IAPHI ] . push_back ( Code [ 14 ] ) ;
Code [ 15 ] = new EventList ( CPAP_Leak , EVL_Event ) ;
session - > eventlist [ CPAP_Leak ] . push_back ( Code [ 15 ] ) ;
Code [ 16 ] = new EventList ( CPAP_RespiratoryRate , EVL_Event ) ;
session - > eventlist [ CPAP_RespiratoryRate ] . push_back ( Code [ 16 ] ) ;
Code [ 17 ] = new EventList ( CPAP_PatientTriggeredBreaths , EVL_Event ) ;
session - > eventlist [ CPAP_PatientTriggeredBreaths ] . push_back ( Code [ 17 ] ) ;
Code [ 18 ] = new EventList ( CPAP_MinuteVentilation , EVL_Event ) ;
session - > eventlist [ CPAP_MinuteVentilation ] . push_back ( Code [ 18 ] ) ;
Code [ 19 ] = new EventList ( CPAP_TidalVolume , EVL_Event , 10.0 ) ;
session - > eventlist [ CPAP_TidalVolume ] . push_back ( Code [ 19 ] ) ;
Code [ 20 ] = new EventList ( CPAP_Snore , EVL_Event ) ;
session - > eventlist [ CPAP_Snore ] . push_back ( Code [ 20 ] ) ;
Code [ 22 ] = new EventList ( CPAP_EAP , EVL_Event , 0.1 ) ;
session - > eventlist [ CPAP_EAP ] . push_back ( Code [ 22 ] ) ;
Code [ 23 ] = new EventList ( CPAP_PS , EVL_Event , 0.1 ) ;
session - > eventlist [ CPAP_PS ] . push_back ( Code [ 23 ] ) ;
2011-07-10 16:20:51 +00:00
2011-07-27 09:21:53 +00:00
}
Code [ 12 ] - > AddEvent ( t , data [ 0 ] = buffer [ pos + + ] ) ; // IAP
Code [ 13 ] - > AddEvent ( t , buffer [ pos + + ] ) ; // IAP Low
Code [ 14 ] - > AddEvent ( t , buffer [ pos + + ] ) ; // IAP High
Code [ 15 ] - > AddEvent ( t , buffer [ pos + + ] ) ; // LEAK
Code [ 16 ] - > AddEvent ( t , buffer [ pos + + ] ) ; // Breaths Per Minute
Code [ 17 ] - > AddEvent ( t , buffer [ pos + + ] ) ; // Patient Triggered Breaths
Code [ 18 ] - > AddEvent ( t , buffer [ pos + + ] ) ; // Minute Ventilation
Code [ 19 ] - > AddEvent ( t , buffer [ pos + + ] ) ; // Tidal Volume
Code [ 20 ] - > AddEvent ( t , data [ 2 ] = buffer [ pos + + ] ) ; // Snore
if ( data [ 2 ] > 0 ) {
if ( ! Code [ 21 ] ) {
Code [ 21 ] = new EventList ( CPAP_VSnore , EVL_Event ) ;
session - > eventlist [ CPAP_VSnore ] . push_back ( Code [ 21 ] ) ;
}
Code [ 21 ] - > AddEvent ( t , 0 ) ; //data[2]); // VSnore
}
Code [ 22 ] - > AddEvent ( t , data [ 1 ] = buffer [ pos + + ] ) ; // EPAP
Code [ 23 ] - > AddEvent ( t , data [ 0 ] - data [ 1 ] ) ; // Pressure Support
2011-07-10 14:23:07 +00:00
break ;
case 0x03 : // BIPAP Pressure
2011-07-27 09:21:53 +00:00
qDebug ( ) < < " 0x03 Observed in ASV data!!???? " ;
2011-07-10 14:23:07 +00:00
data [ 0 ] = buffer [ pos + + ] ;
data [ 1 ] = buffer [ pos + + ] ;
2011-07-27 09:21:53 +00:00
/*data[0]/=10.0;
2011-07-10 14:23:07 +00:00
data [ 1 ] / = 10.0 ;
2011-07-27 09:21:53 +00:00
session - > AddEvent ( new Event ( t , CPAP_EAP , 0 , data , 1 ) ) ;
session - > AddEvent ( new Event ( t , CPAP_IAP , 0 , & data [ 1 ] , 1 ) ) ; */
2011-07-10 14:23:07 +00:00
break ;
2011-07-27 09:21:53 +00:00
case 0x11 : // Not Leak Rate
qDebug ( ) < < " 0x11 Observed in ASV data!!???? " ;
//if (!Code[24]) {
// Code[24]=new EventList(cpapcode,EVL_Event);
//}
//Code[24]->AddEvent(t,buffer[pos++]);
2011-07-10 14:23:07 +00:00
break ;
case 0x0e : // Unknown
2011-07-27 09:21:53 +00:00
qDebug ( ) < < " 0x0E Observed in ASV data!!???? " ;
2011-07-10 14:23:07 +00:00
data [ 0 ] = buffer [ pos + + ] ; // << 8) | buffer[pos];
2011-07-27 09:21:53 +00:00
//session->AddEvent(new Event(t,cpapcode, 0, data, 1));
2011-07-10 14:23:07 +00:00
break ;
case 0x10 : // Unknown
2011-07-27 09:21:53 +00:00
qDebug ( ) < < " 0x10 Observed in ASV data!!???? " ;
2011-07-10 14:23:07 +00:00
data [ 0 ] = buffer [ pos + + ] ; // << 8) | buffer[pos];
data [ 1 ] = buffer [ pos + + ] ;
data [ 2 ] = buffer [ pos + + ] ;
2011-07-27 09:21:53 +00:00
//session->AddEvent(new Event(t,cpapcode, 0, data, 3));
2011-07-10 14:23:07 +00:00
break ;
case 0x0f :
2011-07-27 09:21:53 +00:00
qDebug ( ) < < " 0x0f Observed in ASV data!!???? " ;
2011-07-10 14:23:07 +00:00
data [ 0 ] = buffer [ pos + 1 ] < < 8 | buffer [ pos ] ;
pos + = 2 ;
data [ 1 ] = buffer [ pos ] ; //|buffer[pos+1] << 8
pos + = 1 ;
tt - = data [ 1 ] * 1000 ;
2011-07-27 09:21:53 +00:00
//session->AddEvent(new Event(tt,cpapcode, 0, data, 2));
2011-07-10 14:23:07 +00:00
break ;
case 0x12 : // Summary
2011-07-27 09:21:53 +00:00
qDebug ( ) < < " 0x12 Observed in ASV data!!???? " ;
2011-07-10 14:23:07 +00:00
data [ 0 ] = buffer [ pos + + ] ;
data [ 1 ] = buffer [ pos + + ] ;
data [ 2 ] = buffer [ pos + 1 ] < < 8 | buffer [ pos ] ;
pos + = 2 ;
2011-07-27 09:21:53 +00:00
//session->AddEvent(new Event(t,cpapcode, 0, data,3));
2011-07-10 14:23:07 +00:00
break ;
default :
// ERROR!!!
qWarning ( ) < < " Some new fandangled PRS1 code detected " < < hex < < int ( code ) < < " at " < < pos + 15 ;
return false ;
}
}
2011-07-27 09:21:53 +00:00
/*EventList *a;
for ( int i = 0 ; i < 24 ; i + + ) {
a = Code [ i ] ;
if ( a ) {
int v = ceil ( a - > max ( ) / 5 ) ;
a - > setMax ( v * 5 ) ;
v = floor ( a - > min ( ) / 5 ) ;
a - > setMin ( v * 5 ) ;
}
} */
session - > UpdateLast ( t ) ;
2011-07-10 14:23:07 +00:00
return true ;
}
2011-06-26 08:30:44 +00:00
bool PRS1Loader : : OpenEvents ( Session * session , QString filename )
{
2011-07-10 14:23:07 +00:00
int size , sequence , seconds , br , version ;
2011-07-02 14:35:50 +00:00
qint64 timestamp ;
2011-06-26 08:30:44 +00:00
unsigned char header [ 24 ] ; // use m_buffer?
2011-07-10 14:23:07 +00:00
unsigned char ext , htype ;
2011-06-26 08:30:44 +00:00
QFile f ( filename ) ;
if ( ! f . open ( QIODevice : : ReadOnly ) )
return false ;
int hl = 16 ;
br = f . read ( ( char * ) header , hl ) ;
2011-07-10 14:23:07 +00:00
if ( header [ 0 ] ! = PRS1_MAGIC_NUMBER )
2011-06-26 08:30:44 +00:00
return false ;
sequence = size = timestamp = seconds = ext = 0 ;
sequence = ( header [ 10 ] < < 24 ) | ( header [ 9 ] < < 16 ) | ( header [ 8 ] < < 8 ) | header [ 7 ] ;
timestamp = ( header [ 14 ] < < 24 ) | ( header [ 13 ] < < 16 ) | ( header [ 12 ] < < 8 ) | header [ 11 ] ;
size = ( header [ 2 ] < < 8 ) | header [ 1 ] ;
ext = header [ 6 ] ;
2011-07-10 14:23:07 +00:00
htype = header [ 3 ] ; // 00 = normal // 01=waveform // could be a bool?
version = header [ 4 ] ; // | header[4];
2011-06-26 08:30:44 +00:00
2011-07-18 02:33:25 +00:00
htype = htype ;
sequence = sequence ;
2011-07-10 14:23:07 +00:00
if ( ext ! = PRS1_EVENT_FILE ) // 2 == Event file
2011-06-26 08:30:44 +00:00
return false ;
//size|=(header[3]<<16) | (header[4]<<24); // the jury is still out on the 32bitness of one. doesn't matter here anyway.
size - = ( hl + 2 ) ;
unsigned char sum = 0 ;
for ( int i = 0 ; i < hl - 1 ; i + + ) sum + = header [ i ] ;
if ( sum ! = header [ hl - 1 ] ) return false ;
unsigned char * buffer = ( unsigned char * ) m_buffer ;
br = f . read ( ( char * ) buffer , size ) ;
if ( br < size ) {
return false ;
}
2011-07-10 14:23:07 +00:00
if ( version = = 0 ) {
2011-07-18 02:33:25 +00:00
if ( ! Parse002 ( session , buffer , size , timestamp * 1000L ) ) {
2011-07-10 14:23:07 +00:00
qDebug ( ) < < " Couldn't Parse PRS1 Event File " < < filename ;
return false ;
}
} else if ( version = = 5 ) {
2011-07-18 02:33:25 +00:00
if ( ! Parse002ASV ( session , buffer , size , timestamp * 1000L ) ) {
2011-07-10 14:23:07 +00:00
qDebug ( ) < < " Couldn't Parse PRS1 (ASV) Event File " < < filename ;
return false ;
}
}
2011-06-26 08:30:44 +00:00
return true ;
}
2011-07-21 11:02:23 +00:00
struct WaveHeaderList {
quint16 interleave ;
quint8 sample_format ;
WaveHeaderList ( quint16 i , quint8 f ) { interleave = i ; sample_format = f ; }
} ;
2011-06-26 08:30:44 +00:00
bool PRS1Loader : : OpenWaveforms ( Session * session , QString filename )
2011-07-21 11:02:23 +00:00
{
//int sequence,seconds,br,htype,version,numsignals;
QFile file ( filename ) ;
if ( ! file . open ( QIODevice : : ReadOnly ) ) {
qWarning ( ) < < " Couldn't open waveform file " < < filename ;
return false ;
}
int pos , br , size = file . size ( ) ;
if ( size > max_load_buffer_size ) {
qWarning ( ) < < " Waveform too big, increase max_load_buffer_size in PRS1Loader sourcecode " < < filename ;
return false ;
}
br = file . read ( ( char * ) m_buffer , size ) ;
if ( br < size ) {
qWarning ( ) < < " Couldn't read waveform data.. Disk error? " < < filename ;
return false ;
}
// Look at the initial header and assume this header size for the lot.
if ( ( m_buffer [ 0 ] ! = 2 ) | | ( m_buffer [ 6 ] ! = 0x05 ) ) {
qWarning ( ) < < " Not correct waveform format " < < filename ;
return false ;
}
2011-07-27 09:21:53 +00:00
//quint8 version=m_buffer[4];
2011-07-21 11:02:23 +00:00
quint32 start = m_buffer [ 0xb ] | m_buffer [ 0xc ] < < 8 | m_buffer [ 0xd ] < < 16 | m_buffer [ 0x0e ] < < 24 ;
2011-07-27 09:21:53 +00:00
session - > UpdateFirst ( qint64 ( start ) * 1000L ) ;
2011-07-21 11:02:23 +00:00
quint16 num_signals = m_buffer [ 0x12 ] | m_buffer [ 0x13 ] < < 8 ;
if ( num_signals > 2 ) {
qWarning ( ) < < " More than 2 Waveforms in " < < filename ;
return false ;
}
pos = 0x14 + ( num_signals - 1 ) * 3 ;
vector < WaveHeaderList > whl ;
// add the in reverse...
for ( int i = 0 ; i < num_signals ; i + + ) {
quint16 interleave = m_buffer [ pos ] | m_buffer [ pos + 1 ] < < 8 ;
quint8 sample_format = m_buffer [ pos + 2 ] ;
whl . push_back ( WaveHeaderList ( interleave , sample_format ) ) ;
pos - = 3 ;
}
int hl = 15 + 5 + ( num_signals * 3 ) ;
quint16 duration , length ;
quint32 timestamp , lasttimestamp ;
pos = 0 ;
int block = 0 ;
lasttimestamp = start ;
duration = 0 ;
int corrupt = 0 ;
char waveform [ num_signals ] [ 500000 ] ;
int wlength [ num_signals ] ;
2011-07-27 09:21:53 +00:00
qint64 wdur [ num_signals ] ;
//EventList *evl[num_signals];
2011-07-21 11:02:23 +00:00
for ( int i = 0 ; i < num_signals ; i + + ) {
wlength [ i ] = 0 ;
wdur [ i ] = 0 ;
2011-07-27 09:21:53 +00:00
//evl[i]=NULL;
2011-07-21 11:02:23 +00:00
//waveform[i].resize(500000);
}
2011-07-27 09:21:53 +00:00
//SampleFormat *wf[num_signals];
//EventList *FlowData=EventList(CPAP_FlowRate, EVL_Waveform,1,0,-128,128);
//EventList *MaskData=EventList(CPAP_MaskPressure, EVL_Waveform,1,0,-128,128);
2011-07-21 11:02:23 +00:00
MachineCode wc [ 2 ] = { CPAP_FlowRate , CPAP_MaskPressure } ;
do {
timestamp = m_buffer [ pos + 0xb ] | m_buffer [ pos + 0xc ] < < 8 | m_buffer [ pos + 0xd ] < < 16 | m_buffer [ pos + 0x0e ] < < 24 ;
register unsigned char sum8 = 0 ;
for ( int i = 0 ; i < hl ; i + + ) sum8 + = m_buffer [ pos + i ] ;
if ( m_buffer [ pos + hl ] ! = sum8 ) {
if ( block = = 0 ) {
qDebug ( ) < < " Faulty Header Checksum, aborting " < < filename ;
return false ;
}
if ( + + corrupt > 3 ) {
qDebug ( ) < < " 3 Faulty Waveform Headers in a row.. Aborting " < < filename ;
return false ;
}
qDebug ( ) < < " Faulty Header Checksum, skipping block " < < block ;
pos + = length ;
continue ;
} else {
2011-07-22 13:46:17 +00:00
int diff = timestamp - ( lasttimestamp + duration ) ;
if ( block = = 1 ) {
if ( diff > 0 )
start - = diff ;
}
2011-07-21 11:02:23 +00:00
length = m_buffer [ pos + 0x1 ] | m_buffer [ pos + 0x2 ] < < 8 ; // block length in bytes
duration = m_buffer [ pos + 0xf ] | m_buffer [ pos + 0x10 ] < < 8 ; // block duration in seconds
2011-07-22 16:38:22 +00:00
if ( diff < 0 ) {
qDebug ( ) < < " Padding waveform to keep sync " < < block ;
2011-07-22 13:46:17 +00:00
//diff=abs(diff);
for ( int i = 0 ; i < num_signals ; i + + ) {
for ( int j = 0 ; j < diff ; j + + ) {
for ( int k = 0 ; k < whl [ i ] . interleave ; k + + )
waveform [ i ] [ wlength [ i ] + + ] = 0 ;
}
wdur [ i ] + = diff ;
}
} else
if ( diff > 0 & & wlength [ 0 ] > 0 ) {
2011-07-27 09:21:53 +00:00
qDebug ( ) < < " Timestamp resync " < < block < < diff < < corrupt < < duration < < timestamp - lasttimestamp < < filename ;
2011-07-22 13:46:17 +00:00
2011-07-21 11:02:23 +00:00
for ( int i = 0 ; i < num_signals ; i + + ) {
2011-07-27 09:21:53 +00:00
double rate = ( double ( wdur [ i ] ) * 1000.0 ) / double ( wlength [ i ] ) ;
double gain ;
if ( i = = 1 ) gain = 0.1 ; else gain = 1 ;
EventList * a = new EventList ( wc [ i ] , EVL_Waveform , gain , 0 , 0 , 0 , rate ) ;
if ( whl [ i ] . sample_format )
a - > AddWaveform ( qint64 ( start ) * 1000L , ( unsigned char * ) waveform [ i ] , wlength [ i ] , qint64 ( wdur [ i ] ) * 1000L ) ;
else {
a - > AddWaveform ( qint64 ( start ) * 1000L , ( char * ) waveform [ i ] , wlength [ i ] , qint64 ( wdur [ i ] ) * 1000L ) ;
}
if ( wc [ i ] = = CPAP_FlowRate ) {
a - > setMax ( 120 ) ;
a - > setMin ( - 120 ) ;
} else if ( wc [ i ] = = CPAP_MaskPressure ) {
/* int v=ceil(a->max()/5);
a - > setMax ( v * 5 ) ;
v = floor ( a - > min ( ) / 5 ) ;
a - > setMin ( v * 5 ) ; */
2011-07-21 11:02:23 +00:00
}
2011-07-27 09:21:53 +00:00
session - > eventlist [ wc [ i ] ] . push_back ( a ) ;
session - > UpdateLast ( start + ( qint64 ( wdur [ i ] ) * 1000L ) ) ;
2011-07-21 11:02:23 +00:00
wlength [ i ] = 0 ;
wdur [ i ] = 0 ;
}
start = timestamp ;
corrupt = 0 ;
2011-07-22 16:38:22 +00:00
}
2011-07-21 11:02:23 +00:00
}
pos + = hl + 1 ;
2011-07-22 13:46:17 +00:00
//qDebug() << (duration*num_signals*whl[0].interleave) << duration;
2011-07-21 11:02:23 +00:00
if ( num_signals = = 1 ) { // no interleave.. this is much quicker.
int bs = duration * whl [ 0 ] . interleave ;
memcpy ( ( char * ) & ( waveform [ 0 ] ) [ wlength [ 0 ] ] , ( char * ) & m_buffer [ pos ] , bs ) ;
wlength [ 0 ] + = bs ;
pos + = bs ;
} else {
for ( int i = 0 ; i < duration ; i + + ) {
for ( int s = 0 ; s < num_signals ; s + + ) {
memcpy ( ( char * ) & ( waveform [ s ] ) [ wlength [ s ] ] , ( char * ) & m_buffer [ pos ] , whl [ s ] . interleave ) ;
wlength [ s ] + = whl [ s ] . interleave ;
pos + = whl [ s ] . interleave ;
}
}
}
for ( int i = 0 ; i < num_signals ; i + + ) wdur [ i ] + = duration ;
pos + = 2 ;
block + + ;
lasttimestamp = timestamp ;
} while ( pos < size ) ;
for ( int i = 0 ; i < num_signals ; i + + ) {
2011-07-27 09:21:53 +00:00
double rate = ( double ( wdur [ i ] ) * 1000.0 ) / double ( wlength [ i ] ) ;
double gain ;
if ( i = = 1 ) gain = 0.1 ; else gain = 1 ;
EventList * a = new EventList ( wc [ i ] , EVL_Waveform , gain , 0 , 0 , 0 , rate ) ;
if ( whl [ i ] . sample_format )
a - > AddWaveform ( qint64 ( start ) * 1000L , ( unsigned char * ) waveform [ i ] , wlength [ i ] , qint64 ( wdur [ i ] ) * 1000L ) ;
else {
a - > AddWaveform ( qint64 ( start ) * 1000L , ( char * ) waveform [ i ] , wlength [ i ] , qint64 ( wdur [ i ] ) * 1000L ) ;
2011-07-20 16:01:31 +00:00
}
2011-07-27 09:21:53 +00:00
if ( wc [ i ] = = CPAP_FlowRate ) {
a - > setMax ( 120 ) ;
a - > setMin ( - 120 ) ;
} else if ( wc [ i ] = = CPAP_MaskPressure ) {
/*int v=ceil(a->max()/5);
a - > setMax ( v * 5 ) ;
v = floor ( a - > min ( ) / 5 ) ;
a - > setMin ( v * 5 ) ; */
2011-06-26 08:30:44 +00:00
}
2011-07-27 09:21:53 +00:00
session - > eventlist [ wc [ i ] ] . push_back ( a ) ;
session - > UpdateLast ( start + qint64 ( wdur [ i ] ) * 1000L ) ;
2011-07-10 14:23:07 +00:00
}
2011-06-26 08:30:44 +00:00
return true ;
2011-07-27 09:21:53 +00:00
}
2011-07-22 13:46:17 +00:00
2011-06-26 08:30:44 +00:00
void InitModelMap ( )
{
ModelMap [ 34 ] = " RemStar Pro with C-Flex+ " ;
ModelMap [ 35 ] = " RemStar Auto with A-Flex " ;
2011-07-11 04:54:53 +00:00
ModelMap [ 37 ] = " RemStar BiPAP Auto with Bi-Flex " ;
2011-07-11 01:58:51 +00:00
ModelMap [ 0x41 ] = " BiPAP autoSV Advanced " ;
2011-06-26 08:30:44 +00:00
} ;
bool initialized = false ;
void PRS1Loader : : Register ( )
{
if ( initialized ) return ;
2011-07-01 10:10:44 +00:00
qDebug ( ) < < " Registering PRS1Loader " ;
2011-06-26 08:30:44 +00:00
RegisterLoader ( new PRS1Loader ( ) ) ;
InitModelMap ( ) ;
initialized = true ;
}