unused demodulators

This commit is contained in:
Pascal Brisset
2005-08-19 21:13:25 +00:00
parent a7c24cf683
commit c5acca85d7
21 changed files with 18 additions and 2967 deletions
+13 -8
View File
@@ -21,7 +21,8 @@ LDFLAGSX =-lX11 -L/usr/X11R6/lib
endif
BINDIR =bin-$(shell uname -m)
#BINDIR =bin-$(shell uname -m)
BINDIR =.
AS86 =as86 -0 -a
LD86 =ld86 -0
@@ -37,7 +38,8 @@ AR =ar
STRIP =strip
MKDIR =mkdir
all: $(BINDIR) $(BINDIR)/multimon $(BINDIR)/gen
# all: $(BINDIR) $(BINDIR)/multimon $(BINDIR)/gen
all: $(BINDIR)/multimon
$(BINDIR)/%.s: %.c
$(CC) $(CFLAGS) -S -o $@ $<
@@ -48,12 +50,15 @@ $(BINDIR)/%.o: $(BINDIR)/%.s
$(BINDIR)/%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
SRC_L2 =hdlc.c pocsag.c pprz.c
SRC_L1 =demod_afsk12.c demod_afsk24.c demod_afsk24_2.c demod_afsk48p.c demod_afsk48.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_L2 =hdlc.c pprz.c
# pocsag.c
# SRC_L1 =demod_afsk12.c demod_afsk24.c demod_afsk24_2.c demod_afsk48p.c demod_afsk48.c
SRC_L1 = demod_afsk48p.c demod_display.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 xdisplay.c
# costabf.c
SRC_GEN =gen.c gen_dtmf.c gen_sin.c gen_zvei.c gen_hdlc.c costabi.c
-128
View File
@@ -1,128 +0,0 @@
/*
* 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
@@ -1,125 +0,0 @@
/*
* 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
@@ -1,125 +0,0 @@
/*
* 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
};
/* ---------------------------------------------------------------------- */
-133
View File
@@ -1,133 +0,0 @@
/*
* demod_afsk48.c -- 4800 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 "pprz.h"
#include <math.h>
#include <string.h>
/* ---------------------------------------------------------------------- */
/*
* Standard CMX469A clock frequency: 4.032 Mhz
* Xtal used: 4 MHz
* Ratio: 0.992063
* Mark frequency: 4761.905 Hz
* Space frequency: 2380.952 Hz
*/
#define FREQ_MARK 4762
#define FREQ_SPACE 2381
#define FREQ_SAMP 22050
//#define FREQ_SAMP 44100
#define BAUD 4762
/* ---------------------------------------------------------------------- */
#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 afsk48_init(struct demod_state *s)
{
float f;
int i;
pprz_init(s);
memset(&s->l1.afsk48, 0, sizeof(s->l1.afsk48));
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 afsk48_demod(struct demod_state *s, float *buffer, int length)
{
float f;
unsigned char curbit;
s->l1.afsk48p.sample_count += length;
if (s->l1.afsk48p.sample_count > FREQ_SAMP) {
s->l1.afsk48p.sample_count -= FREQ_SAMP;
pprz_status(s);
}
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.afsk48.dcd_shreg <<= 1;
s->l1.afsk48.dcd_shreg |= (f > 0);
verbprintf(10, "%c", '0'+(s->l1.afsk48.dcd_shreg & 1));
/*
* check if transition
*/
if ((s->l1.afsk48.dcd_shreg ^ (s->l1.afsk48.dcd_shreg >> 1)) & 1) {
if (s->l1.afsk48.sphase < (0x8000u-(SPHASEINC/2)))
s->l1.afsk48.sphase += SPHASEINC/8;
else
s->l1.afsk48.sphase -= SPHASEINC/8;
}
s->l1.afsk48.sphase += SPHASEINC;
if (s->l1.afsk48.sphase >= 0x10000u) {
s->l1.afsk48.sphase &= 0xffffu;
s->l1.afsk48.lasts <<= 1;
s->l1.afsk48.lasts |= s->l1.afsk48.dcd_shreg & 1;
curbit = (s->l1.afsk48.lasts ^
(s->l1.afsk48.lasts >> 1) ^ 1) & 1;
verbprintf(9, " %c ", '0'+curbit);
pprz_hdlc_rxbit(s, curbit);
}
}
}
/* ---------------------------------------------------------------------- */
const struct demod_param demod_afsk4800 = {
"AFSK4800", FREQ_SAMP, CORRLEN, afsk48_init, afsk48_demod
};
/* ---------------------------------------------------------------------- */
-134
View File
@@ -1,134 +0,0 @@
/*
* demod_afsk48p.c -- 4800 baud AFSK demodulator for paparazzi
*
* 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 "pprz.h"
#include <math.h>
#include <string.h>
/* ---------------------------------------------------------------------- */
/*
* Standard CMX469A clock frequency: 4.032 Mhz
* Xtal used: 4 MHz
* Ratio: 0.992063
* Mark frequency: 4761.905 Hz
* Space frequency: 2380.952 Hz
*/
#define FREQ_MARK 4762
#define FREQ_SPACE 2381
#define FREQ_SAMP 22050
//#define FREQ_SAMP 44100
#define BAUD 4762
/* ---------------------------------------------------------------------- */
#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 afsk48p_init(struct demod_state *s)
{
float f;
int i;
pprz_init(s);
memset(&s->l1.afsk48p, 0, sizeof(s->l1.afsk48p));
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;
}
s->l1.afsk48p.sample_count = 0;
}
/* ---------------------------------------------------------------------- */
static void afsk48p_demod(struct demod_state *s, float *buffer, int length)
{
float f;
unsigned char curbit;
s->l1.afsk48p.sample_count += length;
if (s->l1.afsk48p.sample_count > FREQ_SAMP) {
s->l1.afsk48p.sample_count -= FREQ_SAMP;
pprz_status(s);
}
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.afsk48p.dcd_shreg <<= 1;
s->l1.afsk48p.dcd_shreg |= (f > 0);
verbprintf(10, "%c", '0'+(s->l1.afsk48p.dcd_shreg & 1));
/*
* check if transition
*/
if ((s->l1.afsk48p.dcd_shreg ^ (s->l1.afsk48p.dcd_shreg >> 1)) & 1) {
if (s->l1.afsk48p.sphase < (0x8000u-(SPHASEINC/2)))
s->l1.afsk48p.sphase += SPHASEINC/8;
else
s->l1.afsk48p.sphase -= SPHASEINC/8;
}
s->l1.afsk48p.sphase += SPHASEINC;
if (s->l1.afsk48p.sphase >= 0x10000u) {
s->l1.afsk48p.sphase &= 0xffffu;
s->l1.afsk48p.lasts <<= 1;
s->l1.afsk48p.lasts |= s->l1.afsk48p.dcd_shreg & 1;
/* we use direct coded bits, not NRZI */
curbit = (s->l1.afsk48p.lasts ^ 1) & 1;
verbprintf(9, " %c ", '0'+curbit);
pprz_baudot_rxbit(s, curbit);
}
}
}
/* ---------------------------------------------------------------------- */
const struct demod_param demod_afsk4800p = {
"AFSK4800_P", FREQ_SAMP, CORRLEN, afsk48p_init, afsk48p_demod
};
/* ---------------------------------------------------------------------- */
@@ -1,86 +0,0 @@
/*
* 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;
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
@@ -1,151 +0,0 @@
/*
* 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
@@ -1,128 +0,0 @@
/*
* 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
};
/* ---------------------------------------------------------------------- */
-100
View File
@@ -1,100 +0,0 @@
/*
* 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
@@ -1,93 +0,0 @@
/*
* 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
@@ -1,80 +0,0 @@
/*
* 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
@@ -1,92 +0,0 @@
/*
* 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
@@ -1,146 +0,0 @@
/*
* 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
};
/* ---------------------------------------------------------------------- */
File diff suppressed because it is too large Load Diff
-95
View File
@@ -1,95 +0,0 @@
/*
* 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
@@ -1,208 +0,0 @@
/*
* 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
@@ -1,46 +0,0 @@
/*
* 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
@@ -1,87 +0,0 @@
/*
* 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;
}
+5 -4
View File
@@ -177,10 +177,11 @@ 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_afsk4800p, \
&demod_afsk4800, &demod_hapn4800, &demod_fsk9600, &demod_dtmf, \
&demod_zvei, &demod_scope
/* #define ALL_DEMOD &demod_poc5, &demod_poc12, &demod_poc24, \ */
/* &demod_afsk1200, &demod_afsk2400, &demod_afsk2400_2, &demod_afsk4800p, \ */
/* &demod_afsk4800, &demod_hapn4800, &demod_fsk9600, &demod_dtmf, \ */
/* &demod_zvei, &demod_scope */
#define ALL_DEMOD &demod_afsk4800p,&demod_scope
/* ---------------------------------------------------------------------- */
-477
View File
@@ -1,477 +0,0 @@
/*
* 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;
}
/* ---------------------------------------------------------------------- */
#if 0
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;
}
#endif
/* ---------------------------------------------------------------------- */
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, "-");
}
/* ---------------------------------------------------------------------- */