aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2017-05-16 13:48:03 +0200
committerAndreas Eversberg <jolly@eversberg.eu>2017-05-17 20:06:44 +0200
commit9d87b5bf0f216b9f67aa69b59760587b45235e4c (patch)
treeee9caa12f66e993886448da2d572b653d0b7acc0
parent12dcc6c40ffcd434e094370def1048c98e1444a5 (diff)
C-Netz: Improved transmission of speech
The speech is now correctly ramped up and down during pause bits.
-rw-r--r--src/cnetz/dsp.c63
1 files changed, 46 insertions, 17 deletions
diff --git a/src/cnetz/dsp.c b/src/cnetz/dsp.c
index a74a749..675ff9e 100644
--- a/src/cnetz/dsp.c
+++ b/src/cnetz/dsp.c
@@ -71,7 +71,7 @@ static void dsp_init_ramp(cnetz_t *cnetz)
PDEBUG(DDSP, DEBUG_DEBUG, "Generating smooth ramp table.\n");
for (i = 0; i < 256; i++) {
c = cos((double)i / 256.0 * PI);
- /* use cosine-square ramp. tests showed that phones are more
+ /* use square-root of cosine ramp. tests showed that phones are more
* happy with that. */
if (c < 0)
c = -sqrt(-c);
@@ -126,7 +126,7 @@ int dsp_init_sender(cnetz_t *cnetz, int measure_speed, double clock_speed[2])
iir_lowpass_init(&cnetz->lp, MAX_MODULATION, cnetz->sender.samplerate, 2);
/* create speech buffer */
- cnetz->dsp_speech_buffer = calloc(sizeof(sample_t), cnetz->sender.samplerate); /* buffer is greater than sr/1.1, just to be secure */
+ cnetz->dsp_speech_buffer = calloc(sizeof(sample_t), (int)(cnetz->fsk_bitduration * 70.0)); /* more to compensate clock speed. we just need it to fill 62 bits (60 bits, including pause bits). */
if (!cnetz->dsp_speech_buffer) {
PDEBUG(DDSP, DEBUG_DEBUG, "No memory!\n");
rc = -ENOMEM;
@@ -430,8 +430,15 @@ static int fsk_block_encode(cnetz_t *cnetz, const char *bits)
/* encode one distributed data block into samples
* input: 184 data bits (including barker code)
* output: samples
- * if a sample contains 0x8000, it indicates where to insert speech block
- * return number of samples */
+ * if a sample contains a marker, it indicates where to insert speech block
+ * return number of samples
+ *
+ * the marker is placed in the middle of the 6th bit.
+ * because we have a transition (ramp) in the middle of each bit.
+ * the phone will see the position of the marker as start of the 6th bit.
+ * the marker marks the pont where the speech is ramped up, so the phone
+ * will see the speech completely ramped up after the 6th bit
+ */
static int fsk_distributed_encode(cnetz_t *cnetz, const char *bits)
{
/* alloc samples, add 1 in case there is a rest */
@@ -454,7 +461,7 @@ static int fsk_distributed_encode(cnetz_t *cnetz, const char *bits)
} while (phase < 256.0);
phase -= 256.0;
}
- marker = spl;
+ marker = spl - (int)(cnetz->fsk_bitduration / 2.0); /* in the middle of the 6th bit */
for (j = 0; j < 60; j++) {
do {
*spl++ = 0;
@@ -462,7 +469,7 @@ static int fsk_distributed_encode(cnetz_t *cnetz, const char *bits)
} while (phase < 256.0);
phase -= 256.0;
}
- *marker = 999; /* marker for inserting speech */
+ *marker += 10.0; /* marker for inserting speech */
}
/* add 46 * (1+4+1 + 60) bits */
for (i = 0; i < 46; i++) {
@@ -529,7 +536,7 @@ static int fsk_distributed_encode(cnetz_t *cnetz, const char *bits)
}
last = bits[i * 4 + j];
}
- /* unmodulated bit */
+ /* ramp down */
if (last == '0') {
/* ramp up to 0 */
do {
@@ -545,7 +552,7 @@ static int fsk_distributed_encode(cnetz_t *cnetz, const char *bits)
} while (phase < 256.0);
phase -= 256.0;
}
- marker = spl;
+ marker = spl - (int)(cnetz->fsk_bitduration / 2.0); /* in the middle of the 6th bit */
for (j = 0; j < 60; j++) {
do {
*spl++ = 0;
@@ -553,7 +560,7 @@ static int fsk_distributed_encode(cnetz_t *cnetz, const char *bits)
} while (phase < 256.0);
phase -= 256.0;
}
- *marker = 999; /* marker for inserting speech */
+ *marker += 10.0; /* marker for inserting speech */
}
/* depending on the number of samples, return the number */
@@ -705,25 +712,47 @@ again:
if (length - count < copy)
copy = length - count;
for (i = 0; i < copy; i++) {
- if (*spl == 999) {
+ if (*spl > 5.0) { /* marker found */
+ int begin, end, j;
+ /* correct marker (not the best way) */
+ *spl -= 10.0;
+ begin = (int)cnetz->fsk_bitduration;
+ end = (int)(cnetz->fsk_bitduration * 61.0);
/* marker found to insert new chunk of audio */
- jitter_load(&cnetz->sender.dejitter, speech_buffer, 100);
+ jitter_load(&cnetz->sender.dejitter, speech_buffer + begin, 100);
/* 1. compress dynamics */
- compress_audio(&cnetz->cstate, speech_buffer, 100);
+ compress_audio(&cnetz->cstate, speech_buffer + begin, 100);
/* 2. upsample */
- speech_length = samplerate_upsample(&cnetz->sender.srstate, speech_buffer, 100, speech_buffer);
+ speech_length = samplerate_upsample(&cnetz->sender.srstate, speech_buffer + begin, 100, speech_buffer + begin);
/* 3. scramble */
if (cnetz->scrambler)
- scrambler(&cnetz->scrambler_tx, speech_buffer, speech_length);
+ scrambler(&cnetz->scrambler_tx, speech_buffer + begin, speech_length);
/* 4. pre-emphasis is done by cnetz code, not by common code */
/* pre-emphasis is only used when scrambler is off, see FTZ 171 TR 60 Clause 4 */
if (cnetz->pre_emphasis && !cnetz->scrambler)
- pre_emphasis(&cnetz->estate, speech_buffer, speech_length);
+ pre_emphasis(&cnetz->estate, speech_buffer + begin, speech_length);
+ /* 5.1 ramp before speech */
+ for (j = 0; j < begin; j++) {
+ /* ramp up from 0 to speech level */
+ speech_buffer[j] = speech_buffer[begin] * (ramp_up[j * 256 / begin] / cnetz->fsk_deviation / 2.0 + 0.5);
+ }
+ speech_length += begin; /* add one bit duration before speech*/
+ /* 5.2. ramp after speech */
+ while (speech_length < end) {
+ speech_buffer[speech_length] = speech_buffer[speech_length - 1];
+ speech_length++;
+ }
+ speech_length = end; /* shorten 'speech_length', if greater than 'end' */
+ for (j = 0; j < begin; j++) {
+ /* ramp down from speech level to 0 */
+ speech_buffer[end + j] = speech_buffer[end - 1] * (ramp_down[j * 256 / begin] / cnetz->fsk_deviation / 2.0 + 0.5);
+ }
+ speech_length += begin; /* add one bit duration after speech */
speech_pos = 0;
}
- /* copy speech as long as we have something left in buffer */
+ /* add speech as long as we have something left in buffer */
if (speech_pos < speech_length)
- *samples++ = speech_buffer[speech_pos++];
+ *samples++ = *spl + speech_buffer[speech_pos++];
else
*samples++ = *spl;
spl++;