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: 1.3 New features:
Decodes voice from ProVoice signals (requires -fp option) Decodes voice from ProVoice signals (requires -fp option)
algid and kid are now shown in hex notation algid and kid are now shown in hex notation
@@ -17,7 +58,7 @@
Fixed bugs: Fixed bugs:
nac was showing wrong ID 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. printed out in the correct bit order (MSB -> LSB), was reversed.
fixed serveral bugs in dsd_upsample.c, with improved quality fixed serveral bugs in dsd_upsample.c, with improved quality

View File

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

View File

@@ -14,7 +14,7 @@
# PERFORMANCE OF THIS SOFTWARE. # PERFORMANCE OF THIS SOFTWARE.
CC = gcc CC = gcc
CFLAGS = -O2 CFLAGS = -O2 -Wall
INCLUDES = -I. -I/usr/local/include -I/usr/include INCLUDES = -I. -I/usr/local/include -I/usr/include
LIBS = -L/usr/local/lib -lm -lmbe LIBS = -L/usr/local/lib -lm -lmbe
INSTALL=install INSTALL=install
@@ -24,7 +24,7 @@ DEST_BASE=/usr/local
DEST_INC=${DEST_BASE}/include DEST_INC=${DEST_BASE}/include
DEST_LIB=${DEST_BASE}/lib DEST_LIB=${DEST_BASE}/lib
DEST_BIN=${DEST_BASE}/bin 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 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 dstar.o: dstar.c dstar_const.h dsd.h config.h
$(CC) $(CFLAGS) $(INCLUDES) -c dstar.c -o dstar.o $(CC) $(CFLAGS) $(INCLUDES) -c dstar.c -o dstar.o
nxdn96.o: nxdn96.c nxdn96_const.h dsd.h config.h nxdn48_voice.o: nxdn48_voice.c nxdn_const.h dsd.h config.h
$(CC) $(CFLAGS) $(INCLUDES) -c nxdn96.c -o nxdn96.o $(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 dmr_voice.o: dmr_voice.c dmr_const.h dsd.h config.h
$(CC) $(CFLAGS) $(INCLUDES) -c dmr_voice.c -o dmr_voice.o $(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 Copyright (C) 2010 DSD Author
GPG Key ID: 0x3F1D7FD0 (74EF 430D F7F2 0A48 FCE6 F630 FAA2 635D 3F1D 7FD0) 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 DSD is able to decode several digital voice formats from discriminator
tap audio and synthesize the decoded speech. Speech 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. 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 P25 Phase 1 Widely deployed radio standard used in public safety
and amateur radio. and amateur radio.
@@ -46,19 +46,18 @@ PERFORMANCE OF THIS SOFTWARE.
DMR/MOTOTRBO "Digital Mobile Radio" Eurpoean two slot TDMA standard. DMR/MOTOTRBO "Digital Mobile Radio" Eurpoean two slot TDMA standard.
MOTOTRBO is a popular implementation of this standard. MOTOTRBO is a popular implementation of this standard.
Support includes decoding and synthesis of speech and Support includes decoding and synthesis of speech and
the ability to save and replay .amb data files. 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: 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 D-STAR Amateur radio digital voice standard
Development support only. DSD recognized frames and can 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 D-STAR likely uses a version of AMBE not yet supported by
mbelib. The voice bit interleave pattern also needs to be mbelib. The voice bit interleave pattern also needs to be
determined. 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 P25 Phase 2 This is not yet a published standard. Full support is
expected once the standard is published and there are 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 OpenSKY It is possible that the four slot version uses a vocoder
supported by mbelib. The two slot version does not. supported by mbelib. The two slot version does not.
NXDN (4800) This should be supportable as soon as we have .wav files Supported demodulation optimizations in version 1.4:
or access to a radio programmed in this format.
Supported demodulation optimizations in version 1.3:
C4FM Continuous envelope 2 or 4 level FSK with relatively C4FM Continuous envelope 2 or 4 level FSK with relatively
sharp transitions between symbols. Used by most P25 sharp transitions between symbols. Used by most P25
@@ -147,19 +143,19 @@ Display modes
Errorbars mode output for P25 Phase 1 looks like this: 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 inlvl: 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 inlvl: 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 inlvl: 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 inlvl: 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 inlvl: 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 inlvl: 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 inlvl: 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 inlvl: 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 inlvl: 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 inlvl: 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: 52610 tg: 32464 LDU1 e:
Sync: -p25p1 mod: C4FM input: 39% nac: 5C2 src: 52610 tg: 32464 LDU2 e: Sync: -P25p1 mod: C4FM inlvl: 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: 52610 tg: 32464 LDU1 e:
"Sync" indicates the frame type detected and whether the polarity is "Sync" indicates the frame type detected and whether the polarity is
positive or negative. DSD automatically detects and handles either 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. "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 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. 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 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 "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 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. "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: 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 inlvl: 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 inlvl: 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 inlvl: 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: 28% src: 17211 tg: 197 [SLOT0] slot1 VOICE e:
DMR/MOTOTRBO display is similar except it does not yet show source DMR/MOTOTRBO display is similar except it does not yet show source
and talkgroup information. and talkgroup information.
@@ -303,10 +299,10 @@ Display Options
information displayed in Errorbars mode: information displayed in Errorbars mode:
-e Show Frame Info and errorbars (default) -e Show Frame Info and errorbars (default)
-pe Show p25 encryption sync bits -pe Show P25 encryption sync bits
-pl Show p25 link control bits -pl Show P25 link control bits
-ps Show p25 status bits and low speed data -ps Show P25 status bits and low speed data
-pt Show p25 talkgroup info -pt Show P25 talkgroup info
-q Don't show Frame Info/errorbars -q Don't show Frame Info/errorbars
-s Datascope (disables other display options) -s Datascope (disables other display options)
-t Show symbol timing during sync -t Show symbol timing during sync
@@ -439,7 +435,8 @@ Scanner control options:
-B <num> Serial port baud rate (default=115200) -B <num> Serial port baud rate (default=115200)
-C <device> Serial port for scanner control (default=/dev/ttyUSB0) -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 On some P25 systems Packet Data Units (PDU) are sent on the same
frequencies used for voice traffic. If done constantly this can frequencies used for voice traffic. If done constantly this can
@@ -453,7 +450,8 @@ Decoder options
-fa Auto-detect frame type (default) -fa Auto-detect frame type (default)
-f1 Decode only P25 Phase 1 -f1 Decode only P25 Phase 1
-fd Decode only D-STAR* (no audio) -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* -fp Decode only ProVoice*
-fr Decode only DMR/MOTOTRBO -fr Decode only DMR/MOTOTRBO
-fx Decode only X2-TDMA -fx Decode only X2-TDMA
@@ -465,10 +463,13 @@ Decoder options
-xx Expect non-inverted X2-TDMA signal -xx Expect non-inverted X2-TDMA signal
-xr Expect inverted DMR/MOTOTRBO 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 ProVoice and NXDN48 not auto-detected as use different symbol
testing only and have shorter frame sync patterns that are prone to rates (9600 and 2400) than most formats (4800). D-STAR is not
false triggering. 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, MBE speech synthesis is broken down into two main types of sounds,
"Voiced" and "Unvoiced". Voiced speech bands are synthesized with "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); printf ("%s ", syncbits);
#endif #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) if (state->currentslot == 0)
{ {
@@ -217,17 +217,6 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
sprintf (state->slot1light, "[slot1]"); 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) if (opts->errorbars == 1)
{ {

View File

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

57
dsd.h
View File

@@ -18,6 +18,7 @@
#include "config.h" #include "config.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <signal.h>
#include <string.h> #include <string.h>
#define __USE_XOPEN #define __USE_XOPEN
#include <time.h> #include <time.h>
@@ -36,6 +37,12 @@
#include <math.h> #include <math.h>
#include <mbelib.h> #include <mbelib.h>
/*
* global variables
*/
int exitflag;
typedef struct typedef struct
{ {
int onesymbol; int onesymbol;
@@ -71,7 +78,8 @@ typedef struct
int frame_dstar; int frame_dstar;
int frame_x2tdma; int frame_x2tdma;
int frame_p25p1; int frame_p25p1;
int frame_nxdn; int frame_nxdn48;
int frame_nxdn96;
int frame_dmr; int frame_dmr;
int frame_provoice; int frame_provoice;
int mod_c4fm; int mod_c4fm;
@@ -100,6 +108,7 @@ typedef struct
float *audio_out_temp_buf_p; float *audio_out_temp_buf_p;
int audio_out_idx; int audio_out_idx;
int audio_out_idx2; int audio_out_idx2;
int wav_out_bytes;
int center; int center;
int jitter; int jitter;
int synctype; int synctype;
@@ -155,19 +164,35 @@ typedef struct
/* /*
* Frame sync patterns * Frame sync patterns
*/ */
#define INV_FRAME_SYNC "333331331133111131311111" #define INV_P25P1_SYNC "333331331133111131311111"
#define FRAME_SYNC "111113113311333313133333" #define P25P1_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 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 * function prototypes
@@ -189,6 +214,7 @@ void openMbeInFile (dsd_opts * opts, dsd_state * state);
void closeMbeOutFile (dsd_opts * opts, dsd_state * state); void closeMbeOutFile (dsd_opts * opts, dsd_state * state);
void openMbeOutFile (dsd_opts * opts, dsd_state * state); void openMbeOutFile (dsd_opts * opts, dsd_state * state);
void openWavOutFile (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 printFrameInfo (dsd_opts * opts, dsd_state * state);
void processFrame (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); 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 initState (dsd_state * state);
void usage (); void usage ();
void liveScanner (dsd_opts * opts, dsd_state * state); 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); int main (int argc, char **argv);
void playMbeFiles (dsd_opts * opts, dsd_state * state, 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]); 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); int getSymbol (dsd_opts * opts, dsd_state * state, int have_sync);
void upsample (dsd_state * state, float invalue); void upsample (dsd_state * state, float invalue);
void processDSTAR (dsd_opts * opts, dsd_state * state); 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 processP25lcw (dsd_opts * opts, dsd_state * state, char *lcformat, char *mfid, char *lcinfo);
void processHDU (dsd_opts * opts, dsd_state * state); void processHDU (dsd_opts * opts, dsd_state * state);
void processLDU1 (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 = max;
state->aout_max_buf_p++; state->aout_max_buf_p++;
state->aout_max_buf_idx++; 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_idx = 0;
state->aout_max_buf_p = state->aout_max_buf; state->aout_max_buf_p = state->aout_max_buf;
} }
// lookup max history // lookup max history
for (i = 0; i < 75; i++) for (i = 0; i < 25; i++)
{ {
maxbuf = state->aout_max_buf[i]; maxbuf = state->aout_max_buf[i];
if (maxbuf > max) if (maxbuf > max)
@@ -157,6 +157,7 @@ writeSynthesizedVoice (dsd_opts * opts, dsd_state * state)
int n; int n;
short aout_buf[160]; short aout_buf[160];
short *aout_buf_p; short *aout_buf_p;
ssize_t result;
aout_buf_p = aout_buf; aout_buf_p = aout_buf;
state->audio_out_temp_buf_p = state->audio_out_temp_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++; 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); fflush (opts->wav_out_f);
state->wav_out_bytes += 320;
} }
void void
playSynthesizedVoice (dsd_opts * opts, dsd_state * state) playSynthesizedVoice (dsd_opts * opts, dsd_state * state)
{ {
ssize_t result;
if (state->audio_out_idx > opts->delay) if (state->audio_out_idx > opts->delay)
{ {
// output synthesized speech to sound card // 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; 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); b = fgetc (opts->mbe_in_f);
ambe_d[48] = b; ambe_d[48] = (b & 1);
return (0); return (0);
} }
@@ -173,6 +173,7 @@ closeMbeOutFile (dsd_opts * opts, dsd_state * state)
int sum, i, j; int sum, i, j;
int talkgroup; int talkgroup;
struct tm timep; struct tm timep;
int result;
if (opts->mbe_out_f != NULL) 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); strptime (opts->mbe_out_file, "%s.amb", &timep);
} }
for (i = 0; i < 17; i++)
{
tgid[i] = 0;
}
if (state->tgcount > 0) if (state->tgcount > 0)
{ {
for (i = 0; i < 16; i++) 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[i] = (char) (((float) sum / (float) state->tgcount) + 48.5);
} }
tgid[16] = 0;
talkgroup = (int) strtol (tgid, NULL, 2); talkgroup = (int) strtol (tgid, NULL, 2);
} }
else else
@@ -216,7 +213,16 @@ closeMbeOutFile (dsd_opts * opts, dsd_state * state)
strftime (datestr, 31, "%Y-%m-%d-%H%M%S", &timep); strftime (datestr, 31, "%Y-%m-%d-%H%M%S", &timep);
sprintf (newfilename, "nac%X-%s-tg%i%s", state->nac, datestr, talkgroup, ext); sprintf (newfilename, "nac%X-%s-tg%i%s", state->nac, datestr, talkgroup, ext);
sprintf (shell, "mv %s %s", opts->mbe_out_file, newfilename); 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; return;
} }
opts->wav_out_fd = fileno (opts->wav_out_f); opts->wav_out_fd = fileno (opts->wav_out_f);
state->wav_out_bytes = 0;
fprintf (opts->wav_out_f, "RIFF"); fprintf (opts->wav_out_f, "RIFF");
// total length // 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);
fputc (0, opts->wav_out_f); fputc (0, opts->wav_out_f);
// bytes/sample // block align
fputc (2, opts->wav_out_f); fputc (2, opts->wav_out_f);
fputc (0, 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 (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); 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); level = (int) (((float) state->max / (float) 32768) * (float) 100);
if (opts->verbose > 0) if (opts->verbose > 0)
{ {
printf ("input: %2i%% ", level); printf ("inlvl: %2i%% ", level);
} }
if (state->nac != 0) if (state->nac != 0)
{ {
@@ -65,6 +65,7 @@ processFrame (dsd_opts * opts, dsd_state * state)
if ((state->synctype == 8) || (state->synctype == 9)) if ((state->synctype == 8) || (state->synctype == 9))
{ {
state->rf_mod = 2;
state->nac = 0; state->nac = 0;
state->lastsrc = 0; state->lastsrc = 0;
state->lasttg = 0; state->lasttg = 0;
@@ -73,7 +74,7 @@ processFrame (dsd_opts * opts, dsd_state * state)
if (opts->verbose > 0) if (opts->verbose > 0)
{ {
level = (int) (((float) state->max / (float) 32768) * (float) 100); level = (int) (((float) state->max / (float) 32768) * (float) 100);
printf ("input: %2i%% ", level); printf ("inlvl: %2i%% ", level);
} }
} }
state->nac = 0; state->nac = 0;
@@ -82,7 +83,30 @@ processFrame (dsd_opts * opts, dsd_state * state)
openMbeOutFile (opts, state); openMbeOutFile (opts, state);
} }
sprintf (state->fsubtype, " VOICE "); 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; return;
} }
else if ((state->synctype == 6) || (state->synctype == 7)) else if ((state->synctype == 6) || (state->synctype == 7))
@@ -95,7 +119,7 @@ processFrame (dsd_opts * opts, dsd_state * state)
if (opts->verbose > 0) if (opts->verbose > 0)
{ {
level = (int) (((float) state->max / (float) 32768) * (float) 100); level = (int) (((float) state->max / (float) 32768) * (float) 100);
printf ("input: %2i%% ", level); printf ("inlvl: %2i%% ", level);
} }
} }
state->nac = 0; state->nac = 0;
@@ -117,7 +141,7 @@ processFrame (dsd_opts * opts, dsd_state * state)
if (opts->verbose > 0) if (opts->verbose > 0)
{ {
level = (int) (((float) state->max / (float) 32768) * (float) 100); level = (int) (((float) state->max / (float) 32768) * (float) 100);
printf ("input: %2i%% ", level); printf ("inlvl: %2i%% ", level);
} }
} }
if ((state->synctype == 11) || (state->synctype == 12)) 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)) else if ((state->synctype >= 2) && (state->synctype <= 5))
{ {
state->nac = 0; state->nac = 0;
state->lastsrc = 0;
state->lasttg = 0;
if (opts->errorbars == 1) if (opts->errorbars == 1)
{ {
printFrameInfo (opts, state); printFrameInfo (opts, state);
@@ -173,7 +195,7 @@ processFrame (dsd_opts * opts, dsd_state * state)
if (opts->verbose > 0) if (opts->verbose > 0)
{ {
level = (int) (((float) state->max / (float) 32768) * (float) 100); 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)) 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); printFrameInfo (opts, state);
printf (" HDU\n"); printf (" HDU\n");
} }
state->cur_mp->repeat = 0;
if (opts->mbe_out_dir[0] != 0) if (opts->mbe_out_dir[0] != 0)
{ {
closeMbeOutFile (opts, state); closeMbeOutFile (opts, state);
@@ -280,14 +301,15 @@ processFrame (dsd_opts * opts, dsd_state * state)
printFrameInfo (opts, state); printFrameInfo (opts, state);
printf (" TDULC\n"); printf (" TDULC\n");
} }
state->cur_mp->repeat = 0;
if (opts->mbe_out_dir[0] != 0) if (opts->mbe_out_dir[0] != 0)
{ {
closeMbeOutFile (opts, state); closeMbeOutFile (opts, state);
} }
mbe_initMbeParms (state->cur_mp, state->prev_mp, state->prev_mp_enhanced); 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->lastp25type = 0;
state->err_str[0] = 0;
sprintf (state->fsubtype, " TDULC "); sprintf (state->fsubtype, " TDULC ");
state->numtdulc++; state->numtdulc++;
if ((opts->resume > 0) && (state->numtdulc > opts->resume)) if ((opts->resume > 0) && (state->numtdulc > opts->resume))
@@ -304,13 +326,13 @@ processFrame (dsd_opts * opts, dsd_state * state)
printFrameInfo (opts, state); printFrameInfo (opts, state);
printf (" TDU\n"); printf (" TDU\n");
} }
state->cur_mp->repeat = 0;
if (opts->mbe_out_dir[0] != 0) if (opts->mbe_out_dir[0] != 0)
{ {
closeMbeOutFile (opts, state); closeMbeOutFile (opts, state);
} }
mbe_initMbeParms (state->cur_mp, state->prev_mp, state->prev_mp_enhanced); 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->lastp25type = 0;
state->err_str[0] = 0; state->err_str[0] = 0;
sprintf (state->fsubtype, " TDU "); sprintf (state->fsubtype, " TDU ");
@@ -323,6 +345,12 @@ processFrame (dsd_opts * opts, dsd_state * state)
printFrameInfo (opts, state); printFrameInfo (opts, state);
printf (" TSDU\n"); printf (" TSDU\n");
} }
if (opts->resume > 0)
{
resumeScan (opts, state);
}
state->lasttg = 0;
state->lastsrc = 0;
state->lastp25type = 3; state->lastp25type = 3;
sprintf (state->fsubtype, " TSDU "); sprintf (state->fsubtype, " TSDU ");
skipDibit (opts, state, 328); skipDibit (opts, state, 328);
@@ -333,10 +361,10 @@ processFrame (dsd_opts * opts, dsd_state * state)
{ {
printFrameInfo (opts, state); printFrameInfo (opts, state);
printf (" PDU\n"); printf (" PDU\n");
if (opts->resume > 0) }
{ if (opts->resume > 0)
resumeScan (opts, state); {
} resumeScan (opts, state);
} }
if (opts->mbe_out_dir[0] != 0) if (opts->mbe_out_dir[0] != 0)
{ {
@@ -347,7 +375,6 @@ processFrame (dsd_opts * opts, dsd_state * state)
} }
state->lastp25type = 4; state->lastp25type = 4;
sprintf (state->fsubtype, " PDU "); sprintf (state->fsubtype, " PDU ");
} }
// try to guess based on previous frame if unknown type // try to guess based on previous frame if unknown type
else if (state->lastp25type == 1) else if (state->lastp25type == 1)

View File

@@ -43,22 +43,24 @@ int
getFrameSync (dsd_opts * opts, dsd_state * state) getFrameSync (dsd_opts * opts, dsd_state * state)
{ {
/* detects frame sync and returns frame type /* detects frame sync and returns frame type
* 0 = +p25p1 * 0 = +P25p1
* 1 = -p25p1 * 1 = -P25p1
* 2 = +X2-TDMA (non inverted signal data frame) * 2 = +X2-TDMA (non inverted signal data frame)
* 3 = +X2-TDMA (inverted signal voice frame) * 3 = +X2-TDMA (inverted signal voice frame)
* 4 = -X2-TDMA (non inverted signal voice frame) * 4 = -X2-TDMA (non inverted signal voice frame)
* 5 = -X2-TDMA (inverted signal data frame) * 5 = -X2-TDMA (inverted signal data frame)
* 6 = +D-STAR * 6 = +D-STAR
* 7 = -D-STAR * 7 = -D-STAR
* 8 = +NXDN96 * 8 = +NXDN (non inverted voice frame)
* 9 = -NXDN96 * 9 = -NXDN (inverted voice frame)
* 10 = +DMR (non inverted singlan data frame) * 10 = +DMR (non inverted singlan data frame)
* 11 = -DMR (inverted signal voice frame) * 11 = -DMR (inverted signal voice frame)
* 12 = +DMR (non inverted signal voice frame) * 12 = +DMR (non inverted signal voice frame)
* 13 = -DMR (inverted signal data frame) * 13 = -DMR (inverted signal data frame)
* 14 = +ProVoice * 14 = +ProVoice
* 15 = -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; int i, j, t, o, dibit, sync, symbol, synctest_pos, lastt;
@@ -73,13 +75,19 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
int lsum; int lsum;
char spectrum[64]; char spectrum[64];
for (i = 18; i < 24; i++)
{
lbuf[i] = 0;
lbuf2[i] = 0;
}
// detect frame sync // detect frame sync
t = 0; t = 0;
synctest[24] = 0; synctest[24] = 0;
synctest18[18] = 0; synctest18[18] = 0;
synctest32[32] = 0; synctest32[32] = 0;
synctest_pos = 0; synctest_pos = 0;
synctest_p = synctest_buf; synctest_p = synctest_buf + 10;
sync = 0; sync = 0;
lmin = 0; lmin = 0;
lmax = 0; lmax = 0;
@@ -158,18 +166,8 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
dibit = 51; dibit = 51;
} }
/*
printf("%c", dibit);
if (t == 768)
{
printf("\n");
t=0;
}
*/
*synctest_p = dibit; *synctest_p = dibit;
if (t >= 24) if (t >= 18)
{ {
for (i = 0; i < 24; i++) for (i = 0; i < 24; i++)
{ {
@@ -304,7 +302,7 @@ if (t == 768)
strncpy (synctest, (synctest_p - 23), 24); strncpy (synctest, (synctest_p - 23), 24);
if (opts->frame_p25p1 == 1) if (opts->frame_p25p1 == 1)
{ {
if (strcmp (synctest, FRAME_SYNC) == 0) if (strcmp (synctest, P25P1_SYNC) == 0)
{ {
state->carrier = 1; state->carrier = 1;
state->offset = synctest_pos; state->offset = synctest_pos;
@@ -313,12 +311,12 @@ if (t == 768)
sprintf (state->ftype, " P25 Phase 1 "); sprintf (state->ftype, " P25 Phase 1 ");
if (opts->errorbars == 1) if (opts->errorbars == 1)
{ {
printFrameSync (opts, state, " +p25p1 ", synctest_pos + 1, modulation); printFrameSync (opts, state, " +P25p1 ", synctest_pos + 1, modulation);
} }
state->lastsynctype = 0; state->lastsynctype = 0;
return (0); return (0);
} }
if (strcmp (synctest, INV_FRAME_SYNC) == 0) if (strcmp (synctest, INV_P25P1_SYNC) == 0)
{ {
state->carrier = 1; state->carrier = 1;
state->offset = synctest_pos; state->offset = synctest_pos;
@@ -327,7 +325,7 @@ if (t == 768)
sprintf (state->ftype, " P25 Phase 1 "); sprintf (state->ftype, " P25 Phase 1 ");
if (opts->errorbars == 1) if (opts->errorbars == 1)
{ {
printFrameSync (opts, state, " -p25p1 ", synctest_pos + 1, modulation); printFrameSync (opts, state, " -P25p1 ", synctest_pos + 1, modulation);
} }
state->lastsynctype = 1; state->lastsynctype = 1;
return (1); return (1);
@@ -335,7 +333,7 @@ if (t == 768)
} }
if (opts->frame_x2tdma == 1) 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->carrier = 1;
state->offset = synctest_pos; state->offset = synctest_pos;
@@ -368,7 +366,7 @@ if (t == 768)
return (3); 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->carrier = 1;
state->offset = synctest_pos; state->offset = synctest_pos;
@@ -404,7 +402,7 @@ if (t == 768)
} }
if (opts->frame_dmr == 1) 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->carrier = 1;
state->offset = synctest_pos; state->offset = synctest_pos;
@@ -437,7 +435,7 @@ if (t == 768)
return (11); 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->carrier = 1;
state->offset = synctest_pos; state->offset = synctest_pos;
@@ -474,7 +472,7 @@ if (t == 768)
if (opts->frame_provoice == 1) if (opts->frame_provoice == 1)
{ {
strncpy (synctest32, (synctest_p - 31), 32); 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->carrier = 1;
state->offset = synctest_pos; state->offset = synctest_pos;
@@ -488,7 +486,7 @@ if (t == 768)
state->lastsynctype = 14; state->lastsynctype = 14;
return (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->carrier = 1;
state->offset = synctest_pos; 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); 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; if ((state->lastsynctype == 8) || (state->lastsynctype == 16))
state->offset = synctest_pos;
state->max = ((state->max) + lmax) / 2;
state->min = ((state->min) + lmin) / 2;
sprintf (state->ftype, " NXDN96 ");
if (opts->errorbars == 1)
{ {
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; if ((state->lastsynctype == 9) || (state->lastsynctype == 17))
state->offset = synctest_pos;
state->max = ((state->max) + lmax) / 2;
state->min = ((state->min) + lmin) / 2;
sprintf (state->ftype, " NXDN96 ");
if (opts->errorbars == 1)
{ {
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) if (opts->frame_dstar == 1)
@@ -579,7 +678,7 @@ if (t == 768)
sprintf (state->ftype, "(P25 Phase 1)"); sprintf (state->ftype, "(P25 Phase 1)");
if (opts->errorbars == 1) if (opts->errorbars == 1)
{ {
printFrameSync (opts, state, "(+p25p1) ", synctest_pos + 1, modulation); printFrameSync (opts, state, "(+P25p1) ", synctest_pos + 1, modulation);
} }
state->lastsynctype = -1; state->lastsynctype = -1;
return (0); return (0);
@@ -593,12 +692,12 @@ if (t == 768)
sprintf (state->ftype, "(P25 Phase 1)"); sprintf (state->ftype, "(P25 Phase 1)");
if (opts->errorbars == 1) if (opts->errorbars == 1)
{ {
printFrameSync (opts, state, "(-p25p1) ", synctest_pos + 1, modulation); printFrameSync (opts, state, "(-P25p1) ", synctest_pos + 1, modulation);
} }
state->lastsynctype = -1; state->lastsynctype = -1;
return (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->carrier = 1;
state->offset = synctest_pos; state->offset = synctest_pos;
@@ -612,7 +711,7 @@ if (t == 768)
state->lastsynctype = -1; state->lastsynctype = -1;
return (3); 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->carrier = 1;
state->offset = synctest_pos; state->offset = synctest_pos;
@@ -626,7 +725,7 @@ if (t == 768)
state->lastsynctype = -1; state->lastsynctype = -1;
return (4); 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->carrier = 1;
state->offset = synctest_pos; state->offset = synctest_pos;
@@ -640,7 +739,7 @@ if (t == 768)
state->lastsynctype = -1; state->lastsynctype = -1;
return (11); 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->carrier = 1;
state->offset = synctest_pos; state->offset = synctest_pos;
@@ -657,6 +756,11 @@ if (t == 768)
} }
} }
if (exitflag == 1)
{
cleanupAndExit (opts, state);
}
if (synctest_pos < 10200) if (synctest_pos < 10200)
{ {
synctest_pos++; synctest_pos++;
@@ -670,16 +774,13 @@ if (t == 768)
noCarrier (opts, state); noCarrier (opts, state);
} }
if (state->carrier == 1) if (state->lastsynctype != 1)
{ {
if (synctest_pos >= 1800) 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); noCarrier (opts, state);
return (-1); return (-1);

View File

@@ -21,7 +21,7 @@
#include "p25p1_const.h" #include "p25p1_const.h"
#include "x2tdma_const.h" #include "x2tdma_const.h"
#include "dstar_const.h" #include "dstar_const.h"
#include "nxdn96_const.h" #include "nxdn_const.h"
#include "dmr_const.h" #include "dmr_const.h"
#include "provoice_const.h" #include "provoice_const.h"
@@ -39,7 +39,6 @@ comp (const void *a, const void *b)
void void
noCarrier (dsd_opts * opts, dsd_state * state) noCarrier (dsd_opts * opts, dsd_state * state)
{ {
state->dibit_buf_p = state->dibit_buf + 200; state->dibit_buf_p = state->dibit_buf + 200;
memset (state->dibit_buf, 0, sizeof (int) * 200); memset (state->dibit_buf, 0, sizeof (int) * 200);
if (opts->mbe_out_f != NULL) if (opts->mbe_out_f != NULL)
@@ -55,6 +54,8 @@ noCarrier (dsd_opts * opts, dsd_state * state)
state->err_str[0] = 0; state->err_str[0] = 0;
sprintf (state->fsubtype, " "); sprintf (state->fsubtype, " ");
sprintf (state->ftype, " "); sprintf (state->ftype, " ");
state->errs = 0;
state->errs2 = 0;
state->lasttg = 0; state->lasttg = 0;
state->lastsrc = 0; state->lastsrc = 0;
state->lastp25type = 0; state->lastp25type = 0;
@@ -112,7 +113,8 @@ initOpts (dsd_opts * opts)
opts->frame_dstar = 0; opts->frame_dstar = 0;
opts->frame_x2tdma = 1; opts->frame_x2tdma = 1;
opts->frame_p25p1 = 1; opts->frame_p25p1 = 1;
opts->frame_nxdn = 0; opts->frame_nxdn48 = 0;
opts->frame_nxdn96 = 1;
opts->frame_dmr = 1; opts->frame_dmr = 1;
opts->frame_provoice = 0; opts->frame_provoice = 0;
opts->mod_c4fm = 1; opts->mod_c4fm = 1;
@@ -147,6 +149,7 @@ initState (dsd_state * state)
state->audio_out_idx = 0; state->audio_out_idx = 0;
state->audio_out_idx2 = 0; state->audio_out_idx2 = 0;
state->audio_out_temp_buf_p = state->audio_out_temp_buf; state->audio_out_temp_buf_p = state->audio_out_temp_buf;
state->wav_out_bytes = 0;
state->center = 0; state->center = 0;
state->jitter = -1; state->jitter = -1;
state->synctype = -1; state->synctype = -1;
@@ -181,11 +184,11 @@ initState (dsd_state * state)
state->lastp25type = 0; state->lastp25type = 0;
state->offset = 0; state->offset = 0;
state->carrier = 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; state->tgcount = 0;
@@ -218,7 +221,6 @@ initState (dsd_state * state)
void void
usage () usage ()
{ {
printf ("Digital Speech Decoder 1.3\n");
printf ("\n"); printf ("\n");
printf ("Usage:\n"); printf ("Usage:\n");
printf (" dsd [options] Live scanner mode\n"); printf (" dsd [options] Live scanner mode\n");
@@ -227,10 +229,10 @@ usage ()
printf ("\n"); printf ("\n");
printf ("Display Options:\n"); printf ("Display Options:\n");
printf (" -e Show Frame Info and errorbars (default)\n"); printf (" -e Show Frame Info and errorbars (default)\n");
printf (" -pe Show p25 encryption sync bits\n"); printf (" -pe Show P25 encryption sync bits\n");
printf (" -pl Show p25 link control bits\n"); printf (" -pl Show P25 link control bits\n");
printf (" -ps Show p25 status bits and low speed data\n"); printf (" -ps Show P25 status bits and low speed data\n");
printf (" -pt Show p25 talkgroup info\n"); printf (" -pt Show P25 talkgroup info\n");
printf (" -q Don't show Frame Info/errorbars\n"); printf (" -q Don't show Frame Info/errorbars\n");
printf (" -s Datascope (disables other display options)\n"); printf (" -s Datascope (disables other display options)\n");
printf (" -t Show symbol timing during sync\n"); printf (" -t Show symbol timing during sync\n");
@@ -248,13 +250,14 @@ usage ()
printf ("Scanner control options:\n"); printf ("Scanner control options:\n");
printf (" -B <num> Serial port baud rate (default=115200)\n"); printf (" -B <num> Serial port baud rate (default=115200)\n");
printf (" -C <device> Serial port for scanner control (default=/dev/ttyUSB0)\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 ("\n");
printf ("Decoder options:\n"); printf ("Decoder options:\n");
printf (" -fa Auto-detect frame type (default)\n"); printf (" -fa Auto-detect frame type (default)\n");
printf (" -f1 Decode only P25 Phase 1\n"); printf (" -f1 Decode only P25 Phase 1\n");
printf (" -fd Decode only D-STAR* (no audio)\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 (" -fp Decode only ProVoice*\n");
printf (" -fr Decode only DMR/MOTOTRBO\n"); printf (" -fr Decode only DMR/MOTOTRBO\n");
printf (" -fx Decode only X2-TDMA\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 int
main (int argc, char **argv) main (int argc, char **argv)
{ {
@@ -307,13 +329,20 @@ main (int argc, char **argv)
int c; int c;
extern char *optarg; extern char *optarg;
extern int optind, opterr, optopt; extern int optind, opterr, optopt;
dsd_opts opts; dsd_opts opts;
dsd_state state; 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); initOpts (&opts);
initState (&state); 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) 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; opterr = 0;
@@ -424,7 +453,8 @@ main (int argc, char **argv)
opts.frame_dstar = 0; opts.frame_dstar = 0;
opts.frame_x2tdma = 1; opts.frame_x2tdma = 1;
opts.frame_p25p1 = 1; opts.frame_p25p1 = 1;
opts.frame_nxdn = 0; opts.frame_nxdn48 = 0;
opts.frame_nxdn96 = 1;
opts.frame_dmr = 1; opts.frame_dmr = 1;
opts.frame_provoice = 0; opts.frame_provoice = 0;
} }
@@ -433,7 +463,8 @@ main (int argc, char **argv)
opts.frame_dstar = 1; opts.frame_dstar = 1;
opts.frame_x2tdma = 0; opts.frame_x2tdma = 0;
opts.frame_p25p1 = 0; opts.frame_p25p1 = 0;
opts.frame_nxdn = 0; opts.frame_nxdn48 = 0;
opts.frame_nxdn96 = 0;
opts.frame_dmr = 0; opts.frame_dmr = 0;
opts.frame_provoice = 0; opts.frame_provoice = 0;
printf ("Decoding only D-STAR frames.\n"); printf ("Decoding only D-STAR frames.\n");
@@ -443,7 +474,8 @@ main (int argc, char **argv)
opts.frame_dstar = 0; opts.frame_dstar = 0;
opts.frame_x2tdma = 1; opts.frame_x2tdma = 1;
opts.frame_p25p1 = 0; opts.frame_p25p1 = 0;
opts.frame_nxdn = 0; opts.frame_nxdn48 = 0;
opts.frame_nxdn96 = 0;
opts.frame_dmr = 0; opts.frame_dmr = 0;
opts.frame_provoice = 0; opts.frame_provoice = 0;
printf ("Decoding only X2-TDMA frames.\n"); printf ("Decoding only X2-TDMA frames.\n");
@@ -453,7 +485,8 @@ main (int argc, char **argv)
opts.frame_dstar = 0; opts.frame_dstar = 0;
opts.frame_x2tdma = 0; opts.frame_x2tdma = 0;
opts.frame_p25p1 = 0; opts.frame_p25p1 = 0;
opts.frame_nxdn = 0; opts.frame_nxdn48 = 0;
opts.frame_nxdn96 = 0;
opts.frame_dmr = 0; opts.frame_dmr = 0;
opts.frame_provoice = 1; opts.frame_provoice = 1;
state.samplesPerSymbol = 5; state.samplesPerSymbol = 5;
@@ -462,6 +495,7 @@ main (int argc, char **argv)
opts.mod_qpsk = 0; opts.mod_qpsk = 0;
opts.mod_gfsk = 1; opts.mod_gfsk = 1;
state.rf_mod = 2; state.rf_mod = 2;
printf ("Setting symbol rate to 9600 / second\n");
printf ("Enabling only GFSK modulation optimizations.\n"); printf ("Enabling only GFSK modulation optimizations.\n");
printf ("Decoding only ProVoice frames.\n"); printf ("Decoding only ProVoice frames.\n");
} }
@@ -470,19 +504,45 @@ main (int argc, char **argv)
opts.frame_dstar = 0; opts.frame_dstar = 0;
opts.frame_x2tdma = 0; opts.frame_x2tdma = 0;
opts.frame_p25p1 = 1; opts.frame_p25p1 = 1;
opts.frame_nxdn = 0; opts.frame_nxdn48 = 0;
opts.frame_nxdn96 = 0;
opts.frame_dmr = 0; opts.frame_dmr = 0;
opts.frame_provoice = 0; opts.frame_provoice = 0;
printf ("Decoding only P25 Phase 1 frames.\n"); 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') else if (optarg[0] == 'n')
{ {
opts.frame_dstar = 0; opts.frame_dstar = 0;
opts.frame_x2tdma = 0; opts.frame_x2tdma = 0;
opts.frame_p25p1 = 0; opts.frame_p25p1 = 0;
opts.frame_nxdn = 1; opts.frame_nxdn48 = 0;
opts.frame_nxdn96 = 1;
opts.frame_dmr = 0; opts.frame_dmr = 0;
opts.frame_provoice = 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"); printf ("Decoding only NXDN 9600 baud frames.\n");
} }
else if (optarg[0] == 'r') else if (optarg[0] == 'r')
@@ -490,7 +550,8 @@ main (int argc, char **argv)
opts.frame_dstar = 0; opts.frame_dstar = 0;
opts.frame_x2tdma = 0; opts.frame_x2tdma = 0;
opts.frame_p25p1 = 0; opts.frame_p25p1 = 0;
opts.frame_nxdn = 0; opts.frame_nxdn48 = 0;
opts.frame_nxdn96 = 0;
opts.frame_dmr = 1; opts.frame_dmr = 1;
opts.frame_provoice = 0; opts.frame_provoice = 0;
printf ("Decoding only DMR/MOTOTRBO frames.\n"); printf ("Decoding only DMR/MOTOTRBO frames.\n");
@@ -617,7 +678,7 @@ main (int argc, char **argv)
else else
{ {
opts.split = 0; opts.split = 0;
opts.playoffset = 38; opts.playoffset = 25; // 38
opts.delay = 0; opts.delay = 0;
openAudioInDevice (&opts); openAudioInDevice (&opts);
opts.audio_out_fd = opts.audio_in_fd; opts.audio_out_fd = opts.audio_in_fd;
@@ -631,5 +692,6 @@ main (int argc, char **argv)
{ {
liveScanner (&opts, &state); liveScanner (&opts, &state);
} }
cleanupAndExit (&opts, &state);
return (0); 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++) 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); openMbeInFile (opts, state);
mbe_initMbeParms (state->cur_mp, state->prev_mp, state->prev_mp_enhanced); mbe_initMbeParms (state->cur_mp, state->prev_mp, state->prev_mp_enhanced);
printf ("playing %s\n", opts->mbe_in_file); 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); 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; tty.c_cflag = 0;
baud = B115200;
switch (opts->serial_baud) switch (opts->serial_baud)
{ {
case 1200: case 1200:
@@ -70,19 +71,20 @@ void
resumeScan (dsd_opts * opts, dsd_state * state) resumeScan (dsd_opts * opts, dsd_state * state)
{ {
char cmd[7]; char cmd[16];
ssize_t result;
if (opts->serial_fd > 0) if (opts->serial_fd > 0)
{ {
sprintf (cmd, "\rKEY00\r"); sprintf (cmd, "\rKEY00\r");
write (opts->serial_fd, cmd, 7); result = write (opts->serial_fd, cmd, 7);
cmd[0] = 2; cmd[0] = 2;
cmd[1] = 75; cmd[1] = 75;
cmd[2] = 15; cmd[2] = 15;
cmd[3] = 3; cmd[3] = 3;
cmd[4] = 93; cmd[4] = 93;
cmd[5] = 0; cmd[5] = 0;
write (opts->serial_fd, cmd, 5); result = write (opts->serial_fd, cmd, 5);
state->numtdulc = 0; state->numtdulc = 0;
} }
} }

View File

@@ -23,6 +23,7 @@ getSymbol (dsd_opts * opts, dsd_state * state, int have_sync)
short sample; short sample;
int i, sum, symbol, count; int i, sum, symbol, count;
ssize_t result;
sum = 0; sum = 0;
count = 0; count = 0;
@@ -31,7 +32,18 @@ getSymbol (dsd_opts * opts, dsd_state * state, int have_sync)
// timing control // timing control
if ((i == 0) && (have_sync == 0)) 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)) 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; 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)) if ((sample > state->max) && (have_sync == 1) && (state->rf_mod == 0))
{ {
sample = state->max; 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 (state->samplesPerSymbol == 5)
{ {
if ((i >= 2) && (i <= 2)) if (i == 2)
{ {
sum += sample; sum += sample;
count++; count++;

View File

@@ -22,150 +22,47 @@ upsample (dsd_state * state, float invalue)
{ {
int i, j, sum; int i, j, sum;
float *outbuf1, a, b, c, d; float *outbuf1, c, d;
float phasestart, phaseend, resamplestart, resampleend, phasestep, resampleamp2;
float resamplemin, resamplemax;
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; // smoothing
outbuf1--; outbuf1 -= 16;
c = *outbuf1; for (j = 0; j < 4; j++)
outbuf1 -= 6;
b = *outbuf1;
outbuf1 -= 6;
a = *outbuf1;
d = (invalue);
resamplemin = 32767;
resamplemax = -32768;
if (a < resamplemin)
{ {
resamplemin = a; for (i = 0; i < 6; i++)
}
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++)
{ {
sum = 0; sum = 0;
outbuf1--; outbuf1 -= 2;
sum += *outbuf1; sum += *outbuf1;
outbuf1++; outbuf1 += 2;
sum += *outbuf1; sum += *outbuf1;
outbuf1++; outbuf1 += 2;
sum += *outbuf1; sum += *outbuf1;
outbuf1--; outbuf1 -= 2;
*outbuf1 = (sum / (float) 3); *outbuf1 = (sum / (float) 3);
outbuf1++; 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 // 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; j = 0;
for (i = 40; i < 52; i++) for (i = 40; i < 52; i++)
{ {
if (state->tgcount < 24)
{
state->tg[state->tgcount][j] = lcinfo[i];
}
tmpstr[j] = lcinfo[i]; tmpstr[j] = lcinfo[i];
j++; j++;
} }
@@ -52,9 +38,17 @@ processP25lcw (dsd_opts * opts, dsd_state * state, char *lcformat, char *mfid, c
tmpstr[14] = 48; tmpstr[14] = 48;
tmpstr[15] = 48; tmpstr[15] = 48;
tmpstr[16] = 0; tmpstr[16] = 0;
tmpstr[16] = 0;
talkgroup = strtol (tmpstr, NULL, 2); talkgroup = strtol (tmpstr, NULL, 2);
state->lasttg = talkgroup; state->lasttg = talkgroup;
if (state->tgcount < 24)
{
state->tgcount = state->tgcount + 1;
}
if (opts->p25tg == 1)
{
printf ("tg: %li ", talkgroup);
}
if (opts->p25tg == 1) if (opts->p25tg == 1)
{ {
printf ("tg: %li ", talkgroup); printf ("tg: %li ", talkgroup);
@@ -136,6 +130,10 @@ processP25lcw (dsd_opts * opts, dsd_state * state, char *lcformat, char *mfid, c
tmpstr[16] = 0; tmpstr[16] = 0;
talkgroup = strtol (tmpstr, NULL, 2); talkgroup = strtol (tmpstr, NULL, 2);
state->lasttg = talkgroup; state->lasttg = talkgroup;
if (state->tgcount < 24)
{
state->tgcount = state->tgcount + 1;
}
if (opts->p25tg == 1) if (opts->p25tg == 1)
{ {
printf ("tg: %li ", talkgroup); printf ("tg: %li ", talkgroup);

View File

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

View File

@@ -207,7 +207,7 @@ processX2TDMAdata (dsd_opts * opts, dsd_state * state)
printf ("%s ", syncbits); printf ("%s ", syncbits);
#endif #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) if (state->currentslot == 0)
{ {
@@ -218,17 +218,6 @@ processX2TDMAdata (dsd_opts * opts, dsd_state * state)
sprintf (state->slot1light, "[slot1]"); 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) if (opts->errorbars == 1)
{ {

View File

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