📄 biosig.c
字号:
ret = xmlTextReaderRead(reader); } if (ret != 0) { fprintf(stderr, "%s : failed to parse\n", hdr->FileName); } /* * Once the document has been fully parsed check the validation results */ if (xmlTextReaderIsValid(reader) != 1) { fprintf(stderr, "Document %s does not validate\n", hdr->FileName); } xmlFreeTextReader(reader); hdr->TYPE = XML; } else#endif { hdr->TYPE = unknown; // sclose(hdr); // free(hdr); } } if (hdr->TYPE == GDF) { strncpy(tmp,(char*)Header1+3,5); hdr->VERSION = atof(tmp); hdr->NRec = l_endian_i64( *( int64_t*) (Header1+236) ); hdr->Dur[0] = l_endian_u32( *(uint32_t*) (Header1+244) ); hdr->Dur[1] = l_endian_u32( *(uint32_t*) (Header1+248) ); hdr->NS = l_endian_u16( *(uint16_t*) (Header1+252) ); if (hdr->VERSION > 1.90) { hdr->HeadLen = l_endian_u16( *(uint16_t*) (Header1+184) )<<8; strncpy(hdr->AS.PID,Header1+8,66); hdr->Patient.Id = strtok(hdr->AS.PID," "); hdr->Patient.Name = strtok(NULL," "); hdr->Patient.Smoking = Header1[84]%4; hdr->Patient.AlcoholAbuse = (Header1[84]>>2)%4; hdr->Patient.DrugAbuse = (Header1[84]>>4)%4; hdr->Patient.Medication = (Header1[84]>>6)%4; hdr->Patient.Weight = Header1[85]; hdr->Patient.Height = Header1[86]; hdr->Patient.Sex = Header1[87]%4; hdr->Patient.Handedness = (Header1[87]>>2)%4; hdr->Patient.Impairment.Visual = (Header1[87]>>4)%4; *(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) ); if (Header1[156]) { hdr->LOC[0] = 0x00292929; memcpy(&hdr->LOC[1], Header1+156, 12); } else { *(uint32_t*) (Header1+152) = l_endian_u32(*(uint32_t*) (Header1+152)); memcpy(&hdr->LOC, Header1+152, 16); } hdr->T0 = l_endian_i64( *(int64_t*) (Header1+168) ); hdr->Patient.Birthday = l_endian_i64( *(int64_t*) (Header1+176) ); // memcpy(&hdr->T0, Header1+168,8); // memcpy(&hdr->Patient.Birthday, Header1+176, 8); hdr->ID.Equipment = l_endian_i64( *(int64_t*) (Header1+192) ); memcpy(&hdr->IPaddr, Header1+200,6); hdr->Patient.Headsize[0]= l_endian_u16( *(uint16_t*)(Header1+206) ); hdr->Patient.Headsize[1]= l_endian_u16( *(uint16_t*)(Header1+208) ); hdr->Patient.Headsize[2]= l_endian_u16( *(uint16_t*)(Header1+210) ); //memcpy(&hdr->ELEC.REF, Header1+212,12); //memcpy(&hdr->ELEC.GND, Header1+224,12); hdr->ELEC.REF[0] = l_endian_f32( *(float*)(Header1+ 212) ); hdr->ELEC.REF[1] = l_endian_f32( *(float*)(Header1+ 216) ); hdr->ELEC.REF[2] = l_endian_f32( *(float*)(Header1+ 220) ); hdr->ELEC.GND[0] = l_endian_f32( *(float*)(Header1+ 212) ); hdr->ELEC.GND[1] = l_endian_f32( *(float*)(Header1+ 216) ); hdr->ELEC.GND[2] = l_endian_f32( *(float*)(Header1+ 220) ); } else { strncpy(hdr->AS.PID,Header1+8,80); hdr->Patient.Id = strtok(hdr->AS.PID," "); hdr->Patient.Name = strtok(NULL," "); tm_time.tm_sec = atoi(strncpy(tmp,Header1+168+12,2)); tm_time.tm_min = atoi(strncpy(tmp,Header1+168+10,2)); tm_time.tm_hour = atoi(strncpy(tmp,Header1+168+8,2)); tm_time.tm_mday = atoi(strncpy(tmp,Header1+168+6,2)); tm_time.tm_mon = atoi(strncpy(tmp,Header1+168+4,2)); tm_time.tm_year = atoi(strncpy(tmp,Header1+168,4)); hdr->T0 = t_time2gdf_time(mktime(&tm_time)); hdr->HeadLen = l_endian_u64( *(uint64_t*) (Header1+184) ); } hdr->CHANNEL = (CHANNEL_TYPE*) calloc(hdr->NS,sizeof(CHANNEL_TYPE)); Header1 = (char*)realloc(Header1,hdr->HeadLen); Header2 = Header1+256; count = fread(Header2, 1, hdr->HeadLen-256, hdr->FILE.FID); for (k=0; k<hdr->NS; k++) { Header2[16*k + 15] = 0; hdr->CHANNEL[k].Label = (Header2 + 16*k); Header2[16*hdr->NS + 80*k + 79] = 0; hdr->CHANNEL[k].Transducer = (Header2 + 16*hdr->NS + 80*k); hdr->CHANNEL[k].PhysMin = l_endian_f64( *(double*) (Header2+ 8*k + 104*hdr->NS) ); hdr->CHANNEL[k].PhysMax = l_endian_f64( *(double*) (Header2+ 8*k + 112*hdr->NS) ); hdr->CHANNEL[k].SPR = l_endian_u32( *(uint32_t*) (Header2+ 4*k + 216*hdr->NS) ); hdr->CHANNEL[k].GDFTYP = l_endian_u16( *(uint16_t*) (Header2+ 4*k + 220*hdr->NS) ); if (hdr->VERSION < 1.90) { Header2[96*hdr->NS + 16*k + 15] = 0; hdr->CHANNEL[k].PhysDim = (Header2 + 96*hdr->NS + 8*k); /* ###FIXME### hdr->CHANNEL[k].PhysDimCode = hdr->CHANNEL[k].PreFilt = (hdr->Header2+ 68*k + 136*hdr->NS); */ hdr->CHANNEL[k].DigMin = (double) l_endian_i64( *(int64_t*)(Header2+ 8*k + 120*hdr->NS) ); hdr->CHANNEL[k].DigMax = (double) l_endian_i64( *(int64_t*)(Header2+ 8*k + 128*hdr->NS) ); } else { /* ###FIXME### hdr->CHANNEL[k].PhysDim = */ hdr->CHANNEL[k].PhysDimCode = l_endian_u16( *(uint16_t*)(Header2+ 2*k + 102*hdr->NS) ); hdr->CHANNEL[k].DigMin = l_endian_f64( *(double*)(Header2+ 8*k + 120*hdr->NS) ); hdr->CHANNEL[k].DigMax = l_endian_f64( *(double*)(Header2+ 8*k + 128*hdr->NS) ); hdr->CHANNEL[k].LowPass = l_endian_f32( *(float*) (Header2+ 4*k + 204*hdr->NS) ); hdr->CHANNEL[k].HighPass = l_endian_f32( *(float*) (Header2+ 4*k + 208*hdr->NS) ); hdr->CHANNEL[k].Notch = l_endian_f32( *(float*) (Header2+ 4*k + 212*hdr->NS) ); hdr->CHANNEL[k].XYZ[0] = l_endian_f32( *(float*) (Header2+ 4*k + 224*hdr->NS) ); hdr->CHANNEL[k].XYZ[1] = l_endian_f32( *(float*) (Header2+ 4*k + 228*hdr->NS) ); hdr->CHANNEL[k].XYZ[2] = l_endian_f32( *(float*) (Header2+ 4*k + 232*hdr->NS) ); //memcpy(&hdr->CHANNEL[k].XYZ,Header2 + 4*k + 224*hdr->NS,12); hdr->CHANNEL[k].Impedance= ldexp(1.0, (uint8_t)Header2[k + 236*hdr->NS]/8); } hdr->CHANNEL[k].Cal = (hdr->CHANNEL[k].PhysMax-hdr->CHANNEL[k].PhysMin)/(hdr->CHANNEL[k].DigMax-hdr->CHANNEL[k].DigMin); hdr->CHANNEL[k].Off = hdr->CHANNEL[k].PhysMin-hdr->CHANNEL[k].Cal*hdr->CHANNEL[k].DigMin; } for (k=0, hdr->SPR=1, hdr->AS.spb=0, hdr->AS.bpb=0; k<hdr->NS;k++) { 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->SampleRate = ((double)(hdr->SPR))*hdr->Dur[1]/hdr->Dur[0]; // READ EVENTTABLE fseek(hdr->FILE.FID, hdr->HeadLen + hdr->AS.bpb*hdr->NRec, SEEK_SET); fread(buf, sizeof(uint8_t), 8, hdr->FILE.FID); if (hdr->VERSION < 1.94) { hdr->EVENT.SampleRate = (float)buf[1] + (buf[2] + buf[3]*256.0)*256.0; hdr->EVENT.N = l_endian_u32( *(uint32_t*) (buf + 4) ); } else { hdr->EVENT.N = buf[1] + (buf[2] + buf[3]*256)*256; hdr->EVENT.SampleRate = l_endian_f32( *(float*) (buf + 4) ); } hdr->EVENT.POS = (uint32_t*) realloc(hdr->EVENT.POS, hdr->EVENT.N*sizeof(*hdr->EVENT.POS) ); hdr->EVENT.TYP = (uint16_t*) realloc(hdr->EVENT.TYP, hdr->EVENT.N*sizeof(*hdr->EVENT.TYP) ); fread(hdr->EVENT.POS, sizeof(*hdr->EVENT.POS), hdr->EVENT.N, hdr->FILE.FID); fread(hdr->EVENT.TYP, sizeof(*hdr->EVENT.TYP), hdr->EVENT.N, hdr->FILE.FID); for (k32u=0; k32u < hdr->EVENT.N; k32u++) { hdr->EVENT.POS[k32u] = l_endian_u32(hdr->EVENT.POS[k32u]); hdr->EVENT.TYP[k32u] = l_endian_u16(hdr->EVENT.TYP[k32u]); } if (tmp[0]>1) { hdr->EVENT.DUR = (uint32_t*) realloc(hdr->EVENT.DUR,hdr->EVENT.N*sizeof(*hdr->EVENT.DUR)); hdr->EVENT.CHN = (uint16_t*) realloc(hdr->EVENT.CHN,hdr->EVENT.N*sizeof(*hdr->EVENT.CHN)); fread(hdr->EVENT.CHN,sizeof(*hdr->EVENT.CHN),hdr->EVENT.N,hdr->FILE.FID); fread(hdr->EVENT.DUR,sizeof(*hdr->EVENT.DUR),hdr->EVENT.N,hdr->FILE.FID); for (k32u=0; k32u<hdr->EVENT.N; k32u++) { hdr->EVENT.DUR[k32u] = l_endian_u32(hdr->EVENT.DUR[k32u]); hdr->EVENT.CHN[k32u] = l_endian_u16(hdr->EVENT.CHN[k32u]); } } else { hdr->EVENT.DUR = NULL; hdr->EVENT.CHN = NULL; } } else if ((hdr->TYPE == EDF) | (hdr->TYPE == BDF)) { strncpy(hdr->AS.PID,Header1+8,80); hdr->HeadLen = atoi(strncpy(tmp,Header1+184,8)); hdr->NRec = atoi(strncpy(tmp,Header1+236,8)); Dur = atoi(strncpy(tmp,Header1+244,8)); hdr->NS = atoi(strncpy(tmp,Header1+252,4)); if (!Dur) { hdr->Dur[0] = lround(Dur*1e7); hdr->Dur[1] = 10000000L; } tm_time.tm_sec = atoi(strncpy(tmp,Header1+168+14,2)); tm_time.tm_min = atoi(strncpy(tmp,Header1+168+11,2)); tm_time.tm_hour = atoi(strncpy(tmp,Header1+168+8,2)); tm_time.tm_mday = atoi(strncpy(tmp,Header1+168,2)); tm_time.tm_mon = atoi(strncpy(tmp,Header1+168+3,2)); tm_time.tm_year = atoi(strncpy(tmp,Header1+168+6,2)); tm_time.tm_year+= (tm_time.tm_year<85)*100; hdr->T0 = tm_time2gdf_time(&tm_time); if (!strncmp(Header1+192,"EDF+",4)) { hdr->Patient.Id = strtok(hdr->AS.PID," "); ptr_str = strtok(NULL," "); hdr->Patient.Sex = (ptr_str[0]=='f')*2 + (ptr_str[0]=='F')*2 + (ptr_str[0]=='M') + (ptr_str[0]=='m'); ptr_str = strtok(NULL," "); // birthday hdr->Patient.Name= strtok(NULL," "); if (strlen(ptr_str)==11) { tm_time.tm_mday = atoi(strtok(ptr_str,"-")); strcpy(tmp,strtok(NULL,"-")); tm_time.tm_year = atoi(strtok(NULL,"-"))-1900; tm_time.tm_mon = !strcmp(tmp,"Feb")+!strcmp(tmp,"Mar")*2+!strcmp(tmp,"Apr")*3+!strcmp(tmp,"May")*4+!strcmp(tmp,"Jun")*5+!strcmp(tmp,"Jul")*6+!strcmp(tmp,"Aug")*7+!strcmp(tmp,"Sep")*8+!strcmp(tmp,"Oct")*9+!strcmp(tmp,"Nov")*10+!strcmp(tmp,"Dec")*11; tm_time.tm_sec = 0; tm_time.tm_min = 0; tm_time.tm_hour = 12; hdr->Patient.Birthday = t_time2gdf_time(mktime(&tm_time)); } } hdr->CHANNEL = (CHANNEL_TYPE*) calloc(hdr->NS,sizeof(CHANNEL_TYPE)); Header1 = (char*) realloc(Header1,hdr->HeadLen); Header2 = Header1+256; count = fread(Header2, 1, hdr->HeadLen-256, hdr->FILE.FID); for (k=0; k<hdr->NS; k++) { hdr->CHANNEL[k].Label = (Header2 + 16*k); hdr->CHANNEL[k].Label[15]=0;// hack hdr->CHANNEL[k].Transducer = (Header2 + 80*k + 16*hdr->NS); hdr->CHANNEL[k].Transducer[79]=0;// hack hdr->CHANNEL[k].PhysDim = (Header2 + 8*k + 96*hdr->NS); tmp[8] = 0; strncpy(tmp,Header2 + 8*k + 104*hdr->NS,8); // PhysDim -> PhysDimCode belongs here hdr->CHANNEL[k].PhysDim[7]=0; //hack hdr->CHANNEL[k].PhysMin = atof(strncpy(tmp,Header2 + 8*k + 104*hdr->NS,8)); hdr->CHANNEL[k].PhysMax = atof(strncpy(tmp,Header2 + 8*k + 112*hdr->NS,8)); hdr->CHANNEL[k].DigMin = atof(strncpy(tmp,Header2 + 8*k + 120*hdr->NS,8)); hdr->CHANNEL[k].DigMax = atof(strncpy(tmp,Header2 + 8*k + 128*hdr->NS,8)); hdr->CHANNEL[k].Cal = (hdr->CHANNEL[k].PhysMax-hdr->CHANNEL[k].PhysMin)/(hdr->CHANNEL[k].DigMax-hdr->CHANNEL[k].DigMin); hdr->CHANNEL[k].Off = hdr->CHANNEL[k].PhysMin-hdr->CHANNEL[k].Cal*hdr->CHANNEL[k].DigMin; hdr->CHANNEL[k].SPR = atol(strncpy(tmp,Header2+ 8*k + 216*hdr->NS,8)); hdr->CHANNEL[k].GDFTYP = ((hdr->TYPE!=BDF) ? 3 : 255+24); //hdr->CHANNEL[k].PreFilt = (Header2+ 80*k + 136*hdr->NS); if ((hdr->TYPE==EDF) & strncmp(Header1+192,"EDF+",4)) { hdr->CHANNEL[k].OnOff = memcmp(hdr->CHANNEL[k].Label,"EDF Annotations",15); EventChannel = k; // decode filter information into hdr->Filter.{Lowpass, Highpass, Notch} } else if (hdr->TYPE==BDF) { hdr->CHANNEL[k].OnOff = strcmp(hdr->CHANNEL[k].Label,"Status"); EventChannel = k; } else { hdr->CHANNEL[k].OnOff = 1; } } hdr->FLAG.OVERFLOWDETECTION = 0; // EDF does not support automated overflow and saturation detection for (k=0, hdr->SPR=1, hdr->AS.spb=0, hdr->AS.bpb=0; k<hdr->NS; k++) { hdr->AS.spb += hdr->CHANNEL[k].SPR; hdr->AS.bpb += GDFTYP_BYTE[hdr->CHANNEL[k].GDFTYP]*hdr->CHANNEL[k].SPR; if (hdr->CHANNEL[k].OnOff) hdr->SPR = lcm(hdr->SPR,hdr->CHANNEL[k].SPR); } hdr->SampleRate = ((double)(hdr->SPR))*hdr->Dur[1]/hdr->Dur[0]; } else if (hdr->TYPE==BKR) { Header1 = (char*) realloc(Header1,1024); count = fread(Header1+256,1,1024-256,hdr->FILE.FID); hdr->HeadLen = 1024; hdr->NS = l_endian_u16( *(uint16_t*) (Header1+2) ); hdr->SampleRate = (double)l_endian_u16( *(uint16_t*) (Header1+4) ); hdr->NRec = l_endian_u32( *(uint32_t*) (Header1+6) ); hdr->SPR = l_endian_u32( *(uint32_t*) (Header1+10) ); hdr->NRec *= hdr->SPR; hdr->SPR = 1; hdr->T0 = 0; // Unknown; /* extract more header information */ hdr->CHANNEL = (CHANNEL_TYPE*) realloc(hdr->CHANNEL,hdr->NS*sizeof(CHANNEL_TYPE)); for (k=0; k<hdr->NS;k++) { hdr->CHANNEL[k].GDFTYP = 3; hdr->CHANNEL[k].SPR = 1; // *(int32_t*)(Header1+56); *(uint32_t*)(Header1+22) = l_endian_u32(*(uint32_t*)Header1+22); *(uint32_t*)(Header1+26) = l_endian_u32(*(uint32_t*)Header1+26); hdr->CHANNEL[k].LowPass = *(float*)(Header1+22); hdr->CHANNEL[k].HighPass = *(float*)(Header1+26); hdr->CHANNEL[k].Notch = -1.0; *(uint16_t*)(Header1+14) = l_endian_u16(*(uint16_t*)Header1+14); *(uint16_t*)(Header1+16) = l_endian_u16(*(uint16_t*)Header1+16); hdr->CHANNEL[k].PhysMax = (double)*(uint16_t*)(Header1+14); hdr->CHANNEL[k].DigMax = (double)*(uint16_t*)(Header1+16); hdr->CHANNEL[k].Cal = ((double)hdr->CHANNEL[k].PhysMax)/hdr->CHANNEL[k].DigMax; hdr->CHANNEL[k].Off = 0.0; hdr->CHANNEL[k].OnOff = 1; } hdr->FLAG.OVERFLOWDETECTION = 0; // BKR does not support automated overflow and saturation detection } else if (hdr->TYPE==CFWB) { *(uint64_t*)(Header1+8) = l_endian_u64(*(uint64_t*)Header1+8); hdr->SampleRate = *(double*) (Header1+8); tm_time.tm_year = l_endian_u32( *(int32_t*)(Header1+16) ); tm_time.tm_mon = l_endian_u32( *(int32_t*)(Header1+20) ); tm_time.tm_mday = l_endian_u32( *(int32_t*)(Header1+24) ); tm_time.tm_hour = l_endian_u32( *(int32_t*)(Header1+28) ); tm_time.tm_min = l_endian_u32( *(int32_t*)(Header1+32) ); *(uint64_t*)(Header1+36) = l_endian_u64(*(uint64_t*)Header1+36); tm_time.tm_sec = (int)*(double*) (Header1+36); hdr->T0 = tm_time2gdf_time(&tm_time); // = *(double*)(Header1+44); hdr->NS = l_endian_u32( *(int32_t*)(Header1+52) ); hdr->NRec = l_endian_u32( *(int32_t*)(Header1+56) ); // = *(int32_t*)(Header1+60); // TimeChannel // = *(int32_t*)(Header1+64); // DataFormat Header1 = (char*) realloc(Header1,68+96*hdr->NS); Header2 = Header1+96; hdr->HeadLen = 68+96*hdr->NS; fseek(hdr->FILE.FID,68,SEEK_SET); count = fread(Header2,1,96*hdr->NS,hdr->FILE.FID); hdr->CHANNEL = (CHANNEL_TYPE*) realloc(hdr->CHANNEL,hdr->NS*sizeof(CHANNEL_TYPE)); for (k=0; k<hdr->NS; k++) { hdr->CHANNEL[k].GDFTYP = CFWB_GDFTYP[l_endian_u32(*(uint32_t*)(Header1+64))-1]; hdr->CHANNEL[k].SPR = 1; // *(int32_t*)(Header1+56); hdr->CHANNEL[k].Label = Header2+k*96; hdr->CHANNEL[k].PhysDim = Header2+k*96+32; hdr->CHANNEL[k].Cal = l_endian_f64(*(double*)(Header2+k*96+64)); hdr->CHANNEL[k].Off = l_endian_f64(*(double*)(Header2+k*96+72)); hdr->CHANNEL[k].PhysMax = l_endian_f64(*(double*)(Header2+k*96+80)); hdr->CHANNEL[k].PhysMin = l_endian_f64(*(double*)(Header2+k*96+88)); hdr->CHANNEL[k].OnOff = 1; } hdr->FLAG.OVERFLOWDETECTION = 0; // CFWB does not support automated overflow and saturation detection } else if (hdr->TYPE==CNT) { Header1 = (char*) realloc(Header1,900); hdr->VERSION = atof(Header1+8); count = fread(Header1+256,1,900-256,hdr->FILE.FID); ptr_str = Header1+136; hdr->Patient.Sex = (ptr_str[0]=='f')*2 + (ptr_str[0]=='F')*2 + (ptr_str[0]=='M') + (ptr_str[0]=='m'); ptr_str = Header1+137; hdr->Patient.Handedness = (ptr_str[0]=='r')*2 + (ptr_str[0]=='R')*2 + (ptr_str[0]=='L') + (ptr_str[0]=='l'); tm_time.tm_sec = atoi(strncpy(tmp,Header1+225+16,2)); tm_time.tm_min = atoi(strncpy(tmp,Header1+225+13,2)); tm_time.tm_hour = atoi(strncpy(tmp,Header1+225+10,2)); tm_time.tm_mday = atoi(strncpy(tmp,Header1+225,2)); tm_time.tm_mon = atoi(strncpy(tmp,Header1+225+3,2)); tm_time.tm_year = atoi(strncpy(tmp,Header1+225+6,2)); if (tm_time.tm_year<=80) tm_time.tm_year += 2000; else if (tm_time.tm_year<100) tm_time.tm_year += 1900; hdr->T0 = tm_time2gdf_time(&tm_time); hdr->NS = l_endian_u16( *(uint16_t*) (Header1+370) ); hdr->HeadLen = 900+hdr->NS*75; hdr->SampleRate = l_endian_u16( *(uint16_t*) (Header1+376) ); hdr->SPR = 1; #define _eventtablepos (*(uint32_t*)(Header1+886)) hdr->NRec = (_eventtablepos-hdr->HeadLen)/(hdr->NS*2); Header1 = (char*) realloc(Header1,hdr->HeadLen); Header2 = Header1+900; count = fread(Header2,1,hdr->NS*75,hdr->FILE.FID); hdr->CHANNEL = (CHANNEL_TYPE*) calloc(hdr->NS,sizeof(CHANNEL_TYPE)); for (k=0; k<hdr->NS;k++) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -