mirror of
https://github.com/paparazzi/paparazzi.git
synced 2026-05-09 22:49:53 +08:00
Initial revision
This commit is contained in:
@@ -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
|
||||
@@ -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
|
||||
};
|
||||
@@ -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
|
||||
};
|
||||
@@ -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 <math.h>
|
||||
#include <string.h>
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* 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
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@@ -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 <math.h>
|
||||
#include <string.h>
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* 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
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@@ -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 <math.h>
|
||||
#include <string.h>
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* 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
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@@ -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 <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <signal.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
#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
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@@ -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 <math.h>
|
||||
#include <string.h>
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
*
|
||||
* 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
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@@ -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 <math.h>
|
||||
#include <string.h>
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
#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
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@@ -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 <math.h>
|
||||
#include <string.h>
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
#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
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@@ -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 <math.h>
|
||||
#include <string.h>
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
#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
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@@ -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 <math.h>
|
||||
#include <string.h>
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
#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
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@@ -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 <math.h>
|
||||
#include <string.h>
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
#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
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@@ -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 <math.h>
|
||||
#include <string.h>
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
#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
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@@ -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 <stdio.h>
|
||||
|
||||
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 */
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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 */
|
||||
@@ -0,0 +1,8 @@
|
||||
fifsk96.o
|
||||
fifsk96.p
|
||||
fifsk96.g
|
||||
72
|
||||
hamming
|
||||
0
|
||||
66150
|
||||
0 6100 1.000
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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 <stdio.h>
|
||||
#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);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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);
|
||||
|
||||
@@ -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 <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
*
|
||||
* 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;
|
||||
}
|
||||
@@ -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 <string.h>
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 <string.h>
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -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 <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
#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;
|
||||
}
|
||||
@@ -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 <string.h>
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@@ -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 <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
#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);
|
||||
}
|
||||
@@ -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 */
|
||||
@@ -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 <string.h>
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
#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, "<NUL>" },
|
||||
{ 1, "<SOH>" },
|
||||
{ 2, "<STX>" },
|
||||
{ 3, "<ETX>" },
|
||||
{ 4, "<EOT>" },
|
||||
{ 5, "<ENQ>" },
|
||||
{ 6, "<ACK>" },
|
||||
{ 7, "<BEL>" },
|
||||
{ 8, "<BS>" },
|
||||
{ 9, "<HT>" },
|
||||
{ 10, "<LF>" },
|
||||
{ 11, "<VT>" },
|
||||
{ 12, "<FF>" },
|
||||
{ 13, "<CR>" },
|
||||
{ 14, "<SO>" },
|
||||
{ 15, "<SI>" },
|
||||
{ 16, "<DLE>" },
|
||||
{ 17, "<DC1>" },
|
||||
{ 18, "<DC2>" },
|
||||
{ 19, "<DC3>" },
|
||||
{ 20, "<DC4>" },
|
||||
{ 21, "<NAK>" },
|
||||
{ 22, "<SYN>" },
|
||||
{ 23, "<ETB>" },
|
||||
{ 24, "<CAN>" },
|
||||
{ 25, "<EM>" },
|
||||
{ 26, "<SUB>" },
|
||||
{ 27, "<ESC>" },
|
||||
{ 28, "<FS>" },
|
||||
{ 29, "<GS>" },
|
||||
{ 30, "<RS>" },
|
||||
{ 31, "<US>" },
|
||||
#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, "-");
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@@ -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 <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/wait.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef SUN_AUDIO
|
||||
#include <sys/audioio.h>
|
||||
#include <stropts.h>
|
||||
#include <sys/conf.h>
|
||||
#else /* SUN_AUDIO */
|
||||
#include <sys/soundcard.h>
|
||||
#include <sys/ioctl.h>
|
||||
#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 <type> : input file type (any other type than raw requires sox)\n"
|
||||
" -a <demod> : add demodulator\n"
|
||||
" -s <demod> : 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);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@@ -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 <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <signal.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
Reference in New Issue
Block a user