Initial revision

This commit is contained in:
Martin Mueller
2005-05-25 21:48:26 +00:00
parent f1c9cea489
commit ee20dab8e8
31 changed files with 6186 additions and 0 deletions
+92
View File
@@ -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
+262
View File
@@ -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
};
+134
View File
@@ -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
};
+128
View File
@@ -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
};
/* ---------------------------------------------------------------------- */
+125
View File
@@ -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
};
/* ---------------------------------------------------------------------- */
+125
View File
@@ -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
};
/* ---------------------------------------------------------------------- */
+151
View File
@@ -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
};
/* ---------------------------------------------------------------------- */
+128
View File
@@ -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
};
/* ---------------------------------------------------------------------- */
+99
View File
@@ -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
};
/* ---------------------------------------------------------------------- */
+93
View File
@@ -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
};
/* ---------------------------------------------------------------------- */
+80
View File
@@ -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
};
/* ---------------------------------------------------------------------- */
+92
View File
@@ -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
};
/* ---------------------------------------------------------------------- */
+146
View File
@@ -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
};
/* ---------------------------------------------------------------------- */
+277
View File
@@ -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 */
+110
View File
@@ -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
+97
View File
@@ -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);
+95
View File
@@ -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;
}
+208
View File
@@ -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;
}
+46
View File
@@ -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;
}
+87
View File
@@ -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;
}
+283
View File
@@ -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;
}
/* ---------------------------------------------------------------------- */
+63
View File
@@ -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);
}
+171
View File
@@ -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 */
+476
View File
@@ -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, "-");
}
/* ---------------------------------------------------------------------- */
+493
View File
@@ -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);
}
/* ---------------------------------------------------------------------- */
+440
View File
@@ -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;
}
/* ---------------------------------------------------------------------- */