Move samples of int16_t format to sample_t, that is of type double
This prepares the correction of all levels
This commit is contained in:
parent
538a959128
commit
7ea3bc188d
|
@ -42,6 +42,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -81,10 +81,10 @@
|
|||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
#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;
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <errno.h>
|
||||
#include <math.h>
|
||||
#include <inttypes.h>
|
||||
#include "../common/sample.h"
|
||||
#include "../common/debug.h"
|
||||
#include "../common/timer.h"
|
||||
#include "amps.h"
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <getopt.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "../common/sample.h"
|
||||
#include "../common/main.h"
|
||||
#include "../common/debug.h"
|
||||
#include "../common/timer.h"
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include "../common/sample.h"
|
||||
#include "../common/timer.h"
|
||||
#include "amps.h"
|
||||
#include "frame.h"
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include "../common/sample.h"
|
||||
#include "../common/debug.h"
|
||||
#include "../common/timer.h"
|
||||
#include "amps.h"
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -25,10 +25,10 @@
|
|||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
#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;
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include "../common/sample.h"
|
||||
#include "../common/main.h"
|
||||
#include "../common/debug.h"
|
||||
#include "../common/timer.h"
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -25,10 +25,10 @@
|
|||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
#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;
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <getopt.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "../common/sample.h"
|
||||
#include "../common/debug.h"
|
||||
#include "../common/timer.h"
|
||||
#include "../common/call.h"
|
||||
|
|
|
@ -129,6 +129,7 @@
|
|||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
#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;
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "../common/sample.h"
|
||||
#include "../common/debug.h"
|
||||
#include "../common/timer.h"
|
||||
#include "cnetz.h"
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <errno.h>
|
||||
#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 */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -105,6 +105,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <getopt.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "../common/sample.h"
|
||||
#include "../common/main.h"
|
||||
#include "../common/debug.h"
|
||||
#include "../common/timer.h"
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
#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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
#include "../common/sample.h"
|
||||
#include "../common/debug.h"
|
||||
#include "../common/timer.h"
|
||||
#include "cnetz.h"
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include "../common/sample.h"
|
||||
#include "../common/debug.h"
|
||||
#include "../common/timer.h"
|
||||
#include "cnetz.h"
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <sys/time.h>
|
||||
#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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
#include "sample.h"
|
||||
#include "debug.h"
|
||||
#include "display.h"
|
||||
#include "call.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);
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include "sample.h"
|
||||
#include "sender.h"
|
||||
|
||||
#define DISPLAY_INTERVAL 0.04
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#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') = ')';
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -22,7 +22,8 @@
|
|||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
#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) */
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -22,14 +22,15 @@
|
|||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
#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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <unistd.h>
|
||||
#include <math.h>
|
||||
#include <termios.h>
|
||||
#include "sample.h"
|
||||
#include "main.h"
|
||||
#include "debug.h"
|
||||
#include "sender.h"
|
||||
|
|
|
@ -26,7 +26,8 @@
|
|||
#include <sys/un.h>
|
||||
#include <stddef.h>
|
||||
#include <unistd.h>
|
||||
#include "../common/debug.h"
|
||||
#include "sample.h"
|
||||
#include "debug.h"
|
||||
#include "call.h"
|
||||
#include "mncc_sock.h"
|
||||
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#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++;
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
|
@ -22,6 +22,7 @@
|
|||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#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);
|
||||
filter_process(&state->up.lp, samples, 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;
|
||||
if (input == output) {
|
||||
/* copy samples */
|
||||
for (i = 0; i < input_num; i++)
|
||||
*output++ = samples[i];
|
||||
}
|
||||
|
||||
return output_num;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#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++) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <alsa/asoundlib.h>
|
||||
#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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -25,9 +25,9 @@
|
|||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
#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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include "../common/sample.h"
|
||||
#include "../common/debug.h"
|
||||
#include "../common/timer.h"
|
||||
#include "nmt.h"
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include "../common/sample.h"
|
||||
#include "../common/main.h"
|
||||
#include "../common/debug.h"
|
||||
#include "../common/timer.h"
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
#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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include "../common/sample.h"
|
||||
#include "../common/debug.h"
|
||||
#include "../common/timer.h"
|
||||
#include "nmt.h"
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "../common/sample.h"
|
||||
#include "../common/debug.h"
|
||||
#include "../common/timer.h"
|
||||
#include "nmt.h"
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#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);
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#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;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#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;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include "../common/sample.h"
|
||||
#include "../common/filter.h"
|
||||
#include "../common/debug.h"
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "../common/sample.h"
|
||||
#include "../common/debug.h"
|
||||
#include "../common/timer.h"
|
||||
#include "../nmt/nmt.h"
|
||||
|
|
Loading…
Reference in New Issue