📄 biosig.c
字号:
// overflow and saturation detection if ((hdr->FLAG.OVERFLOWDETECTION) && ((sample_value<=hdr->CHANNEL[k1].DigMin) || (sample_value>=hdr->CHANNEL[k1].DigMax))) sample_value = NaN; // missing value else if (!hdr->FLAG.UCAL) // scaling sample_value = sample_value * CHptr->Cal + CHptr->Off; // resampling 1->DIV samples for (k3=0; k3 < DIV; k3++) hdr->data.block[k2*count*hdr->SPR + k4*CHptr->SPR + k5 + k3] = sample_value; } k2++; }} hdr->data.size[0] = hdr->SPR*count; // rows hdr->data.size[1] = k2; // columns return(count);} // end of SREAD /****************************************************************************//** SREAD2 **//****************************************************************************/size_t sread2(biosig_data_type** channels_dest, size_t start, size_t length, HDRTYPE* hdr) {/* * no memory allocation is done * data is moved into channel_dest * 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; } // 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); // set position of file handle hdr->FILE.POS += count; // transfer RAW into BIOSIG data format // hdr->data.block = 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 (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 = (*ptr) + (*(ptr+1)<<8) + (*(ptr+2)*(1<<16)); sample_value = (biosig_data_type)int32_value; } else if (GDFTYP==511+24) { int32_value = (*ptr) + (*(ptr+1)<<8) + (*(ptr+2)<<16); sample_value = (biosig_data_type)int32_value; } else { fprintf(stderr,"Error SREAD: datatype %i not supported\n",GDFTYP); exit(-1); } // overflow and saturation detection if ((hdr->FLAG.OVERFLOWDETECTION) && ((sample_value<=hdr->CHANNEL[k1].DigMin) || (sample_value>=hdr->CHANNEL[k1].DigMax))) sample_value = NaN; // missing value else if (!(hdr->FLAG.UCAL)) // scaling sample_value = sample_value * CHptr->Cal + CHptr->Off; // resampling 1->DIV samples for (k3=0; k3 < DIV; k3++) *(channels_dest[k2] + k4*CHptr->SPR + k5 + k3) = sample_value; //hdr->data.block[k2*count*hdr->SPR + k4*CHptr->SPR + k5 + k3] = sample_value; } k2++; }} hdr->data.size[0] = hdr->SPR*count; // rows hdr->data.size[1] = k2; // columns return(count);} // end of SREAD2 /****************************************************************************//** SWRITE **//****************************************************************************/size_t swrite(const void *ptr, size_t nelem, HDRTYPE* hdr) {/* * writes NELEM blocks with HDR.AS.bpb BYTES each, */ size_t count; // fwrite(hdr->data.block, sizeof(biosig_data_type),hdr->NRec*hdr->SPR*hdr->NS, hdr->FILE.FID); // write data count = fwrite((uint8_t*)ptr, hdr->AS.bpb, nelem, hdr->FILE.FID);/* for (k1=0,k2=0; k1<hdr->NS; k1++) { CHptr = hdr->CHANNEL+k1; if (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) else ; } } } } */ // set position of file handle (hdr->FILE.POS) += count; return(count);} // end of SWRITE /****************************************************************************//** SEOF **//****************************************************************************/int seof(HDRTYPE* hdr){ return(hdr->FILE.POS >= hdr->NRec);}/****************************************************************************//** SREWIND **//****************************************************************************/void srewind(HDRTYPE* hdr){ sseek(hdr,0,SEEK_SET); return;}/****************************************************************************//** SSEEK **//****************************************************************************/int sseek(HDRTYPE* hdr, long int offset, int whence){ long int pos=0; if (whence < 0) pos = offset * hdr->AS.bpb; else if (whence == 0) pos = (hdr->FILE.POS + offset) * hdr->AS.bpb; else if (whence > 0) pos = (hdr->NRec + offset) * hdr->AS.bpb; if ((pos < 0) | (pos > hdr->NRec * hdr->AS.bpb)) return(-1); else if (fseek(hdr->FILE.FID, pos + hdr->HeadLen, SEEK_SET)) return(-1); hdr->FILE.POS = pos / (hdr->AS.bpb); return(0); } // end of SSEEK/****************************************************************************//** STELL **//****************************************************************************/long int stell(HDRTYPE* hdr){ size_t pos; pos = ftell(hdr->FILE.FID); if (pos<0) return(-1); else if (pos != (hdr->FILE.POS * hdr->AS.bpb + hdr->HeadLen)) return(-1); else return(hdr->FILE.POS); } // end of STELL/****************************************************************************//** SCLOSE **//****************************************************************************/int sclose(HDRTYPE* hdr){ int32_t pos, len; uint32_t k32u; uint8_t buf[88]; char tmp[88]; char flag; if ((hdr->NRec<0) & (hdr->FILE.OPEN>1)) if ((hdr->TYPE==GDF) | (hdr->TYPE==EDF) | (hdr->TYPE==BDF)) { // WRITE HDR.NRec pos = (ftell(hdr->FILE.FID)-hdr->HeadLen); if (hdr->NRec<0) { if (pos>0) hdr->NRec = pos/hdr->AS.bpb; else hdr->NRec = 0; fseek(hdr->FILE.FID,236,SEEK_SET); if (hdr->TYPE==GDF) { *(uint64_t*)tmp = l_endian_u64(hdr->NRec); fwrite(tmp,sizeof(hdr->NRec),1,hdr->FILE.FID); } else { len = sprintf(tmp,"%Lu",hdr->NRec); if (len>8) fprintf(stderr,"Warning: NRec is (%s) to long.\n",tmp); fwrite(tmp,len,1,hdr->FILE.FID); } }; // WRITE EVENTTABLE if ((hdr->TYPE==GDF) & (hdr->EVENT.N>0)) { fseek(hdr->FILE.FID, hdr->HeadLen + hdr->AS.bpb*hdr->NRec, SEEK_SET); flag = (hdr->EVENT.DUR != NULL) & (hdr->EVENT.CHN != NULL); if (flag) // any DUR or CHN is larger than 0 for (k32u=0, flag=0; (k32u<hdr->EVENT.N) & !flag; k32u++) flag |= hdr->EVENT.CHN[k32u] | hdr->EVENT.DUR[k32u]; buf[0] = (flag ? 3 : 1); if (hdr->VERSION < 1.94) { k32u = lround(hdr->EVENT.SampleRate); buf[1] = k32u & 0x000000FF; buf[2] = (k32u>>8 ) & 0x000000FF; buf[3] = (k32u>>16) & 0x000000FF; *(uint32_t*)(buf+4) = l_endian_u32(hdr->EVENT.N); } else { k32u = hdr->EVENT.N; buf[1] = k32u & 0x000000FF; buf[2] = (k32u>>8 ) & 0x000000FF; buf[3] = (k32u>>16) & 0x000000FF; *(float*)(buf+4) = l_endian_f32(hdr->EVENT.SampleRate); }; fwrite(buf, 8, 1, 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]); } fwrite(hdr->EVENT.POS, sizeof(*hdr->EVENT.POS), hdr->EVENT.N, hdr->FILE.FID); fwrite(hdr->EVENT.TYP, sizeof(*hdr->EVENT.TYP), hdr->EVENT.N, hdr->FILE.FID); if (tmp[0]>1) { 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]); } fwrite(hdr->EVENT.CHN,sizeof(*hdr->EVENT.CHN),hdr->EVENT.N,hdr->FILE.FID); fwrite(hdr->EVENT.DUR,sizeof(*hdr->EVENT.DUR),hdr->EVENT.N,hdr->FILE.FID); } } } if (hdr->TYPE != XML) { fclose(hdr->FILE.FID); hdr->FILE.FID = 0; } if (hdr->aECG != NULL) free(hdr->aECG); if (hdr->AS.rawdata != NULL) free(hdr->AS.rawdata); if (hdr->data.block != NULL) { free(hdr->data.block); hdr->data.size[0]=0; hdr->data.size[1]=0; } if (hdr->CHANNEL != NULL) free(hdr->CHANNEL); if (hdr->AS.bi != NULL) free(hdr->AS.bi); if (hdr->AS.Header1 != NULL) free(hdr->AS.Header1); if (hdr->EVENT.POS != NULL) free(hdr->EVENT.POS); if (hdr->EVENT.TYP != NULL) free(hdr->EVENT.TYP); if (hdr->EVENT.DUR != NULL) free(hdr->EVENT.DUR); if (hdr->EVENT.CHN != NULL) free(hdr->EVENT.CHN); hdr->EVENT.N = 0; hdr->FILE.OPEN = 0; return(0);}/****************************************************************************//** **//** EOF **//** **//****************************************************************************/// big-endian platforms
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -