34 #define GEN_SIZE_OFFSET 35 #include "compressRecord.h" 36 #undef GEN_SIZE_OFFSET 39 #define indexof(field) compressRecord##field 43 #define initialize NULL 45 static long process(
struct dbCommon *);
46 static long special(DBADDR *,
int);
47 #define get_value NULL 53 #define get_enum_str NULL 54 #define get_enum_strs NULL 55 #define put_enum_str NULL 58 #define get_alarm_double NULL 83 static void reset(compressRecord *
prec)
91 if (prec->alg == compressALG_Average && prec->sptr ==
NULL) {
92 prec->sptr = calloc(prec->nsam,
sizeof(
double));
95 if (prec->bptr && prec->nsam)
96 memset(prec->bptr, 0, prec->nsam *
sizeof(
double));
99 static void monitor(compressRecord *
prec)
101 unsigned short alarm_mask = recGblResetAlarms(prec);
104 if (alarm_mask || prec->nuse != prec->ouse) {
105 db_post_events(prec, &prec->nuse, monitor_mask);
106 prec->ouse = prec->nuse;
108 db_post_events(prec, prec->bptr, monitor_mask);
111 static void put_value(compressRecord *
prec,
double *psource,
int n)
113 int fifo = (
prec->balg == bufferingALG_FIFO);
125 offset = (offset + nsam - 1) % nsam;
127 prec->bptr[offset] = *psource++;
131 offset = (offset + 1) % nsam;
140 static int compare(
const void *arg1,
const void *arg2)
142 double a = *(
double *)arg1;
143 double b = *(
double *)arg2;
145 if ( a < b )
return -1;
146 else if ( a == b )
return 0;
150 static int compress_array(compressRecord *
prec,
151 double *psource,
int no_elements)
160 while (((*psource < prec->ilil) || (*psource >
prec->ihil))
161 && (no_elements > 0)) {
173 if (no_elements < nsam * n)
174 nnew = (no_elements / n);
179 case compressALG_N_to_1_Low_Value:
181 for (i = 0; i < nnew; i++) {
183 for (j = 1; j < n; j++, psource++) {
184 if (value > *psource)
187 put_value(
prec, &value, 1);
190 case compressALG_N_to_1_High_Value:
192 for (i = 0; i < nnew; i++){
194 for (j = 1; j < n; j++, psource++) {
195 if (value < *psource)
198 put_value(
prec, &value, 1);
201 case compressALG_N_to_1_Average:
203 for (i = 0; i < nnew; i++) {
205 for (j = 0; j < n; j++, psource++)
208 put_value(
prec, &value, 1);
212 case compressALG_N_to_1_Median:
215 for (i = 0; i < nnew; i++, psource += nnew) {
216 qsort(psource, n,
sizeof(
double), compare);
217 value = psource[n / 2];
218 put_value(
prec, &value, 1);
225 static int array_average(compressRecord *
prec,
237 if (nuse > no_elements)
240 if (nnow > no_elements)
242 psum = (
double *)
prec->sptr;
246 for (i = 0; i < nnow; i++)
247 *psum++ = *psource++;
248 for (i = nnow; i < nuse; i++)
251 for (i = 0; i < nnow; i++)
252 *psum++ += *psource++;
265 psum = (
double *)
prec->sptr;
266 multiplier = 1.0 / n;
267 for (i = 0; i < nuse; i++, psum++)
268 *psum = *psum * multiplier;
275 static int compress_scalar(
struct compressRecord *
prec,
double *psource)
277 double value = *psource;
278 double *pdest=&
prec->cvb;
283 case (compressALG_N_to_1_Low_Value):
284 if ((value < *pdest) || (inx == 0))
287 case (compressALG_N_to_1_High_Value):
288 if ((value > *pdest) || (inx == 0))
292 case (compressALG_N_to_1_Average):
293 case (compressALG_N_to_1_Median):
298 if (inx + 1 >=
prec->n)
299 *pdest = *pdest / (inx + 1);
304 if (inx >=
prec->n) {
305 put_value(
prec,pdest,1);
315 static long init_record(
struct dbCommon *pcommon,
int pass)
317 struct compressRecord *
prec = (
struct compressRecord *)pcommon;
321 prec->bptr = calloc(prec->nsam,
sizeof(
double));
328 static long process(
struct dbCommon *pcommon)
330 struct compressRecord *
prec = (
struct compressRecord *)pcommon;
336 if (!dbIsLinkConnected(&prec->inp) ||
337 dbGetNelements(&prec->inp, &nelements) ||
342 if (!prec->wptr || nelements != prec->inpn) {
347 prec->wptr =
dbCalloc(nelements,
sizeof(
double));
348 prec->inpn = nelements;
350 status = dbGetLink(&prec->inp,
DBF_DOUBLE, prec->wptr, 0, &nelements);
351 if (status || nelements <= 0) {
355 else if (alg == compressALG_Average) {
356 status = array_average(prec, prec->wptr, nelements);
358 else if (alg == compressALG_Circular_Buffer) {
359 put_value(prec, prec->wptr, nelements);
362 else if (nelements > 1) {
363 status = compress_array(prec, prec->wptr, nelements);
365 else if (nelements == 1){
366 status = compress_scalar(prec, prec->wptr);
375 recGblGetTimeStamp(prec);
385 static long special(DBADDR *paddr,
int after)
387 compressRecord *
prec = (compressRecord *) paddr->precord;
388 int special_type = paddr->special;
398 recGblDbaddrError(S_db_badChoice, paddr,
"compress: special");
399 return S_db_badChoice;
404 compressRecord *
prec = (compressRecord *) paddr->precord;
406 paddr->pfield = prec->bptr;
407 paddr->no_elements = prec->nsam;
409 paddr->field_size =
sizeof(
double);
412 if (prec->balg == bufferingALG_LIFO)
417 static long get_array_info(DBADDR *paddr,
long *no_elements,
long *offset)
424 compressRecord *
prec = (compressRecord *) paddr->precord;
428 if (prec->balg == bufferingALG_FIFO) {
431 off = (off + nsam - nuse) % nsam;
441 compressRecord *
prec = (compressRecord *) paddr->precord;
444 if (prec->balg == bufferingALG_FIFO)
445 prec->off = (prec->off + nNew) % prec->nsam;
447 if (prec->nuse > prec->nsam)
448 prec->nuse = prec->nsam;
450 if (nuse != prec->nuse)
455 static long get_units(DBADDR *paddr,
char *units)
457 compressRecord *
prec = (compressRecord *) paddr->precord;
460 dbGetFieldIndex(paddr) ==
indexof(VAL)) {
461 strncpy(units, prec->egu, DB_UNITS_SIZE);
466 static long get_precision(
const DBADDR *paddr,
long *precision)
468 compressRecord *
prec = (compressRecord *) paddr->precord;
470 *precision = prec->prec;
471 if (dbGetFieldIndex(paddr) !=
indexof(VAL))
472 recGblGetPrec(paddr,precision);
478 compressRecord *
prec = (compressRecord *) paddr->precord;
480 switch (dbGetFieldIndex(paddr)) {
484 pgd->upper_disp_limit = prec->hopr;
485 pgd->lower_disp_limit = prec->lopr;
488 recGblGetGraphicDouble(paddr,pgd);
495 compressRecord *
prec = (compressRecord *) paddr->precord;
497 switch (dbGetFieldIndex(paddr)) {
501 pcd->upper_ctrl_limit = prec->hopr;
502 pcd->lower_ctrl_limit = prec->lopr;
505 recGblGetControlDouble(paddr, pcd);
Miscellaneous macro definitions.
#define get_control_double
#define dbCalloc(nobj, size)
epicsExportAddress(rset, compressRSET)
#define get_graphic_double