diff options
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/Makefile.am | 1 | ||||
-rw-r--r-- | src/common/call.c | 64 | ||||
-rw-r--r-- | src/common/call.h | 2 | ||||
-rw-r--r-- | src/common/display_wave.c | 99 | ||||
-rw-r--r-- | src/common/display_wave.h | 12 | ||||
-rw-r--r-- | src/common/main.h | 3 | ||||
-rw-r--r-- | src/common/main_common.c | 86 | ||||
-rw-r--r-- | src/common/sender.c | 51 | ||||
-rw-r--r-- | src/common/sender.h | 6 |
9 files changed, 223 insertions, 101 deletions
diff --git a/src/common/Makefile.am b/src/common/Makefile.am index 7c11451..f15a9ad 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -21,5 +21,6 @@ libcommon_a_SOURCES = \ ../common/emphasis.c \ ../common/compander.c \ ../common/sender.c \ + ../common/display_wave.c \ ../common/main_common.c diff --git a/src/common/call.c b/src/common/call.c index 4735404..d49ff1f 100644 --- a/src/common/call.c +++ b/src/common/call.c @@ -24,7 +24,6 @@ #include <stdlib.h> #include <errno.h> #include <sys/time.h> -#include <termios.h> #include "../common/debug.h" #include "../common/sender.h" #include "cause.h" @@ -331,25 +330,13 @@ static void get_process_patterns(process_t *process, int16_t *samples, int lengt process->audio_pos = pos; } -static struct termios term_orig; - int call_init(const char *station_id, const char *sounddev, int samplerate, int latency, int dial_digits, int loopback) { - struct termios term; int rc = 0; if (use_mncc_sock) return 0; - if (!loopback) { - tcgetattr(0, &term_orig); - term = term_orig; - term.c_lflag &= ~(ISIG|ICANON|ECHO); - term.c_cc[VMIN]=1; - term.c_cc[VTIME]=2; - tcsetattr(0, TCSANOW, &term); - } - memset(&call, 0, sizeof(call)); strncpy(call.station_id, station_id, sizeof(call.station_id) - 1); call.latspl = latency * samplerate / 1000; @@ -391,8 +378,6 @@ void call_cleanup(void) { if (use_mncc_sock) return; - if (!call.loopback) - tcsetattr(0, TCSANOW, &term_orig); /* close sound devoice */ if (call.sound) @@ -405,33 +390,8 @@ void call_cleanup(void) } } -static int get_char() -{ - struct timeval tv = {0, 0}; - fd_set fds; - char c = 0; - int __attribute__((__unused__)) rc; - - FD_ZERO(&fds); - FD_SET(0, &fds); - select(0+1, &fds, NULL, NULL, &tv); - if (FD_ISSET(0, &fds)) { - rc = read(0, &c, 1); - return c; - } else - return -1; -} - -static int process_ui(void) +static void process_ui(int c) { - int c; - - c = get_char(); - - /* break */ - if (c == 3) - return 1; - switch (call.state) { case CALL_IDLE: if (c > 0) { @@ -493,26 +453,22 @@ dial_after_hangup: break; } fflush(stdout); - - return 0; } /* get keys from keyboad to control call via console * returns 1 on exit (ctrl+c) */ -int process_call(void) +void process_call(int c) { if (use_mncc_sock) { mncc_handle(); - return 0; + return; } - if (!call.loopback) { - if (process_ui()) - return 1; - } + if (!call.loopback) + process_ui(c); if (!call.sound) - return 0; + return; /* handle audio, if sound device is used */ int16_t samples[call.latspl]; @@ -524,7 +480,7 @@ int process_call(void) PDEBUG(DSENDER, DEBUG_ERROR, "Failed to get samples in buffer (rc = %d)!\n", count); if (count == -EPIPE) PDEBUG(DSENDER, DEBUG_ERROR, "Trying to recover.\n"); - return 0; + return; } if (count < call.latspl) { int16_t up[count + 10]; @@ -552,7 +508,7 @@ int process_call(void) PDEBUG(DSENDER, DEBUG_ERROR, "Failed to write TX data to sound device (rc = %d)\n", rc); if (rc == -EPIPE) PDEBUG(DSENDER, DEBUG_ERROR, "Trying to recover.\n"); - return 0; + return; } } count = sound_read(call.sound, samples, samples, call.latspl); @@ -560,7 +516,7 @@ int process_call(void) PDEBUG(DSENDER, DEBUG_ERROR, "Failed to read from sound device (rc = %d)!\n", count); if (count == -EPIPE) PDEBUG(DSENDER, DEBUG_ERROR, "Trying to recover.\n"); - return 0; + return; } if (count) { int16_t down[count]; /* more than enough */ @@ -570,8 +526,6 @@ int process_call(void) count = samplerate_downsample(&call.srstate, samples, count, down); call_rx_audio(call.callref, down, count); } - - return 0; } /* Setup is received from transceiver. */ diff --git a/src/common/call.h b/src/common/call.h index 4df116d..aa38c97 100644 --- a/src/common/call.h +++ b/src/common/call.h @@ -1,7 +1,7 @@ int call_init(const char *station_id, const char *sounddev, int samplerate, int latency, int dial_digits, int loopback); void call_cleanup(void); -int process_call(void); +void process_call(int c); /* received messages */ int call_in_setup(int callref, const char *callerid, const char *dialing); diff --git a/src/common/display_wave.c b/src/common/display_wave.c new file mode 100644 index 0000000..a10debe --- /dev/null +++ b/src/common/display_wave.c @@ -0,0 +1,99 @@ +/* display wave form functions + * + * (C) 2016 by Andreas Eversberg <jolly@eversberg.eu> + * All Rights Reserved + * + * 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 3 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, see <http://www.gnu.org/licenses/>. + */ + +#include <stdio.h> +#include <stdint.h> +#include <string.h> +#include "sender.h" + +#define DISPLAY_INTERVAL 0.04 + +#define WIDTH 80 +#define HEIGHT 10 + +static char screen[HEIGHT][WIDTH+1]; +static int wave_on = 0; + +void display_wave_init(sender_t *sender, int samplerate) +{ + dispwav_t *disp = &sender->dispwav; + + memset(disp, 0, sizeof(*disp)); + disp->interval_max = (double)samplerate * DISPLAY_INTERVAL + 0.5; +} + +void display_wave_on(int on) +{ + int j; + + if (on < 0) + wave_on = 1 - wave_on; + else + wave_on = on; + + memset(&screen, ' ', sizeof(screen)); + printf("\0337\033[H"); + for (j = 0; j < HEIGHT; j++) { + screen[j][WIDTH] = '\0'; + puts(screen[j]); + } + printf("\0338"); fflush(stdout); +} + +void display_wave(sender_t *sender, int16_t *samples, int length) +{ + dispwav_t *disp = &sender->dispwav; + int pos, max; + int16_t *buffer; + int i, j, y; + + if (!wave_on) + return; + + pos = disp->interval_pos; + max = disp->interval_max; + buffer = disp->buffer; + + for (i = 0; i < length; i++) { + if (pos >= WIDTH) { + if (++pos == max) + pos = 0; + continue; + } + buffer[pos++] = samples[i]; + if (pos == WIDTH) { + memset(&screen, ' ', sizeof(screen)); + for (j = 0; j < WIDTH; j++) { + /* must divide by 65536, because we may never reach HEIGHT*2! */ + y = (32767 - (int)buffer[j]) * HEIGHT * 2 / 65536; + screen[y >> 1][j] = (y & 1) ? '_' : '-'; + } + printf("\0337\033[H"); + for (j = 0; j < HEIGHT; j++) { + screen[j][WIDTH] = '\0'; + puts(screen[j]); + } + printf("\0338"); fflush(stdout); + } + } + + disp->interval_pos = pos; +} + + diff --git a/src/common/display_wave.h b/src/common/display_wave.h new file mode 100644 index 0000000..7ff72c0 --- /dev/null +++ b/src/common/display_wave.h @@ -0,0 +1,12 @@ +typedef struct sender sender_t; + +typedef struct display_wave { + int interval_pos; + int interval_max; + int16_t buffer[256]; +} dispwav_t; + +void display_wave_init(sender_t *sender, int samplerate); +void display_wave_on(int on); +void display_wave(sender_t *sender, int16_t *samples, int length); + diff --git a/src/common/main.h b/src/common/main.h index 0df6539..cc50013 100644 --- a/src/common/main.h +++ b/src/common/main.h @@ -35,3 +35,6 @@ void opt_switch_common(int c, char *arg0, int *skip_args); extern int quit; void sighandler(int sigset); + +void main_loop(int *quit, int latency); + diff --git a/src/common/main_common.c b/src/common/main_common.c index 4f4d2ea..9820c1a 100644 --- a/src/common/main_common.c +++ b/src/common/main_common.c @@ -23,10 +23,14 @@ #include <stdlib.h> #include <string.h> #include <signal.h> +#include <unistd.h> #include <math.h> +#include <termios.h> #include "main.h" #include "debug.h" -#include "../common/sender.h" +#include "sender.h" +#include "timer.h" +#include "call.h" /* common settings */ int num_kanal = 0; @@ -241,3 +245,83 @@ void sighandler(int sigset) quit = 1; } +static int get_char() +{ + struct timeval tv = {0, 0}; + fd_set fds; + char c = 0; + int __attribute__((__unused__)) rc; + + FD_ZERO(&fds); + FD_SET(0, &fds); + select(0+1, &fds, NULL, NULL, &tv); + if (FD_ISSET(0, &fds)) { + rc = read(0, &c, 1); + return c; + } else + return -1; +} + +/* Loop through all transceiver instances of one network. */ +void main_loop(int *quit, int latency) +{ + int latspl; + sender_t *sender; + double last_time = 0, now; + struct termios term, term_orig; + int c; + + /* prepare terminal */ + tcgetattr(0, &term_orig); + term = term_orig; + term.c_lflag &= ~(ISIG|ICANON|ECHO); + term.c_cc[VMIN]=1; + term.c_cc[VTIME]=2; + tcsetattr(0, TCSANOW, &term); + + while(!(*quit)) { + /* process sound of all transceivers */ + for (sender = sender_head; sender; sender = sender->next) { + /* do not process audio for an audio slave, since it is done by audio master */ + if (sender->master) /* if master is set, we are an audio slave */ + continue; + latspl = sender->samplerate * latency / 1000; + process_sender_audio(sender, quit, latspl); + } + + /* process timers */ + process_timer(); + + /* process audio for mncc call instances */ + now = get_time(); + if (now - last_time >= 0.1) + last_time = now; + if (now - last_time >= 0.020) { + last_time += 0.020; + /* call clock every 20ms */ + call_mncc_clock(); + } + + c = get_char(); + switch (c) { + case 3: + /* quit */ + *quit = 1; + break; + case 'w': + /* toggle display */ + display_wave_on(-1); + break; + default: + /* process audio of built-in call control */ + process_call(c); + } + + /* sleep a while */ + usleep(1000); + } + + /* reset terminal */ + tcsetattr(0, TCSANOW, &term_orig); +} + diff --git a/src/common/sender.c b/src/common/sender.c index f25df9e..16c7ac4 100644 --- a/src/common/sender.c +++ b/src/common/sender.c @@ -23,13 +23,10 @@ #include <stdio.h> #include <stdint.h> #include <stdlib.h> -#include <unistd.h> #include <errno.h> #include <string.h> #include "debug.h" #include "sender.h" -#include "timer.h" -#include "call.h" sender_t *sender_head = NULL; static sender_t **sender_tailp = &sender_head; @@ -138,6 +135,9 @@ int sender_create(sender_t *sender, int kanal, const char *sounddev, int sampler *sender_tailp = sender; sender_tailp = &sender->next; + if (sender == sender_head) + display_wave_init(sender, samplerate); + return 0; error: sender_destroy(sender); @@ -209,7 +209,7 @@ static void gain_samples(int16_t *samples, int length, double gain) } /* Handle audio streaming of one transceiver. */ -static void process_sender_audio(sender_t *sender, int *quit, int latspl) +void process_sender_audio(sender_t *sender, int *quit, int latspl) { sender_t *slave = sender->slave; int16_t samples[latspl], pilot[latspl], slave_samples[latspl]; @@ -245,6 +245,8 @@ cant_recover: #ifndef WAVE_WRITE_TX if (sender->wave_rec.fp) wave_write(&sender->wave_rec, samples, count); + if (sender == sender_head) + display_wave(sender, samples, count); sender_receive(sender, samples, count); #endif } @@ -362,6 +364,8 @@ cant_recover: if (sender->wave_rec.fp) wave_write(&sender->wave_rec, samples, count); #endif + if (sender == sender_head) + display_wave(sender, samples, count); sender_receive(sender, samples, count); } if (sender->loopback == 3) @@ -387,42 +391,3 @@ cant_recover: } } -/* Loop through all transceiver instances of one network. */ -void main_loop(int *quit, int latency) -{ - int latspl; - sender_t *sender; - double last_time = 0, now; - - while(!(*quit)) { - /* process sound of all transceivers */ - for (sender = sender_head; sender; sender = sender->next) { - /* do not process audio for an audio slave, since it is done by audio master */ - if (sender->master) /* if master is set, we are an audio slave */ - continue; - latspl = sender->samplerate * latency / 1000; - process_sender_audio(sender, quit, latspl); - } - - /* process timers */ - process_timer(); - - /* process audio for mncc call instances */ - now = get_time(); - if (now - last_time >= 0.1) - last_time = now; - if (now - last_time >= 0.020) { - last_time += 0.020; - /* call clock every 20ms */ - call_mncc_clock(); - } - - /* process audio of built-in call control */ - if (process_call()) - break; - - /* sleep a while */ - usleep(1000); - } -} - diff --git a/src/common/sender.h b/src/common/sender.h index e1a8176..8a26537 100644 --- a/src/common/sender.h +++ b/src/common/sender.h @@ -4,6 +4,7 @@ #include "jitter.h" #include "loss.h" #include "emphasis.h" +#include "display_wave.h" #define MAX_SENDER 16 @@ -53,6 +54,9 @@ typedef struct sender { int pilot_on; /* 1 or 0 for on or off */ double pilotton_phaseshift; /* phase to shift every sample */ double pilotton_phase; /* current phase */ + + /* display wave */ + dispwav_t dispwav; /* display wave form */ } sender_t; /* list of all senders */ @@ -61,7 +65,7 @@ extern int cant_recover; int sender_create(sender_t *sender, int kanal, const char *sounddev, int samplerate, int cross_channels, double rx_gain, int pre_emphasis, int de_emphasis, const char *write_wave, const char *read_wave, int loopback, double loss_volume, int use_pilot_signal); void sender_destroy(sender_t *sender); +void process_sender_audio(sender_t *sender, int *quit, int latspl); void sender_send(sender_t *sender, int16_t *samples, int count); void sender_receive(sender_t *sender, int16_t *samples, int count); -void main_loop(int *quit, int latency); |