From 7ea3bc188df54a4dbe3026bc30ed39a5cded8fdb Mon Sep 17 00:00:00 2001 From: Andreas Eversberg Date: Fri, 27 Jan 2017 16:57:34 +0100 Subject: Move samples of int16_t format to sample_t, that is of type double This prepares the correction of all levels --- src/amps/amps.c | 5 +-- src/amps/amps.h | 17 +++++----- src/amps/dsp.c | 80 +++++++++++++++++++-------------------------- src/amps/frame.c | 1 + src/amps/main.c | 1 + src/amps/sysinfo.c | 1 + src/amps/transaction.c | 1 + src/anetz/anetz.c | 5 +-- src/anetz/anetz.h | 5 +-- src/anetz/dsp.c | 37 +++++++++------------ src/anetz/main.c | 1 + src/bnetz/bnetz.c | 5 +-- src/bnetz/bnetz.h | 7 ++-- src/bnetz/dsp.c | 33 ++++++++----------- src/bnetz/main.c | 1 + src/cnetz/cnetz.c | 3 +- src/cnetz/cnetz.h | 10 +++--- src/cnetz/database.c | 1 + src/cnetz/dsp.c | 41 ++++++++++------------- src/cnetz/dsp.h | 2 +- src/cnetz/fsk_fm_demod.c | 25 +++++++------- src/cnetz/fsk_fm_demod.h | 6 ++-- src/cnetz/main.c | 1 + src/cnetz/scrambler.c | 22 ++++--------- src/cnetz/scrambler.h | 2 +- src/cnetz/telegramm.c | 1 + src/cnetz/transaction.c | 1 + src/common/Makefile.am | 1 + src/common/call.c | 51 +++++++++++++++++------------ src/common/call.h | 4 +-- src/common/compandor.c | 27 ++++----------- src/common/compandor.h | 4 +-- src/common/debug.c | 1 + src/common/display.h | 4 +-- src/common/display_iq.c | 1 + src/common/display_wave.c | 14 ++++---- src/common/dtmf.c | 5 +-- src/common/dtmf.h | 2 +- src/common/emphasis.c | 24 ++++---------- src/common/emphasis.h | 4 +-- src/common/goertzel.c | 33 +++++++++++-------- src/common/goertzel.h | 9 +++-- src/common/jitter.c | 13 ++++---- src/common/jitter.h | 6 ++-- src/common/main_common.c | 1 + src/common/mncc_sock.c | 3 +- src/common/sample.c | 27 +++++++++++++++ src/common/sample.h | 6 ++++ src/common/samplerate.c | 47 +++++++++++---------------- src/common/samplerate.h | 4 +-- src/common/sdr.c | 40 ++++++++++------------- src/common/sdr.h | 4 +-- src/common/sender.c | 18 ++++------ src/common/sender.h | 10 +++--- src/common/sound.h | 4 +-- src/common/sound_alsa.c | 71 ++++++++++++++++++++++++++++------------ src/common/uhd.c | 3 -- src/common/wave.c | 19 +++++++---- src/common/wave.h | 4 +-- src/nmt/dms.c | 5 +-- src/nmt/dms.h | 4 +-- src/nmt/dsp.c | 83 +++++++++++++++++++---------------------------- src/nmt/dsp.h | 2 +- src/nmt/frame.c | 1 + src/nmt/main.c | 1 + src/nmt/nmt.c | 5 +-- src/nmt/nmt.h | 11 ++++--- src/nmt/sms.c | 1 + src/nmt/transaction.c | 1 + src/test/test_compandor.c | 15 +++++---- src/test/test_dms.c | 5 +-- src/test/test_emphasis.c | 7 ++-- src/test/test_filter.c | 1 + src/test/test_sms.c | 1 + 74 files changed, 473 insertions(+), 449 deletions(-) create mode 100644 src/common/sample.c create mode 100644 src/common/sample.h (limited to 'src') diff --git a/src/amps/amps.c b/src/amps/amps.c index 1923a30..d600b4b 100644 --- a/src/amps/amps.c +++ b/src/amps/amps.c @@ -42,6 +42,7 @@ #include #include #include +#include "../common/sample.h" #include "../common/debug.h" #include "../common/timer.h" #include "../common/call.h" @@ -902,7 +903,7 @@ void call_out_release(int callref, int cause) } /* Receive audio from call instance. */ -void call_rx_audio(int callref, int16_t *samples, int count) +void call_rx_audio(int callref, sample_t *samples, int count) { sender_t *sender; amps_t *amps; @@ -916,7 +917,7 @@ void call_rx_audio(int callref, int16_t *samples, int count) return; if (amps->dsp_mode == DSP_MODE_AUDIO_RX_AUDIO_TX) { - int16_t up[(int)((double)count * amps->sender.srstate.factor + 0.5) + 10]; + sample_t up[(int)((double)count * amps->sender.srstate.factor + 0.5) + 10]; compress_audio(&s->cstate, samples, count); count = samplerate_upsample(&s->sender.srstate, samples, count, up); jitter_save(&s->sender.dejitter, up, count); diff --git a/src/amps/amps.h b/src/amps/amps.h index 4ff910b..4e2aa81 100644 --- a/src/amps/amps.h +++ b/src/amps/amps.h @@ -1,3 +1,4 @@ +#include "../common/goertzel.h" #include "../common/sender.h" #include "../common/compandor.h" #include "sysinfo.h" @@ -54,15 +55,15 @@ typedef struct amps { /* dsp states */ enum dsp_mode dsp_mode; /* current mode: audio, durable tone 0 or 1, paging */ int flip_polarity; /* 1 = flip */ - int16_t fsk_deviation; /* deviation of FSK signal on sound card */ - int16_t fsk_ramp_up[256]; /* samples of upward ramp shape */ - int16_t fsk_ramp_down[256]; /* samples of downward ramp shape */ + double fsk_deviation; /* deviation of FSK signal on sound card */ + sample_t fsk_ramp_up[256]; /* samples of upward ramp shape */ + sample_t fsk_ramp_down[256]; /* samples of downward ramp shape */ double fsk_bitduration; /* duration of one bit in samples */ double fsk_bitstep; /* fraction of one bit each sample */ /* tx bits generation */ char fsk_tx_frame[FSK_MAX_BITS + 1]; /* +1 because 0-termination */ int fsk_tx_frame_pos; /* current position sending bits */ - int16_t *fsk_tx_buffer; /* tx buffer for one data block */ + sample_t *fsk_tx_buffer; /* tx buffer for one data block */ int fsk_tx_buffer_size; /* size of tx buffer (in samples) */ int fsk_tx_buffer_length; /* usage of buffer (in samples) */ int fsk_tx_buffer_pos; /* current position sending buffer */ @@ -73,7 +74,7 @@ typedef struct amps { double highpass_x_last; /* last input value */ double highpass_y_last; /* last output value */ /* rx detection of bits and sync */ - int16_t fsk_rx_last_sample; /* last sample (for level change detection) */ + sample_t fsk_rx_last_sample; /* last sample (for level change detection) */ double fsk_rx_elapsed; /* bit duration since last level change */ enum fsk_rx_sync fsk_rx_sync; /* sync state */ uint16_t fsk_rx_sync_register; /* shift register to detect sync word */ @@ -88,7 +89,7 @@ typedef struct amps { /* the ex buffer holds the duration of one bit, and wrapps every * bit. */ double fsk_rx_bitcount; /* counts the bit. if it reaches or exceeds 1, the bit is complete and the next bit starts */ - int16_t *fsk_rx_window; /* rx buffer for one bit */ + sample_t *fsk_rx_window; /* rx buffer for one bit */ int fsk_rx_window_length; /* length of rx buffer */ int fsk_rx_window_half; /* half of length of rx buffer */ int fsk_rx_window_begin; /* where to begin detecting level */ @@ -131,8 +132,8 @@ typedef struct amps { /* SAT tone */ int sat; /* use SAT tone 0..2 */ int sat_samples; /* number of samples in buffer for supervisory detection */ - int sat_coeff[5]; /* coefficient for SAT signal decoding */ - int16_t *sat_filter_spl; /* array with sample buffer for supervisory detection */ + goertzel_t sat_goertzel[5]; /* filter for SAT signal decoding */ + sample_t *sat_filter_spl; /* array with sample buffer for supervisory detection */ int sat_filter_pos; /* current sample position in filter_spl */ double sat_phaseshift256[3]; /* how much the phase of sine wave changes per sample */ double sat_phase256; /* current phase */ diff --git a/src/amps/dsp.c b/src/amps/dsp.c index 1a1e3d1..9c6dc2e 100644 --- a/src/amps/dsp.c +++ b/src/amps/dsp.c @@ -81,10 +81,10 @@ #include #include #include +#include "../common/sample.h" #include "../common/debug.h" #include "../common/timer.h" #include "../common/call.h" -#include "../common/goertzel.h" #include "amps.h" #include "frame.h" #include "dsp.h" @@ -180,8 +180,7 @@ static void sat_reset(amps_t *amps, const char *reason); /* Init FSK of transceiver */ int dsp_init_sender(amps_t *amps, int high_pass, int tolerant) { - double coeff; - int16_t *spl; + sample_t *spl; int i; int rc; double RC, dt; @@ -206,12 +205,13 @@ int dsp_init_sender(amps_t *amps, int high_pass, int tolerant) PDEBUG(DDSP, DEBUG_DEBUG, "Use %.4f samples for full bit duration @ %d.\n", amps->fsk_bitduration, amps->sender.samplerate); amps->fsk_tx_buffer_size = amps->fsk_bitduration + 10; /* 10 extra to avoid overflow due to rounding */ - amps->fsk_tx_buffer = calloc(sizeof(int16_t), amps->fsk_tx_buffer_size); - if (!amps->fsk_tx_buffer) { + spl = calloc(sizeof(*spl), amps->fsk_tx_buffer_size); + if (!spl) { PDEBUG(DDSP, DEBUG_DEBUG, "No memory!\n"); rc = -ENOMEM; goto error; } + amps->fsk_tx_buffer = spl; amps->fsk_rx_window_length = ceil(amps->fsk_bitduration); /* buffer holds one bit (rounded up) */ half = amps->fsk_rx_window_length >> 1; @@ -221,12 +221,13 @@ int dsp_init_sender(amps_t *amps, int high_pass, int tolerant) PDEBUG(DDSP, DEBUG_DEBUG, "Bit window length: %d\n", amps->fsk_rx_window_length); PDEBUG(DDSP, DEBUG_DEBUG, " -> Samples in window to analyse level left of edge: %d..%d\n", amps->fsk_rx_window_begin, amps->fsk_rx_window_half - 1); PDEBUG(DDSP, DEBUG_DEBUG, " -> Samples in window to analyse level right of edge: %d..%d\n", amps->fsk_rx_window_half, amps->fsk_rx_window_end - 1); - amps->fsk_rx_window = calloc(sizeof(int16_t), amps->fsk_rx_window_length); - if (!amps->fsk_rx_window) { + spl = calloc(sizeof(*amps->fsk_rx_window), amps->fsk_rx_window_length); + if (!spl) { PDEBUG(DDSP, DEBUG_DEBUG, "No memory!\n"); rc = -ENOMEM; goto error; } + amps->fsk_rx_window = spl; /* create devation and ramp */ amps->fsk_deviation = FSK_DEVIATION; /* be sure not to overflow 32767 */ @@ -234,7 +235,7 @@ int dsp_init_sender(amps_t *amps, int high_pass, int tolerant) /* allocate ring buffer for SAT signal detection */ amps->sat_samples = (int)((double)amps->sender.samplerate * SAT_DURATION + 0.5); - spl = calloc(1, amps->sat_samples * sizeof(*spl)); + spl = calloc(sizeof(*spl), amps->sat_samples); if (!spl) { PDEBUG(DDSP, DEBUG_ERROR, "No memory!\n"); return -ENOMEM; @@ -243,10 +244,7 @@ int dsp_init_sender(amps_t *amps, int high_pass, int tolerant) /* count SAT tones */ for (i = 0; i < 5; i++) { - coeff = 2.0 * cos(2.0 * PI * sat_freq[i] / (double)amps->sender.samplerate); - amps->sat_coeff[i] = coeff * 32768.0; - PDEBUG(DDSP, DEBUG_DEBUG, "sat_coeff[%d] = %d\n", i, (int)amps->sat_coeff[i]); - + audio_goertzel_init(&s->sat_goertzel[i], sat_freq[i], amps->sender.samplerate); if (i < 3) { amps->sat_phaseshift256[i] = 256.0 / ((double)amps->sender.samplerate / sat_freq[i]); PDEBUG(DDSP, DEBUG_DEBUG, "sat_phaseshift256[%d] = %.4f\n", i, amps->sat_phaseshift256[i]); @@ -300,7 +298,7 @@ void dsp_cleanup_sender(amps_t *amps) static int fsk_encode(amps_t *amps, char bit) { - int16_t *spl; + sample_t *spl; double phase, bitstep, deviation; int count; char last; @@ -368,10 +366,10 @@ static int fsk_encode(amps_t *amps, char bit) return count; } -static int fsk_frame(amps_t *amps, int16_t *samples, int length) +static int fsk_frame(amps_t *amps, sample_t *samples, int length) { int count = 0, len, pos, copy, i; - int16_t *spl; + sample_t *spl; int rc; char c; @@ -430,7 +428,7 @@ done: } /* Generate audio stream with SAT signal. Keep phase for next call of function. */ -static void sat_encode(amps_t *amps, int16_t *samples, int length) +static void sat_encode(amps_t *amps, sample_t *samples, int length) { double phaseshift, phase; int32_t sample; @@ -455,7 +453,7 @@ static void sat_encode(amps_t *amps, int16_t *samples, int length) amps->sat_phase256 = phase; } -static void test_tone_encode(amps_t *amps, int16_t *samples, int length) +static void test_tone_encode(amps_t *amps, sample_t *samples, int length) { double phaseshift, phase; int i; @@ -474,7 +472,7 @@ static void test_tone_encode(amps_t *amps, int16_t *samples, int length) } /* Provide stream of audio toward radio unit */ -void sender_send(sender_t *sender, int16_t *samples, int length) +void sender_send(sender_t *sender, sample_t *samples, int length) { amps_t *amps = (amps_t *) sender; int count; @@ -505,12 +503,12 @@ again: } } -static void fsk_rx_bit(amps_t *amps, int16_t *spl, int len, int pos, int begin, int half, int end) +static void fsk_rx_bit(amps_t *amps, sample_t *spl, int len, int pos, int begin, int half, int end) { int i; - int32_t first, second; + double first, second; int bit; - int32_t max = -32768, min = 32767; + double max = 0, min = 0; /* decode one bit. substact the first half from the second half. * the result shows the direction of the bit change: 1 == positive. @@ -522,9 +520,9 @@ static void fsk_rx_bit(amps_t *amps, int16_t *spl, int len, int pos, int begin, pos += len; //printf("second %d: %d\n", pos, spl[pos]); second += spl[pos]; - if (spl[pos] > max) + if (i == 0 || spl[pos] > max) max = spl[pos]; - if (spl[pos] < min) + if (i == 0 || spl[pos] < min) min = spl[pos]; } second /= (half - begin); @@ -683,13 +681,13 @@ static void fsk_rx_dotting(amps_t *amps, double _elapsed) } /* decode frame */ -static void sender_receive_frame(amps_t *amps, int16_t *samples, int length) +static void sender_receive_frame(amps_t *amps, sample_t *samples, int length) { int i; for (i = 0; i < length; i++) { #ifdef DEBUG_DECODER - puts(debug_amplitude((double)samples[i] / (double)FSK_DEVIATION)); + puts(debug_amplitude(samples[i] / (double)FSK_DEVIATION)); #endif /* push sample to detection window and shift */ amps->fsk_rx_window[amps->fsk_rx_window_pos++] = samples[i]; @@ -731,15 +729,13 @@ static void sender_receive_frame(amps_t *amps, int16_t *samples, int length) /* decode signaling tone */ /* compare supervisory signal against noise floor on 5800 Hz */ -static void sat_decode(amps_t *amps, int16_t *samples, int length) +static void sat_decode(amps_t *amps, sample_t *samples, int length) { - int coeff[3]; double result[3], quality[2]; - coeff[0] = amps->sat_coeff[amps->sat]; - coeff[1] = amps->sat_coeff[3]; /* noise floor detection */ - coeff[2] = amps->sat_coeff[4]; /* signaling tone */ - audio_goertzel(samples, length, 0, coeff, result, 3); + audio_goertzel(&s->sat_goertzel[amps->sat], samples, length, 0, &result[0], 1); + audio_goertzel(&s->sat_goertzel[3], samples, length, 0, &result[1], 1); + audio_goertzel(&s->sat_goertzel[4], samples, length, 0, &result[2], 1); quality[0] = (result[0] - result[1]) / result[0]; if (quality[0] < 0) @@ -805,10 +801,10 @@ static void sat_decode(amps_t *amps, int16_t *samples, int length) * time is between SIG_TONE_MINBITS and SIG_TONE_MAXBITS. If it is, the * frequency is close to the singalling tone, so it is detected */ -static void sender_receive_audio(amps_t *amps, int16_t *samples, int length) +static void sender_receive_audio(amps_t *amps, sample_t *samples, int length) { transaction_t *trans = amps->trans_list; - int16_t *spl; + sample_t *spl; int max, pos; int i; @@ -830,21 +826,19 @@ static void sender_receive_audio(amps_t *amps, int16_t *samples, int length) if ((amps->dsp_mode == DSP_MODE_AUDIO_RX_AUDIO_TX || amps->dsp_mode == DSP_MODE_AUDIO_RX_FRAME_TX) && trans && trans->callref && trans->sat_detected) { - int16_t down[length]; /* more than enough */ int pos, count; - int16_t *spl; int i; /* de-emphasis */ if (amps->de_emphasis) de_emphasis(&s->estate, samples, length); /* downsample */ - count = samplerate_downsample(&s->sender.srstate, samples, length, down); - expand_audio(&s->cstate, down, count); + count = samplerate_downsample(&s->sender.srstate, samples, length); + expand_audio(&s->cstate, samples, count); spl = amps->sender.rxbuf; pos = amps->sender.rxbuf_pos; for (i = 0; i < count; i++) { - spl[pos++] = down[i]; + spl[pos++] = samples[i]; if (pos == 160) { call_tx_audio(trans->callref, spl, 160); pos = 0; @@ -856,11 +850,10 @@ static void sender_receive_audio(amps_t *amps, int16_t *samples, int length) } /* Process received audio stream from radio unit. */ -void sender_receive(sender_t *sender, int16_t *samples, int length) +void sender_receive(sender_t *sender, sample_t *samples, int length) { amps_t *amps = (amps_t *) sender; double x, y, x_last, y_last, factor; - int32_t value; int i; /* high pass filter to remove 0-level @@ -874,12 +867,7 @@ void sender_receive(sender_t *sender, int16_t *samples, int length) y = factor * (y_last + x - x_last); x_last = x; y_last = y; - value = (int32_t)(y + 0.5); - if (value < -32768.0) - value = -32768.0; - else if (value > 32767) - value = 32767; - samples[i] = value; + samples[i] = y; } amps->highpass_x_last = x_last; amps->highpass_y_last = y_last; diff --git a/src/amps/frame.c b/src/amps/frame.c index 478739b..ea98c18 100644 --- a/src/amps/frame.c +++ b/src/amps/frame.c @@ -26,6 +26,7 @@ #include #include #include +#include "../common/sample.h" #include "../common/debug.h" #include "../common/timer.h" #include "amps.h" diff --git a/src/amps/main.c b/src/amps/main.c index 8394c37..b853b76 100644 --- a/src/amps/main.c +++ b/src/amps/main.c @@ -22,6 +22,7 @@ #include #include #include +#include "../common/sample.h" #include "../common/main.h" #include "../common/debug.h" #include "../common/timer.h" diff --git a/src/amps/sysinfo.c b/src/amps/sysinfo.c index f57de95..db35fb4 100644 --- a/src/amps/sysinfo.c +++ b/src/amps/sysinfo.c @@ -3,6 +3,7 @@ #include #include #include +#include "../common/sample.h" #include "../common/timer.h" #include "amps.h" #include "frame.h" diff --git a/src/amps/transaction.c b/src/amps/transaction.c index b874f58..ea47a67 100644 --- a/src/amps/transaction.c +++ b/src/amps/transaction.c @@ -20,6 +20,7 @@ #include #include #include +#include "../common/sample.h" #include "../common/debug.h" #include "../common/timer.h" #include "amps.h" diff --git a/src/anetz/anetz.c b/src/anetz/anetz.c index 77493f7..c65d6f1 100644 --- a/src/anetz/anetz.c +++ b/src/anetz/anetz.c @@ -24,6 +24,7 @@ #include #include #include +#include "../common/sample.h" #include "../common/debug.h" #include "../common/timer.h" #include "../common/call.h" @@ -492,7 +493,7 @@ void call_out_release(int callref, __attribute__((unused)) int cause) } /* Receive audio from call instance. */ -void call_rx_audio(int callref, int16_t *samples, int count) +void call_rx_audio(int callref, sample_t *samples, int count) { sender_t *sender; anetz_t *anetz; @@ -506,7 +507,7 @@ void call_rx_audio(int callref, int16_t *samples, int count) return; if (anetz->dsp_mode == DSP_MODE_AUDIO) { - int16_t up[(int)((double)count * anetz->sender.srstate.factor + 0.5) + 10]; + sample_t up[(int)((double)count * anetz->sender.srstate.factor + 0.5) + 10]; count = samplerate_upsample(&anetz->sender.srstate, samples, count, up); jitter_save(&anetz->sender.dejitter, up, count); } diff --git a/src/anetz/anetz.h b/src/anetz/anetz.h index a464db3..05d8e50 100644 --- a/src/anetz/anetz.h +++ b/src/anetz/anetz.h @@ -1,3 +1,4 @@ +#include "../common/goertzel.h" #include "../common/sender.h" enum dsp_mode { @@ -26,9 +27,9 @@ typedef struct anetz { /* dsp states */ enum dsp_mode dsp_mode; /* current mode: audio, durable tone 0 or 1, paging */ - int fsk_tone_coeff[2]; /* coefficient k = 2*cos(2*PI*f/samplerate), k << 15 */ + goertzel_t fsk_tone_goertzel[2]; /* filter for tone decoding */ int samples_per_chunk; /* how many samples lasts one chunk */ - int16_t *fsk_filter_spl; /* array with samples_per_chunk */ + sample_t *fsk_filter_spl; /* array with samples_per_chunk */ int fsk_filter_pos; /* current sample position in filter_spl */ int tone_detected; /* what tone has been detected */ int tone_count; /* how long has that tone been detected */ diff --git a/src/anetz/dsp.c b/src/anetz/dsp.c index a680366..1200c43 100644 --- a/src/anetz/dsp.c +++ b/src/anetz/dsp.c @@ -25,10 +25,10 @@ #include #include #include +#include "../common/sample.h" #include "../common/debug.h" #include "../common/timer.h" #include "../common/call.h" -#include "../common/goertzel.h" #include "anetz.h" #include "dsp.h" @@ -53,7 +53,7 @@ static double fsk_tones[2] = { }; /* table for fast sine generation */ -int dsp_sine_tone[256]; +sample_t dsp_sine_tone[256]; /* global init for audio processing */ void dsp_init(void) @@ -76,8 +76,7 @@ void dsp_init(void) /* Init transceiver instance. */ int dsp_init_sender(anetz_t *anetz, double page_gain, int page_sequence) { - int16_t *spl; - double coeff; + sample_t *spl; int i; double tone; @@ -98,7 +97,7 @@ int dsp_init_sender(anetz_t *anetz, double page_gain, int page_sequence) anetz->samples_per_chunk = anetz->sender.samplerate * CHUNK_DURATION; PDEBUG(DDSP, DEBUG_DEBUG, "Using %d samples per chunk duration.\n", anetz->samples_per_chunk); - spl = calloc(1, anetz->samples_per_chunk << 1); + spl = calloc(anetz->samples_per_chunk, sizeof(sample_t)); if (!spl) { PDEBUG(DDSP, DEBUG_ERROR, "No memory!\n"); return -ENOMEM; @@ -107,11 +106,8 @@ int dsp_init_sender(anetz_t *anetz, double page_gain, int page_sequence) anetz->tone_detected = -1; - for (i = 0; i < 2; i++) { - coeff = 2.0 * cos(2.0 * PI * fsk_tones[i] / (double)anetz->sender.samplerate); - anetz->fsk_tone_coeff[i] = coeff * 32768.0; - PDEBUG(DDSP, DEBUG_DEBUG, "RX %.0f Hz coeff = %d\n", fsk_tones[i], (int)anetz->fsk_tone_coeff[i]); - } + for (i = 0; i < 2; i++) + audio_goertzel_init(&anetz->fsk_tone_goertzel[i], fsk_tones[i], anetz->sender.samplerate); tone = fsk_tones[(anetz->sender.loopback == 0) ? 0 : 1]; anetz->tone_phaseshift256 = 256.0 / ((double)anetz->sender.samplerate / tone); PDEBUG(DDSP, DEBUG_DEBUG, "TX %.0f Hz phaseshift = %.4f\n", tone, anetz->tone_phaseshift256); @@ -159,7 +155,7 @@ static void fsk_receive_tone(anetz_t *anetz, int tone, int goodtone, double leve } /* Filter one chunk of audio an detect tone, quality and loss of signal. */ -static void fsk_decode_chunk(anetz_t *anetz, int16_t *spl, int max) +static void fsk_decode_chunk(anetz_t *anetz, sample_t *spl, int max) { double level, result[2]; @@ -168,7 +164,7 @@ static void fsk_decode_chunk(anetz_t *anetz, int16_t *spl, int max) if (audio_detect_loss(&anetz->sender.loss, level)) anetz_loss_indication(anetz); - audio_goertzel(spl, max, 0, anetz->fsk_tone_coeff, result, 2); + audio_goertzel(anetz->fsk_tone_goertzel, spl, max, 0, result, 2); /* show quality of tone */ if (anetz->sender.loopback) { @@ -189,10 +185,10 @@ static void fsk_decode_chunk(anetz_t *anetz, int16_t *spl, int max) } /* Process received audio stream from radio unit. */ -void sender_receive(sender_t *sender, int16_t *samples, int length) +void sender_receive(sender_t *sender, sample_t *samples, int length) { anetz_t *anetz = (anetz_t *) sender; - int16_t *spl; + sample_t *spl; int max, pos; int i; @@ -211,14 +207,13 @@ void sender_receive(sender_t *sender, int16_t *samples, int length) /* Forward audio to network (call process). */ if (anetz->dsp_mode == DSP_MODE_AUDIO && anetz->callref) { - int16_t down[length]; /* more than enough */ int count; - count = samplerate_downsample(&anetz->sender.srstate, samples, length, down); + count = samplerate_downsample(&anetz->sender.srstate, samples, length); spl = anetz->sender.rxbuf; pos = anetz->sender.rxbuf_pos; for (i = 0; i < count; i++) { - spl[pos++] = down[i]; + spl[pos++] = samples[i]; if (pos == 160) { call_tx_audio(anetz->callref, spl, 160); pos = 0; @@ -242,7 +237,7 @@ void dsp_set_paging(anetz_t *anetz, double *freq) /* Generate audio stream of 4 simultanious paging tones. Keep phase for next call of function. * Use TX_PEAK_TONE*page_gain for all tones, which gives peak of 1/4th for each individual tone. */ -static void fsk_paging_tone(anetz_t *anetz, int16_t *samples, int length) +static void fsk_paging_tone(anetz_t *anetz, sample_t *samples, int length) { double phaseshift[4], phase[4]; int i; @@ -283,7 +278,7 @@ static void fsk_paging_tone(anetz_t *anetz, int16_t *samples, int length) * When tone changes to next tone, a transition of 2ms is performed. The last * tone is faded out and the new tone faded in. */ -static void fsk_paging_tone_sequence(anetz_t *anetz, int16_t *samples, int length, int numspl) +static void fsk_paging_tone_sequence(anetz_t *anetz, sample_t *samples, int length, int numspl) { double phaseshift[4], phase[4]; int i; @@ -341,7 +336,7 @@ static void fsk_paging_tone_sequence(anetz_t *anetz, int16_t *samples, int lengt } /* Generate audio stream from tone. Keep phase for next call of function. */ -static void fsk_tone(anetz_t *anetz, int16_t *samples, int length) +static void fsk_tone(anetz_t *anetz, sample_t *samples, int length) { double phaseshift, phase; int i; @@ -360,7 +355,7 @@ static void fsk_tone(anetz_t *anetz, int16_t *samples, int length) } /* Provide stream of audio toward radio unit */ -void sender_send(sender_t *sender, int16_t *samples, int length) +void sender_send(sender_t *sender, sample_t *samples, int length) { anetz_t *anetz = (anetz_t *) sender; diff --git a/src/anetz/main.c b/src/anetz/main.c index 134807d..0511fb5 100644 --- a/src/anetz/main.c +++ b/src/anetz/main.c @@ -23,6 +23,7 @@ #include #include #include +#include "../common/sample.h" #include "../common/main.h" #include "../common/debug.h" #include "../common/timer.h" diff --git a/src/bnetz/bnetz.c b/src/bnetz/bnetz.c index fb92ef3..d6f7b1f 100644 --- a/src/bnetz/bnetz.c +++ b/src/bnetz/bnetz.c @@ -24,6 +24,7 @@ #include #include #include +#include "../common/sample.h" #include "../common/debug.h" #include "../common/timer.h" #include "../common/call.h" @@ -808,7 +809,7 @@ void call_out_release(int callref, int __attribute__((unused)) cause) } /* Receive audio from call instance. */ -void call_rx_audio(int callref, int16_t *samples, int count) +void call_rx_audio(int callref, sample_t *samples, int count) { sender_t *sender; bnetz_t *bnetz; @@ -822,7 +823,7 @@ void call_rx_audio(int callref, int16_t *samples, int count) return; if (bnetz->dsp_mode == DSP_MODE_AUDIO) { - int16_t up[(int)((double)count * bnetz->sender.srstate.factor + 0.5) + 10]; + sample_t up[(int)((double)count * bnetz->sender.srstate.factor + 0.5) + 10]; count = samplerate_upsample(&bnetz->sender.srstate, samples, count, up); jitter_save(&bnetz->sender.dejitter, up, count); } diff --git a/src/bnetz/bnetz.h b/src/bnetz/bnetz.h index dcd3a87..3ba4b51 100644 --- a/src/bnetz/bnetz.h +++ b/src/bnetz/bnetz.h @@ -1,3 +1,4 @@ +#include "../common/goertzel.h" #include "../common/sender.h" /* fsk modes of transmission */ @@ -74,9 +75,9 @@ typedef struct bnetz { /* dsp states */ enum dsp_mode dsp_mode; /* current mode: audio, durable tone 0 or 1, "Telegramm" */ - int fsk_coeff[2]; /* coefficient k = 2*cos(2*PI*f/samplerate), k << 15 */ + goertzel_t fsk_goertzel[2]; /* filter for fsk decoding */ int samples_per_bit; /* how many samples lasts one bit */ - int16_t *fsk_filter_spl; /* array with samples_per_bit */ + sample_t *fsk_filter_spl; /* array with samples_per_bit */ int fsk_filter_pos; /* current sample position in filter_spl */ int fsk_filter_step; /* number of samples for each analyzation */ int fsk_filter_bit; /* last bit, so we detect a bit change */ @@ -90,7 +91,7 @@ typedef struct bnetz { double phaseshift256[2]; /* how much the phase of sine wave changes per sample */ double phase256; /* current phase */ int telegramm; /* set, if there is a valid telegram */ - int16_t *telegramm_spl; /* 16 * samples_per_bit */ + sample_t *telegramm_spl; /* 16 * samples_per_bit */ int telegramm_pos; /* current sample position in telegramm_spl */ /* loopback test for latency */ diff --git a/src/bnetz/dsp.c b/src/bnetz/dsp.c index 58a5375..95a78d6 100644 --- a/src/bnetz/dsp.c +++ b/src/bnetz/dsp.c @@ -25,10 +25,10 @@ #include #include #include +#include "../common/sample.h" #include "../common/debug.h" #include "../common/timer.h" #include "../common/call.h" -#include "../common/goertzel.h" #include "bnetz.h" #include "dsp.h" @@ -54,7 +54,7 @@ static double fsk_bits[2] = { }; /* table for fast sine generation */ -int dsp_sine[256]; +static sample_t dsp_sine[256]; /* global init for FSK */ void dsp_init(void) @@ -75,8 +75,7 @@ void dsp_init(void) /* Init transceiver instance. */ int dsp_init_sender(bnetz_t *bnetz) { - double coeff; - int16_t *spl; + sample_t *spl; int i; if ((bnetz->sender.samplerate % 1000)) { @@ -114,10 +113,7 @@ int dsp_init_sender(bnetz_t *bnetz) /* count symbols */ for (i = 0; i < 2; i++) { - coeff = 2.0 * cos(2.0 * PI * fsk_bits[i] / (double)bnetz->sender.samplerate); - bnetz->fsk_coeff[i] = coeff * 32768.0; - PDEBUG(DDSP, DEBUG_DEBUG, "coeff[%d] = %d (must be -3601 and 2573 at 8000hz)\n", i, (int)bnetz->fsk_coeff[i]); - + audio_goertzel_init(&bnetz->fsk_goertzel[i], fsk_bits[i], bnetz->sender.samplerate); bnetz->phaseshift256[i] = 256.0 / ((double)bnetz->sender.samplerate / fsk_bits[i]); PDEBUG(DDSP, DEBUG_DEBUG, "phaseshift[%d] = %.4f (must be arround 64 at 8000hz)\n", i, bnetz->phaseshift256[i]); } @@ -205,7 +201,7 @@ static inline void fsk_decode_step(bnetz_t *bnetz, int pos) { double level, result[2], softbit, quality; int max; - int16_t *spl; + sample_t *spl; int bit; max = bnetz->samples_per_bit; @@ -216,7 +212,7 @@ static inline void fsk_decode_step(bnetz_t *bnetz, int pos) if (audio_detect_loss(&bnetz->sender.loss, level)) bnetz_loss_indication(bnetz); - audio_goertzel(spl, max, pos, bnetz->fsk_coeff, result, 2); + audio_goertzel(bnetz->fsk_goertzel, spl, max, pos, result, 2); /* calculate soft bit from both frequencies */ softbit = (result[1] / level - result[0] / level + 1.0) / 2.0; @@ -266,10 +262,10 @@ static inline void fsk_decode_step(bnetz_t *bnetz, int pos) } /* Process received audio stream from radio unit. */ -void sender_receive(sender_t *sender, int16_t *samples, int length) +void sender_receive(sender_t *sender, sample_t *samples, int length) { bnetz_t *bnetz = (bnetz_t *) sender; - int16_t *spl; + sample_t *spl; int max, pos, step; int i; @@ -290,14 +286,13 @@ void sender_receive(sender_t *sender, int16_t *samples, int length) bnetz->fsk_filter_pos = pos; if (bnetz->dsp_mode == DSP_MODE_AUDIO && bnetz->callref) { - int16_t down[length]; /* more than enough */ int count; - count = samplerate_downsample(&bnetz->sender.srstate, samples, length, down); + count = samplerate_downsample(&bnetz->sender.srstate, samples, length); spl = bnetz->sender.rxbuf; pos = bnetz->sender.rxbuf_pos; for (i = 0; i < count; i++) { - spl[pos++] = down[i]; + spl[pos++] = samples[i]; if (pos == 160) { call_tx_audio(bnetz->callref, spl, 160); pos = 0; @@ -308,7 +303,7 @@ void sender_receive(sender_t *sender, int16_t *samples, int length) bnetz->sender.rxbuf_pos = 0; } -static void fsk_tone(bnetz_t *bnetz, int16_t *samples, int length, int tone) +static void fsk_tone(bnetz_t *bnetz, sample_t *samples, int length, int tone) { double phaseshift, phase; int i; @@ -326,9 +321,9 @@ static void fsk_tone(bnetz_t *bnetz, int16_t *samples, int length, int tone) bnetz->phase256 = phase; } -static int fsk_telegramm(bnetz_t *bnetz, int16_t *samples, int length) +static int fsk_telegramm(bnetz_t *bnetz, sample_t *samples, int length) { - int16_t *spl; + sample_t *spl; const char *telegramm; int i, j; double phaseshift, phase; @@ -382,7 +377,7 @@ next_telegramm: } /* Provide stream of audio toward radio unit */ -void sender_send(sender_t *sender, int16_t *samples, int length) +void sender_send(sender_t *sender, sample_t *samples, int length) { bnetz_t *bnetz = (bnetz_t *) sender; int len; diff --git a/src/bnetz/main.c b/src/bnetz/main.c index e8eb47c..c3a5a9b 100644 --- a/src/bnetz/main.c +++ b/src/bnetz/main.c @@ -22,6 +22,7 @@ #include #include #include +#include "../common/sample.h" #include "../common/debug.h" #include "../common/timer.h" #include "../common/call.h" diff --git a/src/cnetz/cnetz.c b/src/cnetz/cnetz.c index 71795da..c811ba7 100644 --- a/src/cnetz/cnetz.c +++ b/src/cnetz/cnetz.c @@ -129,6 +129,7 @@ #include #include #include +#include "../common/sample.h" #include "../common/debug.h" #include "../common/timer.h" #include "../common/call.h" @@ -428,7 +429,7 @@ static void cnetz_release(transaction_t *trans, uint8_t cause) } /* Receive audio from call instance. */ -void call_rx_audio(int callref, int16_t *samples, int count) +void call_rx_audio(int callref, sample_t *samples, int count) { sender_t *sender; cnetz_t *cnetz; diff --git a/src/cnetz/cnetz.h b/src/cnetz/cnetz.h index 5897735..7dda4d3 100644 --- a/src/cnetz/cnetz.h +++ b/src/cnetz/cnetz.h @@ -85,12 +85,12 @@ typedef struct cnetz { /* dsp states */ enum dsp_mode dsp_mode; /* current mode: audio, "Telegramm", .... */ fsk_fm_demod_t fsk_demod; /* demod process */ - int16_t fsk_deviation; /* deviation of FSK signal on sound card */ - int16_t fsk_ramp_up[256]; /* samples of upward ramp shape */ - int16_t fsk_ramp_down[256]; /* samples of downward ramp shape */ + double fsk_deviation; /* deviation of FSK signal on sound card */ + sample_t fsk_ramp_up[256]; /* samples of upward ramp shape */ + sample_t fsk_ramp_down[256]; /* samples of downward ramp shape */ double fsk_noise; /* send static between OgK frames */ double fsk_bitduration; /* duration of a bit in samples */ - int16_t *fsk_tx_buffer; /* tx buffer for one data block */ + sample_t *fsk_tx_buffer; /* tx buffer for one data block */ int fsk_tx_buffer_size; /* size of tx buffer (in samples) */ int fsk_tx_buffer_length; /* usage of buffer (in samples) */ int fsk_tx_buffer_pos; /* current position sending buffer */ @@ -98,7 +98,7 @@ typedef struct cnetz { double fsk_tx_phase; /* current bit position */ uint64_t fsk_tx_scount; /* sample counter (used to sync multiple channels) */ int scrambler; /* 0 = normal speech, 1 = scrambled speech */ - int16_t *dsp_speech_buffer; /* samples in one chunk */ + sample_t *dsp_speech_buffer; /* samples in one chunk */ int dsp_speech_length; /* number of samples */ int dsp_speech_pos; /* current position in buffer */ diff --git a/src/cnetz/database.c b/src/cnetz/database.c index 5bfc4b0..5302035 100644 --- a/src/cnetz/database.c +++ b/src/cnetz/database.c @@ -21,6 +21,7 @@ #include #include #include +#include "../common/sample.h" #include "../common/debug.h" #include "../common/timer.h" #include "cnetz.h" diff --git a/src/cnetz/dsp.c b/src/cnetz/dsp.c index d3a3c69..d104e13 100644 --- a/src/cnetz/dsp.c +++ b/src/cnetz/dsp.c @@ -25,6 +25,7 @@ #include #include #include +#include "../common/sample.h" #include "../common/debug.h" #include "../common/timer.h" #include "../common/call.h" @@ -55,7 +56,7 @@ scrambler_t scrambler_test_scrambler1; scrambler_t scrambler_test_scrambler2; #endif -static int16_t ramp_up[256], ramp_down[256]; +static sample_t ramp_up[256], ramp_down[256]; void dsp_init(void) { @@ -110,7 +111,7 @@ int dsp_init_sender(cnetz_t *cnetz, int measure_speed, double clock_speed[2], do size = cnetz->fsk_bitduration * (double)BLOCK_BITS * 16.0; /* 16 blocks for distributed frames */ cnetz->fsk_tx_buffer_size = size * 1.1; /* more to compensate clock speed */ - cnetz->fsk_tx_buffer = calloc(sizeof(int16_t), cnetz->fsk_tx_buffer_size); + cnetz->fsk_tx_buffer = calloc(sizeof(sample_t), cnetz->fsk_tx_buffer_size); if (!cnetz->fsk_tx_buffer) { PDEBUG(DDSP, DEBUG_DEBUG, "No memory!\n"); rc = -ENOMEM; @@ -123,7 +124,7 @@ int dsp_init_sender(cnetz_t *cnetz, int measure_speed, double clock_speed[2], do cnetz->fsk_noise = noise; /* create speech buffer */ - cnetz->dsp_speech_buffer = calloc(sizeof(int16_t), cnetz->sender.samplerate); /* buffer is greater than sr/1.1, just to be secure */ + cnetz->dsp_speech_buffer = calloc(sizeof(sample_t), cnetz->sender.samplerate); /* buffer is greater than sr/1.1, just to be secure */ if (!cnetz->dsp_speech_buffer) { PDEBUG(DDSP, DEBUG_DEBUG, "No memory!\n"); rc = -ENOMEM; @@ -242,7 +243,7 @@ void calc_clock_speed(cnetz_t *cnetz, uint64_t samples, int tx, int result) static int fsk_testtone_encode(cnetz_t *cnetz) { - int16_t *spl; + sample_t *spl; double phase, bitstep; int i, count; @@ -275,7 +276,7 @@ static int fsk_testtone_encode(cnetz_t *cnetz) static int fsk_nothing_encode(cnetz_t *cnetz) { - int16_t *spl; + sample_t *spl; double phase, bitstep, r; int i, count; @@ -288,7 +289,7 @@ static int fsk_nothing_encode(cnetz_t *cnetz) /* add 198 bits of noise */ for (i = 0; i < 198; i++) { do { - *spl++ = (double)((int16_t)(random() & 0xffff)) * r; + *spl++ = (double)((int16_t)random()) * r / 32768.0; phase += bitstep; } while (phase < 256.0); phase -= 256.0; @@ -320,7 +321,7 @@ static int fsk_nothing_encode(cnetz_t *cnetz) static int fsk_block_encode(cnetz_t *cnetz, const char *bits) { /* alloc samples, add 1 in case there is a rest */ - int16_t *spl; + sample_t *spl; double phase, bitstep, deviation; int i, count; char last; @@ -437,7 +438,7 @@ static int fsk_block_encode(cnetz_t *cnetz, const char *bits) static int fsk_distributed_encode(cnetz_t *cnetz, const char *bits) { /* alloc samples, add 1 in case there is a rest */ - int16_t *spl, *marker; + sample_t *spl, *marker; double phase, bitstep, deviation; int i, j, count; char last; @@ -570,7 +571,7 @@ static int fsk_distributed_encode(cnetz_t *cnetz, const char *bits) /* decode samples and hut for bit changes * use deviation to find greatest slope of the signal (bit change) */ -void sender_receive(sender_t *sender, int16_t *samples, int length) +void sender_receive(sender_t *sender, sample_t *samples, int length) { cnetz_t *cnetz = (cnetz_t *) sender; @@ -590,10 +591,10 @@ void sender_receive(sender_t *sender, int16_t *samples, int length) return; } -static int fsk_telegramm(cnetz_t *cnetz, int16_t *samples, int length) +static int fsk_telegramm(cnetz_t *cnetz, sample_t *samples, int length) { int count = 0, pos, copy, i, speech_length, speech_pos; - int16_t *spl, *speech_buffer; + sample_t *spl, *speech_buffer; const char *bits; speech_buffer = cnetz->dsp_speech_buffer; @@ -756,7 +757,7 @@ again: } /* Provide stream of audio toward radio unit */ -void sender_send(sender_t *sender, int16_t *samples, int length) +void sender_send(sender_t *sender, sample_t *samples, int length) { cnetz_t *cnetz = (cnetz_t *) sender; int count; @@ -780,10 +781,9 @@ void sender_send(sender_t *sender, int16_t *samples, int length) } /* unshrink audio segment from the duration of 60 bits to 12.5 ms */ -void unshrink_speech(cnetz_t *cnetz, int16_t *speech_buffer, int count) +void unshrink_speech(cnetz_t *cnetz, sample_t *speech_buffer, int count) { - int16_t *spl; - int32_t value; + sample_t *spl; int pos, i; double x, y, x_last, y_last, factor; @@ -801,17 +801,12 @@ void unshrink_speech(cnetz_t *cnetz, int16_t *speech_buffer, int count) factor = cnetz->offset_factor; for (i = 0; i < count; i++) { /* change level */ - x = (double)speech_buffer[i] / voice_deviation; + x = speech_buffer[i] / voice_deviation; /* high-pass to remove low level frequencies, caused by level jump between audio chunks */ y = factor * (y_last + x - x_last); x_last = x; y_last = y; - value = (int32_t)y; - if (value < -32768.0) - value = -32768.0; - else if (value > 32767) - value = 32767; - speech_buffer[i] = value; + speech_buffer[i] = y; } cnetz->offset_y_last = y_last; @@ -823,7 +818,7 @@ void unshrink_speech(cnetz_t *cnetz, int16_t *speech_buffer, int count) if (cnetz->scrambler) scrambler(&cnetz->scrambler_rx, speech_buffer, count); /* 2. decompress time */ - count = samplerate_downsample(&cnetz->sender.srstate, speech_buffer, count, speech_buffer); + count = samplerate_downsample(&cnetz->sender.srstate, speech_buffer, count); /* 1. expand dynamics */ expand_audio(&cnetz->cstate, speech_buffer, count); /* to call control */ diff --git a/src/cnetz/dsp.h b/src/cnetz/dsp.h index 7e69b9e..16ea2a7 100644 --- a/src/cnetz/dsp.h +++ b/src/cnetz/dsp.h @@ -3,7 +3,7 @@ void dsp_init(void); int dsp_init_sender(cnetz_t *cnetz, int measure_speed, double clock_speed[2], double noise); void dsp_cleanup_sender(cnetz_t *cnetz); void calc_clock_speed(cnetz_t *cnetz, uint64_t samples, int tx, int result); -void unshrink_speech(cnetz_t *cnetz, int16_t *speech_buffer, int count); +void unshrink_speech(cnetz_t *cnetz, sample_t *speech_buffer, int count); void cnetz_set_dsp_mode(cnetz_t *cnetz, enum dsp_mode mode); void cnetz_set_sched_dsp_mode(cnetz_t *cnetz, enum dsp_mode mode, int frames_ahead); diff --git a/src/cnetz/fsk_fm_demod.c b/src/cnetz/fsk_fm_demod.c index 4d2d7dd..74dd8ab 100644 --- a/src/cnetz/fsk_fm_demod.c +++ b/src/cnetz/fsk_fm_demod.c @@ -105,6 +105,7 @@ #include #include #include +#include "../common/sample.h" #include "../common/timer.h" #include "../common/debug.h" #include "cnetz.h" @@ -330,15 +331,13 @@ got_sync: /* DOC TBD: find change for bit change */ static inline void find_change(fsk_fm_demod_t *fsk) { - int32_t level_min, level_max, change_max; - int change_at, change_positive; - int16_t s, last_s = 0; - int threshold; + sample_t level_min = 0, level_max = 0, change_max = -1; + int change_at = -1, change_positive = -1; + sample_t s, last_s = 0; + sample_t threshold; int i; /* levels at total reverse */ - level_min = 32767; - level_max = -32768; change_max = -1; change_at = -1; change_positive = -1; @@ -359,14 +358,14 @@ static inline void find_change(fsk_fm_demod_t *fsk) change_positive = 0; } } - if (s > level_max) + if (i == 0 || s > level_max) level_max = s; - if (s < level_min) + if (i == 0 || s < level_min) level_min = s; } /* for first bit, we have only half of the modulation deviation, so we divide the threshold by two */ if (fsk->cnetz->dsp_mode == DSP_MODE_SPK_V && fsk->bit_count == 0) - threshold = fsk->level_threshold / 2; + threshold = fsk->level_threshold / 2.0; else threshold = fsk->level_threshold; /* if we are not in sync, for every detected change we set @@ -380,7 +379,7 @@ static inline void find_change(fsk_fm_demod_t *fsk) if (level_max - level_min > threshold && change_at == fsk->bit_buffer_half) { #ifdef DEBUG_DECODER DEBUG_DECODER - printf("receive bit change to %d (level=%d, threshold=%d)\n", change_positive, level_max - level_min, threshold); + printf("receive bit change to %d (level=%.3f, threshold=%.3f)\n", change_positive, level_max - level_min, threshold); #endif fsk->last_change_positive = change_positive; if (!fsk->sync) { @@ -404,7 +403,7 @@ static inline void find_change(fsk_fm_demod_t *fsk) } /* receive FM signal from receiver */ -void fsk_fm_demod(fsk_fm_demod_t *fsk, int16_t *samples, int length) +void fsk_fm_demod(fsk_fm_demod_t *fsk, sample_t *samples, int length) { int i; double t; @@ -418,7 +417,7 @@ void fsk_fm_demod(fsk_fm_demod_t *fsk, int16_t *samples, int length) if (fsk->cnetz->dsp_mode != DSP_MODE_SPK_V) { #ifdef DEBUG_DECODER DEBUG_DECODER - puts(debug_amplitude((double)samples[i] / 32768.0)); + puts(debug_amplitude(samples[i] / 32768.0)); #endif find_change(fsk); } else { @@ -442,7 +441,7 @@ void fsk_fm_demod(fsk_fm_demod_t *fsk, int16_t *samples, int length) if (t >= 0.5 && t < 5.5) { #ifdef DEBUG_DECODER DEBUG_DECODER - puts(debug_amplitude((double)samples[i] / 32768.0)); + puts(debug_amplitude(samples[i] / 32768.0)); #endif find_change(fsk); } else diff --git a/src/cnetz/fsk_fm_demod.h b/src/cnetz/fsk_fm_demod.h index 8f4ce08..bf782e5 100644 --- a/src/cnetz/fsk_fm_demod.h +++ b/src/cnetz/fsk_fm_demod.h @@ -20,7 +20,7 @@ typedef struct fsk_fm_demod { double bit_time_uncorrected; /* same as above, but not corrected by sync */ /* bit detection */ - int16_t *bit_buffer_spl; /* samples ring buffer */ + sample_t *bit_buffer_spl; /* samples ring buffer */ int bit_buffer_len; /* number of samples in ring buffer */ int bit_buffer_half; /* half of ring buffer */ int bit_buffer_pos; /* current position to write next sample */ @@ -35,7 +35,7 @@ typedef struct fsk_fm_demod { double sync_jitter; /* what was the jitter of the sync */ /* speech */ - int16_t *speech_buffer; /* holds one chunk of 12.5ms */ + sample_t *speech_buffer; /* holds one chunk of 12.5ms */ int speech_size; int speech_count; @@ -52,7 +52,7 @@ typedef struct fsk_fm_demod { int fsk_fm_init(fsk_fm_demod_t *fsk, cnetz_t *cnetz, int samplerate, double bitrate); void fsk_fm_exit(fsk_fm_demod_t *fsk); -void fsk_fm_demod(fsk_fm_demod_t *fsk, int16_t *samples, int length); +void fsk_fm_demod(fsk_fm_demod_t *fsk, sample_t *samples, int length); void fsk_correct_sync(fsk_fm_demod_t *fsk, double offset); void fsk_copy_sync(fsk_fm_demod_t *fsk_to, fsk_fm_demod_t *fsk_from); void fsk_demod_reset(fsk_fm_demod_t *fsk); diff --git a/src/cnetz/main.c b/src/cnetz/main.c index 42b4020..9445473 100644 --- a/src/cnetz/main.c +++ b/src/cnetz/main.c @@ -22,6 +22,7 @@ #include #include #include +#include "../common/sample.h" #include "../common/main.h" #include "../common/debug.h" #include "../common/timer.h" diff --git a/src/cnetz/scrambler.c b/src/cnetz/scrambler.c index 2b49335..439e054 100644 --- a/src/cnetz/scrambler.c +++ b/src/cnetz/scrambler.c @@ -19,6 +19,7 @@ #include #include +#include "../common/sample.h" #include "scrambler.h" #define PI M_PI @@ -42,7 +43,8 @@ void scrambler_init(void) int i; for (i = 0; i < 256; i++) { - carrier[i] = sin((double)i / 256.0 * 2 * PI); + /* our amplitude must be doubled, since we have one spectrum above and one below carrier */ + carrier[i] = sin((double)i / 256.0 * 2 * PI) * 2.0; } } @@ -56,10 +58,8 @@ void scrambler_setup(scrambler_t *scrambler, int samplerate) * Then we got spectrum above carrier and mirrored spectrum below carrier. * Afterwards we cut off carrier frequency and frequencies above carrier. */ -void scrambler(scrambler_t *scrambler, int16_t *samples, int length) +void scrambler(scrambler_t *scrambler, sample_t *samples, int length) { - double spl[length]; - int32_t sample; double phaseshift, phase; int i; @@ -68,7 +68,7 @@ void scrambler(scrambler_t *scrambler, int16_t *samples, int length) for (i = 0; i < length; i++) { /* modulate samples to carrier */ - spl[i] = (double)samples[i] / 32768.0 * carrier[((uint8_t)phase) & 0xff]; + samples[i] *= carrier[((uint8_t)phase) & 0xff]; phase += phaseshift; if (phase >= 256.0) phase -= 256.0; @@ -77,17 +77,7 @@ void scrambler(scrambler_t *scrambler, int16_t *samples, int length) scrambler->carrier_phase256 = phase; /* cut off carrier frequency and modulation above carrier frequency */ - filter_process(&scrambler->lp, spl, length); - - for (i = 0; i < length; i++) { - /* store result */ - sample = spl[i] * 2.0 * 32768.0; - if (sample > 32767) - sample = 32767; - else if (sample < -32768) - sample = -32768; - *samples++ = sample; - } + filter_process(&scrambler->lp, samples, length); } diff --git a/src/cnetz/scrambler.h b/src/cnetz/scrambler.h index 0aea77d..ffc2d77 100644 --- a/src/cnetz/scrambler.h +++ b/src/cnetz/scrambler.h @@ -8,5 +8,5 @@ typedef struct scrambler { void scrambler_init(void); void scrambler_setup(scrambler_t *scrambler, int samplerate); -void scrambler(scrambler_t *scrambler, int16_t *samples, int length); +void scrambler(scrambler_t *scrambler, sample_t *samples, int length); diff --git a/src/cnetz/telegramm.c b/src/cnetz/telegramm.c index 09b4461..8edbb2e 100644 --- a/src/cnetz/telegramm.c +++ b/src/cnetz/telegramm.c @@ -26,6 +26,7 @@ #include #include #include +#include "../common/sample.h" #include "../common/debug.h" #include "../common/timer.h" #include "cnetz.h" diff --git a/src/cnetz/transaction.c b/src/cnetz/transaction.c index 8fde1c8..aed8998 100644 --- a/src/cnetz/transaction.c +++ b/src/cnetz/transaction.c @@ -20,6 +20,7 @@ #include #include #include +#include "../common/sample.h" #include "../common/debug.h" #include "../common/timer.h" #include "cnetz.h" diff --git a/src/common/Makefile.am b/src/common/Makefile.am index 8c70533..ce8bba1 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -4,6 +4,7 @@ AM_CPPFLAGS = -Wall -Wextra -g $(all_includes) $(UHD_CFLAGS) noinst_LIBRARIES = libcommon.a libcommon_a_SOURCES = \ + ../common/sample.c \ ../common/debug.c \ ../common/timer.c \ ../common/sound_alsa.c \ diff --git a/src/common/call.c b/src/common/call.c index 72ff516..f816417 100644 --- a/src/common/call.c +++ b/src/common/call.c @@ -24,6 +24,7 @@ #include #include #include +#include "sample.h" #include "debug.h" #include "sender.h" #include "cause.h" @@ -640,8 +641,7 @@ void process_call(int c) return; /* handle audio, if sound device is used */ - - int16_t samples[call.latspl], *spl_list[1]; + sample_t samples[call.latspl + 10], *samples_list[1]; int count; int rc; @@ -653,28 +653,33 @@ void process_call(int c) return; } if (count < call.latspl) { - int16_t up[count + 10]; count = call.latspl - count; + int16_t spl[count + 10]; /* more than enough, count will be reduced by scaling with factor */ switch(call.state) { case CALL_ALERTING: + /* the count will be an approximation that will be upsampled */ count = (int)((double)count / call.srstate.factor + 0.5); - get_call_patterns(samples, count, PATTERN_RINGBACK); - count = samplerate_upsample(&call.srstate, samples, count, up); + get_call_patterns(spl, count, PATTERN_RINGBACK); + int16_to_samples(samples, spl, count); + count = samplerate_upsample(&call.srstate, samples, count, samples); /* prevent click after hangup */ jitter_clear(&call.dejitter); break; case CALL_DISCONNECTED: + /* the count will be an approximation that will be upsampled */ count = (int)((double)count / call.srstate.factor + 0.5); - get_call_patterns(samples, count, cause2pattern(call.disc_cause)); - count = samplerate_upsample(&call.srstate, samples, count, up); + get_call_patterns(spl, count, cause2pattern(call.disc_cause)); + int16_to_samples(samples, spl, count); + count = samplerate_upsample(&call.srstate, samples, count, samples); /* prevent click after hangup */ jitter_clear(&call.dejitter); break; default: - jitter_load(&call.dejitter, up, count); + jitter_load(&call.dejitter, samples, count); } - spl_list[0] = up; - rc = sound_write(call.sound, spl_list, count, NULL, NULL, 1); + samples_to_int16(spl, samples, count); + samples_list[0] = samples; + rc = sound_write(call.sound, samples_list, count, NULL, NULL, 1); if (rc < 0) { PDEBUG(DSENDER, DEBUG_ERROR, "Failed to write TX data to sound device (rc = %d)\n", rc); if (rc == -EPIPE) @@ -682,8 +687,8 @@ void process_call(int c) return; } } - spl_list[0] = samples; - count = sound_read(call.sound, spl_list, call.latspl, 1); + samples_list[0] = samples; + count = sound_read(call.sound, samples_list, call.latspl, 1); if (count < 0) { PDEBUG(DSENDER, DEBUG_ERROR, "Failed to read from sound device (rc = %d)!\n", count); if (count == -EPIPE) @@ -691,12 +696,10 @@ void process_call(int c) return; } if (count) { - int16_t down[count]; /* more than enough */ - if (call.loopback == 3) jitter_save(&call.dejitter, samples, count); - count = samplerate_downsample(&call.srstate, samples, count, down); - call_rx_audio(call.callref, down, count); + count = samplerate_downsample(&call.srstate, samples, count); + call_rx_audio(call.callref, samples, count); } } @@ -899,8 +902,10 @@ void call_in_release(int callref, int cause) } /* forward audio to MNCC or call instance */ -void call_tx_audio(int callref, int16_t *samples, int count) +void call_tx_audio(int callref, sample_t *samples, int count) { + int16_t spl[count]; + if (!callref) return; @@ -915,7 +920,7 @@ void call_tx_audio(int callref, int16_t *samples, int count) /* forward audio */ data->msg_type = ANALOG_8000HZ; data->callref = callref; - memcpy(data->data, samples, count * sizeof(int16_t)); + samples_to_int16((int16_t *)data->data, samples, count); mncc_write(buf, sizeof(buf)); return; @@ -923,13 +928,14 @@ void call_tx_audio(int callref, int16_t *samples, int count) /* save audio from transceiver to jitter buffer */ if (call.sound) { - int16_t up[(int)((double)count * call.srstate.factor + 0.5) + 10]; + sample_t up[(int)((double)count * call.srstate.factor + 0.5) + 10]; count = samplerate_upsample(&call.srstate, samples, count, up); jitter_save(&call.dejitter, up, count); } else /* else, if no sound is used, send test tone to mobile */ if (call.state == CALL_CONNECT) { - get_test_patterns(samples, count); + get_test_patterns(spl, count); + int16_to_samples(samples, spl, count); call_rx_audio(callref, samples, count); } } @@ -966,10 +972,13 @@ void call_mncc_recv(uint8_t *buf, int length) if (mncc->msg_type == ANALOG_8000HZ) { struct gsm_data_frame *data = (struct gsm_data_frame *)buf; int count = (length - sizeof(struct gsm_data_frame)) / 2; + sample_t samples[count]; + /* if we are disconnected, ignore audio */ if (is_process_pattern(data->callref)) return; - call_rx_audio(data->callref, (int16_t *)data->data, count); + int16_to_samples(samples, (int16_t *)data->data, count); + call_rx_audio(data->callref, samples, count); return; } diff --git a/src/common/call.h b/src/common/call.h index 63719f4..fe3a32a 100644 --- a/src/common/call.h +++ b/src/common/call.h @@ -27,8 +27,8 @@ void call_out_disconnect(int callref, int cause); void call_out_release(int callref, int cause); /* send and receive audio */ -void call_rx_audio(int callref, int16_t *samples, int count); -void call_tx_audio(int callref, int16_t *samples, int count); +void call_rx_audio(int callref, sample_t *samples, int count); +void call_tx_audio(int callref, sample_t *samples, int count); /* receive from mncc */ void call_mncc_recv(uint8_t *buf, int length); diff --git a/src/common/compandor.c b/src/common/compandor.c index 9aacbf6..8db2f87 100644 --- a/src/common/compandor.c +++ b/src/common/compandor.c @@ -21,6 +21,7 @@ #include #include #include +#include "sample.h" #include "compandor.h" //#define db2level(db) pow(10, (double)db / 20.0) @@ -64,9 +65,8 @@ void init_compandor(compandor_t *state, int samplerate, double attack_ms, double sqrt_tab[i] = sqrt(i * 0.001); } -void compress_audio(compandor_t *state, int16_t *samples, int num) +void compress_audio(compandor_t *state, sample_t *samples, int num) { - int32_t sample; double value, peak, envelope, step_up, step_down, unaffected; int i; @@ -79,7 +79,7 @@ void compress_audio(compandor_t *state, int16_t *samples, int num) // printf("envelope=%.4f\n", envelope); for (i = 0; i < num; i++) { /* normalize sample value to unaffected level */ - value = (double)(*samples) / unaffected; + value = *samples / unaffected; /* 'peak' is the level that raises directly with the signal * level, but falls with specified recovery rate. */ @@ -100,13 +100,7 @@ void compress_audio(compandor_t *state, int16_t *samples, int num) //if (i > 47000.0 && i < 48144) //printf("time=%.4f envelope=%.4fdb, value=%.4f\n", (double)i/48000.0, 20*log10(envelope), value); - /* convert back from 0 DB level to sample value */ - sample = (int)(value * unaffected); - if (sample > 32767) - sample = 32767; - else if (sample < -32768) - sample = -32768; - *samples++ = sample; + *samples++ = value * unaffected; } //exit(0); @@ -114,9 +108,8 @@ void compress_audio(compandor_t *state, int16_t *samples, int num) state->c.peak = peak; } -void expand_audio(compandor_t *state, int16_t *samples, int num) +void expand_audio(compandor_t *state, sample_t *samples, int num) { - int32_t sample; double value, peak, envelope, step_up, step_down, unaffected; int i; @@ -128,7 +121,7 @@ void expand_audio(compandor_t *state, int16_t *samples, int num) for (i = 0; i < num; i++) { /* normalize sample value to 0 DB level */ - value = (double)(*samples) / unaffected; + value = *samples / unaffected; /* for comments: see compress_audio() */ if (fabs(value) > peak) @@ -144,13 +137,7 @@ void expand_audio(compandor_t *state, int16_t *samples, int num) value = value * envelope; - /* convert back from 0 DB level to sample value */ - sample = (int)(value * unaffected); - if (sample > 32767) - sample = 32767; - else if (sample < -32768) - sample = -32768; - *samples++ = sample; + *samples++ = value * unaffected; } state->e.envelope = envelope; diff --git a/src/common/compandor.h b/src/common/compandor.h index df7dbc2..1d027dd 100644 --- a/src/common/compandor.h +++ b/src/common/compandor.h @@ -16,6 +16,6 @@ typedef struct compandor { } compandor_t; void init_compandor(compandor_t *state, int samplerate, double attack_ms, double recovery_ms, int unaffected_level); -void compress_audio(compandor_t *state, int16_t *samples, int num); -void expand_audio(compandor_t *state, int16_t *samples, int num); +void compress_audio(compandor_t *state, sample_t *samples, int num); +void expand_audio(compandor_t *state, sample_t *samples, int num); diff --git a/src/common/debug.c b/src/common/debug.c index b1b6e5d..e4677e7 100644 --- a/src/common/debug.c +++ b/src/common/debug.c @@ -23,6 +23,7 @@ #include #include #include +#include "sample.h" #include "debug.h" #include "display.h" #include "call.h" diff --git a/src/common/display.h b/src/common/display.h index 2c07bb8..7b1c2e9 100644 --- a/src/common/display.h +++ b/src/common/display.h @@ -6,7 +6,7 @@ typedef struct display_wave { int interval_pos; int interval_max; int offset; - int16_t buffer[MAX_DISPLAY_WIDTH]; + sample_t buffer[MAX_DISPLAY_WIDTH]; } dispwav_t; #define MAX_DISPLAY_IQ 256 @@ -23,7 +23,7 @@ void get_win_size(int *w, int *h); void display_wave_init(sender_t *sender, int samplerate); void display_wave_on(int on); void display_wave_limit_scroll(int on); -void display_wave(sender_t *sender, int16_t *samples, int length); +void display_wave(sender_t *sender, sample_t *samples, int length); void display_iq_init(int samplerate); void display_iq_on(int on); diff --git a/src/common/display_iq.c b/src/common/display_iq.c index 2e1bd52..1d77c56 100644 --- a/src/common/display_iq.c +++ b/src/common/display_iq.c @@ -21,6 +21,7 @@ #include #include #include +#include "sample.h" #include "sender.h" #define DISPLAY_INTERVAL 0.04 diff --git a/src/common/display_wave.c b/src/common/display_wave.c index 677e119..38a74c7 100644 --- a/src/common/display_wave.c +++ b/src/common/display_wave.c @@ -21,6 +21,7 @@ #include #include #include +#include "sample.h" #include "sender.h" #define DISPLAY_INTERVAL 0.04 @@ -112,11 +113,11 @@ void display_wave_limit_scroll(int on) * y is in range of 0..5, so these are 5 steps, where 2 to 2.999 is the * center line. this is calculated by (HEIGHT * 2 - 1) */ -void display_wave(sender_t *sender, int16_t *samples, int length) +void display_wave(sender_t *sender, sample_t *samples, int length) { dispwav_t *disp = &sender->dispwav; int pos, max; - int16_t *buffer; + sample_t *buffer; int i, j, k, y; int color = 9; /* default color */ int center_line; @@ -146,11 +147,10 @@ void display_wave(sender_t *sender, int16_t *samples, int length) if (pos == width) { memset(&screen, ' ', sizeof(screen)); for (j = 0; j < width; j++) { - /* 32767 - buffer[j] never reaches 65536, so - * the result is below HEIGHT * 2 - 1 - */ - y = (32767 - (int)buffer[j]) * (HEIGHT * 2 - 1) / 65536; - screen[y >> 1][j] = (y & 1) ? '_' : '-'; + y = (32767 - (int32_t)buffer[j]) * (HEIGHT * 2 - 1) / 65536; + /* only display level, if it is in range */ + if (y >= 0 && y < HEIGHT * 2) + screen[y >> 1][j] = (y & 1) ? '_' : '-'; } sprintf(screen[0], "(chan %d", sender->kanal); *strchr(screen[0], '\0') = ')'; diff --git a/src/common/dtmf.c b/src/common/dtmf.c index b052fd5..b9870a1 100644 --- a/src/common/dtmf.c +++ b/src/common/dtmf.c @@ -20,6 +20,7 @@ #include #include #include +#include "sample.h" #include "dtmf.h" #define PI M_PI @@ -27,7 +28,7 @@ #define TX_PEAK_DTMF 7000 /* single dtmf tone peak (note this is half to total peak) */ #define DTMF_DURATION 0.100 /* duration in seconds */ -int dsp_sine_dtmf[256]; +static double dsp_sine_dtmf[256]; void dtmf_init(dtmf_t *dtmf, int samplerate) { @@ -75,7 +76,7 @@ void dtmf_set_tone(dtmf_t *dtmf, char tone) } /* Generate audio stream from DTMF tone. Keep phase for next call of function. */ -void dtmf_tone(dtmf_t *dtmf, int16_t *samples, int length) +void dtmf_tone(dtmf_t *dtmf, sample_t *samples, int length) { double *phaseshift, *phase; int i, pos, max; diff --git a/src/common/dtmf.h b/src/common/dtmf.h index a0120db..477affd 100644 --- a/src/common/dtmf.h +++ b/src/common/dtmf.h @@ -10,5 +10,5 @@ typedef struct dtmf { void dtmf_init(dtmf_t *dtmf, int samplerate); void dtmf_set_tone(dtmf_t *dtmf, char tone); -void dtmf_tone(dtmf_t *dtmf, int16_t *samples, int length); +void dtmf_tone(dtmf_t *dtmf, sample_t *samples, int length); diff --git a/src/common/emphasis.c b/src/common/emphasis.c index c4a8242..57273d4 100644 --- a/src/common/emphasis.c +++ b/src/common/emphasis.c @@ -55,9 +55,8 @@ int init_emphasis(emphasis_t *state, int samplerate, double cut_off) return 0; } -void pre_emphasis(emphasis_t *state, int16_t *samples, int num) +void pre_emphasis(emphasis_t *state, double *samples, int num) { - int32_t sample; double x, y, x_last, factor, amp; int i; @@ -66,26 +65,20 @@ void pre_emphasis(emphasis_t *state, int16_t *samples, int num) amp = state->p.amp; for (i = 0; i < num; i++) { - x = (double)(*samples) / 32768.0; + x = *samples / 32768.0; y = x - factor * x_last; x_last = x; - sample = (int)(amp * y * 32768.0); - if (sample > 32767) - sample = 32767; - else if (sample < -32768) - sample = -32768; - *samples++ = sample; + *samples++ = (int)(amp * y * 32768.0); } state->p.x_last = x_last; } -void de_emphasis(emphasis_t *state, int16_t *samples, int num) +void de_emphasis(emphasis_t *state, double *samples, int num) { - int32_t sample; double x, y, z, y_last, z_last, d_factor, h_factor, amp; int i; @@ -96,7 +89,7 @@ void de_emphasis(emphasis_t *state, int16_t *samples, int num) amp = state->d.amp; for (i = 0; i < num; i++) { - x = (double)(*samples) / 32768.0; + x = *samples / 32768.0; /* de-emphasis */ y = x + d_factor * y_last; @@ -107,12 +100,7 @@ void de_emphasis(emphasis_t *state, int16_t *samples, int num) y_last = y; z_last = z; - sample = (int)(amp * z * 32768.0); - if (sample > 32767) - sample = 32767; - else if (sample < -32768) - sample = -32768; - *samples++ = sample; + *samples++ = (int)(amp * z * 32768.0); } state->d.y_last = y_last; diff --git a/src/common/emphasis.h b/src/common/emphasis.h index 8a631e4..39d5246 100644 --- a/src/common/emphasis.h +++ b/src/common/emphasis.h @@ -16,6 +16,6 @@ typedef struct emphasis { #define CUT_OFF_EMPHASIS_DEFAULT 300.0 int init_emphasis(emphasis_t *state, int samplerate, double cut_off); -void pre_emphasis(emphasis_t *state, int16_t *samples, int num); -void de_emphasis(emphasis_t *state, int16_t *samples, int num); +void pre_emphasis(emphasis_t *state, double *samples, int num); +void de_emphasis(emphasis_t *state, double *samples, int num); diff --git a/src/common/goertzel.c b/src/common/goertzel.c index 5a89165..eaa7f99 100644 --- a/src/common/goertzel.c +++ b/src/common/goertzel.c @@ -22,7 +22,8 @@ #include #include #include -#include "../common/debug.h" +#include "sample.h" +#include "debug.h" #include "goertzel.h" /* @@ -30,9 +31,9 @@ */ /* return average value (rectified value), that can be 0..1 */ -double audio_level(int16_t *samples, int length) +double audio_level(sample_t *samples, int length) { - int32_t bias; + double bias; double level; int sk; int n; @@ -57,6 +58,12 @@ double audio_level(int16_t *samples, int length) return level; } +void audio_goertzel_init(goertzel_t *goertzel, double freq, int samplerate) +{ + memset(goertzel, 0, sizeof(*goertzel)); + goertzel->coeff = 2.0 * cos(2.0 * M_PI * freq / (double)samplerate); +} + /* * goertzel filter */ @@ -70,11 +77,11 @@ double audio_level(int16_t *samples, int length) * result: array of result levels (average value of the sine, that is 1 / (PI/2) of the sine's peak) * k: number of frequencies to check */ -void audio_goertzel(int16_t *samples, int length, int offset, int *coeff, double *result, int k) +void audio_goertzel(goertzel_t *goertzel, sample_t *samples, int length, int offset, double *result, int k) { - int32_t bias; - int32_t sk, sk1, sk2; - int64_t cos2pik; + double bias; + double sk, sk1, sk2; + double cos2pik; int i, n; /* calculate bias to remove DC */ @@ -88,10 +95,10 @@ void audio_goertzel(int16_t *samples, int length, int offset, int *coeff, double sk = 0; sk1 = 0; sk2 = 0; - cos2pik = coeff[i]; + cos2pik = goertzel[i].coeff; /* note: after 'length' cycles, offset is restored to its initial value */ for (n = 0; n < length; n++) { - sk = ((cos2pik * sk1) >> 15) - sk2 + samples[offset++] - bias; + sk = (cos2pik * sk1) - sk2 + samples[offset++] - bias; sk2 = sk1; sk1 = sk; if (offset == length) @@ -99,10 +106,10 @@ void audio_goertzel(int16_t *samples, int length, int offset, int *coeff, double } /* compute level of signal */ result[i] = sqrt( - ((double)sk * (double)sk) - - ((double)((cos2pik * sk) >> 15) * (double)sk2) + - ((double)sk2 * (double)sk2) - ) / (double)length / 32767.0 * 2.0 * 0.63662; /* 1 / (PI/2) */ + (sk * sk) - + (cos2pik * sk * sk2) + + (sk2 * sk2) + ) / (double)length * 2.0 * 0.63662; /* 1 / (PI/2) */ } } diff --git a/src/common/goertzel.h b/src/common/goertzel.h index 7feba16..58fcbb8 100644 --- a/src/common/goertzel.h +++ b/src/common/goertzel.h @@ -1,5 +1,10 @@ -double audio_level(int16_t *samples, int length); +double audio_level(sample_t *samples, int length); -void audio_goertzel(int16_t *samples, int length, int offset, int *coeff, double *result, int k); +typedef struct goertzel { + double coeff; +} goertzel_t; + +void audio_goertzel_init(goertzel_t *goertzel, double freq, int samplerate); +void audio_goertzel(goertzel_t *goertzel, sample_t *samples, int length, int offset, double *result, int k); diff --git a/src/common/jitter.c b/src/common/jitter.c index 9f171a0..865438b 100644 --- a/src/common/jitter.c +++ b/src/common/jitter.c @@ -22,14 +22,15 @@ #include #include #include -#include "../common/debug.h" +#include "sample.h" +#include "debug.h" #include "jitter.h" /* create jitter buffer */ int jitter_create(jitter_t *jitter, int length) { memset(jitter, 0, sizeof(*jitter)); - jitter->spl = calloc(length * sizeof(int16_t), 1); + jitter->spl = calloc(length * sizeof(sample_t), 1); if (!jitter->spl) { PDEBUG(DDSP, DEBUG_ERROR, "No memory for jitter buffer.\n"); return -ENOMEM; @@ -51,9 +52,9 @@ void jitter_destroy(jitter_t *jitter) * * stop if buffer is completely filled */ -void jitter_save(jitter_t *jb, int16_t *samples, int length) +void jitter_save(jitter_t *jb, sample_t *samples, int length) { - int16_t *spl; + sample_t *spl; int inptr, outptr, len, space; int i; @@ -76,9 +77,9 @@ void jitter_save(jitter_t *jb, int16_t *samples, int length) /* get audio from jitterbuffer */ -void jitter_load(jitter_t *jb, int16_t *samples, int length) +void jitter_load(jitter_t *jb, sample_t *samples, int length) { - int16_t *spl; + sample_t *spl; int inptr, outptr, len, fill; int i, ii; diff --git a/src/common/jitter.h b/src/common/jitter.h index 6d8d432..658da19 100644 --- a/src/common/jitter.h +++ b/src/common/jitter.h @@ -1,13 +1,13 @@ typedef struct jitter { - int16_t *spl; /* pointer to sample buffer */ + sample_t *spl; /* pointer to sample buffer */ int len; /* buffer size: number of samples */ int inptr, outptr; /* write pointer and read pointer */ } jitter_t; int jitter_create(jitter_t *jitter, int length); void jitter_destroy(jitter_t *jitter); -void jitter_save(jitter_t *jb, int16_t *samples, int length); -void jitter_load(jitter_t *jb, int16_t *samples, int length); +void jitter_save(jitter_t *jb, sample_t *samples, int length); +void jitter_load(jitter_t *jb, sample_t *samples, int length); void jitter_clear(jitter_t *jb); diff --git a/src/common/main_common.c b/src/common/main_common.c index b11d497..7a0cd52 100644 --- a/src/common/main_common.c +++ b/src/common/main_common.c @@ -27,6 +27,7 @@ #include #include #include +#include "sample.h" #include "main.h" #include "debug.h" #include "sender.h" diff --git a/src/common/mncc_sock.c b/src/common/mncc_sock.c index 1a2c5ae..437dec1 100644 --- a/src/common/mncc_sock.c +++ b/src/common/mncc_sock.c @@ -26,7 +26,8 @@ #include #include #include -#include "../common/debug.h" +#include "sample.h" +#include "debug.h" #include "call.h" #include "mncc_sock.h" diff --git a/src/common/sample.c b/src/common/sample.c new file mode 100644 index 0000000..107c8e0 --- /dev/null +++ b/src/common/sample.c @@ -0,0 +1,27 @@ + +#include +#include "sample.h" + +void samples_to_int16(int16_t *spl, sample_t *samples, int length) +{ + while (length--) { + if (*samples > 32767.0) + *spl = 32767; + else if (*samples < -32767.0) + *spl = -32767; + else + *spl = (uint16_t)(*samples); + samples++; + spl++; + } +} + +void int16_to_samples(sample_t *samples, int16_t *spl, int length) +{ + while (length--) { + *samples = (double)(*spl); + samples++; + spl++; + } +} + diff --git a/src/common/sample.h b/src/common/sample.h new file mode 100644 index 0000000..fb578eb --- /dev/null +++ b/src/common/sample.h @@ -0,0 +1,6 @@ + +typedef double sample_t; + +void samples_to_int16(int16_t *spl, sample_t *samples, int length); +void int16_to_samples(sample_t *samples, int16_t *spl, int length); + diff --git a/src/common/samplerate.c b/src/common/samplerate.c index f554cf0..18e039e 100644 --- a/src/common/samplerate.c +++ b/src/common/samplerate.c @@ -22,6 +22,7 @@ #include #include #include +#include "sample.h" #include "samplerate.h" /* NOTE: This is quick and dirtry. */ @@ -44,19 +45,13 @@ int init_samplerate(samplerate_t *state, double samplerate) } /* convert input sample rate to 8000 Hz */ -int samplerate_downsample(samplerate_t *state, int16_t *input, int input_num, int16_t *output) +int samplerate_downsample(samplerate_t *state, sample_t *samples, int input_num) { int output_num = 0, i, idx; double factor = state->factor, in_index; - double spl[input_num]; - int32_t value; - - /* convert samples to double */ - for (i = 0; i < input_num; i++) - spl[i] = *input++ / 32768.0; /* filter down */ - filter_process(&state->down.lp, spl, input_num); + filter_process(&state->down.lp, samples, input_num); /* resample filtered result */ in_index = state->down.in_index; @@ -68,12 +63,7 @@ int samplerate_downsample(samplerate_t *state, int16_t *input, int input_num, in if (idx >= input_num) break; /* copy value from input to output */ - value = spl[idx] * 32768.0; - if (value < -32768) - value = -32768; - else if (value > 32767) - value = 32767; - *output++ = value; + samples[i] = samples[idx]; /* count output number */ output_num++; /* increment input index */ @@ -92,12 +82,17 @@ int samplerate_downsample(samplerate_t *state, int16_t *input, int input_num, in } /* convert 8000 Hz sample rate to output sample rate */ -int samplerate_upsample(samplerate_t *state, int16_t *input, int input_num, int16_t *output) +int samplerate_upsample(samplerate_t *state, sample_t *input, int input_num, sample_t *output) { int output_num = 0, i, idx; double factor = 1.0 / state->factor, in_index; - double spl[(int)((double)input_num / factor + 0.5) + 10]; /* add some fafety */ - int32_t value; + sample_t buff[(int)((double)input_num / factor + 0.5) + 10]; /* add some fafety */ + sample_t *samples; + + if (input == output) + samples = buff; + else + samples = output; /* resample input */ in_index = state->up.in_index; @@ -109,7 +104,7 @@ int samplerate_upsample(samplerate_t *state, int16_t *input, int input_num, int1 if (idx >= input_num) break; /* copy value */ - spl[i] = input[idx] / 32768.0; + samples[i] = input[idx]; /* count output number */ output_num++; /* increment input index */ @@ -125,16 +120,12 @@ int samplerate_upsample(samplerate_t *state, int16_t *input, int input_num, int1 state->up.in_index = in_index; /* filter up */ - filter_process(&state->up.lp, spl, output_num); - - /* convert double to samples */ - for (i = 0; i < output_num; i++) { - value = spl[i] * 32768.0; - if (value < -32768) - value = -32768; - else if (value > 32767) - value = 32767; - *output++ = value; + filter_process(&state->up.lp, samples, output_num); + + if (input == output) { + /* copy samples */ + for (i = 0; i < input_num; i++) + *output++ = samples[i]; } return output_num; diff --git a/src/common/samplerate.h b/src/common/samplerate.h index d8c9d41..9efe3b1 100644 --- a/src/common/samplerate.h +++ b/src/common/samplerate.h @@ -13,5 +13,5 @@ typedef struct samplerate { } samplerate_t; int init_samplerate(samplerate_t *state, double samplerate); -int samplerate_downsample(samplerate_t *state, int16_t *input, int input_num, int16_t *output); -int samplerate_upsample(samplerate_t *state, int16_t *input, int input_num, int16_t *output); +int samplerate_downsample(samplerate_t *state, sample_t *samples, int input_num); +int samplerate_upsample(samplerate_t *state, sample_t *input, int input_num, sample_t *output); diff --git a/src/common/sdr.c b/src/common/sdr.c index db46906..77b31a6 100644 --- a/src/common/sdr.c +++ b/src/common/sdr.c @@ -22,6 +22,7 @@ #include #include #include +#include "sample.h" #include "filter.h" #include "sender.h" #ifdef HAVE_UHD @@ -241,7 +242,7 @@ void sdr_close(void *inst) } } -int sdr_write(void *inst, int16_t **samples, int num, enum paging_signal __attribute__((unused)) *paging_signal, int *on, int channels) +int sdr_write(void *inst, sample_t **samples, int num, enum paging_signal __attribute__((unused)) *paging_signal, int *on, int channels) { sdr_t *sdr = (sdr_t *)inst; float buff[num * 2]; @@ -291,19 +292,19 @@ int sdr_write(void *inst, int16_t **samples, int num, enum paging_signal __attri } if (sdr->wave_tx_rec.fp) { - int16_t spl[2][num], *spl_list[2] = { spl[0], spl[1] }; + sample_t spl[2][num], *spl_list[2] = { spl[0], spl[1] }; for (s = 0, ss = 0; s < num; s++) { if (buff[ss] >= 1.0) - spl[0][s] = 32767; + spl[0][s] = 32767.0; else if (buff[ss] <= -1.0) - spl[0][s] = -32767; + spl[0][s] = -32767.0; else spl[0][s] = 32767.0 * buff[ss]; ss++; if (buff[ss] >= 1.0) - spl[1][s] = 32767; + spl[1][s] = 32767.0; else if (buff[ss] <= -1.0) - spl[1][s] = -32767; + spl[1][s] = -32767.0; else spl[1][s] = 32767.0 * buff[ss]; ss++; @@ -320,14 +321,14 @@ int sdr_write(void *inst, int16_t **samples, int num, enum paging_signal __attri return sent; } -int sdr_read(void *inst, int16_t **samples, int num, int channels) +int sdr_read(void *inst, sample_t **samples, int num, int channels) { sdr_t *sdr = (sdr_t *)inst; float buff[num * 2]; double I[num], Q[num], i, q; int count; int c, s, ss; - double phase, rot, last_phase, spl, dev, rate; + double phase, rot, last_phase, dev, rate; rate = sdr->samplerate; @@ -338,19 +339,19 @@ int sdr_read(void *inst, int16_t **samples, int num, int channels) return count; if (sdr->wave_rx_rec.fp) { - int16_t spl[2][count], *spl_list[2] = { spl[0], spl[1] }; + sample_t spl[2][count], *spl_list[2] = { spl[0], spl[1] }; for (s = 0, ss = 0; s < count; s++) { if (buff[ss] >= 1.0) - spl[0][s] = 32767; + spl[0][s] = 32767.0; else if (buff[ss] <= -1.0) - spl[0][s] = -32767; + spl[0][s] = -32767.0; else spl[0][s] = 32767.0 * buff[ss]; ss++; if (buff[ss] >= 1.0) - spl[1][s] = 32767; + spl[1][s] = 32767.0; else if (buff[ss] <= -1.0) - spl[1][s] = -32767; + spl[1][s] = -32767.0; else spl[1][s] = 32767.0 * buff[ss]; ss++; @@ -358,11 +359,11 @@ int sdr_read(void *inst, int16_t **samples, int num, int channels) wave_write(&sdr->wave_rx_rec, spl_list, count); } if (sdr->wave_rx_play.fp) { - int16_t spl[2][count], *spl_list[2] = { spl[0], spl[1] }; + sample_t spl[2][count], *spl_list[2] = { spl[0], spl[1] }; wave_read(&sdr->wave_rx_play, spl_list, count); for (s = 0, ss = 0; s < count; s++) { - buff[ss++] = (double)spl[0][s] / 32767.0; - buff[ss++] = (double)spl[1][s] / 32767.0; + buff[ss++] = spl[0][s] / 32767.0; + buff[ss++] = spl[1][s] / 32767.0; } } display_iq(buff, count); @@ -390,12 +391,7 @@ int sdr_read(void *inst, int16_t **samples, int num, int channels) else if (dev > 0.49) dev -= 1.0; dev *= rate; - spl = dev / sdr->spl_deviation; - if (spl > 32766.0) - spl = 32766.0; - else if (spl < -32766.0) - spl = -32766.0; - samples[c][s] = spl; + samples[c][s] = dev / sdr->spl_deviation; } sdr->chan[c].rx_last_phase = last_phase; } diff --git a/src/common/sdr.h b/src/common/sdr.h index 8ccd56a..5495de6 100644 --- a/src/common/sdr.h +++ b/src/common/sdr.h @@ -2,7 +2,7 @@ int sdr_init(const char *device_args, double rx_gain, double tx_gain, const char *write_iq_rx_wave, const char *write_iq_tx_wave, const char *read_iq_rx_wave); void *sdr_open(const char *audiodev, double *tx_frequency, double *rx_frequency, int channels, double paging_frequency, int samplerate, double bandwidth, double sample_deviation); void sdr_close(void *inst); -int sdr_write(void *inst, int16_t **samples, int num, enum paging_signal *paging_signal, int *on, int channels); -int sdr_read(void *inst, int16_t **samples, int num, int channels); +int sdr_write(void *inst, sample_t **samples, int num, enum paging_signal *paging_signal, int *on, int channels); +int sdr_read(void *inst, sample_t **samples, int num, int channels); int sdr_get_inbuffer(void *inst); diff --git a/src/common/sender.c b/src/common/sender.c index 21aae70..f63e021 100644 --- a/src/common/sender.c +++ b/src/common/sender.c @@ -24,6 +24,7 @@ #include #include #include +#include "sample.h" #include "debug.h" #include "sender.h" @@ -224,19 +225,12 @@ void sender_destroy(sender_t *sender) jitter_destroy(&sender->dejitter); } -static void gain_samples(int16_t *samples, int length, double gain) +static void gain_samples(sample_t *samples, int length, double gain) { int i; - int32_t sample; - - for (i = 0; i < length; i++) { - sample = (int32_t)((double)(*samples) * gain); - if (sample > 32767) - sample = 32767; - else if (sample < -32768) - sample = -32768; - *samples++ = sample; - } + + for (i = 0; i < length; i++) + *samples++ *= gain; } /* Handle audio streaming of one transceiver. */ @@ -248,7 +242,7 @@ void process_sender_audio(sender_t *sender, int *quit, int latspl) /* count instances for audio channel */ for (num_chan = 0, inst = sender; inst; num_chan++, inst = inst->slave); - int16_t buff[num_chan][latspl], *samples[num_chan]; + sample_t buff[num_chan][latspl], *samples[num_chan]; enum paging_signal paging_signal[num_chan]; int on[num_chan]; for (i = 0; i < num_chan; i++) { diff --git a/src/common/sender.h b/src/common/sender.h index 12f30ab..1af6be1 100644 --- a/src/common/sender.h +++ b/src/common/sender.h @@ -39,8 +39,8 @@ typedef struct sender { char audiodev[64]; /* audio device name (alsa or sdr) */ void *(*audio_open)(const char *, double *, double *, int, double, int, double, double); void (*audio_close)(void *); - int (*audio_write)(void *, int16_t **, int, enum paging_signal *, int *, int); - int (*audio_read)(void *, int16_t **, int, int); + int (*audio_write)(void *, sample_t **, int, enum paging_signal *, int *, int); + int (*audio_read)(void *, sample_t **, int, int); int (*audio_get_inbuffer)(void *); int samplerate; samplerate_t srstate; /* sample rate conversion state */ @@ -64,7 +64,7 @@ typedef struct sender { jitter_t dejitter; /* audio buffer for audio to send to caller (20ms = 160 samples @ 8000Hz) */ - int16_t rxbuf[160]; + sample_t rxbuf[160]; int rxbuf_pos; /* current fill of buffer */ /* loss of carrier detection */ @@ -87,7 +87,7 @@ int sender_create(sender_t *sender, int kanal, double sendefrequenz, double empf void sender_destroy(sender_t *sender); int sender_open_audio(void); 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 sender_send(sender_t *sender, sample_t *samples, int count); +void sender_receive(sender_t *sender, sample_t *samples, int count); void sender_paging(sender_t *sender, int on); diff --git a/src/common/sound.h b/src/common/sound.h index a352f06..607e1f5 100644 --- a/src/common/sound.h +++ b/src/common/sound.h @@ -3,7 +3,7 @@ enum paging_signal; void *sound_open(const char *audiodev, double *tx_frequency, double *rx_frequency, int channels, double paging_frequency, int samplerate, double bandwidth, double sample_deviation); void sound_close(void *inst); -int sound_write(void *inst, int16_t **samples, int num, enum paging_signal *paging_signal, int *on, int channels); -int sound_read(void *inst, int16_t **samples, int num, int channels); +int sound_write(void *inst, sample_t **samples, int num, enum paging_signal *paging_signal, int *on, int channels); +int sound_read(void *inst, sample_t **samples, int num, int channels); int sound_get_inbuffer(void *inst); diff --git a/src/common/sound_alsa.c b/src/common/sound_alsa.c index 4eef893..efc93de 100644 --- a/src/common/sound_alsa.c +++ b/src/common/sound_alsa.c @@ -20,6 +20,7 @@ #include #include #include +#include "sample.h" #include "debug.h" #include "sender.h" @@ -248,35 +249,66 @@ static void gen_paging_tone(sound_t *sound, int16_t *samples, int length, enum p } } -int sound_write(void *inst, int16_t **samples, int num, enum paging_signal *paging_signal, int *on, int channels) +int sound_write(void *inst, sample_t **samples, int num, enum paging_signal *paging_signal, int *on, int channels) { sound_t *sound = (sound_t *)inst; + int32_t value; int16_t buff[num << 1]; int rc; int i, ii; if (sound->pchannels == 2) { + /* two channels */ if (paging_signal && on && paging_signal[0] != PAGING_SIGNAL_NONE) { int16_t paging[num << 1]; gen_paging_tone(sound, paging, num, paging_signal[0], on[0]); for (i = 0, ii = 0; i < num; i++) { - buff[ii++] = samples[0][i]; + value = samples[0][i]; + if (value > 32767) + value = 32767; + else if (value < -32767) + value = -32767; + buff[ii++] = value; buff[ii++] = paging[i]; } } else if (channels == 2) { for (i = 0, ii = 0; i < num; i++) { - buff[ii++] = samples[0][i]; - buff[ii++] = samples[1][i]; + value = samples[0][i]; + if (value > 32767) + value = 32767; + else if (value < -32767) + value = -32767; + buff[ii++] = value; + value = samples[1][i]; + if (value > 32767) + value = 32767; + else if (value < -32767) + value = -32767; + buff[ii++] = value; } } else { for (i = 0, ii = 0; i < num; i++) { - buff[ii++] = samples[0][i]; - buff[ii++] = samples[0][i]; + value = samples[0][i]; + if (value > 32767) + value = 32767; + else if (value < -32767) + value = -32767; + buff[ii++] = value; + buff[ii++] = value; } } - rc = snd_pcm_writei(sound->phandle, buff, num); - } else - rc = snd_pcm_writei(sound->phandle, samples[0], num); + } else { + /* one channel */ + for (i = 0, ii = 0; i < num; i++) { + value = samples[0][i]; + if (value > 32767) + value = 32767; + else if (value < -32767) + value = -32767; + buff[ii++] = value; + } + } + rc = snd_pcm_writei(sound->phandle, buff, num); if (rc < 0) { PDEBUG(DSOUND, DEBUG_ERROR, "failed to write audio to interface (%s)\n", snd_strerror(rc)); @@ -293,7 +325,7 @@ int sound_write(void *inst, int16_t **samples, int num, enum paging_signal *pagi #define KEEP_FRAMES 8 /* minimum frames not to read, due to bug in ALSA */ -int sound_read(void *inst, int16_t **samples, int num, int channels) +int sound_read(void *inst, sample_t **samples, int num, int channels) { sound_t *sound = (sound_t *)inst; int16_t buff[num << 1]; @@ -312,10 +344,7 @@ int sound_read(void *inst, int16_t **samples, int num, int channels) if (in > num) in = num; - if (sound->cchannels == 2) - rc = snd_pcm_readi(sound->chandle, buff, in); - else - rc = snd_pcm_readi(sound->chandle, samples[0], in); + rc = snd_pcm_readi(sound->chandle, buff, in); if (rc < 0) { if (errno == EAGAIN) @@ -332,18 +361,18 @@ int sound_read(void *inst, int16_t **samples, int num, int channels) for (i = 0, ii = 0; i < rc; i++) { spl = buff[ii++]; spl += buff[ii++]; - if (spl > 32767) - spl = 32767; - else if (spl < -32768) - spl = -32768; - samples[0][i] = spl; + samples[0][i] = (sample_t)spl; } } else { for (i = 0, ii = 0; i < rc; i++) { - samples[0][i] = buff[ii++]; - samples[1][i] = buff[ii++]; + samples[0][i] = (sample_t)buff[ii++]; + samples[1][i] = (sample_t)buff[ii++]; } } + } else { + for (i = 0, ii = 0; i < rc; i++) { + samples[0][i] = (sample_t)buff[ii++]; + } } return rc; diff --git a/src/common/uhd.c b/src/common/uhd.c index baf3249..8437e3b 100644 --- a/src/common/uhd.c +++ b/src/common/uhd.c @@ -54,9 +54,6 @@ int uhd_open(const char *device_args, double tx_frequency, double rx_frequency, samplerate = rate; check_rate = 1; -#warning HACK -if (tx_frequency < 200000000) tx_frequency = 463000000, rx_frequency = 463000000; - /* create USRP */ PDEBUG(DUHD, DEBUG_INFO, "Creating USRP with args \"%s\"...\n", device_args); error = uhd_usrp_make(&usrp, device_args); diff --git a/src/common/wave.c b/src/common/wave.c index 097ecc0..804fd5a 100644 --- a/src/common/wave.c +++ b/src/common/wave.c @@ -22,6 +22,7 @@ #include #include #include +#include "sample.h" #include "wave.h" struct fmt { @@ -193,7 +194,7 @@ error: return rc; } -int wave_read(wave_play_t *play, int16_t **samples, int length) +int wave_read(wave_play_t *play, sample_t **samples, int length) { uint8_t buff[2 * length * play->channels]; int __attribute__((__unused__)) len; @@ -201,7 +202,7 @@ int wave_read(wave_play_t *play, int16_t **samples, int length) if (length > (int)play->left) { for (c = 0; c < play->channels; c++) - memset(samples[c], 0, 2 * length); + memset(samples[c], 0, sizeof(samples[c][0] * length)); length = play->left; } if (!length) @@ -215,7 +216,7 @@ int wave_read(wave_play_t *play, int16_t **samples, int length) len = fread(buff, 1, 2 * length * play->channels, play->fp); for (i = 0, j = 0; i < length; i++) { for (c = 0; c < play->channels; c++) { - samples[c][i] = buff[j] + (buff[j + 1] << 8); + samples[c][i] = (double)(buff[j] + (buff[j + 1] << 8)); j += 2; } } @@ -223,8 +224,9 @@ int wave_read(wave_play_t *play, int16_t **samples, int length) return length; } -int wave_write(wave_rec_t *rec, int16_t **samples, int length) +int wave_write(wave_rec_t *rec, sample_t **samples, int length) { + int32_t value; uint8_t buff[2 * length * rec->channels]; int __attribute__((__unused__)) len; int i, j, c; @@ -232,8 +234,13 @@ int wave_write(wave_rec_t *rec, int16_t **samples, int length) /* write and correct endiness */ for (i = 0, j = 0; i < length; i++) { for (c = 0; c < rec->channels; c++) { - buff[j++] = samples[c][i]; - buff[j++] = samples[c][i] >> 8; + value = samples[c][i]; + if (value > 32767) + value = 32767; + else if (value < -32767) + value = -32767; + buff[j++] = value; + buff[j++] = value >> 8; } } len = fwrite(buff, 1, 2 * length * rec->channels, rec->fp); diff --git a/src/common/wave.h b/src/common/wave.h index 3c7aa48..59c1db8 100644 --- a/src/common/wave.h +++ b/src/common/wave.h @@ -14,8 +14,8 @@ typedef struct wave_play { int wave_create_record(wave_rec_t *rec, const char *filename, int samplerate, int channels); int wave_create_playback(wave_play_t *play, const char *filename, int samplerate, int channels); -int wave_read(wave_play_t *play, int16_t **samples, int length); -int wave_write(wave_rec_t *rec, int16_t **samples, int length); +int wave_read(wave_play_t *play, sample_t **samples, int length); +int wave_write(wave_rec_t *rec, sample_t **samples, int length); void wave_destroy_record(wave_rec_t *rec); void wave_destroy_playback(wave_play_t *play); diff --git a/src/nmt/dms.c b/src/nmt/dms.c index 1027e34..2fcaf3c 100644 --- a/src/nmt/dms.c +++ b/src/nmt/dms.c @@ -21,6 +21,7 @@ #include #include #include +#include "../common/sample.h" #include "../common/debug.h" #include "../common/timer.h" #include "nmt.h" @@ -414,10 +415,10 @@ static void trigger_frame_transmission(nmt_t *nmt) } /* send data using FSK */ -int fsk_dms_frame(nmt_t *nmt, int16_t *samples, int length) +int fsk_dms_frame(nmt_t *nmt, sample_t *samples, int length) { dms_t *dms = &nmt->dms; - int16_t *spl; + sample_t *spl; int i; int count, max; diff --git a/src/nmt/dms.h b/src/nmt/dms.h index b03b91e..e4bfd37 100644 --- a/src/nmt/dms.h +++ b/src/nmt/dms.h @@ -25,7 +25,7 @@ struct dms_state { typedef struct dms { /* DMS transmission */ int frame_valid; /* set, if there is a valid frame in sample buffer */ - int16_t *frame_spl; /* 127 * fsk_bit_length */ + sample_t *frame_spl; /* 127 * fsk_bit_length */ int frame_size; /* total size of buffer */ int frame_pos; /* current sample position in frame_spl */ int frame_length; /* number of samples currently in frame_spl */ @@ -52,7 +52,7 @@ typedef struct dms { int dms_init_sender(nmt_t *nmt); void dms_cleanup_sender(nmt_t *nmt); -int fsk_dms_frame(nmt_t *nmt, int16_t *samples, int length); +int fsk_dms_frame(nmt_t *nmt, sample_t *samples, int length); void fsk_receive_bit_dms(nmt_t *nmt, int bit, double quality, double level); void dms_reset(nmt_t *nmt); diff --git a/src/nmt/dsp.c b/src/nmt/dsp.c index ac3018c..7fb8fe5 100644 --- a/src/nmt/dsp.c +++ b/src/nmt/dsp.c @@ -25,9 +25,9 @@ #include #include #include +#include "../common/sample.h" #include "../common/debug.h" #include "../common/timer.h" -#include "../common/goertzel.h" #include "nmt.h" #include "transaction.h" #include "dsp.h" @@ -50,7 +50,7 @@ #define BIT_RATE 1200 /* baud rate */ #define STEPS_PER_BIT 10 /* step every 1/12000 sec */ #define DIALTONE_HZ 425.0 /* dial tone frequency */ -#define TX_PEAK_DIALTONE 16000 /* dial tone peak */ +#define TX_PEAK_DIALTONE 16000.0 /* dial tone peak */ #define SUPER_DURATION 0.25 /* duration of supervisory signal measurement */ #define SUPER_DETECT_COUNT 4 /* number of measures to detect supervisory signal */ #define MUTE_DURATION 0.280 /* a tiny bit more than two frames */ @@ -71,9 +71,9 @@ static double super_freq[5] = { }; /* table for fast sine generation */ -uint16_t dsp_tone_bit[2][2][256]; /* polarity, bit, phase */ -uint16_t dsp_sine_super[256]; -uint16_t dsp_sine_dialtone[256]; +static double dsp_tone_bit[2][2][256]; /* polarity, bit, phase */ +static double dsp_sine_super[256]; +static double dsp_sine_dialtone[256]; /* global init for FSK */ void dsp_init(void) @@ -85,24 +85,23 @@ void dsp_init(void) for (i = 0; i < 256; i++) { s = sin((double)i / 256.0 * 2.0 * PI); /* supervisor sine */ - dsp_sine_super[i] = (int)(s * TX_PEAK_SUPER); + dsp_sine_super[i] = s * TX_PEAK_SUPER; /* dialtone sine */ - dsp_sine_dialtone[i] = (int)(s * TX_PEAK_DIALTONE); + dsp_sine_dialtone[i] = s * TX_PEAK_DIALTONE; /* bit(1) 1 cycle */ - dsp_tone_bit[0][1][i] = (int)(s * TX_PEAK_FSK); - dsp_tone_bit[1][1][i] = (int)(-s * TX_PEAK_FSK); + dsp_tone_bit[0][1][i] = s * TX_PEAK_FSK; + dsp_tone_bit[1][1][i] = -s * TX_PEAK_FSK; /* bit(0) 1.5 cycles */ s = sin((double)i / 256.0 * 3.0 * PI); - dsp_tone_bit[0][0][i] = (int)(s * TX_PEAK_FSK); - dsp_tone_bit[1][0][i] = (int)(-s * TX_PEAK_FSK); + dsp_tone_bit[0][0][i] = s * TX_PEAK_FSK; + dsp_tone_bit[1][0][i] = -s * TX_PEAK_FSK; } } /* Init FSK of transceiver */ int dsp_init_sender(nmt_t *nmt) { - double coeff; - int16_t *spl; + sample_t *spl; int i; /* attack (3ms) and recovery time (13.5ms) according to NMT specs */ @@ -165,20 +164,14 @@ int dsp_init_sender(nmt_t *nmt) nmt->super_filter_spl = spl; /* count symbols */ - for (i = 0; i < 2; i++) { - coeff = 2.0 * cos(2.0 * PI * fsk_freq[i] / (double)nmt->sender.samplerate); - nmt->fsk_coeff[i] = coeff * 32768.0; - PDEBUG(DDSP, DEBUG_DEBUG, "fsk_coeff[%d] = %d\n", i, (int)nmt->fsk_coeff[i]); - } + for (i = 0; i < 2; i++) + audio_goertzel_init(&nmt->fsk_goertzel[i], fsk_freq[i], nmt->sender.samplerate); nmt->fsk_phaseshift256 = 256.0 / nmt->fsk_samples_per_bit; PDEBUG(DDSP, DEBUG_DEBUG, "fsk_phaseshift = %.4f\n", nmt->fsk_phaseshift256); /* count supervidory tones */ for (i = 0; i < 5; i++) { - coeff = 2.0 * cos(2.0 * PI * super_freq[i] / (double)nmt->sender.samplerate); - nmt->super_coeff[i] = coeff * 32768.0; - PDEBUG(DDSP, DEBUG_DEBUG, "supervisory coeff[%d] = %d\n", i, (int)nmt->super_coeff[i]); - + audio_goertzel_init(&nmt->super_goertzel[i], super_freq[i], nmt->sender.samplerate); if (i < 4) { nmt->super_phaseshift256[i] = 256.0 / ((double)nmt->sender.samplerate / super_freq[i]); PDEBUG(DDSP, DEBUG_DEBUG, "super_phaseshift[%d] = %.4f\n", i, nmt->super_phaseshift256[i]); @@ -301,7 +294,7 @@ static inline void fsk_decode_step(nmt_t *nmt, int pos) { double level, result[2], softbit, quality; int max; - int16_t *spl; + sample_t *spl; int bit; max = nmt->fsk_filter_size; @@ -316,7 +309,7 @@ static inline void fsk_decode_step(nmt_t *nmt, int pos) level = 0.01; // level = 0.63662 / 2.0; - audio_goertzel(spl, max, pos, nmt->fsk_coeff, result, 2); + audio_goertzel(nmt->fsk_goertzel, spl, max, pos, result, 2); /* calculate soft bit from both frequencies */ softbit = (result[1] / level - result[0] / level + 1.0) / 2.0; @@ -368,14 +361,12 @@ static inline void fsk_decode_step(nmt_t *nmt, int pos) } /* compare supervisory signal against noise floor on 3900 Hz */ -static void super_decode(nmt_t *nmt, int16_t *samples, int length) +static void super_decode(nmt_t *nmt, sample_t *samples, int length) { - int coeff[2]; double result[2], quality; - coeff[0] = nmt->super_coeff[nmt->supervisory - 1]; - coeff[1] = nmt->super_coeff[4]; /* noise floor detection */ - audio_goertzel(samples, length, 0, coeff, result, 2); + audio_goertzel(&nmt->super_goertzel[nmt->supervisory - 1], samples, length, 0, &result[0], 1); + audio_goertzel(&nmt->super_goertzel[4], samples, length, 0, &result[1], 1); /* noise floor detection */ #if 0 /* normalize levels */ @@ -424,10 +415,10 @@ void super_reset(nmt_t *nmt) } /* Process received audio stream from radio unit. */ -void sender_receive(sender_t *sender, int16_t *samples, int length) +void sender_receive(sender_t *sender, sample_t *samples, int length) { nmt_t *nmt = (nmt_t *) sender; - int16_t *spl; + sample_t *spl; int max, pos; double step, bps; int i; @@ -477,18 +468,17 @@ void sender_receive(sender_t *sender, int16_t *samples, int length) if ((nmt->dsp_mode == DSP_MODE_AUDIO || nmt->dsp_mode == DSP_MODE_DTMF) && nmt->trans && nmt->trans->callref) { - int16_t down[length]; /* more than enough */ int count; - count = samplerate_downsample(&nmt->sender.srstate, samples, length, down); + count = samplerate_downsample(&nmt->sender.srstate, samples, length); if (nmt->compandor) - expand_audio(&nmt->cstate, down, count); + expand_audio(&nmt->cstate, samples, count); if (nmt->dsp_mode == DSP_MODE_DTMF) - dtmf_tone(&nmt->dtmf, down, count); + dtmf_tone(&nmt->dtmf, samples, count); spl = nmt->sender.rxbuf; pos = nmt->sender.rxbuf_pos; for (i = 0; i < count; i++) { - spl[pos++] = down[i]; + spl[pos++] = samples[i]; if (pos == 160) { call_tx_audio(nmt->trans->callref, spl, 160); pos = 0; @@ -500,7 +490,7 @@ void sender_receive(sender_t *sender, int16_t *samples, int length) } /* render frame */ -int fsk_render_frame(nmt_t *nmt, const char *frame, int length, int16_t *sample) +int fsk_render_frame(nmt_t *nmt, const char *frame, int length, sample_t *sample) { int bit, polarity; double phaseshift, phase; @@ -528,10 +518,10 @@ int fsk_render_frame(nmt_t *nmt, const char *frame, int length, int16_t *sample) return count; } -static int fsk_frame(nmt_t *nmt, int16_t *samples, int length) +static int fsk_frame(nmt_t *nmt, sample_t *samples, int length) { const char *frame; - int16_t *spl; + sample_t *spl; int i; int count, max; @@ -575,23 +565,16 @@ next_frame: } /* Generate audio stream with supervisory signal. Keep phase for next call of function. */ -static void super_encode(nmt_t *nmt, int16_t *samples, int length) +static void super_encode(nmt_t *nmt, sample_t *samples, int length) { double phaseshift, phase; - int32_t sample; int i; phaseshift = nmt->super_phaseshift256[nmt->supervisory - 1]; phase = nmt->super_phase256; for (i = 0; i < length; i++) { - sample = *samples; - sample += dsp_sine_super[(uint8_t)phase]; - if (sample > 32767) - sample = 32767; - else if (sample < -32767) - sample = -32767; - *samples++ = sample; + *samples++ += dsp_sine_super[(uint8_t)phase]; phase += phaseshift; if (phase >= 256) phase -= 256; @@ -601,7 +584,7 @@ static void super_encode(nmt_t *nmt, int16_t *samples, int length) } /* Generate audio stream from dial tone. Keep phase for next call of function. */ -static void dial_tone(nmt_t *nmt, int16_t *samples, int length) +static void dial_tone(nmt_t *nmt, sample_t *samples, int length) { double phaseshift, phase; int i; @@ -620,7 +603,7 @@ static void dial_tone(nmt_t *nmt, int16_t *samples, int length) } /* Provide stream of audio toward radio unit */ -void sender_send(sender_t *sender, int16_t *samples, int length) +void sender_send(sender_t *sender, sample_t *samples, int length) { nmt_t *nmt = (nmt_t *) sender; int len; diff --git a/src/nmt/dsp.h b/src/nmt/dsp.h index de5dcf4..a2dbb83 100644 --- a/src/nmt/dsp.h +++ b/src/nmt/dsp.h @@ -2,7 +2,7 @@ void dsp_init(void); int dsp_init_sender(nmt_t *nmt); void dsp_cleanup_sender(nmt_t *nmt); -int fsk_render_frame(nmt_t *nmt, const char *frame, int length, int16_t *sample); +int fsk_render_frame(nmt_t *nmt, const char *frame, int length, sample_t *sample); void nmt_set_dsp_mode(nmt_t *nmt, enum dsp_mode mode); void super_reset(nmt_t *nmt); diff --git a/src/nmt/frame.c b/src/nmt/frame.c index b9c0f0d..bb3adc2 100644 --- a/src/nmt/frame.c +++ b/src/nmt/frame.c @@ -22,6 +22,7 @@ #include #include #include +#include "../common/sample.h" #include "../common/debug.h" #include "../common/timer.h" #include "nmt.h" diff --git a/src/nmt/main.c b/src/nmt/main.c index e1ea69f..9aedd3e 100644 --- a/src/nmt/main.c +++ b/src/nmt/main.c @@ -26,6 +26,7 @@ #include #include #include +#include "../common/sample.h" #include "../common/main.h" #include "../common/debug.h" #include "../common/timer.h" diff --git a/src/nmt/nmt.c b/src/nmt/nmt.c index 5076fd6..79c759c 100644 --- a/src/nmt/nmt.c +++ b/src/nmt/nmt.c @@ -25,6 +25,7 @@ #include #include #include +#include "../common/sample.h" #include "../common/debug.h" #include "../common/timer.h" #include "../common/cause.h" @@ -1799,7 +1800,7 @@ void call_out_release(int callref, int __attribute__((unused)) cause) } /* Receive audio from call instance. */ -void call_rx_audio(int callref, int16_t *samples, int count) +void call_rx_audio(int callref, sample_t *samples, int count) { transaction_t *trans; nmt_t *nmt; @@ -1812,7 +1813,7 @@ void call_rx_audio(int callref, int16_t *samples, int count) return; if (nmt->dsp_mode == DSP_MODE_AUDIO || nmt->dsp_mode == DSP_MODE_DTMF) { - int16_t up[(int)((double)count * nmt->sender.srstate.factor + 0.5) + 10]; + sample_t up[(int)((double)count * nmt->sender.srstate.factor + 0.5) + 10]; if (nmt->compandor) compress_audio(&nmt->cstate, samples, count); count = samplerate_upsample(&nmt->sender.srstate, samples, count, up); diff --git a/src/nmt/nmt.h b/src/nmt/nmt.h index f09d33d..8883bb4 100644 --- a/src/nmt/nmt.h +++ b/src/nmt/nmt.h @@ -1,3 +1,4 @@ +#include "../common/goertzel.h" #include "../common/sender.h" #include "../common/compandor.h" #include "../common/dtmf.h" @@ -94,10 +95,10 @@ typedef struct nmt { double fsk_samples_per_bit; /* number of samples for one bit (1200 Baud) */ double fsk_bits_per_sample; /* fraction of a bit per sample */ int super_samples; /* number of samples in buffer for supervisory detection */ - int fsk_coeff[2]; /* coefficient k = 2*cos(2*PI*f/samplerate), k << 15 */ - int super_coeff[5]; /* coefficient for supervisory signal */ + goertzel_t fsk_goertzel[2]; /* filter for fsk decoding */ + goertzel_t super_goertzel[5]; /* filter for supervisory decoding */ int fsk_polarity; /* current polarity state of bit */ - int16_t *fsk_filter_spl; /* array to hold ring buffer for bit decoding */ + sample_t *fsk_filter_spl; /* array to hold ring buffer for bit decoding */ int fsk_filter_size; /* size of ring buffer */ int fsk_filter_pos; /* position to write next sample */ double fsk_filter_step; /* counts bit duration, to trigger decoding every 10th bit */ @@ -110,7 +111,7 @@ typedef struct nmt { int fsk_filter_count; /* next bit to receive */ double fsk_filter_level[256]; /* level infos */ double fsk_filter_quality[256];/* quality infos */ - int16_t *super_filter_spl; /* array with sample buffer for supervisory detection */ + sample_t *super_filter_spl; /* array with sample buffer for supervisory detection */ int super_filter_pos; /* current sample position in filter_spl */ double super_phaseshift256[4]; /* how much the phase of sine wave changes per sample */ double super_phase256; /* current phase */ @@ -118,7 +119,7 @@ typedef struct nmt { double dial_phase256; /* current phase */ double fsk_phaseshift256; /* how much the phase of fsk synbol changes per sample */ double fsk_phase256; /* current phase */ - int16_t *frame_spl; /* samples to store a complete rendered frame */ + sample_t *frame_spl; /* samples to store a complete rendered frame */ int frame_size; /* total size of sample buffer */ int frame_length; /* current length of data in sample buffer */ int frame_pos; /* current sample position in frame_spl */ diff --git a/src/nmt/sms.c b/src/nmt/sms.c index c1263b2..2c8d311 100644 --- a/src/nmt/sms.c +++ b/src/nmt/sms.c @@ -23,6 +23,7 @@ #include #include #include +#include "../common/sample.h" #include "../common/debug.h" #include "../common/timer.h" #include "nmt.h" diff --git a/src/nmt/transaction.c b/src/nmt/transaction.c index 26a1ccd..71d671f 100644 --- a/src/nmt/transaction.c +++ b/src/nmt/transaction.c @@ -21,6 +21,7 @@ #include #include #include +#include "../common/sample.h" #include "../common/debug.h" #include "../common/timer.h" #include "nmt.h" diff --git a/src/test/test_compandor.c b/src/test/test_compandor.c index 74f4f28..6b7d4cb 100644 --- a/src/test/test_compandor.c +++ b/src/test/test_compandor.c @@ -2,6 +2,7 @@ #include #include #include +#include "../common/sample.h" #include "../common/compandor.h" #define level2db(level) (20 * log10(level)) @@ -14,11 +15,11 @@ static double test_frequency[3] = { 2000.0, 4000.0, 1000.0 }; -static int16_t samples_4db[SAMPLERATE]; -static int16_t samples_16db[SAMPLERATE]; -static int16_t samples_2db[SAMPLERATE]; -static int16_t samples_8db[SAMPLERATE]; -static int16_t samples_0db[SAMPLERATE]; +static sample_t samples_4db[SAMPLERATE]; +static sample_t samples_16db[SAMPLERATE]; +static sample_t samples_2db[SAMPLERATE]; +static sample_t samples_8db[SAMPLERATE]; +static sample_t samples_0db[SAMPLERATE]; /* generate 2 samples: one with -4 dB, the other with -16 dB */ static void generate_test_sample(double test_frequency) @@ -36,7 +37,7 @@ static void generate_test_sample(double test_frequency) } } -static void check_level(int16_t *samples, double duration, const char *desc, double target_db) +static void check_level(sample_t *samples, double duration, const char *desc, double target_db) { int i; int last = 0, envelop = 0; @@ -67,7 +68,7 @@ static void check_level(int16_t *samples, double duration, const char *desc, dou int main(void) { compandor_t cstate; - int16_t samples[SAMPLERATE * 2]; + sample_t samples[SAMPLERATE * 2]; int f; init_compandor(&cstate, SAMPLERATE, ATTACK_MS, RECOVERY_MS, UNAFFECTED); diff --git a/src/test/test_dms.c b/src/test/test_dms.c index c047e5a..a35a6f1 100644 --- a/src/test/test_dms.c +++ b/src/test/test_dms.c @@ -4,6 +4,7 @@ #include #include #include +#include "../common/sample.h" #include "../common/debug.h" #include "../common/timer.h" #include "../nmt/nmt.h" @@ -55,7 +56,7 @@ void dms_all_sent(nmt_t *nmt) } /* receive bits from DMS */ -int fsk_render_frame(nmt_t *nmt, const char *frame, int length, int16_t *sample) +int fsk_render_frame(nmt_t *nmt, const char *frame, int length, sample_t *sample) { printf("(getting %d bits from DMS layer)\n", length); @@ -92,7 +93,7 @@ int main(void) nmt_t *nmt; dms_t *dms; int i, j; - int16_t sample = 0; + sample_t sample = 0; debuglevel = DEBUG_DEBUG; dms_allow_loopback = 1; diff --git a/src/test/test_emphasis.c b/src/test/test_emphasis.c index 036a45e..79799d2 100644 --- a/src/test/test_emphasis.c +++ b/src/test/test_emphasis.c @@ -2,6 +2,7 @@ #include #include #include +#include "../common/sample.h" #include "../common/emphasis.h" #include "../common/debug.h" @@ -13,7 +14,7 @@ static double test_freq[] = { 25, 50, 100, 200, 250, 300, 400, 500, 1000, 2000, 4000, 0 }; -static void check_level(int16_t *samples, double freq, const char *desc) +static void check_level(sample_t *samples, double freq, const char *desc) { int i; int last = 0, envelope = 0; @@ -34,7 +35,7 @@ static void check_level(int16_t *samples, double freq, const char *desc) printf("%s: f = %.0f envelop = %.4f\n", desc, freq, level2db((double)envelope / DEVIATION)); } -static void gen_samples(int16_t *samples, double freq) +static void gen_samples(double *samples, double freq) { int i; double value; @@ -48,7 +49,7 @@ static void gen_samples(int16_t *samples, double freq) int main(void) { emphasis_t estate; - int16_t samples[SAMPLERATE]; + double samples[SAMPLERATE]; int i; debuglevel = DEBUG_DEBUG; diff --git a/src/test/test_filter.c b/src/test/test_filter.c index 8c82292..d78578a 100644 --- a/src/test/test_filter.c +++ b/src/test/test_filter.c @@ -2,6 +2,7 @@ #include #include #include +#include "../common/sample.h" #include "../common/filter.h" #include "../common/debug.h" diff --git a/src/test/test_sms.c b/src/test/test_sms.c index fb63ba0..0768046 100644 --- a/src/test/test_sms.c +++ b/src/test/test_sms.c @@ -4,6 +4,7 @@ #include #include #include +#include "../common/sample.h" #include "../common/debug.h" #include "../common/timer.h" #include "../nmt/nmt.h" -- cgit v1.2.3