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