diff --git a/Makefile b/Makefile index 0639f92..6990d58 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,9 @@ INCLUDES=-I. -CFLAGS= -O3 $(INCLUDES) +CFLAGS= -O3 -Wall $(INCLUDES) -OBJS= main.o image.o dsp.o filter.o reg.o fcolor.o dres.o +OBJS= main.o image.o dsp.o filter.o reg.o fcolor.o atpdec: $(OBJS) $(CC) -o $@ $(OBJS) -lm -lsndfile -lpng diff --git a/dres.c b/dres.c deleted file mode 100644 index d1d8780..0000000 --- a/dres.c +++ /dev/null @@ -1,36 +0,0 @@ -#include -#include - -float vcoef(float av, float at, float bv, float bt) -{ -float dv,dt; -float f; - -#define K 500 - -dv=av-bv; -dt=at-bt; - -f=dv*dv+dt*dt; - -return (1.0/(1.0+K*f)); -} - -void dres( - float av, float at, float bv, float bt, - float cv, float ct, float dv, float dt, - float *v , float *t) -{ -float wab,wac,wda,wbc,wbd,wcd; - -wab=vcoef(av,at,bv,bt); -wac=vcoef(av,at,cv,ct); -wda=vcoef(dv,dt,av,at); -wbc=vcoef(bv,bt,cv,ct); -wbd=vcoef(bv,bt,dv,dt); -wcd=vcoef(cv,ct,dv,dt); - -*v=(wab*(av+bv)+wac*(av+cv)+wda*(dv+av)+wbc*(bv+cv)+wbd*(bv+dv)+wcd*(cv+dv))/(2.0*(wab+wac+wda+wbc+wbd+wcd)); -*t=(wab*(at+bt)+wac*(at+ct)+wda*(dt+at)+wbc*(bt+ct)+wbd*(bt+dt)+wcd*(ct+dt))/(2.0*(wab+wac+wda+wbc+wbd+wcd)); -} - diff --git a/dsp.c b/dsp.c index 86bc087..c6c3694 100755 --- a/dsp.c +++ b/dsp.c @@ -1,6 +1,6 @@ /* * Atpdec - * Copyright (c) 2003 by Thierry Leconte (F4DWV) + * Copyright (c) 2004 by Thierry Leconte (F4DWV) * * $Id$ * @@ -18,14 +18,15 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - */ + */ +#include #include #ifndef M_PI -#define M_PI 3.14159265358979323846 /* for OS that don't know it */ -#endif /* */ +#define M_PI 3.14159265358979323846 /* for OS that don't know it */ +#endif /* */ #include "filter.h" #include "filtercoeff.h" - + #define Fe 11025.0 #define Fc 2400.0 #define DFc 50.0 @@ -35,161 +36,175 @@ #define Fi (Fp*RSMULT) static double FreqOsc = Fc / Fe; static double FreqLine = 1.0; -extern int getsample (float *inbuff, int nb); -static float -pll (float In) + +extern int getsample(float *inbuff, int nb); + +static float pll(float In) { - -/* pll coeff */ + +/* pll coeff */ #define K1 5e-3 #define K2 3e-6 - static double PhaseOsc = 0.0; - static iirbuff_t Ifilterbuff, Qfilterbuff; - double Io, Qo; - double Ip, Qp; - double DPhi; - double DF; - -/* quadrature oscillator */ - Io = cos (PhaseOsc); - Qo = sin (PhaseOsc); - -/* phase detector */ - Ip = iir (In * Io, &Ifilterbuff, &PhaseFilterCf); - Qp = iir (In * Qo, &Qfilterbuff, &PhaseFilterCf); - DPhi = -atan2 (Qp, Ip) / M_PI; - -/* loop filter */ + static double PhaseOsc = 0.0; + static iirbuff_t Ifilterbuff, Qfilterbuff; + double Io, Qo; + double Ip, Qp; + double DPhi; + double DF; + +/* quadrature oscillator */ + Io = cos(PhaseOsc); + Qo = sin(PhaseOsc); + +/* phase detector */ + Ip = iir(In * Io, &Ifilterbuff, &PhaseFilterCf); + Qp = iir(In * Qo, &Qfilterbuff, &PhaseFilterCf); + DPhi = -atan2(Qp, Ip) / M_PI; + +/* loop filter */ DF = K1 * DPhi + FreqOsc; - FreqOsc += K2 * DPhi; - if (FreqOsc > ((Fc + DFc) / Fe)) - FreqOsc = (Fc + DFc) / Fe; - if (FreqOsc < ((Fc - DFc) / Fe)) - FreqOsc = (Fc - DFc) / Fe; - PhaseOsc += 2.0 * M_PI * DF; - if (PhaseOsc > M_PI) - PhaseOsc -= 2.0 * M_PI; - if (PhaseOsc <= -M_PI) - PhaseOsc += 2.0 * M_PI; - return (float) (In * Io); -} static double fr = Fc / Fe; + FreqOsc += K2 * DPhi; + if (FreqOsc > ((Fc + DFc) / Fe)) + FreqOsc = (Fc + DFc) / Fe; + if (FreqOsc < ((Fc - DFc) / Fe)) + FreqOsc = (Fc - DFc) / Fe; + PhaseOsc += 2.0 * M_PI * DF; + if (PhaseOsc > M_PI) + PhaseOsc -= 2.0 * M_PI; + if (PhaseOsc <= -M_PI) + PhaseOsc += 2.0 * M_PI; + return (float) (In * Io); +} + +static double fr = Fc / Fe; static double offset = 0.0; -getamp (float *ambuff, int nb) + +int getamp(float *ambuff, int nb) { - + #define BLKIN 1024 - float inbuff[BLKIN]; - int n; - int res; - res = getsample (inbuff, nb > BLKIN ? BLKIN : nb); - for (n = 0; n < res; n++) { - ambuff[n] = pll (inbuff[n]); - fr = 0.25 * FreqOsc + 0.75 * fr; - } - return (res); + float inbuff[BLKIN]; + int n; + int res; + + res = getsample(inbuff, nb > BLKIN ? BLKIN : nb); + for (n = 0; n < res; n++) { + ambuff[n] = pll(inbuff[n]); + fr = 0.25 * FreqOsc + 0.75 * fr; + } + return (res); } -int -getpixelv (float *pvbuff, int nb) + +int getpixelv(float *pvbuff, int nb) { - + #define BLKAMP 256 - static float ambuff[BLKAMP]; - static int nam = 0; - static int idxam = 0; - int n; - for (n = 0; n < nb; n++) { - double mult; - int shift; - if (nam < BLKAMP) { - int res; - memmove (ambuff, &(ambuff[idxam]), nam * sizeof (float)); - idxam = 0; - res = getamp (&(ambuff[nam]), BLKAMP - nam); - nam += res; - if (nam < BLKAMP) - return (n); + static float ambuff[BLKAMP]; + static int nam = 0; + static int idxam = 0; + int n; + + for (n = 0; n < nb; n++) { + double mult; + int shift; + + if (nam < BLKAMP) { + int res; + memmove(ambuff, &(ambuff[idxam]), nam * sizeof(float)); + idxam = 0; + res = getamp(&(ambuff[nam]), BLKAMP - nam); + nam += res; + if (nam < BLKAMP) + return (n); + } + + mult = (double) Fi *fr / Fc * FreqLine; + + pvbuff[n] = + rsfir(&(ambuff[idxam]), rsfilter, RSFilterLen, offset, + mult) * mult * 2 * 256.0; + + shift = (int) ((RSMULT - offset + mult - 1) / mult); + offset = shift * mult + offset - RSMULT; + idxam += shift; + nam -= shift; } - mult = (double) Fi *fr / Fc * FreqLine; - pvbuff[n] = - rsfir (&(ambuff[idxam]), rsfilter, RSFilterLen, offset, - mult) * mult * 2 * 256.0; - shift = (int) ((RSMULT - offset + mult - 1) / mult); - offset = shift * mult + offset - RSMULT; - idxam += shift; - nam -= shift; - } return (nb); + return (nb); } -int -getpixelrow (float *pixelv) + +int getpixelrow(float *pixelv) { - static float pixels[PixelLine + SyncFilterLen]; - static int npv = 0; - static int synced = 0; - static double max = 0.0; - double corr, ecorr, lcorr; - double ph; - int n, res; - if (npv > 0) - memmove (pixelv, pixels, npv * sizeof (float)); - if (npv < SyncFilterLen + 2) { - res = getpixelv (&(pixelv[npv]), SyncFilterLen + 2 - npv); - npv += res; - if (npv < SyncFilterLen + 2) - return (0); - } - - /* test sync */ - corr = fir (&(pixelv[1]), Sync, SyncFilterLen); - ecorr = fir (pixelv, Sync, SyncFilterLen); - lcorr = fir (&(pixelv[2]), Sync, SyncFilterLen); - FreqLine = 1.0 + (ecorr - lcorr) / corr / PixelLine / 4.0; - if (corr < 0.75 * max) { - synced = 0; - FreqLine = 1.0; - } - max = corr; - if (synced < 8) { - int shift, mshift; - if (npv < PixelLine + SyncFilterLen) { - res = getpixelv (&(pixelv[npv]), PixelLine + SyncFilterLen - npv); - npv += res; - if (npv < PixelLine + SyncFilterLen) - return (0); - } - - /* lookup sync start */ - mshift = 0; - for (shift = 1; shift < PixelLine; shift++) { - double corr; - corr = fir (&(pixelv[shift + 1]), Sync, SyncFilterLen); - if (corr > max) { - mshift = shift; - max = corr; - } + static float pixels[PixelLine + SyncFilterLen]; + static int npv = 0; + static int synced = 0; + static double max = 0.0; + + double corr, ecorr, lcorr; + int res; + + if (npv > 0) + memmove(pixelv, pixels, npv * sizeof(float)); + if (npv < SyncFilterLen + 2) { + res = getpixelv(&(pixelv[npv]), SyncFilterLen + 2 - npv); + npv += res; + if (npv < SyncFilterLen + 2) + return (0); } - if (mshift != 0) { - memmove (pixelv, &(pixelv[mshift]), (npv - mshift) * sizeof (float)); - npv -= mshift; - synced = 0; - FreqLine = 1.0; + + /* test sync */ + corr = fir(&(pixelv[1]), Sync, SyncFilterLen); + ecorr = fir(pixelv, Sync, SyncFilterLen); + lcorr = fir(&(pixelv[2]), Sync, SyncFilterLen); + FreqLine = 1.0 + (ecorr - lcorr) / corr / PixelLine / 4.0; + if (corr < 0.75 * max) { + synced = 0; + FreqLine = 1.0; } - else - synced += 1; - } - if (npv < PixelLine) { - res = getpixelv (&(pixelv[npv]), PixelLine - npv); - npv += res; - if (npv < PixelLine) - return (0); - } - if (npv == PixelLine) { - npv = 0; - } - else { - memmove (pixels, &(pixelv[PixelLine]), - (npv - PixelLine) * sizeof (float)); - npv -= PixelLine; - } return (1); -} + max = corr; + if (synced < 8) { + int shift, mshift; + + if (npv < PixelLine + SyncFilterLen) { + res = + getpixelv(&(pixelv[npv]), PixelLine + SyncFilterLen - npv); + npv += res; + if (npv < PixelLine + SyncFilterLen) + return (0); + } + + /* lookup sync start */ + mshift = 0; + for (shift = 1; shift < PixelLine; shift++) { + double corr; + corr = fir(&(pixelv[shift + 1]), Sync, SyncFilterLen); + if (corr > max) { + mshift = shift; + max = corr; + } + } + if (mshift != 0) { + memmove(pixelv, &(pixelv[mshift]), + (npv - mshift) * sizeof(float)); + npv -= mshift; + synced = 0; + FreqLine = 1.0; + } else + synced += 1; + } + if (npv < PixelLine) { + res = getpixelv(&(pixelv[npv]), PixelLine - npv); + npv += res; + if (npv < PixelLine) + return (0); + } + if (npv == PixelLine) { + npv = 0; + } else { + memmove(pixels, &(pixelv[PixelLine]), + (npv - PixelLine) * sizeof(float)); + npv -= PixelLine; + } + return (1); +} diff --git a/fcolor.c b/fcolor.c index 786b9f9..40af7cd 100644 --- a/fcolor.c +++ b/fcolor.c @@ -2,146 +2,140 @@ #include -typedef struct -{ - float h, s, v; +typedef struct { + float h, s, v; } hsvpix_t; -static void -HSVtoRGB (float *r, float *g, float *b, hsvpix_t pix) +static void HSVtoRGB(float *r, float *g, float *b, hsvpix_t pix) { - int i; - double f, p, q, t, h; - - if (pix.s == 0) { - // achromatic (grey) - *r = *g = *b = pix.v; - return; - } - - h = pix.h / 60; // sector 0 to 5 - i = floor (h); - f = h - i; // factorial part of h - p = pix.v * (1 - pix.s); - q = pix.v * (1 - pix.s * f); - t = pix.v * (1 - pix.s * (1 - f)); - - switch (i) { - case 0: - *r = pix.v; - *g = t; - *b = p; - break; - case 1: - *r = q; - *g = pix.v; - *b = p; - break; - case 2: - *r = p; - *g = pix.v; - *b = t; - break; - case 3: - *r = p; - *g = q; - *b = pix.v; - break; - case 4: - *r = t; - *g = p; - *b = pix.v; - break; - default: // case 5: - *r = pix.v; - *g = p; - *b = q; - break; - } + int i; + double f, p, q, t, h; + + if (pix.s == 0) { + // achromatic (grey) + *r = *g = *b = pix.v; + return; + } + + h = pix.h / 60; // sector 0 to 5 + i = floor(h); + f = h - i; // factorial part of h + p = pix.v * (1 - pix.s); + q = pix.v * (1 - pix.s * f); + t = pix.v * (1 - pix.s * (1 - f)); + + switch (i) { + case 0: + *r = pix.v; + *g = t; + *b = p; + break; + case 1: + *r = q; + *g = pix.v; + *b = p; + break; + case 2: + *r = p; + *g = pix.v; + *b = t; + break; + case 3: + *r = p; + *g = q; + *b = pix.v; + break; + case 4: + *r = t; + *g = p; + *b = pix.v; + break; + default: // case 5: + *r = pix.v; + *g = p; + *b = q; + break; + } } -static struct -{ - float Seathresold; - float Landthresold; - float Tthresold; - hsvpix_t CloudTop; - hsvpix_t CloudBot; - hsvpix_t SeaTop; - hsvpix_t SeaBot; - hsvpix_t GroundTop; - hsvpix_t GroundBot; +static struct { + float Seathresold; + float Landthresold; + float Tthresold; + hsvpix_t CloudTop; + hsvpix_t CloudBot; + hsvpix_t SeaTop; + hsvpix_t SeaBot; + hsvpix_t GroundTop; + hsvpix_t GroundBot; } fcinfo = { - 30.0, 90.0, 100.0, { - 230, 0.2, 0.3}, { - 230, 0.0, 1.0}, { - 200.0, 0.7, 0.6}, { - 240.0, 0.6, 0.4}, { - 60.0, 0.6, 0.2}, { - 100.0, 0.0, 0.5} + 30.0, 90.0, 100.0, { + 230, 0.2, 0.3}, { + 230, 0.0, 1.0}, { + 200.0, 0.7, 0.6}, { + 240.0, 0.6, 0.4}, { + 60.0, 0.6, 0.2}, { + 100.0, 0.0, 0.5} }; -void -readfconf (char *file) +void readfconf(char *file) { - FILE *fin; - - fin = fopen (file, "r"); - if (fin == NULL) - return; - - fscanf (fin, "%g\n", &fcinfo.Seathresold); - fscanf (fin, "%g\n", &fcinfo.Landthresold); - fscanf (fin, "%g\n", &fcinfo.Tthresold); - fscanf (fin, "%g %g %g\n", &fcinfo.CloudTop.h, &fcinfo.CloudTop.s, - &fcinfo.CloudTop.v); - fscanf (fin, "%g %g %g\n", &fcinfo.CloudBot.h, &fcinfo.CloudBot.s, - &fcinfo.CloudBot.v); - fscanf (fin, "%g %g %g\n", &fcinfo.SeaTop.h, &fcinfo.SeaTop.s, - &fcinfo.SeaTop.v); - fscanf (fin, "%g %g %g\n", &fcinfo.SeaBot.h, &fcinfo.SeaBot.s, - &fcinfo.SeaBot.v); - fscanf (fin, "%g %g %g\n", &fcinfo.GroundTop.h, &fcinfo.GroundTop.s, - &fcinfo.GroundTop.v); - fscanf (fin, "%g %g %g\n", &fcinfo.GroundBot.h, &fcinfo.GroundBot.s, - &fcinfo.GroundBot.v); - - fclose (fin); + FILE *fin; + + fin = fopen(file, "r"); + if (fin == NULL) + return; + + fscanf(fin, "%g\n", &fcinfo.Seathresold); + fscanf(fin, "%g\n", &fcinfo.Landthresold); + fscanf(fin, "%g\n", &fcinfo.Tthresold); + fscanf(fin, "%g %g %g\n", &fcinfo.CloudTop.h, &fcinfo.CloudTop.s, + &fcinfo.CloudTop.v); + fscanf(fin, "%g %g %g\n", &fcinfo.CloudBot.h, &fcinfo.CloudBot.s, + &fcinfo.CloudBot.v); + fscanf(fin, "%g %g %g\n", &fcinfo.SeaTop.h, &fcinfo.SeaTop.s, + &fcinfo.SeaTop.v); + fscanf(fin, "%g %g %g\n", &fcinfo.SeaBot.h, &fcinfo.SeaBot.s, + &fcinfo.SeaBot.v); + fscanf(fin, "%g %g %g\n", &fcinfo.GroundTop.h, &fcinfo.GroundTop.s, + &fcinfo.GroundTop.v); + fscanf(fin, "%g %g %g\n", &fcinfo.GroundBot.h, &fcinfo.GroundBot.s, + &fcinfo.GroundBot.v); + + fclose(fin); }; -void -falsecolor (double v, double t, float *r, float *g, float *b) +void falsecolor(double v, double t, float *r, float *g, float *b) { - hsvpix_t top, bot, c; - double scv, sct; - - if (t < fcinfo.Tthresold) { - if (v < fcinfo.Seathresold) { - /* sea */ - top = fcinfo.SeaTop, bot = fcinfo.SeaBot; - scv = v / fcinfo.Seathresold; - sct = t / fcinfo.Tthresold; - } - else { - /* ground */ - top = fcinfo.GroundTop, bot = fcinfo.GroundBot; - scv = - (v - fcinfo.Seathresold) / (fcinfo.Landthresold - fcinfo.Seathresold); - sct = t / fcinfo.Tthresold; + hsvpix_t top, bot, c; + double scv, sct; + + if (t < fcinfo.Tthresold) { + if (v < fcinfo.Seathresold) { + /* sea */ + top = fcinfo.SeaTop, bot = fcinfo.SeaBot; + scv = v / fcinfo.Seathresold; + sct = t / fcinfo.Tthresold; + } else { + /* ground */ + top = fcinfo.GroundTop, bot = fcinfo.GroundBot; + scv = + (v - fcinfo.Seathresold) / (fcinfo.Landthresold - + fcinfo.Seathresold); + sct = t / fcinfo.Tthresold; + } + } else { + /* clouds */ + top = fcinfo.CloudTop, bot = fcinfo.CloudBot; + scv = v / 255.0; + sct = t / 255.0; } - } - else { - /* clouds */ - top = fcinfo.CloudTop, bot = fcinfo.CloudBot; - scv = v / 255.0; - sct = t / 255.0; - } - - c.s = top.s + sct * (bot.s - top.s); - c.v = top.v + scv * (bot.v - top.v); - c.h = top.h + scv * sct * (bot.h - top.h); - - HSVtoRGB (r, g, b, c); + + c.s = top.s + sct * (bot.s - top.s); + c.v = top.v + scv * (bot.v - top.v); + c.h = top.h + scv * sct * (bot.h - top.h); + + HSVtoRGB(r, g, b, c); }; diff --git a/filter.c b/filter.c index 4c9cd64..86e79c7 100755 --- a/filter.c +++ b/filter.c @@ -1,82 +1,88 @@ -/* - * Atpdec - * Copyright (c) 2003 by Thierry Leconte (F4DWV) - * - * $Id$ - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ -#include "filter.h" - float -fir (float *buff, const float *coeff, const int len) -{ - int i; - double r; - r = 0.0; - for (i = 0; i < len; i++) { - r += buff[i] * coeff[i]; - } - return r; - } - void -iqfir (float *buff, const float *Icoeff, const float *Qcoeff, const int len, - float *Iptr, float *Qptr) +/* + * Atpdec + * Copyright (c) 2004 by Thierry Leconte (F4DWV) + * + * $Id$ + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ +#include "filter.h" + +float fir(float *buff, const float *coeff, const int len) { - int i; - float I, Q; - I = Q = 0.0; - for (i = 0; i < len; i++) { - double v; - v = buff[i]; - I += v * Icoeff[i]; - Q += v * Qcoeff[i]; - } *Iptr = I; - *Qptr = Q; - } float -rsfir (float *buff, const float *coeff, const int len, const double offset, - const double delta) + int i; + double r; + + r = 0.0; + for (i = 0; i < len; i++) { + r += buff[i] * coeff[i]; + } + return r; +} + +void +iqfir(float *buff, const float *Icoeff, const float *Qcoeff, const int len, + float *Iptr, float *Qptr) { - int i; - double n; - double out; - out = 0.0; - for (i = 0, n = offset; n < len - 1; n += delta, i++) { - int k; - double alpha; - k = (int) n; - alpha = n - k; - out += buff[i] * (coeff[k] * (1.0 - alpha) + coeff[k + 1] * alpha); - } return out; - } - double -iir (double x, iirbuff_t * buff, const iircoeff_t * coeff) + int i; + float I, Q; + + I = Q = 0.0; + for (i = 0; i < len; i++) { + double v; + + v = buff[i]; + I += v * Icoeff[i]; + Q += v * Qcoeff[i]; + } *Iptr = I; + *Qptr = Q; +} + +float +rsfir(float *buff, const float *coeff, const int len, const double offset, + const double delta) { - buff->x[4] = buff->x[3]; - buff->x[3] = buff->x[2]; - buff->x[2] = buff->x[1]; - buff->x[1] = buff->x[0]; - buff->x[0] = x / coeff->G; - buff->y[2] = buff->y[1]; - buff->y[1] = buff->y[0]; - buff->y[0] = buff->x[4] - +coeff->x[2] * buff->x[3] - +coeff->x[1] * buff->x[2] - +coeff->x[0] * buff->x[1] - +buff->x[0] +coeff->y[1] * buff->y[2] +coeff->y[0] * buff->y[1]; - return (buff->y[0]); - } + int i; + double n; + double out; + + out = 0.0; + for (i = 0, n = offset; n < len - 1; n += delta, i++) { + int k; + double alpha; - + k = (int) n; + alpha = n - k; + out += buff[i] * (coeff[k] * (1.0 - alpha) + coeff[k + 1] * alpha); + } return out; +} + +double iir(double x, iirbuff_t * buff, const iircoeff_t * coeff) +{ + buff->x[4] = buff->x[3]; + buff->x[3] = buff->x[2]; + buff->x[2] = buff->x[1]; + buff->x[1] = buff->x[0]; + buff->x[0] = x / coeff->G; + buff->y[2] = buff->y[1]; + buff->y[1] = buff->y[0]; + buff->y[0] = buff->x[4] + + coeff->x[2] * buff->x[3] + + coeff->x[1] * buff->x[2] + + coeff->x[0] * buff->x[1] + + buff->x[0] + coeff->y[1] * buff->y[2] + coeff->y[0] * buff->y[1]; + return (buff->y[0]); +} diff --git a/image.c b/image.c index e41bc75..7854545 100644 --- a/image.c +++ b/image.c @@ -1,6 +1,6 @@ /* * Atpdec - * Copyright (c) 2003 by Thierry Leconte (F4DWV) + * Copyright (c) 2004 by Thierry Leconte (F4DWV) * * $Id$ * @@ -26,307 +26,298 @@ #include #define REGORDER 3 -typedef struct -{ - double cf[REGORDER + 1]; +typedef struct { + double cf[REGORDER + 1]; } rgparam; -static void -rgcomp (double x[16], rgparam * rgpr) +static void rgcomp(double x[16], rgparam * rgpr) { /*{ 0.106,0.215,0.324,0.433,0.542,0.652,0.78,0.87 ,0.0 }; */ - const double y[9] = - { 31.07, 63.02, 94.96, 126.9, 158.86, 191.1, 228.62, 255.0, 0.0 }; - extern void polyreg (const int m, const int n, const double x[], - const double y[], double c[]); + const double y[9] = + { 31.07, 63.02, 94.96, 126.9, 158.86, 191.1, 228.62, 255.0, 0.0 }; + extern void polyreg(const int m, const int n, const double x[], + const double y[], double c[]); - polyreg (REGORDER, 9, x, y, rgpr->cf); + polyreg(REGORDER, 9, x, y, rgpr->cf); } -static double -rgcal (float x, rgparam * rgpr) +static double rgcal(float x, rgparam * rgpr) { - double y, p; - int i; - - for (i = 0, y = 0.0, p = 1.0; i < REGORDER + 1; i++) { - y += rgpr->cf[i] * p; - p = p * x; - } - return (y); + double y, p; + int i; + + for (i = 0, y = 0.0, p = 1.0; i < REGORDER + 1; i++) { + y += rgpr->cf[i] * p; + p = p * x; + } + return (y); } static double tele[16]; static double Cs; -static nbtele; +static int nbtele; -int -Calibrate (float **prow, int nrow, int offset) +int Calibrate(float **prow, int nrow, int offset) { - double teleline[3000]; - double wedge[16]; - rgparam regr[30]; - int n; - int k; - int mtelestart, telestart; - int channel = -1; - float max; + double teleline[3000]; + double wedge[16]; + rgparam regr[30]; + int n; + int k; + int mtelestart, telestart; + int channel = -1; + float max; - printf ("Calibration "); - fflush (stdout); + printf("Calibration ... "); + fflush(stdout); /* build telemetry values lines */ - for (n = 0; n < nrow; n++) { - int i; + for (n = 0; n < nrow; n++) { + int i; - teleline[n] = 0.0; - for (i = 3; i < 43; i++) { - teleline[n] += prow[n][i + offset + 956]; + teleline[n] = 0.0; + for (i = 3; i < 43; i++) { + teleline[n] += prow[n][i + offset + 956]; + } + teleline[n] /= 40.0; } - teleline[n] /= 40.0; - } - if (nrow < 192) { - fprintf (stderr, " impossible, not enought row\n"); - return (0); - } + if (nrow < 192) { + fprintf(stderr, " impossible, not enought row\n"); + return (0); + } /* find telemetry start in the 2nd third */ - max = 0.0; - mtelestart = 0; - for (n = nrow / 3 - 64; n < 2 * nrow / 3 - 64; n++) { - float df; - - df = - (teleline[n - 4] + teleline[n - 3] + teleline[n - 2] + - teleline[n - 1]) / (teleline[n] + teleline[n + 1] + teleline[n + 2] + - teleline[n + 3]); - if (df > max) { - mtelestart = n; - max = df; + max = 0.0; + mtelestart = 0; + for (n = nrow / 3 - 64; n < 2 * nrow / 3 - 64; n++) { + float df; + + df = (teleline[n - 4] + teleline[n - 3] + teleline[n - 2] + + teleline[n - 1]) / (teleline[n] + teleline[n + 1] + + teleline[n + 2] + teleline[n + 3]); + if (df > max) { + mtelestart = n; + max = df; + } } - } - mtelestart -= 64; - telestart = mtelestart % 128; + mtelestart -= 64; + telestart = mtelestart % 128; - if (mtelestart < 0 || nrow < telestart + 128) { - fprintf (stderr, " impossible, not enought row\n"); - return (0); - } + if (mtelestart < 0 || nrow < telestart + 128) { + fprintf(stderr, " impossible, not enought row\n"); + return (0); + } /* compute wedges and regression */ - for (n = telestart, k = 0; n < nrow - 128; n += 128, k++) { - int j; + for (n = telestart, k = 0; n < nrow - 128; n += 128, k++) { + int j; - for (j = 0; j < 16; j++) { - int i; + for (j = 0; j < 16; j++) { + int i; - wedge[j] = 0.0; - for (i = 1; i < 7; i++) - wedge[j] += teleline[n + j * 8 + i]; - wedge[j] /= 6; - } + wedge[j] = 0.0; + for (i = 1; i < 7; i++) + wedge[j] += teleline[n + j * 8 + i]; + wedge[j] /= 6; + } - rgcomp (wedge, &(regr[k])); + rgcomp(wedge, &(regr[k])); - if (k == nrow / 256) { - int i, l; + if (k == nrow / 256) { + int i, l; - /* telemetry calibration */ - for (j = 0; j < 16; j++) { - tele[j] = rgcal (wedge[j], &(regr[k])); - } + /* telemetry calibration */ + for (j = 0; j < 16; j++) { + tele[j] = rgcal(wedge[j], &(regr[k])); + } - /* channel ID */ - for (j = 0, max = 10000.0, channel = -1; j < 6; j++) { - float df; - df = wedge[15] - wedge[j]; - df = df * df; - if (df < max) { - channel = j; - max = df; - } - } - - /* Cs computation */ - for (Cs = 0.0, i = 0, j = n; j < n + 128; j++) { - double csline; - - for (csline = 0.0, l = 3; l < 43; l++) - csline += prow[n][l + offset]; - csline /= 40.0; - if (csline > 50.0) { - Cs += csline; - i++; + /* channel ID */ + for (j = 0, max = 10000.0, channel = -1; j < 6; j++) { + float df; + + df = wedge[15] - wedge[j]; + df = df * df; + if (df < max) { + channel = j; + max = df; + } + } + + /* Cs computation */ + for (Cs = 0.0, i = 0, j = n; j < n + 128; j++) { + double csline; + + for (csline = 0.0, l = 3; l < 43; l++) + csline += prow[n][l + offset]; + csline /= 40.0; + if (csline > 50.0) { + Cs += csline; + i++; + } + } + Cs /= i; + Cs = rgcal(Cs, &(regr[k])); } - } - Cs /= i; - Cs = rgcal (Cs, &(regr[k])); } - } - nbtele = k; + nbtele = k; /* calibrate */ - for (n = 0; n < nrow; n++) { - float *pixelv; - int i, c; - - pixelv = prow[n]; - for (i = 0; i < 1001; i++) { - float pv; - int k, kof; - - pv = pixelv[i + offset]; - - k = (n - telestart) / 128; - if (k >= nbtele) - k = nbtele - 1; - kof = (n - telestart) % 128; - if (kof < 64) { - if (k < 1) { - pv = rgcal (pv, &(regr[k])); - } - else { - pv = rgcal (pv, &(regr[k])) * (64 + kof) / 128.0 + - rgcal (pv, &(regr[k - 1])) * (64 - kof) / 128.0; - } - } - else { - if ((k + 1) >= nbtele) { - pv = rgcal (pv, &(regr[k])); - } - else { - pv = rgcal (pv, &(regr[k])) * (192 - kof) / 128.0 + - rgcal (pv, &(regr[k + 1])) * (kof - 64) / 128.0; + for (n = 0; n < nrow; n++) { + float *pixelv; + int i; + + pixelv = prow[n]; + for (i = 0; i < 1001; i++) { + float pv; + int k, kof; + + pv = pixelv[i + offset]; + + k = (n - telestart) / 128; + if (k >= nbtele) + k = nbtele - 1; + kof = (n - telestart) % 128; + if (kof < 64) { + if (k < 1) { + pv = rgcal(pv, &(regr[k])); + } else { + pv = rgcal(pv, &(regr[k])) * (64 + kof) / 128.0 + + rgcal(pv, &(regr[k - 1])) * (64 - kof) / 128.0; + } + } else { + if ((k + 1) >= nbtele) { + pv = rgcal(pv, &(regr[k])); + } else { + pv = rgcal(pv, &(regr[k])) * (192 - kof) / 128.0 + + rgcal(pv, &(regr[k + 1])) * (kof - 64) / 128.0; + } + } + + if (pv > 255.0) + pv = 255.0; + if (pv < 0.0) + pv = 0.0; + pixelv[i + offset] = pv; } - } - - if (pv > 255.0) - pv = 255.0; - if (pv < 0.0) - pv = 0.0; - pixelv[i + offset] = pv; } - } - printf ("Done\n"); - return (channel); + printf("Done\n"); + return (channel); } /* ------------------------------temperature calibration -----------------------*/ extern int satnum; -const struct -{ - float d[4][3]; - struct - { - float vc, A, B; - } rad[3]; - struct - { - float Ns; - float b[3]; - } cor[3]; +const struct { + float d[4][3]; + struct { + float vc, A, B; + } rad[3]; + struct { + float Ns; + float b[3]; + } cor[3]; } satcal[2] = #include "satcal.h" - typedef struct -{ - double Nbb; - double Cs; - double Cb; - int ch; + +typedef struct { + double Nbb; + double Cs; + double Cb; + int ch; } tempparam; /* temperature compensation for IR channel */ -static void -tempcomp (double t[16], int ch, tempparam * tpr) +static void tempcomp(double t[16], int ch, tempparam * tpr) { - double Tbb, T[4]; - double C; - double r; - int n; - - tpr->ch = ch - 3; - - /* compute equivalent T black body */ - for (n = 0; n < 4; n++) { - float d0, d1, d2; - - C = t[9 + n] * 4.0; - d0 = satcal[satnum].d[n][0]; - d1 = satcal[satnum].d[n][1]; - d2 = satcal[satnum].d[n][2]; - T[n] = d0; - T[n] += d1 * C; - C = C * C; - T[n] += d2 * C; - } - Tbb = (T[0] + T[1] + T[2] + T[3]) / 4.0; - Tbb = satcal[satnum].rad[tpr->ch].A + satcal[satnum].rad[tpr->ch].B * Tbb; - - /* compute radiance Black body */ - C = satcal[satnum].rad[tpr->ch].vc; - tpr->Nbb = c1 * C * C * C / (exp (c2 * C / Tbb) - 1.0); - /* store Count Blackbody and space */ - tpr->Cs = Cs * 4.0; - tpr->Cb = t[14] * 4.0; + double Tbb, T[4]; + double C; + int n; + + tpr->ch = ch - 3; + + /* compute equivalent T black body */ + for (n = 0; n < 4; n++) { + float d0, d1, d2; + + C = t[9 + n] * 4.0; + d0 = satcal[satnum].d[n][0]; + d1 = satcal[satnum].d[n][1]; + d2 = satcal[satnum].d[n][2]; + T[n] = d0; + T[n] += d1 * C; + C = C * C; + T[n] += d2 * C; + } + Tbb = (T[0] + T[1] + T[2] + T[3]) / 4.0; + Tbb = + satcal[satnum].rad[tpr->ch].A + + satcal[satnum].rad[tpr->ch].B * Tbb; + + /* compute radiance Black body */ + C = satcal[satnum].rad[tpr->ch].vc; + tpr->Nbb = c1 * C * C * C / (exp(c2 * C / Tbb) - 1.0); + /* store Count Blackbody and space */ + tpr->Cs = Cs * 4.0; + tpr->Cb = t[14] * 4.0; } -static double -tempcal (float Ce, tempparam * rgpr) +static double tempcal(float Ce, tempparam * rgpr) { - double Nl, Nc, Ns, Ne; - double T, vc; + double Nl, Nc, Ns, Ne; + double T, vc; - Ns = satcal[satnum].cor[rgpr->ch].Ns; - Nl = Ns + (rgpr->Nbb - Ns) * (rgpr->Cs - Ce * 4.0) / (rgpr->Cs - rgpr->Cb); - Nc = satcal[satnum].cor[rgpr->ch].b[0] + - satcal[satnum].cor[rgpr->ch].b[1] * Nl + - satcal[satnum].cor[rgpr->ch].b[2] * Nl * Nl; + Ns = satcal[satnum].cor[rgpr->ch].Ns; + Nl = Ns + (rgpr->Nbb - Ns) * (rgpr->Cs - Ce * 4.0) / (rgpr->Cs - + rgpr->Cb); + Nc = satcal[satnum].cor[rgpr->ch].b[0] + + satcal[satnum].cor[rgpr->ch].b[1] * Nl + + satcal[satnum].cor[rgpr->ch].b[2] * Nl * Nl; - Ne = Nl + Nc; + Ne = Nl + Nc; - vc = satcal[satnum].rad[rgpr->ch].vc; - T = c2 * vc / log (c1 * vc * vc * vc / Ne + 1.0); - T = (T - satcal[satnum].rad[rgpr->ch].A) / satcal[satnum].rad[rgpr->ch].B; + vc = satcal[satnum].rad[rgpr->ch].vc; + T = c2 * vc / log(c1 * vc * vc * vc / Ne + 1.0); + T = (T - + satcal[satnum].rad[rgpr->ch].A) / satcal[satnum].rad[rgpr->ch].B; - /* rescale to range 0-255 for +40-60 °C */ - T = (-T + 273.15 + 40) / 100.0 * 255.0; + /* rescale to range 0-255 for +40-60 °C */ + T = (-T + 273.15 + 40) / 100.0 * 255.0; - return (T); + return (T); } -int -Temperature (float **prow, int nrow, int channel, int offset) +void Temperature(float **prow, int nrow, int channel, int offset) { - tempparam temp; - int n; + tempparam temp; + int n; - printf ("Temperature "); + printf("Temperature ... "); + fflush(stdout); - tempcomp (tele, channel, &temp); + tempcomp(tele, channel, &temp); - for (n = 0; n < nrow; n++) { - float *pixelv; - int i, c; + for (n = 0; n < nrow; n++) { + float *pixelv; + int i; - pixelv = prow[n]; - for (i = 0; i < 1001; i++) { - float pv; + pixelv = prow[n]; + for (i = 0; i < 1001; i++) { + float pv; - pv = tempcal (pixelv[i + offset], &temp); + pv = tempcal(pixelv[i + offset], &temp); - if (pv > 255.0) - pv = 255.0; - if (pv < 0.0) - pv = 0.0; - pixelv[i + offset] = pv; + if (pv > 255.0) + pv = 255.0; + if (pv < 0.0) + pv = 0.0; + pixelv[i + offset] = pv; + } } - } - printf ("Done\n"); + printf("Done\n"); } diff --git a/reg.c b/reg.c index 1942fe4..f7b07cc 100644 --- a/reg.c +++ b/reg.c @@ -1,151 +1,144 @@ -/* --------------------------------------------------------------------------- - - Polynomial regression, freely adapted from : - - NUMERICAL METHODS: C Programs, (c) John H. Mathews 1995 - Algorithm translated to C by: Dr. Norman Fahrer - NUMERICAL METHODS for Mathematics, Science and Engineering, 2nd Ed, 1992 - Prentice Hall, International Editions: ISBN 0-13-625047-5 - This free software is compliments of the author. - E-mail address: in%"mathews@fullerton.edu" -*/ - -#include - -#define DMAX 5 /* Maximum degree of polynomial */ -#define NMAX 10 /* Maximum number of points */ - static void FactPiv (int N, double A[DMAX][DMAX], double B[], double Cf[]); - void -polyreg (const int M, const int N, const double X[], const double Y[], - double C[]) +/* --------------------------------------------------------------------------- + + Polynomial regression, freely adapted from : + + NUMERICAL METHODS: C Programs, (c) John H. Mathews 1995 + Algorithm translated to C by: Dr. Norman Fahrer + NUMERICAL METHODS for Mathematics, Science and Engineering, 2nd Ed, 1992 + Prentice Hall, International Editions: ISBN 0-13-625047-5 + This free software is compliments of the author. + E-mail address: in%"mathews@fullerton.edu" +*/ + +#include + +#define DMAX 5 /* Maximum degree of polynomial */ +#define NMAX 10 /* Maximum number of points */ +static void FactPiv(int N, double A[DMAX][DMAX], double B[], double Cf[]); +void +polyreg(const int M, const int N, const double X[], const double Y[], + double C[]) { - int R, K, J; /* Loop counters */ - double A[DMAX][DMAX]; /* A */ - double B[DMAX]; - double P[2 * DMAX + 1]; - double x, y; - double p; - - /* Zero the array */ - for (R = 0; R < M + 1; R++) - B[R] = 0; - - /* Compute the column vector */ - for (K = 0; K < N; K++) - { - y = Y[K]; - x = X[K]; - p = 1.0; - for (R = 0; R < M + 1; R++) - { - B[R] += y * p; - p = p * x; - } - } - - /* Zero the array */ - for (J = 1; J <= 2 * M; J++) - P[J] = 0; - P[0] = N; - - /* Compute the sum of powers of x_(K-1) */ - for (K = 0; K < N; K++) - { - x = X[K]; - p = X[K]; - for (J = 1; J <= 2 * M; J++) - { - P[J] += p; - p = p * x; - } - } - - /* Determine the matrix entries */ - for (R = 0; R < M + 1; R++) - { - for (K = 0; K < M + 1; K++) - A[R][K] = P[R + K]; - } - - /* Solve the linear system of M + 1 equations : A*C = B - for the coefficient vector C = (c_1,c_2,..,c_M,c_(M+1)) */ - FactPiv (M + 1, A, B, C); - } /* end main */ - - -/*--------------------------------------------------------*/ - static void -FactPiv (int N, double A[DMAX][DMAX], double B[], double Cf[]) + int R, K, J; /* Loop counters */ + double A[DMAX][DMAX]; /* A */ + double B[DMAX]; + double P[2 * DMAX + 1]; + double x, y; + double p; + + + /* Zero the array */ + for (R = 0; R < M + 1; R++) + B[R] = 0; + + /* Compute the column vector */ + for (K = 0; K < N; K++) { + y = Y[K]; + x = X[K]; + p = 1.0; + for (R = 0; R < M + 1; R++) { + B[R] += y * p; + p = p * x; + } + } + + /* Zero the array */ + for (J = 1; J <= 2 * M; J++) + P[J] = 0; + P[0] = N; + + /* Compute the sum of powers of x_(K-1) */ + for (K = 0; K < N; K++) { + x = X[K]; + p = X[K]; + for (J = 1; J <= 2 * M; J++) { + P[J] += p; + p = p * x; + } + } + + /* Determine the matrix entries */ + for (R = 0; R < M + 1; R++) { + for (K = 0; K < M + 1; K++) + A[R][K] = P[R + K]; + } + + /* Solve the linear system of M + 1 equations : A*C = B + for the coefficient vector C = (c_1,c_2,..,c_M,c_(M+1)) */ + FactPiv(M + 1, A, B, C); +} /* end main */ + + +/*--------------------------------------------------------*/ +static void FactPiv(int N, double A[DMAX][DMAX], double B[], double Cf[]) { - int K, P, C, J; /* Loop counters */ - int Row[NMAX]; /* Field with row-number */ - double X[DMAX], Y[DMAX]; - double SUM, DET = 1.0; - int T; - - /* Initialize the pointer vector */ - for (J = 0; J < N; J++) - Row[J] = J; - - /* Start LU factorization */ - for (P = 0; P < N - 1; P++) { - - /* Find pivot element */ - for (K = P + 1; K < N; K++) { - if (fabs (A[Row[K]][P]) > fabs (A[Row[P]][P])) { - - /* Switch the index for the p-1 th pivot row if necessary */ - T = Row[P]; - Row[P] = Row[K]; - Row[K] = T; - DET = -DET; - } - } /* End of simulated row interchange */ - if (A[Row[P]][P] == 0) { - printf ("The matrix is SINGULAR !\n"); - printf ("Cannot use algorithm --> exit\n"); - exit (1); - } - - /* Multiply the diagonal elements */ - DET = DET * A[Row[P]][P]; - - /* Form multiplier */ - for (K = P + 1; K < N; K++) { - A[Row[K]][P] = A[Row[K]][P] / A[Row[P]][P]; - - /* Eliminate X_(p-1) */ - for (C = P + 1; C < N + 1; C++) { - A[Row[K]][C] -= A[Row[K]][P] * A[Row[P]][C]; - } - } - } /* End of L*U factorization routine */ - DET = DET * A[Row[N - 1]][N - 1]; - - /* Start the forward substitution */ - for (K = 0; K < N; K++) - Y[K] = B[K]; - Y[0] = B[Row[0]]; - for (K = 1; K < N; K++) { - SUM = 0; - for (C = 0; C <= K - 1; C++) - SUM += A[Row[K]][C] * Y[C]; - Y[K] = B[Row[K]] - SUM; - } - - /* Start the back substitution */ - X[N - 1] = Y[N - 1] / A[Row[N - 1]][N - 1]; - for (K = N - 2; K >= 0; K--) { - SUM = 0; - for (C = K + 1; C < N; C++) { - SUM += A[Row[K]][C] * X[C]; - } - X[K] = (Y[K] - SUM) / A[Row[K]][K]; - } /* End of back substitution */ - - /* Output */ + int K, P, C, J; /* Loop counters */ + int Row[NMAX]; /* Field with row-number */ + double X[DMAX], Y[DMAX]; + double SUM, DET = 1.0; + int T; + + + /* Initialize the pointer vector */ + for (J = 0; J < N; J++) + Row[J] = J; + + /* Start LU factorization */ + for (P = 0; P < N - 1; P++) { + + /* Find pivot element */ + for (K = P + 1; K < N; K++) { + if (fabs(A[Row[K]][P]) > fabs(A[Row[P]][P])) { + + /* Switch the index for the p-1 th pivot row if necessary */ + T = Row[P]; + Row[P] = Row[K]; + Row[K] = T; + DET = -DET; + } + } /* End of simulated row interchange */ + if (A[Row[P]][P] == 0) { + /* The matrix is SINGULAR ! */ + return; + } + + /* Multiply the diagonal elements */ + DET = DET * A[Row[P]][P]; + + /* Form multiplier */ + for (K = P + 1; K < N; K++) { + A[Row[K]][P] = A[Row[K]][P] / A[Row[P]][P]; + + /* Eliminate X_(p-1) */ + for (C = P + 1; C < N + 1; C++) { + A[Row[K]][C] -= A[Row[K]][P] * A[Row[P]][C]; + } + } + } /* End of L*U factorization routine */ + DET = DET * A[Row[N - 1]][N - 1]; + + /* Start the forward substitution */ for (K = 0; K < N; K++) - Cf[K] = X[K]; - } + Y[K] = B[K]; + Y[0] = B[Row[0]]; + for (K = 1; K < N; K++) { + SUM = 0; + for (C = 0; C <= K - 1; C++) + SUM += A[Row[K]][C] * Y[C]; + Y[K] = B[Row[K]] - SUM; + } - + /* Start the back substitution */ + X[N - 1] = Y[N - 1] / A[Row[N - 1]][N - 1]; + for (K = N - 2; K >= 0; K--) { + SUM = 0; + for (C = K + 1; C < N; C++) { + SUM += A[Row[K]][C] * X[C]; + } + X[K] = (Y[K] - SUM) / A[Row[K]][K]; + } /* End of back substitution */ + + /* Output */ + for (K = 0; K < N; K++) + Cf[K] = X[K]; +} diff --git a/satcal.h b/satcal.h index 87def06..3648899 100644 --- a/satcal.h +++ b/satcal.h @@ -12,9 +12,9 @@ {2695.9743 , 1.621256 , 0.998015} /* channel 3B */ }, { /* nonlinear radiance correction Ns,b0,b1,b2 */ -{-4.50 , 4.76 , -0.0932 , 0.0004524}, /* channel 4 */ -{-3.61 , 3.83 , -0.0659 , 0.0002811}, /* channel 5*/ -{0.0,0.0,0.0,0.0} /* channel 3B*/ +{-4.50 , {4.76 , -0.0932 , 0.0004524}}, /* channel 4 */ +{-3.61 , {3.83 , -0.0659 , 0.0002811}}, /* channel 5*/ +{0.0,{0.0,0.0,0.0}} /* channel 3B*/ } }, {/* NOAA 17 */ @@ -30,9 +30,9 @@ {2669.3554 , 1.702380 , 0.997378} /* channel 3B */ }, { /* nonlinear radiance correction Ns,b0,b1,b2 */ -{-8.55 , 8.22 , -0.15795 , 0.00075579}, /* channel 4 */ -{-3.97 , 4.31 , -0.07318 , 0.00030976}, /* channel 5 */ -{0.0,0.0,0.0,0.0} /* channel 3B*/ +{-8.55 , {8.22 , -0.15795 , 0.00075579}}, /* channel 4 */ +{-3.97 , {4.31 , -0.07318 , 0.00030976}}, /* channel 5 */ +{0.0,{0.0,0.0,0.0}} /* channel 3B*/ } } };