Correcting all levels and move all remaining integer samples to sample_t

The leves are based on the standards of each mobile network. They
are adjusted to the specified frequency deviation now.
pull/1/head
Andreas Eversberg 6 years ago
parent bd7ccc5fa0
commit 7e45f556ce

@ -54,7 +54,7 @@ A caller must not know the location of the phone anymore to reach the right base
<li>Channel spacing: 10 KHz and optionally 12.5 KHz
<li>Voice modulation: FM
<li>Signaling modulation: carrier FSK
<li>Frequency deviation: 2.5 KHz (FSK); 2.4 KHz (Voice)
<li>Frequency deviation: 2.5 KHz (FSK); 4 KHz (Voice)
<li>Mobile station transmit power: 50 mW up to 15 Watts
<li>Base station transmit power: 25 Watts
<li>Features: Speech Compandor, Audio scrambling

@ -135,14 +135,14 @@ typedef struct amps {
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 */
double sat_phaseshift65536[3]; /* how much the phase of sine wave changes per sample */
double sat_phase65536; /* current phase */
int sat_detected; /* current detection state flag */
int sat_detect_count; /* current number of consecutive detections/losses */
int sig_detected; /* current detection state flag */
int sig_detect_count; /* current number of consecutive detections/losses */
double test_phaseshift256; /* how much the phase of sine wave changes per sample */
double test_phase256; /* current phase */
double test_phaseshift65536; /* how much the phase of sine wave changes per sample */
double test_phase65536; /* current phase */
transaction_t *trans_list; /* list of transactions */

@ -99,10 +99,13 @@
#define PI M_PI
#define BANDWIDTH 20000.0 /* maximum bandwidth */
#define FSK_DEVIATION 32767.0 /* +-8 KHz */
#define SAT_DEVIATION 8192.0 /* +-2 KHz */
#define COMPANDOR_0DB 45000 /* works quite well */
#define MAX_DEVIATION 8000.0
#define MAX_MODULATION 10000.0
#define DBM0_DEVIATION 2900.0 /* deviation of dBm0 at 1 kHz */
#define COMPANDOR_0DB 1.0 /* A level of 0dBm (1.0) shall be unaccected */
#define FSK_DEVIATION (8000.0 / DBM0_DEVIATION) /* no emphasis */
#define SAT_DEVIATION (2000.0 / DBM0_DEVIATION) /* no emphasis */
#define MAX_DISPLAY (8000.0 / DBM0_DEVIATION) /* no emphasis */
#define BITRATE 10000
#define SIG_TONE_CROSSINGS 2000 /* 2000 crossings are 100ms @ 10 KHz */
#define SIG_TONE_MINBITS 950 /* minimum bit durations to detect signaling tone (1000 is perfect for 100 ms) */
@ -116,7 +119,7 @@
#define CUT_OFF_HIGHPASS 300.0 /* cut off frequency for high pass filter to remove dc level from sound card / sample */
#define BEST_QUALITY 0.68 /* Best possible RX quality */
static int16_t ramp_up[256], ramp_down[256];
static sample_t ramp_up[256], ramp_down[256];
static double sat_freq[5] = {
5970.0,
@ -126,8 +129,8 @@ static double sat_freq[5] = {
10000.0, /* signaling tone */
};
static int dsp_sine_sat[256];
static int dsp_sine_test[256];
static sample_t dsp_sine_sat[65536];
static sample_t dsp_sine_test[65536];
static uint8_t dsp_sync_check[0x800];
@ -138,10 +141,10 @@ void dsp_init(void)
double s;
PDEBUG(DDSP, DEBUG_DEBUG, "Generating sine table for SAT signal.\n");
for (i = 0; i < 256; i++) {
s = sin((double)i / 256.0 * 2.0 * PI);
dsp_sine_sat[i] = (int)(s * SAT_DEVIATION);
dsp_sine_test[i] = (int)(s * FSK_DEVIATION);
for (i = 0; i < 65536; i++) {
s = sin((double)i / 65536.0 * 2.0 * PI);
dsp_sine_sat[i] = s * SAT_DEVIATION;
dsp_sine_test[i] = s * FSK_DEVIATION;
}
/* sync checker */
@ -170,7 +173,7 @@ static void dsp_init_ramp(amps_t *amps)
else
c = sqrt(c);
#endif
ramp_down[i] = (int)(c * (double)amps->fsk_deviation);
ramp_down[i] = c * (double)amps->fsk_deviation;
ramp_up[i] = -ramp_down[i];
}
}
@ -190,9 +193,8 @@ int dsp_init_sender(amps_t *amps, int tolerant)
PDEBUG_CHAN(DDSP, DEBUG_DEBUG, "Init DSP for transceiver.\n");
/* set deviation and modulation parameters */
amps->sender.bandwidth = BANDWIDTH;
amps->sender.sample_deviation = 8000.0 / (double)FSK_DEVIATION;
/* set modulation parameters */
sender_set_fm(&amps->sender, MAX_DEVIATION, MAX_MODULATION, DBM0_DEVIATION, MAX_DISPLAY);
if (amps->sender.samplerate < 96000) {
PDEBUG(DDSP, DEBUG_ERROR, "Sample rate must be at least 96000 Hz to process FSK and SAT signals.\n");
@ -229,7 +231,7 @@ int dsp_init_sender(amps_t *amps, int tolerant)
amps->fsk_rx_window = spl;
/* create devation and ramp */
amps->fsk_deviation = FSK_DEVIATION; /* be sure not to overflow 32767 */
amps->fsk_deviation = FSK_DEVIATION;
dsp_init_ramp(amps);
/* allocate ring buffer for SAT signal detection */
@ -245,15 +247,15 @@ int dsp_init_sender(amps_t *amps, int tolerant)
for (i = 0; i < 5; 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]);
amps->sat_phaseshift65536[i] = 65536.0 / ((double)amps->sender.samplerate / sat_freq[i]);
PDEBUG(DDSP, DEBUG_DEBUG, "sat_phaseshift65536[%d] = %.4f\n", i, amps->sat_phaseshift65536[i]);
}
}
sat_reset(amps, "Initial state");
/* test tone */
amps->test_phaseshift256 = 256.0 / ((double)amps->sender.samplerate / 1000.0);
PDEBUG(DDSP, DEBUG_DEBUG, "test_phaseshift256 = %.4f\n", amps->test_phaseshift256);
amps->test_phaseshift65536 = 65536.0 / ((double)amps->sender.samplerate / 1000.0);
PDEBUG(DDSP, DEBUG_DEBUG, "test_phaseshift65536 = %.4f\n", amps->test_phaseshift65536);
/* be more tolerant when syncing */
amps->fsk_rx_sync_tolerant = tolerant;
@ -401,7 +403,7 @@ again:
//printf("pos=%d length=%d copy=%d\n", pos, length, copy);
for (i = 0; i < copy; i++) {
#ifdef DEBUG_ENCODER
puts(debug_amplitude((double)spl[pos] / 32767.0));
puts(debug_amplitude((double)spl[pos]));
#endif
*samples++ = spl[pos++];
}
@ -422,26 +424,19 @@ done:
static void sat_encode(amps_t *amps, sample_t *samples, int length)
{
double phaseshift, phase;
int32_t sample;
int i;
phaseshift = amps->sat_phaseshift256[amps->sat];
phase = amps->sat_phase256;
phaseshift = amps->sat_phaseshift65536[amps->sat];
phase = amps->sat_phase65536;
for (i = 0; i < length; i++) {
sample = *samples;
sample += dsp_sine_sat[(uint8_t)phase];
if (sample > 32767)
sample = 32767;
else if (sample < -32767)
sample = -32767;
*samples++ = sample;
*samples++ += dsp_sine_sat[(uint16_t)phase];
phase += phaseshift;
if (phase >= 256)
phase -= 256;
if (phase >= 65536)
phase -= 65536;
}
amps->sat_phase256 = phase;
amps->sat_phase65536 = phase;
}
static void test_tone_encode(amps_t *amps, sample_t *samples, int length)
@ -449,17 +444,17 @@ static void test_tone_encode(amps_t *amps, sample_t *samples, int length)
double phaseshift, phase;
int i;
phaseshift = amps->test_phaseshift256;
phase = amps->test_phase256;
phaseshift = amps->test_phaseshift65536;
phase = amps->test_phase65536;
for (i = 0; i < length; i++) {
*samples++ = dsp_sine_test[(uint8_t)phase];
*samples++ = dsp_sine_test[(uint16_t)phase];
phase += phaseshift;
if (phase >= 256)
phase -= 256;
if (phase >= 65536)
phase -= 65536;
}
amps->test_phase256 = phase;
amps->test_phase65536 = phase;
}
/* Provide stream of audio toward radio unit */
@ -735,9 +730,9 @@ static void sat_decode(amps_t *amps, sample_t *samples, int length)
if (quality[1] < 0)
quality[1] = 0;
PDEBUG_CHAN(DDSP, DEBUG_NOTICE, "SAT level %.2f%% quality %.0f%%\n", result[0] * 32767.0 / SAT_DEVIATION / 0.63662 * 100.0, quality[0] * 100.0);
PDEBUG_CHAN(DDSP, DEBUG_NOTICE, "SAT level %.2f%% quality %.0f%%\n", result[0] / SAT_DEVIATION / 0.63662 * 100.0, quality[0] * 100.0);
if (amps->sender.loopback || debuglevel == DEBUG_DEBUG) {
PDEBUG_CHAN(DDSP, debuglevel, "Signaling Tone level %.2f%% quality %.0f%%\n", result[2] * 32767.0 / FSK_DEVIATION / 0.63662 * 100.0, quality[1] * 100.0);
PDEBUG_CHAN(DDSP, debuglevel, "Signaling Tone level %.2f%% quality %.0f%%\n", result[2] / FSK_DEVIATION / 0.63662 * 100.0, quality[1] * 100.0);
}
if (quality[0] > SAT_QUALITY) {
if (amps->sat_detected == 0) {

@ -33,12 +33,12 @@ typedef struct anetz {
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 */
double tone_phaseshift256; /* how much the phase of sine wave changes per sample */
double tone_phase256; /* current phase */
double tone_phaseshift65536; /* how much the phase of sine wave changes per sample */
double tone_phase65536; /* current phase */
double page_gain; /* factor to raise the paging tones */
int page_sequence; /* if set, use paging tones in sequence rather than parallel */
double paging_phaseshift256[4];/* how much the phase of sine wave changes per sample */
double paging_phase256[4]; /* current phase */
double paging_phaseshift65536[4];/* how much the phase of sine wave changes per sample */
double paging_phase65536[4]; /* current phase */
int paging_tone; /* current tone (0..3) in sequenced mode */
int paging_count; /* current sample count of tone in seq. mode */
int paging_transition; /* set to number of samples during transition */

@ -35,8 +35,12 @@
#define PI 3.1415927
/* signaling */
#define BANDWIDTH 15000.0 /* maximum bandwidth */
#define TX_PEAK_TONE 8192.0 /* peak amplitude for all tones */
#define MAX_DEVIATION 15000.0
#define MAX_MODULATION 4000.0
#define DBM0_DEVIATION 10500.0 /* deviation of dBm0 at 1 kHz */
#define TX_PEAK_TONE (10500.0 / DBM0_DEVIATION) /* 10.5 kHz, no emphasis */
#define TX_PEAK_PAGE (15000.0 / DBM0_DEVIATION) /* 15 kHz, no emphasis */
#define MAX_DISPLAY (15000.0 / DBM0_DEVIATION) /* 15 kHz, no emphasis */
#define CHUNK_DURATION 0.010 /* 10 ms */
// FIXME: how long until we detect a tone?
@ -53,7 +57,8 @@ static double fsk_tones[2] = {
};
/* table for fast sine generation */
sample_t dsp_sine_tone[256];
static sample_t dsp_sine_tone[65536];
static sample_t dsp_sine_page[65536];
/* global init for audio processing */
void dsp_init(void)
@ -62,14 +67,10 @@ void dsp_init(void)
double s;
PDEBUG(DDSP, DEBUG_DEBUG, "Generating sine tables.\n");
for (i = 0; i < 256; i++) {
s = sin((double)i / 256.0 * 2.0 * PI);
dsp_sine_tone[i] = (int)(s * TX_PEAK_TONE);
}
if (TX_PEAK_TONE > 32767.0) {
fprintf(stderr, "TX_PEAK_TONE definition too high, please fix!\n");
abort();
for (i = 0; i < 65536; i++) {
s = sin((double)i / 65536.0 * 2.0 * PI);
dsp_sine_tone[i] = s * TX_PEAK_TONE;
dsp_sine_page[i] = s * TX_PEAK_PAGE;
}
}
@ -82,15 +83,10 @@ int dsp_init_sender(anetz_t *anetz, double page_gain, int page_sequence)
PDEBUG_CHAN(DDSP, DEBUG_DEBUG, "Init DSP for 'Sender'.\n");
/* set deviation and modulation parameters */
anetz->sender.bandwidth = BANDWIDTH;
anetz->sender.sample_deviation = 11000.0 / (double)TX_PEAK_TONE;
/* set modulation parameters */
sender_set_fm(&anetz->sender, MAX_DEVIATION * page_gain, MAX_MODULATION, DBM0_DEVIATION, MAX_DISPLAY);
anetz->page_gain = page_gain;
if (page_gain * TX_PEAK_TONE > 32767.0) {
page_gain = 32767.0 / TX_PEAK_TONE;
PDEBUG_CHAN(DDSP, DEBUG_NOTICE, "Highest possible gain of paging tones is %.1f dB.\n", log10(page_gain) * 20);
}
anetz->page_sequence = page_sequence;
audio_init_loss(&anetz->sender.loss, LOSS_INTERVAL, anetz->sender.loss_volume, LOSS_TIME);
@ -109,8 +105,8 @@ int dsp_init_sender(anetz_t *anetz, double page_gain, int page_sequence)
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);
anetz->tone_phaseshift65536 = 65536.0 / ((double)anetz->sender.samplerate / tone);
PDEBUG(DDSP, DEBUG_DEBUG, "TX %.0f Hz phaseshift = %.4f\n", tone, anetz->tone_phaseshift65536);
return 0;
}
@ -169,19 +165,19 @@ static void fsk_decode_chunk(anetz_t *anetz, sample_t *spl, int max)
/* show quality of tone */
if (anetz->sender.loopback) {
/* adjust level, so we get peak of sine curve */
PDEBUG_CHAN(DDSP, DEBUG_NOTICE, "Tone %.0f: Level=%3.0f%% Quality=%3.0f%%\n", fsk_tones[1], level / 0.63662 * 100.0 * 32768.0 / TX_PEAK_TONE, result[1] / level * 100.0);
PDEBUG_CHAN(DDSP, DEBUG_NOTICE, "Tone %.0f: Level=%3.0f%% Quality=%3.0f%%\n", fsk_tones[1], level / 0.63662 * 100.0 / TX_PEAK_TONE, result[1] / level * 100.0);
}
if (level / 0.63 > 0.05 && result[0] / level > 0.5)
PDEBUG_CHAN(DDSP, DEBUG_INFO, "Tone %.0f: Level=%3.0f%% Quality=%3.0f%%\n", fsk_tones[0], level / 0.63662 * 100.0 * 32768.0 / TX_PEAK_TONE, result[0] / level * 100.0);
PDEBUG_CHAN(DDSP, DEBUG_INFO, "Tone %.0f: Level=%3.0f%% Quality=%3.0f%%\n", fsk_tones[0], level / 0.63662 * 100.0 / TX_PEAK_TONE, result[0] / level * 100.0);
/* adjust level, so we get peak of sine curve */
/* indicate detected tone */
if (level / 0.63 > 0.05 && result[0] / level > 0.5)
fsk_receive_tone(anetz, 0, 1, level / 0.63662 * 32768.0 / TX_PEAK_TONE);
fsk_receive_tone(anetz, 0, 1, level / 0.63662 / TX_PEAK_TONE);
else if (level / 0.63 > 0.05 && result[1] / level > 0.5)
fsk_receive_tone(anetz, 1, 1, level / 0.63662 * 32768.0 / TX_PEAK_TONE);
fsk_receive_tone(anetz, 1, 1, level / 0.63662 / TX_PEAK_TONE);
else
fsk_receive_tone(anetz, -1, 0, level / 0.63662 * 32768.0 / TX_PEAK_TONE);
fsk_receive_tone(anetz, -1, 0, level / 0.63662 / TX_PEAK_TONE);
}
/* Process received audio stream from radio unit. */
@ -230,42 +226,36 @@ void dsp_set_paging(anetz_t *anetz, double *freq)
int i;
for (i = 0; i < 4; i++) {
anetz->paging_phaseshift256[i] = 256.0 / ((double)anetz->sender.samplerate / freq[i]);
anetz->paging_phase256[i] = 0;
anetz->paging_phaseshift65536[i] = 65536.0 / ((double)anetz->sender.samplerate / freq[i]);
anetz->paging_phase65536[i] = 0;
}
}
/* 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. */
* Use TX_PEAK_PAGE*page_gain for all tones, which gives peak of 1/4th for each individual tone. */
static void fsk_paging_tone(anetz_t *anetz, sample_t *samples, int length)
{
double phaseshift[4], phase[4];
double *phaseshift, *phase;
int i;
double sample;
for (i = 0; i < 4; i++) {
phaseshift[i] = anetz->paging_phaseshift256[i];
phase[i] = anetz->paging_phase256[i];
}
phaseshift = anetz->paging_phaseshift65536;
phase = anetz->paging_phase65536;
for (i = 0; i < length; i++) {
sample = (int32_t)dsp_sine_tone[(uint8_t)phase[0]]
+ (int32_t)dsp_sine_tone[(uint8_t)phase[1]]
+ (int32_t)dsp_sine_tone[(uint8_t)phase[2]]
+ (int32_t)dsp_sine_tone[(uint8_t)phase[3]];
sample = dsp_sine_page[(uint16_t)phase[0]]
+ dsp_sine_page[(uint16_t)phase[1]]
+ dsp_sine_page[(uint16_t)phase[2]]
+ dsp_sine_page[(uint16_t)phase[3]];
*samples++ = sample / 4.0 * anetz->page_gain;
phase[0] += phaseshift[0];
phase[1] += phaseshift[1];
phase[2] += phaseshift[2];
phase[3] += phaseshift[3];
if (phase[0] >= 256) phase[0] -= 256;
if (phase[1] >= 256) phase[1] -= 256;
if (phase[2] >= 256) phase[2] -= 256;
if (phase[3] >= 256) phase[3] -= 256;
}
for (i = 0; i < 4; i++) {
anetz->paging_phase256[i] = phase[i];
if (phase[0] >= 65536) phase[0] -= 65536;
if (phase[1] >= 65536) phase[1] -= 65536;
if (phase[2] >= 65536) phase[2] -= 65536;
if (phase[3] >= 65536) phase[3] -= 65536;
}
}
@ -280,14 +270,11 @@ static void fsk_paging_tone(anetz_t *anetz, sample_t *samples, int length)
*/
static void fsk_paging_tone_sequence(anetz_t *anetz, sample_t *samples, int length, int numspl)
{
double phaseshift[4], phase[4];
int i;
double *phaseshift, *phase;
int tone, count, transition;
for (i = 0; i < 4; i++) {
phaseshift[i] = anetz->paging_phaseshift256[i];
phase[i] = anetz->paging_phase256[i];
}
phaseshift = anetz->paging_phaseshift65536;
phase = anetz->paging_phase65536;
tone = anetz->paging_tone;
count = anetz->paging_count;
transition = anetz->paging_transition;
@ -295,21 +282,21 @@ static void fsk_paging_tone_sequence(anetz_t *anetz, sample_t *samples, int leng
while (length) {
/* use tone, but during transition of tones, keep phase 0 degrees (high level) until next tone reaches 0 degrees (high level) */
if (!transition)
*samples++ = dsp_sine_tone[(uint8_t)phase[tone]] * anetz->page_gain;
*samples++ = dsp_sine_page[(uint16_t)phase[tone]] * anetz->page_gain;
else {
/* fade between old an new tone */
*samples++
= (double)dsp_sine_tone[(uint8_t)phase[(tone - 1) & 3]] * (double)(transition - count) / (double)transition / 2.0 * anetz->page_gain
+ (double)dsp_sine_tone[(uint8_t)phase[tone]] * (double)count / (double)transition / 2.0 * anetz->page_gain;
= (double)dsp_sine_page[(uint16_t)phase[(tone - 1) & 3]] * (double)(transition - count) / (double)transition / 2.0 * anetz->page_gain
+ (double)dsp_sine_page[(uint16_t)phase[tone]] * (double)count / (double)transition / 2.0 * anetz->page_gain;
}
phase[0] += phaseshift[0];
phase[1] += phaseshift[1];
phase[2] += phaseshift[2];
phase[3] += phaseshift[3];
if (phase[0] >= 256) phase[0] -= 256;
if (phase[1] >= 256) phase[1] -= 256;
if (phase[2] >= 256) phase[2] -= 256;
if (phase[3] >= 256) phase[3] -= 256;
if (phase[0] >= 65536) phase[0] -= 65536;
if (phase[1] >= 65536) phase[1] -= 65536;
if (phase[2] >= 65536) phase[2] -= 65536;
if (phase[3] >= 65536) phase[3] -= 65536;
count++;
if (transition && count == transition) {
transition = 0;
@ -327,9 +314,6 @@ static void fsk_paging_tone_sequence(anetz_t *anetz, sample_t *samples, int leng
length--;
}
for (i = 0; i < 4; i++) {
anetz->paging_phase256[i] = phase[i];
}
anetz->paging_tone = tone;
anetz->paging_count = count;
anetz->paging_transition = transition;
@ -341,17 +325,17 @@ static void fsk_tone(anetz_t *anetz, sample_t *samples, int length)
double phaseshift, phase;
int i;
phaseshift = anetz->tone_phaseshift256;
phase = anetz->tone_phase256;
phaseshift = anetz->tone_phaseshift65536;
phase = anetz->tone_phase65536;
for (i = 0; i < length; i++) {
*samples++ = dsp_sine_tone[(uint8_t)phase];
*samples++ = dsp_sine_tone[(uint16_t)phase];
phase += phaseshift;
if (phase >= 256)
phase -= 256;
if (phase >= 65536)
phase -= 65536;
}
anetz->tone_phase256 = phase;
anetz->tone_phase65536 = phase;
}
/* Provide stream of audio toward radio unit */

@ -88,8 +88,8 @@ typedef struct bnetz {
int fsk_filter_qualidx; /* index of quality array above */
int tone_detected; /* what tone has been detected */
int tone_count; /* how long has that tone been detected */
double phaseshift256[2]; /* how much the phase of sine wave changes per sample */
double phase256; /* current phase */
double phaseshift65536[2]; /* how much the phase of sine wave changes per sample */
double phase65536; /* current phase */
int telegramm; /* set, if there is a valid telegram */
sample_t *telegramm_spl; /* 16 * samples_per_bit */
int telegramm_pos; /* current sample position in telegramm_spl */

@ -34,9 +34,19 @@
#define PI 3.1415927
/* Notes on TX_PEAK_TONE level:
*
* At 2000 Hz the deviation shall be 4 kHz, so with emphasis the deviation
* at 1000 Hz would be theoretically 2 kHz. This is factor 0.714 below
* 2.8 kHz deviation we want at dBm0.
*/
/* signaling */
#define BANDWIDTH 5000.0 /* maximum bandwidth */
#define TX_PEAK_TONE 5000.0 /* peak amplitude for all tones */
#define MAX_DEVIATION 4000.0
#define MAX_MODULATION 3000.0
#define DBM0_DEVIATION 2800.0 /* deviation of dBm0 at 1 kHz */
#define TX_PEAK_TONE (4000.0 / 2000.0 * 1000.0 / DBM0_DEVIATION)
#define MAX_DISPLAY 1.4 /* something above dBm0 */
#define BIT_DURATION 0.010 /* bit length: 10 ms */
#define FILTER_STEP 0.001 /* step every 1 ms */
#define METERING_HZ 2900 /* metering pulse frequency */
@ -54,7 +64,7 @@ static double fsk_bits[2] = {
};
/* table for fast sine generation */
static sample_t dsp_sine[256];
static sample_t dsp_sine[65536];
/* global init for FSK */
void dsp_init(void)
@ -62,13 +72,8 @@ void dsp_init(void)
int i;
PDEBUG(DDSP, DEBUG_DEBUG, "Generating sine table.\n");
for (i = 0; i < 256; i++) {
dsp_sine[i] = (int)(sin((double)i / 256.0 * 2.0 * PI) * TX_PEAK_TONE);
}
if (TX_PEAK_TONE > 32767.0) {
fprintf(stderr, "TX_PEAK_TONE definition too high, please fix!\n");
abort();
for (i = 0; i < 65536; i++) {
dsp_sine[i] = sin((double)i / 65536.0 * 2.0 * PI) * TX_PEAK_TONE;
}
}
@ -85,9 +90,8 @@ int dsp_init_sender(bnetz_t *bnetz)
PDEBUG_CHAN(DDSP, DEBUG_DEBUG, "Init DSP for 'Sender'.\n");
/* set deviation and modulation parameters */
bnetz->sender.bandwidth = BANDWIDTH;
bnetz->sender.sample_deviation = 1250.0 / (double)TX_PEAK_TONE; // FIXME: calc real value
/* set modulation parameters */
sender_set_fm(&bnetz->sender, MAX_DEVIATION, MAX_MODULATION, DBM0_DEVIATION, MAX_DISPLAY);
audio_init_loss(&bnetz->sender.loss, LOSS_INTERVAL, bnetz->sender.loss_volume, LOSS_TIME);
@ -114,8 +118,8 @@ int dsp_init_sender(bnetz_t *bnetz)
/* count symbols */
for (i = 0; i < 2; 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]);
bnetz->phaseshift65536[i] = 65536.0 / ((double)bnetz->sender.samplerate / fsk_bits[i]);
PDEBUG(DDSP, DEBUG_DEBUG, "phaseshift[%d] = %.4f (must be arround 64 at 8000hz)\n", i, bnetz->phaseshift65536[i]);
}
return 0;
@ -241,9 +245,9 @@ static inline void fsk_decode_step(bnetz_t *bnetz, int pos)
// FIXME: better threshold
/* adjust level, so we get peak of sine curve */
if (level / 0.63 > 0.05 && (softbit > 0.75 || softbit < 0.25)) {
fsk_receive_tone(bnetz, bit, 1, level / 0.63662 * 32768.0 / TX_PEAK_TONE, quality);
fsk_receive_tone(bnetz, bit, 1, level / 0.63662 / TX_PEAK_TONE, quality);
} else
fsk_receive_tone(bnetz, bit, 0, level / 0.63662 * 32768.0 / TX_PEAK_TONE, quality);
fsk_receive_tone(bnetz, bit, 0, level / 0.63662 / TX_PEAK_TONE, quality);
if (bnetz->fsk_filter_bit != bit) {
/* if we have a bit change, reset sample counter to one half bit duration */
@ -256,7 +260,7 @@ static inline void fsk_decode_step(bnetz_t *bnetz, int pos)
printf("|%s|\n", debug_amplitude(quality);
#endif
/* adjust level, so we get peak of sine curve */
fsk_receive_bit(bnetz, bit, level / 0.63662 * 32768.0 / TX_PEAK_TONE, quality);
fsk_receive_bit(bnetz, bit, level / 0.63662 / TX_PEAK_TONE, quality);
bnetz->fsk_filter_sample = 10;
}
}
@ -308,17 +312,17 @@ static void fsk_tone(bnetz_t *bnetz, sample_t *samples, int length, int tone)
double phaseshift, phase;
int i;
phase = bnetz->phase256;
phaseshift = bnetz->phaseshift256[tone];
phase = bnetz->phase65536;
phaseshift = bnetz->phaseshift65536[tone];
for (i = 0; i < length; i++) {
*samples++ = dsp_sine[(uint8_t)phase];
*samples++ = dsp_sine[(uint16_t)phase];
phase += phaseshift;
if (phase >= 256)
phase -= 256;
if (phase >= 65536)
phase -= 65536;
}
bnetz->phase256 = phase;
bnetz->phase65536 = phase;
}
static int fsk_telegramm(bnetz_t *bnetz, sample_t *samples, int length)
@ -342,17 +346,17 @@ next_telegramm:
bnetz->telegramm_pos = 0;
spl = bnetz->telegramm_spl;
/* render telegramm */
phase = bnetz->phase256;
phase = bnetz->phase65536;
for (i = 0; i < 16; i++) {
phaseshift = bnetz->phaseshift256[telegramm[i] == '1'];
phaseshift = bnetz->phaseshift65536[telegramm[i] == '1'];
for (j = 0; j < bnetz->samples_per_bit; j++) {
*spl++ = dsp_sine[(uint8_t)phase];
*spl++ = dsp_sine[(uint16_t)phase];
phase += phaseshift;
if (phase >= 256)
phase -= 256;
if (phase >= 65536)
phase -= 65536;
}
}
bnetz->phase256 = phase;
bnetz->phase65536 = phase;
}
/* send audio from telegramm */

@ -43,9 +43,12 @@ extern int voice_deviation;
#define PI M_PI
#define BANDWIDTH 5500.0 /* maximum bandwidth */
#define FSK_DEVIATION 10000
#define COMPANDOR_0DB 30000
#define MAX_DEVIATION 4000.0
#define MAX_MODULATION 5280.0
#define DBM0_DEVIATION 4000.0 /* deviation of dBm0 at 1 kHz */
#define COMPANDOR_0DB 1.0 /* A level of 0dBm (1.0) shall be unaccected */
#define FSK_DEVIATION (2500.0 / DBM0_DEVIATION) /* no emphasis */
#define MAX_DISPLAY 1.4 /* something above dBm0, no emphasis */
#define BITRATE 5280.0 /* bits per second */
#define BLOCK_BITS 198 /* duration of one time slot including pause at beginning and end */
#define CUT_OFF_OFFSET 300.0 /* cut off frequency for offset filter (level correction between subsequent audio chunks) */
@ -76,7 +79,7 @@ static void dsp_init_ramp(cnetz_t *cnetz)
c = -sqrt(-c);
else
c = sqrt(c);
ramp_down[i] = (int)(c * (double)cnetz->fsk_deviation);
ramp_down[i] = c * (double)cnetz->fsk_deviation;
ramp_up[i] = -ramp_down[i];
}
}
@ -90,9 +93,8 @@ int dsp_init_sender(cnetz_t *cnetz, int measure_speed, double clock_speed[2], do
PDEBUG_CHAN(DDSP, DEBUG_DEBUG, "Init FSK for 'Sender'.\n");
/* set deviation and modulation parameters */
cnetz->sender.bandwidth = BANDWIDTH;
cnetz->sender.sample_deviation = 2500.0 / (double)FSK_DEVIATION;
/* set modulation parameters */
sender_set_fm(&cnetz->sender, MAX_DEVIATION, MAX_MODULATION, DBM0_DEVIATION, MAX_DISPLAY);
if (measure_speed) {
cnetz->measure_speed = measure_speed;
@ -119,7 +121,7 @@ int dsp_init_sender(cnetz_t *cnetz, int measure_speed, double clock_speed[2], do
}
/* create devation and ramp */
cnetz->fsk_deviation = FSK_DEVIATION; /* be sure not to overflow -32767 .. 32767 */
cnetz->fsk_deviation = FSK_DEVIATION;
dsp_init_ramp(cnetz);
cnetz->fsk_noise = noise;
@ -465,7 +467,7 @@ static int fsk_distributed_encode(cnetz_t *cnetz, const char *bits)
} while (phase < 256.0);
phase -= 256.0;
}
*marker = -32768; /* indicator for inserting speech */
*marker = 999; /* marker for inserting speech */
}
/* add 46 * (1+4+1 + 60) bits */
for (i = 0; i < 46; i++) {
@ -556,7 +558,7 @@ static int fsk_distributed_encode(cnetz_t *cnetz, const char *bits)
} while (phase < 256.0);
phase -= 256.0;
}
*marker = -32768; /* indicator for inserting speech */
*marker = 999; /* marker for inserting speech */
}
/* depending on the number of samples, return the number */
@ -706,7 +708,7 @@ again:
if (length - count < copy)
copy = length - count;
for (i = 0; i < copy; i++) {
if (*spl == -32768) {
if (*spl == 999) {
/* marker found to insert new chunk of audio */
jitter_load(&cnetz->sender.dejitter, speech_buffer, 100);
/* 1. compress dynamics */
@ -722,15 +724,9 @@ again:
pre_emphasis(&cnetz->estate, speech_buffer, speech_length);
/* change level */
if (voice_deviation != 1) {
int sample, j;
for (j = 0; j < speech_length; j++) {
sample = speech_buffer[j] * voice_deviation;
if (sample > 32767)
sample = 32767;
if (sample < -32768)
sample = -32768;
speech_buffer[j] = sample;
}
int j;
for (j = 0; j < speech_length; j++)
speech_buffer[j] *= (double)voice_deviation;
}
speech_pos = 0;
}
@ -801,7 +797,7 @@ void unshrink_speech(cnetz_t *cnetz, sample_t *speech_buffer, int count)
factor = cnetz->offset_factor;
for (i = 0; i < count; i++) {
/* change level */
x = speech_buffer[i] / voice_deviation;
x = speech_buffer[i] / (double)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;

@ -148,7 +148,7 @@ int fsk_fm_init(fsk_fm_demod_t *fsk, cnetz_t *cnetz, int samplerate, double bitr
goto error;
}
fsk->level_threshold = 655;
fsk->level_threshold = 0.1;
return 0;
@ -170,9 +170,10 @@ void fsk_fm_exit(fsk_fm_demod_t *fsk)
}
/* get levels, sync time and jitter from sync sequence or frame data */
static inline void get_levels(fsk_fm_demod_t *fsk, int *_min, int *_max, int *_avg, int *_probes, int num, double *_time, double *_jitter)
static inline void get_levels(fsk_fm_demod_t *fsk, double *_min, double *_max, double *_avg, int *_probes, int num, double *_time, double *_jitter)
{
int min = 32767, max = -32768, avg = 0, count = 0, level;
int count = 0;
double min = 0, max = 0, avg = 0, level;
double time = 0, t, sync_average, sync_time, jitter = 0;
int bit_offset;
int i;
@ -192,19 +193,20 @@ static inline void get_levels(fsk_fm_demod_t *fsk, int *_min, int *_max, int *_a
if (t > BITS_PER_SUPERFRAME / 2)
t -= BITS_PER_SUPERFRAME;
//if (fsk->cnetz->dsp_mode == DSP_MODE_SPK_V)
// printf("%d: level=%d%% @%.2f difference=%.2f\n", bit_offset, level * 100 / 65536, fsk->change_when[(fsk->change_pos - 1 - i) & 0xff], t);
// printf("%d: level=%.0f%% @%.2f difference=%.2f\n", bit_offset, level * 100, fsk->change_when[(fsk->change_pos - 1 - i) & 0xff], t);
time += t;
if (level < min)
if (i == 0 || level < min)
min = level;
if (level > max)
if (i == 0 || level > max)
max = level;
avg += level;
count++;
}
/* should never happen */
if (!count) {
*_min = *_max = *_avg = 0;
*_min = *_max = *_avg = 0.0;
return;
}
@ -219,7 +221,7 @@ static inline void get_levels(fsk_fm_demod_t *fsk, int *_min, int *_max, int *_a
*_probes = count;
*_min = min;
*_max = max;
*_avg = avg / count;
*_avg = avg / (double)count;
if (_time) {
// if (fsk->cnetz->dsp_mode == DSP_MODE_SPK_V)
@ -254,15 +256,16 @@ static inline void get_levels(fsk_fm_demod_t *fsk, int *_min, int *_max, int *_a
}
}
static inline void got_bit(fsk_fm_demod_t *fsk, int bit, int change_level)
static inline void got_bit(fsk_fm_demod_t *fsk, int bit, double change_level)
{
int min, max, avg, probes;
int probes;
double min, max, avg;
/* count bits, but do not exceed 4 bits per SPK block */
if (fsk->cnetz->dsp_mode == DSP_MODE_SPK_V) {
/* for first bit, we have only half of the modulation deviation, so we multiply level by two */
if (fsk->bit_count == 0)
change_level *= 2;
change_level *= 2.0;
if (fsk->bit_count == 4)
return;
}
@ -284,20 +287,20 @@ static inline void got_bit(fsk_fm_demod_t *fsk, int bit, int change_level)
* for all other bits in the sync sequence.
* after sync, the theshold is set to half of the average of
* all changes in the sync sequence */
if (change_level) {
fsk->level_threshold = (double)change_level / 2.0;
if (change_level > 0.0) {
fsk->level_threshold = change_level / 2.0;
} else if ((fsk->rx_sync & 0x1f) == 0x00 || (fsk->rx_sync & 0x1f) == 0x1f) {
if (fsk->cnetz->dsp_mode != DSP_MODE_SPK_V)
fsk->level_threshold = 655;
fsk->level_threshold = 0.01;
}
if (detect_sync(fsk->rx_sync)) {
fsk->sync = FSK_SYNC_POSITIVE;
got_sync:
get_levels(fsk, &min, &max, &avg, &probes, 30, &fsk->sync_time, &fsk->sync_jitter);
fsk->sync_level = (double)avg / 65535.0;
fsk->sync_level = avg / 2.0;
if (fsk->sync == FSK_SYNC_NEGATIVE)
fsk->sync_level = -fsk->sync_level;
// printf("sync (change min=%d%% max=%d%% avg=%d%% sync_time=%.2f jitter=%.2f probes=%d)\n", min * 100 / 65535, max * 100 / 65535, avg * 100 / 65535, fsk->sync_time, fsk->sync_jitter, probes);
// printf("sync (change min=%.0f%% max=%.0f%% avg=%.0f%% sync_time=%.2f jitter=%.2f probes=%d)\n", min * 100, max * 100, avg * 100, fsk->sync_time, fsk->sync_jitter, probes);
fsk->level_threshold = (double)avg / 2.0;
fsk->rx_sync = 0;
fsk->rx_buffer_count = 0;
@ -342,6 +345,10 @@ static inline void find_change(fsk_fm_demod_t *fsk)
change_at = -1;
change_positive = -1;
/* get level range (level_min and level_max) and also
* get maximum slope (change_max) and where it was
* (change_at) and what direction it went (change_positive)
*/
for (i = 0; i < fsk->bit_buffer_len; i++) {
last_s = s;
s = fsk->bit_buffer_spl[fsk->bit_buffer_pos++];
@ -417,7 +424,7 @@ void fsk_fm_demod(fsk_fm_demod_t *fsk, sample_t *samples, int length)
if (fsk->cnetz->dsp_mode != DSP_MODE_SPK_V) {
#ifdef DEBUG_DECODER
DEBUG_DECODER
puts(debug_amplitude(samples[i] / 32768.0));
puts(debug_amplitude(samples[i]));
#endif
find_change(fsk);
} else {
@ -441,7 +448,7 @@ void fsk_fm_demod(fsk_fm_demod_t *fsk, sample_t *samples, int length)
if (t >= 0.5 && t < 5.5) {
#ifdef DEBUG_DECODER
DEBUG_DECODER
puts(debug_amplitude(samples[i] / 32768.0));
puts(debug_amplitude(samples[i]));
#endif
find_change(fsk);
} else

@ -24,7 +24,7 @@ typedef struct fsk_fm_demod {
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 */
int level_threshold; /* threshold for detection of next level change */
double level_threshold; /* threshold for detection of next level change */
double bits_per_sample; /* duration of one sample in bits */
double next_bit; /* count time to detect bits */
int bit_count; /* counts bits, to match 4 bits at distributed signaling */
@ -45,7 +45,7 @@ typedef struct fsk_fm_demod {
int rx_buffer_count; /* counter when receiving bits */
/* statistics */
int change_levels[256]; /* ring buffer to store levels */
double change_levels[256]; /* ring buffer to store levels */
double change_when[256]; /* ring buffer to store time when level has changed */
uint8_t change_pos; /* index for next write */
} fsk_fm_demod_t;

@ -36,22 +36,22 @@
#define TEST_1000HZ_DB 55.0
/* sine wave for carrier to modulate to */
static double carrier[256];
static double carrier[65536];
void scrambler_init(void)
{
int i;
for (i = 0; i < 256; i++) {
for (i = 0; i < 65536; i++) {
/* 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;
carrier[i] = sin((double)i / 65536.0 * 2 * PI) * 2.0;
}
}
void scrambler_setup(scrambler_t *scrambler, int samplerate)
{
filter_lowpass_init(&scrambler->lp, CARRIER_HZ - FILTER_BELOW, samplerate, FILTER_TURNS);
scrambler->carrier_phaseshift256 = 256.0 / ((double)samplerate / CARRIER_HZ);
scrambler->carrier_phaseshift65536 = 65536.0 / ((double)samplerate / CARRIER_HZ);
}
/* Modulate samples to carriere that is twice the mirror frequency.
@ -63,18 +63,18 @@ void scrambler(scrambler_t *scrambler, sample_t *samples, int length)
double phaseshift, phase;
int i;
phaseshift = scrambler->carrier_phaseshift256;
phase = scrambler->carrier_phase256;
phaseshift = scrambler->carrier_phaseshift65536;
phase = scrambler->carrier_phase65536;
for (i = 0; i < length; i++) {
/* modulate samples to carrier */
samples[i] *= carrier[((uint8_t)phase) & 0xff];
samples[i] *= carrier[(uint16_t)phase];
phase += phaseshift;
if (phase >= 256.0)
phase -= 256.0;
if (phase >= 65536.0)
phase -= 65536.0;
}
scrambler->carrier_phase256 = phase;
scrambler->carrier_phase65536 = phase;
/* cut off carrier frequency and modulation above carrier frequency */
filter_process(&scrambler->lp, samples, length);

@ -1,8 +1,8 @@
#include "../common/filter.h"
typedef struct scrambler {
double carrier_phaseshift256; /* carrier phase shift per sample */
double carrier_phase256; /* current phase of carrier frequency */
double carrier_phaseshift65536;/* carrier phase shift per sample */
double carrier_phase65536; /* current phase of carrier frequency */
filter_t lp; /* filter to remove carrier frequency */
} scrambler_t;

@ -1492,9 +1492,9 @@ void cnetz_decode_telegramm(cnetz_t *cnetz, const char *bits, double level, doub
telegramm.jitter = jitter;
if (bit_errors)
PDEBUG_CHAN(DDSP, DEBUG_INFO, "RX Level: %.0f%% Jitter: %.2f Sync Time: %.2f (TS %.2f) Bit errors: %d %s\n", fabs(level) * 32767.0 / cnetz->fsk_deviation * 100.0, jitter, sync_time, sync_time / 396.0, bit_errors, (level < 0) ? "NEGATIVE (phone's mode)" : "POSITIVE (base station's mode)");
PDEBUG_CHAN(DDSP, DEBUG_INFO, "RX Level: %.0f%% Jitter: %.2f Sync Time: %.2f (TS %.2f) Bit errors: %d %s\n", fabs(level) / cnetz->fsk_deviation * 100.0, jitter, sync_time, sync_time / 396.0, bit_errors, (level < 0) ? "NEGATIVE (phone's mode)" : "POSITIVE (base station's mode)");
else
PDEBUG_CHAN(DDSP, DEBUG_INFO, "RX Level: %.0f%% Jitter: %.2f Sync Time: %.2f (TS %.2f) %s\n", fabs(level) * 32767.0 / cnetz->fsk_deviation * 100.0, jitter, sync_time, sync_time / 396.0, (level < 0) ? "NEGATIVE (phone's mode)" : "POSITIVE (base station's mode)");
PDEBUG_CHAN(DDSP, DEBUG_INFO, "RX Level: %.0f%% Jitter: %.2f Sync Time: %.2f (TS %.2f) %s\n", fabs(level) / cnetz->fsk_deviation * 100.0, jitter, sync_time, sync_time / 396.0, (level < 0) ? "NEGATIVE (phone's mode)" : "POSITIVE (base station's mode)");
if (cnetz->sender.loopback) {
PDEBUG(DFRAME, DEBUG_NOTICE, "Received Telegramm in loopback test mode (opcode %d = %s)\n", opcode, definition_opcode[opcode].message_name);

@ -35,6 +35,23 @@
#define DISC_TIMEOUT 30
//#define DEBUG_LEVEL
#ifdef DEBUG_LEVEL
static double level_of(double *samples, int count)
{
double level = 0;
int i;
for (i = 0; i < count; i++) {
if (samples[i] > level)
level = samples[i];
}
return level;
}
#endif
/* stream patterns/announcements */
int16_t *test_spl = NULL;
int16_t *ringback_spl = NULL;
@ -221,7 +238,7 @@ static void get_test_patterns(int16_t *samples, int length)
if (pos >= size)
*samples++ = 0;
else
*samples++ = spl[pos] >> 1;
*samples++ = spl[pos] >> 2;
if (++pos == max)
pos = 0;
}
@ -477,7 +494,8 @@ int call_init(const char *station_id, const char *audiodev, int samplerate, int
return 0;
/* open sound device for call control */
call.sound = sound_open(audiodev, NULL, NULL, 1, 0.0, samplerate, 3700.0, 0.0);
/* use +3.17 dBm0 (factor 1.44) for complete range of sound card */
call.sound = sound_open(audiodev, NULL, NULL, 1, 0.0, samplerate, 1.44, 4000.0);
if (!call.sound) {
PDEBUG(DSENDER, DEBUG_ERROR, "No sound device!\n");
@ -677,7 +695,6 @@ void process_call(int c)
default:
jitter_load(&call.dejitter, samples, count);
}
samples_to_int16(spl, samples, count);
samples_list[0] = samples;
rc = sound_write(call.sound, samples_list, count, NULL, NULL, 1);
if (rc < 0) {
@ -904,8 +921,6 @@ void call_in_release(int callref, int cause)
/* forward audio to MNCC or call instance */
void call_tx_audio(int callref, sample_t *samples, int count)
{
int16_t spl[count];
if (!callref)
return;
@ -920,6 +935,10 @@ void call_tx_audio(int callref, sample_t *samples, int count)
/* forward audio */
data->msg_type = ANALOG_8000HZ;
data->callref = callref;
#ifdef DEBUG_LEVEL
double lev = level_of(samples, count);
printf(" mobil-level: %s%.4f\n", debug_db(lev), (20 * log10(lev)));
#endif
samples_to_int16((int16_t *)data->data, samples, count);
mncc_write(buf, sizeof(buf));
@ -934,6 +953,7 @@ void call_tx_audio(int callref, sample_t *samples, int count)
} else
/* else, if no sound is used, send test tone to mobile */
if (call.state == CALL_CONNECT) {
int16_t spl[count];
get_test_patterns(spl, count);
int16_to_samples(samples, spl, count);
call_rx_audio(callref, samples, count);
@ -953,6 +973,13 @@ void call_mncc_clock(void)
data->callref = process->callref;
/* try to get patterns, else copy the samples we got */
get_process_patterns(process, (int16_t *)data->data, 160);
#ifdef DEBUG_LEVEL
sample_t samples[160];
int16_to_samples(samples, (int16_t *)data->data, 160);
double lev = level_of(samples, 160);
printf(" mobil-level: %s%.4f\n", debug_db(lev), (20 * log10(lev)));
samples_to_int16((int16_t *)data->data, samples, 160);
#endif
mncc_write(buf, sizeof(buf));
}
process = process->next;
@ -978,6 +1005,10 @@ void call_mncc_recv(uint8_t *buf, int length)
if (is_process_pattern(data->callref))
return;
int16_to_samples(samples, (int16_t *)data->data, count);
#ifdef DEBUG_LEVEL
double lev = level_of(samples, count);
printf("festnetz-level: %s %.4f\n", debug_db(lev), (20 * log10(lev)));
#endif
call_rx_audio(data->callref, samples, count);
return;
}

@ -35,6 +35,9 @@
/* Minimum level value to keep state */
#define ENVELOPE_MIN 0.001
/* Maximum level, to prevent sqrt_tab to overflow */
#define ENVELOPE_MAX 9.990
static double sqrt_tab[10000];
/*
@ -43,7 +46,7 @@ static double sqrt_tab[10000];
* Hopefully this is correct
*
*/
void init_compandor(compandor_t *state, int samplerate, double attack_ms, double recovery_ms, int unaffected_level)
void init_compandor(compandor_t *state, int samplerate, double attack_ms, double recovery_ms, double unaffected_level)
{
int i;
@ -95,6 +98,8 @@ void compress_audio(compandor_t *state, sample_t *samples, int num)
envelope = peak;
if (envelope < ENVELOPE_MIN)
envelope = ENVELOPE_MIN;
if (envelope > ENVELOPE_MAX)
envelope = ENVELOPE_MAX;
value = value / sqrt_tab[(int)(envelope / 0.001)];
//if (i > 47000.0 && i < 48144)

@ -15,7 +15,7 @@ typedef struct compandor {
} e;
} compandor_t;
void init_compandor(compandor_t *state, int samplerate, double attack_ms, double recovery_ms, int unaffected_level);
void init_compandor(compandor_t *state, int samplerate, double attack_ms, double recovery_ms, double unaffected_level);
void compress_audio(compandor_t *state, sample_t *samples, int num);
void expand_audio(compandor_t *state, sample_t *samples, int num);

@ -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, sample_t *samples, int length);
void display_wave(sender_t *sender, sample_t *samples, int length, double range);
void display_iq_init(int samplerate);
void display_iq_on(int on);

@ -20,6 +20,7 @@
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <math.h>
#include <sys/ioctl.h>
#include "sample.h"
#include "sender.h"
@ -110,10 +111,10 @@ void display_wave_limit_scroll(int on)
* HEIGHT is odd, so the center line's char is '-' (otherwise '_')
* (HEIGHT - 1) / 2 = 1, so the center line is drawn in line 1
*
* y is in range of 0..5, so these are 5 steps, where 2 to 2.999 is the
* y is in range of 0..4, so these are 5 steps, where 2 is the
* center line. this is calculated by (HEIGHT * 2 - 1)
*/
void display_wave(sender_t *sender, sample_t *samples, int length)
void display_wave(sender_t *sender, sample_t *samples, int length, double range)
{
dispwav_t *disp = &sender->dispwav;
int pos, max;
@ -147,9 +148,16 @@ void display_wave(sender_t *sender, sample_t *samples, int length)
if (pos == width) {
memset(&screen, ' ', sizeof(screen));
for (j = 0; j < width; j++) {
y = (32767 - (int32_t)buffer[j]) * (HEIGHT * 2 - 1) / 65536;
/* Input value is scaled to range -1 .. 1 and then substracted from 1,
* so the result ranges from 0 .. 2.
* HEIGHT-1 is multiplied with the range, so a HEIGHT of 3 would allow
* 0..4 (5 steps) and a HEIGHT of 11 would allow 0..20 (21 steps).
* We always use odd number of steps, so there will be a center between
* values.
*/
y = round((1.0 - buffer[j] / range) * (double)(HEIGHT - 1));
/* only display level, if it is in range */
if (y >= 0 && y < HEIGHT * 2)
if (y >= 0 && y < HEIGHT * 2 - 1)
screen[y >> 1][j] = (y & 1) ? '_' : '-';
}
sprintf(screen[0], "(chan %d", sender->kanal);

@ -25,10 +25,12 @@
#define PI M_PI
#define TX_PEAK_DTMF 7000 /* single dtmf tone peak (note this is half to total peak) */
#define DTMF_DURATION 0.100 /* duration in seconds */
static double tx_peak_dtmf_low = 0.2818 / SPEECH_LEVEL; /* -11 dBm, relative to speech level */
static double tx_peak_dtmf_high = 0.3548 / SPEECH_LEVEL;/* -9 dBm, relative to speech level */
#define DTMF_DURATION 0.100 /* duration in seconds */
static double dsp_sine_dtmf[256];
static sample_t dsp_sine_dtmf_low[65536];
static sample_t dsp_sine_dtmf_high[65536];
void dtmf_init(dtmf_t *dtmf, int samplerate)
{
@ -39,8 +41,10 @@ void dtmf_init(dtmf_t *dtmf, int samplerate)
dtmf->max = (int)((double)samplerate * DTMF_DURATION + 0.5);
// FIXME: do this globally and not per instance */
for (i = 0; i < 256