1 /*
2 %
3 % $Id$
4 % Copyright (C) 2008,2009,2012 Alois Schloegl <alois.schloegl@ist.ac.at>
5 % This file is part of the "BioSig for C/C++" repository
6 % (biosig4c++) at http://biosig.sf.net/
7 
8 
9     This program is free software; you can redistribute it and/or
10     modify it under the terms of the GNU General Public License
11     as published by the Free Software Foundation; either version 3
12     of the License, or (at your option) any later version.
13 
14     This program is distributed in the hope that it will be useful,
15     but WITHOUT ANY WARRANTY; without even the implied warranty of
16     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17     GNU General Public License for more details.
18 
19     You should have received a copy of the GNU General Public License
20     along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 
22  */
23 
24 
25 // swig.i
26 
27 %module biosig
28 %{
29 #include "../biosig.h"
30 %}
31 
32 
33 %include <inttypes.i>
34 
35 
36 typedef int64_t gdf_time; 	/* gdf time is represented in 64 bits */
37 
38 typedef int64_t nrec_t; 	/* type for number of records */
39 
40 
41 	/* list of file formats */
42 enum FileFormat {
43 	noFile, unknown,
44 	ABF, ACQ, ACR_NEMA, AIFC, AIFF, AINF, alpha, ARFF,
45 	ASCII_IBI, ASCII, AU, ASF, ATES, ATF, AVI, Axona,
46 	BCI2000, BDF, BESA, BIN, BKR, BLSC, BMP, BNI, BSCS,
47 	BrainVision, BrainVisionVAmp, BrainVisionMarker, BZ2,
48 	CDF, CFS, CFWB, CNT, CTF, DICOM, DEMG,
49 	EBS, EDF, EEG1100, EEProbe, EEProbe2, EEProbeAvr, EGI,
50 	EGIS, ELF, EMBLA, EMSA, ePrime, ET_MEG, ETG4000, EVENT, EXIF,
51 	FAMOS, FEF, FITS, FLAC, GDF, GDF1,
52 	GIF, GTF, GZIP, HDF, HL7aECG, HEKA,
53 	ISHNE, ITX, JPEG, JSON, Lexicor,
54 	Matlab, MFER, MIDI, MIT, MM, MSI, MSVCLIB, MS_LNK,
55 	native, NeuroLoggerHEX, NetCDF, NEURON, NEV, NEX1, NIFTI,
56 	OGG, OpenXDF,
57 	PBMA, PBMN, PDF, PDP, Persyst, PGMA, PGMB,
58 	PLEXON, PNG, PNM, POLY5, PPMA, PPMB, PS,
59 	RDF, RIFF,
60 	SASXPT, SCP_ECG, SIGIF, Sigma, SMA, SND, SQLite,
61 	SPSS, STATA, SVG, SXI, SYNERGY,
62 	TIFF, TMS32, TMSiLOG, TRC, UNIPRO, VRML, VTK,
63 	WAV, WG1, WinEEG, WMF, XML, XPM,
64 	Z, ZIP, ZIP2
65 };
66 
67 
68 typedef struct CHANNEL_STRUCT {
69 	double 		PhysMin;		/* physical minimum */
70 	double 		PhysMax;		/* physical maximum */
71 	double 		DigMin;			/* digital minimum */
72 	double	 	DigMax;			/* digital maximum */
73 	double		Cal;			/* gain factor */
74 	double		Off;			/* bias */
75 
76 	char		OnOff;
77 	char		Label[MAX_LENGTH_LABEL+1]; 		/* Label of channel */
78 	uint16_t	LeadIdCode;				/* Lead identification code */
79 	char 		Transducer[MAX_LENGTH_TRANSDUCER+1];	/* transducer e.g. EEG: Ag-AgCl electrodes */
80 //	char 		PhysDim[MAX_LENGTH_PHYSDIM+1] ;		/* physical dimension */
81 			/*PhysDim is now obsolete - use function PhysDim3(PhysDimCode) instead */
82 	uint16_t	PhysDimCode;		/* code for physical dimension */
83 	/* char* 	PreFilt;		// pre-filtering */
84 
85 	float 		TOffset;		/* time delay of sampling */
86 	float 		LowPass;		/* lowpass filter */
87 	float 		HighPass;		/* high pass */
88 	float 		Notch;			/* notch filter */
89 	float 		XYZ[3];			/* sensor position */
90 //	float 		Orientation[3];		// sensor direction
91 //	float 		Area;			// area of sensor (e.g. for MEG)
92 
93 	union {
94         /* context specific channel information */
95 	float 		Impedance;   		/* Electrode Impedance in Ohm, defined only if PhysDim = _Volt */
96 	float 		fZ;	   		/* ICG probe frequency, defined only if PhysDim = _Ohm */
97 	};
98 
99 	uint16_t 	GDFTYP;			/* data type */
100 	uint32_t 	SPR;			/* samples per record (block) */
101 } CHANNEL_TYPE;
102 
103 
104 
105 /*
106 	This structure defines the general (fixed) header
107 */
108 typedef struct {
109 	float 		VERSION;	/* GDF version number */
110 	char* 	        FileName;
111 	enum FileFormat TYPE; 		/* type of file format */
112 
113 	struct {
114 		size_t 			size[2]; /* size {rows, columns} of data block	 */
115 		biosig_data_type* 	block; 	 /* data block */
116 	} data;
117 
118 	uint8_t 	IPaddr[16]; 	/* IP address of recording device (if applicable) */
119 	double 		SampleRate;	/* Sampling rate */
120 	int64_t  	NRec;		/* number of records/blocks -1 indicates length is unknown. */
121 	gdf_time 	T0; 		/* starttime of recording */
122 	uint32_t 	HeadLen;	/* length of header in bytes */
123 	uint32_t 	SPR;		/* samples per block (when different sampling rates are used, this is the LCM(CHANNEL[..].SPR) */
124 	uint32_t  	LOC[4];		/* location of recording according to RFC1876 */
125 	uint16_t 	NS;		/* number of channels */
126 	int16_t 	tzmin; 		/* time zone (minutes of difference to UTC */
127 
128 #ifdef CHOLMOD_H
129 	cholmod_sparse  *Calib;                  /* re-referencing matrix */
130 #endif
131 	CHANNEL_TYPE 	*rerefCHANNEL;
132 
133 	/* Patient specific information */
134 	struct {
135 		gdf_time 	Birthday; 	/* Birthday of Patient */
136 		// 		Age;		/* the age is HDR.T0 - HDR.Patient.Birthday, even if T0 and Birthday are not known */
137 		uint16_t	Headsize[3]; 	/* circumference, nasion-inion, left-right mastoid in millimeter;  */
138 		char		Name[MAX_LENGTH_NAME+1]; /* because for privacy protection it is by default not supported, support is turned on with FLAG.ANONYMOUS */
139 //		char*		Name;	/* because for privacy protection it is by default not supported, support is turned on with FLAG.ANONYMOUS */
140 		char		Id[MAX_LENGTH_PID+1];	/* patient identification, identification code as used in hospital  */
141 		uint8_t		Weight;		/* weight in kilograms [kg] 0:unkown, 255: overflow  */
142 		uint8_t		Height;		/* height in centimeter [cm] 0:unkown, 255: overflow  */
143 		//		BMI;		/* the body-mass index = weight[kg]/height[m]^2 */
144 		/* Patient classification */
145 		int	 	Sex;		/* 0:Unknown, 1: Male, 2: Female  */
146 		int		Handedness;	/* 0:Unknown, 1: Right, 2: Left, 3: Equal */
147 		int		Smoking;	/* 0:Unknown, 1: NO, 2: YES */
148 		int		AlcoholAbuse;	/* 0:Unknown, 1: NO, 2: YES */
149 		int		DrugAbuse;	/* 0:Unknown, 1: NO, 2: YES */
150 		int		Medication;	/* 0:Unknown, 1: NO, 2: YES */
151 		struct {
152 			int 	Visual;		/* 0:Unknown, 1: NO, 2: YES, 3: Corrected */
153 			int 	Heart;		/* 0:Unknown, 1: NO, 2: YES, 3: Pacemaker */
154 		} Impairment;
155 	} Patient;
156 
157 	struct {
158 		char		Recording[MAX_LENGTH_RID+1]; 	/* HL7, EDF, GDF, BDF replaces HDR.AS.RID */
159 		char* 		Technician;
160 		char* 		Hospital;
161 		uint64_t 	Equipment; 	/* identifies this software */
162 		struct {
163 			/* see
164 				SCP: section1, tag14,
165 				MFER: tag23:  "Manufacturer^model^version number^serial number"
166 				GDF: tag3:  "Manufacturer\0model\0version\0number\0serial number\0"
167 			*/
168 //			char	_field[MAX_LENGTH_MANUF+1];	/* buffer */
169 			char*	Name;
170 			char*	Model;
171 			char*	Version;
172 			char*	SerialNumber;
173 		} Manufacturer;
174 	} ID;
175 
176 	/* position of electrodes; see also HDR.CHANNEL[k].XYZ */
177 	struct {
178 		float		REF[3];	/* XYZ position of reference electrode */
179 		float		GND[3];	/* XYZ position of ground electrode */
180 	} ELEC;
181 
182 	/*	EVENTTABLE */
183 	struct {
184 		double  	SampleRate;	/* for converting POS and DUR into seconds  */
185 		uint16_t 	*TYP;	/* defined at ../biosig4matlab/doc/eventcodes.txt */
186 		uint32_t 	*POS;	/* starting position [in samples] */
187 		uint32_t 	*DUR;	/* duration [in samples] */
188 		uint16_t 	*CHN;	/* channel number; 0: all channels  */
189 #if (BIOSIG_VERSION >= 10500)
190 		gdf_time        *TimeStamp ATT_ALI;  /* store time stamps */
191 #endif
192 		char		**CodeDesc;	/* describtion of "free text"/"user specific" events (encoded with TYP=0..255 */
193 		uint32_t  	N;	/* number of events */
194 		uint16_t	LenCodeDesc;	/* length of CodeDesc Table */
195 	} EVENT;
196 
197 	struct {	/* flags */
198 		char		OVERFLOWDETECTION; 	/* overflow & saturation detection 0: OFF, !=0 ON */
199 		char		UCAL; 		/* UnCalibration  0: scaling  !=0: NO scaling - raw data return  */
200 		char		ANONYMOUS; 	/* 1: anonymous mode, no personal names are processed */
201 		char		ROW_BASED_CHANNELS;	/* 0: column-based data [default]; 1: row-based data */
202 		char		TARGETSEGMENT; /* in multi-segment files (like Nihon-Khoden, EEG1100), it is used to select a segment */
203 	} FLAG;
204 
205 	CHANNEL_TYPE *CHANNEL;
206 
207 	struct {	/* File specific data  */
208 #ifdef ZLIB_H
209 		gzFile		gzFID;
210 #endif
211 #ifdef _BZLIB_H
212 //		BZFILE*		bzFID;
213 #endif
214 		FILE* 		FID;		/* file handle  */
215 		size_t 		POS;		/* current reading/writing position [in blocks] */
216 //		int		Des;		/* file descriptor */
217 		uint8_t		OPEN; 		/* 0: closed, 1:read, 2: write */
218 		uint8_t		LittleEndian;
219 		uint8_t		COMPRESSION;   /* 0: no compression 9: best compression */
220 //		int		DES;		/* descriptor for streams */
221 	} FILE;
222 
223 	/*	internal variables (not public)  */
224 	struct {
225 		const char*	B4C_ERRMSG;	/* error message */
226 //		char 		PID[MAX_LENGTH_PID+1];	/* use HDR.Patient.Id instead */
227 //		char* 		RID;		/* recording identification */
228 //		uint32_t 	spb;		/* total samples per block */
229 //		uint32_t 	bpb;  		/* total bytes per block */
230 //		uint32_t 	bpb8;  		/* total bits per block */
231 		uint8_t*	Header;
232 //		uint8_t*	rawEventData;
233 //		uint8_t*	rawdata; 	/* raw data block */
234 //		char		flag_collapsed_rawdata; /*0 if rawdata contain obsolete channels, too. 	*/
235 //		nrec_t		first;		/* first block loaded in buffer - this is equivalent to hdr->FILE.POS */
236 //		nrec_t		length;		/* number of block(s) loaded in buffer */
237 		uint8_t*	auxBUF;		/* auxillary buffer - used for storing EVENT.CodeDesc, MIT FMT infor */
238 		char*		bci2000;
239 //		uint32_t	SegSel[5];	/* segment selection in a hirachical data formats, e.g. sweeps in HEKA/PatchMaster format */
240 		enum B4C_ERROR	B4C_ERRNUM;	/* error code */
241 //		char		flag_collapsed_rawdata; /* 0 if rawdata contain obsolete channels, too. 	*/
242 	} AS;
243 
244 	void *aECG;
245 
246 } HDRTYPE;
247 
248 HDRTYPE* constructHDR(const unsigned NS, const unsigned N_EVENT);
249 void 	 destructHDR(HDRTYPE* hdr);
250 HDRTYPE* sopen(const char* FileName, const char* MODE, HDRTYPE* hdr);
251 int 	sclose(HDRTYPE* hdr);
252 size_t	sread(biosig_data_type* data, size_t start, size_t length, HDRTYPE* hdr);
253 size_t  swrite(const biosig_data_type *data, size_t nelem, HDRTYPE* hdr);
254 int	seof(HDRTYPE* hdr);
255 void	srewind(HDRTYPE* hdr);
256 int 	sseek(HDRTYPE* hdr, long int offset, int whence);
257 long int stell(HDRTYPE* hdr);
258 int 	serror2(HDRTYPE* hdr);
259 int	hdr2ascii(HDRTYPE* hdr, FILE *fid, int verbosity);
260 
261 int RerefCHANNEL(HDRTYPE *hdr, void *ReRef, char rrtype);
262 const char* GetFileTypeString(enum FileFormat FMT);
263 
264 uint16_t PhysDimCode(char* PhysDim0);
265 char* 	PhysDim3(uint16_t PhysDimCode);
266 
267 int fprintf_hdr2json(FILE *stream, HDRTYPE* hdr);
268 int asprintf_hdr2json(char **str, HDRTYPE* hdr);
269 
270 
271 int printf_hdr2json(HDRTYPE* hdr);
272 %{
printf_hdr2json(HDRTYPE * hdr)273 	int printf_hdr2json(HDRTYPE* hdr) {
274 		return ( fprintf_hdr2json(stdout, hdr) );
275 	};
276 %}
277 
278 char *display_header(const char *filename);
279 %{
display_header(const char * filename)280 	int display_header(const char *filename) {
281 		HDRTYPE *hdr = sopen(filename,"r",NULL);
282 		if (serror()) return NULL;
283 
284 		char *str = NULL;
285 		asprintf_hdr2json(&str, hdr);
286 		destructHDR(hdr);
287 		return str;
288 	};
289 %}
290 
291 
292 /*
293 HDRTYPE* sopen(char *filename);
294 %{
295 	HDRTYPE* sopen(char *filename)
296 	{
297 		HDRTYPE *hdr = constructHDR(0,0);
298 		hdr = sopen(filename, "r", hdr);
299 		return hdr;
300         }
301 %}
302 
303 int sclose(HDRTYPE *hdr);
304 %{
305 	int sclose(HDRTYPE *hdr)
306 	{
307 		sclose(hdr);
308 		destructHDR(hdr);
309 		return 0;
310         }
311 %}
312 
313 void serror();
314 %{
315 	void _serror() {
316 		fprintf(stderr,"Use of SERROR is deprecated - use serror2(HDR) instead");
317 		serror();
318 	}
319 %}
320 
321 void hdr2ascii(HDRTYPE* hdr, int verbosity);
322 %{
323 	void hdr2ascii(HDRTYPE* hdr, int verbosity)
324 	{
325 		hdr2ascii(hdr, stdout, verbosity);
326         }
327 %}
328 
329 */
330 
331