Browse Source

made 1300C conditional

Added ulaw
64bit fixes
master
Jeroen Vreeken 3 years ago
parent
commit
26b1d6aea1
11 changed files with 275 additions and 13 deletions
  1. +2
    -1
      Makefile.am
  2. +1
    -1
      configure.ac
  3. +4
    -4
      dml_reflector.c
  4. +4
    -1
      dml_trx.c
  5. +2
    -0
      dml_trx.conf
  6. +1
    -1
      dmld.conf
  7. +5
    -0
      htdocs/index.html
  8. +52
    -0
      htdocs/ulaw.js
  9. +28
    -5
      trx_dv.c
  10. +149
    -0
      ulaw.c
  11. +27
    -0
      ulaw.h

+ 2
- 1
Makefile.am View File

@ -20,7 +20,8 @@ DML_SRCS = \
TRX_SRCS = \
trx_dv.c \
alaw.c
alaw.c \
ulaw.c
FPRS_DB_SRCS = \


+ 1
- 1
configure.ac View File

@ -1,4 +1,4 @@
AC_INIT([dml], [0.0], [jeroen@vreeken.net], [https://video.vreeken.net/~dml/])
AC_INIT([dml], [0.0], [jeroen@vreeken.net], [https://dmlinking.net/])
AM_INIT_AUTOMAKE([foreign dist-xz])
AM_SILENT_RULES([yes])
LT_INIT


+ 4
- 4
dml_reflector.c View File

@ -375,7 +375,7 @@ void send_data(void *data, size_t size, uint64_t timestamp)
prev_timestamp = timestamp;
printf("+ %016lx\n", timestamp);
printf("+ %016"PRIx64"\n", timestamp);
dml_packet_send_data(dml_con, packet_id, data, size, timestamp, dk);
}
@ -422,7 +422,7 @@ int parrot_dequeue(void *data)
&(struct timespec){ 0, waitms * 1000000});
parrot_timestamp = dml_ts2timestamp(&parrot_ts);
printf("e %016lx %ld %ld %d\n", parrot_timestamp, diff, waitms, entry->duration);
printf("e %016"PRIx64" %ld %ld %d\n", parrot_timestamp, diff, waitms, entry->duration);
dml_packet_send_data(dml_con, packet_id,
entry->data, entry->size, parrot_timestamp, dk);
@ -443,7 +443,7 @@ printf("e %016lx %ld %ld %d\n", parrot_timestamp, diff, waitms, entry->duration)
data[7] = 0;
parrot_timestamp = dml_ts2timestamp(&parrot_ts);
printf("= %016lx\n", parrot_timestamp);
printf("= %016"PRIx64"\n", parrot_timestamp);
dml_packet_send_data(dml_con, packet_id, data, 8, parrot_timestamp, dk);
parrot_ts.tv_sec = 0;
}
@ -494,7 +494,7 @@ void recv_data(void *data, size_t size, uint64_t timestamp)
duration = trx_dv_duration(size - 8, mode);
// printf("mode %d state %d\n", mode, state);
printf("mode %d state %d duration: %d\n", mode, state, duration);
if (state != tx_state) {
char call[ETH_AR_CALL_SIZE];


+ 4
- 1
dml_trx.c View File

@ -55,6 +55,7 @@
static bool fullduplex = false;
static bool repeater = false;
static bool allow_commands = true;
static struct dml_stream *stream_dv;
static struct dml_stream *stream_fprs;
@ -910,7 +911,8 @@ static int command_cb(void *arg, uint8_t from[6], uint8_t to[6], char *ctrl, siz
if (command[command_len] == '#') {
if (command[0] == '*') {
command[command_len] = 0;
command_cb_handle(command+1);
if (allow_commands)
command_cb_handle(command+1);
}
command_len = 0;
} else {
@ -1014,6 +1016,7 @@ int main(int argc, char **argv)
fullduplex = atoi(dml_config_value("fullduplex", NULL, "0"));
repeater = atoi(dml_config_value("repeater", NULL, "0"));
allow_commands = atoi(dml_config_value("allow_commands", NULL, "0"));
dv_dev = dml_config_value("dv_device", NULL, NULL);
if (dv_dev) {


+ 2
- 0
dml_trx.conf View File

@ -17,6 +17,8 @@ ca = ./ca/
#fullduplex = 0
## Should we repeat our own signal?
#repeater = 0
## May we respond to on-air commands?
#allow_commands = 1
#aprsis_host = euro.aprs2.net
#aprsis_port = 14580

+ 1
- 1
dmld.conf View File

@ -1,5 +1,5 @@
## Other dmld servers to connect to.
##
server=video.vreeken.net
server=dmlinking.net
## Same server on AMPRnet:
#server=pe1rxq.ampr.org

+ 5
- 0
htdocs/index.html View File

@ -62,6 +62,7 @@ dml_httpd works!
<script src="fprs.js"></script>
<script src="aprs_symbol.js"></script>
<script src="alaw.js"></script>
<script src="ulaw.js"></script>
<script src="resample.js"></script>
<script src="libcodec2.js"></script>
<script src="codec2.js"></script>
@ -69,6 +70,7 @@ dml_httpd works!
CODEC2.MODE[65] = 'A-law';
CODEC2.MODE[85] = 'u-law';
function char2hex(c)
@ -479,6 +481,7 @@ function dmlc2()
var timeout_var = false;
dmlc2_this.alaw_data = new alaw();
dmlc2_this.ulaw_data = new ulaw();
dmlc2_this.c2 = new codec2();
this.data = function dmlc2_data(newdata) {
@ -495,6 +498,8 @@ function dmlc2()
var samples
if (newmode == 'A-law') {
samples = dmlc2_this.alaw_data.decode(c2_buf);
} else if (newmode == 'u-law') {
samples = dmlc2_this.ulaw_data.decode(c2_buf);
} else {
dmlc2_this.c2.create(bytemode);
samples = dmlc2_this.c2.decode(c2_buf);


+ 52
- 0
htdocs/ulaw.js View File

@ -0,0 +1,52 @@
/*
Copyright Jeroen Vreeken (jeroen@vreeken.net), 2016
@licstart The following is the entire license notice for the
JavaScript code in this page.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
@licend The above is the entire license notice
for the JavaScript code in this page.
*/
function ulaw()
{
this.decode = function (arraybuffer) {
var u8_view = new Uint8Array(arraybuffer);
var i;
var s_buf = new Array(u8_view.length);
for (i = 0; i < u8_view.length; i++) {
var u_val = u8_view[i];
var s_val;
/* Complement to obtain normal u-law value. */
u_val = ~u_val;
/*
* Extract and bias the quantization bits. Then
* shift up by the segment number and subtract out the bias.
*/
t = ((u_val & 0xf) << 3) + 0x84;
t <<= (u_val & 0x70) >> 4;
s_val = ((u_val & 0x80) ? (0x84 - t) : (t - 0x84));
s_buf[i] = s_val / 32767;
}
return s_buf;
}
}

+ 28
- 5
trx_dv.c View File

@ -19,6 +19,7 @@
#include <eth_ar/eth_ar.h>
#include "dml_poll.h"
#include "alaw.h"
#include "ulaw.h"
#include <arpa/inet.h>
#include <linux/if_packet.h>
@ -50,7 +51,7 @@ static int trx_dv_in_cb(void *arg)
{
uint8_t dv_frame[6 + 6 + 2 + 1500];
ssize_t ret;
ret = recv(dv_sock, dv_frame, sizeof(dv_frame), 0);
if (ret >= 14) {
uint16_t type = (dv_frame[12] << 8) | dv_frame[13];
@ -93,14 +94,20 @@ static int trx_dv_in_cb(void *arg)
mode = CODEC2_MODE_700C;
datasize = 4;
break;
#ifdef CODEC2_MODE_1300C
case ETH_P_CODEC2_1300C:
mode = CODEC2_MODE_1300C;
datasize = 7;
break;
#endif
case ETH_P_ALAW:
mode = 'A';
datasize = ret - 14;
break;
case ETH_P_ULAW:
mode = 'U';
datasize = ret - 14;
break;
case ETH_P_AR_CONTROL:
return ctrl_cb(in_cb_arg, dv_frame + 6, dv_frame, (char *)dv_frame + 14, ret - 14);
case ETH_P_FPRS:
@ -148,10 +155,17 @@ int trx_dv_transcode(uint8_t from[6], uint8_t to[6], int from_mode, uint8_t *fro
short speech[samples];
if (from_mode != 'A') {
codec2_decode(trans_dec, speech, from_dv);
} else {
alaw_decode(speech, from_dv, samples);
switch (from_mode)
{
case 'A':
alaw_decode(speech, from_dv, samples);
break;
case 'U':
ulaw_decode(speech, from_dv, samples);
break;
default:
codec2_decode(trans_dec, speech, from_dv);
break;
}
while (samples) {
@ -213,12 +227,17 @@ int trx_dv_send(uint8_t from[6], uint8_t to[6], int mode, uint8_t *dv, size_t si
case CODEC2_MODE_700C:
type = htons(ETH_P_CODEC2_700C);
break;
#ifdef CODEC2_MODE_1300C
case CODEC2_MODE_1300C:
type = htons(ETH_P_CODEC2_1300C);
break;
#endif
case 'A':
type = htons(ETH_P_ALAW);
break;
case 'U':
type = htons(ETH_P_ULAW);
break;
default:
return -1;
}
@ -291,8 +310,10 @@ int trx_dv_duration(size_t size, int mode)
return (size * 40) / 4;
case CODEC2_MODE_700C:
return (size * 40) / 4;
#ifdef CODEC2_MODE_1300C
case CODEC2_MODE_1300C:
return (size * 40) / 7;
#endif
case 'A':
return size / 8;
default:
@ -404,8 +425,10 @@ int trx_dv_init(char *dev,
limit_mode = CODEC2_MODE_700B;
} else if (!strcmp(mode, "700C")) {
limit_mode = CODEC2_MODE_700C;
#ifdef CODEC2_MODE_1300C
} else if (!strcmp(mode, "1300C")) {
limit_mode = CODEC2_MODE_1300C;
#endif
} else {
return -1;
}


+ 149
- 0
ulaw.c View File

@ -0,0 +1,149 @@
/* Mu-law code from Linux kernel
* Copyright (c) 1999 by Jaroslav Kysela <perex@perex.cz>
* Uros Bizjak <uros@kss-loka.si>
* Copyright Jeroen Vreeken (jeroen@vreeken.net), 2017
*
* Based on reference implementation by Sun Microsystems, Inc.
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "ulaw.h"
#define BIAS (0x84) /* Bias for linear code. */
#define SIGN_BIT (0x80) /* Sign bit for a u-law byte. */
#define QUANT_MASK (0xf) /* Quantization field mask. */
#define NSEGS (8) /* Number of u-law segments. */
#define SEG_SHIFT (4) /* Left shift for segment number. */
#define SEG_MASK (0x70) /* Segment field mask. */
static inline int val_seg(int val)
{
int r = 0;
val >>= 7;
if (val & 0xf0) {
val >>= 4;
r += 4;
}
if (val & 0x0c) {
val >>= 2;
r += 2;
}
if (val & 0x02)
r += 1;
return r;
}
/*
* linear2ulaw() - Convert a linear PCM value to u-law
*
* In order to simplify the encoding process, the original linear magnitude
* is biased by adding 33 which shifts the encoding range from (0 - 8158) to
* (33 - 8191). The result can be seen in the following encoding table:
*
* Biased Linear Input Code Compressed Code
* ------------------------ ---------------
* 00000001wxyza 000wxyz
* 0000001wxyzab 001wxyz
* 000001wxyzabc 010wxyz
* 00001wxyzabcd 011wxyz
* 0001wxyzabcde 100wxyz
* 001wxyzabcdef 101wxyz
* 01wxyzabcdefg 110wxyz
* 1wxyzabcdefgh 111wxyz
*
* Each biased linear code has a leading 1 which identifies the segment
* number. The value of the segment number is equal to 7 minus the number
* of leading 0's. The quantization interval is directly available as the
* four bits wxyz. * The trailing bits (a - h) are ignored.
*
* Ordinarily the complement of the resulting code word is used for
* transmission, and so the code word is complemented before it is returned.
*
* For further information see John C. Bellamy's Digital Telephony, 1982,
* John Wiley & Sons, pps 98-111 and 472-476.
*/
static uint8_t linear2ulaw(int16_t pcm_val) /* 2's complement (16-bit range) */
{
int mask;
int seg;
unsigned char uval;
/* Get the sign and the magnitude of the value. */
if (pcm_val < 0) {
pcm_val = BIAS - pcm_val;
mask = 0x7F;
} else {
pcm_val += BIAS;
mask = 0xFF;
}
if (pcm_val > 0x7FFF)
pcm_val = 0x7FFF;
/* Convert the scaled magnitude to segment number. */
seg = val_seg(pcm_val);
/*
* Combine the sign, segment, quantization bits;
* and complement the code word.
*/
uval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0xF);
return uval ^ mask;
}
/*
* ulaw2linear() - Convert a u-law value to 16-bit linear PCM
*
* First, a biased linear code is derived from the code word. An unbiased
* output can then be obtained by subtracting 33 from the biased code.
*
* Note that this function expects to be passed the complement of the
* original code word. This is in keeping with ISDN conventions.
*/
static int16_t ulaw2linear(uint8_t u_val)
{
int t;
/* Complement to obtain normal u-law value. */
u_val = ~u_val;
/*
* Extract and bias the quantization bits. Then
* shift up by the segment number and subtract out the bias.
*/
t = ((u_val & QUANT_MASK) << 3) + BIAS;
t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT;
return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS));
}
void ulaw_decode(int16_t *samples, uint8_t *ulaw, int nr)
{
int i;
for (i = 0; i < nr; i++) {
samples[i] = ulaw2linear(ulaw[i]);
}
}
void ulaw_encode(uint8_t *ulaw, int16_t *samples, int nr)
{
int i;
for (i = 0; i < nr; i++) {
ulaw[i] = linear2ulaw(samples[i]);
}
}

+ 27
- 0
ulaw.h View File

@ -0,0 +1,27 @@
/*
Copyright Jeroen Vreeken (jeroen@vreeken.net), 2017
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _INCLUDE_ULAW_H_
#define _INCLUDE_ULAW_H_
#include <stdint.h>
void ulaw_decode(int16_t *samples, uint8_t *ulaw, int nr);
void ulaw_encode(uint8_t *ulaw, int16_t *samples, int nr);
#endif /* _INCLUDE_ULAW_H_ */

Loading…
Cancel
Save