📄 biosig.c
字号:
hdr->CHANNEL[k].GDFTYP = 3; hdr->CHANNEL[k].SPR = 1; // *(int32_t*)(Header1+56); hdr->CHANNEL[k].Label = Header2+k*75; hdr->CHANNEL[k].PhysDim = "uV"; hdr->CHANNEL[k].PhysDimCode = 4256+19; hdr->CHANNEL[k].Cal = l_endian_f32(*(float*)(Header2+k*75+59)); hdr->CHANNEL[k].Cal *= l_endian_f32(*(float*)(Header2+k*75+71))/204.8; hdr->CHANNEL[k].Off = l_endian_f32(*(float*)(Header2+k*75+47)) * hdr->CHANNEL[k].Cal; hdr->CHANNEL[k].HighPass= CNT_SETTINGS_HIGHPASS[(uint8_t)Header2[64+k*75]]; hdr->CHANNEL[k].LowPass = CNT_SETTINGS_LOWPASS[(uint8_t)Header2[65+k*75]]; hdr->CHANNEL[k].Notch = CNT_SETTINGS_NOTCH[(uint8_t)Header1[682]]; hdr->CHANNEL[k].OnOff = 1; } /* extract more header information */ // eventtablepos = l_endian_u32( *(uint32_t*) (Header1+886) ); fseek(hdr->FILE.FID,_eventtablepos,SEEK_SET); hdr->FLAG.OVERFLOWDETECTION = 0; // automated overflow and saturation detection not supported } else if (hdr->TYPE==SCP_ECG) { fseek(hdr->FILE.FID,0,-1); hdr = sopen_SCP_read(Header1,hdr); } else if (hdr->TYPE==XML) { hdr = sopen_HL7aECG_read(hdr); } else // if (hdr->TYPE==unknown) { fprintf(stdout,"unknown file format %s \n",hdr->FileName); } }else { // WRITE if (hdr->TYPE==GDF) { hdr->HeadLen = (hdr->NS+1)*256; Header1 = (char*) malloc(hdr->HeadLen); Header2 = Header1+256; memset(Header1,0,hdr->HeadLen); sprintf(Header1,"GDF %4.2f",hdr->VERSION); strncat(Header1+8, hdr->Patient.Id, 66); strncat(Header1+8, " ", 66); strncat(Header1+8, hdr->Patient.Name, 66); Header1[84] = (hdr->Patient.Smoking%4) + ((hdr->Patient.AlcoholAbuse%4)<<2) + ((hdr->Patient.DrugAbuse%4)<<4) + ((hdr->Patient.Medication%4)<<6); Header1[85] = hdr->Patient.Weight; Header1[86] = hdr->Patient.Height; Header1[87] = (hdr->Patient.Sex%4) + ((hdr->Patient.Handedness%4)<<2) + ((hdr->Patient.Impairment.Visual%4)<<4); len = strlen(hdr->AS.RID); memcpy(Header1+ 88, hdr->AS.RID, min(len,80)); memcpy(Header1+152, &hdr->LOC, 16); *(uint32_t*) (Header1+152) = l_endian_u32( *(uint32_t*) (Header1+152) ); *(uint32_t*) (Header1+156) = l_endian_u32( *(uint32_t*) (Header1+156) ); *(uint32_t*) (Header1+160) = l_endian_u32( *(uint32_t*) (Header1+160) ); *(uint32_t*) (Header1+164) = l_endian_u32( *(uint32_t*) (Header1+164) ); //memcpy(Header1+168, &hdr->T0, 8); *(uint64_t*) (Header1+168) = l_endian_u64(hdr->T0); //memcpy(Header1+176, &hdr->Patient.Birthday, 8); *(uint64_t*) (Header1+176) = l_endian_u64(hdr->Patient.Birthday); // *(uint16_t*)(Header1+184) = (hdr->HeadLen>>8)+(hdr->HeadLen%256>0); *(uint16_t*) (Header1+184) = l_endian_u16(hdr->HeadLen>>8); memcpy(Header1+192, &hdr->ID.Equipment, 8); memcpy(Header1+200, &hdr->IPaddr, 6); memcpy(Header1+206, &hdr->Patient.Headsize, 6); *(float*) (Header1+212) = l_endian_f32(hdr->ELEC.REF[0]); *(float*) (Header1+216) = l_endian_f32(hdr->ELEC.REF[1]); *(float*) (Header1+220) = l_endian_f32(hdr->ELEC.REF[2]); *(float*) (Header1+224) = l_endian_f32(hdr->ELEC.GND[0]); *(float*) (Header1+228) = l_endian_f32(hdr->ELEC.GND[1]); *(float*) (Header1+232) = l_endian_f32(hdr->ELEC.GND[2]); //memcpy(Header1+236, &hdr->NRec, 8); *(uint64_t*) (Header1+236) = l_endian_u64(hdr->NRec); //memcpy(Header1+244, &hdr->Dur, 8); *(uint32_t*) (Header1+244) = l_endian_u32(hdr->Dur[0]); *(uint32_t*) (Header1+248) = l_endian_u32(hdr->Dur[1]); //memcpy(Header1+252, &hdr->NS, 2); *(uint16_t*) (Header1+252) = l_endian_u16(hdr->NS); /* define HDR.Header2 this requires checking the arguments in the fields of the struct HDR.CHANNEL and filling in the bytes in HDR.Header2. */ for (k=0;k<hdr->NS;k++) { len = strlen(hdr->CHANNEL[k].Label); memcpy(Header2+16*k,hdr->CHANNEL[k].Label,min(len,16)); len = strlen(hdr->CHANNEL[k].Transducer); memcpy(Header2+80*k + 16*hdr->NS,hdr->CHANNEL[k].Transducer,min(len,80)); len = strlen(hdr->CHANNEL[k].PhysDim); if (hdr->VERSION<1.9) memcpy(Header2+ 8*k + 96*hdr->NS,hdr->CHANNEL[k].PhysDim,min(len,8)); else { memcpy(Header2+ 6*k + 96*hdr->NS,hdr->CHANNEL[k].PhysDim,min(len,6)); *(uint16_t*)(Header2+ 2*k +102*hdr->NS) = l_endian_u16(hdr->CHANNEL[k].PhysDimCode); }; *(double*)(Header2 + 8*k + 104*hdr->NS) = l_endian_f64(hdr->CHANNEL[k].PhysMin); *(double*)(Header2 + 8*k + 112*hdr->NS) = l_endian_f64(hdr->CHANNEL[k].PhysMax); *(double*)(Header2 + 8*k + 120*hdr->NS) = l_endian_f64(hdr->CHANNEL[k].DigMin); *(double*)(Header2 + 8*k + 128*hdr->NS) = l_endian_f64(hdr->CHANNEL[k].DigMax); *(float*) (Header2+ 4*k + 204*hdr->NS) = l_endian_f32(hdr->CHANNEL[k].LowPass); *(float*) (Header2+ 4*k + 208*hdr->NS) = l_endian_f32(hdr->CHANNEL[k].HighPass); *(float*) (Header2+ 4*k + 212*hdr->NS) = l_endian_f32(hdr->CHANNEL[k].Notch); *(uint32_t*) (Header2+ 4*k + 216*hdr->NS) = l_endian_u32(hdr->CHANNEL[k].SPR); *(uint32_t*) (Header2+ 4*k + 220*hdr->NS) = l_endian_u32(hdr->CHANNEL[k].GDFTYP); *(float*) (Header2+ 4*k + 224*hdr->NS) = l_endian_f32(hdr->CHANNEL[k].XYZ[0]); *(float*) (Header2+ 4*k + 228*hdr->NS) = l_endian_f32(hdr->CHANNEL[k].XYZ[1]); *(float*) (Header2+ 4*k + 232*hdr->NS) = l_endian_f32(hdr->CHANNEL[k].XYZ[2]); Header2[k+236*hdr->NS] = (uint8_t)ceil(log10(min(39e8,hdr->CHANNEL[k].Impedance))/log10(2.0)*8.0-0.5); } hdr->AS.bi = (uint32_t*) realloc(hdr->AS.bi,(hdr->NS+1)*sizeof(int32_t)); hdr->AS.bi[0] = 0; for (k=0, hdr->AS.spb=0, hdr->AS.bpb=0; k<hdr->NS;) { hdr->AS.spb += hdr->CHANNEL[k].SPR; hdr->AS.bpb += GDFTYP_BYTE[hdr->CHANNEL[k].GDFTYP] * hdr->CHANNEL[k].SPR; hdr->AS.bi[++k] = hdr->AS.bpb; } hdr->AS.Header1 = Header1; } else if ((hdr->TYPE==EDF) | (hdr->TYPE==BDF)) { hdr->HeadLen = (hdr->NS+1)*256; Header1 = (char*) malloc(hdr->HeadLen); Header2 = Header1+256; if (hdr->TYPE==BDF) { Header1[0] = 255; memcpy(Header1+1,"BIOSEMI",7); } else { memset(Header1,' ',hdr->HeadLen); memcpy(Header1,"0 ",8); } tt = gdf_time2t_time(hdr->Patient.Birthday); if (hdr->Patient.Birthday>1) strftime(tmp,81,"%d-%b-%Y",localtime(&tt)); else strcpy(tmp,"X"); sprintf(cmd,"%s %c %s %s",hdr->Patient.Id,GENDER[hdr->Patient.Sex],tmp,hdr->Patient.Name); memcpy(Header1+8, cmd, strlen(cmd)); tt = gdf_time2t_time(hdr->T0); if (hdr->T0>1) strftime(tmp,81,"%d-%b-%Y",localtime(&tt)); else strcpy(tmp,"X"); len = sprintf(cmd,"Startdate %s X X ",tmp); memcpy(Header1+88, cmd, len); memcpy(Header1+88+len, &hdr->ID.Equipment, 8); tt = gdf_time2t_time(hdr->T0); strftime(tmp,81,"%d.%m.%y%H:%M:%S",localtime(&tt)); memcpy(Header1+168, tmp, 16); len = sprintf(tmp,"%i",hdr->HeadLen); if (len>8) fprintf(stderr,"Warning: HeaderLength is (%s) to long.\n",tmp); memcpy(Header1+184, tmp, len); memcpy(Header1+192, "EDF+C ", 5); len = sprintf(tmp,"%lu",hdr->NRec); if (len>8) fprintf(stderr,"Warning: NRec is (%s) to long.\n",tmp); memcpy(Header1+236, tmp, len); len = sprintf(tmp,"%f",((double)hdr->Dur[0])/hdr->Dur[1]); if (len>8) fprintf(stderr,"Warning: Duration is %s) to long.\n",tmp); memcpy(Header1+244, tmp, len); len = sprintf(tmp,"%i",hdr->NS); if (len>4) fprintf(stderr,"Warning: NS is %s) to long.\n",tmp); memcpy(Header1+252, tmp, len); for (k=0;k<hdr->NS;k++) { len = strlen(hdr->CHANNEL[k].Label); if (len>16) fprintf(stderr,"Warning: Label (%s) of channel %i is to long.\n",hdr->CHANNEL[k].Label,k); memcpy(Header2+16*k,hdr->CHANNEL[k].Label,min(len,16)); len = strlen(hdr->CHANNEL[k].Transducer); if (len>80) fprintf(stderr,"Warning: Transducer (%s) of channel %i is to long.\n",hdr->CHANNEL[k].Transducer,k); memcpy(Header2+80*k + 16*hdr->NS,hdr->CHANNEL[k].Transducer,min(len,80)); len = strlen(hdr->CHANNEL[k].PhysDim); if (len>8) fprintf(stderr,"Warning: Physical Dimension (%s) of channel %i is to long.\n",hdr->CHANNEL[k].PhysDim,k); memcpy(Header2+ 8*k + 96*hdr->NS,hdr->CHANNEL[k].PhysDim,min(len,8)); len = sprintf(tmp,"%f",hdr->CHANNEL[k].PhysMin); if (len>8) fprintf(stderr,"Warning: PhysMin (%s) of channel %i is to long.\n",tmp,k); memcpy(Header2+ 8*k + 104*hdr->NS,tmp,min(8,len)); len = sprintf(tmp,"%f",hdr->CHANNEL[k].PhysMax); if (len>8) fprintf(stderr,"Warning: PhysMax (%s) of channel %i is to long.\n",tmp,k); memcpy(Header2+ 8*k + 112*hdr->NS,tmp,min(8,len)); len = sprintf(tmp,"%f",hdr->CHANNEL[k].DigMin); if (len>8) fprintf(stderr,"Warning: DigMin (%s) of channel %i is to long.\n",tmp,k); memcpy(Header2+ 8*k + 120*hdr->NS,tmp,min(8,len)); len = sprintf(tmp,"%f",hdr->CHANNEL[k].DigMax); if (len>8) fprintf(stderr,"Warning: DigMax (%s) of channel %i is to long.\n",tmp,k); memcpy(Header2+ 8*k + 128*hdr->NS,tmp,min(8,len)); if (hdr->CHANNEL[k].Notch>0) len = sprintf(tmp,"HP:%fHz LP:%fHz Notch:%fHz",hdr->CHANNEL[k].HighPass,hdr->CHANNEL[k].LowPass,hdr->CHANNEL[k].Notch); else len = sprintf(tmp,"HP:%fHz LP:%fHz",hdr->CHANNEL[k].HighPass,hdr->CHANNEL[k].LowPass); memcpy(Header2+ 80*k + 136*hdr->NS,tmp,min(80,len)); len = sprintf(tmp,"%i",hdr->CHANNEL[k].SPR); if (len>8) fprintf(stderr,"Warning: SPR (%s) of channel %i is to long.\n",tmp,k); memcpy(Header2+ 8*k + 216*hdr->NS,tmp,min(8,len)); hdr->CHANNEL[k].GDFTYP = ( (hdr->TYPE != BDF) ? 3 : 255+24); } hdr->AS.Header1 = Header1; } else if (hdr->TYPE==SCP_ECG) { hdr->FileName = FileName;// hdr->AS.Header1 = Header1; hdr = sopen_SCP_write(hdr); } else if (hdr->TYPE==HL7aECG) { hdr = sopen_HL7aECG_write(hdr); } else { fprintf(stderr,"ERROR: Writing of format (%c) not supported\n",hdr->TYPE); return(NULL); } /* ##FIXME## this is a hack. Currently, the SCP file is written within the DoTheSCPfile. Therefore it must not be written again. */ if (hdr->TYPE!=SCP_ECG) { hdr->FILE.FID = fopen(FileName,"wb"); if (hdr->FILE.FID == NULL) { fprintf(stderr,"ERROR: Unable to open file %s \n",FileName); return(NULL); } fwrite(hdr->AS.Header1,sizeof(char),hdr->HeadLen,hdr->FILE.FID); hdr->FILE.OPEN = 2; hdr->FILE.POS = 0; }; } // end of else // internal variables hdr->AS.bi = (uint32_t*) realloc(hdr->AS.bi,(hdr->NS+1)*sizeof(uint32_t)); hdr->AS.bi[0] = 0; for (k=0, hdr->SPR = 1, hdr->AS.spb=0, hdr->AS.bpb=0; k<hdr->NS;) { hdr->AS.spb += hdr->CHANNEL[k].SPR; hdr->AS.bpb += GDFTYP_BYTE[hdr->CHANNEL[k].GDFTYP]*hdr->CHANNEL[k].SPR; hdr->SPR = lcm(hdr->SPR,hdr->CHANNEL[k].SPR); hdr->AS.bi[++k] = hdr->AS.bpb; } return(hdr);} // end of SOPEN /****************************************************************************//** SREAD **//****************************************************************************/size_t sread(HDRTYPE* hdr, size_t start, size_t length) {/* * reads LENGTH blocks with HDR.AS.bpb BYTES each, * rawdata is available in hdr->AS.rawdata * output data is available in hdr->data.block * size of output data is availabe in hdr->data.size * * channel selection is controlled by hdr->CHANNEL[k}.OnOff * * start <0: read from current position * >=0: start reading from position start * length : try to read length blocks * */ size_t count,k1,k2,k3,k4,k5,DIV,SZ,nelem; int GDFTYP; uint8_t* ptr; CHANNEL_TYPE* CHptr; int32_t int32_value; biosig_data_type sample_value; // check reading segment if (start >= 0) { if (start > hdr->NRec) return(0); else if (fseek(hdr->FILE.FID, start*hdr->AS.bpb + hdr->HeadLen, SEEK_SET)) return(0); hdr->FILE.POS = start; } if (hdr->TYPE != SCP_ECG) { // allocate AS.rawdata hdr->AS.rawdata = (uint8_t*) realloc(hdr->AS.rawdata, (hdr->AS.bpb)*length); // limit reading to end of data block nelem = max(min(length, hdr->NRec - hdr->FILE.POS),0); // read data count = fread(hdr->AS.rawdata, hdr->AS.bpb, nelem, hdr->FILE.FID); if (count<nelem) fprintf(stderr,"warning: only %i instead of %i blocks read - something went wrong\n",count,nelem,hdr->FILE.POS,hdr->AS.bpb); } else { // SCP format // hdr->AS.rawdata was defined in SOPEN count = hdr->SPR*hdr->NRec; } // set position of file handle hdr->FILE.POS += count; // transfer RAW into BIOSIG data format hdr->data.block = (biosig_data_type*) realloc(hdr->data.block, (hdr->SPR) * count * (hdr->NS) * sizeof(biosig_data_type)); for (k1=0,k2=0; k1<hdr->NS; k1++) { CHptr = hdr->CHANNEL+k1; if (1) //(CHptr->OnOff != 0) { DIV = hdr->SPR/CHptr->SPR; GDFTYP = CHptr->GDFTYP; SZ = GDFTYP_BYTE[GDFTYP]; int32_value = 0; for (k4 = 0; k4 < count; k4++) for (k5 = 0; k5 < CHptr->SPR; k5++) { // get source address ptr = hdr->AS.rawdata + k4*hdr->AS.bpb + hdr->AS.bi[k1] + k5*SZ; // mapping of raw data type to (biosig_data_type) if (0); else if (GDFTYP==3) sample_value = (biosig_data_type)l_endian_i16(*(int16_t*)ptr); else if (GDFTYP==4) sample_value = (biosig_data_type)l_endian_u16(*(uint16_t*)ptr); else if (GDFTYP==16) sample_value = (biosig_data_type)(l_endian_f32(*(float*)(ptr))); else if (GDFTYP==17) sample_value = (biosig_data_type)(l_endian_f64(*(double*)(ptr))); else if (GDFTYP==0) sample_value = (biosig_data_type)(*(char*)ptr); else if (GDFTYP==1) sample_value = (biosig_data_type)(*(int8_t*)ptr); else if (GDFTYP==2) sample_value = (biosig_data_type)(*(uint8_t*)ptr); else if (GDFTYP==5) sample_value = (biosig_data_type)l_endian_i32(*(int32_t*)ptr); else if (GDFTYP==6) sample_value = (biosig_data_type)l_endian_u32(*(uint32_t*)ptr); else if (GDFTYP==7) sample_value = (biosig_data_type)l_endian_i64(*(int64_t*)ptr); else if (GDFTYP==8) sample_value = (biosig_data_type)l_endian_u64(*(uint64_t*)ptr); else if (GDFTYP==255+24) { int32_value = (*(uint8_t*)(ptr)) + (*(uint8_t*)(ptr+1)<<8) + (*(int8_t*)(ptr+2)*(1<<16)); sample_value = (biosig_data_type)int32_value; } else if (GDFTYP==511+24) { int32_value = (*(uint8_t*)(ptr)) + (*(uint8_t*)(ptr+1)<<8) + (*(uint8_t*)(ptr+2)<<16); sample_value = (biosig_data_type)int32_value; } else { fprintf(stderr,"Error SREAD: datatype %i not supported\n",GDFTYP); exit(-1); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -