📄 sopen_scp_write.c
字号:
tmp = aECG->Section1.Tag14.ACQ_DEV_SCP_SW; len = min(25, strlen(tmp) + 1); strncpy((char*)(ptr+sectionStart+curSectLen+len1), tmp, len); len1 += len; tmp = aECG->Section1.Tag14.ACQ_DEV_MANUF; len = min(25, strlen(tmp) + 1); strncpy((char*)(ptr+sectionStart+curSectLen+len1), tmp, len); len1 += len; *(uint16_t*)(ptr+sectionStart+curSectLen+1-3) = l_endian_u16(len1); // length curSectLen += len1; // Tag 20 (max len = 64 ) len = strlen(aECG->ReferringPhysician); if (len>0) { *(ptr+sectionStart+curSectLen) = 20; // tag len = min(64,len+1); *(uint16_t*)(ptr+sectionStart+curSectLen+1) = l_endian_u16(len); // length strncpy((char*)(ptr+sectionStart+curSectLen+3),aECG->ReferringPhysician,len); curSectLen += 3+len; }; // Tag 21 (max len = 64 ) len = strlen(aECG->MedicationDrugs); if (len>0) { *(ptr+sectionStart+curSectLen) = 21; // tag len = min(64,len+1); *(uint16_t*)(ptr+sectionStart+curSectLen+1) = l_endian_u16(len); // length strncpy((char*)(ptr+sectionStart+curSectLen+3),aECG->MedicationDrugs,len); curSectLen += 3+len; }; // Tag 24 ( len = 1 ) *(ptr+sectionStart+curSectLen) = 24; // tag *(uint16_t*)(ptr+sectionStart+curSectLen+1) = l_endian_u16(1); // length *(ptr+sectionStart+curSectLen+3) = aECG->EmergencyLevel; curSectLen += 4; // Tag 25 (len = 4) T0 = gdf_time2t_time(hdr->T0); T0_tm = gmtime(&T0); *(ptr+sectionStart+curSectLen) = 25; // tag *(uint16_t*)(ptr+sectionStart+curSectLen+1) = l_endian_u16(4); // length *(uint16_t*)(ptr+sectionStart+curSectLen+3) = l_endian_u16((uint16_t)(T0_tm->tm_year+1900));// year *(ptr+sectionStart+curSectLen+5) = (uint8_t)(T0_tm->tm_mon + 1); // month *(ptr+sectionStart+curSectLen+6) = (uint8_t)T0_tm->tm_mday; // day curSectLen += 7; // Tag 26 (len = 3) *(ptr+sectionStart+curSectLen) = 26; // tag *(uint16_t*)(ptr+sectionStart+curSectLen+1) = l_endian_u16(3); // length *(ptr+sectionStart+curSectLen+3) = (uint8_t)T0_tm->tm_hour; // hour *(ptr+sectionStart+curSectLen+4) = (uint8_t)T0_tm->tm_min; // minute *(ptr+sectionStart+curSectLen+5) = (uint8_t)T0_tm->tm_sec; // second curSectLen += 6; if (hdr->NS>0) { // Tag 27 (len = 3) highpass filter *(ptr+sectionStart+curSectLen) = 27; // tag *(uint16_t*)(ptr+sectionStart+curSectLen+1) = l_endian_u16(2); // length *(uint16_t*)(ptr+sectionStart+curSectLen+3) = (uint16_t)hdr->CHANNEL[1].HighPass; // hour curSectLen += 5; // Tag 28 (len = 3) lowpass filter *(ptr+sectionStart+curSectLen) = 28; // tag *(uint16_t*)(ptr+sectionStart+curSectLen+1) = l_endian_u16(2); // length *(uint16_t*)(ptr+sectionStart+curSectLen+3) = (uint16_t)hdr->CHANNEL[1].LowPass; // hour curSectLen += 5; // Tag 29 (len = 1) filter bitmap uint8_t bitmap = 0; if (fabs(hdr->CHANNEL[1].LowPass-60.0)<0.01) bitmap = 1; else if (fabs(hdr->CHANNEL[1].LowPass-50.0)<0.01) bitmap = 2; else bitmap = 0; *(ptr+sectionStart+curSectLen) = 29; // tag *(uint16_t*)(ptr+sectionStart+curSectLen+1) = l_endian_u16(1); // length *(ptr+sectionStart+curSectLen+3) = bitmap; curSectLen += 4; } // Tag 34 (len = 5) *(ptr+sectionStart+curSectLen) = 34; // tag *(uint16_t*)(ptr+sectionStart+curSectLen+1) = l_endian_u16(5); // length // FIXME: compensation for daylight saving time not included //*(int16_t*)(ptr+sectionStart+curSectLen+3) = 0; *(int16_t*)(ptr+sectionStart+curSectLen+3) = l_endian_i16((int16_t)round(-timezone/60)); //*(int16_t*)(ptr+sectionStart+curSectLen+3) = l_endian_u16((int16_t)round(T0_tm->tm_gmtoff/60)); curSectLen += 8; // Tag 255 (len = 0) *(ptr+sectionStart+curSectLen) = 255; // tag *(uint16_t*)(ptr+sectionStart+curSectLen+1) = l_endian_u16(0); // length curSectLen += 3; // Evaluate the size and correct it if odd if (curSectLen & 1) { *(ptr+sectionStart+curSectLen++) = 0; } } else if (curSect==2) // SECTION 2 { } else if (curSect==3) // SECTION 3 { ptr = (uint8_t*)realloc(ptr,sectionStart+16+2+9*hdr->NS+1); PtrCurSect = ptr+sectionStart; curSectLen = 16; // current section length // Number of leads enclosed *(ptr+sectionStart+curSectLen++) = hdr->NS;// ### Situations with reference beat subtraction are not supported// Situations with not all the leads simultaneously recorded are not supported// Situations number of leads simultaneouly recorded != total number of leads are not supported// We assume all the leads are recorded simultaneously *(ptr+sectionStart+curSectLen++) = (hdr->NS<<3) | 0x04; for (i = 0; i < hdr->NS; i++) { *(uint32_t*)(ptr+sectionStart+curSectLen) = l_endian_u32(1L); *(uint32_t*)(ptr+sectionStart+curSectLen+4) = l_endian_u32(hdr->data.size[0]); *(ptr+sectionStart+curSectLen+8) = (uint8_t)hdr->CHANNEL[i].LeadIdCode; curSectLen += 9; } // Evaluate the size and correct it if odd if ((curSectLen % 2) != 0) { *(ptr+sectionStart+curSectLen++) = 0; } memset(ptr+sectionStart+10,0,6); // reserved } else if (curSect==4) // SECTION 4 { } else if (curSect==5) // SECTION 5 { curSectLen = 0; // current section length aECG->Section5.StartPtr = sectionStart; aECG->Section5.Length = curSectLen; } else if (curSect==6) // SECTION 6 { uint16_t GDFTYP = 3; size_t SZ = GDFTYP_BYTE[GDFTYP]; for (i = 0; i < hdr->NS; i++) hdr->CHANNEL[i].GDFTYP = GDFTYP; ptr = (uint8_t*)realloc(ptr,sectionStart+16+6+2*hdr->NS+SZ*(hdr->data.size[0]*hdr->data.size[1])); PtrCurSect = ptr+sectionStart; curSectLen = 16; // current section length // Create all the fields // Amplitude Value Multiplier (AVM) i = 0; AVM = hdr->CHANNEL[i].Cal * 1e9 * PhysDimScale(hdr->CHANNEL[i].PhysDimCode); for (i = 1; i < hdr->NS; i++) { // check for physical dimension and adjust scaling factor to "nV" avm = hdr->CHANNEL[i].Cal * 1e9 * PhysDimScale(hdr->CHANNEL[i].PhysDimCode); // check whether all channels have the same scaling factor if (fabs((AVM - avm)/AVM) > 1e-14) fprintf(stderr,"Warning SOPEN (SCP-WRITE): scaling factors differ between channels. Scaling factor of 1st channel is used.\n"); }; *(uint16_t*)(ptr+sectionStart+curSectLen) = l_endian_u16((uint16_t)AVM); avm = l_endian_u16(*(uint16_t*)(ptr+sectionStart+curSectLen)); curSectLen += 2; if (fabs((AVM - avm)/AVM)>1e-14) fprintf(stderr,"Warning SOPEN (SCP-WRITE): Scaling factor has been truncated (%f instead %f).\n",avm,AVM); // Sample interval AVM = 1e6/hdr->SampleRate; *(uint16_t*)(ptr+sectionStart+curSectLen) = l_endian_u16((uint16_t)AVM); avm = l_endian_u16(*(uint16_t*)(ptr+sectionStart+curSectLen)); curSectLen += 2; if (fabs((AVM - avm)/AVM)>1e-14) fprintf(stderr,"Warning SOPEN (SCP-WRITE): Sampling interval has been truncated (%f instead %f us).\n",avm,AVM); // Diff used *(ptr+sectionStart+curSectLen++) = 0; // Bimodal/Non-bimodal *(ptr+sectionStart+curSectLen++) = 0; /* DATA COMPRESSION currently, no compression method is supported. In case of data compression, the data compression can happen here. */ // Fill the length block for (i = 0; i < hdr->NS; i++) { *(uint16_t*)(ptr+sectionStart+curSectLen) = l_endian_u16((uint16_t)hdr->data.size[0]*2); avm = l_endian_u16(*(uint16_t*)(ptr+sectionStart+curSectLen)); AVM = hdr->data.size[0]*2; if (fabs((AVM - avm)/AVM)>1e-14) fprintf(stderr,"Warning SOPEN (SCP-WRITE): Block length truncated (%f instead %f us).\n",avm,AVM); curSectLen += 2; } /* data in channel multiplexed order */ for (i = 0; i < hdr->NS; i++) { hdr->CHANNEL[i].SPR *= hdr->NRec; }; hdr->NRec = 1; // Prepare filling the data block with the ECG samples by SWRITE // free(hdr->AS.rawdata); // hdr->AS.rawdata = PtrCurSect+16+6+2*hdr->NS; curSectLen += SZ*(hdr->data.size[0]*hdr->data.size[1]); // Evaluate the size and correct it if odd if ((curSectLen % 2) != 0) { fprintf(stderr,"Warning Section 6 has an odd length\n"); *(ptr+sectionStart+curSectLen++) = 0; } memset(ptr+sectionStart+10,0,6); // reserved aECG->Section6.StartPtr = sectionStart; aECG->Section6.Length = curSectLen; } else if (curSect==7) // SECTION 7 { } else if (curSect==8) // SECTION 8 { } else if (curSect==9) // SECTION 9 { } else if (curSect==10) // SECTION 10 { } else if (curSect==11) // SECTION 11 { } else { } // write to pointer field in Section 0 *(uint16_t*)(ptr+curSect*10+6+16) = l_endian_u16(curSect); // *(uint32_t*)(ptr+curSect*10+6+16+2) = l_endian_u32(curSectLen); // length // Section start - must be odd. See EN1064:2005(E) Section 5.2.1 // write to Section ID Header if (curSectLen>0) { // Section 0: startpos in pointer field *(uint32_t*)(ptr+curSect*10+6+16+6) = l_endian_u32(sectionStart+1); // Section ID header (16 bytes) *(int16_t*)(ptr+sectionStart+2) = l_endian_u16(curSect); // Section ID *(uint32_t*)(ptr+sectionStart+4)= l_endian_u32(curSectLen); // section length->section header ptr[sectionStart+8] = VERSION; // Section Version Number ptr[sectionStart+9] = VERSION; // Protocol Version Number crc = CRCEvaluate(ptr+sectionStart+2,curSectLen-2); // compute CRC *(uint16_t*)(ptr+sectionStart) = l_endian_u16(crc); } sectionStart += curSectLen; // offset for next section } // Prepare filling the data block with the ECG samples by SWRITE hdr->AS.rawdata = ptr+aECG->Section6.StartPtr+16+6+2*hdr->NS; hdr->AS.Header = ptr; return(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -