From ee20dab8e8671bc1008c8a7ea570ae34a8d4fe26 Mon Sep 17 00:00:00 2001 From: Martin Mueller Date: Wed, 25 May 2005 21:48:26 +0000 Subject: [PATCH] Initial revision --- sw/ground_segment/multimon/Makefile | 92 ++ sw/ground_segment/multimon/costabf.c | 262 +++++ sw/ground_segment/multimon/costabi.c | 134 +++ sw/ground_segment/multimon/demod_afsk12.c | 128 ++ sw/ground_segment/multimon/demod_afsk24.c | 125 ++ sw/ground_segment/multimon/demod_afsk24_2.c | 125 ++ sw/ground_segment/multimon/demod_display.c | 86 ++ sw/ground_segment/multimon/demod_dtmf.c | 151 +++ sw/ground_segment/multimon/demod_fsk96.c | 128 ++ sw/ground_segment/multimon/demod_hapn48.c | 99 ++ sw/ground_segment/multimon/demod_poc12.c | 93 ++ sw/ground_segment/multimon/demod_poc24.c | 80 ++ sw/ground_segment/multimon/demod_poc5.c | 92 ++ sw/ground_segment/multimon/demod_zvei.c | 146 +++ sw/ground_segment/multimon/filter-i386.h | 277 +++++ sw/ground_segment/multimon/filter.h | 110 ++ sw/ground_segment/multimon/filter/fifsk96 | 8 + sw/ground_segment/multimon/filter/fifsk96.g | 1028 +++++++++++++++++ sw/ground_segment/multimon/filter/mkfifsk96.c | 43 + sw/ground_segment/multimon/gen.c | 520 +++++++++ sw/ground_segment/multimon/gen.h | 97 ++ sw/ground_segment/multimon/gen_dtmf.c | 95 ++ sw/ground_segment/multimon/gen_hdlc.c | 208 ++++ sw/ground_segment/multimon/gen_sin.c | 46 + sw/ground_segment/multimon/gen_zvei.c | 87 ++ sw/ground_segment/multimon/hdlc.c | 283 +++++ sw/ground_segment/multimon/mkcostab.c | 63 + sw/ground_segment/multimon/multimon.h | 171 +++ sw/ground_segment/multimon/pocsag.c | 476 ++++++++ sw/ground_segment/multimon/unixinput.c | 493 ++++++++ sw/ground_segment/multimon/xdisplay.c | 440 +++++++ 31 files changed, 6186 insertions(+) create mode 100644 sw/ground_segment/multimon/Makefile create mode 100644 sw/ground_segment/multimon/costabf.c create mode 100644 sw/ground_segment/multimon/costabi.c create mode 100644 sw/ground_segment/multimon/demod_afsk12.c create mode 100644 sw/ground_segment/multimon/demod_afsk24.c create mode 100644 sw/ground_segment/multimon/demod_afsk24_2.c create mode 100644 sw/ground_segment/multimon/demod_display.c create mode 100644 sw/ground_segment/multimon/demod_dtmf.c create mode 100644 sw/ground_segment/multimon/demod_fsk96.c create mode 100644 sw/ground_segment/multimon/demod_hapn48.c create mode 100644 sw/ground_segment/multimon/demod_poc12.c create mode 100644 sw/ground_segment/multimon/demod_poc24.c create mode 100644 sw/ground_segment/multimon/demod_poc5.c create mode 100644 sw/ground_segment/multimon/demod_zvei.c create mode 100644 sw/ground_segment/multimon/filter-i386.h create mode 100644 sw/ground_segment/multimon/filter.h create mode 100644 sw/ground_segment/multimon/filter/fifsk96 create mode 100644 sw/ground_segment/multimon/filter/fifsk96.g create mode 100644 sw/ground_segment/multimon/filter/mkfifsk96.c create mode 100644 sw/ground_segment/multimon/gen.c create mode 100644 sw/ground_segment/multimon/gen.h create mode 100644 sw/ground_segment/multimon/gen_dtmf.c create mode 100644 sw/ground_segment/multimon/gen_hdlc.c create mode 100644 sw/ground_segment/multimon/gen_sin.c create mode 100644 sw/ground_segment/multimon/gen_zvei.c create mode 100644 sw/ground_segment/multimon/hdlc.c create mode 100644 sw/ground_segment/multimon/mkcostab.c create mode 100644 sw/ground_segment/multimon/multimon.h create mode 100644 sw/ground_segment/multimon/pocsag.c create mode 100644 sw/ground_segment/multimon/unixinput.c create mode 100644 sw/ground_segment/multimon/xdisplay.c diff --git a/sw/ground_segment/multimon/Makefile b/sw/ground_segment/multimon/Makefile new file mode 100644 index 0000000000..56bcc32119 --- /dev/null +++ b/sw/ground_segment/multimon/Makefile @@ -0,0 +1,92 @@ +DEBUG =n +OS =$(shell uname) + +CFLAGS =-Wall -Wstrict-prototypes -I/usr/X11R6/include +ifeq ($(OS),SunOS) +ifeq ($(DEBUG),y) +CFLAGS +=-g -O -DSUN_AUDIO -DARCH_SPARC +else +CFLAGS +=-O3 -DSUN_AUDIO -DARCH_SPARC +endif +LDFLAGSX =-lX11 -L/usr/X11R6/lib -R/usr/X11R6/lib -lsocket -lnsl +else +ifeq ($(DEBUG),y) +CFLAGS +=-g -O -m486 -malign-loops=2 -malign-jumps=2 \ + -malign-functions=2 -DARCH_I386 +else +CFLAGS +=-O3 -m486 -malign-loops=2 -malign-jumps=2 \ + -malign-functions=2 -DARCH_I386 +endif +LDFLAGSX =-lX11 -L/usr/X11R6/lib +endif + + +BINDIR =bin-$(shell uname -m) + +AS86 =as86 -0 -a +LD86 =ld86 -0 + +AS =as +LD =ld +LDFLAGS =-lm +HOSTCC =gcc +CC =gcc +MAKE =make +CPP =$(CC) -E +AR =ar +STRIP =strip +MKDIR =mkdir + +all: $(BINDIR) $(BINDIR)/multimon $(BINDIR)/gen + +$(BINDIR)/%.s: %.c + $(CC) $(CFLAGS) -S -o $@ $< + +$(BINDIR)/%.o: $(BINDIR)/%.s + $(AS) -c -o $@ $< + +$(BINDIR)/%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +SRC_L2 =hdlc.c pocsag.c +SRC_L1 =demod_afsk12.c demod_afsk24.c demod_afsk24_2.c +SRC_L1 +=demod_hapn48.c demod_fsk96.c +SRC_L1 +=demod_poc5.c demod_poc12.c demod_poc24.c +SRC_L1 +=demod_dtmf.c demod_zvei.c demod_display.c +SRC_MISC =unixinput.c costabf.c xdisplay.c + +SRC_GEN =gen.c gen_dtmf.c gen_sin.c gen_zvei.c gen_hdlc.c costabi.c + +OBJ_L2 =$(SRC_L2:%.c=$(BINDIR)/%.o) +OBJ_L1 =$(SRC_L1:%.c=$(BINDIR)/%.o) +OBJ_MISC =$(SRC_MISC:%.c=$(BINDIR)/%.o) + +OBJ_GEN =$(SRC_GEN:%.c=$(BINDIR)/%.o) + +$(BINDIR): + $(MKDIR) $(BINDIR) + +$(BINDIR)/multimon: $(OBJ_L2) $(OBJ_L1) $(OBJ_MISC) + $(CC) $^ $(LDFLAGS) $(LDFLAGSX) -o $@ + +$(BINDIR)/gen: $(OBJ_GEN) + $(CC) $^ $(LDFLAGS) -o $@ + +$(BINDIR)/mkcostab: $(BINDIR)/mkcostab.o + $(CC) $^ $(LDFLAGS) -o $@ + +costabi.c costabf.c: $(BINDIR)/mkcostab + $(BINDIR)/mkcostab + +clean: + $(RM) -f core `find . -name '*.[oas]' -print` + $(RM) -f core `find . -name 'core' -print` + $(RM) -f core costabi.c costabf.c *~ + + +depend dep: + $(CPP) -M $(CFLAGS) $(SRC_MISC) $(SRC_L1) $(SRC_L2) $(SRC_GEN) mkcostab.c > $(BINDIR)/.depend + +ifeq ($(BINDIR)/.depend,$(wildcard $(BINDIR)/.depend)) +include $(BINDIR)/.depend +endif diff --git a/sw/ground_segment/multimon/costabf.c b/sw/ground_segment/multimon/costabf.c new file mode 100644 index 0000000000..d97c43e413 --- /dev/null +++ b/sw/ground_segment/multimon/costabf.c @@ -0,0 +1,262 @@ +/* + * This file is machine generated, DO NOT EDIT! + */ + +float costabf[1024] = { + 1.000000000, 0.999981165, 0.999924719, 0.999830604, + 0.999698818, 0.999529421, 0.999322355, 0.999077737, + 0.998795450, 0.998475552, 0.998118103, 0.997723043, + 0.997290432, 0.996820271, 0.996312618, 0.995767415, + 0.995184720, 0.994564593, 0.993906975, 0.993211925, + 0.992479563, 0.991709769, 0.990902662, 0.990058184, + 0.989176512, 0.988257587, 0.987301409, 0.986308098, + 0.985277653, 0.984210074, 0.983105481, 0.981963873, + 0.980785251, 0.979569793, 0.978317380, 0.977028131, + 0.975702107, 0.974339366, 0.972939968, 0.971503913, + 0.970031261, 0.968522072, 0.966976464, 0.965394437, + 0.963776052, 0.962121427, 0.960430503, 0.958703458, + 0.956940353, 0.955141187, 0.953306019, 0.951435030, + 0.949528158, 0.947585583, 0.945607305, 0.943593442, + 0.941544056, 0.939459205, 0.937339008, 0.935183525, + 0.932992816, 0.930766940, 0.928506076, 0.926210225, + 0.923879504, 0.921514034, 0.919113874, 0.916679084, + 0.914209783, 0.911706030, 0.909168005, 0.906595707, + 0.903989315, 0.901348829, 0.898674488, 0.895966232, + 0.893224299, 0.890448749, 0.887639642, 0.884797096, + 0.881921291, 0.879012227, 0.876070082, 0.873094976, + 0.870086968, 0.867046237, 0.863972843, 0.860866964, + 0.857728601, 0.854557991, 0.851355195, 0.848120332, + 0.844853580, 0.841554999, 0.838224709, 0.834862888, + 0.831469595, 0.828045070, 0.824589312, 0.821102500, + 0.817584813, 0.814036310, 0.810457170, 0.806847572, + 0.803207517, 0.799537241, 0.795836926, 0.792106569, + 0.788346410, 0.784556568, 0.780737221, 0.776888490, + 0.773010433, 0.769103348, 0.765167236, 0.761202395, + 0.757208824, 0.753186822, 0.749136388, 0.745057762, + 0.740951121, 0.736816585, 0.732654274, 0.728464365, + 0.724247098, 0.720002532, 0.715730846, 0.711432219, + 0.707106769, 0.702754736, 0.698376238, 0.693971455, + 0.689540565, 0.685083687, 0.680601001, 0.676092684, + 0.671558976, 0.666999936, 0.662415802, 0.657806695, + 0.653172851, 0.648514390, 0.643831551, 0.639124453, + 0.634393275, 0.629638255, 0.624859512, 0.620057225, + 0.615231574, 0.610382795, 0.605511069, 0.600616455, + 0.595699310, 0.590759695, 0.585797846, 0.580813944, + 0.575808167, 0.570780754, 0.565731823, 0.560661554, + 0.555570245, 0.550457954, 0.545324981, 0.540171444, + 0.534997642, 0.529803634, 0.524589658, 0.519356012, + 0.514102757, 0.508830130, 0.503538370, 0.498227656, + 0.492898196, 0.487550169, 0.482183784, 0.476799220, + 0.471396744, 0.465976506, 0.460538715, 0.455083579, + 0.449611336, 0.444122136, 0.438616246, 0.433093816, + 0.427555084, 0.422000259, 0.416429549, 0.410843164, + 0.405241311, 0.399624199, 0.393992037, 0.388345033, + 0.382683426, 0.377007425, 0.371317208, 0.365612984, + 0.359895051, 0.354163527, 0.348418683, 0.342660725, + 0.336889863, 0.331106305, 0.325310290, 0.319502026, + 0.313681751, 0.307849646, 0.302005947, 0.296150893, + 0.290284663, 0.284407526, 0.278519690, 0.272621363, + 0.266712755, 0.260794103, 0.254865646, 0.248927608, + 0.242980182, 0.237023607, 0.231058106, 0.225083917, + 0.219101235, 0.213110313, 0.207111374, 0.201104641, + 0.195090324, 0.189068660, 0.183039889, 0.177004218, + 0.170961887, 0.164913118, 0.158858150, 0.152797192, + 0.146730468, 0.140658244, 0.134580702, 0.128498107, + 0.122410677, 0.116318628, 0.110222206, 0.104121633, + 0.098017141, 0.091908954, 0.085797310, 0.079682440, + 0.073564567, 0.067443922, 0.061320737, 0.055195246, + 0.049067676, 0.042938258, 0.036807224, 0.030674804, + 0.024541229, 0.018406730, 0.012271538, 0.006135885, + 0.000000000, -0.006135885, -0.012271538, -0.018406730, + -0.024541229, -0.030674804, -0.036807224, -0.042938258, + -0.049067676, -0.055195246, -0.061320737, -0.067443922, + -0.073564567, -0.079682440, -0.085797310, -0.091908954, + -0.098017141, -0.104121633, -0.110222206, -0.116318628, + -0.122410677, -0.128498107, -0.134580702, -0.140658244, + -0.146730468, -0.152797192, -0.158858150, -0.164913118, + -0.170961887, -0.177004218, -0.183039889, -0.189068660, + -0.195090324, -0.201104641, -0.207111374, -0.213110313, + -0.219101235, -0.225083917, -0.231058106, -0.237023607, + -0.242980182, -0.248927608, -0.254865646, -0.260794103, + -0.266712755, -0.272621363, -0.278519690, -0.284407526, + -0.290284663, -0.296150893, -0.302005947, -0.307849646, + -0.313681751, -0.319502026, -0.325310290, -0.331106305, + -0.336889863, -0.342660725, -0.348418683, -0.354163527, + -0.359895051, -0.365612984, -0.371317208, -0.377007425, + -0.382683426, -0.388345033, -0.393992037, -0.399624199, + -0.405241311, -0.410843164, -0.416429549, -0.422000259, + -0.427555084, -0.433093816, -0.438616246, -0.444122136, + -0.449611336, -0.455083579, -0.460538715, -0.465976506, + -0.471396744, -0.476799220, -0.482183784, -0.487550169, + -0.492898196, -0.498227656, -0.503538370, -0.508830130, + -0.514102757, -0.519356012, -0.524589658, -0.529803634, + -0.534997642, -0.540171444, -0.545324981, -0.550457954, + -0.555570245, -0.560661554, -0.565731823, -0.570780754, + -0.575808167, -0.580813944, -0.585797846, -0.590759695, + -0.595699310, -0.600616455, -0.605511069, -0.610382795, + -0.615231574, -0.620057225, -0.624859512, -0.629638255, + -0.634393275, -0.639124453, -0.643831551, -0.648514390, + -0.653172851, -0.657806695, -0.662415802, -0.666999936, + -0.671558976, -0.676092684, -0.680601001, -0.685083687, + -0.689540565, -0.693971455, -0.698376238, -0.702754736, + -0.707106769, -0.711432219, -0.715730846, -0.720002532, + -0.724247098, -0.728464365, -0.732654274, -0.736816585, + -0.740951121, -0.745057762, -0.749136388, -0.753186822, + -0.757208824, -0.761202395, -0.765167236, -0.769103348, + -0.773010433, -0.776888490, -0.780737221, -0.784556568, + -0.788346410, -0.792106569, -0.795836926, -0.799537241, + -0.803207517, -0.806847572, -0.810457170, -0.814036310, + -0.817584813, -0.821102500, -0.824589312, -0.828045070, + -0.831469595, -0.834862888, -0.838224709, -0.841554999, + -0.844853580, -0.848120332, -0.851355195, -0.854557991, + -0.857728601, -0.860866964, -0.863972843, -0.867046237, + -0.870086968, -0.873094976, -0.876070082, -0.879012227, + -0.881921291, -0.884797096, -0.887639642, -0.890448749, + -0.893224299, -0.895966232, -0.898674488, -0.901348829, + -0.903989315, -0.906595707, -0.909168005, -0.911706030, + -0.914209783, -0.916679084, -0.919113874, -0.921514034, + -0.923879504, -0.926210225, -0.928506076, -0.930766940, + -0.932992816, -0.935183525, -0.937339008, -0.939459205, + -0.941544056, -0.943593442, -0.945607305, -0.947585583, + -0.949528158, -0.951435030, -0.953306019, -0.955141187, + -0.956940353, -0.958703458, -0.960430503, -0.962121427, + -0.963776052, -0.965394437, -0.966976464, -0.968522072, + -0.970031261, -0.971503913, -0.972939968, -0.974339366, + -0.975702107, -0.977028131, -0.978317380, -0.979569793, + -0.980785251, -0.981963873, -0.983105481, -0.984210074, + -0.985277653, -0.986308098, -0.987301409, -0.988257587, + -0.989176512, -0.990058184, -0.990902662, -0.991709769, + -0.992479563, -0.993211925, -0.993906975, -0.994564593, + -0.995184720, -0.995767415, -0.996312618, -0.996820271, + -0.997290432, -0.997723043, -0.998118103, -0.998475552, + -0.998795450, -0.999077737, -0.999322355, -0.999529421, + -0.999698818, -0.999830604, -0.999924719, -0.999981165, + -1.000000000, -0.999981165, -0.999924719, -0.999830604, + -0.999698818, -0.999529421, -0.999322355, -0.999077737, + -0.998795450, -0.998475552, -0.998118103, -0.997723043, + -0.997290432, -0.996820271, -0.996312618, -0.995767415, + -0.995184720, -0.994564593, -0.993906975, -0.993211925, + -0.992479563, -0.991709769, -0.990902662, -0.990058184, + -0.989176512, -0.988257587, -0.987301409, -0.986308098, + -0.985277653, -0.984210074, -0.983105481, -0.981963873, + -0.980785251, -0.979569793, -0.978317380, -0.977028131, + -0.975702107, -0.974339366, -0.972939968, -0.971503913, + -0.970031261, -0.968522072, -0.966976464, -0.965394437, + -0.963776052, -0.962121427, -0.960430503, -0.958703458, + -0.956940353, -0.955141187, -0.953306019, -0.951435030, + -0.949528158, -0.947585583, -0.945607305, -0.943593442, + -0.941544056, -0.939459205, -0.937339008, -0.935183525, + -0.932992816, -0.930766940, -0.928506076, -0.926210225, + -0.923879504, -0.921514034, -0.919113874, -0.916679084, + -0.914209783, -0.911706030, -0.909168005, -0.906595707, + -0.903989315, -0.901348829, -0.898674488, -0.895966232, + -0.893224299, -0.890448749, -0.887639642, -0.884797096, + -0.881921291, -0.879012227, -0.876070082, -0.873094976, + -0.870086968, -0.867046237, -0.863972843, -0.860866964, + -0.857728601, -0.854557991, -0.851355195, -0.848120332, + -0.844853580, -0.841554999, -0.838224709, -0.834862888, + -0.831469595, -0.828045070, -0.824589312, -0.821102500, + -0.817584813, -0.814036310, -0.810457170, -0.806847572, + -0.803207517, -0.799537241, -0.795836926, -0.792106569, + -0.788346410, -0.784556568, -0.780737221, -0.776888490, + -0.773010433, -0.769103348, -0.765167236, -0.761202395, + -0.757208824, -0.753186822, -0.749136388, -0.745057762, + -0.740951121, -0.736816585, -0.732654274, -0.728464365, + -0.724247098, -0.720002532, -0.715730846, -0.711432219, + -0.707106769, -0.702754736, -0.698376238, -0.693971455, + -0.689540565, -0.685083687, -0.680601001, -0.676092684, + -0.671558976, -0.666999936, -0.662415802, -0.657806695, + -0.653172851, -0.648514390, -0.643831551, -0.639124453, + -0.634393275, -0.629638255, -0.624859512, -0.620057225, + -0.615231574, -0.610382795, -0.605511069, -0.600616455, + -0.595699310, -0.590759695, -0.585797846, -0.580813944, + -0.575808167, -0.570780754, -0.565731823, -0.560661554, + -0.555570245, -0.550457954, -0.545324981, -0.540171444, + -0.534997642, -0.529803634, -0.524589658, -0.519356012, + -0.514102757, -0.508830130, -0.503538370, -0.498227656, + -0.492898196, -0.487550169, -0.482183784, -0.476799220, + -0.471396744, -0.465976506, -0.460538715, -0.455083579, + -0.449611336, -0.444122136, -0.438616246, -0.433093816, + -0.427555084, -0.422000259, -0.416429549, -0.410843164, + -0.405241311, -0.399624199, -0.393992037, -0.388345033, + -0.382683426, -0.377007425, -0.371317208, -0.365612984, + -0.359895051, -0.354163527, -0.348418683, -0.342660725, + -0.336889863, -0.331106305, -0.325310290, -0.319502026, + -0.313681751, -0.307849646, -0.302005947, -0.296150893, + -0.290284663, -0.284407526, -0.278519690, -0.272621363, + -0.266712755, -0.260794103, -0.254865646, -0.248927608, + -0.242980182, -0.237023607, -0.231058106, -0.225083917, + -0.219101235, -0.213110313, -0.207111374, -0.201104641, + -0.195090324, -0.189068660, -0.183039889, -0.177004218, + -0.170961887, -0.164913118, -0.158858150, -0.152797192, + -0.146730468, -0.140658244, -0.134580702, -0.128498107, + -0.122410677, -0.116318628, -0.110222206, -0.104121633, + -0.098017141, -0.091908954, -0.085797310, -0.079682440, + -0.073564567, -0.067443922, -0.061320737, -0.055195246, + -0.049067676, -0.042938258, -0.036807224, -0.030674804, + -0.024541229, -0.018406730, -0.012271538, -0.006135885, + -0.000000000, 0.006135885, 0.012271538, 0.018406730, + 0.024541229, 0.030674804, 0.036807224, 0.042938258, + 0.049067676, 0.055195246, 0.061320737, 0.067443922, + 0.073564567, 0.079682440, 0.085797310, 0.091908954, + 0.098017141, 0.104121633, 0.110222206, 0.116318628, + 0.122410677, 0.128498107, 0.134580702, 0.140658244, + 0.146730468, 0.152797192, 0.158858150, 0.164913118, + 0.170961887, 0.177004218, 0.183039889, 0.189068660, + 0.195090324, 0.201104641, 0.207111374, 0.213110313, + 0.219101235, 0.225083917, 0.231058106, 0.237023607, + 0.242980182, 0.248927608, 0.254865646, 0.260794103, + 0.266712755, 0.272621363, 0.278519690, 0.284407526, + 0.290284663, 0.296150893, 0.302005947, 0.307849646, + 0.313681751, 0.319502026, 0.325310290, 0.331106305, + 0.336889863, 0.342660725, 0.348418683, 0.354163527, + 0.359895051, 0.365612984, 0.371317208, 0.377007425, + 0.382683426, 0.388345033, 0.393992037, 0.399624199, + 0.405241311, 0.410843164, 0.416429549, 0.422000259, + 0.427555084, 0.433093816, 0.438616246, 0.444122136, + 0.449611336, 0.455083579, 0.460538715, 0.465976506, + 0.471396744, 0.476799220, 0.482183784, 0.487550169, + 0.492898196, 0.498227656, 0.503538370, 0.508830130, + 0.514102757, 0.519356012, 0.524589658, 0.529803634, + 0.534997642, 0.540171444, 0.545324981, 0.550457954, + 0.555570245, 0.560661554, 0.565731823, 0.570780754, + 0.575808167, 0.580813944, 0.585797846, 0.590759695, + 0.595699310, 0.600616455, 0.605511069, 0.610382795, + 0.615231574, 0.620057225, 0.624859512, 0.629638255, + 0.634393275, 0.639124453, 0.643831551, 0.648514390, + 0.653172851, 0.657806695, 0.662415802, 0.666999936, + 0.671558976, 0.676092684, 0.680601001, 0.685083687, + 0.689540565, 0.693971455, 0.698376238, 0.702754736, + 0.707106769, 0.711432219, 0.715730846, 0.720002532, + 0.724247098, 0.728464365, 0.732654274, 0.736816585, + 0.740951121, 0.745057762, 0.749136388, 0.753186822, + 0.757208824, 0.761202395, 0.765167236, 0.769103348, + 0.773010433, 0.776888490, 0.780737221, 0.784556568, + 0.788346410, 0.792106569, 0.795836926, 0.799537241, + 0.803207517, 0.806847572, 0.810457170, 0.814036310, + 0.817584813, 0.821102500, 0.824589312, 0.828045070, + 0.831469595, 0.834862888, 0.838224709, 0.841554999, + 0.844853580, 0.848120332, 0.851355195, 0.854557991, + 0.857728601, 0.860866964, 0.863972843, 0.867046237, + 0.870086968, 0.873094976, 0.876070082, 0.879012227, + 0.881921291, 0.884797096, 0.887639642, 0.890448749, + 0.893224299, 0.895966232, 0.898674488, 0.901348829, + 0.903989315, 0.906595707, 0.909168005, 0.911706030, + 0.914209783, 0.916679084, 0.919113874, 0.921514034, + 0.923879504, 0.926210225, 0.928506076, 0.930766940, + 0.932992816, 0.935183525, 0.937339008, 0.939459205, + 0.941544056, 0.943593442, 0.945607305, 0.947585583, + 0.949528158, 0.951435030, 0.953306019, 0.955141187, + 0.956940353, 0.958703458, 0.960430503, 0.962121427, + 0.963776052, 0.965394437, 0.966976464, 0.968522072, + 0.970031261, 0.971503913, 0.972939968, 0.974339366, + 0.975702107, 0.977028131, 0.978317380, 0.979569793, + 0.980785251, 0.981963873, 0.983105481, 0.984210074, + 0.985277653, 0.986308098, 0.987301409, 0.988257587, + 0.989176512, 0.990058184, 0.990902662, 0.991709769, + 0.992479563, 0.993211925, 0.993906975, 0.994564593, + 0.995184720, 0.995767415, 0.996312618, 0.996820271, + 0.997290432, 0.997723043, 0.998118103, 0.998475552, + 0.998795450, 0.999077737, 0.999322355, 0.999529421, + 0.999698818, 0.999830604, 0.999924719, 0.999981165 +}; diff --git a/sw/ground_segment/multimon/costabi.c b/sw/ground_segment/multimon/costabi.c new file mode 100644 index 0000000000..e0139aecd3 --- /dev/null +++ b/sw/ground_segment/multimon/costabi.c @@ -0,0 +1,134 @@ +/* + * This file is machine generated, DO NOT EDIT! + */ + +int costabi[1024] = { + 32767, 32766, 32764, 32761, 32757, 32751, 32744, 32736, + 32727, 32717, 32705, 32692, 32678, 32662, 32646, 32628, + 32609, 32588, 32567, 32544, 32520, 32495, 32468, 32441, + 32412, 32382, 32350, 32318, 32284, 32249, 32213, 32176, + 32137, 32097, 32056, 32014, 31970, 31926, 31880, 31833, + 31785, 31735, 31684, 31633, 31580, 31525, 31470, 31413, + 31356, 31297, 31236, 31175, 31113, 31049, 30984, 30918, + 30851, 30783, 30713, 30643, 30571, 30498, 30424, 30349, + 30272, 30195, 30116, 30036, 29955, 29873, 29790, 29706, + 29621, 29534, 29446, 29358, 29268, 29177, 29085, 28992, + 28897, 28802, 28706, 28608, 28510, 28410, 28309, 28208, + 28105, 28001, 27896, 27790, 27683, 27575, 27466, 27355, + 27244, 27132, 27019, 26905, 26789, 26673, 26556, 26437, + 26318, 26198, 26077, 25954, 25831, 25707, 25582, 25456, + 25329, 25201, 25072, 24942, 24811, 24679, 24546, 24413, + 24278, 24143, 24006, 23869, 23731, 23592, 23452, 23311, + 23169, 23027, 22883, 22739, 22594, 22448, 22301, 22153, + 22004, 21855, 21705, 21554, 21402, 21249, 21096, 20942, + 20787, 20631, 20474, 20317, 20159, 20000, 19840, 19680, + 19519, 19357, 19194, 19031, 18867, 18702, 18537, 18371, + 18204, 18036, 17868, 17699, 17530, 17360, 17189, 17017, + 16845, 16672, 16499, 16325, 16150, 15975, 15799, 15623, + 15446, 15268, 15090, 14911, 14732, 14552, 14372, 14191, + 14009, 13827, 13645, 13462, 13278, 13094, 12909, 12724, + 12539, 12353, 12166, 11980, 11792, 11604, 11416, 11227, + 11038, 10849, 10659, 10469, 10278, 10087, 9895, 9703, + 9511, 9319, 9126, 8932, 8739, 8545, 8351, 8156, + 7961, 7766, 7571, 7375, 7179, 6982, 6786, 6589, + 6392, 6195, 5997, 5799, 5601, 5403, 5205, 5006, + 4807, 4608, 4409, 4210, 4011, 3811, 3611, 3411, + 3211, 3011, 2811, 2610, 2410, 2209, 2009, 1808, + 1607, 1406, 1206, 1005, 804, 603, 402, 201, + 0, -201, -402, -603, -804, -1005, -1206, -1406, + -1607, -1808, -2009, -2209, -2410, -2610, -2811, -3011, + -3211, -3411, -3611, -3811, -4011, -4210, -4409, -4608, + -4807, -5006, -5205, -5403, -5601, -5799, -5997, -6195, + -6392, -6589, -6786, -6982, -7179, -7375, -7571, -7766, + -7961, -8156, -8351, -8545, -8739, -8932, -9126, -9319, + -9511, -9703, -9895, -10087, -10278, -10469, -10659, -10849, + -11038, -11227, -11416, -11604, -11792, -11980, -12166, -12353, + -12539, -12724, -12909, -13094, -13278, -13462, -13645, -13827, + -14009, -14191, -14372, -14552, -14732, -14911, -15090, -15268, + -15446, -15623, -15799, -15975, -16150, -16325, -16499, -16672, + -16845, -17017, -17189, -17360, -17530, -17699, -17868, -18036, + -18204, -18371, -18537, -18702, -18867, -19031, -19194, -19357, + -19519, -19680, -19840, -20000, -20159, -20317, -20474, -20631, + -20787, -20942, -21096, -21249, -21402, -21554, -21705, -21855, + -22004, -22153, -22301, -22448, -22594, -22739, -22883, -23027, + -23169, -23311, -23452, -23592, -23731, -23869, -24006, -24143, + -24278, -24413, -24546, -24679, -24811, -24942, -25072, -25201, + -25329, -25456, -25582, -25707, -25831, -25954, -26077, -26198, + -26318, -26437, -26556, -26673, -26789, -26905, -27019, -27132, + -27244, -27355, -27466, -27575, -27683, -27790, -27896, -28001, + -28105, -28208, -28309, -28410, -28510, -28608, -28706, -28802, + -28897, -28992, -29085, -29177, -29268, -29358, -29446, -29534, + -29621, -29706, -29790, -29873, -29955, -30036, -30116, -30195, + -30272, -30349, -30424, -30498, -30571, -30643, -30713, -30783, + -30851, -30918, -30984, -31049, -31113, -31175, -31236, -31297, + -31356, -31413, -31470, -31525, -31580, -31633, -31684, -31735, + -31785, -31833, -31880, -31926, -31970, -32014, -32056, -32097, + -32137, -32176, -32213, -32249, -32284, -32318, -32350, -32382, + -32412, -32441, -32468, -32495, -32520, -32544, -32567, -32588, + -32609, -32628, -32646, -32662, -32678, -32692, -32705, -32717, + -32727, -32736, -32744, -32751, -32757, -32761, -32764, -32766, + -32767, -32766, -32764, -32761, -32757, -32751, -32744, -32736, + -32727, -32717, -32705, -32692, -32678, -32662, -32646, -32628, + -32609, -32588, -32567, -32544, -32520, -32495, -32468, -32441, + -32412, -32382, -32350, -32318, -32284, -32249, -32213, -32176, + -32137, -32097, -32056, -32014, -31970, -31926, -31880, -31833, + -31785, -31735, -31684, -31633, -31580, -31525, -31470, -31413, + -31356, -31297, -31236, -31175, -31113, -31049, -30984, -30918, + -30851, -30783, -30713, -30643, -30571, -30498, -30424, -30349, + -30272, -30195, -30116, -30036, -29955, -29873, -29790, -29706, + -29621, -29534, -29446, -29358, -29268, -29177, -29085, -28992, + -28897, -28802, -28706, -28608, -28510, -28410, -28309, -28208, + -28105, -28001, -27896, -27790, -27683, -27575, -27466, -27355, + -27244, -27132, -27019, -26905, -26789, -26673, -26556, -26437, + -26318, -26198, -26077, -25954, -25831, -25707, -25582, -25456, + -25329, -25201, -25072, -24942, -24811, -24679, -24546, -24413, + -24278, -24143, -24006, -23869, -23731, -23592, -23452, -23311, + -23169, -23027, -22883, -22739, -22594, -22448, -22301, -22153, + -22004, -21855, -21705, -21554, -21402, -21249, -21096, -20942, + -20787, -20631, -20474, -20317, -20159, -20000, -19840, -19680, + -19519, -19357, -19194, -19031, -18867, -18702, -18537, -18371, + -18204, -18036, -17868, -17699, -17530, -17360, -17189, -17017, + -16845, -16672, -16499, -16325, -16150, -15975, -15799, -15623, + -15446, -15268, -15090, -14911, -14732, -14552, -14372, -14191, + -14009, -13827, -13645, -13462, -13278, -13094, -12909, -12724, + -12539, -12353, -12166, -11980, -11792, -11604, -11416, -11227, + -11038, -10849, -10659, -10469, -10278, -10087, -9895, -9703, + -9511, -9319, -9126, -8932, -8739, -8545, -8351, -8156, + -7961, -7766, -7571, -7375, -7179, -6982, -6786, -6589, + -6392, -6195, -5997, -5799, -5601, -5403, -5205, -5006, + -4807, -4608, -4409, -4210, -4011, -3811, -3611, -3411, + -3211, -3011, -2811, -2610, -2410, -2209, -2009, -1808, + -1607, -1406, -1206, -1005, -804, -603, -402, -201, + 0, 201, 402, 603, 804, 1005, 1206, 1406, + 1607, 1808, 2009, 2209, 2410, 2610, 2811, 3011, + 3211, 3411, 3611, 3811, 4011, 4210, 4409, 4608, + 4807, 5006, 5205, 5403, 5601, 5799, 5997, 6195, + 6392, 6589, 6786, 6982, 7179, 7375, 7571, 7766, + 7961, 8156, 8351, 8545, 8739, 8932, 9126, 9319, + 9511, 9703, 9895, 10087, 10278, 10469, 10659, 10849, + 11038, 11227, 11416, 11604, 11792, 11980, 12166, 12353, + 12539, 12724, 12909, 13094, 13278, 13462, 13645, 13827, + 14009, 14191, 14372, 14552, 14732, 14911, 15090, 15268, + 15446, 15623, 15799, 15975, 16150, 16325, 16499, 16672, + 16845, 17017, 17189, 17360, 17530, 17699, 17868, 18036, + 18204, 18371, 18537, 18702, 18867, 19031, 19194, 19357, + 19519, 19680, 19840, 20000, 20159, 20317, 20474, 20631, + 20787, 20942, 21096, 21249, 21402, 21554, 21705, 21855, + 22004, 22153, 22301, 22448, 22594, 22739, 22883, 23027, + 23169, 23311, 23452, 23592, 23731, 23869, 24006, 24143, + 24278, 24413, 24546, 24679, 24811, 24942, 25072, 25201, + 25329, 25456, 25582, 25707, 25831, 25954, 26077, 26198, + 26318, 26437, 26556, 26673, 26789, 26905, 27019, 27132, + 27244, 27355, 27466, 27575, 27683, 27790, 27896, 28001, + 28105, 28208, 28309, 28410, 28510, 28608, 28706, 28802, + 28897, 28992, 29085, 29177, 29268, 29358, 29446, 29534, + 29621, 29706, 29790, 29873, 29955, 30036, 30116, 30195, + 30272, 30349, 30424, 30498, 30571, 30643, 30713, 30783, + 30851, 30918, 30984, 31049, 31113, 31175, 31236, 31297, + 31356, 31413, 31470, 31525, 31580, 31633, 31684, 31735, + 31785, 31833, 31880, 31926, 31970, 32014, 32056, 32097, + 32137, 32176, 32213, 32249, 32284, 32318, 32350, 32382, + 32412, 32441, 32468, 32495, 32520, 32544, 32567, 32588, + 32609, 32628, 32646, 32662, 32678, 32692, 32705, 32717, + 32727, 32736, 32744, 32751, 32757, 32761, 32764, 32766 +}; diff --git a/sw/ground_segment/multimon/demod_afsk12.c b/sw/ground_segment/multimon/demod_afsk12.c new file mode 100644 index 0000000000..82b5fb12ba --- /dev/null +++ b/sw/ground_segment/multimon/demod_afsk12.c @@ -0,0 +1,128 @@ +/* + * demod_afsk12.c -- 1200 baud AFSK demodulator + * + * Copyright (C) 1996 + * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* ---------------------------------------------------------------------- */ + +#include "multimon.h" +#include "filter.h" +#include +#include + +/* ---------------------------------------------------------------------- */ + +/* + * Standard TCM3105 clock frequency: 4.4336MHz + * Mark frequency: 2200 Hz + * Space frequency: 1200 Hz + */ + +#define FREQ_MARK 1200 +#define FREQ_SPACE 2200 +#define FREQ_SAMP 22050 +#define BAUD 1200 +#define SUBSAMP 2 + +/* ---------------------------------------------------------------------- */ + +#define CORRLEN ((int)(FREQ_SAMP/BAUD)) +#define SPHASEINC (0x10000u*BAUD*SUBSAMP/FREQ_SAMP) + +static float corr_mark_i[CORRLEN]; +static float corr_mark_q[CORRLEN]; +static float corr_space_i[CORRLEN]; +static float corr_space_q[CORRLEN]; + +/* ---------------------------------------------------------------------- */ + +static void afsk12_init(struct demod_state *s) +{ + float f; + int i; + + hdlc_init(s); + memset(&s->l1.afsk12, 0, sizeof(s->l1.afsk12)); + for (f = 0, i = 0; i < CORRLEN; i++) { + corr_mark_i[i] = cos(f); + corr_mark_q[i] = sin(f); + f += 2.0*M_PI*FREQ_MARK/FREQ_SAMP; + } + for (f = 0, i = 0; i < CORRLEN; i++) { + corr_space_i[i] = cos(f); + corr_space_q[i] = sin(f); + f += 2.0*M_PI*FREQ_SPACE/FREQ_SAMP; + } +} + +/* ---------------------------------------------------------------------- */ + +static void afsk12_demod(struct demod_state *s, float *buffer, int length) +{ + float f; + unsigned char curbit; + + if (s->l1.afsk12.subsamp) { + int numfill = SUBSAMP - s->l1.afsk12.subsamp; + if (length < numfill) { + s->l1.afsk12.subsamp += length; + return; + } + buffer += numfill; + length -= numfill; + s->l1.afsk12.subsamp = 0; + } + for (; length >= SUBSAMP; length -= SUBSAMP, buffer += SUBSAMP) { + f = fsqr(mac(buffer, corr_mark_i, CORRLEN)) + + fsqr(mac(buffer, corr_mark_q, CORRLEN)) - + fsqr(mac(buffer, corr_space_i, CORRLEN)) - + fsqr(mac(buffer, corr_space_q, CORRLEN)); + s->l1.afsk12.dcd_shreg <<= 1; + s->l1.afsk12.dcd_shreg |= (f > 0); + verbprintf(10, "%c", '0'+(s->l1.afsk12.dcd_shreg & 1)); + /* + * check if transition + */ + if ((s->l1.afsk12.dcd_shreg ^ (s->l1.afsk12.dcd_shreg >> 1)) & 1) { + if (s->l1.afsk12.sphase < (0x8000u-(SPHASEINC/2))) + s->l1.afsk12.sphase += SPHASEINC/8; + else + s->l1.afsk12.sphase -= SPHASEINC/8; + } + s->l1.afsk12.sphase += SPHASEINC; + if (s->l1.afsk12.sphase >= 0x10000u) { + s->l1.afsk12.sphase &= 0xffffu; + s->l1.afsk12.lasts <<= 1; + s->l1.afsk12.lasts |= s->l1.afsk12.dcd_shreg & 1; + curbit = (s->l1.afsk12.lasts ^ + (s->l1.afsk12.lasts >> 1) ^ 1) & 1; + verbprintf(9, " %c ", '0'+curbit); + hdlc_rxbit(s, curbit); + } + } + s->l1.afsk12.subsamp = length; +} + +/* ---------------------------------------------------------------------- */ + +const struct demod_param demod_afsk1200 = { + "AFSK1200", FREQ_SAMP, CORRLEN, afsk12_init, afsk12_demod +}; + +/* ---------------------------------------------------------------------- */ diff --git a/sw/ground_segment/multimon/demod_afsk24.c b/sw/ground_segment/multimon/demod_afsk24.c new file mode 100644 index 0000000000..f818eebc25 --- /dev/null +++ b/sw/ground_segment/multimon/demod_afsk24.c @@ -0,0 +1,125 @@ +/* + * demod_afsk24.c -- 2400 baud AFSK demodulator + * + * Copyright (C) 1996 + * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* ---------------------------------------------------------------------- */ + +#include "multimon.h" +#include "filter.h" +#include +#include + +/* ---------------------------------------------------------------------- */ + +/* + * Standard TCM3105 clock frequency: 4.4336MHz + * Xtal used: 8 MHz + * Ratio: 1.8044 + * Mark frequency: 3970 Hz + * Space frequency: 2165 Hz + */ + +#define FREQ_MARK 3970 +#define FREQ_SPACE 2165 +#define FREQ_SAMP 22050 +#define BAUD 2400 + +/* ---------------------------------------------------------------------- */ + +#define CORRLEN (2*(int)(FREQ_SAMP/BAUD)) +#define SPHASEINC (0x10000u*BAUD/FREQ_SAMP) + +static float corr_mark_i[CORRLEN]; +static float corr_mark_q[CORRLEN]; +static float corr_space_i[CORRLEN]; +static float corr_space_q[CORRLEN]; + +/* ---------------------------------------------------------------------- */ + +static void afsk24_init(struct demod_state *s) +{ + float f; + int i; + + hdlc_init(s); + memset(&s->l1.afsk24, 0, sizeof(s->l1.afsk24)); + for (f = 0, i = 0; i < CORRLEN; i++) { + corr_mark_i[i] = cos(f); + corr_mark_q[i] = sin(f); + f += 2.0*M_PI*FREQ_MARK/FREQ_SAMP; + } + for (f = 0, i = 0; i < CORRLEN; i++) { + corr_space_i[i] = cos(f); + corr_space_q[i] = sin(f); + f += 2.0*M_PI*FREQ_SPACE/FREQ_SAMP; + } + for (i = 0; i < CORRLEN; i++) { + f = 0.54 - 0.46*cos(2*M_PI*i/(float)(CORRLEN-1)); + corr_mark_i[i] *= f; + corr_mark_q[i] *= f; + corr_space_i[i] *= f; + corr_space_q[i] *= f; + } +} + +/* ---------------------------------------------------------------------- */ + +static void afsk24_demod(struct demod_state *s, float *buffer, int length) +{ + float f; + unsigned char curbit; + + for (; length > 0; length--, buffer++) { + f = fsqr(mac(buffer, corr_mark_i, CORRLEN)) + + fsqr(mac(buffer, corr_mark_q, CORRLEN)) - + fsqr(mac(buffer, corr_space_i, CORRLEN)) - + fsqr(mac(buffer, corr_space_q, CORRLEN)); + s->l1.afsk24.dcd_shreg <<= 1; + s->l1.afsk24.dcd_shreg |= (f > 0); + verbprintf(10, "%c", '0'+(s->l1.afsk24.dcd_shreg & 1)); + /* + * check if transition + */ + if ((s->l1.afsk24.dcd_shreg ^ (s->l1.afsk24.dcd_shreg >> 1)) & 1) { + if (s->l1.afsk24.sphase < (0x8000u-(SPHASEINC/2))) + s->l1.afsk24.sphase += SPHASEINC/8; + else + s->l1.afsk24.sphase -= SPHASEINC/8; + } + s->l1.afsk24.sphase += SPHASEINC; + if (s->l1.afsk24.sphase >= 0x10000u) { + s->l1.afsk24.sphase &= 0xffffu; + s->l1.afsk24.lasts <<= 1; + s->l1.afsk24.lasts |= s->l1.afsk24.dcd_shreg & 1; + curbit = (s->l1.afsk24.lasts ^ + (s->l1.afsk24.lasts >> 1) ^ 1) & 1; + verbprintf(9, " %c ", '0'+curbit); + hdlc_rxbit(s, curbit); + } + } +} + +/* ---------------------------------------------------------------------- */ + +const struct demod_param demod_afsk2400 = { + "AFSK2400", FREQ_SAMP, CORRLEN, afsk24_init, afsk24_demod +}; + +/* ---------------------------------------------------------------------- */ diff --git a/sw/ground_segment/multimon/demod_afsk24_2.c b/sw/ground_segment/multimon/demod_afsk24_2.c new file mode 100644 index 0000000000..37260a89dc --- /dev/null +++ b/sw/ground_segment/multimon/demod_afsk24_2.c @@ -0,0 +1,125 @@ +/* + * demod_afsk24.c -- 2400 baud AFSK demodulator + * + * Copyright (C) 1996 + * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* ---------------------------------------------------------------------- */ + +#include "multimon.h" +#include "filter.h" +#include +#include + +/* ---------------------------------------------------------------------- */ + +/* + * Standard TCM3105 clock frequency: 4.4336MHz + * Xtal used: 7.3728 MHz + * Ratio: 1.6629 + * Mark frequency: 3658 Hz + * Space frequency: 1996 Hz + */ + +#define FREQ_MARK 3658 +#define FREQ_SPACE 1996 +#define FREQ_SAMP 22050 +#define BAUD 2400 + +/* ---------------------------------------------------------------------- */ + +#define CORRLEN ((int)(2*FREQ_SAMP/BAUD)) +#define SPHASEINC (0x10000u*BAUD/FREQ_SAMP) + +static float corr_mark_i[CORRLEN]; +static float corr_mark_q[CORRLEN]; +static float corr_space_i[CORRLEN]; +static float corr_space_q[CORRLEN]; + +/* ---------------------------------------------------------------------- */ + +static void afsk24_2_init(struct demod_state *s) +{ + float f; + int i; + + hdlc_init(s); + memset(&s->l1.afsk24, 0, sizeof(s->l1.afsk24)); + for (f = 0, i = 0; i < CORRLEN; i++) { + corr_mark_i[i] = cos(f); + corr_mark_q[i] = sin(f); + f += 2.0*M_PI*FREQ_MARK/FREQ_SAMP; + } + for (f = 0, i = 0; i < CORRLEN; i++) { + corr_space_i[i] = cos(f); + corr_space_q[i] = sin(f); + f += 2.0*M_PI*FREQ_SPACE/FREQ_SAMP; + } + for (i = 0; i < CORRLEN; i++) { + f = 0.54 - 0.46*cos(2*M_PI*i/(float)(CORRLEN-1)); + corr_mark_i[i] *= f; + corr_mark_q[i] *= f; + corr_space_i[i] *= f; + corr_space_q[i] *= f; + } +} + +/* ---------------------------------------------------------------------- */ + +static void afsk24_2_demod(struct demod_state *s, float *buffer, int length) +{ + float f; + unsigned char curbit; + + for (; length > 0; length--, buffer++) { + f = fsqr(mac(buffer, corr_mark_i, CORRLEN)) + + fsqr(mac(buffer, corr_mark_q, CORRLEN)) - + fsqr(mac(buffer, corr_space_i, CORRLEN)) - + fsqr(mac(buffer, corr_space_q, CORRLEN)); + s->l1.afsk24.dcd_shreg <<= 1; + s->l1.afsk24.dcd_shreg |= (f > 0); + verbprintf(10, "%c", '0'+(s->l1.afsk24.dcd_shreg & 1)); + /* + * check if transition + */ + if ((s->l1.afsk24.dcd_shreg ^ (s->l1.afsk24.dcd_shreg >> 1)) & 1) { + if (s->l1.afsk24.sphase < (0x8000u-(SPHASEINC/2))) + s->l1.afsk24.sphase += SPHASEINC/8; + else + s->l1.afsk24.sphase -= SPHASEINC/8; + } + s->l1.afsk24.sphase += SPHASEINC; + if (s->l1.afsk24.sphase >= 0x10000u) { + s->l1.afsk24.sphase &= 0xffffu; + s->l1.afsk24.lasts <<= 1; + s->l1.afsk24.lasts |= s->l1.afsk24.dcd_shreg & 1; + curbit = (s->l1.afsk24.lasts ^ + (s->l1.afsk24.lasts >> 1) ^ 1) & 1; + verbprintf(9, " %c ", '0'+curbit); + hdlc_rxbit(s, curbit); + } + } +} + +/* ---------------------------------------------------------------------- */ + +const struct demod_param demod_afsk2400_2 = { + "AFSK2400_2", FREQ_SAMP, CORRLEN, afsk24_2_init, afsk24_2_demod +}; + +/* ---------------------------------------------------------------------- */ diff --git a/sw/ground_segment/multimon/demod_display.c b/sw/ground_segment/multimon/demod_display.c new file mode 100644 index 0000000000..85ed08fa4f --- /dev/null +++ b/sw/ground_segment/multimon/demod_display.c @@ -0,0 +1,86 @@ +/* + * demod_display.c -- signal display + * + * Copyright (C) 1996 + * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* ---------------------------------------------------------------------- */ + +#include "multimon.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* ---------------------------------------------------------------------- */ + +#define SAMPLING_RATE 22050 + +/* ---------------------------------------------------------------------- */ + +static void scope_init(struct demod_state *s) +{ + memset(&s->l1.scope, 0, sizeof(s->l1.scope)); + s->l1.scope.dispnum = xdisp_start(); + if (s->l1.scope.dispnum == -1) + return; +} + +/* ---------------------------------------------------------------------- */ + +#define MEMSIZE sizeof(s->l1.scope.data)/sizeof(s->l1.scope.data[0]) + +static void scope_demod(struct demod_state *s, float *buffer, int length) +{ + float *src, *dst; + int i, j; + + if (s->l1.scope.dispnum == -1) + return; + if (length >= MEMSIZE) { + src = buffer+length-MEMSIZE; + dst = s->l1.scope.data; + i = MEMSIZE; + } else { + i = MEMSIZE-length; + memmove(s->l1.scope.data, s->l1.scope.data+i, + i*sizeof(s->l1.scope.data[0])); + src = buffer; + dst = s->l1.scope.data+i; + i = length; + } + s->l1.scope.datalen += i; + memcpy(dst, src, i*sizeof(s->l1.scope.data[0])); + if (s->l1.scope.datalen < MEMSIZE) + return; + if (xdisp_update(s->l1.scope.dispnum, s->l1.scope.data)) + s->l1.scope.datalen = 0; +} + +/* ---------------------------------------------------------------------- */ + +const struct demod_param demod_scope = { + "SCOPE", SAMPLING_RATE, 0, scope_init, scope_demod +}; + +/* ---------------------------------------------------------------------- */ diff --git a/sw/ground_segment/multimon/demod_dtmf.c b/sw/ground_segment/multimon/demod_dtmf.c new file mode 100644 index 0000000000..d4fabecfb0 --- /dev/null +++ b/sw/ground_segment/multimon/demod_dtmf.c @@ -0,0 +1,151 @@ +/* + * demod_dtmf.c -- DTMF signalling demodulator/decoder + * + * Copyright (C) 1996 + * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* ---------------------------------------------------------------------- */ + +#include "multimon.h" +#include "filter.h" +#include +#include + +/* ---------------------------------------------------------------------- */ + +/* + * + * DTMF frequencies + * + * 1209 1336 1477 1633 + * 697 1 2 3 A + * 770 4 5 6 B + * 852 7 8 9 C + * 941 * 0 # D + * + */ + +#define SAMPLE_RATE 22050 +#define BLOCKLEN (SAMPLE_RATE/100) /* 10ms blocks */ +#define BLOCKNUM 4 /* must match numbers in multimon.h */ + +#define PHINC(x) ((x)*0x10000/SAMPLE_RATE) + +static const char *dtmf_transl = "123A456B789C*0#D"; + +static const unsigned int dtmf_phinc[8] = { + PHINC(1209), PHINC(1336), PHINC(1477), PHINC(1633), + PHINC(697), PHINC(770), PHINC(852), PHINC(941) +}; + +/* ---------------------------------------------------------------------- */ + +static void dtmf_init(struct demod_state *s) +{ + memset(&s->l1.dtmf, 0, sizeof(s->l1.dtmf)); +} + +/* ---------------------------------------------------------------------- */ + +static int find_max_idx(const float *f) +{ + float en = 0; + int idx = -1, i; + + for (i = 0; i < 4; i++) + if (f[i] > en) { + en = f[i]; + idx = i; + } + if (idx < 0) + return -1; + en *= 0.1; + for (i = 0; i < 4; i++) + if (idx != i && f[i] > en) + return -1; + return idx; +} + +/* ---------------------------------------------------------------------- */ + +static inline int process_block(struct demod_state *s) +{ + float tote; + float totte[16]; + int i, j; + + tote = 0; + for (i = 0; i < BLOCKNUM; i++) + tote += s->l1.dtmf.energy[i]; + for (i = 0; i < 16; i++) { + totte[i] = 0; + for (j = 0; j < BLOCKNUM; j++) + totte[i] += s->l1.dtmf.tenergy[j][i]; + } + for (i = 0; i < 8; i++) + totte[i] = fsqr(totte[i]) + fsqr(totte[i+8]); + memmove(s->l1.dtmf.energy+1, s->l1.dtmf.energy, + sizeof(s->l1.dtmf.energy) - sizeof(s->l1.dtmf.energy[0])); + s->l1.dtmf.energy[0] = 0; + memmove(s->l1.dtmf.tenergy+1, s->l1.dtmf.tenergy, + sizeof(s->l1.dtmf.tenergy) - sizeof(s->l1.dtmf.tenergy[0])); + memset(s->l1.dtmf.tenergy, 0, sizeof(s->l1.dtmf.tenergy[0])); + tote *= (BLOCKNUM*BLOCKLEN*0.5); /* adjust for block lengths */ + verbprintf(10, "DTMF: Energies: %8.5f %8.5f %8.5f %8.5f %8.5f %8.5f %8.5f %8.5f %8.5f\n", + tote, totte[0], totte[1], totte[2], totte[3], totte[4], totte[5], totte[6], totte[7]); + if ((i = find_max_idx(totte)) < 0) + return -1; + if ((j = find_max_idx(totte+4)) < 0) + return -1; + if ((tote * 0.4) > (totte[i] + totte[j+4])) + return -1; + return (i & 3) | ((j << 2) & 0xc); +} + +/* ---------------------------------------------------------------------- */ + +static void dtmf_demod(struct demod_state *s, float *buffer, int length) +{ + float s_in; + int i; + + for (; length > 0; length--, buffer++) { + s_in = *buffer; + s->l1.dtmf.energy[0] += fsqr(s_in); + for (i = 0; i < 8; i++) { + s->l1.dtmf.tenergy[0][i] += COS(s->l1.dtmf.ph[i]) * s_in; + s->l1.dtmf.tenergy[0][i+8] += SIN(s->l1.dtmf.ph[i]) * s_in; + s->l1.dtmf.ph[i] += dtmf_phinc[i]; + } + if ((s->l1.dtmf.blkcount--) <= 0) { + s->l1.dtmf.blkcount = BLOCKLEN; + i = process_block(s); + if (i != s->l1.dtmf.lastch && i >= 0) + verbprintf(0, "DTMF: %c\n", dtmf_transl[i]); + s->l1.dtmf.lastch = i; + } + } +} + +/* ---------------------------------------------------------------------- */ + +const struct demod_param demod_dtmf = { + "DTMF", SAMPLE_RATE, 0, dtmf_init, dtmf_demod +}; + +/* ---------------------------------------------------------------------- */ diff --git a/sw/ground_segment/multimon/demod_fsk96.c b/sw/ground_segment/multimon/demod_fsk96.c new file mode 100644 index 0000000000..2238321398 --- /dev/null +++ b/sw/ground_segment/multimon/demod_fsk96.c @@ -0,0 +1,128 @@ +/* + * demod_fsk96.c -- FSK 9600 baud demodulator (G3RUH) + * + * Copyright (C) 1996 + * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* ---------------------------------------------------------------------- */ + +#include "multimon.h" +#include "filter.h" +#include +#include + +/* ---------------------------------------------------------------------- */ + +#define FREQ_SAMP 22050 +#define BAUD 9600 + +/* ---------------------------------------------------------------------- */ + +#define DESCRAM_TAP1 0x20000 +#define DESCRAM_TAP2 0x01000 +#define DESCRAM_TAP3 0x00001 + +#define DESCRAM_TAPSH1 17 +#define DESCRAM_TAPSH2 12 +#define DESCRAM_TAPSH3 0 + +#define SCRAM_TAP1 0x20000 /* X^17 */ +#define SCRAM_TAPN 0x00021 /* X^0+X^5 */ + +/* --------------------------------------------------------------------- */ + +#define FILTLEN 24 +#define UPSAMP 3 + +static const float inp_filt[3][24] = { + { 0.000440, -0.001198, -0.000493, 0.003648, + -0.000630, -0.008433, 0.005567, 0.015557, + -0.019931, -0.026514, 0.079822, 0.181779, + 0.124956, -0.002471, -0.032062, 0.008024, + 0.012568, -0.006559, -0.004235, 0.003711, + 0.000909, -0.001520, -0.000018, 0.000709}, + { 0.000686, -0.000618, -0.001332, 0.002494, + 0.002258, -0.007308, -0.001538, 0.016708, + -0.004897, -0.035748, 0.034724, 0.161417, + 0.161417, 0.034724, -0.035748, -0.004897, + 0.016708, -0.001538, -0.007308, 0.002258, + 0.002494, -0.001332, -0.000618, 0.000686}, + { 0.000709, -0.000018, -0.001520, 0.000909, + 0.003711, -0.004235, -0.006559, 0.012568, + 0.008024, -0.032062, -0.002471, 0.124956, + 0.181779, 0.079822, -0.026514, -0.019931, + 0.015557, 0.005567, -0.008433, -0.000630, + 0.003648, -0.000493, -0.001198, 0.000440} +}; + +#define SPHASEINC (0x10000u*BAUD/FREQ_SAMP/UPSAMP) + +/* ---------------------------------------------------------------------- */ + +static void fsk96_init(struct demod_state *s) +{ + hdlc_init(s); + memset(&s->l1.fsk96, 0, sizeof(s->l1.fsk96)); +} + +/* ---------------------------------------------------------------------- */ + +static void fsk96_demod(struct demod_state *s, float *buffer, int length) +{ + float f; + unsigned char curbit; + int i; + unsigned int descx; + + for (; length > 0; length--, buffer++) { + for (i = 0; i < UPSAMP; i++) { + f = mac(buffer, inp_filt[i], FILTLEN); + s->l1.fsk96.dcd_shreg <<= 1; + s->l1.fsk96.dcd_shreg |= (f > 0); + verbprintf(10, "%c", '0'+(s->l1.fsk96.dcd_shreg & 1)); + /* + * check if transition + */ + if ((s->l1.fsk96.dcd_shreg ^ (s->l1.fsk96.dcd_shreg >> 1)) & 1) { + if (s->l1.fsk96.sphase < (0x8000u-(SPHASEINC/2))) + s->l1.fsk96.sphase += SPHASEINC/8; + else + s->l1.fsk96.sphase -= SPHASEINC/8; + } + s->l1.fsk96.sphase += SPHASEINC; + if (s->l1.fsk96.sphase >= 0x10000u) { + s->l1.fsk96.sphase &= 0xffffu; + s->l1.fsk96.descram <<= 1; + s->l1.fsk96.descram |= s->l1.fsk96.dcd_shreg & 1; + descx = s->l1.fsk96.descram ^ (s->l1.fsk96.descram >> 1); + curbit = ((descx >> DESCRAM_TAPSH1) ^ (descx >> DESCRAM_TAPSH2) ^ + (descx >> DESCRAM_TAPSH3) ^ 1) & 1; + verbprintf(9, " %c ", '0'+curbit); + hdlc_rxbit(s, curbit); + } + } + } +} + +/* ---------------------------------------------------------------------- */ + +const struct demod_param demod_fsk9600 = { + "FSK9600", FREQ_SAMP, FILTLEN, fsk96_init, fsk96_demod +}; + +/* ---------------------------------------------------------------------- */ diff --git a/sw/ground_segment/multimon/demod_hapn48.c b/sw/ground_segment/multimon/demod_hapn48.c new file mode 100644 index 0000000000..d76ee2e841 --- /dev/null +++ b/sw/ground_segment/multimon/demod_hapn48.c @@ -0,0 +1,99 @@ +/* + * demod_hapn48.c -- HAPN 4800 baud demodulator (G3RUH) + * + * Copyright (C) 1996 + * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* ---------------------------------------------------------------------- */ + +#include "multimon.h" +#include "filter.h" +#include +#include + +/* ---------------------------------------------------------------------- */ + +#define FREQ_SAMP 22050 +#define BAUD 4800 + +/* ---------------------------------------------------------------------- */ + +#define SPHASEINC (0x10000u*BAUD/FREQ_SAMP) + +/* ---------------------------------------------------------------------- */ + +static void hapn48_init(struct demod_state *s) +{ + hdlc_init(s); + memset(&s->l1.hapn48, 0, sizeof(s->l1.hapn48)); +} + +/* ---------------------------------------------------------------------- */ + +static void hapn48_demod(struct demod_state *s, float *buffer, int length) +{ + int cursync; + unsigned int curbit; + + for (; length > 0; length--, buffer++) { + s->l1.hapn48.lvlhi *= 0.999; + s->l1.hapn48.lvllo *= 0.999; + if (buffer[1] > s->l1.hapn48.lvlhi) + s->l1.hapn48.lvlhi = buffer[1]; + if (buffer[1] < s->l1.hapn48.lvllo) + s->l1.hapn48.lvllo = buffer[1]; + cursync = 0; + s->l1.hapn48.shreg = (s->l1.hapn48.shreg << 1) | + (s->l1.hapn48.shreg & 1); + if (buffer[1] > s->l1.hapn48.lvlhi * 0.5) { + s->l1.hapn48.shreg |= 1; + cursync = (buffer[1] > buffer[0] && buffer[1] > buffer[2]); + } else if (buffer[1] < s->l1.hapn48.lvllo * 0.5) { + s->l1.hapn48.shreg &= ~1; + cursync = (buffer[1] < buffer[0] && buffer[1] < buffer[2]); + } + verbprintf(10, "%c", '0' + (s->l1.hapn48.shreg & 1)); + s->l1.hapn48.sphase += SPHASEINC; + if (((s->l1.hapn48.shreg >> 1) ^ s->l1.hapn48.shreg) & 1) + if (s->l1.hapn48.sphase >= 0x8000+SPHASEINC/2) + s->l1.hapn48.sphase -= 0x800; + else + s->l1.hapn48.sphase += 0x800; +#if 0 + if (cursync) + if (((s->l1.hapn48.sphase-0x8000)&0xffffu) >= 0x8000+SPHASEINC/2) + s->l1.hapn48.sphase -= 0x800; + else + s->l1.hapn48.sphase += 0x800; +#endif + if (s->l1.hapn48.sphase >= 0x10000) { + s->l1.hapn48.sphase &= 0xffff; + curbit = ((s->l1.hapn48.shreg >> 4) ^ s->l1.hapn48.shreg ^ 1) & 1; + verbprintf(9, " %c ", '0'+curbit); + hdlc_rxbit(s, curbit); + } + } +} + +/* ---------------------------------------------------------------------- */ + +const struct demod_param demod_hapn4800 = { + "HAPN4800", FREQ_SAMP, 3, hapn48_init, hapn48_demod +}; + +/* ---------------------------------------------------------------------- */ diff --git a/sw/ground_segment/multimon/demod_poc12.c b/sw/ground_segment/multimon/demod_poc12.c new file mode 100644 index 0000000000..340623407f --- /dev/null +++ b/sw/ground_segment/multimon/demod_poc12.c @@ -0,0 +1,93 @@ +/* + * demod_poc12.c -- 1200 baud POCSAG demodulator + * + * Copyright (C) 1996 + * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) + * + * POCSAG (Post Office Code Standard Advisory Group) + * Radio Paging Decoder + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* ---------------------------------------------------------------------- */ + +#include "multimon.h" +#include "filter.h" +#include +#include + +/* ---------------------------------------------------------------------- */ + +#define FREQ_SAMP 22050 +#define BAUD 1200 +#define SUBSAMP 2 +#define FILTLEN 1 + +/* ---------------------------------------------------------------------- */ + +#define SPHASEINC (0x10000u*BAUD*SUBSAMP/FREQ_SAMP) + +/* ---------------------------------------------------------------------- */ + +static void poc12_init(struct demod_state *s) +{ + pocsag_init(s); + memset(&s->l1.poc12, 0, sizeof(s->l1.poc12)); +} + +/* ---------------------------------------------------------------------- */ + +static void poc12_demod(struct demod_state *s, float *buffer, int length) +{ + if (s->l1.poc12.subsamp) { + int numfill = SUBSAMP - s->l1.poc12.subsamp; + if (length < numfill) { + s->l1.poc12.subsamp += length; + return; + } + buffer += numfill; + length -= numfill; + s->l1.poc12.subsamp = 0; + } + for (; length >= SUBSAMP; length -= SUBSAMP, buffer += SUBSAMP) { + s->l1.poc12.dcd_shreg <<= 1; + s->l1.poc12.dcd_shreg |= ((*buffer) > 0); + verbprintf(10, "%c", '0'+(s->l1.poc12.dcd_shreg & 1)); + /* + * check if transition + */ + if ((s->l1.poc12.dcd_shreg ^ (s->l1.poc12.dcd_shreg >> 1)) & 1) { + if (s->l1.poc12.sphase < (0x8000u-(SPHASEINC/2))) + s->l1.poc12.sphase += SPHASEINC/8; + else + s->l1.poc12.sphase -= SPHASEINC/8; + } + s->l1.poc12.sphase += SPHASEINC; + if (s->l1.poc12.sphase >= 0x10000u) { + s->l1.poc12.sphase &= 0xffffu; + pocsag_rxbit(s, s->l1.poc12.dcd_shreg & 1); + } + } + s->l1.poc12.subsamp = length; +} + +/* ---------------------------------------------------------------------- */ + +const struct demod_param demod_poc12 = { + "POCSAG1200", FREQ_SAMP, FILTLEN, poc12_init, poc12_demod +}; + +/* ---------------------------------------------------------------------- */ diff --git a/sw/ground_segment/multimon/demod_poc24.c b/sw/ground_segment/multimon/demod_poc24.c new file mode 100644 index 0000000000..7645d9af3c --- /dev/null +++ b/sw/ground_segment/multimon/demod_poc24.c @@ -0,0 +1,80 @@ +/* + * demod_poc24.c -- 2400 baud POCSAG demodulator + * + * Copyright (C) 1996 + * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) + * + * POCSAG (Post Office Code Standard Advisory Group) + * Radio Paging Decoder + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* ---------------------------------------------------------------------- */ + +#include "multimon.h" +#include "filter.h" +#include +#include +/* ---------------------------------------------------------------------- */ + +#define FREQ_SAMP 22050 +#define BAUD 2400 +#define FILTLEN 1 + +/* ---------------------------------------------------------------------- */ + +#define SPHASEINC (0x10000u*BAUD/FREQ_SAMP) + +/* ---------------------------------------------------------------------- */ + +static void poc24_init(struct demod_state *s) +{ + pocsag_init(s); + memset(&s->l1.poc24, 0, sizeof(s->l1.poc24)); +} + +/* ---------------------------------------------------------------------- */ + +static void poc24_demod(struct demod_state *s, float *buffer, int length) +{ + for (; length > 0; length--, buffer++) { + s->l1.poc24.dcd_shreg <<= 1; + s->l1.poc24.dcd_shreg |= ((*buffer) > 0); + verbprintf(10, "%c", '0'+(s->l1.poc24.dcd_shreg & 1)); + /* + * check if transition + */ + if ((s->l1.poc24.dcd_shreg ^ (s->l1.poc24.dcd_shreg >> 1)) & 1) { + if (s->l1.poc24.sphase < (0x8000u-(SPHASEINC/2))) + s->l1.poc24.sphase += SPHASEINC/8; + else + s->l1.poc24.sphase -= SPHASEINC/8; + } + s->l1.poc24.sphase += SPHASEINC; + if (s->l1.poc24.sphase >= 0x10000u) { + s->l1.poc24.sphase &= 0xffffu; + pocsag_rxbit(s, s->l1.poc24.dcd_shreg & 1); + } + } +} + +/* ---------------------------------------------------------------------- */ + +const struct demod_param demod_poc24 = { + "POCSAG2400", FREQ_SAMP, FILTLEN, poc24_init, poc24_demod +}; + +/* ---------------------------------------------------------------------- */ diff --git a/sw/ground_segment/multimon/demod_poc5.c b/sw/ground_segment/multimon/demod_poc5.c new file mode 100644 index 0000000000..3204468f71 --- /dev/null +++ b/sw/ground_segment/multimon/demod_poc5.c @@ -0,0 +1,92 @@ +/* + * demod_poc5.c -- 512 baud POCSAG demodulator + * + * Copyright (C) 1996 + * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) + * + * POCSAG (Post Office Code Standard Advisory Group) + * Radio Paging Decoder + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* ---------------------------------------------------------------------- */ + +#include "multimon.h" +#include "filter.h" +#include +#include +/* ---------------------------------------------------------------------- */ + +#define FREQ_SAMP 22050 +#define BAUD 512 +#define SUBSAMP 5 +#define FILTLEN 1 + +/* ---------------------------------------------------------------------- */ + +#define SPHASEINC (0x10000u*BAUD*SUBSAMP/FREQ_SAMP) + +/* ---------------------------------------------------------------------- */ + +static void poc5_init(struct demod_state *s) +{ + pocsag_init(s); + memset(&s->l1.poc5, 0, sizeof(s->l1.poc5)); +} + +/* ---------------------------------------------------------------------- */ + +static void poc5_demod(struct demod_state *s, float *buffer, int length) +{ + if (s->l1.poc5.subsamp) { + int numfill = SUBSAMP - s->l1.poc5.subsamp; + if (length < numfill) { + s->l1.poc5.subsamp += length; + return; + } + buffer += numfill; + length -= numfill; + s->l1.poc5.subsamp = 0; + } + for (; length >= SUBSAMP; length -= SUBSAMP, buffer += SUBSAMP) { + s->l1.poc5.dcd_shreg <<= 1; + s->l1.poc5.dcd_shreg |= ((*buffer) > 0); + verbprintf(10, "%c", '0'+(s->l1.poc5.dcd_shreg & 1)); + /* + * check if transition + */ + if ((s->l1.poc5.dcd_shreg ^ (s->l1.poc5.dcd_shreg >> 1)) & 1) { + if (s->l1.poc5.sphase < (0x8000u-(SPHASEINC/2))) + s->l1.poc5.sphase += SPHASEINC/8; + else + s->l1.poc5.sphase -= SPHASEINC/8; + } + s->l1.poc5.sphase += SPHASEINC; + if (s->l1.poc5.sphase >= 0x10000u) { + s->l1.poc5.sphase &= 0xffffu; + pocsag_rxbit(s, s->l1.poc5.dcd_shreg & 1); + } + } + s->l1.poc5.subsamp = length; +} + +/* ---------------------------------------------------------------------- */ + +const struct demod_param demod_poc5 = { + "POCSAG512", FREQ_SAMP, FILTLEN, poc5_init, poc5_demod +}; + +/* ---------------------------------------------------------------------- */ diff --git a/sw/ground_segment/multimon/demod_zvei.c b/sw/ground_segment/multimon/demod_zvei.c new file mode 100644 index 0000000000..e50e1ecc56 --- /dev/null +++ b/sw/ground_segment/multimon/demod_zvei.c @@ -0,0 +1,146 @@ +/* + * demod_zvei.c -- ZVEI signalling demodulator/decoder + * + * Copyright (C) 1996 + * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* ---------------------------------------------------------------------- */ + +#include "multimon.h" +#include "filter.h" +#include +#include + +/* ---------------------------------------------------------------------- */ + +#define SAMPLE_RATE 22050 +#define BLOCKLEN (SAMPLE_RATE/100) /* 10ms blocks */ +#define BLOCKNUM 4 /* must match numbers in multimon.h */ + +#define PHINC(x) ((x)*0x10000/SAMPLE_RATE) + +static const unsigned int zvei_freq[16] = { + PHINC(2400), PHINC(1060), PHINC(1160), PHINC(1270), + PHINC(1400), PHINC(1530), PHINC(1670), PHINC(1830), + PHINC(2000), PHINC(2200), PHINC(2800), PHINC(810), + PHINC(970), PHINC(886), PHINC(2600), PHINC(0) +}; + +static const unsigned int zveis_freq[16] = { + PHINC(2400), PHINC(1060), PHINC(1160), PHINC(1270), + PHINC(1400), PHINC(1530), PHINC(1670), PHINC(1830), + PHINC(2000), PHINC(2200), PHINC(886), PHINC(810), + PHINC(740), PHINC(680), PHINC(970), PHINC(0) +}; + +/* ---------------------------------------------------------------------- */ + +static void zvei_init(struct demod_state *s) +{ + memset(&s->l1.zvei, 0, sizeof(s->l1.zvei)); +} + +/* ---------------------------------------------------------------------- */ + +static int find_max_idx(const float *f) +{ + float en = 0; + int idx = -1, i; + + for (i = 0; i < 16; i++) + if (f[i] > en) { + en = f[i]; + idx = i; + } + if (idx < 0) + return -1; + en *= 0.1; + for (i = 0; i < 16; i++) + if (idx != i && f[i] > en) + return -1; + return idx; +} + +/* ---------------------------------------------------------------------- */ + +static inline int process_block(struct demod_state *s) +{ + float tote; + float totte[32]; + int i, j; + + tote = 0; + for (i = 0; i < BLOCKNUM; i++) + tote += s->l1.zvei.energy[i]; + for (i = 0; i < 32; i++) { + totte[i] = 0; + for (j = 0; j < BLOCKNUM; j++) + totte[i] += s->l1.zvei.tenergy[j][i]; + } + for (i = 0; i < 16; i++) + totte[i] = fsqr(totte[i]) + fsqr(totte[i+16]); + memmove(s->l1.zvei.energy+1, s->l1.zvei.energy, + sizeof(s->l1.zvei.energy) - sizeof(s->l1.zvei.energy[0])); + s->l1.zvei.energy[0] = 0; + memmove(s->l1.zvei.tenergy+1, s->l1.zvei.tenergy, + sizeof(s->l1.zvei.tenergy) - sizeof(s->l1.zvei.tenergy[0])); + memset(s->l1.zvei.tenergy, 0, sizeof(s->l1.zvei.tenergy[0])); + tote *= (BLOCKNUM*BLOCKLEN*0.5); /* adjust for block lengths */ + verbprintf(10, "ZVEI: Energies: %8.5f %8.5f %8.5f %8.5f %8.5f %8.5f %8.5f %8.5f %8.5f" + " %8.5f %8.5f %8.5f %8.5f %8.5f %8.5f %8.5f %8.5f\n", + tote, totte[0], totte[1], totte[2], totte[3], totte[4], totte[5], totte[6], totte[7], + totte[8], totte[9], totte[10], totte[11], totte[12], totte[13], totte[14], totte[15]); + if ((i = find_max_idx(totte)) < 0) + return -1; + if ((tote * 0.4) > totte[i]) + return -1; + return i; +} + +/* ---------------------------------------------------------------------- */ + +static void zvei_demod(struct demod_state *s, float *buffer, int length) +{ + float s_in; + int i; + + for (; length > 0; length--, buffer++) { + s_in = *buffer; + s->l1.zvei.energy[0] += fsqr(s_in); + for (i = 0; i < 16; i++) { + s->l1.zvei.tenergy[0][i] += COS(s->l1.zvei.ph[i]) * s_in; + s->l1.zvei.tenergy[0][i+16] += SIN(s->l1.zvei.ph[i]) * s_in; + s->l1.zvei.ph[i] += zvei_freq[i]; + } + if ((s->l1.zvei.blkcount--) <= 0) { + s->l1.zvei.blkcount = BLOCKLEN; + i = process_block(s); + if (i != s->l1.zvei.lastch && i >= 0) + verbprintf(0, "ZVEI: %1x\n", i); + s->l1.zvei.lastch = i; + } + } +} + +/* ---------------------------------------------------------------------- */ + +const struct demod_param demod_zvei = { + "ZVEI", SAMPLE_RATE, 0, zvei_init, zvei_demod +}; + +/* ---------------------------------------------------------------------- */ diff --git a/sw/ground_segment/multimon/filter-i386.h b/sw/ground_segment/multimon/filter-i386.h new file mode 100644 index 0000000000..73857e4528 --- /dev/null +++ b/sw/ground_segment/multimon/filter-i386.h @@ -0,0 +1,277 @@ +/* + * filter-i386.h -- optimized filter routines + * + * Copyright (C) 1996 + * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* ---------------------------------------------------------------------- */ + +#ifndef _FILTER_I386_H +#define _FILTER_I386_H + +/* ---------------------------------------------------------------------- */ + +#define __HAVE_ARCH_MAC +#define mac(a,b,size) \ +(__builtin_constant_p(size) ? __mac_c((a),(b),(size)) : __mac_g((a),(b),(size))) + +#include + +extern inline float __mac_g(const float *a, const float *b, unsigned int size) +{ + float sum = 0; + unsigned int i; + + for (i = 0; i < size; i++) + sum += (*a++) * (*b++); + return sum; +} + +extern inline float __mac_c(const float *a, const float *b, unsigned int size) +{ + float f; + + /* + * inspired from Phil Karn, KA9Q's home page + */ + switch (size) { + case 9: + asm volatile ("flds (%1);\n\t" + "fmuls (%2);\n\t" + "flds 4(%1);\n\t" + "fmuls 4(%2);\n\t" + "flds 8(%1);\n\t" + "fmuls 8(%2);\n\t" + "fxch %%st(2);\n\t" + "faddp;\n\t" + "flds 12(%1);\n\t" + "fmuls 12(%2);\n\t" + "fxch %%st(2);\n\t" + "faddp;\n\t" + "flds 16(%1);\n\t" + "fmuls 16(%2);\n\t" + "fxch %%st(2);\n\t" + "faddp;\n\t" + "flds 20(%1);\n\t" + "fmuls 20(%2);\n\t" + "fxch %%st(2);\n\t" + "faddp;\n\t" + "flds 24(%1);\n\t" + "fmuls 24(%2);\n\t" + "fxch %%st(2);\n\t" + "faddp;\n\t" + "flds 28(%1);\n\t" + "fmuls 28(%2);\n\t" + "fxch %%st(2);\n\t" + "faddp;\n\t" + "flds 32(%1);\n\t" + "fmuls 32(%2);\n\t" + "fxch %%st(2);\n\t" + "faddp;\n\t" + "faddp;\n\t" : + "=t" (f) : + "r" (a), + "r" (b) : "memory"); + return f; + + case 18: + asm volatile ("flds (%1);\n\t" + "fmuls (%2);\n\t" + "flds 4(%1);\n\t" + "fmuls 4(%2);\n\t" + "flds 8(%1);\n\t" + "fmuls 8(%2);\n\t" + "fxch %%st(2);\n\t" + "faddp;\n\t" + "flds 12(%1);\n\t" + "fmuls 12(%2);\n\t" + "fxch %%st(2);\n\t" + "faddp;\n\t" + "flds 16(%1);\n\t" + "fmuls 16(%2);\n\t" + "fxch %%st(2);\n\t" + "faddp;\n\t" + "flds 20(%1);\n\t" + "fmuls 20(%2);\n\t" + "fxch %%st(2);\n\t" + "faddp;\n\t" + "flds 24(%1);\n\t" + "fmuls 24(%2);\n\t" + "fxch %%st(2);\n\t" + "faddp;\n\t" + "flds 28(%1);\n\t" + "fmuls 28(%2);\n\t" + "fxch %%st(2);\n\t" + "faddp;\n\t" + "flds 32(%1);\n\t" + "fmuls 32(%2);\n\t" + "fxch %%st(2);\n\t" + "faddp;\n\t" + "flds 36(%1);\n\t" + "fmuls 36(%2);\n\t" + "fxch %%st(2);\n\t" + "faddp;\n\t" + "flds 40(%1);\n\t" + "fmuls 40(%2);\n\t" + "fxch %%st(2);\n\t" + "faddp;\n\t" + "flds 44(%1);\n\t" + "fmuls 44(%2);\n\t" + "fxch %%st(2);\n\t" + "faddp;\n\t" + "flds 48(%1);\n\t" + "fmuls 48(%2);\n\t" + "fxch %%st(2);\n\t" + "faddp;\n\t" + "flds 52(%1);\n\t" + "fmuls 52(%2);\n\t" + "fxch %%st(2);\n\t" + "faddp;\n\t" + "flds 56(%1);\n\t" + "fmuls 56(%2);\n\t" + "fxch %%st(2);\n\t" + "faddp;\n\t" + "flds 60(%1);\n\t" + "fmuls 60(%2);\n\t" + "fxch %%st(2);\n\t" + "faddp;\n\t" + "flds 64(%1);\n\t" + "fmuls 64(%2);\n\t" + "fxch %%st(2);\n\t" + "faddp;\n\t" + "flds 68(%1);\n\t" + "fmuls 68(%2);\n\t" + "fxch %%st(2);\n\t" + "faddp;\n\t" + "faddp;\n\t" : + "=t" (f) : + "r" (a), + "r" (b) : "memory"); + return f; + + case 24: + asm volatile ("flds (%1);\n\t" + "fmuls (%2);\n\t" + "flds 4(%1);\n\t" + "fmuls 4(%2);\n\t" + "flds 8(%1);\n\t" + "fmuls 8(%2);\n\t" + "fxch %%st(2);\n\t" + "faddp;\n\t" + "flds 12(%1);\n\t" + "fmuls 12(%2);\n\t" + "fxch %%st(2);\n\t" + "faddp;\n\t" + "flds 16(%1);\n\t" + "fmuls 16(%2);\n\t" + "fxch %%st(2);\n\t" + "faddp;\n\t" + "flds 20(%1);\n\t" + "fmuls 20(%2);\n\t" + "fxch %%st(2);\n\t" + "faddp;\n\t" + "flds 24(%1);\n\t" + "fmuls 24(%2);\n\t" + "fxch %%st(2);\n\t" + "faddp;\n\t" + "flds 28(%1);\n\t" + "fmuls 28(%2);\n\t" + "fxch %%st(2);\n\t" + "faddp;\n\t" + "flds 32(%1);\n\t" + "fmuls 32(%2);\n\t" + "fxch %%st(2);\n\t" + "faddp;\n\t" + "flds 36(%1);\n\t" + "fmuls 36(%2);\n\t" + "fxch %%st(2);\n\t" + "faddp;\n\t" + "flds 40(%1);\n\t" + "fmuls 40(%2);\n\t" + "fxch %%st(2);\n\t" + "faddp;\n\t" + "flds 44(%1);\n\t" + "fmuls 44(%2);\n\t" + "fxch %%st(2);\n\t" + "faddp;\n\t" + "flds 48(%1);\n\t" + "fmuls 48(%2);\n\t" + "fxch %%st(2);\n\t" + "faddp;\n\t" + "flds 52(%1);\n\t" + "fmuls 52(%2);\n\t" + "fxch %%st(2);\n\t" + "faddp;\n\t" + "flds 56(%1);\n\t" + "fmuls 56(%2);\n\t" + "fxch %%st(2);\n\t" + "faddp;\n\t" + "flds 60(%1);\n\t" + "fmuls 60(%2);\n\t" + "fxch %%st(2);\n\t" + "faddp;\n\t" + "flds 64(%1);\n\t" + "fmuls 64(%2);\n\t" + "fxch %%st(2);\n\t" + "faddp;\n\t" + "flds 68(%1);\n\t" + "fmuls 68(%2);\n\t" + "fxch %%st(2);\n\t" + "faddp;\n\t" + "flds 72(%1);\n\t" + "fmuls 72(%2);\n\t" + "fxch %%st(2);\n\t" + "faddp;\n\t" + "flds 76(%1);\n\t" + "fmuls 76(%2);\n\t" + "fxch %%st(2);\n\t" + "faddp;\n\t" + "flds 80(%1);\n\t" + "fmuls 80(%2);\n\t" + "fxch %%st(2);\n\t" + "faddp;\n\t" + "flds 84(%1);\n\t" + "fmuls 84(%2);\n\t" + "fxch %%st(2);\n\t" + "faddp;\n\t" + "flds 88(%1);\n\t" + "fmuls 88(%2);\n\t" + "fxch %%st(2);\n\t" + "faddp;\n\t" + "flds 92(%1);\n\t" + "fmuls 92(%2);\n\t" + "fxch %%st(2);\n\t" + "faddp;\n\t" + "faddp;\n\t" : + "=t" (f) : + "r" (a), + "r" (b) : "memory"); + return f; + + default: + printf("Warning: optimize __mac_c(..., ..., %d)\n", size); + return __mac_g(a, b, size); + } +} + +/* ---------------------------------------------------------------------- */ +#endif /* _FILTER_I386_H */ + + + + diff --git a/sw/ground_segment/multimon/filter.h b/sw/ground_segment/multimon/filter.h new file mode 100644 index 0000000000..1389ec0785 --- /dev/null +++ b/sw/ground_segment/multimon/filter.h @@ -0,0 +1,110 @@ +/* + * filter.h -- optimized filter routines + * + * Copyright (C) 1996 + * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* ---------------------------------------------------------------------- */ + +#ifndef _FILTER_H +#define _FILTER_H + +/* ---------------------------------------------------------------------- */ + +#ifdef ARCH_I386 +#include "filter-i386.h" +#endif /* ARCH_I386 */ + +/* ---------------------------------------------------------------------- */ + +extern inline unsigned int hweight32(unsigned int w) + __attribute__ ((unused)); +extern inline unsigned int hweight16(unsigned short w) + __attribute__ ((unused)); +extern inline unsigned int hweight8(unsigned char w) + __attribute__ ((unused)); + +extern inline unsigned int hweight32(unsigned int w) +{ + unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555); + res = (res & 0x33333333) + ((res >> 2) & 0x33333333); + res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F); + res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF); + return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF); +} + +extern inline unsigned int hweight16(unsigned short w) +{ + unsigned short res = (w & 0x5555) + ((w >> 1) & 0x5555); + res = (res & 0x3333) + ((res >> 2) & 0x3333); + res = (res & 0x0F0F) + ((res >> 4) & 0x0F0F); + return (res & 0x00FF) + ((res >> 8) & 0x00FF); +} + +extern inline unsigned int hweight8(unsigned char w) +{ + unsigned short res = (w & 0x55) + ((w >> 1) & 0x55); + res = (res & 0x33) + ((res >> 2) & 0x33); + return (res & 0x0F) + ((res >> 4) & 0x0F); +} + +extern inline unsigned int gcd(unsigned int x, unsigned int y) + __attribute__ ((unused)); +extern inline unsigned int lcm(unsigned int x, unsigned int y) + __attribute__ ((unused)); + +extern inline unsigned int gcd(unsigned int x, unsigned int y) +{ + for (;;) { + if (!x) + return y; + if (!y) + return x; + if (x > y) + x %= y; + else + y %= x; + } +} + +extern inline unsigned int lcm(unsigned int x, unsigned int y) +{ + return x * y / gcd(x, y); +} + +/* ---------------------------------------------------------------------- */ + +#ifndef __HAVE_ARCH_MAC +extern inline float mac(const float *a, const float *b, unsigned int size) +{ + float sum = 0; + unsigned int i; + + for (i = 0; i < size; i++) + sum += (*a++) * (*b++); + return sum; +} +#endif /* __HAVE_ARCH_MAC */ + +extern inline float fsqr(float f) +{ + return f*f; +} + +/* ---------------------------------------------------------------------- */ +#endif /* _FILTER_H */ diff --git a/sw/ground_segment/multimon/filter/fifsk96 b/sw/ground_segment/multimon/filter/fifsk96 new file mode 100644 index 0000000000..db12dad37b --- /dev/null +++ b/sw/ground_segment/multimon/filter/fifsk96 @@ -0,0 +1,8 @@ +fifsk96.o +fifsk96.p +fifsk96.g +72 +hamming +0 +66150 +0 6100 1.000 diff --git a/sw/ground_segment/multimon/filter/fifsk96.g b/sw/ground_segment/multimon/filter/fifsk96.g new file mode 100644 index 0000000000..8cfd331643 --- /dev/null +++ b/sw/ground_segment/multimon/filter/fifsk96.g @@ -0,0 +1,1028 @@ +% for logarithmic plots, use gnuplot with: +% plot [0:33075.000000] "fifsk96.g" using 1:2 with lines +for linear plots, use gnuplot with: +% plot [0:33075.000000] "fifsk96.g" using 1:3 with lines + 0.000000 -0.278720 0.968421 + 64.599609 -0.278944 0.968396 + 129.199219 -0.279600 0.968322 + 193.798828 -0.280655 0.968205 + 258.398438 -0.282053 0.968049 + 322.998047 -0.283719 0.967863 + 387.597656 -0.285563 0.967658 + 452.197266 -0.287486 0.967444 + 516.796875 -0.289386 0.967232 + 581.396484 -0.291158 0.967035 + 645.996094 -0.292708 0.966862 + 710.595703 -0.293951 0.966724 + 775.195312 -0.294819 0.966627 + 839.794922 -0.295263 0.966578 + 904.394531 -0.295257 0.966579 + 968.994141 -0.294800 0.966629 + 1033.593750 -0.293914 0.966728 + 1098.193359 -0.292643 0.966870 + 1162.792969 -0.291053 0.967046 + 1227.392578 -0.289227 0.967250 + 1291.992188 -0.287261 0.967469 + 1356.591797 -0.285258 0.967692 + 1421.191406 -0.283323 0.967907 + 1485.791016 -0.281559 0.968104 + 1550.390625 -0.280057 0.968271 + 1614.990234 -0.278900 0.968401 + 1679.589844 -0.278147 0.968484 + 1744.189453 -0.277840 0.968519 + 1808.789062 -0.277998 0.968501 + 1873.388672 -0.278611 0.968433 + 1937.988281 -0.279652 0.968317 + 2002.587891 -0.281067 0.968159 + 2067.187500 -0.282787 0.967967 + 2131.787109 -0.284723 0.967751 + 2196.386719 -0.286781 0.967522 + 2260.986328 -0.288857 0.967291 + 2325.585938 -0.290849 0.967069 + 2390.185547 -0.292661 0.966867 + 2454.785156 -0.294208 0.966695 + 2519.384766 -0.295421 0.966560 + 2583.984375 -0.296246 0.966468 + 2648.583984 -0.296657 0.966423 + 2713.183594 -0.296640 0.966425 + 2777.783203 -0.296210 0.966473 + 2842.382812 -0.295399 0.966563 + 2906.982422 -0.294260 0.966689 + 2971.582031 -0.292850 0.966846 + 3036.181641 -0.291241 0.967026 + 3100.781250 -0.289502 0.967219 + 3165.380859 -0.287702 0.967420 + 3229.980469 -0.285899 0.967620 + 3294.580078 -0.284139 0.967817 + 3359.179688 -0.282450 0.968005 + 3423.779297 -0.280843 0.968184 + 3488.378906 -0.279309 0.968355 + 3552.978516 -0.277826 0.968520 + 3617.578125 -0.276358 0.968684 + 3682.177734 -0.274867 0.968850 + 3746.777344 -0.273316 0.969023 + 3811.376953 -0.271688 0.969205 + 3875.976562 -0.269993 0.969394 + 3940.576172 -0.268283 0.969585 + 4005.175781 -0.266671 0.969765 + 4069.775391 -0.265341 0.969913 + 4134.375000 -0.264565 0.970000 + 4198.974609 -0.264714 0.969983 + 4263.574219 -0.266274 0.969809 + 4328.173828 -0.269847 0.969410 + 4392.773438 -0.276167 0.968705 + 4457.373047 -0.286091 0.967599 + 4521.972656 -0.300613 0.965983 + 4586.572266 -0.320844 0.963735 + 4651.171875 -0.348018 0.960725 + 4715.771484 -0.383479 0.956811 + 4780.371094 -0.428671 0.951846 + 4844.970703 -0.485124 0.945679 + 4909.570312 -0.554444 0.938162 + 4974.169922 -0.638297 0.929148 + 5038.769531 -0.738401 0.918502 + 5103.369141 -0.856509 0.906097 + 5167.968750 -0.994401 0.891826 + 5232.568359 -1.153877 0.875601 + 5297.167969 -1.336748 0.857359 + 5361.767578 -1.544833 0.837063 + 5426.367188 -1.779952 0.814709 + 5490.966797 -2.043930 0.790321 + 5555.566406 -2.338596 0.763959 + 5620.166016 -2.665783 0.735717 + 5684.765625 -3.027342 0.705721 + 5749.365234 -3.425136 0.674129 + 5813.964844 -3.861061 0.641131 + 5878.564453 -4.337048 0.606943 + 5943.164062 -4.855081 0.571802 + 6007.763672 -5.417207 0.535969 + 6072.363281 -6.025558 0.499715 + 6136.962891 -6.682366 0.463321 + 6201.562500 -7.389989 0.427071 + 6266.162109 -8.150934 0.391249 + 6330.761719 -8.967894 0.356127 + 6395.361328 -9.843774 0.321967 + 6459.960938 -10.781745 0.289010 + 6524.560547 -11.785291 0.257475 + 6589.160156 -12.858274 0.227555 + 6653.759766 -14.005014 0.199411 + 6718.359375 -15.230392 0.173173 + 6782.958984 -16.539972 0.148937 + 6847.558594 -17.940182 0.126763 + 6912.158203 -19.438532 0.106678 + 6976.757812 -21.043924 0.088676 + 7041.357422 -22.767096 0.072719 + 7105.957031 -24.621235 0.058741 + 7170.556641 -26.622974 0.046650 + 7235.156250 -28.793827 0.036334 + 7299.755859 -31.162664 0.027661 + 7364.355469 -33.770035 0.020488 + 7428.955078 -36.676125 0.014662 + 7493.554688 -39.977604 0.010026 + 7558.154297 -43.846790 0.006422 + 7622.753906 -48.645748 0.003696 + 7687.353516 -55.389706 0.001700 + 7751.953125 -70.528481 0.000298 + 7816.552734 -63.904583 0.000638 + 7881.152344 -58.287296 0.001218 + 7945.751953 -56.253147 0.001539 + 8010.351562 -55.476501 0.001683 + 8074.951172 -55.311096 0.001716 + 8139.550781 -55.456886 0.001687 + 8204.150391 -55.731697 0.001635 + 8268.750000 -56.014076 0.001582 + 8333.349609 -56.228798 0.001544 + 8397.949219 -56.344891 0.001523 + 8462.548828 -56.373440 0.001518 + 8527.148438 -56.355679 0.001521 + 8591.748047 -56.352348 0.001522 + 8656.347656 -56.430927 0.001508 + 8720.947266 -56.660595 0.001469 + 8785.546875 -57.114773 0.001394 + 8850.146484 -57.878582 0.001277 + 8914.746094 -59.070004 0.001113 + 8979.345703 -60.884552 0.000903 + 9043.945312 -63.728230 0.000651 + 9108.544922 -68.780762 0.000364 + 9173.144531 -85.628151 0.000052 + 9237.744141 -71.347839 0.000271 + 9302.343750 -64.570816 0.000591 + 9366.943359 -60.986828 0.000893 + 9431.542969 -58.701527 0.001161 + 9496.142578 -57.184135 0.001383 + 9560.742188 -56.216286 0.001546 + 9625.341797 -55.696812 0.001641 + 9689.941406 -55.581482 0.001663 + 9754.541016 -55.865685 0.001610 + 9819.140625 -56.581841 0.001482 + 9883.740234 -57.811268 0.001287 + 9948.339844 -59.730328 0.001032 + 10012.939453 -62.745205 0.000729 + 10077.539062 -68.103874 0.000393 + 10142.138672 -87.813911 0.000041 + 10206.738281 -70.110649 0.000312 + 10271.337891 -63.763126 0.000648 + 10335.937500 -60.428680 0.000952 + 10400.537109 -58.358494 0.001208 + 10465.136719 -57.046913 0.001405 + 10529.736328 -56.286488 0.001533 + 10594.335938 -55.983944 0.001588 + 10658.935547 -56.104431 0.001566 + 10723.535156 -56.656635 0.001469 + 10788.134766 -57.696621 0.001304 + 10852.734375 -59.355042 0.001077 + 10917.333984 -61.925838 0.000801 + 10981.933594 -66.202026 0.000490 + 11046.533203 -76.027138 0.000158 + 11111.132812 -75.007957 0.000178 + 11175.732422 -66.002464 0.000501 + 11240.332031 -61.973900 0.000797 + 11304.931641 -59.571301 0.001051 + 11369.531250 -58.055210 0.001251 + 11434.130859 -57.148190 0.001389 + 11498.730469 -56.726894 0.001458 + 11563.330078 -56.739555 0.001456 + 11627.929688 -57.183292 0.001383 + 11692.529297 -58.099991 0.001245 + 11757.128906 -59.597141 0.001047 + 11821.728516 -61.916138 0.000802 + 11886.328125 -65.668625 0.000521 + 11950.927734 -73.253914 0.000217 + 12015.527344 -80.651566 0.000093 + 12080.126953 -68.071823 0.000395 + 12144.726562 -63.424065 0.000674 + 12209.326172 -60.747375 0.000918 + 12273.925781 -59.065598 0.001114 + 12338.525391 -58.038994 0.001253 + 12403.125000 -57.519058 0.001331 + 12467.724609 -57.442314 0.001342 + 12532.324219 -57.795464 0.001289 + 12596.923828 -58.610329 0.001174 + 12661.523438 -59.978786 0.001002 + 12726.123047 -62.106640 0.000785 + 12790.722656 -65.493515 0.000531 + 12855.322266 -71.871254 0.000255 + 12919.921875 -90.275864 0.000031 + 12984.521484 -70.131248 0.000311 + 13049.121094 -64.821152 0.000574 + 13113.720703 -61.875553 0.000806 + 13178.320312 -60.037033 0.000996 + 13242.919922 -58.898315 0.001135 + 13307.519531 -58.286922 0.001218 + 13372.119141 -58.126968 0.001241 + 13436.718750 -58.396976 0.001203 + 13501.318359 -59.119576 0.001107 + 13565.917969 -60.373631 0.000958 + 13630.517578 -62.336903 0.000764 + 13695.117188 -65.429832 0.000535 + 13759.716797 -70.973564 0.000283 + 13824.316406 -94.389519 0.000019 + 13888.916016 -72.297798 0.000243 + 13953.515625 -66.196312 0.000490 + 14018.115234 -62.964512 0.000711 + 14082.714844 -60.965012 0.000895 + 14147.314453 -59.714199 0.001033 + 14211.914062 -59.012627 0.001120 + 14276.513672 -58.771996 0.001152 + 14341.113281 -58.961704 0.001127 + 14405.712891 -59.596745 0.001048 + 14470.312500 -60.744297 0.000918 + 14534.912109 -62.559414 0.000745 + 14599.511719 -65.398346 0.000537 + 14664.111328 -70.304214 0.000305 + 14728.710938 -84.304283 0.000061 + 14793.310547 -74.696449 0.000184 + 14857.910156 -67.578011 0.000418 + 14922.509766 -64.024597 0.000629 + 14987.109375 -61.854134 0.000808 + 15051.708984 -60.487232 0.000945 + 15116.308594 -59.694530 0.001036 + 15180.908203 -59.372753 0.001075 + 15245.507812 -59.483616 0.001061 + 15310.107422 -60.033680 0.000996 + 15374.707031 -61.080471 0.000883 + 15439.306641 -62.757633 0.000728 + 15503.906250 -65.370667 0.000539 + 15568.505859 -69.759087 0.000325 + 15633.105469 -80.223701 0.000097 + 15697.705078 -77.524490 0.000133 + 15762.304688 -68.995399 0.000355 + 15826.904297 -65.070374 0.000558 + 15891.503906 -62.712959 0.000732 + 15956.103516 -61.224205 0.000869 + 16020.703125 -60.337479 0.000962 + 16085.302734 -59.933750 0.001008 + 16149.902344 -59.965607 0.001004 + 16214.501953 -60.432983 0.000951 + 16279.101562 -61.381954 0.000853 + 16343.701172 -62.929710 0.000714 + 16408.300781 -65.338783 0.000541 + 16472.900391 -69.292953 0.000343 + 16537.500000 -77.717232 0.000130 + 16602.099609 -81.151131 0.000088 + 16666.699219 -70.480301 0.000299 + 16731.298828 -66.113571 0.000495 + 16795.898438 -63.549938 0.000665 + 16860.498047 -61.930298 0.000801 + 16925.097656 -60.945457 0.000897 + 16989.697266 -60.458618 0.000949 + 17054.296875 -60.411190 0.000954 + 17118.896484 -60.796383 0.000912 + 17183.496094 -61.650623 0.000827 + 17248.095703 -63.075897 0.000702 + 17312.695312 -65.297554 0.000543 + 17377.294922 -68.881821 0.000360 + 17441.894531 -75.929855 0.000160 + 17506.494141 -86.648331 0.000047 + 17571.093750 -72.074837 0.000249 + 17635.693359 -67.170158 0.000438 + 17700.292969 -64.373940 0.000604 + 17764.892578 -62.614243 0.000740 + 17829.492188 -61.526299 0.000839 + 17894.091797 -60.953465 0.000896 + 17958.691406 -60.826534 0.000909 + 18023.291016 -61.129791 0.000878 + 18087.890625 -61.892078 0.000804 + 18152.490234 -63.200459 0.000692 + 18217.089844 -65.249924 0.000546 + 18281.689453 -68.513046 0.000375 + 18346.289062 -74.561356 0.000187 + 18410.888672 -100.000000 0.000009 + 18475.488281 -73.828125 0.000204 + 18540.087891 -68.250229 0.000387 + 18604.687500 -65.191368 0.000550 + 18669.287109 -63.278957 0.000686 + 18733.886719 -62.082947 0.000787 + 18798.486328 -61.421432 0.000849 + 18863.085938 -61.213749 0.000870 + 18927.685547 -61.436081 0.000848 + 18992.285156 -62.107971 0.000785 + 19056.884766 -63.304436 0.000684 + 19121.484375 -65.194382 0.000550 + 19186.083984 -68.172180 0.000390 + 19250.683594 -73.449486 0.000213 + 19315.283203 -91.843185 0.000026 + 19379.882812 -75.832939 0.000162 + 19444.482422 -69.376022 0.000340 + 19509.082031 -66.012901 0.000500 + 19573.681641 -63.933987 0.000636 + 19638.281250 -62.622856 0.000739 + 19702.880859 -61.869362 0.000806 + 19767.480469 -61.579693 0.000834 + 19832.080078 -61.720978 0.000820 + 19896.679688 -62.304604 0.000767 + 19961.279297 -63.393597 0.000677 + 20025.878906 -65.134140 0.000554 + 20090.478516 -67.860840 0.000405 + 20155.078125 -72.525055 0.000236 + 20219.677734 -84.768745 0.000058 + 20284.277344 -78.212051 0.000123 + 20348.876953 -70.559204 0.000297 + 20413.476562 -66.842964 0.000455 + 20478.076172 -64.580574 0.000590 + 20542.675781 -63.146893 0.000696 + 20607.275391 -62.298256 0.000768 + 20671.875000 -61.924564 0.000801 + 20736.474609 -61.984562 0.000796 + 20801.074219 -62.481232 0.000752 + 20865.673828 -63.467007 0.000671 + 20930.273438 -65.067535 0.000558 + 20994.873047 -67.567329 0.000418 + 21059.472656 -71.727280 0.000259 + 21124.072266 -81.101768 0.000088 + 21188.671875 -81.260773 0.000086 + 21253.271484 -71.833534 0.000256 + 21317.871094 -67.695480 0.000412 + 21382.470703 -65.227982 0.000548 + 21447.070312 -63.663212 0.000656 + 21511.669922 -62.714561 0.000732 + 21576.269531 -62.255745 0.000771 + 21640.869141 -62.233643 0.000773 + 21705.468750 -62.644665 0.000738 + 21770.068359 -63.530270 0.000666 + 21834.667969 -64.999557 0.000562 + 21899.267578 -67.294731 0.000432 + 21963.867188 -71.034187 0.000281 + 22028.466797 -78.662560 0.000117 + 22093.066406 -85.613525 0.000052 + 22157.666016 -73.223534 0.000218 + 22222.265625 -68.573647 0.000373 + 22286.865234 -65.877441 0.000508 + 22351.464844 -64.171257 0.000619 + 22416.064453 -63.118355 0.000698 + 22480.664062 -62.571217 0.000744 + 22545.263672 -62.467247 0.000753 + 22609.863281 -62.793423 0.000725 + 22674.462891 -63.582382 0.000662 + 22739.062500 -64.926979 0.000567 + 22803.662109 -67.035439 0.000445 + 22868.261719 -70.414467 0.000301 + 22932.861328 -76.834648 0.000144 + 22997.460938 -93.978439 0.000020 + 23062.060547 -74.782753 0.000182 + 23126.660156 -69.494308 0.000335 + 23191.259766 -66.537582 0.000471 + 23255.859375 -64.678223 0.000584 + 23320.458984 -63.514870 0.000667 + 23385.058594 -62.877304 0.000718 + 23449.658203 -62.690361 0.000734 + 23514.257812 -62.932217 0.000713 + 23578.857422 -63.627163 0.000659 + 23643.457031 -64.853630 0.000572 + 23708.056641 -66.790588 0.000458 + 23772.656250 -69.859253 0.000321 + 23837.255859 -75.392502 0.000170 + 23901.855469 -99.301361 0.000011 + 23966.455078 -76.576553 0.000148 + 24031.054688 -70.466377 0.000300 + 24095.654297 -67.211250 0.000436 + 24160.253906 -65.184273 0.000551 + 24224.853516 -63.904663 0.000638 + 24289.453125 -63.173603 0.000694 + 24354.052734 -62.902275 0.000716 + 24418.652344 -63.060429 0.000703 + 24483.251953 -63.663448 0.000656 + 24547.851562 -64.777702 0.000577 + 24612.451172 -66.555984 0.000470 + 24677.050781 -69.351929 0.000341 + 24741.650391 -74.193192 0.000195 + 24806.250000 -87.857033 0.000040 + 24870.849609 -78.732735 0.000116 + 24935.449219 -71.510429 0.000266 + 25000.048828 -67.906342 0.000402 + 25064.648438 -65.695320 0.000519 + 25129.248047 -64.291985 0.000610 + 25193.847656 -63.464149 0.000671 + 25258.447266 -63.106930 0.000699 + 25323.046875 -63.181889 0.000693 + 25387.646484 -63.694950 0.000654 + 25452.246094 -64.701447 0.000582 + 25516.845703 -66.332985 0.000482 + 25581.445312 -68.887520 0.000359 + 25646.044922 -73.177101 0.000219 + 25710.644531 -83.226524 0.000069 + 25775.244141 -81.473427 0.000084 + 25839.843750 -72.643448 0.000233 + 25904.443359 -68.627472 0.000370 + 25969.042969 -66.212769 0.000489 + 26033.642578 -64.677383 0.000584 + 26098.242188 -63.748062 0.000650 + 26162.841797 -63.303810 0.000684 + 26227.441406 -63.295509 0.000684 + 26292.041016 -63.720211 0.000652 + 26356.640625 -64.622841 0.000587 + 26421.240234 -66.116966 0.000494 + 26485.839844 -68.454559 0.000378 + 26550.439453 -72.288086 0.000243 + 26615.039062 -80.298035 0.000097 + 26679.638672 -85.341446 0.000054 + 26744.238281 -73.900726 0.000202 + 26808.837891 -69.385399 0.000339 + 26873.437500 -66.742218 0.000460 + 26938.037109 -65.064720 0.000558 + 27002.636719 -64.029839 0.000629 + 27067.236328 -63.496017 0.000669 + 27131.835938 -63.403572 0.000676 + 27196.435547 -63.741508 0.000650 + 27261.035156 -64.544754 0.000593 + 27325.634766 -65.909653 0.000506 + 27390.234375 -68.051674 0.000396 + 27454.833984 -71.502296 0.000266 + 27519.433594 -78.162804 0.000124 + 27584.033203 -92.155983 0.000025 + 27648.632812 -75.321014 0.000171 + 27713.232422 -70.186813 0.000309 + 27777.832031 -67.285744 0.000432 + 27842.431641 -65.454178 0.000534 + 27907.031250 -64.308693 0.000609 + 27971.630859 -63.683537 0.000654 + 28036.230469 -63.506504 0.000668 + 28100.830078 -63.758369 0.000649 + 28165.429688 -64.464859 0.000598 + 28230.029297 -65.707840 0.000518 + 28294.628906 -67.671677 0.000413 + 28359.228516 -70.794441 0.000289 + 28423.828125 -76.485512 0.000150 + 28488.427734 -100.000000 0.000004 + 28553.027344 -76.973343 0.000142 + 28617.626953 -71.047348 0.000280 + 28682.226562 -67.849190 0.000405 + 28746.826172 -65.850601 0.000510 + 28811.425781 -64.587288 0.000590 + 28876.025391 -63.867538 0.000641 + 28940.625000 -63.605148 0.000660 + 29005.224609 -63.772121 0.000648 + 29069.824219 -64.384926 0.000604 + 29134.423828 -65.512772 0.000530 + 29199.023438 -67.313004 0.000431 + 29263.623047 -70.150421 0.000311 + 29328.222656 -75.104454 0.000176 + 29392.822266 -89.836014 0.000032 + 29457.421875 -78.966774 0.000113 + 29522.021484 -71.977470 0.000252 + 29586.621094 -68.436539 0.000379 + 29651.220703 -66.253998 0.000487 + 29715.820312 -64.866570 0.000571 + 29780.419922 -64.049126 0.000627 + 29845.019531 -63.700275 0.000653 + 29909.619141 -63.782562 0.000647 + 29974.218750 -64.303749 0.000609 + 30038.818359 -65.321541 0.000542 + 30103.417969 -66.970284 0.000448 + 30168.017578 -69.557610 0.000333 + 30232.617188 -73.927132 0.000201 + 30297.216797 -84.444298 0.000060 + 30361.816406 -81.505341 0.000084 + 30426.416016 -72.999474 0.000224 + 30491.015625 -69.053177 0.000353 + 30555.615234 -66.667831 0.000464 + 30620.214844 -65.148094 0.000553 + 30684.814453 -64.229034 0.000615 + 30749.414062 -63.792160 0.000646 + 30814.013672 -63.790066 0.000646 + 30878.613281 -64.221817 0.000615 + 30943.212891 -65.133919 0.000554 + 31007.812500 -66.642265 0.000465 + 31072.412109 -69.006081 0.000355 + 31137.011719 -72.900230 0.000226 + 31201.611328 -81.170776 0.000087 + 31266.210938 -85.060944 0.000056 + 31330.810547 -74.142868 0.000196 + 31395.410156 -69.708229 0.000327 + 31460.009766 -67.095482 0.000442 + 31524.609375 -65.433830 0.000535 + 31589.208984 -64.408722 0.000602 + 31653.808594 -63.882088 0.000640 + 31718.408203 -63.795303 0.000646 + 31783.007812 -64.139229 0.000621 + 31847.607422 -64.950272 0.000566 + 31912.207031 -66.327011 0.000483 + 31976.806641 -68.490295 0.000376 + 32041.406250 -71.987686 0.000252 + 32106.005859 -78.816048 0.000115 + 32170.605469 -91.092804 0.000028 + 32235.205078 -75.444229 0.000169 + 32299.804688 -70.406883 0.000302 + 32364.404297 -67.538834 0.000420 + 32429.003906 -65.724152 0.000517 + 32493.603516 -64.587914 0.000590 + 32558.203125 -63.969238 0.000633 + 32622.802734 -63.797520 0.000646 + 32687.402344 -64.054871 0.000627 + 32752.001953 -64.768204 0.000578 + 32816.601562 -66.021255 0.000500 + 32881.201172 -68.002449 0.000398 + 32945.800781 -71.162201 0.000277 + 33010.400391 -76.968475 0.000142 + 33075.000000 -76.968475 0.000142 + 33139.599609 -71.162201 0.000277 + 33204.199219 -68.002449 0.000398 + 33268.798828 -66.021255 0.000500 + 33333.398438 -64.768204 0.000578 + 33397.998047 -64.054871 0.000627 + 33462.597656 -63.797520 0.000646 + 33527.197266 -63.969238 0.000633 + 33591.796875 -64.587914 0.000590 + 33656.396484 -65.724152 0.000517 + 33720.996094 -67.538834 0.000420 + 33785.595703 -70.406883 0.000302 + 33850.195312 -75.444229 0.000169 + 33914.794922 -91.092804 0.000028 + 33979.394531 -78.816048 0.000115 + 34043.994141 -71.987686 0.000252 + 34108.593750 -68.490295 0.000376 + 34173.193359 -66.327011 0.000483 + 34237.792969 -64.950272 0.000566 + 34302.392578 -64.139229 0.000621 + 34366.992188 -63.795303 0.000646 + 34431.591797 -63.882088 0.000640 + 34496.191406 -64.408722 0.000602 + 34560.791016 -65.433830 0.000535 + 34625.390625 -67.095482 0.000442 + 34689.990234 -69.708229 0.000327 + 34754.589844 -74.142868 0.000196 + 34819.189453 -85.060944 0.000056 + 34883.789062 -81.170776 0.000087 + 34948.388672 -72.900230 0.000226 + 35012.988281 -69.006081 0.000355 + 35077.587891 -66.642265 0.000465 + 35142.187500 -65.133919 0.000554 + 35206.787109 -64.221817 0.000615 + 35271.386719 -63.790066 0.000646 + 35335.986328 -63.792160 0.000646 + 35400.585938 -64.229034 0.000615 + 35465.185547 -65.148094 0.000553 + 35529.785156 -66.667831 0.000464 + 35594.384766 -69.053177 0.000353 + 35658.984375 -72.999474 0.000224 + 35723.583984 -81.505341 0.000084 + 35788.183594 -84.444298 0.000060 + 35852.783203 -73.927132 0.000201 + 35917.382812 -69.557610 0.000333 + 35981.982422 -66.970284 0.000448 + 36046.582031 -65.321541 0.000542 + 36111.181641 -64.303749 0.000609 + 36175.781250 -63.782562 0.000647 + 36240.380859 -63.700275 0.000653 + 36304.980469 -64.049126 0.000627 + 36369.580078 -64.866570 0.000571 + 36434.179688 -66.253998 0.000487 + 36498.779297 -68.436539 0.000379 + 36563.378906 -71.977470 0.000252 + 36627.978516 -78.966774 0.000113 + 36692.578125 -89.836014 0.000032 + 36757.177734 -75.104454 0.000176 + 36821.777344 -70.150421 0.000311 + 36886.376953 -67.313004 0.000431 + 36950.976562 -65.512772 0.000530 + 37015.576172 -64.384926 0.000604 + 37080.175781 -63.772121 0.000648 + 37144.775391 -63.605148 0.000660 + 37209.375000 -63.867538 0.000641 + 37273.974609 -64.587288 0.000590 + 37338.574219 -65.850601 0.000510 + 37403.173828 -67.849190 0.000405 + 37467.773438 -71.047348 0.000280 + 37532.373047 -76.973343 0.000142 + 37596.972656 -100.000000 0.000004 + 37661.572266 -76.485512 0.000150 + 37726.171875 -70.794441 0.000289 + 37790.771484 -67.671677 0.000413 + 37855.371094 -65.707840 0.000518 + 37919.970703 -64.464859 0.000598 + 37984.570312 -63.758369 0.000649 + 38049.169922 -63.506504 0.000668 + 38113.769531 -63.683537 0.000654 + 38178.369141 -64.308693 0.000609 + 38242.968750 -65.454178 0.000534 + 38307.568359 -67.285744 0.000432 + 38372.167969 -70.186813 0.000309 + 38436.767578 -75.321014 0.000171 + 38501.367188 -92.155983 0.000025 + 38565.966797 -78.162804 0.000124 + 38630.566406 -71.502296 0.000266 + 38695.166016 -68.051674 0.000396 + 38759.765625 -65.909653 0.000506 + 38824.365234 -64.544754 0.000593 + 38888.964844 -63.741508 0.000650 + 38953.564453 -63.403572 0.000676 + 39018.164062 -63.496017 0.000669 + 39082.763672 -64.029839 0.000629 + 39147.363281 -65.064720 0.000558 + 39211.962891 -66.742218 0.000460 + 39276.562500 -69.385399 0.000339 + 39341.162109 -73.900726 0.000202 + 39405.761719 -85.341446 0.000054 + 39470.361328 -80.298035 0.000097 + 39534.960938 -72.288086 0.000243 + 39599.560547 -68.454559 0.000378 + 39664.160156 -66.116966 0.000494 + 39728.759766 -64.622841 0.000587 + 39793.359375 -63.720211 0.000652 + 39857.958984 -63.295509 0.000684 + 39922.558594 -63.303810 0.000684 + 39987.158203 -63.748062 0.000650 + 40051.757812 -64.677383 0.000584 + 40116.357422 -66.212769 0.000489 + 40180.957031 -68.627472 0.000370 + 40245.556641 -72.643448 0.000233 + 40310.156250 -81.473427 0.000084 + 40374.755859 -83.226524 0.000069 + 40439.355469 -73.177101 0.000219 + 40503.955078 -68.887520 0.000359 + 40568.554688 -66.332985 0.000482 + 40633.154297 -64.701447 0.000582 + 40697.753906 -63.694950 0.000654 + 40762.353516 -63.181889 0.000693 + 40826.953125 -63.106930 0.000699 + 40891.552734 -63.464149 0.000671 + 40956.152344 -64.291985 0.000610 + 41020.751953 -65.695320 0.000519 + 41085.351562 -67.906342 0.000402 + 41149.951172 -71.510429 0.000266 + 41214.550781 -78.732735 0.000116 + 41279.150391 -87.857033 0.000040 + 41343.750000 -74.193192 0.000195 + 41408.349609 -69.351929 0.000341 + 41472.949219 -66.555984 0.000470 + 41537.548828 -64.777702 0.000577 + 41602.148438 -63.663448 0.000656 + 41666.748047 -63.060429 0.000703 + 41731.347656 -62.902275 0.000716 + 41795.947266 -63.173603 0.000694 + 41860.546875 -63.904663 0.000638 + 41925.146484 -65.184273 0.000551 + 41989.746094 -67.211250 0.000436 + 42054.345703 -70.466377 0.000300 + 42118.945312 -76.576553 0.000148 + 42183.544922 -99.301361 0.000011 + 42248.144531 -75.392502 0.000170 + 42312.744141 -69.859253 0.000321 + 42377.343750 -66.790588 0.000458 + 42441.943359 -64.853630 0.000572 + 42506.542969 -63.627163 0.000659 + 42571.142578 -62.932217 0.000713 + 42635.742188 -62.690361 0.000734 + 42700.341797 -62.877304 0.000718 + 42764.941406 -63.514870 0.000667 + 42829.541016 -64.678223 0.000584 + 42894.140625 -66.537582 0.000471 + 42958.740234 -69.494308 0.000335 + 43023.339844 -74.782753 0.000182 + 43087.939453 -93.978439 0.000020 + 43152.539062 -76.834648 0.000144 + 43217.138672 -70.414467 0.000301 + 43281.738281 -67.035439 0.000445 + 43346.337891 -64.926979 0.000567 + 43410.937500 -63.582382 0.000662 + 43475.537109 -62.793423 0.000725 + 43540.136719 -62.467247 0.000753 + 43604.736328 -62.571217 0.000744 + 43669.335938 -63.118355 0.000698 + 43733.935547 -64.171257 0.000619 + 43798.535156 -65.877441 0.000508 + 43863.134766 -68.573647 0.000373 + 43927.734375 -73.223534 0.000218 + 43992.333984 -85.613525 0.000052 + 44056.933594 -78.662560 0.000117 + 44121.533203 -71.034187 0.000281 + 44186.132812 -67.294731 0.000432 + 44250.732422 -64.999557 0.000562 + 44315.332031 -63.530270 0.000666 + 44379.931641 -62.644665 0.000738 + 44444.531250 -62.233643 0.000773 + 44509.130859 -62.255745 0.000771 + 44573.730469 -62.714561 0.000732 + 44638.330078 -63.663212 0.000656 + 44702.929688 -65.227982 0.000548 + 44767.529297 -67.695480 0.000412 + 44832.128906 -71.833534 0.000256 + 44896.728516 -81.260773 0.000086 + 44961.328125 -81.101768 0.000088 + 45025.927734 -71.727280 0.000259 + 45090.527344 -67.567329 0.000418 + 45155.126953 -65.067535 0.000558 + 45219.726562 -63.467007 0.000671 + 45284.326172 -62.481232 0.000752 + 45348.925781 -61.984562 0.000796 + 45413.525391 -61.924564 0.000801 + 45478.125000 -62.298256 0.000768 + 45542.724609 -63.146893 0.000696 + 45607.324219 -64.580574 0.000590 + 45671.923828 -66.842964 0.000455 + 45736.523438 -70.559204 0.000297 + 45801.123047 -78.212051 0.000123 + 45865.722656 -84.768745 0.000058 + 45930.322266 -72.525055 0.000236 + 45994.921875 -67.860840 0.000405 + 46059.521484 -65.134140 0.000554 + 46124.121094 -63.393597 0.000677 + 46188.720703 -62.304604 0.000767 + 46253.320312 -61.720978 0.000820 + 46317.919922 -61.579693 0.000834 + 46382.519531 -61.869362 0.000806 + 46447.119141 -62.622856 0.000739 + 46511.718750 -63.933987 0.000636 + 46576.318359 -66.012901 0.000500 + 46640.917969 -69.376022 0.000340 + 46705.517578 -75.832939 0.000162 + 46770.117188 -91.843185 0.000026 + 46834.716797 -73.449486 0.000213 + 46899.316406 -68.172180 0.000390 + 46963.916016 -65.194382 0.000550 + 47028.515625 -63.304436 0.000684 + 47093.115234 -62.107971 0.000785 + 47157.714844 -61.436081 0.000848 + 47222.314453 -61.213749 0.000870 + 47286.914062 -61.421432 0.000849 + 47351.513672 -62.082947 0.000787 + 47416.113281 -63.278957 0.000686 + 47480.712891 -65.191368 0.000550 + 47545.312500 -68.250229 0.000387 + 47609.912109 -73.828125 0.000204 + 47674.511719 -100.000000 0.000009 + 47739.111328 -74.561356 0.000187 + 47803.710938 -68.513046 0.000375 + 47868.310547 -65.249924 0.000546 + 47932.910156 -63.200459 0.000692 + 47997.509766 -61.892078 0.000804 + 48062.109375 -61.129791 0.000878 + 48126.708984 -60.826534 0.000909 + 48191.308594 -60.953465 0.000896 + 48255.908203 -61.526299 0.000839 + 48320.507812 -62.614243 0.000740 + 48385.107422 -64.373940 0.000604 + 48449.707031 -67.170158 0.000438 + 48514.306641 -72.074837 0.000249 + 48578.906250 -86.648331 0.000047 + 48643.505859 -75.929855 0.000160 + 48708.105469 -68.881821 0.000360 + 48772.705078 -65.297554 0.000543 + 48837.304688 -63.075897 0.000702 + 48901.904297 -61.650623 0.000827 + 48966.503906 -60.796383 0.000912 + 49031.103516 -60.411190 0.000954 + 49095.703125 -60.458618 0.000949 + 49160.302734 -60.945457 0.000897 + 49224.902344 -61.930298 0.000801 + 49289.501953 -63.549938 0.000665 + 49354.101562 -66.113571 0.000495 + 49418.701172 -70.480301 0.000299 + 49483.300781 -81.151131 0.000088 + 49547.900391 -77.717232 0.000130 + 49612.500000 -69.292953 0.000343 + 49677.099609 -65.338783 0.000541 + 49741.699219 -62.929710 0.000714 + 49806.298828 -61.381954 0.000853 + 49870.898438 -60.432983 0.000951 + 49935.498047 -59.965607 0.001004 + 50000.097656 -59.933750 0.001008 + 50064.697266 -60.337479 0.000962 + 50129.296875 -61.224205 0.000869 + 50193.896484 -62.712959 0.000732 + 50258.496094 -65.070374 0.000558 + 50323.095703 -68.995399 0.000355 + 50387.695312 -77.524490 0.000133 + 50452.294922 -80.223701 0.000097 + 50516.894531 -69.759087 0.000325 + 50581.494141 -65.370667 0.000539 + 50646.093750 -62.757633 0.000728 + 50710.693359 -61.080471 0.000883 + 50775.292969 -60.033680 0.000996 + 50839.892578 -59.483616 0.001061 + 50904.492188 -59.372753 0.001075 + 50969.091797 -59.694530 0.001036 + 51033.691406 -60.487232 0.000945 + 51098.291016 -61.854134 0.000808 + 51162.890625 -64.024597 0.000629 + 51227.490234 -67.578011 0.000418 + 51292.089844 -74.696449 0.000184 + 51356.689453 -84.304283 0.000061 + 51421.289062 -70.304214 0.000305 + 51485.888672 -65.398346 0.000537 + 51550.488281 -62.559414 0.000745 + 51615.087891 -60.744297 0.000918 + 51679.687500 -59.596745 0.001048 + 51744.287109 -58.961704 0.001127 + 51808.886719 -58.771996 0.001152 + 51873.486328 -59.012627 0.001120 + 51938.085938 -59.714199 0.001033 + 52002.685547 -60.965012 0.000895 + 52067.285156 -62.964512 0.000711 + 52131.884766 -66.196312 0.000490 + 52196.484375 -72.297798 0.000243 + 52261.083984 -94.389519 0.000019 + 52325.683594 -70.973564 0.000283 + 52390.283203 -65.429832 0.000535 + 52454.882812 -62.336903 0.000764 + 52519.482422 -60.373631 0.000958 + 52584.082031 -59.119576 0.001107 + 52648.681641 -58.396976 0.001203 + 52713.281250 -58.126968 0.001241 + 52777.880859 -58.286922 0.001218 + 52842.480469 -58.898315 0.001135 + 52907.080078 -60.037033 0.000996 + 52971.679688 -61.875553 0.000806 + 53036.279297 -64.821152 0.000574 + 53100.878906 -70.131248 0.000311 + 53165.478516 -90.275864 0.000031 + 53230.078125 -71.871254 0.000255 + 53294.677734 -65.493515 0.000531 + 53359.277344 -62.106640 0.000785 + 53423.876953 -59.978786 0.001002 + 53488.476562 -58.610329 0.001174 + 53553.076172 -57.795464 0.001289 + 53617.675781 -57.442314 0.001342 + 53682.275391 -57.519058 0.001331 + 53746.875000 -58.038994 0.001253 + 53811.474609 -59.065598 0.001114 + 53876.074219 -60.747375 0.000918 + 53940.673828 -63.424065 0.000674 + 54005.273438 -68.071823 0.000395 + 54069.873047 -80.651566 0.000093 + 54134.472656 -73.253914 0.000217 + 54199.072266 -65.668625 0.000521 + 54263.671875 -61.916138 0.000802 + 54328.271484 -59.597141 0.001047 + 54392.871094 -58.099991 0.001245 + 54457.470703 -57.183292 0.001383 + 54522.070312 -56.739555 0.001456 + 54586.669922 -56.726894 0.001458 + 54651.269531 -57.148190 0.001389 + 54715.869141 -58.055210 0.001251 + 54780.468750 -59.571301 0.001051 + 54845.068359 -61.973900 0.000797 + 54909.667969 -66.002464 0.000501 + 54974.267578 -75.007957 0.000178 + 55038.867188 -76.027138 0.000158 + 55103.466797 -66.202026 0.000490 + 55168.066406 -61.925838 0.000801 + 55232.666016 -59.355042 0.001077 + 55297.265625 -57.696621 0.001304 + 55361.865234 -56.656635 0.001469 + 55426.464844 -56.104431 0.001566 + 55491.064453 -55.983944 0.001588 + 55555.664062 -56.286488 0.001533 + 55620.263672 -57.046913 0.001405 + 55684.863281 -58.358494 0.001208 + 55749.462891 -60.428680 0.000952 + 55814.062500 -63.763126 0.000648 + 55878.662109 -70.110649 0.000312 + 55943.261719 -87.813911 0.000041 + 56007.861328 -68.103874 0.000393 + 56072.460938 -62.745205 0.000729 + 56137.060547 -59.730328 0.001032 + 56201.660156 -57.811268 0.001287 + 56266.259766 -56.581841 0.001482 + 56330.859375 -55.865685 0.001610 + 56395.458984 -55.581482 0.001663 + 56460.058594 -55.696812 0.001641 + 56524.658203 -56.216286 0.001546 + 56589.257812 -57.184135 0.001383 + 56653.857422 -58.701527 0.001161 + 56718.457031 -60.986828 0.000893 + 56783.056641 -64.570816 0.000591 + 56847.656250 -71.347839 0.000271 + 56912.255859 -85.628151 0.000052 + 56976.855469 -68.780762 0.000364 + 57041.455078 -63.728230 0.000651 + 57106.054688 -60.884552 0.000903 + 57170.654297 -59.070004 0.001113 + 57235.253906 -57.878582 0.001277 + 57299.853516 -57.114773 0.001394 + 57364.453125 -56.660595 0.001469 + 57429.052734 -56.430927 0.001508 + 57493.652344 -56.352348 0.001522 + 57558.251953 -56.355679 0.001521 + 57622.851562 -56.373440 0.001518 + 57687.451172 -56.344891 0.001523 + 57752.050781 -56.228798 0.001544 + 57816.650391 -56.014076 0.001582 + 57881.250000 -55.731697 0.001635 + 57945.849609 -55.456886 0.001687 + 58010.449219 -55.311096 0.001716 + 58075.048828 -55.476501 0.001683 + 58139.648438 -56.253147 0.001539 + 58204.248047 -58.287296 0.001218 + 58268.847656 -63.904583 0.000638 + 58333.447266 -70.528481 0.000298 + 58398.046875 -55.389706 0.001700 + 58462.646484 -48.645748 0.003696 + 58527.246094 -43.846790 0.006422 + 58591.845703 -39.977604 0.010026 + 58656.445312 -36.676125 0.014662 + 58721.044922 -33.770035 0.020488 + 58785.644531 -31.162664 0.027661 + 58850.244141 -28.793827 0.036334 + 58914.843750 -26.622974 0.046650 + 58979.443359 -24.621235 0.058741 + 59044.042969 -22.767096 0.072719 + 59108.642578 -21.043924 0.088676 + 59173.242188 -19.438532 0.106678 + 59237.841797 -17.940182 0.126763 + 59302.441406 -16.539972 0.148937 + 59367.041016 -15.230392 0.173173 + 59431.640625 -14.005014 0.199411 + 59496.240234 -12.858274 0.227555 + 59560.839844 -11.785291 0.257475 + 59625.439453 -10.781745 0.289010 + 59690.039062 -9.843774 0.321967 + 59754.638672 -8.967894 0.356127 + 59819.238281 -8.150934 0.391249 + 59883.837891 -7.389989 0.427071 + 59948.437500 -6.682366 0.463321 + 60013.037109 -6.025558 0.499715 + 60077.636719 -5.417207 0.535969 + 60142.236328 -4.855081 0.571802 + 60206.835938 -4.337048 0.606943 + 60271.435547 -3.861061 0.641131 + 60336.035156 -3.425136 0.674129 + 60400.634766 -3.027342 0.705721 + 60465.234375 -2.665783 0.735717 + 60529.833984 -2.338596 0.763959 + 60594.433594 -2.043930 0.790321 + 60659.033203 -1.779952 0.814709 + 60723.632812 -1.544833 0.837063 + 60788.232422 -1.336748 0.857359 + 60852.832031 -1.153877 0.875601 + 60917.431641 -0.994401 0.891826 + 60982.031250 -0.856509 0.906097 + 61046.630859 -0.738401 0.918502 + 61111.230469 -0.638297 0.929148 + 61175.830078 -0.554444 0.938162 + 61240.429688 -0.485124 0.945679 + 61305.029297 -0.428671 0.951846 + 61369.628906 -0.383479 0.956811 + 61434.228516 -0.348018 0.960725 + 61498.828125 -0.320844 0.963735 + 61563.427734 -0.300613 0.965983 + 61628.027344 -0.286091 0.967599 + 61692.626953 -0.276167 0.968705 + 61757.226562 -0.269847 0.969410 + 61821.826172 -0.266274 0.969809 + 61886.425781 -0.264714 0.969983 + 61951.025391 -0.264565 0.970000 + 62015.625000 -0.265341 0.969913 + 62080.224609 -0.266671 0.969765 + 62144.824219 -0.268283 0.969585 + 62209.423828 -0.269993 0.969394 + 62274.023438 -0.271688 0.969205 + 62338.623047 -0.273316 0.969023 + 62403.222656 -0.274867 0.968850 + 62467.822266 -0.276358 0.968684 + 62532.421875 -0.277826 0.968520 + 62597.021484 -0.279309 0.968355 + 62661.621094 -0.280843 0.968184 + 62726.220703 -0.282450 0.968005 + 62790.820312 -0.284139 0.967817 + 62855.419922 -0.285899 0.967620 + 62920.019531 -0.287702 0.967420 + 62984.619141 -0.289502 0.967219 + 63049.218750 -0.291241 0.967026 + 63113.818359 -0.292850 0.966846 + 63178.417969 -0.294260 0.966689 + 63243.017578 -0.295399 0.966563 + 63307.617188 -0.296210 0.966473 + 63372.216797 -0.296640 0.966425 + 63436.816406 -0.296657 0.966423 + 63501.416016 -0.296246 0.966468 + 63566.015625 -0.295421 0.966560 + 63630.615234 -0.294208 0.966695 + 63695.214844 -0.292661 0.966867 + 63759.814453 -0.290849 0.967069 + 63824.414062 -0.288857 0.967291 + 63889.013672 -0.286781 0.967522 + 63953.613281 -0.284723 0.967751 + 64018.212891 -0.282787 0.967967 + 64082.812500 -0.281067 0.968159 + 64147.412109 -0.279652 0.968317 + 64212.011719 -0.278611 0.968433 + 64276.611328 -0.277998 0.968501 + 64341.210938 -0.277840 0.968519 + 64405.810547 -0.278147 0.968484 + 64470.410156 -0.278900 0.968401 + 64535.009766 -0.280057 0.968271 + 64599.609375 -0.281559 0.968104 + 64664.208984 -0.283323 0.967907 + 64728.808594 -0.285258 0.967692 + 64793.408203 -0.287261 0.967469 + 64858.007812 -0.289227 0.967250 + 64922.607422 -0.291053 0.967046 + 64987.207031 -0.292643 0.966870 + 65051.806641 -0.293914 0.966728 + 65116.406250 -0.294800 0.966629 + 65181.005859 -0.295257 0.966579 + 65245.605469 -0.295263 0.966578 + 65310.205078 -0.294819 0.966627 + 65374.804688 -0.293951 0.966724 + 65439.404297 -0.292708 0.966862 + 65504.003906 -0.291158 0.967035 + 65568.603516 -0.289386 0.967232 + 65633.203125 -0.287486 0.967444 + 65697.802734 -0.285563 0.967658 + 65762.402344 -0.283719 0.967863 + 65827.001953 -0.282053 0.968049 + 65891.601562 -0.280655 0.968205 + 65956.201172 -0.279600 0.968322 + 66020.800781 -0.278944 0.968396 + 66085.400391 -0.278720 0.968421 diff --git a/sw/ground_segment/multimon/filter/mkfifsk96.c b/sw/ground_segment/multimon/filter/mkfifsk96.c new file mode 100644 index 0000000000..0cfa87cfa9 --- /dev/null +++ b/sw/ground_segment/multimon/filter/mkfifsk96.c @@ -0,0 +1,43 @@ +float fir_coeff[72] = { + 0.000709, 0.000686, 0.000440, -0.000018, + -0.000618, -0.001198, -0.001520, -0.001332, + -0.000493, 0.000909, 0.002494, 0.003648, + 0.003711, 0.002258, -0.000630, -0.004235, + -0.007308, -0.008433, -0.006559, -0.001538, + 0.005567, 0.012568, 0.016708, 0.015557, + 0.008024, -0.004897, -0.019931, -0.032062, + -0.035748, -0.026514, -0.002471, 0.034724, + 0.079822, 0.124956, 0.161417, 0.181779, + 0.181779, 0.161417, 0.124956, 0.079822, + 0.034724, -0.002471, -0.026514, -0.035748, + -0.032062, -0.019931, -0.004897, 0.008024, + 0.015557, 0.016708, 0.012568, 0.005567, + -0.001538, -0.006559, -0.008433, -0.007308, + -0.004235, -0.000630, 0.002258, 0.003711, + 0.003648, 0.002494, 0.000909, -0.000493, + -0.001332, -0.001520, -0.001198, -0.000618, + -0.000018, 0.000440, 0.000686, 0.000709 +}; + +#include +#define UPSAMP 3 +#define FILTLEN (sizeof(fir_coeff)/sizeof(fir_coeff[0])/UPSAMP) + +void main(void) +{ + const float *f; + int i, j; + + printf("#define FILTLEN %d\n" + "#define UPSAMP %d\n" + "static const float inp_filt[%d][%d] = {\n\t", FILTLEN, UPSAMP, UPSAMP, FILTLEN); + for (i = 0; i < UPSAMP; i++) { + printf("{"); + for (j = 0, f = fir_coeff+i; j < FILTLEN; j++, f += UPSAMP) + printf("%10f%s", *f, (j < FILTLEN-1) ? (((j & 3) == 3) ? ",\n\t " : ",") : ""); + printf("}%s", (i < UPSAMP-1) ? ",\n\t" : ""); + } + printf("\n};\n\n"); + exit(0); +} + diff --git a/sw/ground_segment/multimon/gen.c b/sw/ground_segment/multimon/gen.c new file mode 100644 index 0000000000..6a714aa15a --- /dev/null +++ b/sw/ground_segment/multimon/gen.c @@ -0,0 +1,520 @@ +/* + * gen.c -- generate different test signals + * + * Copyright (C) 1997 + * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* ---------------------------------------------------------------------- */ + +#include "gen.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef SUN_AUDIO +#include +#include +#include +#else /* SUN_AUDIO */ +#include +#include +#endif /* SUN_AUDIO */ + +/* ---------------------------------------------------------------------- */ + +#ifdef __sun__ +#include + +int snprintf(char *buf, size_t sz, const char *fmt, ...) +{ + int i; + + va_list arg; + va_start(arg, fmt); + i = vsprintf(buf, fmt, arg); + va_end(arg); + return i; +} + +#endif /* __sun__ */ + +/* ---------------------------------------------------------------------- */ + +static const char *allowed_types[] = { + "raw", "aiff", "au", "hcom", "sf", "voc", "cdr", "dat", + "smp", "wav", "maud", "vwe", NULL +}; + +/* ---------------------------------------------------------------------- */ + +typedef void (*t_init_procs)(struct gen_params *, struct gen_state *); +typedef int (*t_gen_procs)(signed short *, int, struct gen_params *, struct gen_state *); + +static const t_init_procs init_procs[] = { + gen_init_dtmf, gen_init_sine, gen_init_zvei, gen_init_hdlc +}; + +static const t_gen_procs gen_procs[] = { + gen_dtmf, gen_sine, gen_zvei, gen_hdlc +}; + +/* ---------------------------------------------------------------------- */ + +#define MAX_GEN 16 +static struct gen_params params[MAX_GEN]; +static struct gen_state state[MAX_GEN]; +static int num_gen = 0; + +/* ---------------------------------------------------------------------- */ + +static int process_buffer(short *buf, int len) +{ + int i; + int totnum = 0, num; + + memset(buf, 0, len*sizeof(buf[0])); + for (i = 0; i < num_gen; i++) { + if (params[i].type >= sizeof(gen_procs)/sizeof(gen_procs[0])) + break; + if (!gen_procs[params[i].type]) + break; + num = gen_procs[params[i].type](buf, len, params+i, state+i); + if (num > totnum) + totnum = num; + } + return totnum; +} + +/* ---------------------------------------------------------------------- */ +#ifdef SUN_AUDIO + +static void output_sound(unsigned int sample_rate, const char *ifname) +{ + audio_info_t audioinfo; + audio_info_t audioinfo2; + audio_device_t audiodev; + int fd; + short buffer[8192]; + short *sp; + int i, num, num2; + + if ((fd = open(ifname ? ifname : "/dev/audio", O_WRONLY)) < 0) { + perror("open"); + exit (10); + } + if (ioctl(fd, AUDIO_GETDEV, &audiodev) == -1) { + perror("ioctl: AUDIO_GETDEV"); + exit (10); + } + AUDIO_INITINFO(&audioinfo); + audioinfo.record.sample_rate = sample_rate; + audioinfo.record.channels = 1; + audioinfo.record.precision = 16; + audioinfo.record.encoding = AUDIO_ENCODING_LINEAR; + /*audioinfo.record.gain = 0x20; + audioinfo.record.port = AUDIO_LINE_IN; + audioinfo.monitor_gain = 0;*/ + if (ioctl(fd, AUDIO_SETINFO, &audioinfo) == -1) { + perror("ioctl: AUDIO_SETINFO"); + exit (10); + } + if (ioctl(fd, I_FLUSH, FLUSHW) == -1) { + perror("ioctl: I_FLUSH"); + exit (10); + } + if (ioctl(fd, AUDIO_GETINFO, &audioinfo2) == -1) { + perror("ioctl: AUDIO_GETINFO"); + exit (10); + } + fprintf(stdout, "Audio device: name %s, ver %s, config %s, " + "sampling rate %d\n", audiodev.name, audiodev.version, + audiodev.config, audioinfo.record.sample_rate); + do { + num2 = num = process_buffer(sp = buffer, sizeof(buffer)/sizeof(buffer[0])); + while (num > 0) { + i = write(fd, sp, num*sizeof(sp[0])); + if (i < 0 && errno != EAGAIN) { + perror("write"); + exit(4); + } + if (i > 0) { + if (i % sizeof(sp[0])) + fprintf(stderr, "gen: warning: write wrote noninteger number of samples\n"); + num -= i / sizeof(sp[0]); + } + } + } while (num2 > 0); + close(fd); +} + +#else /* SUN_AUDIO */ +/* ---------------------------------------------------------------------- */ + +static void output_sound(unsigned int sample_rate, const char *ifname) +{ + int sndparam; + int fd; + union { + short s[8192]; + unsigned char b[8192]; + } b; + int i; + short *sp; + unsigned char *bp; + int fmt = 0, num, num2; + + if ((fd = open(ifname ? ifname : "/dev/dsp", O_WRONLY)) < 0) { + perror("open"); + exit (10); + } + sndparam = AFMT_S16_LE; /* we want 16 bits/sample signed */ + /* little endian; works only on little endian systems! */ + if (ioctl(fd, SNDCTL_DSP_SETFMT, &sndparam) == -1) { + perror("ioctl: SNDCTL_DSP_SETFMT"); + exit (10); + } + if (sndparam != AFMT_S16_LE) { + fmt = 1; + sndparam = AFMT_U8; + if (ioctl(fd, SNDCTL_DSP_SETFMT, &sndparam) == -1) { + perror("ioctl: SNDCTL_DSP_SETFMT"); + exit (10); + } + if (sndparam != AFMT_U8) { + perror("ioctl: SNDCTL_DSP_SETFMT"); + exit (10); + } + } + sndparam = 0; /* we want only 1 channel */ + if (ioctl(fd, SNDCTL_DSP_STEREO, &sndparam) == -1) { + perror("ioctl: SNDCTL_DSP_STEREO"); + exit (10); + } + if (sndparam != 0) { + fprintf(stderr, "gen: Error, cannot set the channel " + "number to 1\n"); + exit (10); + } + sndparam = sample_rate; + if (ioctl(fd, SNDCTL_DSP_SPEED, &sndparam) == -1) { + perror("ioctl: SNDCTL_DSP_SPEED"); + exit (10); + } + if ((10*abs(sndparam-sample_rate)) > sample_rate) { + perror("ioctl: SNDCTL_DSP_SPEED"); + exit (10); + } + if (sndparam != sample_rate) { + fprintf(stderr, "Warning: Sampling rate is %u, " + "requested %u\n", sndparam, sample_rate); + } +#if 0 + sndparam = 4; + if (ioctl(fd, SOUND_PCM_SUBDIVIDE, &sndparam) == -1) { + perror("ioctl: SOUND_PCM_SUBDIVIDE"); + } + if (sndparam != 4) { + perror("ioctl: SOUND_PCM_SUBDIVIDE"); + } +#endif + do { + num2 = num = process_buffer(b.s, sizeof(b.s)/sizeof(b.s[0])); + if (fmt) { + for (bp = b.b, sp = b.s, i = sizeof(b.s)/sizeof(b.s[0]); i > 0; i--, bp++, sp++) + *bp = 0x80 + (*sp >> 8); + bp = b.b; + while (num > 0) { + i = write(fd, bp, num*sizeof(bp[0])); + if (i < 0 && errno != EAGAIN) { + perror("write"); + exit(4); + } + if (i > 0) { + if (i % sizeof(bp[0])) + fprintf(stderr, "gen: warning: write wrote noninteger number of samples\n"); + num -= i / sizeof(bp[0]); + } + } + } else { + sp = b.s; + while (num > 0) { + i = write(fd, sp, num*sizeof(sp[0])); + if (i < 0 && errno != EAGAIN) { + perror("write"); + exit(4); + } + if (i > 0) { + if (i % sizeof(sp[0])) + fprintf(stderr, "gen: warning: write wrote noninteger number of samples\n"); + num -= i / sizeof(sp[0]); + } + } + } + } while (num2 > 0); + close(fd); +} +#endif /* SUN_AUDIO */ + +/* ---------------------------------------------------------------------- */ + +static void output_file(unsigned int sample_rate, const char *fname, const char *type) +{ + struct stat statbuf; + int pipedes[2]; + int pid = 0, soxstat; + int fd; + int i, num, num2; + short buffer[8192]; + short *sp; + + /* + * if the input type is not raw, sox is started to convert the + * samples to the requested format + */ + if (!type || !strcmp(type, "raw")) { + if ((fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0777)) < 0) { + perror("open"); + exit(10); + } + } else { + if (stat(fname, &statbuf)) { + perror("stat"); + exit(10); + } + if (pipe(pipedes)) { + perror("pipe"); + exit(10); + } + if (!(pid = fork())) { + char srate[8]; + /* + * child starts here... first set up filedescriptors, + * then start sox... + */ + snprintf(srate, sizeof(srate), "%d", sample_rate); + close(pipedes[1]); /* close writing pipe end */ + close(0); /* close standard input */ + if (dup2(pipedes[0], 0) < 0) + perror("dup2"); + close(pipedes[0]); /* close reading pipe end */ + execlp("sox", "sox", + "-t", "raw", "-s", "-w", "-r", srate, "-", + "-t", type, fname, + NULL); + perror("execlp"); + exit(10); + } + if (pid < 0) { + perror("fork"); + exit(10); + } + close(pipedes[0]); /* close reading pipe end */ + fd = pipedes[1]; + } + /* + * modulate + */ + do { + num2 = num = process_buffer(sp = buffer, sizeof(buffer)/sizeof(buffer[0])); + while (num > 0) { + i = write(fd, sp, num*sizeof(sp[0])); + if (i < 0 && errno != EAGAIN) { + perror("write"); + exit(4); + } + if (i > 0) { + if (i % sizeof(sp[0])) + fprintf(stderr, "gen: warning: write wrote noninteger number of samples\n"); + num -= i / sizeof(sp[0]); + } + } + } while (num2 > 0); + close(fd); + waitpid(pid, &soxstat, 0); +} + +/* ---------------------------------------------------------------------- */ + +static const char usage_str[] = "gen\n" +"Generates test signals\n" +"(C) 1997 by Thomas Sailer HB9JNX/AE4WA\n" +" -t : input file type (any other type than raw requires sox)\n" +" -a : amplitude\n" +" -d : encode DTMF string\n" +" -z : encode ZVEI string\n" +" -s : encode sine\n" +" -p : encode hdlc packet\n"; + +void main(int argc, char *argv[]) +{ + int c; + int errflg = 0; + char **otype; + char *output_type = "hw"; + char *cp; + + fprintf(stdout, "gen - (C) 1997 by Tom Sailer HB9JNX/AE4WA\n"); + while ((c = getopt(argc, argv, "t:a:d:s:z:p:")) != EOF) { + switch (c) { + case '?': + errflg++; + break; + + case 't': + for (otype = (char **)allowed_types; *otype; otype++) + if (!strcmp(*otype, optarg)) { + output_type = *otype; + goto outtypefound; + } + fprintf(stderr, "invalid output type \"%s\"\n" + "allowed types: ", optarg); + for (otype = (char **)allowed_types; *otype; otype++) + fprintf(stderr, "%s ", *otype); + fprintf(stderr, "\n"); + errflg++; + outtypefound: + break; + + case 'a': + if (num_gen <= 0) { + fprintf(stderr, "gen: no generator selected\n"); + errflg++; + } + if (!(cp = strstr(optarg, "dB"))) + cp = strstr(optarg, "db"); + if (cp) { + *cp = '\0'; + params[num_gen-1].ampl = 16384.0 * pow(10.0, strtod(optarg, NULL) / 20.0); + } else { + params[num_gen-1].ampl = 16384.0 * strtod(optarg, NULL); + } + break; + + case 'd': + num_gen++; + if (num_gen > MAX_GEN) { + fprintf(stderr, "too many generators\n"); + errflg++; + break; + } + params[num_gen-1].type = gentype_dtmf; + params[num_gen-1].ampl = 16384; + params[num_gen-1].p.dtmf.duration = MS(100); + params[num_gen-1].p.dtmf.pause = MS(100); + strncpy(params[num_gen-1].p.dtmf.str, optarg, sizeof(params[num_gen-1].p.dtmf.str)); + break; + + case 's': + num_gen++; + if (num_gen > MAX_GEN) { + fprintf(stderr, "too many generators\n"); + errflg++; + break; + } + params[num_gen-1].type = gentype_sine; + params[num_gen-1].ampl = 16384; + params[num_gen-1].p.sine.duration = MS(1000); + params[num_gen-1].p.sine.freq = strtoul(optarg, NULL, 0); + break; + + case 'z': + num_gen++; + if (num_gen > MAX_GEN) { + fprintf(stderr, "too many generators\n"); + errflg++; + break; + } + params[num_gen-1].type = gentype_zvei; + params[num_gen-1].ampl = 16384; + params[num_gen-1].p.zvei.duration = MS(50); + params[num_gen-1].p.zvei.pause = MS(50); + strncpy(params[num_gen-1].p.zvei.str, optarg, sizeof(params[num_gen-1].p.dtmf.str)); + break; + + case 'p': + num_gen++; + if (num_gen > MAX_GEN) { + fprintf(stderr, "too many generators\n"); + errflg++; + break; + } + params[num_gen-1].type = gentype_hdlc; + params[num_gen-1].ampl = 16384; + params[num_gen-1].p.hdlc.modulation = 0; + params[num_gen-1].p.hdlc.txdelay = 100; + params[num_gen-1].p.hdlc.pkt[0] = ('H') << 1; + params[num_gen-1].p.hdlc.pkt[1] = ('B') << 1; + params[num_gen-1].p.hdlc.pkt[2] = ('9') << 1; + params[num_gen-1].p.hdlc.pkt[3] = ('J') << 1; + params[num_gen-1].p.hdlc.pkt[4] = ('N') << 1; + params[num_gen-1].p.hdlc.pkt[5] = ('X') << 1; + params[num_gen-1].p.hdlc.pkt[6] = (0x00) << 1; + params[num_gen-1].p.hdlc.pkt[7] = ('A') << 1; + params[num_gen-1].p.hdlc.pkt[8] = ('E') << 1; + params[num_gen-1].p.hdlc.pkt[9] = ('4') << 1; + params[num_gen-1].p.hdlc.pkt[10] = ('W') << 1; + params[num_gen-1].p.hdlc.pkt[11] = ('A') << 1; + params[num_gen-1].p.hdlc.pkt[12] = (' ') << 1; + params[num_gen-1].p.hdlc.pkt[13] = ((0x00) << 1) | 1; + params[num_gen-1].p.hdlc.pkt[14] = 0x03; + params[num_gen-1].p.hdlc.pkt[15] = 0xf0; + strncpy(params[num_gen-1].p.hdlc.pkt+16, optarg, + sizeof(params[num_gen-1].p.hdlc.pkt)-16); + params[num_gen-1].p.hdlc.pktlen = 16 + + strlen(params[num_gen-1].p.hdlc.pkt+16); + } + } + + if (errflg || num_gen <= 0) { + (void)fprintf(stderr, usage_str); + exit(2); + } + + memset(state, 0, sizeof(state)); + for (c = 0; c < num_gen; c++) { + if (params[c].type >= sizeof(init_procs)/sizeof(init_procs[0])) + break; + if (!init_procs[params[c].type]) + break; + init_procs[params[c].type](params+c, state+c); + } + + if (!strcmp(output_type, "hw")) { + if ((argc - optind) >= 1) + output_sound(SAMPLE_RATE, argv[optind]); + else + output_sound(SAMPLE_RATE, NULL); + exit(0); + } + if ((argc - optind) < 1) { + (void)fprintf(stderr, "no destination file specified\n"); + exit(4); + } + output_file(SAMPLE_RATE, argv[optind], output_type); + exit(0); +} + + + diff --git a/sw/ground_segment/multimon/gen.h b/sw/ground_segment/multimon/gen.h new file mode 100644 index 0000000000..95d5c15add --- /dev/null +++ b/sw/ground_segment/multimon/gen.h @@ -0,0 +1,97 @@ +/* + * gen.h -- generate different test signals + * + * Copyright (C) 1997 + * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* ---------------------------------------------------------------------- */ + +#define SAMPLE_RATE 22050 +#define MS(x) ((float)(x)*SAMPLE_RATE/1000) + +extern const int costabi[0x400]; + +#define COS(x) costabi[(((x)>>6)&0x3ffu)] + +enum gen_type { gentype_dtmf, gentype_sine, gentype_zvei, gentype_hdlc }; + +struct gen_params { + enum gen_type type; + int ampl; + union { + struct { + int duration; + int pause; + char str[256]; + } dtmf; + struct { + int duration; + int freq; + } sine; + struct { + int duration; + int pause; + char str[256]; + } zvei; + struct { + int modulation; + int txdelay; + int pktlen; + unsigned char pkt[256]; + } hdlc; + } p; +}; + +struct gen_state { + union { + struct { + int ch_idx; + int ph_row, ph_col, phinc_row, phinc_col; + int time, time2; + } dtmf; + struct { + int ph, phinc; + int time; + } sine; + struct { + int ch_idx; + int ph, phinc; + int time, time2; + } zvei; + struct { + int lastb; + int ch_idx, bitmask; + unsigned int ph, phinc, bitph; + unsigned int datalen; + unsigned char data[512]; + } hdlc; + } s; +}; + +extern void gen_init_dtmf(struct gen_params *p, struct gen_state *s); +extern int gen_dtmf(signed short *buf, int buflen, struct gen_params *p, struct gen_state *s); + +extern void gen_init_sine(struct gen_params *p, struct gen_state *s); +extern int gen_sine(signed short *buf, int buflen, struct gen_params *p, struct gen_state *s); + +extern void gen_init_zvei(struct gen_params *p, struct gen_state *s); +extern int gen_zvei(signed short *buf, int buflen, struct gen_params *p, struct gen_state *s); + +extern void gen_init_hdlc(struct gen_params *p, struct gen_state *s); +extern int gen_hdlc(signed short *buf, int buflen, struct gen_params *p, struct gen_state *s); + diff --git a/sw/ground_segment/multimon/gen_dtmf.c b/sw/ground_segment/multimon/gen_dtmf.c new file mode 100644 index 0000000000..92a5f9999e --- /dev/null +++ b/sw/ground_segment/multimon/gen_dtmf.c @@ -0,0 +1,95 @@ +/* + * gen_dtmf.c -- generate DTMF sequences + * + * Copyright (C) 1997 + * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* ---------------------------------------------------------------------- */ + +#include "gen.h" +#include +#include +#include + +/* ---------------------------------------------------------------------- */ + +/* + * + * DTMF frequencies + * + * 1209 1336 1477 1633 + * 697 1 2 3 A + * 770 4 5 6 B + * 852 7 8 9 C + * 941 * 0 # D + * + */ + + +static const char *dtmf_transl = "123A456B789C*0#D"; + +#define PHINC(x) ((float)(x)*0x10000/SAMPLE_RATE) + +static const unsigned int row_freq[4] = { + PHINC(697), PHINC(770), PHINC(852), PHINC(941) +}; + +static const unsigned int col_freq[4] = { + PHINC(1209), PHINC(1336), PHINC(1477), PHINC(1633) +}; + +void gen_init_dtmf(struct gen_params *p, struct gen_state *s) +{ + memset(s, 0, sizeof(struct gen_state)); +} + +int gen_dtmf(signed short *buf, int buflen, struct gen_params *p, struct gen_state *s) +{ + char c; + char *cp; + int num = 0, i; + + for (; buflen > 0; buflen--, buf++, num++) { + if (s->s.dtmf.time <= 0) { + c = p->p.dtmf.str[s->s.dtmf.ch_idx]; + if (!c) + return num; + s->s.dtmf.ch_idx++; + cp = memchr(dtmf_transl, toupper(c), 16); + if (!cp) { + s->s.dtmf.time = s->s.dtmf.time2 = 1; + fprintf(stderr, "gen: dtmf; invalid char '%c'\n", c); + } else { + s->s.dtmf.time = p->p.dtmf.duration + p->p.dtmf.pause; + s->s.dtmf.time2 = p->p.dtmf.duration; + i = cp - dtmf_transl; + s->s.dtmf.phinc_row = row_freq[(i >> 2) & 3]; + s->s.dtmf.phinc_col = col_freq[i & 3]; + } + } else if (!s->s.dtmf.time2) { + s->s.dtmf.phinc_row = s->s.dtmf.phinc_col = 0; + s->s.dtmf.ph_row = s->s.dtmf.ph_col = 0xc000; + } + s->s.dtmf.time--; + s->s.dtmf.time2--; + *buf += ((p->ampl >> 1) * (COS(s->s.dtmf.ph_row) + COS(s->s.dtmf.ph_col))) >> 15; + s->s.dtmf.ph_row += s->s.dtmf.phinc_row; + s->s.dtmf.ph_col += s->s.dtmf.phinc_col; + } + return num; +} diff --git a/sw/ground_segment/multimon/gen_hdlc.c b/sw/ground_segment/multimon/gen_hdlc.c new file mode 100644 index 0000000000..59961c2e6b --- /dev/null +++ b/sw/ground_segment/multimon/gen_hdlc.c @@ -0,0 +1,208 @@ +/* + * gen_hdlc.c -- generate DTMF sequences + * + * Copyright (C) 1997 + * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* ---------------------------------------------------------------------- */ + +#include "gen.h" +#include + +/* ---------------------------------------------------------------------- */ +/* + * the CRC routines are stolen from WAMPES + * by Dieter Deyke + */ + +static const unsigned short crc_ccitt_table[] = { + 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, + 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, + 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, + 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, + 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, + 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, + 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, + 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, + 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, + 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, + 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, + 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, + 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, + 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, + 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, + 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, + 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, + 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, + 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, + 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, + 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, + 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, + 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, + 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, + 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, + 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, + 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, + 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, + 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, + 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, + 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, + 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 +}; + +/*---------------------------------------------------------------------------*/ + +#if 0 +static inline void append_crc_ccitt(unsigned char *buffer, int len) +{ + unsigned int crc = 0xffff; + + for (;len>0;len--) + crc = (crc >> 8) ^ crc_ccitt_table[(crc ^ *buffer++) & 0xff]; + crc ^= 0xffff; + *buffer++ = crc; + *buffer++ = crc >> 8; +} + +/*---------------------------------------------------------------------------*/ + +static inline int check_crc_ccitt(const unsigned char *buf, int cnt) +{ + unsigned int crc = 0xffff; + + for (; cnt > 0; cnt--) + crc = (crc >> 8) ^ crc_ccitt_table[(crc ^ *buf++) & 0xff]; + return (crc & 0xffff) == 0xf0b8; +} +#endif + +/*---------------------------------------------------------------------------*/ + +static __inline__ int calc_crc_ccitt(const unsigned char *buf, int cnt) +{ + unsigned int crc = 0xffff; + + for (; cnt > 0; cnt--) + crc = (crc >> 8) ^ crc_ccitt_table[(crc ^ *buf++) & 0xff]; + crc ^= 0xffff; + return (crc & 0xffff); +} + +/* ---------------------------------------------------------------------- */ + +struct hdlctx { + unsigned int bitstream; + unsigned int bitbuf; + int numbits; +}; + +static void txb_addbyte(struct gen_state *s, struct hdlctx *hdlctx, + unsigned char bits, unsigned char stuff) +{ + unsigned int mask1, mask2; + unsigned int mask3; + int i; + + if (hdlctx->numbits >= 8) { + if (s->s.hdlc.datalen >= sizeof(s->s.hdlc.data)) + return; + s->s.hdlc.data[s->s.hdlc.datalen++] = hdlctx->bitbuf; + hdlctx->bitbuf >>= 8; + hdlctx->numbits -= 8; + } + hdlctx->bitbuf |= bits << hdlctx->numbits; + hdlctx->bitstream >>= 8; + hdlctx->bitstream |= bits << 8; + mask1 = 0x1f0; + mask2 = 0x100; + mask3 = 0xffffffff >> (31 - hdlctx->numbits); + hdlctx->numbits += 8; + if (!stuff) + goto nostuff; + for(i = 0; i < 8; i++, mask1 <<= 1, mask2 <<= 1, mask3 = (mask3 << 1) | 1) { + if ((hdlctx->bitstream & mask1) != mask1) + continue; + hdlctx->bitstream &= ~mask2; + hdlctx->bitbuf = (hdlctx->bitbuf & mask3) | ((hdlctx->bitbuf & (~mask3)) << 1); + hdlctx->numbits++; + mask3 = (mask3 << 1) | 1; + } +nostuff: + if (hdlctx->numbits >= 8) { + if (s->s.hdlc.datalen >= sizeof(s->s.hdlc.data)) + return; + s->s.hdlc.data[s->s.hdlc.datalen++] = hdlctx->bitbuf; + hdlctx->bitbuf >>= 8; + hdlctx->numbits -= 8; + } +} + +/* ---------------------------------------------------------------------- */ + +void gen_init_hdlc(struct gen_params *p, struct gen_state *s) +{ + struct hdlctx hdlctx = { 0, 0, 0 }; + int i; + + memset(s, 0, sizeof(struct gen_state)); + s->s.hdlc.bitmask = 1; + for (i = 0; i < (p->p.hdlc.txdelay * (1200/100) / 8); i++) + txb_addbyte(s, &hdlctx, 0x7e, 0); + txb_addbyte(s, &hdlctx, 0x7e, 0); + for (i = 0; i < p->p.hdlc.pktlen; i++) + txb_addbyte(s, &hdlctx, p->p.hdlc.pkt[i], 1); + i = calc_crc_ccitt(p->p.hdlc.pkt, p->p.hdlc.pktlen); + txb_addbyte(s, &hdlctx, i, 1); + txb_addbyte(s, &hdlctx, i >> 8, 1); + txb_addbyte(s, &hdlctx, 0x7e, 0); + txb_addbyte(s, &hdlctx, 0x7e, 0); + txb_addbyte(s, &hdlctx, 0x7e, 0); + txb_addbyte(s, &hdlctx, 0x7e, 0); + txb_addbyte(s, &hdlctx, 0x7e, 0); + txb_addbyte(s, &hdlctx, 0x7e, 0); +} + +int gen_hdlc(signed short *buf, int buflen, struct gen_params *p, struct gen_state *s) +{ + int num = 0; + + if (!s || s->s.hdlc.ch_idx < 0 || s->s.hdlc.ch_idx >= s->s.hdlc.datalen) + return 0; + for (; buflen > 0; buflen--, buf++, num++) { + s->s.hdlc.bitph += 0x10000*1200 / SAMPLE_RATE; + if (s->s.hdlc.bitph >= 0x10000u) { + s->s.hdlc.bitph &= 0xffffu; + s->s.hdlc.bitmask <<= 1; + if (s->s.hdlc.bitmask >= 0x100) { + s->s.hdlc.bitmask = 1; + s->s.hdlc.ch_idx++; + if (s->s.hdlc.ch_idx >= s->s.hdlc.datalen) + return num; + } + if (!(s->s.hdlc.data[s->s.hdlc.ch_idx] & s->s.hdlc.bitmask)) + s->s.hdlc.lastb = !s->s.hdlc.lastb; + s->s.hdlc.phinc = (s->s.hdlc.lastb) ? + 0x10000*2200/SAMPLE_RATE : 0x10000*1200/SAMPLE_RATE; + } + *buf += (p->ampl * COS(s->s.hdlc.ph)) >> 15; + s->s.hdlc.ph += s->s.hdlc.phinc; + } + return num; +} + + diff --git a/sw/ground_segment/multimon/gen_sin.c b/sw/ground_segment/multimon/gen_sin.c new file mode 100644 index 0000000000..957e408bde --- /dev/null +++ b/sw/ground_segment/multimon/gen_sin.c @@ -0,0 +1,46 @@ +/* + * gen_sine.c -- generate DTMF sequences + * + * Copyright (C) 1997 + * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* ---------------------------------------------------------------------- */ + +#include "gen.h" +#include + +/* ---------------------------------------------------------------------- */ + +void gen_init_sine(struct gen_params *p, struct gen_state *s) +{ + memset(s, 0, sizeof(struct gen_state)); + s->s.sine.ph = 0; + s->s.sine.phinc = (float)0x10000 * p->p.sine.freq / SAMPLE_RATE; + s->s.sine.time = p->p.sine.duration; +} + +int gen_sine(signed short *buf, int buflen, struct gen_params *p, struct gen_state *s) +{ + int num = 0; + + for (; (buflen > 0) && (s->s.sine.time > 0); buflen--, buf++, num++, s->s.sine.time--) { + *buf += (p->ampl * COS(s->s.sine.ph)) >> 15; + s->s.sine.ph += s->s.sine.phinc; + } + return num; +} diff --git a/sw/ground_segment/multimon/gen_zvei.c b/sw/ground_segment/multimon/gen_zvei.c new file mode 100644 index 0000000000..ffcb147bb4 --- /dev/null +++ b/sw/ground_segment/multimon/gen_zvei.c @@ -0,0 +1,87 @@ +/* + * gen_zvei.c -- generate DTMF sequences + * + * Copyright (C) 1997 + * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* ---------------------------------------------------------------------- */ + +#include "gen.h" +#include +#include +#include + +/* ---------------------------------------------------------------------- */ + +#define PHINC(x) ((float)(x)*0x10000/SAMPLE_RATE) + +static const unsigned int zvei_freq[16] = { + PHINC(2400), PHINC(1060), PHINC(1160), PHINC(1270), + PHINC(1400), PHINC(1530), PHINC(1670), PHINC(1830), + PHINC(2000), PHINC(2200), PHINC(2800), PHINC(810), + PHINC(970), PHINC(886), PHINC(2600), PHINC(0) +}; + +static const unsigned int zveis_freq[16] = { + PHINC(2400), PHINC(1060), PHINC(1160), PHINC(1270), + PHINC(1400), PHINC(1530), PHINC(1670), PHINC(1830), + PHINC(2000), PHINC(2200), PHINC(886), PHINC(810), + PHINC(740), PHINC(680), PHINC(970), PHINC(0) +}; + +void gen_init_zvei(struct gen_params *p, struct gen_state *s) +{ + memset(s, 0, sizeof(struct gen_state)); +} + +int gen_zvei(signed short *buf, int buflen, struct gen_params *p, struct gen_state *s) +{ + char c; + int num = 0, i; + + for (; buflen > 0; buflen--, buf++, num++) { + if (s->s.zvei.time <= 0) { + c = p->p.zvei.str[s->s.zvei.ch_idx]; + if (!c) + return num; + s->s.zvei.ch_idx++; + if (!isxdigit(c)) { + s->s.zvei.time = s->s.zvei.time2 = 1; + fprintf(stderr, "gen: zvei; invalid char '%c'\n", c); + } else { + s->s.zvei.time = p->p.zvei.duration + p->p.zvei.pause; + s->s.zvei.time2 = p->p.zvei.duration; + if (c >= '0' && c <= '9') + i = c - '0'; + else if (c >= 'A' && c <= 'F') + i = c - 'A' + 10; + else + i = c - 'a' + 10; + s->s.zvei.phinc = zvei_freq[i & 0xf]; + } + } else if (!s->s.zvei.time2) { + s->s.zvei.phinc = 0; + s->s.zvei.ph = 0xc000; + } + s->s.zvei.time--; + s->s.zvei.time2--; + *buf += (p->ampl * COS(s->s.zvei.ph)) >> 15; + s->s.zvei.ph += s->s.zvei.phinc; + } + return num; +} diff --git a/sw/ground_segment/multimon/hdlc.c b/sw/ground_segment/multimon/hdlc.c new file mode 100644 index 0000000000..31d9db8e26 --- /dev/null +++ b/sw/ground_segment/multimon/hdlc.c @@ -0,0 +1,283 @@ +/* + * hdlc.c -- hdlc decoder and AX.25 packet dump + * + * Copyright (C) 1996 + * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* ---------------------------------------------------------------------- */ + +#include "multimon.h" +#include + +/* ---------------------------------------------------------------------- */ + +/* + * the CRC routines are stolen from WAMPES + * by Dieter Deyke + */ + +static const unsigned short crc_ccitt_table[] = { + 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, + 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, + 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, + 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, + 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, + 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, + 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, + 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, + 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, + 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, + 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, + 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, + 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, + 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, + 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, + 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, + 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, + 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, + 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, + 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, + 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, + 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, + 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, + 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, + 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, + 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, + 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, + 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, + 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, + 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, + 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, + 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 +}; + +/* ---------------------------------------------------------------------- */ + +static inline int check_crc_ccitt(const unsigned char *buf, int cnt) +{ + unsigned int crc = 0xffff; + + for (; cnt > 0; cnt--) + crc = (crc >> 8) ^ crc_ccitt_table[(crc ^ *buf++) & 0xff]; + return (crc & 0xffff) == 0xf0b8; +} + +/* ---------------------------------------------------------------------- */ + +static void ax25_disp_packet(struct demod_state *s, unsigned char *bp, unsigned int len) +{ + unsigned char v1=1,cmd=0; + unsigned char i,j; + + if (!bp || len < 10) + return; +#if 1 + if (!check_crc_ccitt(bp, len)) + return; +#endif + len -= 2; + if (bp[1] & 1) { + /* + * FlexNet Header Compression + */ + v1 = 0; + cmd = (bp[1] & 2) != 0; + verbprintf(0, "%s: fm ? to ", s->dem_par->name); + i = (bp[2] >> 2) & 0x3f; + if (i) + verbprintf(0, "%c",i+0x20); + i = ((bp[2] << 4) | ((bp[3] >> 4) & 0xf)) & 0x3f; + if (i) + verbprintf(0, "%c",i+0x20); + i = ((bp[3] << 2) | ((bp[4] >> 6) & 3)) & 0x3f; + if (i) + verbprintf(0, "%c",i+0x20); + i = bp[4] & 0x3f; + if (i) + verbprintf(0, "%c",i+0x20); + i = (bp[5] >> 2) & 0x3f; + if (i) + verbprintf(0, "%c",i+0x20); + i = ((bp[5] << 4) | ((bp[6] >> 4) & 0xf)) & 0x3f; + if (i) + verbprintf(0, "%c",i+0x20); + verbprintf(0, "-%u QSO Nr %u", bp[6] & 0xf, (bp[0] << 6) | (bp[1] >> 2)); + bp += 7; + len -= 7; + } else { + /* + * normal header + */ + if (len < 15) + return; + if ((bp[6] & 0x80) != (bp[13] & 0x80)) { + v1 = 0; + cmd = (bp[6] & 0x80); + } + verbprintf(0, "%s: fm ", s->dem_par->name); + for(i = 7; i < 13; i++) + if ((bp[i] &0xfe) != 0x40) + verbprintf(0, "%c",bp[i] >> 1); + verbprintf(0, "-%u to ",(bp[13] >> 1) & 0xf); + for(i = 0; i < 6; i++) + if ((bp[i] &0xfe) != 0x40) + verbprintf(0, "%c",bp[i] >> 1); + verbprintf(0, "-%u",(bp[6] >> 1) & 0xf); + bp += 14; + len -= 14; + if ((!(bp[-1] & 1)) && (len >= 7)) + verbprintf(0, " via "); + while ((!(bp[-1] & 1)) && (len >= 7)) { + for(i = 0; i < 6; i++) + if ((bp[i] &0xfe) != 0x40) + verbprintf(0, "%c",bp[i] >> 1); + verbprintf(0, "-%u",(bp[6] >> 1) & 0xf); + bp += 7; + len -= 7; + if ((!(bp[-1] & 1)) && (len >= 7)) + verbprintf(0, ","); + } + } + if(!len) + return; + i = *bp++; + len--; + j = v1 ? ((i & 0x10) ? '!' : ' ') : + ((i & 0x10) ? (cmd ? '+' : '-') : (cmd ? '^' : 'v')); + if (!(i & 1)) { + /* + * Info frame + */ + verbprintf(0, " I%u%u%c",(i >> 5) & 7,(i >> 1) & 7,j); + } else if (i & 2) { + /* + * U frame + */ + switch (i & (~0x10)) { + case 0x03: + verbprintf(0, " UI%c",j); + break; + case 0x2f: + verbprintf(0, " SABM%c",j); + break; + case 0x43: + verbprintf(0, " DISC%c",j); + break; + case 0x0f: + verbprintf(0, " DM%c",j); + break; + case 0x63: + verbprintf(0, " UA%c",j); + break; + case 0x87: + verbprintf(0, " FRMR%c",j); + break; + default: + verbprintf(0, " unknown U (0x%x)%c",i & (~0x10),j); + break; + } + } else { + /* + * supervisory + */ + switch (i & 0xf) { + case 0x1: + verbprintf(0, " RR%u%c",(i >> 5) & 7,j); + break; + case 0x5: + verbprintf(0, " RNR%u%c",(i >> 5) & 7,j); + break; + case 0x9: + verbprintf(0, " REJ%u%c",(i >> 5) & 7,j); + break; + default: + verbprintf(0, " unknown S (0x%x)%u%c", i & 0xf, + (i >> 5) & 7, j); + break; + } + } + if (!len) { + verbprintf(0, "\n"); + return; + } + verbprintf(0, " pid=%02X\n", *bp++); + len--; + j = 0; + while (len) { + i = *bp++; + if ((i >= 32) && (i < 128)) + verbprintf(0, "%c",i); + else if (i == 13) { + if (j) + verbprintf(0, "\n"); + j = 0; + } else + verbprintf(0, "."); + if (i >= 32) + j = 1; + len--; + } + if (j) + verbprintf(0, "\n"); +} + +/* ---------------------------------------------------------------------- */ + +void hdlc_init(struct demod_state *s) +{ + memset(&s->l2.hdlc, 0, sizeof(s->l2.hdlc)); +} + +/* ---------------------------------------------------------------------- */ + +void hdlc_rxbit(struct demod_state *s, int bit) +{ + s->l2.hdlc.rxbitstream <<= 1; + s->l2.hdlc.rxbitstream |= !!bit; + if ((s->l2.hdlc.rxbitstream & 0xff) == 0x7e) { + if (s->l2.hdlc.rxstate && (s->l2.hdlc.rxptr - s->l2.hdlc.rxbuf) > 2) + ax25_disp_packet(s, s->l2.hdlc.rxbuf, s->l2.hdlc.rxptr - s->l2.hdlc.rxbuf); + s->l2.hdlc.rxstate = 1; + s->l2.hdlc.rxptr = s->l2.hdlc.rxbuf; + s->l2.hdlc.rxbitbuf = 0x80; + return; + } + if ((s->l2.hdlc.rxbitstream & 0x7f) == 0x7f) { + s->l2.hdlc.rxstate = 0; + return; + } + if (!s->l2.hdlc.rxstate) + return; + if ((s->l2.hdlc.rxbitstream & 0x3f) == 0x3e) /* stuffed bit */ + return; + if (s->l2.hdlc.rxbitstream & 1) + s->l2.hdlc.rxbitbuf |= 0x100; + if (s->l2.hdlc.rxbitbuf & 1) { + if (s->l2.hdlc.rxptr >= s->l2.hdlc.rxbuf+sizeof(s->l2.hdlc.rxbuf)) { + s->l2.hdlc.rxstate = 0; + verbprintf(1, "Error: packet size too large\n"); + return; + } + *s->l2.hdlc.rxptr++ = s->l2.hdlc.rxbitbuf >> 1; + s->l2.hdlc.rxbitbuf = 0x80; + return; + } + s->l2.hdlc.rxbitbuf >>= 1; +} + +/* ---------------------------------------------------------------------- */ diff --git a/sw/ground_segment/multimon/mkcostab.c b/sw/ground_segment/multimon/mkcostab.c new file mode 100644 index 0000000000..185b6241f6 --- /dev/null +++ b/sw/ground_segment/multimon/mkcostab.c @@ -0,0 +1,63 @@ +/* + * mkcostab.c -- cosine table generator + * + * Copyright (C) 1996 + * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* ---------------------------------------------------------------------- */ + +#include +#include + +/* ---------------------------------------------------------------------- */ + +#define COSTABSIZE 0x400 + +/* ---------------------------------------------------------------------- */ + +int main(int argc, char *argv[]) +{ + int i; + FILE *fi, *ff; + float f; + + if (!(fi = fopen("costabi.c", "w"))) + exit(1); + if (!(ff = fopen("costabf.c", "w"))) + exit(1); + fprintf(fi, "/*\n * This file is machine generated, DO NOT EDIT!\n */\n\n" + "int costabi[%i] = {", COSTABSIZE); + fprintf(ff, "/*\n * This file is machine generated, DO NOT EDIT!\n */\n\n" + "float costabf[%i] = {", COSTABSIZE); + for (i = 0; i < COSTABSIZE; i++) { + if ((i & 3) == 0) + fprintf(ff, "\n\t"); + if ((i & 7) == 0) + fprintf(fi, "\n\t"); + f = cos(M_PI*2.0*i/COSTABSIZE); + fprintf(ff, "%12.9f", f); + fprintf(fi, "%6i", (int)(32767.0*f)); + if (i < COSTABSIZE-1) { + fprintf(ff, ", "); + fprintf(fi, ", "); + } + } + fprintf(ff, "\n};\n"); + fprintf(fi, "\n};\n"); + exit(0); +} diff --git a/sw/ground_segment/multimon/multimon.h b/sw/ground_segment/multimon/multimon.h new file mode 100644 index 0000000000..ec4470ac04 --- /dev/null +++ b/sw/ground_segment/multimon/multimon.h @@ -0,0 +1,171 @@ +/* + * multimon.h -- Monitor for many different modulation formats + * + * Copyright (C) 1996 + * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* ---------------------------------------------------------------------- */ + +#ifndef _MULTIMON_H +#define _MULTIMON_H + +/* ---------------------------------------------------------------------- */ + +extern const float costabf[0x400]; +#define COS(x) costabf[(((x)>>6)&0x3ffu)] +#define SIN(x) COS((x)+0xc000) + +/* ---------------------------------------------------------------------- */ + +struct demod_state { + const struct demod_param *dem_par; + union { + struct l2_state_hdlc { + unsigned char rxbuf[512]; + unsigned char *rxptr; + unsigned int rxstate; + unsigned int rxbitstream; + unsigned int rxbitbuf; + } hdlc; + + struct l2_state_pocsag { + unsigned long rx_data; + struct l2_pocsag_rx { + unsigned char rx_sync; + unsigned char rx_word; + unsigned char rx_bit; + char func; + unsigned long adr; + unsigned char buffer[128]; + unsigned int numnibbles; + } rx[2]; + } pocsag; + } l2; + union { + struct l1_state_poc5 { + unsigned int dcd_shreg; + unsigned int sphase; + unsigned int subsamp; + } poc5; + + struct l1_state_poc12 { + unsigned int dcd_shreg; + unsigned int sphase; + unsigned int subsamp; + } poc12; + + struct l1_state_poc24 { + unsigned int dcd_shreg; + unsigned int sphase; + } poc24; + + struct l1_state_afsk12 { + unsigned int dcd_shreg; + unsigned int sphase; + unsigned int lasts; + unsigned int subsamp; + } afsk12; + + struct l1_state_afsk24 { + unsigned int dcd_shreg; + unsigned int sphase; + unsigned int lasts; + } afsk24; + + struct l1_state_hapn48 { + unsigned int shreg; + unsigned int sphase; + float lvllo, lvlhi; + } hapn48; + + struct l1_state_fsk96 { + unsigned int dcd_shreg; + unsigned int sphase; + unsigned int descram; + } fsk96; + + struct l1_state_dtmf { + unsigned int ph[8]; + float energy[4]; + float tenergy[4][16]; + int blkcount; + int lastch; + } dtmf; + + struct l1_state_zvei { + unsigned int ph[16]; + float energy[4]; + float tenergy[4][32]; + int blkcount; + int lastch; + } zvei; + + struct l1_state_scope { + int datalen; + int dispnum; + float data[512]; + } scope; + } l1; +}; + +struct demod_param { + const char *name; + unsigned int samplerate; + unsigned int overlap; + void (*init)(struct demod_state *s); + void (*demod)(struct demod_state *s, float *buffer, int length); +}; + +/* ---------------------------------------------------------------------- */ + +extern const struct demod_param demod_poc5; +extern const struct demod_param demod_poc12; +extern const struct demod_param demod_poc24; + +extern const struct demod_param demod_afsk1200; +extern const struct demod_param demod_afsk2400; +extern const struct demod_param demod_afsk2400_2; + +extern const struct demod_param demod_hapn4800; +extern const struct demod_param demod_fsk9600; + +extern const struct demod_param demod_dtmf; +extern const struct demod_param demod_zvei; + +extern const struct demod_param demod_scope; + +#define ALL_DEMOD &demod_poc5, &demod_poc12, &demod_poc24, \ +&demod_afsk1200, &demod_afsk2400, &demod_afsk2400_2, &demod_hapn4800, \ +&demod_fsk9600, &demod_dtmf, &demod_zvei, &demod_scope + +/* ---------------------------------------------------------------------- */ + +void verbprintf(int verb_level, const char *fmt, ...); + +void hdlc_init(struct demod_state *s); +void hdlc_rxbit(struct demod_state *s, int bit); + +void pocsag_init(struct demod_state *s); +void pocsag_rxbit(struct demod_state *s, int bit); + +void xdisp_terminate(int cnum); +int xdisp_start(void); +int xdisp_update(int cnum, float *f); + +/* ---------------------------------------------------------------------- */ +#endif /* _MULTIMON_H */ diff --git a/sw/ground_segment/multimon/pocsag.c b/sw/ground_segment/multimon/pocsag.c new file mode 100644 index 0000000000..2bfa998fb3 --- /dev/null +++ b/sw/ground_segment/multimon/pocsag.c @@ -0,0 +1,476 @@ +/* + * pocsag.c -- POCSAG protocol decoder + * + * Copyright (C) 1996 + * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) + * + * POCSAG (Post Office Code Standard Advisory Group) + * Radio Paging Decoder + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* ---------------------------------------------------------------------- */ + +#include "multimon.h" +#include + +/* ---------------------------------------------------------------------- */ + +#define CHARSET_LATIN1 + +/* ---------------------------------------------------------------------- */ + +/* + * the code used by POCSAG is a (n=31,k=21) BCH Code with dmin=5, + * thus it could correct two bit errors in a 31-Bit codeword. + * It is a systematic code. + * The generator polynomial is: + * g(x) = x^10+x^9+x^8+x^6+x^5+x^3+1 + * The parity check polynomial is: + * h(x) = x^21+x^20+x^18+x^16+x^14+x^13+x^12+x^11+x^8+x^5+x^3+1 + * g(x) * h(x) = x^n+1 + */ +#define BCH_POLY 03551 /* octal */ +#define BCH_N 31 +#define BCH_K 21 + +/* + * some codewords with special POCSAG meaning + */ +#define POCSAG_SYNC 0x7cd215d8 +#define POCSAG_SYNCINFO 0x7cf21436 +#define POCSAG_IDLE 0x7a89c197 + +#define POCSAG_SYNC_WORDS ((2000000 >> 3) << 13) + +/* ---------------------------------------------------------------------- */ + +static unsigned char service_mask = 0x87; + +/* ---------------------------------------------------------------------- */ + +static inline unsigned char even_parity(unsigned long data) +{ + unsigned int temp = data ^ (data >> 16); + + temp = temp ^ (temp >> 8); + temp = temp ^ (temp >> 4); + temp = temp ^ (temp >> 2); + temp = temp ^ (temp >> 1); + return temp & 1; +} + +/* ---------------------------------------------------------------------- */ + +static unsigned long pocsag_code(unsigned long data) +{ + unsigned long ret = data << (BCH_N-BCH_K), shreg = ret; + unsigned long mask = 1L << (BCH_N-1), coeff = BCH_POLY << (BCH_K-1); + int n = BCH_K; + + for(; n > 0; mask >>= 1, coeff >>= 1, n--) + if (shreg & mask) + shreg ^= coeff; + ret ^= shreg; + ret = (ret << 1) | even_parity(ret); + verbprintf(9, "BCH coder: data: %08lx shreg: %08lx ret: %08lx\n", + data, shreg, ret); + return ret; +} + +/* ---------------------------------------------------------------------- */ + +static unsigned int pocsag_syndrome(unsigned long data) +{ + unsigned long shreg = data >> 1; /* throw away parity bit */ + unsigned long mask = 1L << (BCH_N-1), coeff = BCH_POLY << (BCH_K-1); + int n = BCH_K; + + for(; n > 0; mask >>= 1, coeff >>= 1, n--) + if (shreg & mask) + shreg ^= coeff; + if (even_parity(data)) + shreg |= (1 << (BCH_N - BCH_K)); + verbprintf(9, "BCH syndrome: data: %08lx syn: %08lx\n", data, shreg); + return shreg; +} + +/* ---------------------------------------------------------------------- */ + +static void print_msg_numeric(struct l2_pocsag_rx *rx) +{ + static const char *conv_table = "084 2.6]195-3U7["; + unsigned char *bp = rx->buffer; + int len = rx->numnibbles; + char buf[256], *cp = buf; + + if (len >= sizeof(buf)) + len = sizeof(buf)-1; + for (; len > 0; bp++, len -= 2) { + *cp++ = conv_table[(*bp >> 4) & 0xf]; + if (len > 1) + *cp++ = conv_table[*bp & 0xf]; + } + *cp = '\0'; + verbprintf(0, "%s\n", buf); +} + +/* ---------------------------------------------------------------------- */ + +static char *translate_alpha(unsigned char chr) +{ + static const struct trtab { + unsigned char code; + char *str; + } trtab[] = {{ 0, "" }, + { 1, "" }, + { 2, "" }, + { 3, "" }, + { 4, "" }, + { 5, "" }, + { 6, "" }, + { 7, "" }, + { 8, "" }, + { 9, "" }, + { 10, "" }, + { 11, "" }, + { 12, "" }, + { 13, "" }, + { 14, "" }, + { 15, "" }, + { 16, "" }, + { 17, "" }, + { 18, "" }, + { 19, "" }, + { 20, "" }, + { 21, "" }, + { 22, "" }, + { 23, "" }, + { 24, "" }, + { 25, "" }, + { 26, "" }, + { 27, "" }, + { 28, "" }, + { 29, "" }, + { 30, "" }, + { 31, "" }, +#ifdef CHARSET_LATIN1 + { 0x5b, "\304" }, /* upper case A dieresis */ + { 0x5c, "\326" }, /* upper case O dieresis */ + { 0x5d, "\334" }, /* upper case U dieresis */ + { 0x7b, "\344" }, /* lower case a dieresis */ + { 0x7c, "\366" }, /* lower case o dieresis */ + { 0x7d, "\374" }, /* lower case u dieresis */ + { 0x7e, "\337" }}; /* sharp s */ +#else /* CHARSET_LATIN1 */ + { 0x5b, "AE" }, /* upper case A dieresis */ + { 0x5c, "OE" }, /* upper case O dieresis */ + { 0x5d, "UE" }, /* upper case U dieresis */ + { 0x7b, "ae" }, /* lower case a dieresis */ + { 0x7c, "oe" }, /* lower case o dieresis */ + { 0x7d, "ue" }, /* lower case u dieresis */ + { 0x7e, "ss" }}; /* sharp s */ +#endif /* CHARSET_LATIN1 */ + int min = 0, max = (sizeof(trtab) / sizeof(trtab[0])) - 1; + + /* + * binary search, list must be ordered! + */ + for (;;) { + int mid = (min+max) >> 1; + const struct trtab *tb = trtab + mid; + int cmp = ((int) tb->code) - ((int) chr); + + if (!cmp) + return tb->str; + if (cmp < 0) { + min = mid+1; + if (min > max) + return NULL; + } + if (cmp > 0) { + max = mid-1; + if (max < min) + return NULL; + } + } +} + +/* ---------------------------------------------------------------------- */ + +static void print_msg_alpha(struct l2_pocsag_rx *rx) +{ + unsigned long data = 0; + int datalen = 0; + unsigned char *bp = rx->buffer; + int len = rx->numnibbles; + char buf[256], *cp = buf; + int buffree = sizeof(buf)-1; + unsigned char curchr; + char *tstr; + + while (len > 0) { + while (datalen < 7 && len > 0) { + if (len == 1) { + data = (data << 4) | ((*bp >> 4) & 0xf); + datalen += 4; + len = 0; + } else { + data = (data << 8) | *bp++; + datalen += 8; + len -= 2; + } + } + if (datalen < 7) + continue; + datalen -= 7; + curchr = ((data >> datalen) & 0x7f) << 1; + curchr = ((curchr & 0xf0) >> 4) | ((curchr & 0x0f) << 4); + curchr = ((curchr & 0xcc) >> 2) | ((curchr & 0x33) << 2); + curchr = ((curchr & 0xaa) >> 1) | ((curchr & 0x55) << 1); + tstr = translate_alpha(curchr); + if (tstr) { + int tlen = strlen(tstr); + if (buffree >= tlen) { + memcpy(cp, tstr, tlen); + cp += tlen; + buffree -= tlen; + } + } else if (buffree > 0) { + *cp++ = curchr; + buffree--; + } + } + *cp = '\0'; + verbprintf(0, "%s\n", buf); +} + +/* ---------------------------------------------------------------------- */ + +static void print_msg_skyper(struct l2_pocsag_rx *rx) +{ + unsigned long data = 0; + int datalen = 0; + unsigned char *bp = rx->buffer; + int len = rx->numnibbles; + char buf[256], *cp = buf; + int buffree = sizeof(buf)-1; + unsigned char curchr; + char *tstr; + + while (len > 0) { + while (datalen < 7 && len > 0) { + if (len == 1) { + data = (data << 4) | ((*bp >> 4) & 0xf); + datalen += 4; + len = 0; + } else { + data = (data << 8) | *bp++; + datalen += 8; + len -= 2; + } + } + if (datalen < 7) + continue; + datalen -= 7; + curchr = ((data >> datalen) & 0x7f) << 1; + curchr = ((curchr & 0xf0) >> 4) | ((curchr & 0x0f) << 4); + curchr = ((curchr & 0xcc) >> 2) | ((curchr & 0x33) << 2); + curchr = ((curchr & 0xaa) >> 1) | ((curchr & 0x55) << 1); + tstr = translate_alpha(curchr-1); + if (tstr) { + int tlen = strlen(tstr); + if (buffree >= tlen) { + memcpy(cp, tstr, tlen); + cp += tlen; + buffree -= tlen; + } + } else if (buffree > 0) { + *cp++ = curchr-1; + buffree--; + } + } + *cp = '\0'; + verbprintf(0, "%s\n", buf); +} + +/* ---------------------------------------------------------------------- */ + +static void pocsag_printmessage(struct demod_state *s, struct l2_pocsag_rx *rx, + const char *add_name) +{ + verbprintf(0, "%s%s: Address: %7lu Function: %1u\n", + s->dem_par->name, add_name, rx->adr, rx->func); + if (!rx->numnibbles) + return; + if (service_mask & (0x01 << rx->func)) { + verbprintf(0, "%s%s: Numeric: ", s->dem_par->name, add_name); + print_msg_numeric(rx); + } + if (service_mask & (0x10 << rx->func)) { + if (rx->func == 3 && rx->adr >= 4000 && + rx->adr <= 5000) { + verbprintf(0, "%s%s: Alpha (SKYPER): ", s->dem_par->name, add_name); + print_msg_skyper(rx); + } else { + verbprintf(0, "%s%s: Alpha: ", s->dem_par->name, add_name); + print_msg_alpha(rx); + } + } +} + +/* ---------------------------------------------------------------------- */ + +void pocsag_init(struct demod_state *s) +{ + memset(&s->l2.pocsag, 0, sizeof(s->l2.pocsag)); +} + +/* ---------------------------------------------------------------------- */ + +static void do_one_bit(struct demod_state *s, struct l2_pocsag_rx *rx, + unsigned long rx_data, const char *add_name) +{ + unsigned char rxword; + + if (!rx->rx_sync) { + if (rx_data == POCSAG_SYNC || rx_data == POCSAG_SYNCINFO) { + rx->rx_sync = 2; + rx->rx_bit = rx->rx_word = 0; + rx->func = -1; + return; + } + return; + } + + if ((++(rx->rx_bit)) < 32) + return; + /* + * one complete word received + */ + rx->rx_bit = 0; + /* + * check codeword + */ + if (pocsag_syndrome(rx_data)) { + /* + * codeword not valid + */ + rx->rx_sync--; + verbprintf(7, "%s: Bad codeword: %08lx%s\n", + s->dem_par->name, rx_data, + rx->rx_sync ? "" : "sync lost"); + if (!(rx->func & (~3))) { + verbprintf(0, "%s%s: Warning: message garbled\n", + s->dem_par->name, add_name); + pocsag_printmessage(s, rx, add_name); + } + rx->func = -1; /* invalidate message */ + return; + } + /* do something with the data */ + verbprintf(8, "%s%s: Codeword: %08lx\n", s->dem_par->name, add_name, rx_data); + rxword = rx->rx_word++; + if (rxword >= 16) { + /* + * received word shoud be a + * frame synch + */ + rx->rx_word = 0; + if ((rx_data == POCSAG_SYNC) || + (rx_data == POCSAG_SYNCINFO)) + rx->rx_sync = 10; + else + rx->rx_sync -= 2; + return; + } + if (rx_data == POCSAG_IDLE) { + /* + * it seems that we can output the message right here + */ + if (!(rx->func & (~3))) + pocsag_printmessage(s, rx, add_name); + rx->func = -1; /* invalidate message */ + return; + } + if (rx_data & 0x80000000) { + /* + * this is a data word + */ + unsigned long data; + unsigned char *bp; + + if (rx->func & (~3)) { + /* + * no message being received + */ + verbprintf(7, "%s%s: Lonesome data codeword: %08lx\n", + s->dem_par->name, add_name, rx_data); + return; + } + if (rx->numnibbles > sizeof(rx->buffer)*2 - 5) { + verbprintf(0, "%s%s: Warning: Message too long\n", + s->dem_par->name, add_name); + pocsag_printmessage(s, rx, add_name); + rx->func = -1; + return; + } + bp = rx->buffer + (rx->numnibbles >> 1); + data = rx_data >> 11; + if (rx->numnibbles & 1) { + bp[0] = (bp[0] & 0xf0) | ((data >> 16) & 0xf); + bp[1] = data >> 8; + bp[2] = data; + } else { + bp[0] = data >> 12; + bp[1] = data >> 4; + bp[2] = data << 4; + } + rx->numnibbles += 5; + return; + } + /* + * process address codeword + */ + if (rx_data >= POCSAG_SYNC_WORDS) { + unsigned char func = (rx_data >> 11) & 3; + unsigned long adr = ((rx_data >> 10) & 0x1ffff8) | + ((rxword >> 1) & 7); + + verbprintf(0, "%s%s: Nonstandard address codeword: %08lx " + "func %1u adr %08lx\n", s->dem_par->name, add_name, rx_data, + func, adr); + return; + } + if (!(rx->func & (~3))) + pocsag_printmessage(s, rx, add_name); + rx->func = (rx_data >> 11) & 3; + rx->adr = ((rx_data >> 10) & 0x1ffff8) | ((rxword >> 1) & 7); + rx->numnibbles = 0; +} + +/* ---------------------------------------------------------------------- */ + +void pocsag_rxbit(struct demod_state *s, int bit) +{ + s->l2.pocsag.rx_data <<= 1; + s->l2.pocsag.rx_data |= !bit; + verbprintf(9, " %c ", '1'-(s->l2.pocsag.rx_data & 1)); + do_one_bit(s, s->l2.pocsag.rx, ~(s->l2.pocsag.rx_data), "+"); + do_one_bit(s, s->l2.pocsag.rx+1, s->l2.pocsag.rx_data, "-"); +} + +/* ---------------------------------------------------------------------- */ diff --git a/sw/ground_segment/multimon/unixinput.c b/sw/ground_segment/multimon/unixinput.c new file mode 100644 index 0000000000..46bada67bf --- /dev/null +++ b/sw/ground_segment/multimon/unixinput.c @@ -0,0 +1,493 @@ +/* + * unixinput.c -- input sound samples + * + * Copyright (C) 1996 + * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* ---------------------------------------------------------------------- */ + +#include "multimon.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef SUN_AUDIO +#include +#include +#include +#else /* SUN_AUDIO */ +#include +#include +#endif /* SUN_AUDIO */ + +/* ---------------------------------------------------------------------- */ + +static const char *allowed_types[] = { + "raw", "aiff", "au", "hcom", "sf", "voc", "cdr", "dat", + "smp", "wav", "maud", "vwe", NULL +}; + +/* ---------------------------------------------------------------------- */ + +static const struct demod_param *dem[] = { ALL_DEMOD }; + +#define NUMDEMOD (sizeof(dem)/sizeof(dem[0])) + +static struct demod_state dem_st[NUMDEMOD]; +static unsigned int dem_mask[(NUMDEMOD+31)/32]; + +#define MASK_SET(n) dem_mask[(n)>>5] |= 1<<((n)&0x1f) +#define MASK_RESET(n) dem_mask[(n)>>5] &= ~(1<<((n)&0x1f)) +#define MASK_ISSET(n) (dem_mask[(n)>>5] & 1<<((n)&0x1f)) + +/* ---------------------------------------------------------------------- */ + +static int verbose_level = 0; + +/* ---------------------------------------------------------------------- */ + +void verbprintf(int verb_level, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + if (verb_level <= verbose_level) + vfprintf(stdout, fmt, args); + va_end(args); +} + +/* ---------------------------------------------------------------------- */ + +static void process_buffer(float *buf, unsigned int len) +{ + int i; + + for (i = 0; i < NUMDEMOD; i++) + if (MASK_ISSET(i) && dem[i]->demod) + dem[i]->demod(dem_st+i, buf, len); +} + +/* ---------------------------------------------------------------------- */ +#ifdef SUN_AUDIO + +static void input_sound(unsigned int sample_rate, unsigned int overlap, + const char *ifname) +{ + audio_info_t audioinfo; + audio_info_t audioinfo2; + audio_device_t audiodev; + int fd; + short buffer[8192]; + float fbuf[16384]; + unsigned int fbuf_cnt = 0; + int i; + short *sp; + + if ((fd = open(ifname ? ifname : "/dev/audio", O_RDONLY)) < 0) { + perror("open"); + exit (10); + } + if (ioctl(fd, AUDIO_GETDEV, &audiodev) == -1) { + perror("ioctl: AUDIO_GETDEV"); + exit (10); + } + AUDIO_INITINFO(&audioinfo); + audioinfo.record.sample_rate = sample_rate; + audioinfo.record.channels = 1; + audioinfo.record.precision = 16; + audioinfo.record.encoding = AUDIO_ENCODING_LINEAR; + /*audioinfo.record.gain = 0x20; + audioinfo.record.port = AUDIO_LINE_IN; + audioinfo.monitor_gain = 0;*/ + if (ioctl(fd, AUDIO_SETINFO, &audioinfo) == -1) { + perror("ioctl: AUDIO_SETINFO"); + exit (10); + } + if (ioctl(fd, I_FLUSH, FLUSHR) == -1) { + perror("ioctl: I_FLUSH"); + exit (10); + } + if (ioctl(fd, AUDIO_GETINFO, &audioinfo2) == -1) { + perror("ioctl: AUDIO_GETINFO"); + exit (10); + } + fprintf(stdout, "Audio device: name %s, ver %s, config %s, " + "sampling rate %d\n", audiodev.name, audiodev.version, + audiodev.config, audioinfo.record.sample_rate); + for (;;) { + i = read(fd, sp = buffer, sizeof(buffer)); + if (i < 0 && errno != EAGAIN) { + perror("read"); + exit(4); + } + if (!i) + break; + if (i > 0) { + for (; i >= sizeof(buffer[0]); i -= sizeof(buffer[0]), sp++) + fbuf[fbuf_cnt++] = (*sp) * (1.0/32768.0); + if (i) + fprintf(stderr, "warning: noninteger number of samples read\n"); + if (fbuf_cnt > overlap) { + process_buffer(fbuf, fbuf_cnt-overlap); + memmove(fbuf, fbuf+fbuf_cnt-overlap, overlap*sizeof(fbuf[0])); + fbuf_cnt = overlap; + } + } + } + close(fd); +} + +#else /* SUN_AUDIO */ +/* ---------------------------------------------------------------------- */ + +static void input_sound(unsigned int sample_rate, unsigned int overlap, + const char *ifname) +{ + int sndparam; + int fd; + union { + short s[8192]; + unsigned char b[8192]; + } b; + float fbuf[16384]; + unsigned int fbuf_cnt = 0; + int i; + short *sp; + unsigned char *bp; + int fmt = 0; + + if ((fd = open(ifname ? ifname : "/dev/dsp", O_RDONLY)) < 0) { + perror("open"); + exit (10); + } + sndparam = AFMT_S16_LE; /* we want 16 bits/sample signed */ + /* little endian; works only on little endian systems! */ + if (ioctl(fd, SNDCTL_DSP_SETFMT, &sndparam) == -1) { + perror("ioctl: SNDCTL_DSP_SETFMT"); + exit (10); + } + if (sndparam != AFMT_S16_LE) { + fmt = 1; + sndparam = AFMT_U8; + if (ioctl(fd, SNDCTL_DSP_SETFMT, &sndparam) == -1) { + perror("ioctl: SNDCTL_DSP_SETFMT"); + exit (10); + } + if (sndparam != AFMT_U8) { + perror("ioctl: SNDCTL_DSP_SETFMT"); + exit (10); + } + } + sndparam = 0; /* we want only 1 channel */ + if (ioctl(fd, SNDCTL_DSP_STEREO, &sndparam) == -1) { + perror("ioctl: SNDCTL_DSP_STEREO"); + exit (10); + } + if (sndparam != 0) { + fprintf(stderr, "soundif: Error, cannot set the channel " + "number to 1\n"); + exit (10); + } + sndparam = sample_rate; + if (ioctl(fd, SNDCTL_DSP_SPEED, &sndparam) == -1) { + perror("ioctl: SNDCTL_DSP_SPEED"); + exit (10); + } + if ((10*abs(sndparam-sample_rate)) > sample_rate) { + perror("ioctl: SNDCTL_DSP_SPEED"); + exit (10); + } + if (sndparam != sample_rate) { + fprintf(stderr, "Warning: Sampling rate is %u, " + "requested %u\n", sndparam, sample_rate); + } +#if 0 + sndparam = 4; + if (ioctl(fd, SOUND_PCM_SUBDIVIDE, &sndparam) == -1) { + perror("ioctl: SOUND_PCM_SUBDIVIDE"); + } + if (sndparam != 4) { + perror("ioctl: SOUND_PCM_SUBDIVIDE"); + } +#endif + for (;;) { + if (fmt) { + i = read(fd, bp = b.b, sizeof(b.b)); + if (i < 0 && errno != EAGAIN) { + perror("read"); + exit(4); + } + if (!i) + break; + if (i > 0) { + for (; i >= sizeof(b.b[0]); i -= sizeof(b.b[0]), sp++) + fbuf[fbuf_cnt++] = ((int)(*bp)-0x80) * (1.0/128.0); + if (i) + fprintf(stderr, "warning: noninteger number of samples read\n"); + if (fbuf_cnt > overlap) { + process_buffer(fbuf, fbuf_cnt-overlap); + memmove(fbuf, fbuf+fbuf_cnt-overlap, overlap*sizeof(fbuf[0])); + fbuf_cnt = overlap; + } + } + } else { + i = read(fd, sp = b.s, sizeof(b.s)); + if (i < 0 && errno != EAGAIN) { + perror("read"); + exit(4); + } + if (!i) + break; + if (i > 0) { + for (; i >= sizeof(b.s[0]); i -= sizeof(b.s[0]), sp++) + fbuf[fbuf_cnt++] = (*sp) * (1.0/32768.0); + if (i) + fprintf(stderr, "warning: noninteger number of samples read\n"); + if (fbuf_cnt > overlap) { + process_buffer(fbuf, fbuf_cnt-overlap); + memmove(fbuf, fbuf+fbuf_cnt-overlap, overlap*sizeof(fbuf[0])); + fbuf_cnt = overlap; + } + } + } + } + close(fd); +} +#endif /* SUN_AUDIO */ + +/* ---------------------------------------------------------------------- */ + +static void input_file(unsigned int sample_rate, unsigned int overlap, + const char *fname, const char *type) +{ + struct stat statbuf; + int pipedes[2]; + int pid = 0, soxstat; + int fd; + int i; + short buffer[8192]; + float fbuf[16384]; + unsigned int fbuf_cnt = 0; + short *sp; + + /* + * if the input type is not raw, sox is started to convert the + * samples to the requested format + */ + if (!type || !strcmp(type, "raw")) { + if ((fd = open(fname, O_RDONLY)) < 0) { + perror("open"); + exit(10); + } + } else { + if (stat(fname, &statbuf)) { + perror("stat"); + exit(10); + } + if (pipe(pipedes)) { + perror("pipe"); + exit(10); + } + if (!(pid = fork())) { + char srate[8]; + /* + * child starts here... first set up filedescriptors, + * then start sox... + */ + sprintf(srate, "%d", sample_rate); + close(pipedes[0]); /* close reading pipe end */ + close(1); /* close standard output */ + if (dup2(pipedes[1], 1) < 0) + perror("dup2"); + close(pipedes[1]); /* close writing pipe end */ + execlp("sox", "sox", + "-t", type, fname, + "-t", "raw", "-s", "-w", "-r", srate, "-", + NULL); + perror("execlp"); + exit(10); + } + if (pid < 0) { + perror("fork"); + exit(10); + } + close(pipedes[1]); /* close writing pipe end */ + fd = pipedes[0]; + } + /* + * demodulate + */ + for (;;) { + i = read(fd, sp = buffer, sizeof(buffer)); + if (i < 0 && errno != EAGAIN) { + perror("read"); + exit(4); + } + if (!i) + break; + if (i > 0) { + for (; i >= sizeof(buffer[0]); i -= sizeof(buffer[0]), sp++) + fbuf[fbuf_cnt++] = (*sp) * (1.0/32768.0); + if (i) + fprintf(stderr, "warning: noninteger number of samples read\n"); + if (fbuf_cnt > overlap) { + process_buffer(fbuf, fbuf_cnt-overlap); + memmove(fbuf, fbuf+fbuf_cnt-overlap, overlap*sizeof(fbuf[0])); + fbuf_cnt = overlap; + } + } + } + close(fd); + waitpid(pid, &soxstat, 0); +} + +/* ---------------------------------------------------------------------- */ + +static const char usage_str[] = "multimod\n" +"Demodulates many different radio transmission formats\n" +"(C) 1996 by Thomas Sailer HB9JNX/AE4WA\n" +" -t : input file type (any other type than raw requires sox)\n" +" -a : add demodulator\n" +" -s : subtract demodulator\n"; + +int main(int argc, char *argv[]) +{ + int c; + int errflg = 0; + int i; + char **itype; + int mask_first = 1; + int sample_rate = -1; + unsigned int overlap = 0; + char *input_type = "hw"; + + fprintf(stdout, "multimod (C) 1996/1997 by Tom Sailer HB9JNX/AE4WA\n" + "available demodulators:"); + for (i = 0; i < NUMDEMOD; i++) + fprintf(stdout, " %s", dem[i]->name); + fprintf(stdout, "\n"); + while ((c = getopt(argc, argv, "t:a:s:v:")) != EOF) { + switch (c) { + case '?': + errflg++; + break; + + case 'v': + verbose_level = strtoul(optarg, 0, 0); + break; + + case 't': + for (itype = (char **)allowed_types; *itype; itype++) + if (!strcmp(*itype, optarg)) { + input_type = *itype; + goto intypefound; + } + fprintf(stderr, "invalid input type \"%s\"\n" + "allowed types: ", optarg); + for (itype = (char **)allowed_types; *itype; itype++) + fprintf(stderr, "%s ", *itype); + fprintf(stderr, "\n"); + errflg++; + intypefound: + break; + + case 'a': + if (mask_first) + memset(dem_mask, 0, sizeof(dem_mask)); + mask_first = 0; + for (i = 0; i < NUMDEMOD; i++) + if (!strcasecmp(optarg, dem[i]->name)) { + MASK_SET(i); + break; + } + if (i >= NUMDEMOD) { + fprintf(stderr, "invalid mode \"%s\"\n", optarg); + errflg++; + } + break; + + case 's': + if (mask_first) + memset(dem_mask, 0xff, sizeof(dem_mask)); + mask_first = 0; + for (i = 0; i < NUMDEMOD; i++) + if (!strcasecmp(optarg, dem[i]->name)) { + MASK_RESET(i); + break; + } + if (i >= NUMDEMOD) { + fprintf(stderr, "invalid mode \"%s\"\n", optarg); + errflg++; + } + break; + + } + } + if (errflg) { + (void)fprintf(stderr, usage_str); + exit(2); + } + if (mask_first) + memset(dem_mask, 0xff, sizeof(dem_mask)); + + fprintf(stdout, "Enabled demodulators:"); + for (i = 0; i < NUMDEMOD; i++) + if (MASK_ISSET(i)) { + fprintf(stdout, " %s", dem[i]->name); + memset(dem_st+i, 0, sizeof(dem_st[i])); + dem_st[i].dem_par = dem[i]; + if (dem[i]->init) + dem[i]->init(dem_st+i); + if (sample_rate == -1) + sample_rate = dem[i]->samplerate; + else if (sample_rate != dem[i]->samplerate) { + fprintf(stdout, "\n"); + fprintf(stderr, "Error: Current sampling rate %d, " + " demodulator \"%s\" requires %d\n", + sample_rate, dem[i]->name, dem[i]->samplerate); + exit(3); + } + if (dem[i]->overlap > overlap) + overlap = dem[i]->overlap; + } + fprintf(stdout, "\n"); + + if (!strcmp(input_type, "hw")) { + if ((argc - optind) >= 1) + input_sound(sample_rate, overlap, argv[optind]); + else + input_sound(sample_rate, overlap, NULL); + exit(0); + } + if ((argc - optind) < 1) { + (void)fprintf(stderr, "no source files specified\n"); + exit(4); + } + for (i = optind; i < argc; i++) + input_file(sample_rate, overlap, argv[i], input_type); + exit(0); +} + +/* ---------------------------------------------------------------------- */ diff --git a/sw/ground_segment/multimon/xdisplay.c b/sw/ground_segment/multimon/xdisplay.c new file mode 100644 index 0000000000..a3ef545420 --- /dev/null +++ b/sw/ground_segment/multimon/xdisplay.c @@ -0,0 +1,440 @@ +/* + * xdisplay.c -- actually displaying things + * + * Copyright (C) 1996 + * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* ---------------------------------------------------------------------- */ + +#include "multimon.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* ---------------------------------------------------------------------- */ + +#define WIDTH 512 +#define HEIGHT 256 + +union comdata { + short s[WIDTH]; + unsigned char b[0]; +}; + +#define SAMPLING_RATE 22050 + +/* ---------------------------------------------------------------------- */ + +/* + * child data structures + */ + +static Display *display = NULL; +static Window window; +static GC gc; +static Pixmap pixmap; +static unsigned long col_zeroline; +static unsigned long col_background; +static unsigned long col_trace; + +static int cmdpipe[2]; +static int datapipe[2]; + +/* + * parent data + */ + +struct xdisp { + int used; + pid_t pid; + int cmdfd; + int datafd; +}; + +#define NUMCLI 16 + +static struct xdisp cli[NUMCLI] = { { 0, }, }; + +/* ---------------------------------------------------------------------- */ + +static int x_error_handler(Display *disp, XErrorEvent *evt) +{ + char err_buf[256], mesg[256], number[256]; + char *mtype = "XlibMessage"; + + XGetErrorText(disp, evt->error_code, err_buf, sizeof(err_buf)); + (void)fprintf(stderr, "X Error: %s\n", err_buf); + XGetErrorDatabaseText(disp, mtype, "MajorCode", + "Request Major code %d", mesg, sizeof(mesg)); + (void)fprintf(stderr, mesg, evt->request_code); + (void)sprintf(number, "%d", evt->request_code); + XGetErrorDatabaseText(disp, "XRequest", number, "", err_buf, + sizeof(err_buf)); + (void)fprintf(stderr, " (%s)\n", err_buf); + + abort(); +} + +/* ---------------------------------------------------------------------- */ + +static Bool predicate(Display *display, XEvent *event, char *arg) +{ + return True; +} + +/* ---------------------------------------------------------------------- */ + +static char *x_getkey(void) +{ + XWindowAttributes winattrs; + XEvent evt; + static char kbuf[32]; + int i; + + if (!display) + return NULL; + while (XCheckIfEvent(display, &evt, predicate, NULL)) { + switch (evt.type) { + case KeyPress: + i = XLookupString((XKeyEvent *)&evt, kbuf, + sizeof(kbuf)-1, NULL, NULL); + if (i) { + kbuf[i] = 0; + return kbuf; + } + continue; + case DestroyNotify: + XCloseDisplay(display); + exit(0); + case Expose: + XGetWindowAttributes(display, window, &winattrs); + XCopyArea(display, window, pixmap, gc, 0, 0, + winattrs.width, winattrs.height, 0, 0); + continue; + default: + continue; + } + } + return NULL; +} + +/* ---------------------------------------------------------------------- */ + +static void process_keystrokes(void) +{ + char *cp; + + while ((cp = x_getkey())) { + printf("X: Keys pressed: %s\n", cp); + } +} + +/* ---------------------------------------------------------------------- */ + +static int do_x_select(int fd, int wr) +{ + int *xconn, xconnnum; + int max = fd, i; + fd_set rmask, wmask; + + if (!XInternalConnectionNumbers(display, &xconn, &xconnnum)) { + perror("XInternalConnectionNumbers"); + exit(1); + } + FD_ZERO(&rmask); + FD_ZERO(&wmask); + if (wr) + FD_SET(fd, &wmask); + else + FD_SET(fd, &rmask); + for (i = 0; i < xconnnum; i++) { + FD_SET(xconn[i], &rmask); + if (xconn[i] > max) + max = xconn[i]; + } + i = select(max+1, &rmask, &wmask, NULL, NULL); + if (i < 0) { + perror("select"); + exit(1); + } + for (i = 0; i < xconnnum; i++) + if (FD_ISSET(xconn[i], &rmask)) + XProcessInternalConnection(display, xconn[i]); + XFree(xconn); + process_keystrokes(); + if (wr) + return FD_ISSET(fd, &wmask); + else + return FD_ISSET(fd, &rmask); +} + +/* ---------------------------------------------------------------------- */ + +static void child_win_init(void) +{ + XSetWindowAttributes attr; + XGCValues gcv; + XColor color, dummy; + XSizeHints sizehints; + + /* + * start graphical output + */ + if (!(display = XOpenDisplay(NULL))) { + fprintf(stderr, "X: Unable to open X display\n"); + exit(1); + } + XSetErrorHandler(x_error_handler); + XAllocNamedColor(display, DefaultColormap(display, 0), "red", + &color, &dummy); + col_zeroline = color.pixel; + col_background = WhitePixel(display, 0); + col_trace = BlackPixel(display, 0); + attr.background_pixel = col_background; + window = XCreateWindow(display, XRootWindow(display, 0), + 200, 200, WIDTH, HEIGHT, 5, + DefaultDepth(display, 0), + InputOutput, DefaultVisual(display, 0), + CWBackPixel, &attr); + if (!(pixmap = XCreatePixmap(display, window, WIDTH, HEIGHT, + DefaultDepth(display, 0)))) { + fprintf(stderr, "X: unable to open offscreen pixmap\n"); + exit(1); + } + XSelectInput(display, window, KeyPressMask | StructureNotifyMask + | ExposureMask) ; + gcv.line_width = 1; + gcv.line_style = LineSolid; + gc = XCreateGC(display, pixmap, GCForeground | GCLineWidth, &gcv); + /* + * Do not allow the window to be resized + */ + memset(&sizehints, 0, sizeof(sizehints)); + sizehints.min_width = sizehints.max_width = WIDTH; + sizehints.min_height = sizehints.max_height = HEIGHT; + sizehints.flags = PMinSize | PMaxSize; + XSetWMNormalHints(display, window, &sizehints); + XMapWindow(display, window); + XSynchronize(display, 1); +} + +/* ---------------------------------------------------------------------- */ + +#define YCOORD(x) (((x)>>8)+(HEIGHT/2)) + +static void child_process(void) +{ + union comdata d; + unsigned char *bp; + int i, j; + + /* + * main loop + */ + for (;;) { + /* + * send synchronisation mark + */ + while (!do_x_select(cmdpipe[1], 1)); + i = write(cmdpipe[1], "r", 1); + if (i < 1) { + perror("write"); + exit(1); + } + /* + * read data + */ + for (j = sizeof(d), bp = d.b; j > 0; ) { + while (!do_x_select(datapipe[0], 0)); + i = read(datapipe[0], bp, j); + if (i < 1) { + perror("read"); + exit(1); + } + j -= i; + bp += i; + } + /* + * clear pixmap + */ + XSetState(display, gc, col_background, col_background, + GXcopy, AllPlanes); + XFillRectangle(display, pixmap, gc, 0, 0, + WIDTH, HEIGHT); + /* + * draw zero line + */ + XSetForeground(display, gc, col_zeroline); + XDrawLine(display, pixmap, gc, 0, YCOORD(0), WIDTH, + YCOORD(0)); + /* + * draw input + */ + XSetForeground(display, gc, col_trace); + for (i = 1; i < WIDTH; i++) + XDrawLine(display, pixmap, gc, i-1, YCOORD(d.s[i-1]), + i, YCOORD(d.s[i])); + XCopyArea(display, pixmap, window, gc, 0, 0, + WIDTH, HEIGHT, 0, 0); + /* XSync(display, 0); */ + } + XDestroyWindow(display, window); + XCloseDisplay(display); +} + +/* ---------------------------------------------------------------------- */ + +static void sigchld_handler(int sig) +{ + pid_t pid; + int st; + unsigned int cnum; + + while ((pid = wait4(0, &st, WNOHANG, NULL)) != (pid_t)-1) { + for (cnum = 0; cnum < NUMCLI; cnum++) + if (cli[cnum].used && cli[cnum].pid == pid) { + cli[cnum].used = 0; + close(cli[cnum].cmdfd); + close(cli[cnum].datafd); + cli[cnum].pid = (pid_t)-1; + fprintf(stderr, "child process %i died, " + "status %i\n", (int)pid, st); + } + } +} + +/* ---------------------------------------------------------------------- */ + +void xdisp_terminate(int cnum) +{ + if (cnum < 0 || cnum >= NUMCLI) + return; + kill(cli[cnum].pid, SIGTERM); +} + +/* ---------------------------------------------------------------------- */ + +int xdisp_start(void) +{ + unsigned int cnum; + + /* + * find free client struct + */ + for (cnum = 0; (cnum < NUMCLI) && cli[cnum].used; cnum++); + if (cnum >= NUMCLI) + return -1; + signal(SIGCHLD, sigchld_handler); + /* + * start "IPC" mechanism (using the pipes) + */ + if (pipe(cmdpipe)) + return -1; + if (pipe(datapipe)) { + close(cmdpipe[0]); + close(cmdpipe[1]); + } + if ((cli[cnum].pid = fork())) { + if (cli[cnum].pid == (pid_t)-1) { + /* error */ + close(cmdpipe[0]); + close(cmdpipe[1]); + close(datapipe[0]); + close(datapipe[1]); + return -1; + } + /* parent */ + cli[cnum].cmdfd = cmdpipe[0]; + close(cmdpipe[1]); + close(datapipe[0]); + cli[cnum].datafd = datapipe[1]; + cli[cnum].used = 1; + fcntl(cmdpipe[0], F_SETFL, + (fcntl(cmdpipe[0], F_GETFL, 0) | O_NDELAY)); + return cnum; + } + /* + * child; the X process + */ + close(cmdpipe[0]); + close(datapipe[1]); + close(0); /* close stdin */ + child_win_init(); + child_process(); + exit(0); +} + +/* ---------------------------------------------------------------------- */ + +int xdisp_update(int cnum, float *f) +{ + unsigned char *bp; + short *sp; + int i, j; + char c; + union comdata d; + + if (cnum < 0 || cnum >= NUMCLI) + return 0; + i = read(cli[cnum].cmdfd, &c, 1); + if (i < 0 && errno != EAGAIN) { + perror("read"); + xdisp_terminate(cnum); + return 0; + } + if (i < 1) + return 0; + if (c != 'r') + return 0; + for (sp = d.s, i = 0; i < WIDTH; i++, sp++, f++) { + if (*f >= 1) + *sp = 32767; + else if (*f <= -1) + *sp = -32767; + else + *sp = 32767.0 * (*f); + } + bp = d.b; + j = sizeof(d); + while (j > 0) { + i = write(cli[cnum].datafd, bp, j); + if (i < 0 && errno != EAGAIN) { + perror("write"); + xdisp_terminate(cnum); + return 0; + } + if (i > 0) { + bp += i; + j -= i; + } + } + return 1; +} + +/* ---------------------------------------------------------------------- */