Prepare for NMT: Fixes and improvements at common code

This commit is contained in:
Andreas Eversberg 2016-03-11 06:59:05 +01:00
parent 287b914b56
commit 0dc81fe210
16 changed files with 137 additions and 105 deletions

View File

@ -26,6 +26,8 @@
#include "../common/timer.h" #include "../common/timer.h"
#include "../common/call.h" #include "../common/call.h"
#include "../common/cause.h" #include "../common/cause.h"
#include "../common/freiton.h"
#include "../common/besetztton.h"
#include "anetz.h" #include "anetz.h"
#include "dsp.h" #include "dsp.h"

View File

@ -29,6 +29,8 @@
#include "../common/timer.h" #include "../common/timer.h"
#include "../common/call.h" #include "../common/call.h"
#include "../common/mncc_sock.h" #include "../common/mncc_sock.h"
#include "../common/freiton.h"
#include "../common/besetztton.h"
#include "anetz.h" #include "anetz.h"
#include "dsp.h" #include "dsp.h"
#include "image.h" #include "image.h"
@ -39,7 +41,7 @@ double lossdetect = 0;
void print_help(const char *arg0) void print_help(const char *arg0)
{ {
print_help_common(arg0); print_help_common(arg0, "");
/* - - */ /* - - */
printf(" -P --page-sequence 0 | <ms>\n"); printf(" -P --page-sequence 0 | <ms>\n");
printf(" Cycle paging tones, rather than sending simultaniously.\n"); printf(" Cycle paging tones, rather than sending simultaniously.\n");
@ -96,6 +98,10 @@ int main(int argc, char *argv[])
int skip_args; int skip_args;
const char *station_id = ""; const char *station_id = "";
/* init common tones */
init_freiton();
init_besetzton();
skip_args = handle_options(argc, argv); skip_args = handle_options(argc, argv);
argc -= skip_args; argc -= skip_args;
argv += skip_args; argv += skip_args;
@ -129,7 +135,7 @@ int main(int argc, char *argv[])
} }
dsp_init(); dsp_init();
anetz_init(); anetz_init();
rc = call_init(station_id, call_sounddev, samplerate, latency, loopback); rc = call_init(station_id, call_sounddev, samplerate, latency, 5, loopback);
if (rc < 0) { if (rc < 0) {
fprintf(stderr, "Failed to create call control instance. Quitting!\n"); fprintf(stderr, "Failed to create call control instance. Quitting!\n");
goto fail; goto fail;

View File

@ -7,7 +7,7 @@ bnetz_SOURCES = \
bnetz.c \ bnetz.c \
dsp.c \ dsp.c \
image.c \ image.c \
ansage-27.c \ ansage.c \
main.c main.c
bnetz_LDADD = \ bnetz_LDADD = \
$(COMMON_LA) \ $(COMMON_LA) \

View File

@ -1,3 +0,0 @@
void init_ansage_27(void);

View File

@ -1,5 +1,5 @@
#include <stdint.h> #include <stdint.h>
#include "ansage-27.h" #include "ansage.h"
static int16_t pattern[] = { static int16_t pattern[] = {
0xffd1, 0x0011, 0x0031, 0x002d, 0x0016, 0x000d, 0x002f, 0xffea, 0xffd1, 0x0011, 0x0031, 0x002d, 0x0016, 0x000d, 0x002f, 0xffea,
@ -4991,13 +4991,15 @@ static int16_t pattern[] = {
0x0006, 0x000e, 0xfffd, 0x000b, 0xfffc, 0x000b, 0x000e, 0xfffb, 0x0006, 0x000e, 0xfffd, 0x000b, 0xfffc, 0x000b, 0x000e, 0xfffb,
}; };
extern int16_t *ansage_27_spl; extern int16_t *outoforder_spl;
extern int ansage_27_size; extern int outoforder_size;
extern int outoforder_max;
void init_ansage_27(void) void init_ansage(void)
{ {
ansage_27_spl = pattern; outoforder_spl = pattern;
ansage_27_size = sizeof(pattern) / sizeof(pattern[0]); outoforder_size = sizeof(pattern) / sizeof(pattern[0]);
outoforder_max = outoforder_size;
} }

3
src/bnetz/ansage.h Normal file
View File

@ -0,0 +1,3 @@
void init_ansage(void);

View File

@ -84,13 +84,13 @@ int dsp_init_sender(bnetz_t *bnetz)
PDEBUG(DFSK, DEBUG_DEBUG, "Using %d samples per bit duration.\n", bnetz->samples_per_bit); PDEBUG(DFSK, DEBUG_DEBUG, "Using %d samples per bit duration.\n", bnetz->samples_per_bit);
bnetz->fsk_filter_step = bnetz->sender.samplerate * FILTER_STEP; bnetz->fsk_filter_step = bnetz->sender.samplerate * FILTER_STEP;
PDEBUG(DFSK, DEBUG_DEBUG, "Using %d samples per filter step.\n", bnetz->fsk_filter_step); PDEBUG(DFSK, DEBUG_DEBUG, "Using %d samples per filter step.\n", bnetz->fsk_filter_step);
spl = calloc(16, bnetz->samples_per_bit << 1); spl = calloc(16, bnetz->samples_per_bit * sizeof(*spl));
if (!spl) { if (!spl) {
PDEBUG(DFSK, DEBUG_ERROR, "No memory!\n"); PDEBUG(DFSK, DEBUG_ERROR, "No memory!\n");
return -ENOMEM; return -ENOMEM;
} }
bnetz->telegramm_spl = spl; bnetz->telegramm_spl = spl;
spl = calloc(1, bnetz->samples_per_bit << 1); spl = calloc(1, bnetz->samples_per_bit * sizeof(*spl));
if (!spl) { if (!spl) {
PDEBUG(DFSK, DEBUG_ERROR, "No memory!\n"); PDEBUG(DFSK, DEBUG_ERROR, "No memory!\n");
return -ENOMEM; return -ENOMEM;
@ -204,7 +204,7 @@ char *show_level(int value)
/* Filter one chunk of audio an detect tone, quality and loss of signal. /* Filter one chunk of audio an detect tone, quality and loss of signal.
* The chunk is a window of 10ms. This window slides over audio stream * The chunk is a window of 10ms. This window slides over audio stream
* and is processed every 1ms. (one step) */ * and is processed every 1ms. (one step) */
void fsk_decode_step(bnetz_t *bnetz, int pos) static inline void fsk_decode_step(bnetz_t *bnetz, int pos)
{ {
double level, result[2], softbit, quality; double level, result[2], softbit, quality;
int max; int max;

View File

@ -29,10 +29,12 @@
#include "../common/call.h" #include "../common/call.h"
#include "../common/mncc_sock.h" #include "../common/mncc_sock.h"
#include "../common/main.h" #include "../common/main.h"
#include "../common/freiton.h"
#include "../common/besetztton.h"
#include "bnetz.h" #include "bnetz.h"
#include "dsp.h" #include "dsp.h"
#include "image.h" #include "image.h"
#include "ansage-27.h" #include "ansage.h"
int gfs = 2; int gfs = 2;
const char *pilot = "tone"; const char *pilot = "tone";
@ -40,7 +42,7 @@ double lossdetect = 0;
void print_help(const char *arg0) void print_help(const char *arg0)
{ {
print_help_common(arg0); print_help_common(arg0, "");
/* - - */ /* - - */
printf(" -g --gfs <gruppenfreisignal>\n"); printf(" -g --gfs <gruppenfreisignal>\n");
printf(" Gruppenfreisignal\" 1..9 | 19 | 10..18 (default = '%d')\n", gfs); printf(" Gruppenfreisignal\" 1..9 | 19 | 10..18 (default = '%d')\n", gfs);
@ -109,6 +111,11 @@ int main(int argc, char *argv[])
int skip_args; int skip_args;
const char *station_id = ""; const char *station_id = "";
/* init common tones */
init_freiton();
init_besetzton();
init_ansage();
skip_args = handle_options(argc, argv); skip_args = handle_options(argc, argv);
argc -= skip_args; argc -= skip_args;
argv += skip_args; argv += skip_args;
@ -138,10 +145,9 @@ int main(int argc, char *argv[])
return -1; return -1;
} }
} }
init_ansage_27();
dsp_init(); dsp_init();
bnetz_init(); bnetz_init();
rc = call_init(station_id, call_sounddev, samplerate, latency, loopback); rc = call_init(station_id, call_sounddev, samplerate, latency, 5, loopback);
if (rc < 0) { if (rc < 0) {
fprintf(stderr, "Failed to create call control instance. Quitting!\n"); fprintf(stderr, "Failed to create call control instance. Quitting!\n");
goto fail; goto fail;

View File

@ -173,13 +173,23 @@ static int16_t pattern[] = {
0x008f, 0x0099, 0x001c, 0xffa8, 0xff93, 0xff52, 0xff9a, 0x0060, 0x008f, 0x0099, 0x001c, 0xffa8, 0xff93, 0xff52, 0xff9a, 0x0060,
}; };
extern int16_t *besetztton_spl; extern int16_t *busy_spl;
extern int besetztton_size; extern int busy_size;
extern int busy_max;
extern int16_t *congestion_spl;
extern int congestion_size;
extern int congestion_max;
void init_besetzton(void) void init_besetzton(void)
{ {
besetztton_spl = pattern; busy_spl = pattern;
besetztton_size = sizeof(pattern) / sizeof(pattern[0]); busy_size = sizeof(pattern) / sizeof(pattern[0]);
busy_max = 8 * 750;
congestion_spl = pattern;
congestion_size = sizeof(pattern) / sizeof(pattern[0]);
congestion_max = 8 * 750;
} }

View File

@ -30,19 +30,23 @@
#include "cause.h" #include "cause.h"
#include "call.h" #include "call.h"
#include "mncc_sock.h" #include "mncc_sock.h"
#include "freiton.h"
#include "besetztton.h"
extern int use_mncc_sock; extern int use_mncc_sock;
extern int send_patterns; extern int send_patterns;
/* stream patterns/announcements */ /* stream patterns/announcements */
int16_t *ansage_27_spl = NULL; int16_t *outoforder_spl = NULL;
int16_t *freiton_spl = NULL; int16_t *ringback_spl = NULL;
int16_t *besetztton_spl = NULL; int16_t *busy_spl = NULL;
int ansage_27_size = 0; int16_t *congestion_spl = NULL;
int freiton_size = 0; int outoforder_size = 0;
int besetztton_size = 0; int ringback_size = 0;
int busy_size = 0;
int congestion_size = 0;
int outoforder_max = 0;
int ringback_max = 0;
int busy_max = 0;
int congestion_max = 0;
enum call_state { enum call_state {
CALL_IDLE = 0, CALL_IDLE = 0,
@ -57,24 +61,61 @@ enum audio_pattern {
PATTERN_NONE = 0, PATTERN_NONE = 0,
PATTERN_RINGBACK, PATTERN_RINGBACK,
PATTERN_BUSY, PATTERN_BUSY,
PATTERN_CONGESTION,
PATTERN_OUTOFORDER, PATTERN_OUTOFORDER,
}; };
void get_pattern(const int16_t **spl, int *size, int *max, enum audio_pattern pattern)
{
*spl = NULL;
*size = 0;
*max = 0;
switch (pattern) {
case PATTERN_RINGBACK:
*spl = ringback_spl;
*size = ringback_size;
*max = ringback_max;
break;
case PATTERN_BUSY:
*spl = busy_spl;
*size = busy_size;
*max = busy_max;
break;
case PATTERN_CONGESTION:
no_outoforder:
*spl = congestion_spl;
*size = congestion_size;
*max = congestion_max;
break;
case PATTERN_OUTOFORDER:
if (!outoforder_spl)
goto no_outoforder;
*spl = outoforder_spl;
*size = outoforder_size;
*max = outoforder_max;
break;
default:
;
}
}
static int new_callref = 0; /* toward mobile */ static int new_callref = 0; /* toward mobile */
/* built in call instance */ /* built in call instance */
typedef struct call { typedef struct call {
int callref; int callref;
enum call_state state; enum call_state state;
int disc_cause; /* cause that has been sent by transceiver instance for release */ int disc_cause; /* cause that has been sent by transceiver instance for release */
char station_id[6]; char station_id[16];
char dialing[16]; char dialing[16];
void *sound; /* headphone interface */ void *sound; /* headphone interface */
int latspl; /* sample latency at sound interface */ int latspl; /* sample latency at sound interface */
samplerate_t srstate; /* patterns/announcement upsampling */ samplerate_t srstate; /* patterns/announcement upsampling */
jitter_t audio; /* headphone audio dejittering */ jitter_t audio; /* headphone audio dejittering */
int audio_pos; /* position when playing patterns */ int audio_pos; /* position when playing patterns */
int loopback; /* loopback test for echo */ int dial_digits; /* number of digits to be dialed */
int loopback; /* loopback test for echo */
} call_t; } call_t;
static call_t call; static call_t call;
@ -87,31 +128,10 @@ static void call_new_state(enum call_state state)
static void get_call_patterns(int16_t *samples, int length, enum audio_pattern pattern) static void get_call_patterns(int16_t *samples, int length, enum audio_pattern pattern)
{ {
const int16_t *spl = NULL; const int16_t *spl;
int size = 0, max = 0, pos; int size, max, pos;
switch (pattern) { get_pattern(&spl, &size, &max, pattern);
case PATTERN_RINGBACK:
spl = freiton_spl;
size = freiton_size;
max = 8 * 5000;
break;
case PATTERN_BUSY:
busy:
spl = besetztton_spl;
size = besetztton_size;
max = 8 * 750;
break;
case PATTERN_OUTOFORDER:
spl = ansage_27_spl;
size = ansage_27_size;
if (!spl || !size)
goto busy;
max = size;
break;
default:
return;
}
/* stream sample */ /* stream sample */
pos = call.audio_pos; pos = call.audio_pos;
@ -131,11 +151,14 @@ static enum audio_pattern cause2pattern(int cause)
int pattern; int pattern;
switch (cause) { switch (cause) {
case CAUSE_BUSY:
pattern = PATTERN_BUSY;
break;
case CAUSE_OUTOFORDER: case CAUSE_OUTOFORDER:
pattern = PATTERN_OUTOFORDER; pattern = PATTERN_OUTOFORDER;
break; break;
default: default:
pattern = PATTERN_BUSY; pattern = PATTERN_CONGESTION;
} }
return pattern; return pattern;
@ -290,28 +313,10 @@ static int is_process_pattern(int callref)
static void get_process_patterns(process_t *process, int16_t *samples, int length) static void get_process_patterns(process_t *process, int16_t *samples, int length)
{ {
const int16_t *spl = NULL; const int16_t *spl;
int size = 0, max = 0, pos; int size, max, pos;
switch (process->pattern) { get_pattern(&spl, &size, &max, process->pattern);
case PATTERN_RINGBACK:
spl = freiton_spl;
size = freiton_size;
max = 8 * 5000;
break;
case PATTERN_BUSY:
spl = besetztton_spl;
size = besetztton_size;
max = 8 * 750;
break;
case PATTERN_OUTOFORDER:
spl = ansage_27_spl;
size = ansage_27_size;
max = size;
break;
default:
return;
}
/* stream sample */ /* stream sample */
pos = process->audio_pos; pos = process->audio_pos;
@ -328,15 +333,11 @@ static void get_process_patterns(process_t *process, int16_t *samples, int lengt
static struct termios term_orig; static struct termios term_orig;
int call_init(const char *station_id, const char *sounddev, int samplerate, int latency, int loopback) int call_init(const char *station_id, const char *sounddev, int samplerate, int latency, int dial_digits, int loopback)
{ {
struct termios term; struct termios term;
int rc = 0; int rc = 0;
/* init common tones */
init_freiton();
init_besetzton();
if (use_mncc_sock) if (use_mncc_sock)
return 0; return 0;
@ -352,6 +353,7 @@ int call_init(const char *station_id, const char *sounddev, int samplerate, int
memset(&call, 0, sizeof(call)); memset(&call, 0, sizeof(call));
strncpy(call.station_id, station_id, sizeof(call.station_id) - 1); strncpy(call.station_id, station_id, sizeof(call.station_id) - 1);
call.latspl = latency * samplerate / 1000; call.latspl = latency * samplerate / 1000;
call.dial_digits = dial_digits;
call.loopback = loopback; call.loopback = loopback;
if (!sounddev[0]) if (!sounddev[0])
@ -433,13 +435,13 @@ static int process_ui(void)
switch (call.state) { switch (call.state) {
case CALL_IDLE: case CALL_IDLE:
if (c > 0) { if (c > 0) {
if (c >= '0' && c <= '9' && strlen(call.station_id) < 5) { if (c >= '0' && c <= '9' && strlen(call.station_id) < call.dial_digits) {
call.station_id[strlen(call.station_id) + 1] = '\0'; call.station_id[strlen(call.station_id) + 1] = '\0';
call.station_id[strlen(call.station_id)] = c; call.station_id[strlen(call.station_id)] = c;
} }
if ((c == 8 || c == 127) && strlen(call.station_id)) if ((c == 8 || c == 127) && strlen(call.station_id))
call.station_id[strlen(call.station_id) - 1] = '\0'; call.station_id[strlen(call.station_id) - 1] = '\0';
if (c == 'd' && strlen(call.station_id) == 5) { if (c == 'd' && strlen(call.station_id) == call.dial_digits) {
int rc; int rc;
int callref = ++new_callref; int callref = ++new_callref;
@ -456,7 +458,7 @@ static int process_ui(void)
} }
} }
} }
printf("on-hook: %s%s (enter 0..9 or d=dial)\r", call.station_id, "....." + strlen(call.station_id)); printf("on-hook: %s%s (enter 0..9 or d=dial)\r", call.station_id, "..............." + 15 - call.dial_digits + strlen(call.station_id));
break; break;
case CALL_SETUP_MO: case CALL_SETUP_MO:
case CALL_SETUP_MT: case CALL_SETUP_MT:
@ -624,8 +626,8 @@ int call_in_setup(int callref, const char *callerid, const char *dialing)
call.callref = callref; call.callref = callref;
call_new_state(CALL_CONNECT); call_new_state(CALL_CONNECT);
if (callerid[0]) { if (callerid[0]) {
strncpy(call.station_id, callerid, 5); strncpy(call.station_id, callerid, call.dial_digits);
call.station_id[5] = '\0'; call.station_id[call.dial_digits] = '\0';
} }
strncpy(call.dialing, dialing, sizeof(call.dialing) - 1); strncpy(call.dialing, dialing, sizeof(call.dialing) - 1);
call.dialing[sizeof(call.dialing) - 1] = '\0'; call.dialing[sizeof(call.dialing) - 1] = '\0';
@ -694,8 +696,8 @@ void call_in_answer(int callref, const char *connectid)
return; return;
} }
call_new_state(CALL_CONNECT); call_new_state(CALL_CONNECT);
strncpy(call.station_id, connectid, 5); strncpy(call.station_id, connectid, call.dial_digits);
call.station_id[5] = '\0'; call.station_id[call.dial_digits] = '\0';
} }
/* Transceiver indicates release. */ /* Transceiver indicates release. */

View File

@ -1,5 +1,5 @@
int call_init(const char *station_id, const char *sounddev, int samplerate, int latency, int loopback); int call_init(const char *station_id, const char *sounddev, int samplerate, int latency, int dial_digits, int loopback);
void call_cleanup(void); void call_cleanup(void);
int process_call(void); int process_call(void);

View File

@ -1061,13 +1061,15 @@ static int16_t pattern[] = {
0x0095, 0x0042, 0x0006, 0x0036, 0x0000, 0x003a, 0x00a9, 0xfffa, 0x0095, 0x0042, 0x0006, 0x0036, 0x0000, 0x003a, 0x00a9, 0xfffa,
}; };
extern int16_t *freiton_spl; extern int16_t *ringback_spl;
extern int freiton_size; extern int ringback_size;
extern int ringback_max;
void init_freiton(void) void init_freiton(void)
{ {
freiton_spl = pattern; ringback_spl = pattern;
freiton_size = sizeof(pattern) / sizeof(pattern[0]); ringback_size = sizeof(pattern) / sizeof(pattern[0]);
ringback_max = 8 * 5000;
} }

View File

@ -10,7 +10,7 @@ extern int loopback;
extern int rt_prio; extern int rt_prio;
void print_help(const char *arg0); void print_help(const char *arg0);
void print_help_common(const char *arg0); void print_help_common(const char *arg0, const char *ext_usage);
extern struct option *long_options; extern struct option *long_options;
extern char *optstring; extern char *optstring;
void set_options_common(const char *optstring_special, struct option *long_options_special); void set_options_common(const char *optstring_special, struct option *long_options_special);

View File

@ -37,9 +37,9 @@ int send_patterns = 1;
int loopback = 0; int loopback = 0;
int rt_prio = 0; int rt_prio = 0;
void print_help_common(const char *arg0) void print_help_common(const char *arg0, const char *ext_usage)
{ {
printf("Usage: %s -k kanal [options] [station-id]\n", arg0); printf("Usage: %s -k <kanal/channel> %s[options] [station-id]\n", arg0, ext_usage);
printf("\noptions:\n"); printf("\noptions:\n");
/* - - */ /* - - */
printf(" -h --help\n"); printf(" -h --help\n");

View File

@ -74,6 +74,7 @@ void timer_start(struct timer *timer, double duration)
gettimeofday(&tv, NULL); gettimeofday(&tv, NULL);
timer->duration = duration;
timer->timeout = get_time() + duration; timer->timeout = get_time() + duration;
} }

View File

@ -2,6 +2,7 @@
struct timer { struct timer {
struct timer *next; struct timer *next;
int linked; /* set is timer is initialized and linked */ int linked; /* set is timer is initialized and linked */
double duration;
double timeout; double timeout;
void (*fn)(struct timer *timer); void (*fn)(struct timer *timer);
void *priv; void *priv;