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:
Andreas Eversberg 2017-01-27 16:57:34 +01:00
parent 538a959128
commit 7ea3bc188d
74 changed files with 471 additions and 447 deletions

View File

@ -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(&amps->cstate, samples, count);
count = samplerate_upsample(&amps->sender.srstate, samples, count, up);
jitter_save(&amps->sender.dejitter, up, count);

View File

@ -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 */

View File

@ -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(&amps->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(&amps->sat_goertzel[amps->sat], samples, length, 0, &result[0], 1);
audio_goertzel(&amps->sat_goertzel[3], samples, length, 0, &result[1], 1);
audio_goertzel(&amps->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(&amps->estate, samples, length);
/* downsample */
count = samplerate_downsample(&amps->sender.srstate, samples, length, down);
expand_audio(&amps->cstate, down, count);
count = samplerate_downsample(&amps->sender.srstate, samples, length);
expand_audio(&amps->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;

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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);
}

View File

@ -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 */

View File

@ -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;

View File

@ -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"

View File

@ -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);
}

View File

@ -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 */

View File

@ -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;

View File

@ -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"

View File

@ -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;

View File

@ -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 */

View File

@ -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"

View File

@ -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 */

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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"

View File

@ -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);
}

View File

@ -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);

View File

@ -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"

View File

@ -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"

View File

@ -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 \

View File

@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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"

View File

@ -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);

View File

@ -21,6 +21,7 @@
#include <stdint.h>
#include <string.h>
#include <math.h>
#include "sample.h"
#include "sender.h"
#define DISPLAY_INTERVAL 0.04

View File

@ -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') = ')';

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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) */
}
}

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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"

View File

@ -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"

27
src/common/sample.c Normal file
View File

@ -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++;
}
}

6
src/common/sample.h Normal file
View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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++) {

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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"

View File

@ -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"

View File

@ -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);

View File

@ -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 */

View File

@ -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"

View File

@ -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"

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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"

View File

@ -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"