mirror of
https://github.com/paparazzi/paparazzi.git
synced 2026-05-25 14:35:51 +08:00
[ground_segment] remove multimon (telemetry over audio)
This commit is contained in:
@@ -61,7 +61,6 @@ STATICINCLUDE=$(PAPARAZZI_HOME)/var/include
|
||||
CONF=$(PAPARAZZI_SRC)/conf
|
||||
AIRBORNE=sw/airborne
|
||||
SIMULATOR=sw/simulator
|
||||
MULTIMON=sw/ground_segment/multimon
|
||||
COCKPIT=sw/ground_segment/cockpit
|
||||
TMTC=sw/ground_segment/tmtc
|
||||
GENERATORS=$(PAPARAZZI_SRC)/sw/tools/generators
|
||||
@@ -143,19 +142,16 @@ libpprzlink:
|
||||
libpprz: libpprzlink _save_build_version
|
||||
$(MAKE) -C $(LIB)/ocaml
|
||||
|
||||
multimon:
|
||||
$(MAKE) -C $(MULTIMON)
|
||||
|
||||
cockpit: libpprz
|
||||
$(MAKE) -C $(COCKPIT)
|
||||
|
||||
cockpit.opt: libpprz
|
||||
$(MAKE) -C $(COCKPIT) opt
|
||||
|
||||
tmtc: libpprz cockpit multimon
|
||||
tmtc: libpprz cockpit
|
||||
$(MAKE) -C $(TMTC)
|
||||
|
||||
tmtc.opt: libpprz cockpit.opt multimon
|
||||
tmtc.opt: libpprz cockpit.opt
|
||||
$(MAKE) -C $(TMTC) opt
|
||||
|
||||
generators: libpprz
|
||||
@@ -333,7 +329,7 @@ test_sim: all
|
||||
prove tests/sim
|
||||
|
||||
.PHONY: all print_build_version _print_building _save_build_version update_google_version init dox ground_segment ground_segment.opt \
|
||||
subdirs $(SUBDIRS) conf ext libpprz multimon cockpit cockpit.opt tmtc tmtc.opt generators\
|
||||
subdirs $(SUBDIRS) conf ext libpprz cockpit cockpit.opt tmtc tmtc.opt generators\
|
||||
static sim_static lpctools commands \
|
||||
clean cleanspaces ab_clean dist_clean distclean dist_clean_irreversible \
|
||||
test test_examples test_math test_sim test_all_confs
|
||||
|
||||
@@ -2876,23 +2876,6 @@
|
||||
</msg_class>
|
||||
|
||||
|
||||
|
||||
<msg_class name="DIA"> <!-- data in audio -->
|
||||
<message name="NAV_INFO" id="1">
|
||||
<field name="unix_time" type="float"/>
|
||||
|
||||
<field name="lat" type="float" unit="deg"/>
|
||||
<field name="long" type="float" unit="deg"/>
|
||||
<field name="alt" type="uint16" unit="m"/>
|
||||
|
||||
<field name="course" type="uint16" unit="deg"/>
|
||||
<field name="speed" type="uint16" unit="cm/s"/>
|
||||
|
||||
<field name="cam_roll" type="int16" unit="deg"/>
|
||||
<field name="cam_pitch" type="int16" unit="deg"/>
|
||||
</message>
|
||||
</msg_class>
|
||||
|
||||
<msg_class name="intermcu">
|
||||
<message name="IMCU_COMMANDS" id="1">
|
||||
<field name="status" type="uint8"/>
|
||||
@@ -2905,5 +2888,4 @@
|
||||
</message>
|
||||
</msg_class>
|
||||
|
||||
|
||||
</protocol>
|
||||
|
||||
@@ -31,7 +31,7 @@ INCLUDES=
|
||||
LIBS=
|
||||
LIBSX=$(LIBS:.cma=.cmxa)
|
||||
|
||||
INCLUDES= -I ../multimon
|
||||
INCLUDES=
|
||||
PKG = -package pprz.xlib
|
||||
LINKPKG = $(PKG) -linkpkg -dllpath-pkg pprz.xlib,pprzlink
|
||||
|
||||
|
||||
@@ -1,151 +0,0 @@
|
||||
# Hey Emacs, this is a -*- makefile -*-
|
||||
#
|
||||
# Copyright (C) 2003-2012 The Paparazzi Team
|
||||
#
|
||||
# This file is part of paparazzi.
|
||||
#
|
||||
# paparazzi 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, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# paparazzi 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 paparazzi; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
# Boston, MA 02111-1307, USA.
|
||||
|
||||
# Quiet compilation
|
||||
# Launch with "make Q=''" to get full command display
|
||||
Q=@
|
||||
|
||||
DEBUG=n
|
||||
MACHINE:=$(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
|
||||
|
||||
include ../../Makefile.ocaml
|
||||
|
||||
CFLAGS=-Wall -Wstrict-prototypes -I/usr/X11R6/include -I`$(OCAMLC) -where`
|
||||
ifeq ($(DEBUG),y)
|
||||
CFLAGS += -g -O
|
||||
else
|
||||
CFLAGS += -O3
|
||||
endif
|
||||
|
||||
ifeq ($(MACHINE),'i686')
|
||||
CFLAGS += -march=i486 -falign-loops=2 -falign-jumps=2 -falign-functions=2 -DARCH_I386
|
||||
else
|
||||
# PositionIndependentCode for all other architectures
|
||||
CFLAGS += -fPIC
|
||||
endif
|
||||
|
||||
LDFLAGSX = -lX11 -L/usr/X11R6/lib
|
||||
|
||||
#BINDIR = bin-$(shell uname -m)
|
||||
BINDIR =.
|
||||
|
||||
UNAME = $(shell uname -s)
|
||||
ifneq (,$(findstring $(UNAME),linux Linux))
|
||||
OBJFILES=pprzlib.o hdlc.o demod_afsk12.o demodml.o costabi.o gen_hdlc.o ml_hdlc.o demod.cmo hdlc.cmo
|
||||
ALLTARGETS=$(BINDIR)/multimon multimon.cma
|
||||
endif
|
||||
ifeq ($(UNAME),Darwin)
|
||||
OBJFILES=demodml.o ml_hdlc.o demod.cmo hdlc.cmo
|
||||
ALLTARGETS=multimon.cma
|
||||
endif
|
||||
|
||||
all: $(ALLTARGETS)
|
||||
|
||||
multimon.cma: $(OBJFILES)
|
||||
@echo OLD $@
|
||||
$(Q)ocamlmklib -o multimon $^
|
||||
|
||||
|
||||
$(BINDIR)/%.s: %.c
|
||||
$(CC) $(CFLAGS) -S -o $@ $<
|
||||
|
||||
$(BINDIR)/%.o: $(BINDIR)/%.s
|
||||
$(AS) -c -o $@ $<
|
||||
|
||||
$(BINDIR)/%.o: %.c
|
||||
@echo CC $<
|
||||
$(Q)$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
SRC_L2 = hdlc.c pprz.c
|
||||
SRC_L1 = demod_afsk48p.c demod_display.c
|
||||
SRC_MISC = unixinput.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)
|
||||
@echo LD $@
|
||||
$(Q)$(CC) $^ $(LDFLAGS) $(LDFLAGSX) -o $@
|
||||
|
||||
$(BINDIR)/gen: $(OBJ_GEN)
|
||||
@echo LD $@
|
||||
$(Q)$(CC) $^ $(LDFLAGS) -o $@
|
||||
|
||||
$(BINDIR)/mkcostab: $(BINDIR)/mkcostab.o
|
||||
@echo LD $@
|
||||
$(Q)$(CC) $^ $(LDFLAGS) -o $@
|
||||
|
||||
costabi.c costabf.c: $(BINDIR)/mkcostab
|
||||
@echo EXEC $<
|
||||
$(Q)$(BINDIR)/mkcostab
|
||||
|
||||
|
||||
libtest: pprzlib.o demodml.c demod.ml test.ml
|
||||
$(OCAMLC) -custom -o $@ pprzlib.o demodml.c -I +lablgtk2 unix.cma lablgtk.cma demod.ml test.ml
|
||||
|
||||
hdlc_test : multimon.cma test_gen_hdlc.ml
|
||||
$(OCAMLC) -o $@ -custom -I +lablgtk2 -thread unix.cma threads.cma lablgtk.cma gtkThread.cmo -I . $^ -cclib -ljack
|
||||
|
||||
hdlc.cmo : hdlc.cmi
|
||||
|
||||
%.cmo : %.ml
|
||||
@echo OC $<
|
||||
$(Q)$(OCAMLC) -c $<
|
||||
|
||||
%.cmi : %.mli
|
||||
@echo OC $<
|
||||
$(Q)$(OCAMLC) $<
|
||||
|
||||
clean:
|
||||
$(Q)rm -fr *.cm* mkcostab .depend
|
||||
$(Q)$(RM) -f core `find . -name '*.[oas]' -print` *.so
|
||||
$(Q)$(RM) -f core `find . -name 'core' -print`
|
||||
$(Q)$(RM) -f core costabi.c costabf.c *~
|
||||
$(Q)$(RM) $(BINDIR)/multimon
|
||||
|
||||
.PHONY: all clean depend dep
|
||||
|
||||
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
|
||||
@@ -1,34 +0,0 @@
|
||||
Linux Radio Transmission Decoder
|
||||
by Thomas Sailer, HB9JNX/AE4WA
|
||||
Paparazzi adaptions added by Martin Mueller, DL3FCC
|
||||
|
||||
Description
|
||||
|
||||
The multimon software can decode a variety of digital transmission modes commonly found on UHF radio. A standard PC soundcard is used to acquire the signal from a transceiver. The decoding is done completely in software. Currently, the following modes are supported:
|
||||
|
||||
* AX.25
|
||||
o 1200 Baud AFSK
|
||||
o 2400 Baud AFSK (2 variants)
|
||||
o 4800 Baud HAPN
|
||||
o 9600 Baud FSK (G3RUH)
|
||||
* POCSAG
|
||||
o 512 Baud
|
||||
o 1200 Baud
|
||||
o 2400 Baud
|
||||
* Miscellaneous
|
||||
o DTMF
|
||||
o ZVEI
|
||||
o 4800 Baud AFSK PPRZ (baudot and hdlc)
|
||||
|
||||
An arbitrary set of the above modes may run concurrently on the same input signal (provided the CPU power is sufficient), so you do not have to know in advance which mode is used. Note however that some modes might require modifications to the radio (especially the 9600 baud FSK and the POCSAG modes) to work properly.
|
||||
|
||||
POCSAG (Post Office Code Standards Advisory Group) is a common paging transmission format.
|
||||
Download
|
||||
|
||||
PPRZ is a proprietary 4800 Baud baudot-like protocol. This is used by the Paparazzi project which is located at http://www.nongnu.org/paparazzi
|
||||
|
||||
Please note that monitoring commercial services may be prohibited in some countries, this software should therefore only be used to monitor the amateur radio service.
|
||||
|
||||
The software is published under the GNU GPL V2
|
||||
|
||||
The original software can be found at http://www.baycom.org/~tom/ham/linux/multimon.html
|
||||
@@ -1,2 +0,0 @@
|
||||
external init : string -> Unix.file_descr = "ml_demod_init"
|
||||
external get_data : unit -> string * string = "ml_demod_get_data"
|
||||
@@ -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];
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@@ -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
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@@ -1,48 +0,0 @@
|
||||
#include <caml/mlvalues.h>
|
||||
#include <caml/fail.h>
|
||||
#include <caml/alloc.h>
|
||||
#include <caml/memory.h>
|
||||
|
||||
#include "pprzlib.h"
|
||||
|
||||
value
|
||||
ml_demod_init(value dev) {
|
||||
#ifndef __APPLE__
|
||||
int fd = pprz_demod_init(String_val(dev));
|
||||
return Val_int(fd);
|
||||
#else
|
||||
failwith("Not supported under OSX");
|
||||
return Val_int(0);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
value
|
||||
ml_demod_get_data(value unit) {
|
||||
#ifndef __APPLE__
|
||||
struct data *data = pprz_demod_read_data();
|
||||
if (data) {
|
||||
int i;
|
||||
|
||||
CAMLparam0();
|
||||
CAMLlocal3 (result,l, r);
|
||||
result = alloc(2, 0);
|
||||
l = alloc_string(data->len_left);
|
||||
for(i = 0; i < data->len_left; i++) Byte(l, i) = data->data_left[i];
|
||||
r = alloc_string(data->len_right);
|
||||
for(i = 0; i < data->len_right; i++) Byte(r, i) = data->data_right[i];
|
||||
|
||||
Store_field(result, 0, l);
|
||||
Store_field(result, 1, r);
|
||||
CAMLreturn (result);
|
||||
} else {
|
||||
failwith("End of file");
|
||||
}
|
||||
#else
|
||||
CAMLparam0();
|
||||
CAMLlocal3 (result,l, r);
|
||||
result = alloc(2, 0);
|
||||
failwith("Not supported under OSX");
|
||||
CAMLreturn (result);
|
||||
#endif
|
||||
}
|
||||
@@ -1,458 +0,0 @@
|
||||
/*
|
||||
* 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>
|
||||
|
||||
static 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;
|
||||
}
|
||||
|
||||
static 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 8:
|
||||
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"
|
||||
"faddp;\n\t" :
|
||||
"=t" (f) :
|
||||
"r" (a),
|
||||
"r" (b) : "memory");
|
||||
return f;
|
||||
|
||||
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;
|
||||
case 36:
|
||||
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"
|
||||
"flds 96(%1);\n\t"
|
||||
"fmuls 96(%2);\n\t"
|
||||
"fxch %%st(2);\n\t"
|
||||
"faddp;\n\t"
|
||||
"flds 100(%1);\n\t"
|
||||
"fmuls 100(%2);\n\t"
|
||||
"fxch %%st(2);\n\t"
|
||||
"faddp;\n\t"
|
||||
"flds 104(%1);\n\t"
|
||||
"fmuls 104(%2);\n\t"
|
||||
"fxch %%st(2);\n\t"
|
||||
"faddp;\n\t"
|
||||
"flds 108(%1);\n\t"
|
||||
"fmuls 108(%2);\n\t"
|
||||
"fxch %%st(2);\n\t"
|
||||
"faddp;\n\t"
|
||||
"flds 112(%1);\n\t"
|
||||
"fmuls 112(%2);\n\t"
|
||||
"fxch %%st(2);\n\t"
|
||||
"faddp;\n\t"
|
||||
"flds 116(%1);\n\t"
|
||||
"fmuls 116(%2);\n\t"
|
||||
"fxch %%st(2);\n\t"
|
||||
"faddp;\n\t"
|
||||
"flds 120(%1);\n\t"
|
||||
"fmuls 120(%2);\n\t"
|
||||
"fxch %%st(2);\n\t"
|
||||
"faddp;\n\t"
|
||||
"flds 124(%1);\n\t"
|
||||
"fmuls 124(%2);\n\t"
|
||||
"fxch %%st(2);\n\t"
|
||||
"faddp;\n\t"
|
||||
"flds 128(%1);\n\t"
|
||||
"fmuls 128(%2);\n\t"
|
||||
"fxch %%st(2);\n\t"
|
||||
"faddp;\n\t"
|
||||
"flds 132(%1);\n\t"
|
||||
"fmuls 132(%2);\n\t"
|
||||
"fxch %%st(2);\n\t"
|
||||
"faddp;\n\t"
|
||||
"flds 136(%1);\n\t"
|
||||
"fmuls 136(%2);\n\t"
|
||||
"fxch %%st(2);\n\t"
|
||||
"faddp;\n\t"
|
||||
"flds 140(%1);\n\t"
|
||||
"fmuls 140(%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 */
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,110 +0,0 @@
|
||||
/*
|
||||
* 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 */
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
static inline unsigned int hweight32(unsigned int w)
|
||||
__attribute__ ((unused));
|
||||
static inline unsigned int hweight16(unsigned short w)
|
||||
__attribute__ ((unused));
|
||||
static inline unsigned int hweight8(unsigned char w)
|
||||
__attribute__ ((unused));
|
||||
|
||||
static 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);
|
||||
}
|
||||
|
||||
static 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);
|
||||
}
|
||||
|
||||
static 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);
|
||||
}
|
||||
|
||||
static inline unsigned int gcd(unsigned int x, unsigned int y)
|
||||
__attribute__ ((unused));
|
||||
static inline unsigned int lcm(unsigned int x, unsigned int y)
|
||||
__attribute__ ((unused));
|
||||
|
||||
static 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;
|
||||
}
|
||||
}
|
||||
|
||||
static inline unsigned int lcm(unsigned int x, unsigned int y)
|
||||
{
|
||||
return x * y / gcd(x, y);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
#ifndef __HAVE_ARCH_MAC
|
||||
static 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 */
|
||||
|
||||
static inline float fsqr(float f)
|
||||
{
|
||||
return f*f;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
#endif /* _FILTER_H */
|
||||
@@ -1,97 +0,0 @@
|
||||
/*
|
||||
* 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 DEFAULT_SAMPLE_RATE 22050
|
||||
extern int hdlc_sample_rate;
|
||||
|
||||
#define MS(x) ((float)(x)*SAMPLE_RATE/1000)
|
||||
|
||||
extern const int costabi[0x400];
|
||||
|
||||
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);
|
||||
|
||||
@@ -1,216 +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>
|
||||
|
||||
#define COS(x) costabi[(((x)>>6)&0x3ffu)]
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/*
|
||||
* 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 hdlc_sample_rate = DEFAULT_SAMPLE_RATE;
|
||||
|
||||
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 / hdlc_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/hdlc_sample_rate : 0x10000*1200/hdlc_sample_rate;
|
||||
}
|
||||
*buf += (p->ampl * COS(s->s.hdlc.ph)) >> 15;
|
||||
s->s.hdlc.ph += s->s.hdlc.phinc;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
@@ -1,295 +0,0 @@
|
||||
/*
|
||||
* 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>
|
||||
#include <stdio.h>
|
||||
|
||||
char hdlc_data_received[HDLC_DATA_LEN];
|
||||
int hdlc_data_received_idx;
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* 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(1, "%s: fm ? to ", s->dem_par->name);
|
||||
i = (bp[2] >> 2) & 0x3f;
|
||||
if (i)
|
||||
verbprintf(1, "%c",i+0x20);
|
||||
i = ((bp[2] << 4) | ((bp[3] >> 4) & 0xf)) & 0x3f;
|
||||
if (i)
|
||||
verbprintf(1, "%c",i+0x20);
|
||||
i = ((bp[3] << 2) | ((bp[4] >> 6) & 3)) & 0x3f;
|
||||
if (i)
|
||||
verbprintf(1, "%c",i+0x20);
|
||||
i = bp[4] & 0x3f;
|
||||
if (i)
|
||||
verbprintf(1, "%c",i+0x20);
|
||||
i = (bp[5] >> 2) & 0x3f;
|
||||
if (i)
|
||||
verbprintf(1, "%c",i+0x20);
|
||||
i = ((bp[5] << 4) | ((bp[6] >> 4) & 0xf)) & 0x3f;
|
||||
if (i)
|
||||
verbprintf(1, "%c",i+0x20);
|
||||
verbprintf(1, "-%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(1, "%s: fm ", s->dem_par->name);
|
||||
for(i = 7; i < 13; i++)
|
||||
if ((bp[i] &0xfe) != 0x40)
|
||||
verbprintf(1, "%c",bp[i] >> 1);
|
||||
verbprintf(1, "-%u to ",(bp[13] >> 1) & 0xf);
|
||||
for(i = 0; i < 6; i++)
|
||||
if ((bp[i] &0xfe) != 0x40)
|
||||
verbprintf(1, "%c",bp[i] >> 1);
|
||||
verbprintf(1, "-%u",(bp[6] >> 1) & 0xf);
|
||||
bp += 14;
|
||||
len -= 14;
|
||||
if ((!(bp[-1] & 1)) && (len >= 7))
|
||||
verbprintf(1, " via ");
|
||||
while ((!(bp[-1] & 1)) && (len >= 7)) {
|
||||
for(i = 0; i < 6; i++)
|
||||
if ((bp[i] &0xfe) != 0x40)
|
||||
verbprintf(1, "%c",bp[i] >> 1);
|
||||
verbprintf(1, "-%u",(bp[6] >> 1) & 0xf);
|
||||
bp += 7;
|
||||
len -= 7;
|
||||
if ((!(bp[-1] & 1)) && (len >= 7))
|
||||
verbprintf(1, ",");
|
||||
}
|
||||
}
|
||||
|
||||
if(!len)
|
||||
return;
|
||||
i = *bp++;
|
||||
len--;
|
||||
j = v1 ? ((i & 0x10) ? '!' : ' ') :
|
||||
((i & 0x10) ? (cmd ? '+' : '-') : (cmd ? '^' : 'v'));
|
||||
if (!(i & 1)) {
|
||||
/*
|
||||
* Info frame
|
||||
*/
|
||||
verbprintf(1, " I%u%u%c",(i >> 5) & 7,(i >> 1) & 7,j);
|
||||
} else if (i & 2) {
|
||||
/*
|
||||
* U frame
|
||||
*/
|
||||
switch (i & (~0x10)) {
|
||||
case 0x03:
|
||||
verbprintf(1, " UI%c",j);
|
||||
break;
|
||||
case 0x2f:
|
||||
verbprintf(1, " SABM%c",j);
|
||||
break;
|
||||
case 0x43:
|
||||
verbprintf(1, " DISC%c",j);
|
||||
break;
|
||||
case 0x0f:
|
||||
verbprintf(1, " DM%c",j);
|
||||
break;
|
||||
case 0x63:
|
||||
verbprintf(1, " UA%c",j);
|
||||
break;
|
||||
case 0x87:
|
||||
verbprintf(1, " FRMR%c",j);
|
||||
break;
|
||||
default:
|
||||
verbprintf(1, " unknown U (0x%x)%c",i & (~0x10),j);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* supervisory
|
||||
*/
|
||||
switch (i & 0xf) {
|
||||
case 0x1:
|
||||
verbprintf(1, " RR%u%c",(i >> 5) & 7,j);
|
||||
break;
|
||||
case 0x5:
|
||||
verbprintf(1, " RNR%u%c",(i >> 5) & 7,j);
|
||||
break;
|
||||
case 0x9:
|
||||
verbprintf(1, " REJ%u%c",(i >> 5) & 7,j);
|
||||
break;
|
||||
default:
|
||||
verbprintf(1, " unknown S (0x%x)%u%c", i & 0xf,
|
||||
(i >> 5) & 7, j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!len) {
|
||||
verbprintf(1, "\n");
|
||||
return;
|
||||
}
|
||||
verbprintf(1, " pid=%02X\n", *bp++);
|
||||
len--;
|
||||
j = 0;
|
||||
while (len) {
|
||||
i = *bp++;
|
||||
if (hdlc_data_received_idx < HDLC_DATA_LEN)
|
||||
hdlc_data_received[hdlc_data_received_idx++] = i;
|
||||
else
|
||||
fprintf(stderr, "hdlc buffer full: discarding 1 char\n");
|
||||
if ((i >= 32) && (i < 128)) {
|
||||
verbprintf(1, "%c",i);
|
||||
} else if (i == 13) {
|
||||
if (j)
|
||||
verbprintf(1, "\n");
|
||||
j = 0;
|
||||
} else
|
||||
verbprintf(1, ".");
|
||||
if (i >= 32)
|
||||
j = 1;
|
||||
len--;
|
||||
}
|
||||
if (j)
|
||||
verbprintf(1, "\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;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@@ -1,8 +0,0 @@
|
||||
|
||||
external init_gen : string -> Unix.file_descr = "ml_init_gen_hdlc"
|
||||
external init_dec : string -> Unix.file_descr = "ml_init_dec_hdlc"
|
||||
external write_data : string -> unit = "ml_gen_hdlc"
|
||||
external get_data : unit -> string = "ml_get_hdlc"
|
||||
external write_to_dsp : unit -> unit = "ml_write_to_dsp"
|
||||
|
||||
let write_period = 90
|
||||
@@ -1,9 +0,0 @@
|
||||
val init_gen : string -> Unix.file_descr
|
||||
val write_data : string -> unit
|
||||
val write_to_dsp : unit -> unit
|
||||
|
||||
val write_period : int
|
||||
(** (ms) Recommended period to call write_to_dsp *)
|
||||
|
||||
val init_dec : string -> Unix.file_descr
|
||||
val get_data : unit -> string
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* 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>
|
||||
#include <stdlib.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);
|
||||
}
|
||||
@@ -1,334 +0,0 @@
|
||||
/*
|
||||
* ml_hdlc.c -- OCaml binding to multimon HDLC library
|
||||
*
|
||||
* Copyright (C) 1997
|
||||
* Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu)
|
||||
* Copyright (C) 2007, Pascal Brisset for Paparazzi
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifndef __APPLE__
|
||||
#include <sys/soundcard.h>
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
#include <caml/mlvalues.h>
|
||||
#include <caml/fail.h>
|
||||
#include <caml/alloc.h>
|
||||
#include <caml/memory.h>
|
||||
#include <caml/signals.h>
|
||||
|
||||
#include "gen.h"
|
||||
#include "multimon.h"
|
||||
|
||||
#define Min(a, b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
static struct gen_params params;
|
||||
static struct gen_state state;
|
||||
int fd;
|
||||
int fmt = 0;
|
||||
|
||||
#define MY_BUF_LEN 32768
|
||||
short my_buffer[MY_BUF_LEN];
|
||||
int idx_start, idx_end;
|
||||
|
||||
/** intermediate buffer */
|
||||
#define BUF_LEN 16384
|
||||
short silence_buffer[BUF_LEN];
|
||||
|
||||
|
||||
#define OUTPUT_BUF_LEN 1024
|
||||
|
||||
|
||||
static struct demod_state dem_st;
|
||||
|
||||
|
||||
static int process_buffer(short *buf, int len)
|
||||
{
|
||||
memset(buf, 0, len*sizeof(buf[0]));
|
||||
return gen_hdlc(buf, len, ¶ms, &state);
|
||||
}
|
||||
|
||||
value ml_init_gen_hdlc(value device) {
|
||||
/** From multimon, gen.c:output_sound() */
|
||||
|
||||
#ifndef __APPLE__
|
||||
char *ifname=String_val(device);
|
||||
int sample_rate = DEFAULT_SAMPLE_RATE;
|
||||
|
||||
int sndparam;
|
||||
|
||||
if ((fd = open(ifname ? ifname : "/dev/dsp", O_WRONLY)) < 0) {
|
||||
caml_failwith("open");
|
||||
exit (10);
|
||||
}
|
||||
|
||||
/** Doesn't work, stay with 8192
|
||||
int frag = (0x7fff << 16) | (14); // 14=16384, http://manuals.opensound.com/developer/SNDCTL_DSP_SETFRAGMENT.html
|
||||
ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &frag);
|
||||
*/
|
||||
|
||||
sndparam = AFMT_S16_LE; /* we want 16 bits/sample signed */
|
||||
/* little endian; works only on little endian systems! */
|
||||
if (ioctl(fd, SNDCTL_DSP_SETFMT, &sndparam) == -1) {
|
||||
perror("ioctl: SNDCTL_DSP_SETFMT");
|
||||
exit (10);
|
||||
}
|
||||
if (sndparam != AFMT_S16_LE) {
|
||||
fmt = 1;
|
||||
sndparam = AFMT_U8;
|
||||
if (ioctl(fd, SNDCTL_DSP_SETFMT, &sndparam) == -1) {
|
||||
perror("ioctl: SNDCTL_DSP_SETFMT");
|
||||
exit (10);
|
||||
}
|
||||
if (sndparam != AFMT_U8) {
|
||||
perror("ioctl: SNDCTL_DSP_SETFMT");
|
||||
exit (10);
|
||||
}
|
||||
}
|
||||
sndparam = 0; /* we want only 1 channel */
|
||||
if (ioctl(fd, SNDCTL_DSP_STEREO, &sndparam) == -1) {
|
||||
perror("ioctl: SNDCTL_DSP_STEREO");
|
||||
exit (10);
|
||||
}
|
||||
if (sndparam != 0) {
|
||||
fprintf(stderr, "gen: Error, cannot set the channel "
|
||||
"number to 1\n");
|
||||
exit (10);
|
||||
}
|
||||
sndparam = sample_rate;
|
||||
if (ioctl(fd, SNDCTL_DSP_SPEED, &sndparam) == -1) {
|
||||
perror("ioctl: SNDCTL_DSP_SPEED");
|
||||
exit (10);
|
||||
}
|
||||
if ((10*abs(sndparam-sample_rate)) > sample_rate) {
|
||||
perror("ioctl: SNDCTL_DSP_SPEED");
|
||||
exit (10);
|
||||
}
|
||||
if (sndparam != sample_rate) {
|
||||
fprintf(stderr, "Warning: Sampling rate is %u, "
|
||||
"requested %u\n", sndparam, sample_rate);
|
||||
}
|
||||
|
||||
|
||||
params.type = gentype_hdlc;
|
||||
params.ampl = 16384;
|
||||
params.p.hdlc.modulation = 0;
|
||||
params.p.hdlc.pkt[0] = ('H') << 1;
|
||||
params.p.hdlc.pkt[1] = ('B') << 1;
|
||||
params.p.hdlc.pkt[2] = ('9') << 1;
|
||||
params.p.hdlc.pkt[3] = ('J') << 1;
|
||||
params.p.hdlc.pkt[4] = ('N') << 1;
|
||||
params.p.hdlc.pkt[5] = ('X') << 1;
|
||||
params.p.hdlc.pkt[6] = (0x00) << 1;
|
||||
params.p.hdlc.pkt[7] = ('A') << 1;
|
||||
params.p.hdlc.pkt[8] = ('E') << 1;
|
||||
params.p.hdlc.pkt[9] = ('4') << 1;
|
||||
params.p.hdlc.pkt[10] = ('W') << 1;
|
||||
params.p.hdlc.pkt[11] = ('A') << 1;
|
||||
params.p.hdlc.pkt[12] = (' ') << 1;
|
||||
params.p.hdlc.pkt[13] = ((0x00) << 1) | 1;
|
||||
params.p.hdlc.pkt[14] = 0x03;
|
||||
params.p.hdlc.pkt[15] = 0xf0;
|
||||
|
||||
/** Generate a buffer full of silence **/
|
||||
params.p.hdlc.txdelay = 100; /* 1 s */
|
||||
params.p.hdlc.pktlen = 16;
|
||||
memset(&state, 0, sizeof(state));
|
||||
gen_init_hdlc(¶ms, &state);
|
||||
process_buffer(silence_buffer, sizeof(silence_buffer)/sizeof(silence_buffer[0]));
|
||||
|
||||
idx_start = idx_end = 0;
|
||||
|
||||
return Val_int(fd);
|
||||
#else
|
||||
failwith("Not supported under OSX");
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
value ml_init_dec_hdlc(value dev) {
|
||||
char *ifname = String_val(dev);
|
||||
#ifndef __APPLE__
|
||||
if ((fd = open(ifname, O_RDONLY)) < 0) {
|
||||
caml_failwith("Hdlc.init_dec: open failed");
|
||||
}
|
||||
|
||||
int 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) {
|
||||
perror("ioctl: AFMT_S16_LE");
|
||||
exit (10);
|
||||
}
|
||||
|
||||
sndparam = DEFAULT_SAMPLE_RATE;
|
||||
if (ioctl(fd, SNDCTL_DSP_SPEED, &sndparam) == -1) {
|
||||
perror("ioctl: SNDCTL_DSP_SPEED");
|
||||
exit (10);
|
||||
}
|
||||
if ((10*abs(sndparam-DEFAULT_SAMPLE_RATE)) > DEFAULT_SAMPLE_RATE) {
|
||||
perror("ioctl: SNDCTL_DSP_SPEED");
|
||||
exit (10);
|
||||
}
|
||||
if (sndparam != DEFAULT_SAMPLE_RATE) {
|
||||
fprintf(stderr, "Warning: Sampling rate is %u, "
|
||||
"requested %u\n", sndparam, DEFAULT_SAMPLE_RATE);
|
||||
}
|
||||
|
||||
memset(&dem_st, 0, sizeof(struct demod_state));
|
||||
afsk12_init(&dem_st);
|
||||
dem_st.dem_par = &demod_afsk1200;
|
||||
return Val_int(fd);
|
||||
#else
|
||||
failwith("Not supported under OSX");
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
value ml_gen_hdlc(value val_data) {
|
||||
#ifndef __APPLE__
|
||||
/** Handling the data input */
|
||||
int data_len = string_length(val_data);
|
||||
if (data_len + 16 > sizeof(params.p.hdlc.pkt))
|
||||
caml_invalid_argument("Hdlc.write_data: argument too large");
|
||||
|
||||
char *data = String_val(val_data);
|
||||
int i;
|
||||
for(i = 0; i < data_len; i++) {
|
||||
params.p.hdlc.pkt[16+i] = data[i];
|
||||
}
|
||||
params.p.hdlc.pktlen = 16 + data_len;
|
||||
params.p.hdlc.txdelay = 10;
|
||||
|
||||
memset(&state, 0, sizeof(state));
|
||||
gen_init_hdlc(¶ms, &state);
|
||||
|
||||
/** Intermediate buffer */
|
||||
short s[BUF_LEN];
|
||||
|
||||
int n = process_buffer(s, sizeof(s)/sizeof(s[0]));
|
||||
assert(state.s.hdlc.ch_idx == state.s.hdlc.datalen);
|
||||
|
||||
int occupied = (idx_end + MY_BUF_LEN - idx_start) % MY_BUF_LEN;
|
||||
if (occupied + n > MY_BUF_LEN) {
|
||||
caml_failwith("buffer full");
|
||||
} else {
|
||||
int i;
|
||||
for(i = 0; i < n; i++)
|
||||
my_buffer[(idx_end+i) % MY_BUF_LEN] = s[i];
|
||||
idx_end = (idx_end + n) % MY_BUF_LEN;
|
||||
}
|
||||
|
||||
return Val_unit;
|
||||
#else
|
||||
failwith("Not supported under OSX");
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* max ospace = 8192 = 4096 samples = 4096/22050 seconds = 0.18 */
|
||||
value ml_write_to_dsp(value _) {
|
||||
#ifndef __APPLE__
|
||||
audio_buf_info bi;
|
||||
ioctl(fd, SNDCTL_DSP_GETOSPACE, &bi);
|
||||
int ospace = bi.bytes;
|
||||
|
||||
int n = ospace/sizeof(short);
|
||||
|
||||
int available = (idx_end + MY_BUF_LEN - idx_start) % MY_BUF_LEN;
|
||||
/* complete with silence */
|
||||
int i;
|
||||
for(i = available; i < n; i++) {
|
||||
my_buffer[(idx_start+i)%MY_BUF_LEN] = silence_buffer[i];
|
||||
}
|
||||
|
||||
int k = Min(n, MY_BUF_LEN - idx_start);
|
||||
int num = write(fd, my_buffer+idx_start, k*sizeof(short));
|
||||
num += write(fd, my_buffer+0, (n - k)*sizeof(short));
|
||||
if (available <= n) {
|
||||
/* buffer is empty */
|
||||
idx_start = idx_end = 0;
|
||||
} else {
|
||||
idx_start = (idx_start + n) % MY_BUF_LEN;
|
||||
}
|
||||
|
||||
assert(num == n*sizeof(short));
|
||||
|
||||
return Val_unit
|
||||
#else
|
||||
failwith("Not supported under OSX");
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
static union {
|
||||
short s[8192];
|
||||
unsigned char b[8192];
|
||||
} b;
|
||||
static float fbuf[16384];
|
||||
static unsigned int fbuf_cnt = 0;
|
||||
|
||||
|
||||
value ml_get_hdlc(value unit) {
|
||||
#ifndef __APPLE__
|
||||
unsigned int overlap = demod_afsk1200.overlap;
|
||||
short *sp;
|
||||
int i = read(fd, sp = b.s, sizeof(b.s));
|
||||
if(i < 0)
|
||||
caml_failwith("Hdlc.get_data: read failed");
|
||||
|
||||
CAMLparam0();
|
||||
CAMLlocal1 (result);
|
||||
|
||||
hdlc_data_received_idx = 0;
|
||||
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) {
|
||||
demod_afsk1200.demod(&dem_st, fbuf, fbuf_cnt-overlap);
|
||||
|
||||
memmove(fbuf, fbuf+fbuf_cnt-overlap, overlap*sizeof(fbuf[0]));
|
||||
fbuf_cnt = overlap;
|
||||
}
|
||||
}
|
||||
|
||||
/* Alloc the caml string and fill it */
|
||||
result = alloc_string(hdlc_data_received_idx);
|
||||
for(i = 0; i < hdlc_data_received_idx; i++)
|
||||
Byte(result, i) = hdlc_data_received[i];
|
||||
CAMLreturn(result);
|
||||
#else
|
||||
failwith("Not supported under OSX");
|
||||
#endif
|
||||
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
/*
|
||||
* 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_pprz {
|
||||
unsigned char rxbuf[512];
|
||||
unsigned char *rxptr;
|
||||
unsigned int rxstate;
|
||||
unsigned int rxbitstream;
|
||||
unsigned int rxbitbuf;
|
||||
char* pipe_path;
|
||||
int pipe_fd;
|
||||
} pprz;
|
||||
} l2;
|
||||
union {
|
||||
struct l1_state_afsk48p {
|
||||
unsigned int dcd_shreg;
|
||||
unsigned int sphase;
|
||||
unsigned int lasts;
|
||||
unsigned int dcd_count;
|
||||
unsigned int sample_count;
|
||||
} afsk48p;
|
||||
|
||||
struct l1_state_scope {
|
||||
int datalen;
|
||||
int dispnum;
|
||||
float data[512];
|
||||
} scope;
|
||||
|
||||
struct l1_state_afsk12 {
|
||||
unsigned int dcd_shreg;
|
||||
unsigned int sphase;
|
||||
unsigned int lasts;
|
||||
unsigned int subsamp;
|
||||
} afsk12;
|
||||
} 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);
|
||||
};
|
||||
|
||||
|
||||
#define HDLC_DATA_LEN 256
|
||||
extern char hdlc_data_received[HDLC_DATA_LEN];
|
||||
extern int hdlc_data_received_idx;
|
||||
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
extern const struct demod_param demod_afsk4800p;
|
||||
extern const struct demod_param demod_afsk1200;
|
||||
extern const struct demod_param demod_scope;
|
||||
|
||||
#define ALL_DEMOD &demod_afsk4800p,&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 afsk12_init(struct demod_state *s);
|
||||
|
||||
void pprz_init(struct demod_state *s);
|
||||
void pprz_rxbit(struct demod_state *s, int bit);
|
||||
void pprz_status(struct demod_state *s);
|
||||
|
||||
void xdisp_terminate(int cnum);
|
||||
int xdisp_start(void);
|
||||
int xdisp_update(int cnum, float *f);
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
#endif /* _MULTIMON_H */
|
||||
@@ -1,193 +0,0 @@
|
||||
/*
|
||||
* pprz.c -- paparazzi decoder
|
||||
*
|
||||
* Copyright (C) 1996
|
||||
* Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu)
|
||||
* Copyright (C) 2005
|
||||
* Martin Mueller (ma.mueller@tu-bs.de)
|
||||
*
|
||||
* 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>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define STX 0x02
|
||||
#define ETX 0x03
|
||||
|
||||
#define MSG_DATA 0
|
||||
#define MSG_ERROR 1
|
||||
#define MSG_CD 2
|
||||
#define MSG_DEBUG 3
|
||||
#define MSG_VALIM 4
|
||||
|
||||
#define INPUT_BUF_LEN 10
|
||||
|
||||
#define MULTIMON_PIPE_NAME "/tmp/multimon"
|
||||
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
static void pprz_tmtc_send(struct demod_state *s, unsigned char *data, unsigned int len, unsigned char type)
|
||||
{
|
||||
unsigned char msg[INPUT_BUF_LEN+6];
|
||||
unsigned int count = 0;
|
||||
int ret;
|
||||
|
||||
unsigned char checksum = 0;
|
||||
const unsigned char real_len = len + 2;
|
||||
unsigned char i;
|
||||
|
||||
msg[count++] = STX;
|
||||
msg[count++] = real_len;
|
||||
checksum ^= real_len;
|
||||
msg[count++] = type;
|
||||
checksum ^= type;
|
||||
for (i=0; i < len; i++) {
|
||||
msg[count++] = data[i];
|
||||
checksum ^= data[i];
|
||||
}
|
||||
msg[count++] = checksum;
|
||||
msg[count++] = ETX;
|
||||
|
||||
ret = write(s->l2.pprz.pipe_fd, msg, count);
|
||||
|
||||
if (count != ret)
|
||||
perror("write pipe");
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
char multimon_pipe_name[1024] = MULTIMON_PIPE_NAME;
|
||||
|
||||
void pprz_init(struct demod_state *s)
|
||||
{
|
||||
memset(&s->l2.hdlc, 0, sizeof(s->l2.hdlc));
|
||||
|
||||
/* open named pipe */
|
||||
struct stat st;
|
||||
if (stat(multimon_pipe_name, &st)) {
|
||||
if (mkfifo(multimon_pipe_name, 0644) == -1) {
|
||||
perror("make pipe");
|
||||
exit (10);
|
||||
}
|
||||
}
|
||||
if ((s->l2.pprz.pipe_fd = open(multimon_pipe_name, O_WRONLY /*| O_NONBLOCK*/)) < 0) {
|
||||
perror("open pipe");
|
||||
exit (10);
|
||||
}
|
||||
|
||||
/* reset buffer pointer */
|
||||
s->l2.pprz.rxptr = s->l2.hdlc.rxbuf;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void pprz_baudot_rxbit(struct demod_state *s, int bit)
|
||||
{
|
||||
/* (stop)bit found? */
|
||||
if (bit & 1) {
|
||||
/* check for sync and start bit */
|
||||
if ((s->l2.hdlc.rxbitbuf & 1) &&
|
||||
!(s->l2.hdlc.rxbitbuf & 2)) {
|
||||
/* found new byte */
|
||||
*s->l2.hdlc.rxptr++ = (s->l2.hdlc.rxbitbuf >> 2) & 0xFF;
|
||||
verbprintf(8, "0x%02X ", (s->l2.hdlc.rxbitbuf >> 2) & 0xFF);
|
||||
/* reset bit buffer */
|
||||
s->l2.hdlc.rxbitbuf = 0x400;
|
||||
} else {
|
||||
/* add data bit */
|
||||
s->l2.hdlc.rxbitbuf |= 0x400;
|
||||
}
|
||||
}
|
||||
|
||||
if ((s->l2.hdlc.rxptr - s->l2.hdlc.rxbuf) >= INPUT_BUF_LEN) {
|
||||
pprz_tmtc_send(s, s->l2.hdlc.rxbuf, s->l2.hdlc.rxptr - s->l2.hdlc.rxbuf, MSG_DATA);
|
||||
/* reset data buffer */
|
||||
s->l2.hdlc.rxptr = s->l2.hdlc.rxbuf;
|
||||
}
|
||||
|
||||
/* frame end / out of sync */
|
||||
if (s->l2.hdlc.rxbitbuf & 1)
|
||||
s->l2.hdlc.rxbitbuf |= 2;
|
||||
|
||||
/* shift in new data */
|
||||
s->l2.hdlc.rxbitbuf >>= 1;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void pprz_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)
|
||||
pprz_tmtc_send(s, s->l2.hdlc.rxbuf, s->l2.hdlc.rxptr - s->l2.hdlc.rxbuf, MSG_DATA);
|
||||
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;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void pprz_status(struct demod_state *s)
|
||||
{
|
||||
unsigned char data[2];
|
||||
|
||||
/* TODO find carrier */
|
||||
data[0] = 0x01; pprz_tmtc_send(s, data, 1, MSG_CD);
|
||||
/* just write some useful value (get it from acpi?) */
|
||||
data[0] = 0x00; data[1] = 0x04; pprz_tmtc_send(s, data, 2, MSG_VALIM);
|
||||
/* no debug value */
|
||||
data[0] = 0x00; pprz_tmtc_send(s, data, 1, MSG_DEBUG);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@@ -1,12 +0,0 @@
|
||||
#ifndef PPRZ_H
|
||||
#define PPRZ_H
|
||||
|
||||
extern char multimon_pipe_name[];
|
||||
|
||||
|
||||
void pprz_init(struct demod_state *s);
|
||||
void pprz_baudot_rxbit(struct demod_state *s, int bit);
|
||||
void pprz_hdlc_rxbit(struct demod_state *s, int bit);
|
||||
void pprz_status(struct demod_state *s);
|
||||
|
||||
#endif /* PPRZ_H */
|
||||
@@ -1,345 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 1996
|
||||
* Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu)
|
||||
* Copyright (C) 2005 Pascal Brisset, Antoine Drouin
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/soundcard.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
|
||||
#include "multimon.h"
|
||||
#include "filter.h"
|
||||
#include "pprz.h"
|
||||
#include "pprzlib.h"
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#define LEFT 0
|
||||
#define RIGHT 1
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* 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];
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
#define TEMP_BUF_LEN 10
|
||||
#define OUTPUT_BUF_LEN 512
|
||||
|
||||
|
||||
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 int glob_data_received_len = 0; /** Easier with a global var */
|
||||
static void
|
||||
pprz_tmtc_send(unsigned char *data, unsigned int len, char* data_received)
|
||||
{
|
||||
unsigned char i;
|
||||
for (i=0; i < len && glob_data_received_len < OUTPUT_BUF_LEN; i++) {
|
||||
data_received[glob_data_received_len++] = data[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
my_pprz_baudot_rxbit(struct demod_state *s, int bit, char* data)
|
||||
{
|
||||
/* (stop)bit found? */
|
||||
if (bit & 1) {
|
||||
/* check for sync and start bit */
|
||||
if ((s->l2.hdlc.rxbitbuf & 1) &&
|
||||
!(s->l2.hdlc.rxbitbuf & 2)) {
|
||||
/* found new byte */
|
||||
*s->l2.hdlc.rxptr++ = (s->l2.hdlc.rxbitbuf >> 2) & 0xFF;
|
||||
verbprintf(8, "0x%02X ", (s->l2.hdlc.rxbitbuf >> 2) & 0xFF);
|
||||
/* reset bit buffer */
|
||||
s->l2.hdlc.rxbitbuf = 0x400;
|
||||
} else {
|
||||
/* add data bit */
|
||||
s->l2.hdlc.rxbitbuf |= 0x400;
|
||||
}
|
||||
}
|
||||
|
||||
if ((s->l2.hdlc.rxptr - s->l2.hdlc.rxbuf) >= TEMP_BUF_LEN) {
|
||||
pprz_tmtc_send(s->l2.hdlc.rxbuf, s->l2.hdlc.rxptr - s->l2.hdlc.rxbuf, data);
|
||||
/* reset data buffer */
|
||||
s->l2.hdlc.rxptr = s->l2.hdlc.rxbuf;
|
||||
}
|
||||
|
||||
/* frame end / out of sync */
|
||||
if (s->l2.hdlc.rxbitbuf & 1)
|
||||
s->l2.hdlc.rxbitbuf |= 2;
|
||||
|
||||
/* shift in new data */
|
||||
s->l2.hdlc.rxbitbuf >>= 1;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
pprz_init(struct demod_state *s)
|
||||
{
|
||||
memset(&s->l2.hdlc, 0, sizeof(s->l2.hdlc));
|
||||
|
||||
/* reset buffer pointer */
|
||||
s->l2.pprz.rxptr = s->l2.hdlc.rxbuf;
|
||||
}
|
||||
|
||||
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, char* data)
|
||||
{
|
||||
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);
|
||||
my_pprz_baudot_rxbit(s, curbit, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int fd;
|
||||
union {
|
||||
short s[8192];
|
||||
unsigned char b[8192];
|
||||
} b;
|
||||
int stereo = 1;
|
||||
unsigned int sample_rate = FREQ_SAMP;
|
||||
|
||||
static int
|
||||
input_init(const char *ifname) {
|
||||
int sndparam;
|
||||
|
||||
if ((fd = open(ifname, O_RDONLY)) < 0) {
|
||||
perror("open");
|
||||
exit (10);
|
||||
}
|
||||
if (!strncmp("/dev", ifname, 4)) {
|
||||
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) {
|
||||
perror("ioctl: AFMT_S16_LE");
|
||||
exit (10);
|
||||
}
|
||||
stereo = TRUE;
|
||||
sndparam = 1; /* we want 2 channels */
|
||||
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 2: using mono\n");
|
||||
stereo=FALSE;
|
||||
} else if (sndparam != 1) {
|
||||
fprintf(stderr, "soundif: Error, cannot set the channel "
|
||||
"number to 2\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);
|
||||
}
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
||||
static struct demod_state dem_st[2];
|
||||
|
||||
char data_left[OUTPUT_BUF_LEN+1];
|
||||
char data_right[OUTPUT_BUF_LEN+1];
|
||||
struct data data_received = {data_left, 0, data_right, 0};
|
||||
unsigned int fbuf_cnt = 0;
|
||||
float fbuf[2][16384];
|
||||
|
||||
struct data*
|
||||
pprz_demod_read_data(void) {
|
||||
unsigned int overlap = CORRLEN;
|
||||
int i;
|
||||
short *sp;
|
||||
|
||||
i = read(fd, sp = b.s, sizeof(b.s));
|
||||
if (i < 0 && errno != EAGAIN) {
|
||||
perror("read");
|
||||
exit(4);
|
||||
}
|
||||
if (i > 0) {
|
||||
data_received.len_left = 0;
|
||||
data_received.len_right = 0;
|
||||
if (stereo) {
|
||||
for (; i >= sizeof(b.s[0]); i -= (sizeof(b.s[0])*2), sp+=2) {
|
||||
fbuf[LEFT][fbuf_cnt] = (*sp) * (1.0/32768.0);
|
||||
fbuf[RIGHT][fbuf_cnt++] = (*(sp+1)) * (1.0/32768.0);
|
||||
}
|
||||
} else {
|
||||
for (; i >= sizeof(b.s[0]); i -= sizeof(b.s[0]), sp++)
|
||||
fbuf[LEFT][fbuf_cnt++] = (*sp) * (1.0/32768.0);
|
||||
}
|
||||
if (i)
|
||||
fprintf(stderr, "warning: noninteger number of samples read\n");
|
||||
if (fbuf_cnt > overlap) {
|
||||
|
||||
glob_data_received_len = 0;
|
||||
afsk48p_demod(&dem_st[LEFT], fbuf[LEFT], fbuf_cnt-overlap, data_received.data_left);
|
||||
|
||||
data_received.len_left = glob_data_received_len;
|
||||
memmove(fbuf[LEFT], fbuf[LEFT]+fbuf_cnt-overlap, overlap*sizeof(fbuf[LEFT][0]));
|
||||
if (stereo) {
|
||||
glob_data_received_len = 0;
|
||||
afsk48p_demod(&dem_st[RIGHT], fbuf[RIGHT], fbuf_cnt-overlap, data_received.data_right);
|
||||
data_received.len_right = glob_data_received_len;
|
||||
memmove(fbuf[RIGHT], fbuf[RIGHT]+fbuf_cnt-overlap, overlap*sizeof(fbuf[RIGHT][0]));
|
||||
}
|
||||
fbuf_cnt = overlap;
|
||||
}
|
||||
return &data_received;
|
||||
} else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int pprz_demod_init(char *dev) {
|
||||
memset(dem_st, 0, 2*sizeof(struct demod_state));
|
||||
afsk48p_init(&dem_st[LEFT]);
|
||||
afsk48p_init(&dem_st[RIGHT]);
|
||||
return input_init(dev);
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
int pprz_demod_init(char *dev);
|
||||
|
||||
struct data { char* data_left; int len_left; char* data_right; int len_right;};
|
||||
struct data* pprz_demod_read_data(void);
|
||||
/** Returns NULL if no characters are available on the device */
|
||||
@@ -1,18 +0,0 @@
|
||||
let print_hex = fun s ->
|
||||
for i = 0 to String.length s - 1 do
|
||||
Printf.printf "%02x" (Char.code s.[i])
|
||||
done;
|
||||
print_newline ()
|
||||
|
||||
|
||||
let _ =
|
||||
let dsp = Demod.init "/dev/dsp" in
|
||||
|
||||
let cb = fun _ ->
|
||||
let l, r = Demod.get_data () in
|
||||
print_hex l; print_hex r; true in
|
||||
|
||||
ignore (Glib.Io.add_watch [`IN] cb (Glib.Io.channel_of_descr dsp));
|
||||
|
||||
let loop = Glib.Main.create true in
|
||||
while Glib.Main.is_running loop do ignore (Glib.Main.iteration true) done
|
||||
@@ -1,27 +0,0 @@
|
||||
let my_write = fun fd buf ->
|
||||
let rec loop = fun i ->
|
||||
Printf.printf "i=%d\n%!" i;
|
||||
let r = String.length buf - i in
|
||||
if r > 0 then
|
||||
loop (i + Unix.write fd buf i (min 8192 r)) in
|
||||
loop 0
|
||||
|
||||
|
||||
let _ =
|
||||
let _fd = Hdlc.init_gen "/dev/dsp" in
|
||||
|
||||
let i = ref 0 in
|
||||
let cb = fun _ ->
|
||||
incr i;
|
||||
(***)
|
||||
Hdlc.write_data
|
||||
(let s = Printf.sprintf "coucou [%d]" !i in prerr_endline s; s);
|
||||
true in
|
||||
|
||||
(***) ignore (Glib.Timeout.add 1000 cb); (***)
|
||||
ignore (Glib.Timeout.add 90 (fun _ -> Hdlc.write_to_dsp (); true));
|
||||
(** ignore (Glib.Timeout.add 100 (fun _ -> prerr_endline "x"; true)); **)
|
||||
|
||||
(** Threaded main loop (blocking write) *)
|
||||
GtkThread.main ()
|
||||
|
||||
@@ -1,433 +0,0 @@
|
||||
/*
|
||||
* 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 "pprz.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>
|
||||
|
||||
#include <sys/soundcard.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
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;
|
||||
int stereo = 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 == 1) {
|
||||
fprintf(stderr, "soundif: Warning, cannot set the channel "
|
||||
"number to 1, will use stereo\n");
|
||||
stereo=1;
|
||||
} else
|
||||
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) {
|
||||
if (stereo) {
|
||||
for (; i >= sizeof(b.s[0]); i -= (sizeof(b.s[0])*2), sp+=2)
|
||||
fbuf[fbuf_cnt++] = (*sp) * (1.0/32768.0);
|
||||
} else {
|
||||
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);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
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"
|
||||
" -p <fifo> : output\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:p: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 'p':
|
||||
printf("pipe=%s\n", optarg);
|
||||
strcpy(multimon_pipe_name, optarg);
|
||||
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);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@@ -1,441 +0,0 @@
|
||||
/*
|
||||
* 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 <stdlib.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;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@@ -28,25 +28,22 @@ include ../../Makefile.ocaml
|
||||
CONF = ../../../conf
|
||||
VAR = ../../../var
|
||||
|
||||
INCLUDES= -I ../multimon
|
||||
INCLUDES=
|
||||
PKG = -package glibivy,pprz
|
||||
LINKPKG = $(PKG) -linkpkg -dllpath-pkg pprz,pprzlink
|
||||
XPKG = -package pprz.xlib
|
||||
XLINKPKG = $(XPKG) -linkpkg -dllpath-pkg pprz.xlib,pprzlink
|
||||
|
||||
LIBMULTIMONCMA=../multimon/multimon.cma
|
||||
LIBMULTIMONDLL= multimon.cma -dllpath $(PAPARAZZI_SRC)/sw/ground_segment/multimon
|
||||
|
||||
SERVERCMO = server_globals.cmo aircraft.cmo wind.cmo airprox.cmo kml.cmo fw_server.ml rotorcraft_server.ml intruder.cmo server.cmo
|
||||
SERVERCMX = $(SERVERCMO:.cmo=.cmx)
|
||||
|
||||
|
||||
all: link server messages settings dia diadec ivy_tcp_aircraft ivy_tcp_controller broadcaster ivy2udp ivy_serial_bridge app_server ivy2nmea
|
||||
all: link server messages settings ivy_tcp_aircraft ivy_tcp_controller broadcaster ivy2udp ivy_serial_bridge app_server ivy2nmea
|
||||
|
||||
opt: server.opt
|
||||
|
||||
clean:
|
||||
$(Q)rm -f link server messages settings dia diadec *.bak *~ core *.o .depend *.opt *.out *.cm* ivy_tcp_aircraft ivy_tcp_controller broadcaster ivy2udp ivy_serial_bridge app_server gpsd2ivy c_ivy_client_example_1 c_ivy_client_example_2 c_ivy_client_example_3 ivy2nmea
|
||||
$(Q)rm -f link server messages settings *.bak *~ core *.o .depend *.opt *.out *.cm* ivy_tcp_aircraft ivy_tcp_controller broadcaster ivy2udp ivy_serial_bridge app_server gpsd2ivy c_ivy_client_example_1 c_ivy_client_example_2 c_ivy_client_example_3 ivy2nmea
|
||||
|
||||
messages : messages.cmo $(LIBPPRZCMA)
|
||||
@echo OL $@
|
||||
@@ -64,9 +61,9 @@ server.opt : $(SERVERCMX) $(LIBPPRZCMXA)
|
||||
@echo OOL $@
|
||||
$(Q)$(OCAMLOPT) $(INCLUDES) -o $@ -package glibivy,pprz -linkpkg $(SERVERCMX)
|
||||
|
||||
link : link.cmo $(LIBMULTIMONCMA) $(LIBPPRZCMA)
|
||||
link : link.cmo $(LIBPPRZCMA)
|
||||
@echo OL $@
|
||||
$(Q)$(OCAMLC) $(INCLUDES) -o $@ $(LINKPKG) $(LIBMULTIMONDLL) $<
|
||||
$(Q)$(OCAMLC) $(INCLUDES) -o $@ $(LINKPKG) $<
|
||||
|
||||
|
||||
ivy_tcp_aircraft : ivy_tcp_aircraft.cmo $(LIBPPRZCMA)
|
||||
@@ -89,16 +86,6 @@ ivy2udp : ivy2udp.cmo $(LIBPPRZCMA)
|
||||
$(Q)$(OCAMLC) $(INCLUDES) -o $@ $(LINKPKG) $<
|
||||
|
||||
|
||||
dia : dia.cmo $(LIBMULTIMONCMA) $(LIBPPRZCMA)
|
||||
@echo OL $@
|
||||
$(Q)$(OCAMLC) $(INCLUDES) -o $@ $(LINKPKG) $(LIBMULTIMONDLL) $<
|
||||
|
||||
|
||||
diadec : diadec.cmo $(LIBMULTIMONCMA) $(LIBPPRZCMA)
|
||||
@echo OL $@
|
||||
$(Q)$(OCAMLC) $(INCLUDES) -o $@ $(LINKPKG) $(LIBMULTIMONDLL) $<
|
||||
|
||||
|
||||
150m : 150m.cmo $(LIBPPRZCMA)
|
||||
@echo OL $@
|
||||
$(Q)$(OCAMLC) $(INCLUDES) -o $@ $(LINKPKG) gtkInit.cmo $<
|
||||
@@ -171,7 +158,7 @@ ivy_serial_bridge: ivy_serial_bridge.c
|
||||
|
||||
.depend: Makefile
|
||||
@echo DEPEND $@
|
||||
$(Q)$(OCAMLDEP) -I $(LIBPPRZDIR) -I ../multimon *.ml* > .depend
|
||||
$(Q)$(OCAMLDEP) -I $(LIBPPRZDIR) *.ml* > .depend
|
||||
|
||||
ifneq ($(MAKECMDGOALS),clean)
|
||||
-include .depend
|
||||
|
||||
@@ -1,122 +0,0 @@
|
||||
(*
|
||||
* Copyright (C) 2007- ENAC, Pascal Brisset, Antoine Drouin
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi 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, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*)
|
||||
|
||||
(** Encode telemetry messages in an audio stream (to be mixed with a
|
||||
video stream). Listen messages from the "ground" class (a server
|
||||
must be running) and write message(s) of the "DIA" class.
|
||||
*)
|
||||
|
||||
open Printf
|
||||
|
||||
let msg_period = 500 (* ms *)
|
||||
let ac_id = ref 1
|
||||
|
||||
module Ground_Pprz = PprzLink.Messages(struct let name = "ground" end)
|
||||
module Sub_Pprz = PprzLink.Messages(struct let name = "DIA" end)
|
||||
|
||||
type state = {
|
||||
mutable lat : float;
|
||||
mutable long : float;
|
||||
mutable alt : int;
|
||||
|
||||
mutable course : int;
|
||||
mutable speed : int;
|
||||
|
||||
mutable cam_roll : int;
|
||||
mutable cam_pitch : int;
|
||||
}
|
||||
|
||||
let state = {
|
||||
lat = 0.; long = 0.; alt = 0;
|
||||
course = 0; speed = 0;
|
||||
cam_roll = 0; cam_pitch = 0;
|
||||
}
|
||||
|
||||
let msg_id, _ = Sub_Pprz.message_of_name "NAV_INFO"
|
||||
let send_msg = fun () ->
|
||||
let t = (Unix.gettimeofday ()) -. 1e9 in
|
||||
let vs = [
|
||||
"unix_time", PprzLink.Float t;
|
||||
|
||||
"lat", PprzLink.Float state.lat;
|
||||
"long", PprzLink.Float state.long;
|
||||
"alt", PprzLink.Int state.alt;
|
||||
|
||||
"course", PprzLink.Int state.course;
|
||||
"speed", PprzLink.Int state.speed;
|
||||
|
||||
"cam_roll", PprzLink.Int state.cam_roll;
|
||||
"cam_pitch", PprzLink.Int state.cam_pitch
|
||||
] in
|
||||
let s = Sub_Pprz.payload_of_values msg_id !ac_id vs in
|
||||
Debug.call 'l' (fun f -> fprintf f "sending: %s\n" (Debug.xprint (Protocol.string_of_payload s)));
|
||||
Hdlc.write_data (Protocol.string_of_payload s)
|
||||
|
||||
let fp_msg = fun _sender vs ->
|
||||
if int_of_string (PprzLink.string_assoc "ac_id" vs) = !ac_id then begin
|
||||
state.lat <- PprzLink.float_assoc "lat" vs;
|
||||
state.long <- PprzLink.float_assoc "long" vs;
|
||||
state.alt <- truncate (PprzLink.float_assoc "alt" vs);
|
||||
state.course <- truncate (PprzLink.float_assoc "course" vs);
|
||||
state.speed <- truncate (PprzLink.float_assoc "speed" vs *. 100.);
|
||||
state.cam_roll <- truncate (PprzLink.float_assoc "roll" vs); (* FIXME *)
|
||||
state.cam_pitch <- truncate (PprzLink.float_assoc "pitch" vs); (* FIXME *)
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
let _ =
|
||||
let ivy_bus = ref Defivybus.default_ivy_bus
|
||||
and port = ref "/dev/dsp" in
|
||||
let options = [
|
||||
"-b", Arg.Set_string ivy_bus, (sprintf "<ivy bus> Default is %s" !ivy_bus);
|
||||
"-d", Arg.Set_string port, (sprintf "<port> Default is %s" !port);
|
||||
"-ac", Arg.Set_int ac_id, (sprintf "<A/C id> Default is %d" !ac_id);
|
||||
] in
|
||||
|
||||
Arg.parse
|
||||
options
|
||||
(fun _x -> ())
|
||||
"Usage: ";
|
||||
|
||||
(* Connect to Ivy bus *)
|
||||
Ivy.init "Link" "READY" (fun _ _ -> ());
|
||||
Ivy.start !ivy_bus;
|
||||
|
||||
(* Listen for telemetry messages *)
|
||||
ignore (Ground_Pprz.message_bind "FLIGHT_PARAM" fp_msg);
|
||||
|
||||
(* Open the audio output and launch the periodic writings *)
|
||||
let _fd = Hdlc.init_gen "/dev/dsp" in
|
||||
ignore (Glib.Timeout.add Hdlc.write_period (fun _ -> Hdlc.write_to_dsp (); true));
|
||||
|
||||
(* Periodically send messages *)
|
||||
ignore (Glib.Timeout.add msg_period (fun () -> send_msg (); true));
|
||||
|
||||
|
||||
(* Main Loop *)
|
||||
let loop = Glib.Main.create true in
|
||||
while Glib.Main.is_running loop do
|
||||
ignore (Glib.Main.iteration true)
|
||||
done
|
||||
@@ -1,63 +0,0 @@
|
||||
(*
|
||||
* Copyright (C) 2007- ENAC, Pascal Brisset, Antoine Drouin
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi 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, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*)
|
||||
|
||||
(** Decode Data In Audio stream and print the messages on stdout *)
|
||||
|
||||
open Printf
|
||||
|
||||
module Sub_Pprz = PprzLink.Messages(struct let name = "DIA" end)
|
||||
module PprzTransport = Protocol.Transport(Pprz_transport.Transport)
|
||||
|
||||
|
||||
let use_tele_message = fun buf ->
|
||||
let payload = Protocol.payload_of_string buf in
|
||||
Debug.call 'l' (fun f -> fprintf f "pprz receiving: %s\n" (Debug.xprint buf));
|
||||
try
|
||||
let (msg_id, ac_id, values) = Sub_Pprz.values_of_payload payload in
|
||||
let msg = Sub_Pprz.message_of_id msg_id in
|
||||
printf "%d %s\n%!" ac_id (Sub_Pprz.string_of_message msg values)
|
||||
with
|
||||
_ ->
|
||||
Debug.call 'W' (fun f -> fprintf f "Warning, cannot use: %s\n" (Debug.xprint buf))
|
||||
|
||||
|
||||
let _ =
|
||||
let port = ref "/dev/dsp" in
|
||||
let options = [
|
||||
"-d", Arg.Set_string port, (sprintf "<port> Default is %s" !port);
|
||||
] in
|
||||
|
||||
Arg.parse
|
||||
options
|
||||
(fun _x -> ())
|
||||
"Usage: ";
|
||||
|
||||
(* Open the audio output and launch the periodic writings *)
|
||||
let fd = Hdlc.init_dec "/dev/dsp" in
|
||||
|
||||
ignore (Glib.Io.add_watch [`IN] (fun _ -> use_tele_message (Hdlc.get_data ()); true) (GMain.Io.channel_of_descr fd));
|
||||
|
||||
(* Main Loop *)
|
||||
let loop = Glib.Main.create true in
|
||||
while Glib.Main.is_running loop do
|
||||
ignore (Glib.Main.iteration true)
|
||||
done
|
||||
@@ -1,137 +0,0 @@
|
||||
(*
|
||||
* Hardware modem receiver
|
||||
*
|
||||
* Copyright (C) 2004 CENA/ENAC, Pascal Brisset, Antoine Drouin
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi 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, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*)
|
||||
|
||||
open Printf
|
||||
|
||||
|
||||
let modem_msg_period = 1000 (** ms *)
|
||||
|
||||
module Tele_Class = struct let name = "telemetry_ap" end
|
||||
module Tele_Pprz = PprzLink.Protocol(Tele_Class)
|
||||
module PprzTransport = Protocol.Transport(Tele_Pprz)
|
||||
|
||||
(** Monitoring of the message reception *)
|
||||
type status = {
|
||||
mutable ac_id : string;
|
||||
mutable rx_byte : int;
|
||||
mutable rx_msg : int;
|
||||
mutable rx_err : int
|
||||
}
|
||||
(** Ivy messages are initially tagged "modem" and with the A/C
|
||||
id as soon as it is identified (IDENT message) *)
|
||||
let make_status = fun id ->
|
||||
{ ac_id = id; rx_byte = 0; rx_msg = 0; rx_err = 0 }
|
||||
|
||||
let status_left = make_status "modem_left"
|
||||
let status_right = make_status "modem_right"
|
||||
|
||||
|
||||
(** Callback for each decoded message *)
|
||||
let use_pprz_message = fun status (msg_id, values) ->
|
||||
status.rx_msg <- status.rx_msg + 1; (** Monitoring update *)
|
||||
let msg = Tele_Pprz.message_of_id msg_id in
|
||||
if msg.PprzLink.name = "IDENT" then
|
||||
status.ac_id <- PprzLink.string_assoc "id" values;
|
||||
prerr_endline (status.ac_id^":"^msg.PprzLink.name);
|
||||
Tele_Pprz.message_send status.ac_id msg.PprzLink.name values
|
||||
|
||||
(** Listen on a dsp device *)
|
||||
let listen_pprz_modem = fun pprz_message_cb devdsp ->
|
||||
let fd = Demod.init devdsp in
|
||||
|
||||
(** Callback for a checksumed pprz message *)
|
||||
let use_pprz_buf = fun status buf ->
|
||||
status.rx_byte <- status.rx_byte + String.length buf;
|
||||
Debug.call 'P' (fun f -> fprintf f "use_pprz: %s\n" (Debug.xprint buf));
|
||||
pprz_message_cb status (Tele_PprzLink.values_of_bin buf) in
|
||||
|
||||
(** Callback for available chars *)
|
||||
let cb = fun status buffer data ->
|
||||
(** Accumulate in a buffer *)
|
||||
let b = !buffer ^ data in
|
||||
Debug.call 'M' (fun f -> fprintf f "Pprz buffer: %s\n" (Debug.xprint b));
|
||||
(** Parse as pprz message and ... *)
|
||||
let x = PprzTransport.parse (use_pprz_buf status) b in
|
||||
status.rx_err <- !PprzTransport.nb_err;
|
||||
(** ... remove from the buffer the chars which have been used *)
|
||||
buffer := String.sub b x (String.length b - x)
|
||||
in
|
||||
let buffer_left = ref "" and buffer_right = ref "" in
|
||||
let cb_stereo = fun _ ->
|
||||
let (data_left, data_right) = Demod.get_data () in
|
||||
cb status_left buffer_left data_left;
|
||||
cb status_right buffer_right data_right;
|
||||
true in
|
||||
|
||||
(** Attach the callback to the channel *)
|
||||
ignore (Glib.Io.add_watch [`IN] cb_stereo (Glib.Io.channel_of_descr fd))
|
||||
|
||||
(** Modem monitoring messages *)
|
||||
let send_modem_msg = fun status ->
|
||||
let rx_msg = ref 0
|
||||
and rx_byte = ref 0
|
||||
and start = Unix.gettimeofday () in
|
||||
fun () ->
|
||||
let dt = float modem_msg_period /. 1000. in
|
||||
let t = int_of_float (Unix.gettimeofday () -. start) in
|
||||
let byte_rate = float (status.rx_byte - !rx_byte) /. dt
|
||||
and msg_rate = float (status.rx_msg - !rx_msg) /. dt in
|
||||
rx_msg := status.rx_msg;
|
||||
rx_byte := status.rx_byte;
|
||||
let vs = ["run_time", PprzLink.Int t;
|
||||
"rx_bytes_rate", PprzLink.Float byte_rate;
|
||||
"rx_msgs_rate", PprzLink.Float msg_rate;
|
||||
"rx_err", PprzLink.Int status.rx_err;
|
||||
"rx_bytes", PprzLink.Int status.rx_byte;
|
||||
"rx_msgs", PprzLink.Int status.rx_msg
|
||||
] in
|
||||
Tele_Pprz.message_send status.ac_id "DOWNLINK_STATUS" vs
|
||||
|
||||
(* main loop *)
|
||||
let _ =
|
||||
let ivy_bus = Defivybus.default_ivy_bus in
|
||||
let port = ref "/dev/dsp" in
|
||||
let options =
|
||||
[ "-b", Arg.Set_string ivy_bus, (sprintf "Ivy bus (%s)" !ivy_bus);
|
||||
"-d", Arg.Set_string port, (sprintf "Port (%s)" !port)] in
|
||||
Arg.parse
|
||||
options
|
||||
(fun x -> fprintf stderr "Warning:ignoring %s\n" x)
|
||||
"Usage: ";
|
||||
|
||||
Ivy.init "Paparazzi stereo demod" "READY" (fun _ _ -> ());
|
||||
Ivy.start !ivy_bus;
|
||||
|
||||
(** Listening on the given port (serial device or multimon fifo)*)
|
||||
listen_pprz_modem use_pprz_message !port;
|
||||
|
||||
(** Sending periodically modem and downlink status messages *)
|
||||
let send_left = send_modem_msg status_left
|
||||
and send_right = send_modem_msg status_right in
|
||||
ignore (Glib.Timeout.add modem_msg_period (fun () -> send_left (); send_right (); true));
|
||||
|
||||
let loop = Glib.Main.create true in
|
||||
while Glib.Main.is_running loop do
|
||||
ignore (Glib.Main.iteration true)
|
||||
done
|
||||
Reference in New Issue
Block a user