version 1.4.1

This commit is contained in:
Jared Szechy 2011-08-21 03:36:53 -04:00
parent 59f8d3890e
commit b1024fba95
24 changed files with 818 additions and 395 deletions

View File

@ -1,3 +1,44 @@
1.4.1
New features:
Several new sync types for existing formats now recognized:
Decodes voice from NXDN 4800 (6.25kHz) signals
Decodes voice from NXDN 9600 (12.5kHz) repeater output
Decodes voice from DMR/MotoTRBO simplex/repeater input
Decodes voice from X2-TDMA simplex/repeater input
Fixed bugs:
renamed "input:" to "inlvl:" to reduce confusion. This value
indicates the audio input level, NOT the "decode success
rate". Voice decode errors are indicated by the errorbars "=".
1.4
New features:
Decodes voice from NXDN 9600 (12.5 kHz) simplex/repeater input
NXDN96 frames enabled by default
Improved resistance to NXDN96 sync false positives
Fixed bugs:
.wav file header updated after playing .imb/.amb data files
.imb/.amb files now have correct tgid in filename
1.3.1 New features:
Support for ProVoice EA sync
CTRL-C is now caught so .wav files can be properly closed
DSD now shows mbelib version as well as it's own version
-R resume option now triggers on any TSDU so control channels can be left
in conventional scanlists.
Auto output gain now has 0.5 second hold time for faster error burst recovery
(was 1.5 seconds)
Audio output upsampling function simplified and improved
Fixed bugs:
DSD_Author.pgp now has correct public key (was copy of mbelib_Author key)
TGID and SRC are now cleared after TDULC or TDU.
Voice error counter is now reset in noCarrier()
TGID and SRC were not displaying for X2-TDMA frames
Fixed buffer issue in resumeScan()
Fixed error in .wav file headers preventing playback on some apps
1.3 New features:
Decodes voice from ProVoice signals (requires -fp option)
algid and kid are now shown in hex notation
@ -17,7 +58,7 @@
Fixed bugs:
nac was showing wrong ID
p25 metadata (lcinfo, mfid, lfcormat, mi, keyid, algid, lsd) are now
P25 metadata (lcinfo, mfid, lfcormat, mi, keyid, algid, lsd) are now
printed out in the correct bit order (MSB -> LSB), was reversed.
fixed serveral bugs in dsd_upsample.c, with improved quality

View File

@ -1,30 +1,30 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.4.10
mQENBEufusYBCADN1SNkRkQzdLM02MCjen8KQmfuA38MrQIV0dZLpPJcn1+hsvZZ
KWvpUiWCNw1ClGRsJAT5cjonndi1PV7tpzQz+CyMqSP5OwR40eTJBoZhl74hdmU8
QvcKkJ32khSsOXMo60NHk5iIMDELzOGqq57NHhbunj6NtYog2mR5+WT37JLCvF/q
dvYl2KkRwEHD76/b/O1CyheiiqNMGBb13zPN0qO/PRlENSgViLcDh9qVj4ETNNS6
zMlP4D4pa07iED4Ua31wiXI04ReznnmvMqzQb8uFbg7d98F3bZpsbNURbmsFHMhj
c9qw65nzaMa3OHfZ3Qwl4XRlNqEzZrclIZADABEBAAG0DW1iZWxpYiBBdXRob3KJ
ATgEEwECACIFAkufusYCGwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEE+Y
6GPqXv4sI/4H/RsumInT5GtDdBTgxt3lERqc5GF8tI5CAQX9DUMMkKxQ306Fgb4M
ISYdepgL6BlbtSyMdKpKsDLScNA6YXER4gMU1nhhyBulqj41kAfsVbG8hiTBy5Ri
FTo36HrC//Zj1MlaTCB8Rl6B6IftAHIb1U+Gda3WnLDe+R5Pym/76TqeYx23PnJl
V+qfrkjbNyOb2bttyko2iccm9DSq/I1OF0Ufz3P60ssUwHW/b2S6WOXRxiZIq0sz
8pAweUFCxIMWo+XYlSpRtwpebfx+JoHJKdW1cSCgY9jwVsOZO1zxc8P+jr3ByiIR
ZPd0PfBt/AHuC6Hmw9nC12e49+4qsHkj50S5AQ0ES5+6xgEIALf60WjqHm552FIX
KqmG0TIrXpCsYoTWzDdO5j0Ro6fmg9U48BqDH5aS4YRvuyPE7q6DGYEnXF5EIPtU
FhUk4FMmez5eMg91UW4Qjqx8M3reoBROYocM5Nfbc9w7St8+3oRS6rUBIh/B6o4O
kEjkoW3R7O3uFpC53Oi9IVhx/joWxhi430RrUTig5CQzuPFTAHd3xJVE6Pv44nsY
/PsOhBLu2Z3kRkvjcGbsGDlAl2bDEobzQdsqXDD8gJkF5W4IeBKvRC54SE0FSm57
G1gadhZ7vT4DWQZvYYKXR+AE7FTcopoAFHdapYokOGLHCguabyeZ5q7+s7J4nddL
p5yq8ikAEQEAAYkBHwQYAQIACQUCS5+6xgIbDAAKCRBPmOhj6l7+LPi6B/sEkDkm
Qs/aTz9HDANBAbTuDZTY4WBbkPdFos3xxC2Z/TH5m4bfHEkvNk5WD+j+vYB3exAc
uBi7ZiqibRpap4kiAiKKCRXOyvmEmrjKB5wOWbRpkdTeEdPcpsQ4dDDw1ZUKwzjN
1jI/9GOgq49nAGdlU59f3IdPut6oQNq9vrtanTq2xHVN/rOhV9GLE6gLX1YWkpIH
zYSUheGPsnv4sWRsQDTB7xmF+6RZzjmauKNwsGFscX1TenOWtUbYb9qFCwvNMOSk
51sEaD6PK6wWTXMqQlgjaoGqh1ZaePgT0QTh1W/bvOD0fL5NEToJl2h/lBSvO+ez
R9B++dt5JX9BMxAH
=puA7
mQENBEufuqsBCADAtWFE1qE3xqJE4xggUn6id0fVulM7y+rSH1VPxo7Ps9duc/O9
VegEx8+N5KphDROS4RgHxMiS1O8Qy5Hpq4gEp6RvLNj3s+0DMwqRZoA0tBCkNmvF
K7sF+GncrOu/NZkDIZ8emN9NWWeWynWJvuM2H5HQA9yCq+YTFae5sgyr3APC3xh4
OkTuVMcclGTJdVrISlNBDpo/AZLJ/nV0SgITpiZVsI4RSNiQPP1kX+2fIDEAwtxN
3HIDyegDoX36cOItsb05zHkLxoUoZnWoxMvV3rwnqXg5cr6PWfiwgqWd0avl1sg6
abpR6MKV68OCpTkqMrDIXJJrM2sTz+ZB2bBtABEBAAG0CkRTRCBBdXRob3KJATgE
EwECACIFAkufuqsCGwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEPqiY10/
HX/Q11UH/0ZutGQWLZyZD5ZqVdBeYEf6IKhKhaC2vD/+5zUJ2cIgT5xJVTPCKN7X
sygBANJc9GyPRYRvQecdcTHR5B+wUKCPeibv9iQuU3v7Uqb5edXEh2b4jOMWNvHJ
l3lqBdUefuQdbc2xXCPgn+GkyexXEBsVF3hCzWV9r4bCpY57iWUYZZT0wAbN81hz
jPKCCRmF+gZUUufxyhUGq/+eAKeUll6lgG5Ms2YKOlUMphfMav45qgWZHj1DASOV
wPsiIVUaC6+GtHTTzHYRL05ydxxduX+yyKDO1emCE4fx1n3jdwToHLRrC1ui+AJM
Q1s+bp+bGmMYaYaKc/JtNHcN8mbWyCK5AQ0ES5+6qwEIAJvPrnv2QO5Be3FRsnYL
qbA1h/Lj0SjnuimaiNOzCYFIYtusLpyWjwWUnOEXdw5FoExqUStOHJ557SDG/zFB
qy+DsNC9ncSRZ5U2tUQUtt50m2lpYvoy/sVf3oN+IsyZ5hZpiAwrxlyMC/aoGR3C
6ZlLkZ42azNCmEmoBniIxQ+XwhwkLMRsOnqLoFyXB9CcDFIXeEhZkVWZT0B5+20f
yGSBDJ6VcIAASoaIyvSwU9l/DT7D/s0J8WnZQZmRdrsZ3Ikj0Sv/4D2MJnCVJTSw
DHq5Sf7DmUq/WD0iWRLEXWmPt9w3WxP4imhtmIpICxCDoeQUTkqFpOTf29sVcpPt
838AEQEAAYkBHwQYAQIACQUCS5+6qwIbDAAKCRD6omNdPx1/0O8ECADAcPORjGFl
RnIrsgiVMp82GQ7hnZZxktU1WVVx8EsPTT1DD79nIoeKI+UcenzuOGyTX7DGcy+P
rWntUbt2ZygPTbP5Wu6zd845y9EzjxQ5q0vDF4oAefQptwqGDVeO/KBv9cZLbnih
VEjQELgC/rVB7nd5p83EL5vb8qL/Eiu65stxwZ3QOT9pp2bsAPk6LJWWnVqJroKI
Pc6KWG7n6mMJPbhFmE8Ld2lcNlSKQwLHIxDocL2GAqh5S5hJeGg2oLMFpy0g2Ron
643w0zPfpKC15TlnkJDCIgtRlHovrs42Qkypz9y3e8yOL9O0RLYIKbuKw4mNR3cT
OdeV+TjfiZ5I
=2oe6
-----END PGP PUBLIC KEY BLOCK-----

View File

@ -14,7 +14,7 @@
# PERFORMANCE OF THIS SOFTWARE.
CC = gcc
CFLAGS = -O2
CFLAGS = -O2 -Wall
INCLUDES = -I. -I/usr/local/include -I/usr/include
LIBS = -L/usr/local/lib -lm -lmbe
INSTALL=install
@ -24,7 +24,7 @@ DEST_BASE=/usr/local
DEST_INC=${DEST_BASE}/include
DEST_LIB=${DEST_BASE}/lib
DEST_BIN=${DEST_BASE}/bin
OBJS = dsd_main.o dsd_symbol.o dsd_dibit.o dsd_frame_sync.o dsd_file.o dsd_audio.o dsd_serial.o dsd_frame.o dsd_mbe.o dsd_upsample.o p25p1_hdu.o p25p1_ldu1.o p25p1_ldu2.o p25p1_tdulc.o p25_lcw.o x2tdma_voice.o x2tdma_data.o dstar.o nxdn96.o dmr_voice.o dmr_data.o provoice.o
OBJS = dsd_main.o dsd_symbol.o dsd_dibit.o dsd_frame_sync.o dsd_file.o dsd_audio.o dsd_serial.o dsd_frame.o dsd_mbe.o dsd_upsample.o p25p1_hdu.o p25p1_ldu1.o p25p1_ldu2.o p25p1_tdulc.o p25_lcw.o x2tdma_voice.o x2tdma_data.o dstar.o nxdn_voice.o nxdn_data.o dmr_voice.o dmr_data.o provoice.o
all: dsd
@ -84,8 +84,14 @@ x2tdma_data.o: x2tdma_data.c x2tdma_const.h dsd.h config.h
dstar.o: dstar.c dstar_const.h dsd.h config.h
$(CC) $(CFLAGS) $(INCLUDES) -c dstar.c -o dstar.o
nxdn96.o: nxdn96.c nxdn96_const.h dsd.h config.h
$(CC) $(CFLAGS) $(INCLUDES) -c nxdn96.c -o nxdn96.o
nxdn48_voice.o: nxdn48_voice.c nxdn_const.h dsd.h config.h
$(CC) $(CFLAGS) $(INCLUDES) -c nxdn48_voice.c -o nxdn48_voice.o
nxdn_voice.o: nxdn_voice.c nxdn_const.h dsd.h config.h
$(CC) $(CFLAGS) $(INCLUDES) -c nxdn_voice.c -o nxdn_voice.o
nxdn_data.o: nxdn_data.c nxdn_const.h dsd.h config.h
$(CC) $(CFLAGS) $(INCLUDES) -c nxdn_data.c -o nxdn_data.o
dmr_voice.o: dmr_voice.c dmr_const.h dsd.h config.h
$(CC) $(CFLAGS) $(INCLUDES) -c dmr_voice.c -o dmr_voice.o

95
README
View File

@ -1,4 +1,4 @@
Digital Speech Decoder 1.3
Digital Speech Decoder 1.4
Copyright (C) 2010 DSD Author
GPG Key ID: 0x3F1D7FD0 (74EF 430D F7F2 0A48 FCE6 F630 FAA2 635D 3F1D 7FD0)
@ -16,10 +16,10 @@ PERFORMANCE OF THIS SOFTWARE.
DSD is able to decode several digital voice formats from discriminator
tap audio and synthesize the decoded speech. Speech
synthesis requires mbelib, which is a separate package. DSD 1.3
synthesis requires mbelib, which is a separate package. DSD 1.4.1
requires mbelib 1.1 or later.
Supported formats in version 1.3:
Supported formats in version 1.4.1:
P25 Phase 1 Widely deployed radio standard used in public safety
and amateur radio.
@ -46,19 +46,18 @@ PERFORMANCE OF THIS SOFTWARE.
DMR/MOTOTRBO "Digital Mobile Radio" Eurpoean two slot TDMA standard.
MOTOTRBO is a popular implementation of this standard.
Support includes decoding and synthesis of speech and
the ability to save and replay .amb data files.
Support includes decoding and synthesis of speech and
the ability to save and replay .amb data files.
NXDN Digital radio standard used by NEXEDGE and IDAS brands.
Supports both 9600 baud (12.5 kHz) and
4800 baud (6.25 kHz) digital voice.
Support includes decoding and synthesis of speech and
the ability to save and replay .amb data files.
Development (no speech) support only:
NXDN (9600) Digital radio standard used by NEXEDGE and IDAS brands.
Development support only. DSD recognizes frames and can
extract the voice bits but speech is not yet decoded.
The issue is likely either an unusual interleave pattern
or a pseudo-random bit mask initialized by a "color code"
Note: not enabled by default, use -fn to enable.
D-STAR Amateur radio digital voice standard
Development support only. DSD recognized frames and can
@ -66,9 +65,9 @@ PERFORMANCE OF THIS SOFTWARE.
D-STAR likely uses a version of AMBE not yet supported by
mbelib. The voice bit interleave pattern also needs to be
determined.
Note: not enabled by default, use -fn to enable.
Note: not enabled by default, use -fd to enable.
Unsupported formats in version 1.3 considered for future development:
Unsupported formats in version 1.4 considered for future development:
P25 Phase 2 This is not yet a published standard. Full support is
expected once the standard is published and there are
@ -78,10 +77,7 @@ PERFORMANCE OF THIS SOFTWARE.
OpenSKY It is possible that the four slot version uses a vocoder
supported by mbelib. The two slot version does not.
NXDN (4800) This should be supportable as soon as we have .wav files
or access to a radio programmed in this format.
Supported demodulation optimizations in version 1.3:
Supported demodulation optimizations in version 1.4:
C4FM Continuous envelope 2 or 4 level FSK with relatively
sharp transitions between symbols. Used by most P25
@ -147,19 +143,19 @@ Display modes
Errorbars mode output for P25 Phase 1 looks like this:
Sync: -p25p1 mod: C4FM input: 39% nac: 5C2 src: 0 tg: 32464 TDULC
Sync: -p25p1 mod: C4FM input: 39% nac: 5C2 src: 0 tg: 32464 TDULC
Sync: -p25p1 mod: C4FM input: 39% nac: 5C2 src: 0 tg: 32464 TDULC
Sync: -p25p1 mod: C4FM input: 39% nac: 5C2 src: 0 tg: 32464 TDULC
Sync: -p25p1 mod: C4FM input: 38% nac: 5C2 src: 0 tg: 32464 TDU
Sync: -p25p1 mod: C4FM input: 38% nac: 5C2 src: 0 tg: 32464 HDU
Sync: -p25p1 mod: C4FM input: 42% nac: 5C2 src: 0 tg: 32464 LDU1 e:
Sync: (-p25p1) mod: C4FM input: 39% nac: 5C2 src: 52610 tg: 32464 (LDU2) e:
Sync: -p25p1 mod: C4FM input: 38% nac: 5C2 src: 52610 tg: 32464 LDU1 e:
Sync: -p25p1 mod: C4FM input: 39% nac: 5C2 src: 52610 tg: 32464 LDU2 e:
Sync: -p25p1 mod: C4FM input: 39% nac: 5C2 src: 52610 tg: 32464 LDU1 e:
Sync: -p25p1 mod: C4FM input: 39% nac: 5C2 src: 52610 tg: 32464 LDU2 e:
Sync: -p25p1 mod: C4FM input: 39% nac: 5C2 src: 52610 tg: 32464 LDU1 e:
Sync: -P25p1 mod: C4FM inlvl: 39% nac: 5C2 src: 0 tg: 32464 TDULC
Sync: -P25p1 mod: C4FM inlvl: 39% nac: 5C2 src: 0 tg: 32464 TDULC
Sync: -P25p1 mod: C4FM inlvl: 39% nac: 5C2 src: 0 tg: 32464 TDULC
Sync: -P25p1 mod: C4FM inlvl: 39% nac: 5C2 src: 0 tg: 32464 TDULC
Sync: -P25p1 mod: C4FM inlvl: 38% nac: 5C2 src: 0 tg: 32464 TDU
Sync: -P25p1 mod: C4FM inlvl: 38% nac: 5C2 src: 0 tg: 32464 HDU
Sync: -P25p1 mod: C4FM inlvl: 42% nac: 5C2 src: 0 tg: 32464 LDU1 e:
Sync: (-P25p1) mod: C4FM inlvl: 39% nac: 5C2 src: 52610 tg: 32464 (LDU2) e:
Sync: -P25p1 mod: C4FM inlvl: 38% nac: 5C2 src: 52610 tg: 32464 LDU1 e:
Sync: -P25p1 mod: C4FM inlvl: 39% nac: 5C2 src: 52610 tg: 32464 LDU2 e:
Sync: -P25p1 mod: C4FM inlvl: 39% nac: 5C2 src: 52610 tg: 32464 LDU1 e:
Sync: -P25p1 mod: C4FM inlvl: 39% nac: 5C2 src: 52610 tg: 32464 LDU2 e:
Sync: -P25p1 mod: C4FM inlvl: 39% nac: 5C2 src: 52610 tg: 32464 LDU1 e:
"Sync" indicates the frame type detected and whether the polarity is
positive or negative. DSD automatically detects and handles either
@ -179,7 +175,7 @@ Sync: -p25p1 mod: C4FM input: 39% nac: 5C2 src: 52610 tg: 32464 LDU1 e:
"mod" indicates the current demodulation optimizations.
"input" indicates the audio input level. QPSK signals tend to appear
"inlvl" indicates the audio input level. QPSK signals tend to appear
much "wider" than C4FM from a discriminator tap so it is important
to set your input gain using a QPSK signal if you plan to montir them.
It is not necessary nor desirable to get to 100%, in fact your sound
@ -189,7 +185,7 @@ Sync: -p25p1 mod: C4FM input: 39% nac: 5C2 src: 52610 tg: 32464 LDU1 e:
"nac" is the P25 Phase 1 Network Access Code. This is a 12 bit field
in each P25 Phase 1 header. It should not be confused with the 16
bit System ID used in non-p25 trunking control channels.
bit System ID used in non-P25 trunking control channels.
"src" is the radio id of the trasmitting subscriber unit.
@ -207,10 +203,10 @@ Sync: -p25p1 mod: C4FM input: 39% nac: 5C2 src: 52610 tg: 32464 LDU1 e:
Errorbars mode output for X2-TDMA looks like this:
Sync: -X2-TDMA mod: QPSK input: 59% src: 17211 tg: 197 [SLOT0] slot1 VOICE e:
Sync: -X2-TDMA mod: QPSK input: 47% src: 17211 tg: 197 [SLOT0] slot1 VOICE e:
Sync: -X2-TDMA mod: QPSK input: 43% src: 17211 tg: 197 [SLOT0] slot1 VOICE e:
Sync: (-X2-TDMA) mod: QPSK input: 28% src: 17211 tg: 197 [SLOT0] slot1 VOICE e:
Sync: -X2-TDMA mod: QPSK inlvl: 59% src: 17211 tg: 197 [SLOT0] slot1 VOICE e:
Sync: -X2-TDMA mod: QPSK inlvl: 47% src: 17211 tg: 197 [SLOT0] slot1 VOICE e:
Sync: -X2-TDMA mod: QPSK inlvl: 43% src: 17211 tg: 197 [SLOT0] slot1 VOICE e:
Sync: (-X2-TDMA) mod: QPSK inlvl: 28% src: 17211 tg: 197 [SLOT0] slot1 VOICE e:
DMR/MOTOTRBO display is similar except it does not yet show source
and talkgroup information.
@ -303,10 +299,10 @@ Display Options
information displayed in Errorbars mode:
-e Show Frame Info and errorbars (default)
-pe Show p25 encryption sync bits
-pl Show p25 link control bits
-ps Show p25 status bits and low speed data
-pt Show p25 talkgroup info
-pe Show P25 encryption sync bits
-pl Show P25 link control bits
-ps Show P25 status bits and low speed data
-pt Show P25 talkgroup info
-q Don't show Frame Info/errorbars
-s Datascope (disables other display options)
-t Show symbol timing during sync
@ -439,7 +435,8 @@ Scanner control options:
-B <num> Serial port baud rate (default=115200)
-C <device> Serial port for scanner control (default=/dev/ttyUSB0)
-R <num> Resume scan after <num> TDULC frames or any PDU
-R <num> Resume scan after <num> TDULC frames or any PDU or TSDU
On some P25 systems Packet Data Units (PDU) are sent on the same
frequencies used for voice traffic. If done constantly this can
@ -453,7 +450,8 @@ Decoder options
-fa Auto-detect frame type (default)
-f1 Decode only P25 Phase 1
-fd Decode only D-STAR* (no audio)
-fn Decode only NXDN96* (no audio)
-fi Decode only NXDN48* (6.25 kHz) / IDAS*
-fn Decode only NXDN96 (12.5 kHz)
-fp Decode only ProVoice*
-fr Decode only DMR/MOTOTRBO
-fx Decode only X2-TDMA
@ -465,10 +463,13 @@ Decoder options
-xx Expect non-inverted X2-TDMA signal
-xr Expect inverted DMR/MOTOTRBO signal
* denotes frame types that cannot be auto-detected.
NXDN and D-STAR are not enabled by default as they are for development
testing only and have shorter frame sync patterns that are prone to
false triggering.
ProVoice and NXDN48 not auto-detected as use different symbol
rates (9600 and 2400) than most formats (4800). D-STAR is not
enabled by default as voice decode does not work and it has a
short sync word that is prone to false triggering. It is included
for development/testing only.
MBE speech synthesis is broken down into two main types of sounds,
"Voiced" and "Unvoiced". Voiced speech bands are synthesized with

0
configure vendored Normal file → Executable file
View File

View File

@ -206,7 +206,7 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
printf ("%s ", syncbits);
#endif
if (strcmp (sync, DMR_DATA_SYNC) == 0)
if ((strcmp (sync, DMR_BS_DATA_SYNC) == 0) || (strcmp (sync, DMR_MS_DATA_SYNC) == 0))
{
if (state->currentslot == 0)
{
@ -217,17 +217,6 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
sprintf (state->slot1light, "[slot1]");
}
}
else if (strcmp (sync, DMR_VOICE_SYNC) == 0)
{
if (state->currentslot == 0)
{
sprintf (state->slot0light, "[SLOT0]");
}
else
{
sprintf (state->slot1light, "[SLOT1]");
}
}
if (opts->errorbars == 1)
{

View File

@ -32,6 +32,7 @@ processDMRvoice (dsd_opts * opts, dsd_state * state)
char syncdata[25];
char cachdata[13];
int mutecurrentslot;
int msMode;
#ifdef DMR_DUMP
int k;
@ -40,6 +41,7 @@ processDMRvoice (dsd_opts * opts, dsd_state * state)
#endif
mutecurrentslot = 0;
msMode = 0;
dibit_p = state->dibit_buf_p - 144;
for (j = 0; j < 6; j++)
@ -193,7 +195,7 @@ processDMRvoice (dsd_opts * opts, dsd_state * state)
sync[24] = 0;
syncdata[24] = 0;
if (strcmp (sync, DMR_DATA_SYNC) == 0)
if ((strcmp (sync, DMR_BS_DATA_SYNC) == 0) || (strcmp (sync, DMR_MS_DATA_SYNC) == 0))
{
mutecurrentslot = 1;
if (state->currentslot == 0)
@ -205,7 +207,7 @@ processDMRvoice (dsd_opts * opts, dsd_state * state)
sprintf (state->slot1light, "[slot1]");
}
}
else if (strcmp (sync, DMR_VOICE_SYNC) == 0)
else if ((strcmp (sync, DMR_BS_VOICE_SYNC) == 0) || (strcmp (sync, DMR_MS_VOICE_SYNC) == 0))
{
mutecurrentslot = 0;
if (state->currentslot == 0)
@ -217,6 +219,10 @@ processDMRvoice (dsd_opts * opts, dsd_state * state)
sprintf (state->slot1light, "[SLOT1]");
}
}
if ((strcmp (sync, DMR_MS_VOICE_SYNC) == 0) || (strcmp (sync, DMR_MS_DATA_SYNC) == 0))
{
msMode = 1;
}
if ((j == 0) && (opts->errorbars == 1))
{
@ -318,7 +324,7 @@ processDMRvoice (dsd_opts * opts, dsd_state * state)
sync[24] = 0;
syncdata[24] = 0;
if (strcmp (sync, DMR_DATA_SYNC) == 0)
if ((strcmp (sync, DMR_BS_DATA_SYNC) == 0) || (msMode == 1))
{
if (state->currentslot == 0)
{
@ -329,7 +335,7 @@ processDMRvoice (dsd_opts * opts, dsd_state * state)
sprintf (state->slot0light, " slot0 ");
}
}
else if (strcmp (sync, DMR_VOICE_SYNC) == 0)
else if (strcmp (sync, DMR_BS_VOICE_SYNC) == 0)
{
if (state->currentslot == 0)
{

57
dsd.h
View File

@ -18,6 +18,7 @@
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#define __USE_XOPEN
#include <time.h>
@ -36,6 +37,12 @@
#include <math.h>
#include <mbelib.h>
/*
* global variables
*/
int exitflag;
typedef struct
{
int onesymbol;
@ -71,7 +78,8 @@ typedef struct
int frame_dstar;
int frame_x2tdma;
int frame_p25p1;
int frame_nxdn;
int frame_nxdn48;
int frame_nxdn96;
int frame_dmr;
int frame_provoice;
int mod_c4fm;
@ -100,6 +108,7 @@ typedef struct
float *audio_out_temp_buf_p;
int audio_out_idx;
int audio_out_idx2;
int wav_out_bytes;
int center;
int jitter;
int synctype;
@ -155,19 +164,35 @@ typedef struct
/*
* Frame sync patterns
*/
#define INV_FRAME_SYNC "333331331133111131311111"
#define FRAME_SYNC "111113113311333313133333"
#define X2TDMA_VOICE_SYNC "113131333331313331113311"
#define X2TDMA_DATA_SYNC "331313111113131113331133"
#define DSTAR_SYNC "313131313133131113313111"
#define INV_DSTAR_SYNC "131313131311313331131333"
#define INV_NXDN96_SYNC "313133113131111333"
#define NXDN96_SYNC "131311331313333111"
#define DMR_DATA_SYNC "313333111331131131331131"
#define DMR_VOICE_SYNC "131111333113313313113313"
#define INV_PROVOICE_SYNC "31313111333133133311331133113311"
#define PROVOICE_SYNC "13131333111311311133113311331133"
#define INV_P25P1_SYNC "333331331133111131311111"
#define P25P1_SYNC "111113113311333313133333"
#define X2TDMA_BS_VOICE_SYNC "113131333331313331113311"
#define X2TDMA_BS_DATA_SYNC "331313111113131113331133"
#define X2TDMA_MS_DATA_SYNC "313113333111111133333313"
#define X2TDMA_MS_VOICE_SYNC "131331111333333311111131"
#define DSTAR_SYNC "313131313133131113313111"
#define INV_DSTAR_SYNC "131313131311313331131333"
#define NXDN_MS_DATA_SYNC "313133113131111333"
#define INV_NXDN_MS_DATA_SYNC "131311331313333111"
#define NXDN_MS_VOICE_SYNC "313133113131113133"
#define INV_NXDN_MS_VOICE_SYNC "131311331313331311"
#define INV_NXDN_BS_DATA_SYNC "131311331313333131"
#define NXDN_BS_DATA_SYNC "313133113131111313"
#define INV_NXDN_BS_VOICE_SYNC "131311331313331331"
#define NXDN_BS_VOICE_SYNC "313133113131113113"
#define DMR_BS_DATA_SYNC "313333111331131131331131"
#define DMR_BS_VOICE_SYNC "131111333113313313113313"
#define DMR_MS_DATA_SYNC "311131133313133331131113"
#define DMR_MS_VOICE_SYNC "133313311131311113313331"
#define INV_PROVOICE_SYNC "31313111333133133311331133113311"
#define PROVOICE_SYNC "13131333111311311133113311331133"
#define INV_PROVOICE_EA_SYNC "13313133113113333311313133133311"
#define PROVOICE_EA_SYNC "31131311331331111133131311311133"
/*
* function prototypes
@ -189,6 +214,7 @@ void openMbeInFile (dsd_opts * opts, dsd_state * state);
void closeMbeOutFile (dsd_opts * opts, dsd_state * state);
void openMbeOutFile (dsd_opts * opts, dsd_state * state);
void openWavOutFile (dsd_opts * opts, dsd_state * state);
void closeWavOutFile (dsd_opts * opts, dsd_state * state);
void printFrameInfo (dsd_opts * opts, dsd_state * state);
void processFrame (dsd_opts * opts, dsd_state * state);
void printFrameSync (dsd_opts * opts, dsd_state * state, char *frametype, int offset, char *modulation);
@ -199,6 +225,8 @@ void initOpts (dsd_opts * opts);
void initState (dsd_state * state);
void usage ();
void liveScanner (dsd_opts * opts, dsd_state * state);
void cleanupAndExit (dsd_opts * opts, dsd_state * state);
void sigfun (int sig);
int main (int argc, char **argv);
void playMbeFiles (dsd_opts * opts, dsd_state * state, int argc, char **argv);
void processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char ambe_fr[4][24], char imbe7100_fr[7][24]);
@ -207,7 +235,8 @@ void resumeScan (dsd_opts * opts, dsd_state * state);
int getSymbol (dsd_opts * opts, dsd_state * state, int have_sync);
void upsample (dsd_state * state, float invalue);
void processDSTAR (dsd_opts * opts, dsd_state * state);
void processNXDN96 (dsd_opts * opts, dsd_state * state);
void processNXDNVoice (dsd_opts * opts, dsd_state * state);
void processNXDNData (dsd_opts * opts, dsd_state * state);
void processP25lcw (dsd_opts * opts, dsd_state * state, char *lcformat, char *mfid, char *lcinfo);
void processHDU (dsd_opts * opts, dsd_state * state);
void processLDU1 (dsd_opts * opts, dsd_state * state);

View File

@ -41,14 +41,14 @@ processAudio (dsd_opts * opts, dsd_state * state)
*state->aout_max_buf_p = max;
state->aout_max_buf_p++;
state->aout_max_buf_idx++;
if (state->aout_max_buf_idx > 74)
if (state->aout_max_buf_idx > 24)
{
state->aout_max_buf_idx = 0;
state->aout_max_buf_p = state->aout_max_buf;
}
// lookup max history
for (i = 0; i < 75; i++)
for (i = 0; i < 25; i++)
{
maxbuf = state->aout_max_buf[i];
if (maxbuf > max)
@ -157,6 +157,7 @@ writeSynthesizedVoice (dsd_opts * opts, dsd_state * state)
int n;
short aout_buf[160];
short *aout_buf_p;
ssize_t result;
aout_buf_p = aout_buf;
state->audio_out_temp_buf_p = state->audio_out_temp_buf;
@ -175,18 +176,21 @@ writeSynthesizedVoice (dsd_opts * opts, dsd_state * state)
state->audio_out_temp_buf_p++;
}
write (opts->wav_out_fd, aout_buf, 320);
result = write (opts->wav_out_fd, aout_buf, 320);
fflush (opts->wav_out_f);
state->wav_out_bytes += 320;
}
void
playSynthesizedVoice (dsd_opts * opts, dsd_state * state)
{
ssize_t result;
if (state->audio_out_idx > opts->delay)
{
// output synthesized speech to sound card
write (opts->audio_out_fd, (state->audio_out_buf_p - state->audio_out_idx), (state->audio_out_idx * 2));
result = write (opts->audio_out_fd, (state->audio_out_buf_p - state->audio_out_idx), (state->audio_out_idx * 2));
state->audio_out_idx = 0;
}

View File

@ -125,7 +125,7 @@ readAmbe2250Data (dsd_opts * opts, dsd_state * state, char *ambe_d)
}
}
b = fgetc (opts->mbe_in_f);
ambe_d[48] = b;
ambe_d[48] = (b & 1);
return (0);
}
@ -173,6 +173,7 @@ closeMbeOutFile (dsd_opts * opts, dsd_state * state)
int sum, i, j;
int talkgroup;
struct tm timep;
int result;
if (opts->mbe_out_f != NULL)
{
@ -187,11 +188,6 @@ closeMbeOutFile (dsd_opts * opts, dsd_state * state)
strptime (opts->mbe_out_file, "%s.amb", &timep);
}
for (i = 0; i < 17; i++)
{
tgid[i] = 0;
}
if (state->tgcount > 0)
{
for (i = 0; i < 16; i++)
@ -203,6 +199,7 @@ closeMbeOutFile (dsd_opts * opts, dsd_state * state)
}
tgid[i] = (char) (((float) sum / (float) state->tgcount) + 48.5);
}
tgid[16] = 0;
talkgroup = (int) strtol (tgid, NULL, 2);
}
else
@ -216,7 +213,16 @@ closeMbeOutFile (dsd_opts * opts, dsd_state * state)
strftime (datestr, 31, "%Y-%m-%d-%H%M%S", &timep);
sprintf (newfilename, "nac%X-%s-tg%i%s", state->nac, datestr, talkgroup, ext);
sprintf (shell, "mv %s %s", opts->mbe_out_file, newfilename);
system (shell);
result = system (shell);
state->tgcount = 0;
for (i = 0; i < 25; i++)
{
for (j = 0; j < 16; j++)
{
state->tg[i][j] = 48;
}
}
}
}
@ -273,6 +279,7 @@ openWavOutFile (dsd_opts * opts, dsd_state * state)
return;
}
opts->wav_out_fd = fileno (opts->wav_out_f);
state->wav_out_bytes = 0;
fprintf (opts->wav_out_f, "RIFF");
// total length
@ -310,7 +317,7 @@ openWavOutFile (dsd_opts * opts, dsd_state * state)
fputc (0, opts->wav_out_f);
fputc (0, opts->wav_out_f);
// bytes/sample
// block align
fputc (2, opts->wav_out_f);
fputc (0, opts->wav_out_f);
@ -325,7 +332,75 @@ openWavOutFile (dsd_opts * opts, dsd_state * state)
fputc (0, opts->wav_out_f);
fputc (0, opts->wav_out_f);
fputc (0, opts->wav_out_f);
fputc (127, opts->wav_out_f);
fputc (0, opts->wav_out_f);
fflush (opts->wav_out_f);
}
void
closeWavOutFile (dsd_opts * opts, dsd_state * state)
{
int length;
if (opts->wav_out_f != NULL)
{
rewind (opts->wav_out_f);
length = state->wav_out_bytes;
fprintf (opts->wav_out_f, "RIFF");
// total length
fputc (((36 + length) & 0xff), opts->wav_out_f);
fputc ((((36 + length) >> 8) & 0xff), opts->wav_out_f);
fputc ((((36 + length) >> 16) & 0xff), opts->wav_out_f);
fputc ((((36 + length) >> 24) & 0xff), opts->wav_out_f);
fprintf (opts->wav_out_f, "WAVE");
fprintf (opts->wav_out_f, "fmt ");
// length of format chunk
fputc (16, opts->wav_out_f);
fputc (0, opts->wav_out_f);
fputc (0, opts->wav_out_f);
fputc (0, opts->wav_out_f);
// always 0x1
fputc (1, opts->wav_out_f);
fputc (0, opts->wav_out_f);
// channels
fputc (1, opts->wav_out_f);
fputc (0, opts->wav_out_f);
// sample rate
fputc (64, opts->wav_out_f);
fputc (31, opts->wav_out_f);
fputc (0, opts->wav_out_f);
fputc (0, opts->wav_out_f);
// bytes per second
fputc (128, opts->wav_out_f);
fputc (62, opts->wav_out_f);
fputc (0, opts->wav_out_f);
fputc (0, opts->wav_out_f);
// block align
fputc (2, opts->wav_out_f);
fputc (0, opts->wav_out_f);
// bits/sample
fputc (16, opts->wav_out_f);
fputc (0, opts->wav_out_f);
// data chunk header
fprintf (opts->wav_out_f, "data");
// length of data
fputc ((length & 0xff), opts->wav_out_f);
fputc (((length >> 8) & 0xff), opts->wav_out_f);
fputc (((length >> 16) & 0xff), opts->wav_out_f);
fputc (((length >> 24) & 0xff), opts->wav_out_f);
fflush (opts->wav_out_f);
}
}

View File

@ -26,7 +26,7 @@ printFrameInfo (dsd_opts * opts, dsd_state * state)
level = (int) (((float) state->max / (float) 32768) * (float) 100);
if (opts->verbose > 0)
{
printf ("input: %2i%% ", level);
printf ("inlvl: %2i%% ", level);
}
if (state->nac != 0)
{
@ -65,6 +65,7 @@ processFrame (dsd_opts * opts, dsd_state * state)
if ((state->synctype == 8) || (state->synctype == 9))
{
state->rf_mod = 2;
state->nac = 0;
state->lastsrc = 0;
state->lasttg = 0;
@ -73,7 +74,7 @@ processFrame (dsd_opts * opts, dsd_state * state)
if (opts->verbose > 0)
{
level = (int) (((float) state->max / (float) 32768) * (float) 100);
printf ("input: %2i%% ", level);
printf ("inlvl: %2i%% ", level);
}
}
state->nac = 0;
@ -82,7 +83,30 @@ processFrame (dsd_opts * opts, dsd_state * state)
openMbeOutFile (opts, state);
}
sprintf (state->fsubtype, " VOICE ");
processNXDN96 (opts, state);
processNXDNVoice (opts, state);
return;
}
else if ((state->synctype == 16) || (state->synctype == 17))
{
state->rf_mod = 2;
state->nac = 0;
state->lastsrc = 0;
state->lasttg = 0;
if (opts->errorbars == 1)
{
if (opts->verbose > 0)
{
level = (int) (((float) state->max / (float) 32768) * (float) 100);
printf ("inlvl: %2i%% ", level);
}
}
state->nac = 0;
if ((opts->mbe_out_dir[0] != 0) && (opts->mbe_out_f == NULL))
{
openMbeOutFile (opts, state);
}
sprintf (state->fsubtype, " DATA ");
processNXDNData (opts, state);
return;
}
else if ((state->synctype == 6) || (state->synctype == 7))
@ -95,7 +119,7 @@ processFrame (dsd_opts * opts, dsd_state * state)
if (opts->verbose > 0)
{
level = (int) (((float) state->max / (float) 32768) * (float) 100);
printf ("input: %2i%% ", level);
printf ("inlvl: %2i%% ", level);
}
}
state->nac = 0;
@ -117,7 +141,7 @@ processFrame (dsd_opts * opts, dsd_state * state)
if (opts->verbose > 0)
{
level = (int) (((float) state->max / (float) 32768) * (float) 100);
printf ("input: %2i%% ", level);
printf ("inlvl: %2i%% ", level);
}
}
if ((state->synctype == 11) || (state->synctype == 12))
@ -140,8 +164,6 @@ processFrame (dsd_opts * opts, dsd_state * state)
else if ((state->synctype >= 2) && (state->synctype <= 5))
{
state->nac = 0;
state->lastsrc = 0;
state->lasttg = 0;
if (opts->errorbars == 1)
{
printFrameInfo (opts, state);
@ -173,7 +195,7 @@ processFrame (dsd_opts * opts, dsd_state * state)
if (opts->verbose > 0)
{
level = (int) (((float) state->max / (float) 32768) * (float) 100);
printf ("input: %2i%% ", level);
printf ("inlvl: %2i%% ", level);
}
}
if ((opts->mbe_out_dir[0] != 0) && (opts->mbe_out_f == NULL))
@ -211,7 +233,6 @@ processFrame (dsd_opts * opts, dsd_state * state)
printFrameInfo (opts, state);
printf (" HDU\n");
}
state->cur_mp->repeat = 0;
if (opts->mbe_out_dir[0] != 0)
{
closeMbeOutFile (opts, state);
@ -280,14 +301,15 @@ processFrame (dsd_opts * opts, dsd_state * state)
printFrameInfo (opts, state);
printf (" TDULC\n");
}
state->cur_mp->repeat = 0;
if (opts->mbe_out_dir[0] != 0)
{
closeMbeOutFile (opts, state);
}
mbe_initMbeParms (state->cur_mp, state->prev_mp, state->prev_mp_enhanced);
state->tgcount = 0;
state->lasttg = 0;
state->lastsrc = 0;
state->lastp25type = 0;
state->err_str[0] = 0;
sprintf (state->fsubtype, " TDULC ");
state->numtdulc++;
if ((opts->resume > 0) && (state->numtdulc > opts->resume))
@ -304,13 +326,13 @@ processFrame (dsd_opts * opts, dsd_state * state)
printFrameInfo (opts, state);
printf (" TDU\n");
}
state->cur_mp->repeat = 0;
if (opts->mbe_out_dir[0] != 0)
{
closeMbeOutFile (opts, state);
}
mbe_initMbeParms (state->cur_mp, state->prev_mp, state->prev_mp_enhanced);
state->tgcount = 0;
state->lasttg = 0;
state->lastsrc = 0;
state->lastp25type = 0;
state->err_str[0] = 0;
sprintf (state->fsubtype, " TDU ");
@ -323,6 +345,12 @@ processFrame (dsd_opts * opts, dsd_state * state)
printFrameInfo (opts, state);
printf (" TSDU\n");
}
if (opts->resume > 0)
{
resumeScan (opts, state);
}
state->lasttg = 0;
state->lastsrc = 0;
state->lastp25type = 3;
sprintf (state->fsubtype, " TSDU ");
skipDibit (opts, state, 328);
@ -333,10 +361,10 @@ processFrame (dsd_opts * opts, dsd_state * state)
{
printFrameInfo (opts, state);
printf (" PDU\n");
if (opts->resume > 0)
{
resumeScan (opts, state);
}
}
if (opts->resume > 0)
{
resumeScan (opts, state);
}
if (opts->mbe_out_dir[0] != 0)
{
@ -347,7 +375,6 @@ processFrame (dsd_opts * opts, dsd_state * state)
}
state->lastp25type = 4;
sprintf (state->fsubtype, " PDU ");
}
// try to guess based on previous frame if unknown type
else if (state->lastp25type == 1)

View File

@ -43,22 +43,24 @@ int
getFrameSync (dsd_opts * opts, dsd_state * state)
{
/* detects frame sync and returns frame type
* 0 = +p25p1
* 1 = -p25p1
* 0 = +P25p1
* 1 = -P25p1
* 2 = +X2-TDMA (non inverted signal data frame)
* 3 = +X2-TDMA (inverted signal voice frame)
* 4 = -X2-TDMA (non inverted signal voice frame)
* 5 = -X2-TDMA (inverted signal data frame)
* 6 = +D-STAR
* 7 = -D-STAR
* 8 = +NXDN96
* 9 = -NXDN96
* 8 = +NXDN (non inverted voice frame)
* 9 = -NXDN (inverted voice frame)
* 10 = +DMR (non inverted singlan data frame)
* 11 = -DMR (inverted signal voice frame)
* 12 = +DMR (non inverted signal voice frame)
* 13 = -DMR (inverted signal data frame)
* 14 = +ProVoice
* 15 = -ProVoice
* 16 = +NXDN (non inverted data frame)
* 17 = -NXDN (inverted data frame)
*/
int i, j, t, o, dibit, sync, symbol, synctest_pos, lastt;
@ -73,13 +75,19 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
int lsum;
char spectrum[64];
for (i = 18; i < 24; i++)
{
lbuf[i] = 0;
lbuf2[i] = 0;
}
// detect frame sync
t = 0;
synctest[24] = 0;
synctest18[18] = 0;
synctest32[32] = 0;
synctest_pos = 0;
synctest_p = synctest_buf;
synctest_p = synctest_buf + 10;
sync = 0;
lmin = 0;
lmax = 0;
@ -158,18 +166,8 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
dibit = 51;
}
/*
printf("%c", dibit);
if (t == 768)
{
printf("\n");
t=0;
}
*/
*synctest_p = dibit;
if (t >= 24)
if (t >= 18)
{
for (i = 0; i < 24; i++)
{
@ -304,7 +302,7 @@ if (t == 768)
strncpy (synctest, (synctest_p - 23), 24);
if (opts->frame_p25p1 == 1)
{
if (strcmp (synctest, FRAME_SYNC) == 0)
if (strcmp (synctest, P25P1_SYNC) == 0)
{
state->carrier = 1;
state->offset = synctest_pos;
@ -313,12 +311,12 @@ if (t == 768)
sprintf (state->ftype, " P25 Phase 1 ");
if (opts->errorbars == 1)
{
printFrameSync (opts, state, " +p25p1 ", synctest_pos + 1, modulation);
printFrameSync (opts, state, " +P25p1 ", synctest_pos + 1, modulation);
}
state->lastsynctype = 0;
return (0);
}
if (strcmp (synctest, INV_FRAME_SYNC) == 0)
if (strcmp (synctest, INV_P25P1_SYNC) == 0)
{
state->carrier = 1;
state->offset = synctest_pos;
@ -327,7 +325,7 @@ if (t == 768)
sprintf (state->ftype, " P25 Phase 1 ");
if (opts->errorbars == 1)
{
printFrameSync (opts, state, " -p25p1 ", synctest_pos + 1, modulation);
printFrameSync (opts, state, " -P25p1 ", synctest_pos + 1, modulation);
}
state->lastsynctype = 1;
return (1);
@ -335,7 +333,7 @@ if (t == 768)
}
if (opts->frame_x2tdma == 1)
{
if (strcmp (synctest, X2TDMA_DATA_SYNC) == 0)
if ((strcmp (synctest, X2TDMA_BS_DATA_SYNC) == 0) || (strcmp (synctest, X2TDMA_MS_DATA_SYNC) == 0))
{
state->carrier = 1;
state->offset = synctest_pos;
@ -368,7 +366,7 @@ if (t == 768)
return (3);
}
}
if (strcmp (synctest, X2TDMA_VOICE_SYNC) == 0)
if ((strcmp (synctest, X2TDMA_BS_VOICE_SYNC) == 0) || (strcmp (synctest, X2TDMA_MS_VOICE_SYNC) == 0))
{
state->carrier = 1;
state->offset = synctest_pos;
@ -404,7 +402,7 @@ if (t == 768)
}
if (opts->frame_dmr == 1)
{
if (strcmp (synctest, DMR_DATA_SYNC) == 0)
if ((strcmp (synctest, DMR_MS_DATA_SYNC) == 0) || (strcmp (synctest, DMR_BS_DATA_SYNC) == 0))
{
state->carrier = 1;
state->offset = synctest_pos;
@ -437,7 +435,7 @@ if (t == 768)
return (11);
}
}
if (strcmp (synctest, DMR_VOICE_SYNC) == 0)
if ((strcmp (synctest, DMR_MS_VOICE_SYNC) == 0) || (strcmp (synctest, DMR_BS_VOICE_SYNC) == 0))
{
state->carrier = 1;
state->offset = synctest_pos;
@ -474,7 +472,7 @@ if (t == 768)
if (opts->frame_provoice == 1)
{
strncpy (synctest32, (synctest_p - 31), 32);
if (strcmp (synctest32, PROVOICE_SYNC) == 0)
if ((strcmp (synctest32, PROVOICE_SYNC) == 0) || (strcmp (synctest32, PROVOICE_EA_SYNC) == 0))
{
state->carrier = 1;
state->offset = synctest_pos;
@ -488,7 +486,7 @@ if (t == 768)
state->lastsynctype = 14;
return (14);
}
else if (strcmp (synctest32, INV_PROVOICE_SYNC) == 0)
else if ((strcmp (synctest32, INV_PROVOICE_SYNC) == 0) || (strcmp (synctest32, INV_PROVOICE_EA_SYNC) == 0))
{
state->carrier = 1;
state->offset = synctest_pos;
@ -504,36 +502,137 @@ if (t == 768)
}
}
if (opts->frame_nxdn == 1)
if ((opts->frame_nxdn96 == 1) || (opts->frame_nxdn48 == 1))
{
strncpy (synctest18, (synctest_p - 17), 18);
if (strcmp (synctest18, NXDN96_SYNC) == 0)
if ((strcmp (synctest18, NXDN_BS_VOICE_SYNC) == 0) || (strcmp (synctest18, NXDN_MS_VOICE_SYNC) == 0))
{
state->carrier = 1;
state->offset = synctest_pos;
state->max = ((state->max) + lmax) / 2;
state->min = ((state->min) + lmin) / 2;
sprintf (state->ftype, " NXDN96 ");
if (opts->errorbars == 1)
if ((state->lastsynctype == 8) || (state->lastsynctype == 16))
{
printFrameSync (opts, state, " +NXDN96 ", synctest_pos + 1, modulation);
state->carrier = 1;
state->offset = synctest_pos;
state->max = ((state->max) + lmax) / 2;
state->min = ((state->min) + lmin) / 2;
if (state->samplesPerSymbol == 20)
{
sprintf (state->ftype, " NXDN48 ");
if (opts->errorbars == 1)
{
printFrameSync (opts, state, " +NXDN48 ", synctest_pos + 1, modulation);
}
}
else
{
sprintf (state->ftype, " NXDN96 ");
if (opts->errorbars == 1)
{
printFrameSync (opts, state, " +NXDN96 ", synctest_pos + 1, modulation);
}
}
state->lastsynctype = 8;
return (8);
}
else
{
state->lastsynctype = 8;
}
state->lastsynctype = 8;
return (8);
}
if (strcmp (synctest18, INV_NXDN96_SYNC) == 0)
else if ((strcmp (synctest18, INV_NXDN_BS_VOICE_SYNC) == 0) || (strcmp (synctest18, INV_NXDN_MS_VOICE_SYNC) == 0))
{
state->carrier = 1;
state->offset = synctest_pos;
state->max = ((state->max) + lmax) / 2;
state->min = ((state->min) + lmin) / 2;
sprintf (state->ftype, " NXDN96 ");
if (opts->errorbars == 1)
if ((state->lastsynctype == 9) || (state->lastsynctype == 17))
{
printFrameSync (opts, state, " -NXDN96 ", synctest_pos + 1, modulation);
state->carrier = 1;
state->offset = synctest_pos;
state->max = ((state->max) + lmax) / 2;
state->min = ((state->min) + lmin) / 2;
if (state->samplesPerSymbol == 20)
{
sprintf (state->ftype, " NXDN48 ");
if (opts->errorbars == 1)
{
printFrameSync (opts, state, " -NXDN48 ", synctest_pos + 1, modulation);
}
}
else
{
sprintf (state->ftype, " NXDN96 ");
if (opts->errorbars == 1)
{
printFrameSync (opts, state, " -NXDN96 ", synctest_pos + 1, modulation);
}
}
state->lastsynctype = 9;
return (9);
}
else
{
state->lastsynctype = 9;
}
}
else if ((strcmp (synctest18, NXDN_BS_DATA_SYNC) == 0) || (strcmp (synctest18, NXDN_MS_DATA_SYNC) == 0))
{
if ((state->lastsynctype == 8) || (state->lastsynctype == 16))
{
state->carrier = 1;
state->offset = synctest_pos;
state->max = ((state->max) + lmax) / 2;
state->min = ((state->min) + lmin) / 2;
if (state->samplesPerSymbol == 20)
{
sprintf (state->ftype, " NXDN48 ");
if (opts->errorbars == 1)
{
printFrameSync (opts, state, " +NXDN48 ", synctest_pos + 1, modulation);
}
}
else
{
sprintf (state->ftype, " NXDN96 ");
if (opts->errorbars == 1)
{
printFrameSync (opts, state, " +NXDN96 ", synctest_pos + 1, modulation);
}
}
state->lastsynctype = 16;
return (16);
}
else
{
state->lastsynctype = 16;
}
}
else if ((strcmp (synctest18, INV_NXDN_BS_DATA_SYNC) == 0) || (strcmp (synctest18, INV_NXDN_MS_DATA_SYNC) == 0))
{
if ((state->lastsynctype == 9) || (state->lastsynctype == 17))
{
state->carrier = 1;
state->offset = synctest_pos;
state->max = ((state->max) + lmax) / 2;
state->min = ((state->min) + lmin) / 2;
sprintf (state->ftype, " NXDN ");
if (state->samplesPerSymbol == 20)
{
sprintf (state->ftype, " NXDN48 ");
if (opts->errorbars == 1)
{
printFrameSync (opts, state, " -NXDN48 ", synctest_pos + 1, modulation);
}
}
else
{
sprintf (state->ftype, " NXDN96 ");
if (opts->errorbars == 1)
{
printFrameSync (opts, state, " -NXDN96 ", synctest_pos + 1, modulation);
}
}
state->lastsynctype = 17;
return (17);
}
else
{
state->lastsynctype = 17;
}
state->lastsynctype = 9;
return (9);
}
}
if (opts->frame_dstar == 1)
@ -579,7 +678,7 @@ if (t == 768)
sprintf (state->ftype, "(P25 Phase 1)");
if (opts->errorbars == 1)
{
printFrameSync (opts, state, "(+p25p1) ", synctest_pos + 1, modulation);
printFrameSync (opts, state, "(+P25p1) ", synctest_pos + 1, modulation);
}
state->lastsynctype = -1;
return (0);
@ -593,12 +692,12 @@ if (t == 768)
sprintf (state->ftype, "(P25 Phase 1)");
if (opts->errorbars == 1)
{
printFrameSync (opts, state, "(-p25p1) ", synctest_pos + 1, modulation);
printFrameSync (opts, state, "(-P25p1) ", synctest_pos + 1, modulation);
}
state->lastsynctype = -1;
return (1);
}
else if ((state->lastsynctype == 3) && (strcmp (synctest, X2TDMA_VOICE_SYNC) != 0))
else if ((state->lastsynctype == 3) && ((strcmp (synctest, X2TDMA_BS_VOICE_SYNC) != 0) || (strcmp (synctest, X2TDMA_MS_VOICE_SYNC) != 0)))
{
state->carrier = 1;
state->offset = synctest_pos;
@ -612,7 +711,7 @@ if (t == 768)
state->lastsynctype = -1;
return (3);
}
else if ((state->lastsynctype == 4) && (strcmp (synctest, X2TDMA_DATA_SYNC) != 0))
else if ((state->lastsynctype == 4) && ((strcmp (synctest, X2TDMA_BS_DATA_SYNC) != 0) || (strcmp (synctest, X2TDMA_MS_DATA_SYNC) != 0)))
{
state->carrier = 1;
state->offset = synctest_pos;
@ -626,7 +725,7 @@ if (t == 768)
state->lastsynctype = -1;
return (4);
}
else if ((state->lastsynctype == 11) && (strcmp (synctest, DMR_VOICE_SYNC) != 0))
else if ((state->lastsynctype == 11) && ((strcmp (synctest, DMR_BS_VOICE_SYNC) != 0) || (strcmp (synctest, DMR_MS_VOICE_SYNC) != 0)))
{
state->carrier = 1;
state->offset = synctest_pos;
@ -640,7 +739,7 @@ if (t == 768)
state->lastsynctype = -1;
return (11);
}
else if ((state->lastsynctype == 12) && (strcmp (synctest, DMR_DATA_SYNC) != 0))
else if ((state->lastsynctype == 12) && ((strcmp (synctest, DMR_BS_DATA_SYNC) != 0) || (strcmp (synctest, DMR_MS_DATA_SYNC) != 0)))
{
state->carrier = 1;
state->offset = synctest_pos;
@ -657,6 +756,11 @@ if (t == 768)
}
}
if (exitflag == 1)
{
cleanupAndExit (opts, state);
}
if (synctest_pos < 10200)
{
synctest_pos++;
@ -670,16 +774,13 @@ if (t == 768)
noCarrier (opts, state);
}
if (state->carrier == 1)
if (state->lastsynctype != 1)
{
if (synctest_pos >= 1800)
{
if (opts->errorbars == 1)
if ((opts->errorbars == 1) && (opts->verbose > 1) && (state->carrier == 1))
{
if (opts->verbose > 1)
{
printf ("Sync: no sync\n");
}
printf ("Sync: no sync\n");
}
noCarrier (opts, state);
return (-1);

View File

@ -21,7 +21,7 @@
#include "p25p1_const.h"
#include "x2tdma_const.h"
#include "dstar_const.h"
#include "nxdn96_const.h"
#include "nxdn_const.h"
#include "dmr_const.h"
#include "provoice_const.h"
@ -39,7 +39,6 @@ comp (const void *a, const void *b)
void
noCarrier (dsd_opts * opts, dsd_state * state)
{
state->dibit_buf_p = state->dibit_buf + 200;
memset (state->dibit_buf, 0, sizeof (int) * 200);
if (opts->mbe_out_f != NULL)
@ -55,6 +54,8 @@ noCarrier (dsd_opts * opts, dsd_state * state)
state->err_str[0] = 0;
sprintf (state->fsubtype, " ");
sprintf (state->ftype, " ");
state->errs = 0;
state->errs2 = 0;
state->lasttg = 0;
state->lastsrc = 0;
state->lastp25type = 0;
@ -112,7 +113,8 @@ initOpts (dsd_opts * opts)
opts->frame_dstar = 0;
opts->frame_x2tdma = 1;
opts->frame_p25p1 = 1;
opts->frame_nxdn = 0;
opts->frame_nxdn48 = 0;
opts->frame_nxdn96 = 1;
opts->frame_dmr = 1;
opts->frame_provoice = 0;
opts->mod_c4fm = 1;
@ -147,6 +149,7 @@ initState (dsd_state * state)
state->audio_out_idx = 0;
state->audio_out_idx2 = 0;
state->audio_out_temp_buf_p = state->audio_out_temp_buf;
state->wav_out_bytes = 0;
state->center = 0;
state->jitter = -1;
state->synctype = -1;
@ -181,11 +184,11 @@ initState (dsd_state * state)
state->lastp25type = 0;
state->offset = 0;
state->carrier = 0;
for (j = 0; i < 25; j++)
for (i = 0; i < 25; i++)
{
for (i = 0; j < 16; i++)
for (j = 0; j < 16; j++)
{
state->tg[i][j] = 0;
state->tg[i][j] = 48;
}
}
state->tgcount = 0;
@ -218,7 +221,6 @@ initState (dsd_state * state)
void
usage ()
{
printf ("Digital Speech Decoder 1.3\n");
printf ("\n");
printf ("Usage:\n");
printf (" dsd [options] Live scanner mode\n");
@ -227,10 +229,10 @@ usage ()
printf ("\n");
printf ("Display Options:\n");
printf (" -e Show Frame Info and errorbars (default)\n");
printf (" -pe Show p25 encryption sync bits\n");
printf (" -pl Show p25 link control bits\n");
printf (" -ps Show p25 status bits and low speed data\n");
printf (" -pt Show p25 talkgroup info\n");
printf (" -pe Show P25 encryption sync bits\n");
printf (" -pl Show P25 link control bits\n");
printf (" -ps Show P25 status bits and low speed data\n");
printf (" -pt Show P25 talkgroup info\n");
printf (" -q Don't show Frame Info/errorbars\n");
printf (" -s Datascope (disables other display options)\n");
printf (" -t Show symbol timing during sync\n");
@ -248,13 +250,14 @@ usage ()
printf ("Scanner control options:\n");
printf (" -B <num> Serial port baud rate (default=115200)\n");
printf (" -C <device> Serial port for scanner control (default=/dev/ttyUSB0)\n");
printf (" -R <num> Resume scan after <num> TDULC frames or any PDU\n");
printf (" -R <num> Resume scan after <num> TDULC frames or any PDU or TSDU\n");
printf ("\n");
printf ("Decoder options:\n");
printf (" -fa Auto-detect frame type (default)\n");
printf (" -f1 Decode only P25 Phase 1\n");
printf (" -fd Decode only D-STAR* (no audio)\n");
printf (" -fn Decode only NXDN96* (no audio)\n");
printf (" -fi Decode only NXDN48* (6.25 kHz) / IDAS*\n");
printf (" -fn Decode only NXDN96 (12.5 kHz)\n");
printf (" -fp Decode only ProVoice*\n");
printf (" -fr Decode only DMR/MOTOTRBO\n");
printf (" -fx Decode only X2-TDMA\n");
@ -300,6 +303,25 @@ liveScanner (dsd_opts * opts, dsd_state * state)
}
}
void
cleanupAndExit (dsd_opts * opts, dsd_state * state)
{
noCarrier (opts, state);
if (opts->wav_out_f != NULL)
{
closeWavOutFile (opts, state);
}
printf ("Exiting.\n");
exit (0);
}
void
sigfun (int sig)
{
exitflag = 1;
signal (SIGINT, SIG_DFL);
}
int
main (int argc, char **argv)
{
@ -307,13 +329,20 @@ main (int argc, char **argv)
int c;
extern char *optarg;
extern int optind, opterr, optopt;
dsd_opts opts;
dsd_state state;
char versionstr[25];
mbe_printVersion (versionstr);
printf ("Digital Speech Decoder 1.4.1\n");
printf ("mbelib version %s\n", versionstr);
initOpts (&opts);
initState (&state);
exitflag = 0;
signal (SIGINT, sigfun);
while ((c = getopt (argc, argv, "hep:qstv:z:i:o:d:g:nw:B:C:R:f:m:u:x:A:S:M:r")) != -1)
{
opterr = 0;
@ -424,7 +453,8 @@ main (int argc, char **argv)
opts.frame_dstar = 0;
opts.frame_x2tdma = 1;
opts.frame_p25p1 = 1;
opts.frame_nxdn = 0;
opts.frame_nxdn48 = 0;
opts.frame_nxdn96 = 1;
opts.frame_dmr = 1;
opts.frame_provoice = 0;
}
@ -433,7 +463,8 @@ main (int argc, char **argv)
opts.frame_dstar = 1;
opts.frame_x2tdma = 0;
opts.frame_p25p1 = 0;
opts.frame_nxdn = 0;
opts.frame_nxdn48 = 0;
opts.frame_nxdn96 = 0;
opts.frame_dmr = 0;
opts.frame_provoice = 0;
printf ("Decoding only D-STAR frames.\n");
@ -443,7 +474,8 @@ main (int argc, char **argv)
opts.frame_dstar = 0;
opts.frame_x2tdma = 1;
opts.frame_p25p1 = 0;
opts.frame_nxdn = 0;
opts.frame_nxdn48 = 0;
opts.frame_nxdn96 = 0;
opts.frame_dmr = 0;
opts.frame_provoice = 0;
printf ("Decoding only X2-TDMA frames.\n");
@ -453,7 +485,8 @@ main (int argc, char **argv)
opts.frame_dstar = 0;
opts.frame_x2tdma = 0;
opts.frame_p25p1 = 0;
opts.frame_nxdn = 0;
opts.frame_nxdn48 = 0;
opts.frame_nxdn96 = 0;
opts.frame_dmr = 0;
opts.frame_provoice = 1;
state.samplesPerSymbol = 5;
@ -462,6 +495,7 @@ main (int argc, char **argv)
opts.mod_qpsk = 0;
opts.mod_gfsk = 1;
state.rf_mod = 2;
printf ("Setting symbol rate to 9600 / second\n");
printf ("Enabling only GFSK modulation optimizations.\n");
printf ("Decoding only ProVoice frames.\n");
}
@ -470,19 +504,45 @@ main (int argc, char **argv)
opts.frame_dstar = 0;
opts.frame_x2tdma = 0;
opts.frame_p25p1 = 1;
opts.frame_nxdn = 0;
opts.frame_nxdn48 = 0;
opts.frame_nxdn96 = 0;
opts.frame_dmr = 0;
opts.frame_provoice = 0;
printf ("Decoding only P25 Phase 1 frames.\n");
}
else if (optarg[0] == 'i')
{
opts.frame_dstar = 0;
opts.frame_x2tdma = 0;
opts.frame_p25p1 = 0;
opts.frame_nxdn48 = 1;
opts.frame_nxdn96 = 0;
opts.frame_dmr = 0;
opts.frame_provoice = 0;
state.samplesPerSymbol = 20;
state.symbolCenter = 10;
opts.mod_c4fm = 0;
opts.mod_qpsk = 0;
opts.mod_gfsk = 1;
state.rf_mod = 2;
printf ("Setting symbol rate to 2400 / second\n");
printf ("Enabling only GFSK modulation optimizations.\n");
printf ("Decoding only NXDN 4800 baud frames.\n");
}
else if (optarg[0] == 'n')
{
opts.frame_dstar = 0;
opts.frame_x2tdma = 0;
opts.frame_p25p1 = 0;
opts.frame_nxdn = 1;
opts.frame_nxdn48 = 0;
opts.frame_nxdn96 = 1;
opts.frame_dmr = 0;
opts.frame_provoice = 0;
opts.mod_c4fm = 0;
opts.mod_qpsk = 0;
opts.mod_gfsk = 1;
state.rf_mod = 2;
printf ("Enabling only GFSK modulation optimizations.\n");
printf ("Decoding only NXDN 9600 baud frames.\n");
}
else if (optarg[0] == 'r')
@ -490,7 +550,8 @@ main (int argc, char **argv)
opts.frame_dstar = 0;
opts.frame_x2tdma = 0;
opts.frame_p25p1 = 0;
opts.frame_nxdn = 0;
opts.frame_nxdn48 = 0;
opts.frame_nxdn96 = 0;
opts.frame_dmr = 1;
opts.frame_provoice = 0;
printf ("Decoding only DMR/MOTOTRBO frames.\n");
@ -617,7 +678,7 @@ main (int argc, char **argv)
else
{
opts.split = 0;
opts.playoffset = 38;
opts.playoffset = 25; // 38
opts.delay = 0;
openAudioInDevice (&opts);
opts.audio_out_fd = opts.audio_in_fd;
@ -631,5 +692,6 @@ main (int argc, char **argv)
{
liveScanner (&opts, &state);
}
cleanupAndExit (&opts, &state);
return (0);
}

View File

@ -27,7 +27,7 @@ playMbeFiles (dsd_opts * opts, dsd_state * state, int argc, char **argv)
for (i = state->optind; i < argc; i++)
{
sprintf (opts->mbe_in_file, argv[i]);
sprintf (opts->mbe_in_file, "%s", argv[i]);
openMbeInFile (opts, state);
mbe_initMbeParms (state->cur_mp, state->prev_mp, state->prev_mp_enhanced);
printf ("playing %s\n", opts->mbe_in_file);
@ -62,6 +62,10 @@ playMbeFiles (dsd_opts * opts, dsd_state * state, int argc, char **argv)
playSynthesizedVoice (opts, state);
}
}
if (exitflag == 1)
{
cleanupAndExit (opts, state);
}
}
}
}

View File

@ -18,6 +18,7 @@ openSerial (dsd_opts * opts, dsd_state * state)
tty.c_cflag = 0;
baud = B115200;
switch (opts->serial_baud)
{
case 1200:
@ -70,19 +71,20 @@ void
resumeScan (dsd_opts * opts, dsd_state * state)
{
char cmd[7];
char cmd[16];
ssize_t result;
if (opts->serial_fd > 0)
{
sprintf (cmd, "\rKEY00\r");
write (opts->serial_fd, cmd, 7);
result = write (opts->serial_fd, cmd, 7);
cmd[0] = 2;
cmd[1] = 75;
cmd[2] = 15;
cmd[3] = 3;
cmd[4] = 93;
cmd[5] = 0;
write (opts->serial_fd, cmd, 5);
result = write (opts->serial_fd, cmd, 5);
state->numtdulc = 0;
}
}

View File

@ -23,6 +23,7 @@ getSymbol (dsd_opts * opts, dsd_state * state, int have_sync)
short sample;
int i, sum, symbol, count;
ssize_t result;
sum = 0;
count = 0;
@ -31,7 +32,18 @@ getSymbol (dsd_opts * opts, dsd_state * state, int have_sync)
// timing control
if ((i == 0) && (have_sync == 0))
{
if (state->rf_mod == 1)
if (state->samplesPerSymbol == 20)
{
if ((state->jitter >= 7) && (state->jitter <= 10))
{
i--;
}
else if ((state->jitter >= 11) && (state->jitter <= 14))
{
i++;
}
}
else if (state->rf_mod == 1)
{
if ((state->jitter >= 0) && (state->jitter < state->symbolCenter))
{
@ -67,7 +79,7 @@ getSymbol (dsd_opts * opts, dsd_state * state, int have_sync)
state->jitter = -1;
}
read (opts->audio_in_fd, &sample, 2);
result = read (opts->audio_in_fd, &sample, 2);
if ((sample > state->max) && (have_sync == 1) && (state->rf_mod == 0))
{
sample = state->max;
@ -143,9 +155,17 @@ getSymbol (dsd_opts * opts, dsd_state * state, int have_sync)
}
}
}
if (state->samplesPerSymbol == 20)
{
if ((i >= 9) && (i <= 11))
{
sum += sample;
count++;
}
}
if (state->samplesPerSymbol == 5)
{
if ((i >= 2) && (i <= 2))
if (i == 2)
{
sum += sample;
count++;

View File

@ -22,150 +22,47 @@ upsample (dsd_state * state, float invalue)
{
int i, j, sum;
float *outbuf1, a, b, c, d;
float phasestart, phaseend, resamplestart, resampleend, phasestep, resampleamp2;
float resamplemin, resamplemax;
float *outbuf1, c, d;
if (state->audio_out_idx2 > 23)
outbuf1 = state->audio_out_float_buf_p;
outbuf1--;
c = *outbuf1;
d = invalue;
// basic triangle interpolation
outbuf1++;
*outbuf1 = ((invalue * (float) 0.166) + (c * (float) 0.834));
outbuf1++;
*outbuf1 = ((invalue * (float) 0.332) + (c * (float) 0.668));
outbuf1++;
*outbuf1 = ((invalue * (float) 0.5) + (c * (float) 0.5));
outbuf1++;
*outbuf1 = ((invalue * (float) 0.668) + (c * (float) 0.332));
outbuf1++;
*outbuf1 = ((invalue * (float) 0.834) + (c * (float) 0.166));
outbuf1++;
*outbuf1 = d;
outbuf1++;
if (state->audio_out_idx2 > 24)
{
outbuf1 = state->audio_out_float_buf_p;
outbuf1--;
c = *outbuf1;
outbuf1 -= 6;
b = *outbuf1;
outbuf1 -= 6;
a = *outbuf1;
d = (invalue);
resamplemin = 32767;
resamplemax = -32768;
if (a < resamplemin)
// smoothing
outbuf1 -= 16;
for (j = 0; j < 4; j++)
{
resamplemin = a;
}
if (a > resamplemax)
{
resamplemax = a;
}
if (b < resamplemin)
{
resamplemin = b;
}
if (b > resamplemax)
{
resamplemax = b;
}
if (c < resamplemin)
{
resamplemin = c;
}
if (c > resamplemax)
{
resamplemax = c;
}
if (d < resamplemin)
{
resamplemin = d;
}
if (d > resamplemax)
{
resamplemax = d;
}
resampleamp2 = ((float) resamplemax - (float) resamplemin) / (float) 2;
#ifdef UPSAMPLE_DEBUG
printf ("a:%f b:%f c:%f d:%f resamplemin:%f resamplemax:%f resampleamp2:%f\n", a, b, c, d, resamplemin, resamplemax, resampleamp2);
#endif
if (resampleamp2 == 0)
{
resamplestart = (float) 0;
resampleend = (float) 0;
}
else
{
resamplestart = (((float) b - (float) resamplemin) / resampleamp2) - (float) 1.0;
resampleend = (((float) c - (float) resamplemin) / resampleamp2) - (float) 1.0;
}
if (resamplestart < -1)
{
resamplestart = (float) -1;
}
else if (resamplestart > (float) 1)
{
resamplestart = (float) 1;
}
if (resampleend < -1)
{
resampleend = (float) -1;
}
else if (resampleend > (float) 1)
{
resampleend = (float) 1;
}
phasestart = asinf (resamplestart);
phaseend = asinf (resampleend);
phasestep = (phaseend - phasestart) / 6;
#ifdef UPSAMPLE_DEBUG
printf ("resamplestart:%f, resampleend:%f, phasestart:%f, phaseend:%f, phasestep:%f\n", resamplestart, resampleend, phasestart, phaseend, phasestep);
#endif
// rewrite samples between b and c
outbuf1 = state->audio_out_float_buf_p;
outbuf1 -= 6;
for (i = 1; i < 6; i++)
{
*outbuf1 = (resamplemin + resampleamp2 + (resampleamp2 * sin (phasestart + (phasestep * (float) i))));
#ifdef UPSAMPLE_DEBUG
printf ("audio_out_idx2:%i outbuf:%f\n", state->audio_out_idx2, *outbuf1);
#endif
outbuf1++;
}
#ifdef UPSAMPLE_DEBUG
printf ("(c):%f\n", *outbuf1);
#endif
// write d
outbuf1 += 6;
*outbuf1 = d;
#ifdef UPSAMPLE_DEBUG
printf ("audio_out_idx2:%i outbuf(d):%f\n", state->audio_out_idx2, *outbuf1);
#endif
outbuf1++;
// smooth
outbuf1 -= 36;
for (j = 0; j < 12; j++)
{
for (i = 0; i < 12; i++)
for (i = 0; i < 6; i++)
{
sum = 0;
outbuf1--;
outbuf1 -= 2;
sum += *outbuf1;
outbuf1++;
outbuf1 += 2;
sum += *outbuf1;
outbuf1++;
outbuf1 += 2;
sum += *outbuf1;
outbuf1--;
outbuf1 -= 2;
*outbuf1 = (sum / (float) 3);
outbuf1++;
}
outbuf1 -= 11;
outbuf1 -= 8;
}
}
else
{
outbuf1 = state->audio_out_float_buf_p;
outbuf1--;
c = *outbuf1;
*outbuf1 = ((invalue * (float) 0.166) + (c * (float) 0.834));
outbuf1++;
*outbuf1 = ((invalue * (float) 0.332) + (c * (float) 0.668));
outbuf1++;
*outbuf1 = ((invalue * (float) 0.5) + (c * (float) 0.5));
outbuf1++;
*outbuf1 = ((invalue * (float) 0.668) + (c * (float) 0.332));
outbuf1++;
*outbuf1 = ((invalue * (float) 0.834) + (c * (float) 0.166));
outbuf1++;
*outbuf1 = invalue;
}
}

66
nxdn_const.h Normal file
View File

@ -0,0 +1,66 @@
/*
* Copyright (C) 2010 DSD Author
* GPG Key ID: 0x3F1D7FD0 (74EF 430D F7F2 0A48 FCE6 F630 FAA2 635D 3F1D 7FD0)
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _MAIN
extern const int nW[36];
extern const int nX[36];
extern const int nY[36];
extern const int nZ[36];
extern const char nxdnpr[145];
#else
/*
* pseudorandom bit sequence
*/
const char nxdnpr[145] = { 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1 };
/*
* NXDN AMBE interleave schedule
*/
const int nW[36] = { 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 2,
0, 2, 0, 2, 0, 2,
0, 2, 0, 2, 0, 2
};
const int nX[36] = { 23, 10, 22, 9, 21, 8,
20, 7, 19, 6, 18, 5,
17, 4, 16, 3, 15, 2,
14, 1, 13, 0, 12, 10,
11, 9, 10, 8, 9, 7,
8, 6, 7, 5, 6, 4
};
const int nY[36] = { 0, 2, 0, 2, 0, 2,
0, 2, 0, 3, 0, 3,
1, 3, 1, 3, 1, 3,
1, 3, 1, 3, 1, 3,
1, 3, 1, 3, 1, 3,
1, 3, 1, 3, 1, 3
};
const int nZ[36] = { 5, 3, 4, 2, 3, 1,
2, 0, 1, 13, 0, 12,
22, 11, 21, 10, 20, 9,
19, 8, 18, 7, 17, 6,
16, 5, 15, 4, 14, 3,
13, 2, 12, 1, 11, 0
};
#endif

36
nxdn_data.c Normal file
View File

@ -0,0 +1,36 @@
#include "dsd.h"
void
processNXDNData (dsd_opts * opts, dsd_state * state)
{
int i, dibit;
if (opts->errorbars == 1)
{
printf ("DATA ");
}
for (i = 0; i < 30; i++)
{
dibit = getDibit (opts, state);
#ifdef NXDN_DUMP
printf ("%c", dibit + 48);
#endif
}
#ifdef NXDN_DUMP
printf (" ");
#endif
for (i = 0; i < 144; i++)
{
dibit = getDibit (opts, state);
#ifdef NXDN_DUMP
printf ("%c", dibit + 48);
#endif
}
if (opts->errorbars == 1)
{
printf ("\n");
}
}

59
nxdn_voice.c Normal file
View File

@ -0,0 +1,59 @@
#include "dsd.h"
#include "nxdn_const.h"
void
processNXDNVoice (dsd_opts * opts, dsd_state * state)
{
int i, j, dibit;
char ambe_fr[4][24];
const int *w, *x, *y, *z;
const char *pr;
if (opts->errorbars == 1)
{
printf ("VOICE e:");
}
for (i = 0; i < 30; i++)
{
dibit = getDibit (opts, state);
#ifdef NXDN_DUMP
printf ("%c", dibit + 48);
#endif
}
#ifdef NXDN_DUMP
printf (" ");
#endif
pr = nxdnpr;
for (j = 0; j < 4; j++)
{
w = nW;
x = nX;
y = nY;
z = nZ;
for (i = 0; i < 36; i++)
{
dibit = getDibit (opts, state);
#ifdef NXDN_DUMP
printf ("%c", dibit + 48);
#endif
ambe_fr[*w][*x] = *pr ^ (1 & (dibit >> 1)); // bit 1
pr++;
ambe_fr[*y][*z] = (1 & dibit); // bit 0
w++;
x++;
y++;
z++;
}
processMbeFrame (opts, state, NULL, ambe_fr, NULL);
#ifdef NXDN_DUMP
printf (" ");
#endif
}
if (opts->errorbars == 1)
{
printf ("\n");
}
}

View File

@ -23,27 +23,13 @@ processP25lcw (dsd_opts * opts, dsd_state * state, char *lcformat, char *mfid, c
{
// first tg is the active channel
if (state->tgcount < 24)
{
// update tg buffer
j = 0;
for (i = 40; i < 52; i++)
{
state->tg[state->tgcount][j] = lcinfo[i];
j++;
}
tmpstr[12] = 48;
tmpstr[13] = 48;
tmpstr[14] = 48;
tmpstr[15] = 48;
tmpstr[16] = 0;
state->tgcount = state->tgcount + 1;
}
// first one again for tg display
j = 0;
for (i = 40; i < 52; i++)
{
if (state->tgcount < 24)
{
state->tg[state->tgcount][j] = lcinfo[i];
}
tmpstr[j] = lcinfo[i];
j++;
}
@ -52,9 +38,17 @@ processP25lcw (dsd_opts * opts, dsd_state * state, char *lcformat, char *mfid, c
tmpstr[14] = 48;
tmpstr[15] = 48;
tmpstr[16] = 0;
tmpstr[16] = 0;
talkgroup = strtol (tmpstr, NULL, 2);
state->lasttg = talkgroup;
if (state->tgcount < 24)
{
state->tgcount = state->tgcount + 1;
}
if (opts->p25tg == 1)
{
printf ("tg: %li ", talkgroup);
}
if (opts->p25tg == 1)
{
printf ("tg: %li ", talkgroup);
@ -136,6 +130,10 @@ processP25lcw (dsd_opts * opts, dsd_state * state, char *lcformat, char *mfid, c
tmpstr[16] = 0;
talkgroup = strtol (tmpstr, NULL, 2);
state->lasttg = talkgroup;
if (state->tgcount < 24)
{
state->tgcount = state->tgcount + 1;
}
if (opts->p25tg == 1)
{
printf ("tg: %li ", talkgroup);

View File

@ -305,6 +305,10 @@ processHDU (dsd_opts * opts, dsd_state * state)
tmpstr[16] = 0;
talkgroup = strtol (tmpstr, NULL, 2);
state->lasttg = talkgroup;
if (state->tgcount < 24)
{
state->tgcount = state->tgcount + 1;
}
if (opts->p25tg == 1)
{
printf ("tg: %li\n", talkgroup);

View File

@ -207,7 +207,7 @@ processX2TDMAdata (dsd_opts * opts, dsd_state * state)
printf ("%s ", syncbits);
#endif
if (strcmp (sync, X2TDMA_DATA_SYNC) == 0)
if ((strcmp (sync, X2TDMA_BS_DATA_SYNC) == 0) || (strcmp (sync, X2TDMA_BS_DATA_SYNC) == 0))
{
if (state->currentslot == 0)
{
@ -218,17 +218,6 @@ processX2TDMAdata (dsd_opts * opts, dsd_state * state)
sprintf (state->slot1light, "[slot1]");
}
}
else if (strcmp (sync, X2TDMA_VOICE_SYNC) == 0)
{
if (state->currentslot == 0)
{
sprintf (state->slot0light, "[SLOT0]");
}
else
{
sprintf (state->slot1light, "[SLOT1]");
}
}
if (opts->errorbars == 1)
{

View File

@ -38,6 +38,7 @@ processX2TDMAvoice (dsd_opts * opts, dsd_state * state)
int burstd;
int mutecurrentslot;
int algidhex, kidhex;
int msMode;
#ifdef X2TDMA_DUMP
int k;
@ -53,6 +54,7 @@ processX2TDMAvoice (dsd_opts * opts, dsd_state * state)
aiei = 0;
burstd = 0;
mutecurrentslot = 0;
msMode = 0;
dibit_p = state->dibit_buf_p - 144;
for (j = 0; j < 6; j++)
@ -206,7 +208,7 @@ processX2TDMAvoice (dsd_opts * opts, dsd_state * state)
sync[24] = 0;
syncdata[24] = 0;
if (strcmp (sync, X2TDMA_DATA_SYNC) == 0)
if ((strcmp (sync, X2TDMA_BS_DATA_SYNC) == 0) || (strcmp (sync, X2TDMA_MS_DATA_SYNC) == 0))
{
mutecurrentslot = 1;
if (state->currentslot == 0)
@ -218,7 +220,7 @@ processX2TDMAvoice (dsd_opts * opts, dsd_state * state)
sprintf (state->slot1light, "[slot1]");
}
}
else if (strcmp (sync, X2TDMA_VOICE_SYNC) == 0)
else if ((strcmp (sync, X2TDMA_BS_VOICE_SYNC) == 0) || (strcmp (sync, X2TDMA_MS_VOICE_SYNC) == 0))
{
mutecurrentslot = 0;
if (state->currentslot == 0)
@ -231,6 +233,11 @@ processX2TDMAvoice (dsd_opts * opts, dsd_state * state)
}
}
if ((strcmp (sync, X2TDMA_MS_VOICE_SYNC) == 0) || (strcmp (sync, X2TDMA_MS_DATA_SYNC) == 0))
{
msMode = 1;
}
if ((j == 0) && (opts->errorbars == 1))
{
printf ("%s %s VOICE e:", state->slot0light, state->slot1light);
@ -564,7 +571,7 @@ processX2TDMAvoice (dsd_opts * opts, dsd_state * state)
sync[24] = 0;
syncdata[24] = 0;
if (strcmp (sync, X2TDMA_DATA_SYNC) == 0)
if ((strcmp (sync, X2TDMA_BS_DATA_SYNC) == 0) || (msMode == 1))
{
if (state->currentslot == 0)
{
@ -575,7 +582,7 @@ processX2TDMAvoice (dsd_opts * opts, dsd_state * state)
sprintf (state->slot0light, " slot0 ");
}
}
else if (strcmp (sync, X2TDMA_VOICE_SYNC) == 0)
else if (strcmp (sync, X2TDMA_BS_VOICE_SYNC) == 0)
{
if (state->currentslot == 0)
{