1 /*
2     Copyright (C) 2010-2019 Alois Schloegl <alois.schloegl@ist.ac.at>
3     This file is part of the "BioSig for C/C++" repository
4     (biosig4c++) at https://biosig.sourceforge.io
5 
6 
7     This program is free software; you can redistribute it and/or
8     modify it under the terms of the GNU General Public License
9     as published by the Free Software Foundation; either version 3
10     of the License, or (at your option) any later version.
11 
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.
16 
17     You should have received a copy of the GNU General Public License
18     along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 
20  */
21 
22 #include <stdlib.h>
23 #include "mathlink.h"
24 #include <biosig.h>
25 
26 #ifdef NDEBUG
27 #define VERBOSE_LEVEL 0 	// turn off debugging information, but its only used without NDEBUG
28 #else
29 extern int VERBOSE_LEVEL; 	// used for debugging, variable is always defined
30 #endif
31 
sload(const char * fn,int * SZ,long SZlen)32 void sload(const char *fn, int *SZ, long SZlen) {
33 
34 	uint16_t numberChannels;
35 	size_t k=0;
36 	size_t numberSamples;
37 	double samplerate;
38 	double *t;
39 	char *str = NULL;
40 	long int sz[2];
41 	biosig_data_type *data=NULL;
42 #ifdef __LIBBIOSIG2_H__
43 	size_t rowcol[2];
44 #endif
45 
46 	HDRTYPE *hdr = constructHDR(0,0);
47 
48 if (VERBOSE_LEVEL > 5)
49 	fprintf(stdout,"=== start sload ===\n");
50 
51 /* contains [experiment,series,sweep,trace] numbers for selecting data. */
52 
53 	while ((k < SZlen) && (k < 5)) {
54 #ifdef __LIBBIOSIG2_H__
55 		biosig_set_segment_selection(hdr, k+1, SZ[k]);
56 #else
57 		hdr->AS.SegSel[k] = (uint32_t)SZ[k];
58 #endif
59 		k++;
60 	}
61 
62 	// ********* open file and read header ************
63 	hdr = sopen(fn, "r", hdr);
64 	if (serror2(hdr)) {
65 		destructHDR(hdr);
66 		MLEvaluate(stdlink,"Message[sload::failed]");
67 		MLNextPacket(stdlink);
68 		MLNewPacket(stdlink);
69 		MLPutSymbol(stdlink,"$Failed");
70 		return;
71 	}
72 
73 #ifdef __LIBBIOSIG2_H__
74 	numberChannels = biosig_get_number_of_channels(hdr);
75 	numberSamples = biosig_get_number_of_samples(hdr);
76 	samplerate = biosig_get_samplerate(hdr);
77 	biosig_reset_flag(hdr, BIOSIG_FLAG_ROW_BASED_CHANNELS);
78 #else
79 	numberChannels = hdr->NS;
80 	numberSamples = hdr->NRec * hdr->SPR;
81 	samplerate = hdr->SampleRate;
82 	hdr->FLAG.ROW_BASED_CHANNELS = 0;
83 #endif
84 
85 if (VERBOSE_LEVEL > 5)
86 	fprintf(stdout,"open filename <%s>NoOfChans=%i\n", fn, numberChannels);
87 
88 	// ********** read data ********************
89 	sread(NULL, 0, numberSamples, hdr);
90 	if (serror2(hdr)) {
91 		destructHDR(hdr);
92 		MLEvaluate(stdlink,"Message[sload::failed]");
93 		MLNextPacket(stdlink);
94 		MLNewPacket(stdlink);
95 		MLPutSymbol(stdlink,"$Failed");
96 		return;
97 	}
98 
99 #ifdef __LIBBIOSIG2_H__
100 	biosig_get_datablock(hdr, &data, &rowcol[0], &rowcol[1]);
101 	sz[0] = rowcol[1];
102 	sz[1] = rowcol[0];
103 #else
104 	sz[0] = hdr->data.size[1];
105 	sz[1] = hdr->data.size[0];
106 	data  = hdr->data.block;
107 #endif
108 
109 	MLPutFunction(stdlink, "List", 3);
110 	// write data matrix
111 	MLPutRealArray(stdlink, data, sz, NULL, 2);
112 
113 	// generate and write time axis
114 	t = (double*)malloc(numberSamples * sizeof(double));
115 	for (k=0; k < numberSamples;k++) {
116 		t[k] = (k+1)/samplerate;
117 	}
118 	MLPutRealList(stdlink, t, numberSamples);
119 	free(t);
120 
121 	// generate and write header information in JSON format
122 	asprintf_hdr2json(&str, hdr);
123 	MLPutFunction(stdlink,"ImportString",2);
124 	  MLPutUTF8String(stdlink,str,strlen(str));
125 	  MLPutString(stdlink,"JSON");
126 	free(str);
127 
128 	if (VERBOSE_LEVEL > 5) {
129 		for (k=0; k<numberChannels; k++)
130 			fprintf(stdout,"%f ",data[k]);
131 		fprintf(stdout,"\n\nopen filename <%s>@%p sz=[%zd,%zd]\n", fn, data, sz[1],sz[0]);
132 	}
133 
134 	// *********** close file *********************
135 	destructHDR(hdr);
136 	return;
137 }
138 
139 
uload(const char * fn,int * SZ,long SZlen)140 void uload(const char *fn, int *SZ, long SZlen) {
141 
142 	uint16_t numberChannels;
143 	size_t k=0;
144 	size_t numberSamples;
145 	double samplerate;
146 	double *t;
147 	char *str = NULL;
148 	long int sz[2];
149 	biosig_data_type *data=NULL;
150 #ifdef __LIBBIOSIG2_H__
151 	size_t rowcol[2];
152 #endif
153 
154 	HDRTYPE *hdr = constructHDR(0,0);
155 
156 if (VERBOSE_LEVEL > 5)
157 	fprintf(stdout,"=== start uload ===\n");
158 
159 /* contains [experiment,series,sweep,trace] numbers for selecting data. */
160 
161 	while ((k < SZlen) && (k < 5)) {
162 #ifdef __LIBBIOSIG2_H__
163 		biosig_set_segment_selection(hdr, k+1, SZ[k]);
164 #else
165 		hdr->AS.SegSel[k] = (uint32_t)SZ[k];
166 #endif
167 		k++;
168 	}
169 
170 	// ********* open file and read header ************
171 	hdr = sopen(fn, "r", hdr);
172 	if (serror2(hdr)) {
173 		destructHDR(hdr);
174 		MLEvaluate(stdlink,"Message[uload::failed]");
175 		MLNextPacket(stdlink);
176 		MLNewPacket(stdlink);
177 		MLPutSymbol(stdlink,"$Failed");
178 		return;
179 	}
180 
181 	// do NOT apply calibration/scaling factor
182 	biosig_set_flag(hdr, BIOSIG_FLAG_UCAL);
183 
184 #ifdef __LIBBIOSIG2_H__
185 	numberChannels = biosig_get_number_of_channels(hdr);
186 	numberSamples = biosig_get_number_of_samples(hdr);
187 	samplerate = biosig_get_samplerate(hdr);
188 	biosig_reset_flag(hdr, BIOSIG_FLAG_ROW_BASED_CHANNELS);
189 #else
190 	numberChannels = hdr->NS;
191 	numberSamples = hdr->NRec * hdr->SPR;
192 	samplerate = hdr->SampleRate;
193 	hdr->FLAG.ROW_BASED_CHANNELS = 0;
194 #endif
195 
196 if (VERBOSE_LEVEL > 5)
197 	fprintf(stdout,"open filename <%s>NoOfChans=%i\n", fn, numberChannels);
198 
199 	// ********** read data ********************
200 	sread(NULL, 0, numberSamples, hdr);
201 	if (serror2(hdr)) {
202 		destructHDR(hdr);
203 		MLEvaluate(stdlink,"Message[uload::failed]");
204 		MLNextPacket(stdlink);
205 		MLNewPacket(stdlink);
206 		MLPutSymbol(stdlink,"$Failed");
207 		return;
208 	}
209 
210 #ifdef __LIBBIOSIG2_H__
211 	biosig_get_datablock(hdr, &data, &rowcol[0], &rowcol[1]);
212 	sz[0] = rowcol[1];
213 	sz[1] = rowcol[0];
214 #else
215 	sz[0] = hdr->data.size[1];
216 	sz[1] = hdr->data.size[0];
217 	data  = hdr->data.block;
218 #endif
219 
220 	MLPutFunction(stdlink, "List", 3);
221 	// write data matrix
222 	MLPutRealArray(stdlink, data, sz, NULL, 2);
223 
224 	// generate and write time axis
225 	t = (double*)malloc(numberSamples * sizeof(double));
226 	for (k=0; k < numberSamples;k++) {
227 		t[k] = (k+1)/samplerate;
228 	}
229 	MLPutRealList(stdlink, t, numberSamples);
230 	free(t);
231 
232 	// generate and write header information in JSON format
233 	asprintf_hdr2json(&str, hdr);
234 	MLPutFunction(stdlink,"ImportString",2);
235 	  MLPutUTF8String(stdlink,str,strlen(str));
236 	  MLPutString(stdlink,"JSON");
237 	free(str);
238 
239 	if (VERBOSE_LEVEL > 5) {
240 		for (k=0; k<numberChannels; k++)
241 			fprintf(stdout,"%f ",data[k]);
242 		fprintf(stdout,"\n\nopen filename <%s>@%p sz=[%zd,%zd]\n", fn, data, sz[1],sz[0]);
243 	}
244 
245 	// *********** close file *********************
246 	destructHDR(hdr);
247 	return;
248 }
249 
250 
main(int argc,char * argv[])251 int main(int argc, char *argv[]) {
252    return MLMain(argc, argv);
253 }
254 
255