mirror of
https://github.com/lwvmobile/dsd-fme.git
synced 2026-11-12 16:57:23 -05:00
DMR Stereo TDMA
DMR Stereo TDMA --play voice in both TDMA slots with the -T option (dsd -fr -T) --Improved MS voice (mostly working) and data handling (hit or miss) --pretty pretty colors on the console log output --rate 3/4 data decoding partially working
This commit is contained in:
139
include/dsd.h
139
include/dsd.h
@@ -17,6 +17,17 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
//pretty pretty colors
|
||||
|
||||
#define KNRM "\x1B[0m"
|
||||
#define KRED "\x1B[31m"
|
||||
#define KGRN "\x1B[32m"
|
||||
#define KYEL "\x1B[33m"
|
||||
#define KBLU "\x1B[34m"
|
||||
#define KMAG "\x1B[35m"
|
||||
#define KCYN "\x1B[36m"
|
||||
#define KWHT "\x1B[37m"
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -67,13 +78,11 @@
|
||||
//look into making this not required by doing ifdef, make new c file for methods, and CLI case option for ncurses terminal
|
||||
#include <locale.h> //move this stuff to dsd.h
|
||||
#include <ncurses.h> //move this stuff to dsd.h
|
||||
/*
|
||||
* global variables
|
||||
*/
|
||||
//
|
||||
|
||||
//
|
||||
static volatile int exitflag;
|
||||
|
||||
//borrow from LEH
|
||||
typedef struct
|
||||
{
|
||||
uint8_t RFChannelType;
|
||||
@@ -148,8 +157,6 @@ typedef struct
|
||||
} NxdnElementsContent_t;
|
||||
|
||||
|
||||
//LEH DMR
|
||||
|
||||
enum
|
||||
{
|
||||
MODE_UNENCRYPTED,
|
||||
@@ -230,8 +237,8 @@ typedef struct
|
||||
FullLinkControlPDU_t FullLC;
|
||||
} TimeSlotVoiceSuperFrame_t;
|
||||
|
||||
//end borrow from LEH
|
||||
//LEH dPMR
|
||||
|
||||
//dPMR
|
||||
/* Could only be 2 or 4 */
|
||||
#define NB_OF_DPMR_VOICE_FRAME_TO_DECODE 2
|
||||
|
||||
@@ -293,11 +300,13 @@ typedef struct
|
||||
int audio_out_type; // 0 for device, 1 for file, 2 for portaudio
|
||||
int split;
|
||||
int playoffset;
|
||||
int playoffsetR;
|
||||
char mbe_out_dir[1024];
|
||||
char mbe_out_file[1024];
|
||||
char mbe_out_path[1024];
|
||||
FILE *mbe_out_f;
|
||||
float audio_gain;
|
||||
float audio_gainR;
|
||||
int audio_out;
|
||||
char wav_out_file[1024];
|
||||
SNDFILE *wav_out_f;
|
||||
@@ -337,27 +346,34 @@ typedef struct
|
||||
int pulse_raw_rate_out;
|
||||
int pulse_digi_rate_in;
|
||||
int pulse_digi_rate_out;
|
||||
//int pulse_digi_rate_outR;
|
||||
int pulse_raw_in_channels;
|
||||
int pulse_raw_out_channels;
|
||||
int pulse_digi_in_channels;
|
||||
int pulse_digi_out_channels;
|
||||
//int pulse_digi_out_channelsR;
|
||||
int pulse_flush;
|
||||
pa_simple *pulse_raw_dev_in;
|
||||
pa_simple *pulse_raw_dev_out;
|
||||
pa_simple *pulse_digi_dev_in;
|
||||
pa_simple *pulse_digi_dev_out;
|
||||
pa_simple *pulse_digi_dev_outR;
|
||||
int use_ncurses_terminal;
|
||||
int reset_state;
|
||||
int payload;
|
||||
char output_name[1024];
|
||||
//LEH DMR Stuff
|
||||
|
||||
int EncryptionMode;
|
||||
|
||||
//LEH dPMR stuff
|
||||
unsigned int dPMR_curr_frame_is_encrypted;
|
||||
int dPMR_next_part_of_superframe;
|
||||
int inverted_dpmr;
|
||||
int frame_dpmr;
|
||||
//
|
||||
short int dmr_stereo;
|
||||
//
|
||||
int frame_ysf;
|
||||
int inverted_ysf; //not sure if ysf comes in inverted or not, but signal could if IQ flipped
|
||||
|
||||
} dsd_opts;
|
||||
|
||||
@@ -365,6 +381,8 @@ typedef struct
|
||||
{
|
||||
int *dibit_buf;
|
||||
int *dibit_buf_p;
|
||||
int *dmr_payload_buf; //try loading up a small amount to buffer, 144 or 288?
|
||||
int *dmr_payload_p; //position for payload buffer
|
||||
int repeat;
|
||||
short *audio_out_buf;
|
||||
short *audio_out_buf_p;
|
||||
@@ -418,6 +436,8 @@ typedef struct
|
||||
int nac;
|
||||
int errs;
|
||||
int errs2;
|
||||
int errsR;
|
||||
int errs2R;
|
||||
int mbe_file_type;
|
||||
int optind;
|
||||
int numtdulc;
|
||||
@@ -425,17 +445,25 @@ typedef struct
|
||||
char slot0light[8];
|
||||
//char slot1light[8];
|
||||
float aout_gain;
|
||||
float aout_gainR;
|
||||
float aout_max_buf[200];
|
||||
float aout_max_bufR[200];
|
||||
float *aout_max_buf_p;
|
||||
float *aout_max_buf_pR;
|
||||
int aout_max_buf_idx;
|
||||
int aout_max_buf_idxR;
|
||||
int samplesPerSymbol;
|
||||
int symbolCenter;
|
||||
char algid[9];
|
||||
char keyid[17];
|
||||
int currentslot;
|
||||
int hardslot;
|
||||
mbe_parms *cur_mp;
|
||||
mbe_parms *prev_mp;
|
||||
mbe_parms *prev_mp_enhanced;
|
||||
mbe_parms *cur_mp2;
|
||||
mbe_parms *prev_mp2;
|
||||
mbe_parms *prev_mp_enhanced2;
|
||||
int p25kid;
|
||||
int payload_algid;
|
||||
int payload_keyid;
|
||||
@@ -444,6 +472,7 @@ typedef struct
|
||||
unsigned long long int K;
|
||||
|
||||
unsigned int debug_audio_errors;
|
||||
unsigned int debug_audio_errorsR;
|
||||
unsigned int debug_header_errors;
|
||||
unsigned int debug_header_critical_errors;
|
||||
|
||||
@@ -478,10 +507,9 @@ typedef struct
|
||||
unsigned int nxdn_cipher_type;
|
||||
unsigned int nxdn_key;
|
||||
char nxdn_call_type[1024];
|
||||
char dmr_callsign[4][99]; //plenty of room in case of overflow;
|
||||
char dmr_callsign[6][99]; //plenty of room in case of overflow;
|
||||
char dmr_lrrp[6][9999];
|
||||
|
||||
//borrow from LEH
|
||||
NxdnSacchRawPart_t NxdnSacchRawPart[4];
|
||||
NxdnFacch1RawPart_t NxdnFacch1RawPart[2];
|
||||
NxdnFacch2RawPart_t NxdnFacch2RawPart;
|
||||
@@ -492,8 +520,7 @@ typedef struct
|
||||
|
||||
char ambe_ciphered[49];
|
||||
char ambe_deciphered[49];
|
||||
//end borrow
|
||||
//LEH DMR struff
|
||||
|
||||
unsigned int color_code;
|
||||
unsigned int color_code_ok;
|
||||
unsigned int PI;
|
||||
@@ -511,10 +538,13 @@ typedef struct
|
||||
TimeSlotVoiceSuperFrame_t TS2SuperFrame;
|
||||
|
||||
char dmr_branding[25];
|
||||
uint8_t dmr_12_rate_sf[36]; //going three frames deep
|
||||
uint8_t dmr_34_rate_sf[54]; //going three frames deep
|
||||
uint8_t dmr_12_rate_sf[2][60]; //going five frames deep by 12 bytes //[slot][value]
|
||||
uint8_t dmr_34_rate_sf[2][64]; //going four frames deep by 16 bytes //[slot][value]
|
||||
//char dmr_stereo_payload[144]; //load up 144 dibit buffer for every single DMR TDMA frame
|
||||
//char dmr_msmode_payload[144];
|
||||
int dmr_stereo_payload[144]; //load up 144 dibit buffer for every single DMR TDMA frame
|
||||
|
||||
|
||||
//LEH dPMR stuff
|
||||
dPMRVoiceFS2Frame_t dPMRVoiceFS2Frame;
|
||||
|
||||
//These flags are used to known the DMR frame
|
||||
@@ -539,6 +569,10 @@ typedef struct
|
||||
unsigned char * dpmr_target_id;
|
||||
int dpmr_color_code;
|
||||
|
||||
short int dmr_stereo; //need state variable for upsample function
|
||||
short int dmr_ms_rc;
|
||||
short int dmr_ms_mode;
|
||||
|
||||
#ifdef TRACE_DSD
|
||||
char debug_prefix;
|
||||
char debug_prefix_2;
|
||||
@@ -555,6 +589,10 @@ typedef struct
|
||||
/*
|
||||
* Frame sync patterns
|
||||
*/
|
||||
|
||||
#define FUSION_SYNC "31111311313113131131" //HA!
|
||||
#define INV_FUSION_SYNC "13333133131331313313" //HA!
|
||||
|
||||
#define INV_P25P1_SYNC "333331331133111131311111"
|
||||
#define P25P1_SYNC "111113113311333313133333"
|
||||
|
||||
@@ -568,14 +606,6 @@ typedef struct
|
||||
#define DSTAR_SYNC "313131313133131113313111"
|
||||
#define INV_DSTAR_SYNC "131313131311313331131333"
|
||||
|
||||
//bogus nxdnn data syncs to troubleshoot
|
||||
/*
|
||||
#define NXDN_MS_DATA_SYNC "33333313133113131111333333333111"
|
||||
#define INV_NXDN_MS_DATA_SYNC "11133331313113313133331113333331"
|
||||
#define INV_NXDN_BS_DATA_SYNC "33331111313113313133331313333333"
|
||||
#define NXDN_BS_DATA_SYNC "11113333131331131311113133333333"
|
||||
//end bogus nxdn data syncs
|
||||
*/
|
||||
#define NXDN_MS_DATA_SYNC "313133113131111333"
|
||||
#define INV_NXDN_MS_DATA_SYNC "131311331313333111"
|
||||
#define INV_NXDN_BS_DATA_SYNC "131311331313333131"
|
||||
@@ -589,64 +619,52 @@ typedef struct
|
||||
#define DMR_BS_VOICE_SYNC "131111333113313313113313"
|
||||
#define DMR_MS_DATA_SYNC "311131133313133331131113"
|
||||
#define DMR_MS_VOICE_SYNC "133313311131311113313331"
|
||||
//borrow extra syncs from LEH
|
||||
|
||||
//inversion testing on MS
|
||||
//#define DMR_MS_DATA_SYNC "133313311131311113313331"
|
||||
//#define DMR_MS_VOICE_SYNC "311131133313133331131113"
|
||||
|
||||
#define DMR_RC_DATA_SYNC "131331111133133133311313"
|
||||
|
||||
#define DMR_DIRECT_MODE_TS1_DATA_SYNC "331333313111313133311111"
|
||||
#define DMR_DIRECT_MODE_TS1_VOICE_SYNC "113111131333131311133333"
|
||||
#define DMR_DIRECT_MODE_TS2_DATA_SYNC "311311111333113333133311"
|
||||
#define DMR_DIRECT_MODE_TS2_VOICE_SYNC "133133333111331111311133"
|
||||
//end LEH
|
||||
|
||||
#define INV_PROVOICE_SYNC "31313111333133133311331133113311"
|
||||
#define PROVOICE_SYNC "13131333111311311133113311331133"
|
||||
#define INV_PROVOICE_EA_SYNC "13313133113113333311313133133311"
|
||||
#define PROVOICE_EA_SYNC "31131311331331111133131311311133"
|
||||
|
||||
//LEH dPMR
|
||||
/* dPMR Frame Sync 1 - 48 bits sequence
|
||||
* HEX : 57 FF 5F 75 D5 77
|
||||
* Binary : 0101 0111 1111 1111 0101 1111 0111 0101 1101 0101 0111 0111
|
||||
* Dibit : 1 1 1 3 3 3 3 3 1 1 3 3 1 3 1 1 3 1 1 1 1 3 1 3 */
|
||||
|
||||
#define DPMR_FRAME_SYNC_1 "111333331133131131111313"
|
||||
|
||||
/* dPMR Frame Sync 2 - 24 bits sequence
|
||||
* HEX : 5F F7 7D
|
||||
* Binary : 0101 1111 1111 0111 0111 1101
|
||||
* Dibit : 1 1 3 3 3 3 1 3 1 3 3 1 */
|
||||
#define DPMR_FRAME_SYNC_2 "113333131331"
|
||||
|
||||
/* dPMR Frame Sync 3 - 24 bits sequence
|
||||
* HEX : 7D DF F5
|
||||
* Binary : 0111 1101 1101 1111 1111 0101
|
||||
* Dibit : 1 3 3 1 3 1 3 3 3 3 1 1 */
|
||||
#define DPMR_FRAME_SYNC_3 "133131333311"
|
||||
|
||||
/* dPMR Frame Sync 4 - 48 bits sequence
|
||||
* HEX : FD 55 F5 DF 7F DD
|
||||
* Binary : 1111 1101 0101 0101 1111 0101 1101 1111 0111 1111 1101 1101
|
||||
* Dibit : 3 3 3 1 1 1 1 1 3 3 1 1 3 1 3 3 1 3 3 3 3 1 3 1 */
|
||||
#define DPMR_FRAME_SYNC_4 "333111113311313313333131"
|
||||
//#define DPMR_FRAME_SYNC_4 "111333331133131131111313"
|
||||
|
||||
/* dPMR Frame Sync 1 to 4 - Inverted */
|
||||
#define INV_DPMR_FRAME_SYNC_1 "333111113311313313333131"
|
||||
#define INV_DPMR_FRAME_SYNC_2 "331111313113"
|
||||
#define INV_DPMR_FRAME_SYNC_3 "311313111133"
|
||||
#define INV_DPMR_FRAME_SYNC_4 "111333331133131131111313"
|
||||
//#define INV_DPMR_FRAME_SYNC_4 "333111113311313313333131"
|
||||
|
||||
//
|
||||
/*
|
||||
* function prototypes
|
||||
*/
|
||||
void processDMRdata (dsd_opts * opts, dsd_state * state);
|
||||
void processDMRvoice (dsd_opts * opts, dsd_state * state);
|
||||
void dmrBSBootstrap (dsd_opts * opts, dsd_state * state);
|
||||
void dmrBS (dsd_opts * opts, dsd_state * state);
|
||||
void dmrMS (dsd_opts * opts, dsd_state * state);
|
||||
void dmrMSData (dsd_opts * opts, dsd_state * state);
|
||||
void dmrMSBootstrap (dsd_opts * opts, dsd_state * state);
|
||||
void processdPMRvoice (dsd_opts * opts, dsd_state * state);
|
||||
void processAudio (dsd_opts * opts, dsd_state * state);
|
||||
void playRawAudio (dsd_opts * opts, dsd_state * state); //added this one HERE HERE
|
||||
void processAudioR (dsd_opts * opts, dsd_state * state);
|
||||
void openPulseInput (dsd_opts * opts); //not sure if we need to just pass opts, or opts and state yet
|
||||
void openPulseOutput (dsd_opts * opts); //not sure if we need to just pass opts, or opts and state yet
|
||||
void writeSynthesizedVoice (dsd_opts * opts, dsd_state * state);
|
||||
void playSynthesizedVoice (dsd_opts * opts, dsd_state * state);
|
||||
void playSynthesizedVoiceR (dsd_opts * opts, dsd_state * state);
|
||||
void openAudioOutDevice (dsd_opts * opts, int speed);
|
||||
void openAudioInDevice (dsd_opts * opts);
|
||||
|
||||
@@ -695,10 +713,11 @@ void processProVoice (dsd_opts * opts, dsd_state * state);
|
||||
void processX2TDMAdata (dsd_opts * opts, dsd_state * state);
|
||||
void processX2TDMAvoice (dsd_opts * opts, dsd_state * state);
|
||||
void processDSTAR_HD (dsd_opts * opts, dsd_state * state);
|
||||
void processYSF(dsd_opts * opts, dsd_state * state); //YSF
|
||||
short dmr_filter(short sample);
|
||||
short nxdn_filter(short sample);
|
||||
|
||||
//borrow from LEH for testing 'improved NXDN detection'
|
||||
|
||||
int strncmperr(const char *s1, const char *s2, size_t size, int MaxErr);
|
||||
/* Global functions */ //also borrowed
|
||||
uint32_t ConvertBitIntoBytes(uint8_t * BufferIn, uint32_t BitLength);
|
||||
@@ -711,7 +730,7 @@ void ncursesOpen ();
|
||||
void ncursesPrinter (dsd_opts * opts, dsd_state * state);
|
||||
void ncursesClose ();
|
||||
//endif ncurses
|
||||
//borrow from LEH
|
||||
|
||||
/* NXDN frame decoding functions */
|
||||
void ProcessNXDNFrame(dsd_opts * opts, dsd_state * state, uint8_t Inverted);
|
||||
void ProcessNxdnRCCHFrame(dsd_opts * opts, dsd_state * state, uint8_t Inverted);
|
||||
@@ -722,7 +741,7 @@ void ProcessNXDNIdleData (dsd_opts * opts, dsd_state * state, uint8_t Inverted);
|
||||
void ProcessNXDNFacch1Data (dsd_opts * opts, dsd_state * state, uint8_t Inverted);
|
||||
void ProcessNXDNUdchData (dsd_opts * opts, dsd_state * state, uint8_t Inverted);
|
||||
//end borrow
|
||||
//borrow from LEH
|
||||
|
||||
/* NXDN functions */
|
||||
void CNXDNConvolution_start(void);
|
||||
void CNXDNConvolution_decode(uint8_t s0, uint8_t s1);
|
||||
@@ -751,7 +770,7 @@ uint16_t CRC12BitNXDN(uint8_t * BufferIn, uint32_t BitLength);
|
||||
uint8_t CRC6BitNXDN(uint8_t * BufferIn, uint32_t BitLength);
|
||||
void ScrambledNXDNVoiceBit(int * LfsrValue, char * BufferIn, char * BufferOut, int NbOfBitToScramble);
|
||||
|
||||
//LEH dPMR
|
||||
|
||||
void dPMRVoiceFrameProcess(dsd_opts * opts, dsd_state * state);
|
||||
void printdPMRAmbeVoiceSample(dsd_opts * opts, dsd_state * state);
|
||||
void printdPMRRawVoiceFrame (dsd_opts * opts, dsd_state * state);
|
||||
@@ -762,7 +781,7 @@ uint8_t CRC7BitdPMR(uint8_t * BufferIn, uint32_t BitLength);
|
||||
uint8_t CRC8BitdPMR(uint8_t * BufferIn, uint32_t BitLength);
|
||||
void ConvertAirInterfaceID(uint32_t AI_ID, uint8_t ID[8]);
|
||||
int32_t GetdPmrColorCode(uint8_t ChannelCodeBit[24]);
|
||||
//LEH DMR
|
||||
|
||||
void ProcessDMR (dsd_opts * opts, dsd_state * state);
|
||||
void DMRDataFrameProcess(dsd_opts * opts, dsd_state * state);
|
||||
void DMRVoiceFrameProcess(dsd_opts * opts, dsd_state * state);
|
||||
@@ -797,6 +816,7 @@ void Process34Data(dsd_opts * opts, dsd_state * state, unsigned char tdibits[98]
|
||||
void ProcessMBCData(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint8_t syncdata[48], uint8_t SlotType[20]);
|
||||
void ProcessMBChData(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint8_t syncdata[48], uint8_t SlotType[20]);
|
||||
void ProcessWTFData(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint8_t syncdata[48], uint8_t SlotType[20]);
|
||||
void ProcessUnifiedData(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint8_t syncdata[48], uint8_t SlotType[20]);
|
||||
|
||||
|
||||
void Hamming_7_4_init();
|
||||
@@ -836,9 +856,6 @@ void QR_16_7_6_encode(unsigned char *origBits, unsigned char *encodedBits);
|
||||
bool QR_16_7_6_decode(unsigned char *rxBits);
|
||||
|
||||
void InitAllFecFunction(void);
|
||||
|
||||
//end borrow from LEH
|
||||
|
||||
void resetState (dsd_state * state);
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -860,6 +877,8 @@ void CDMRTrellisPointsToDibits(const unsigned char* points, signed char* dibits)
|
||||
void CDMRTrellisBitsToTribits(const unsigned char* payload, unsigned char* tribits);
|
||||
bool CDMRTrellisDecode(const unsigned char* data, unsigned char* payload);
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
462
src/dmr_bs.c
Normal file
462
src/dmr_bs.c
Normal file
@@ -0,0 +1,462 @@
|
||||
#include "dsd.h"
|
||||
#include "dmr_const.h"
|
||||
|
||||
//A subroutine for processing each TDMA frame individually to allow for
|
||||
//processing voice and/or data on both BS slots (channels) simultaneously
|
||||
void dmrBS (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
int i, j, k, l, dibit;
|
||||
int *dibit_p;
|
||||
char ambe_fr[4][24] = {0};
|
||||
char ambe_fr2[4][24] = {0};
|
||||
char ambe_fr3[4][24] = {0};
|
||||
char t_ambe_fr[4][24] = {9};
|
||||
char t_ambe_fr2[4][24] = {9};
|
||||
char t_ambe_fr3[4][24] = {9};
|
||||
const int *w, *x, *y, *z;
|
||||
char sync[25];
|
||||
char syncdata[48];
|
||||
char cachdata[13] = {0};
|
||||
int mutecurrentslot;
|
||||
int msMode;
|
||||
char cc[4];
|
||||
unsigned char EmbeddedSignalling[16];
|
||||
int EmbeddedSignallingOk;
|
||||
unsigned int internalcolorcode;
|
||||
int internalslot;
|
||||
char redundancyA[36];
|
||||
char redundancyB[36];
|
||||
unsigned short int vc1;
|
||||
unsigned short int vc2;
|
||||
|
||||
//add time to mirror printFrameSync
|
||||
time_t now;
|
||||
char * getTime(void) //get pretty hh:mm:ss timestamp
|
||||
{
|
||||
time_t t = time(NULL);
|
||||
|
||||
char * curr;
|
||||
char * stamp = asctime(localtime( & t));
|
||||
|
||||
curr = strtok(stamp, " ");
|
||||
curr = strtok(NULL, " ");
|
||||
curr = strtok(NULL, " ");
|
||||
curr = strtok(NULL, " ");
|
||||
|
||||
return curr;
|
||||
}
|
||||
|
||||
//Init the superframe buffers
|
||||
//memset(&state->TS1SuperFrame, 0, sizeof(TimeSlotVoiceSuperFrame_t));
|
||||
//memset(&state->TS2SuperFrame, 0, sizeof(TimeSlotVoiceSuperFrame_t));
|
||||
|
||||
//Init the color code status
|
||||
state->color_code_ok = 0;
|
||||
|
||||
vc1 = 2;
|
||||
vc2 = 2;
|
||||
|
||||
short int loop = 1;
|
||||
short int skipcount = 0;
|
||||
|
||||
//Run Loop while the getting is good
|
||||
while (loop == 1) {
|
||||
|
||||
// CACH
|
||||
internalslot = -1; //reset here so we know if this value is being set properly
|
||||
for(i = 0; i < 12; i++)
|
||||
{
|
||||
dibit = getDibit(opts, state);
|
||||
if(opts->inverted_dmr == 1)
|
||||
{
|
||||
dibit = (dibit ^ 2);
|
||||
}
|
||||
cachdata[i] = dibit;
|
||||
state->dmr_stereo_payload[i] = dibit;
|
||||
if(i == 2)
|
||||
{
|
||||
state->currentslot = (1 & (dibit >> 1));
|
||||
internalslot = (1 & (dibit >> 1));
|
||||
}
|
||||
}
|
||||
|
||||
//Setup for first AMBE Frame
|
||||
//Interleave Schedule
|
||||
w = rW;
|
||||
x = rX;
|
||||
y = rY;
|
||||
z = rZ;
|
||||
|
||||
//First AMBE Frame, Full 36
|
||||
for(i = 0; i < 36; i++)
|
||||
{
|
||||
dibit = getDibit(opts, state);
|
||||
if(opts->inverted_dmr == 1)
|
||||
{
|
||||
dibit = (dibit ^ 2);
|
||||
}
|
||||
state->dmr_stereo_payload[i+12] = dibit;
|
||||
redundancyA[i] = dibit;
|
||||
ambe_fr[*w][*x] = (1 & (dibit >> 1)); // bit 1
|
||||
ambe_fr[*y][*z] = (1 & dibit); // bit 0
|
||||
|
||||
w++;
|
||||
x++;
|
||||
y++;
|
||||
z++;
|
||||
|
||||
}
|
||||
|
||||
//check for repetitive data if caught in a 'no carrier' loop? Just picking random values.
|
||||
//this will test for no carrier (input signal) and return us to no sync state if necessary
|
||||
if (redundancyA[16] == redundancyB[16] && redundancyA[27] == redundancyB[27] &&
|
||||
redundancyA[01] == redundancyB[01] && redundancyA[32] == redundancyB[32] &&
|
||||
redundancyA[03] == redundancyB[03] && redundancyA[33] == redundancyB[33] &&
|
||||
redundancyA[13] == redundancyB[13] && redundancyA[07] == redundancyB[07] )
|
||||
{
|
||||
goto END;
|
||||
}
|
||||
// end redundancy test, set B to A
|
||||
for(i = 0; i < 36; i++)
|
||||
{
|
||||
redundancyB[i] = redundancyA[i];
|
||||
}
|
||||
|
||||
//Setup for Second AMBE Frame
|
||||
//Interleave Schedule
|
||||
w = rW;
|
||||
x = rX;
|
||||
y = rY;
|
||||
z = rZ;
|
||||
|
||||
//Second AMBE Frame, First Half 18 dibits just before Sync or EmbeddedSignalling
|
||||
for(i = 0; i < 18; i++)
|
||||
{
|
||||
dibit = getDibit(opts, state);
|
||||
if(opts->inverted_dmr == 1)
|
||||
{
|
||||
dibit = (dibit ^ 2);
|
||||
}
|
||||
state->dmr_stereo_payload[i+48] = dibit;
|
||||
ambe_fr2[*w][*x] = (1 & (dibit >> 1)); // bit 1
|
||||
ambe_fr2[*y][*z] = (1 & dibit); // bit 0
|
||||
|
||||
w++;
|
||||
x++;
|
||||
y++;
|
||||
z++;
|
||||
|
||||
}
|
||||
|
||||
//short int l = 0; //do I still use this?
|
||||
// signaling data or sync
|
||||
for(i = 0; i < 24; i++)
|
||||
{
|
||||
dibit = getDibit(opts, state);
|
||||
if(opts->inverted_dmr == 1)
|
||||
{
|
||||
dibit = (dibit ^ 2);
|
||||
}
|
||||
state->dmr_stereo_payload[i+66] = dibit;
|
||||
syncdata[(2*i)] = (1 & (dibit >> 1)); // bit 1
|
||||
syncdata[(2*i)+1] = (1 & dibit); // bit 0
|
||||
sync[i] = (dibit | 1) + 48;
|
||||
|
||||
if (i < 4 || i > 19) //
|
||||
{
|
||||
EmbeddedSignalling[2*i] = (1 & (dibit >> 1)); // bit 1
|
||||
EmbeddedSignalling[2*i+1] = (1 & dibit); // bit 0
|
||||
}
|
||||
|
||||
//Used for ProcessVoiceBurstSync
|
||||
if(internalslot == 0 && vc1 > 1 && vc1 < 6) //grab on vc1 values 2-5 B C D and E
|
||||
{
|
||||
/* Time slot 1 superframe buffer filling => SYNC data */
|
||||
state->TS1SuperFrame.TimeSlotRawVoiceFrame[vc1-1].Sync[i*2] = (1 & (dibit >> 1)); // bit 1
|
||||
state->TS1SuperFrame.TimeSlotRawVoiceFrame[vc1-1].Sync[i*2+1] = (1 & dibit); // bit 0
|
||||
}
|
||||
if(internalslot == 1 && vc2 > 1 && vc2 < 6) //grab on vc2 values 2-5 B C D and E
|
||||
{
|
||||
/* Time slot 2 superframe buffer filling => SYNC data */
|
||||
state->TS2SuperFrame.TimeSlotRawVoiceFrame[vc2-1].Sync[i*2] = (1 & (dibit >> 1)); // bit 1
|
||||
state->TS2SuperFrame.TimeSlotRawVoiceFrame[vc2-1].Sync[i*2+1] = (1 & dibit); // bit 0
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sync[24] = 0;
|
||||
EmbeddedSignallingOk = -1;
|
||||
if(QR_16_7_6_decode(EmbeddedSignalling))
|
||||
{
|
||||
EmbeddedSignallingOk = 1;
|
||||
}
|
||||
|
||||
internalcolorcode = 69; //set so we know if this value is being set properly
|
||||
if(EmbeddedSignallingOk == 1)
|
||||
{
|
||||
state->color_code = (unsigned int)((EmbeddedSignalling[0] << 3) + (EmbeddedSignalling[1] << 2) + (EmbeddedSignalling[2] << 1) + EmbeddedSignalling[3]);
|
||||
internalcolorcode = (unsigned int)((EmbeddedSignalling[0] << 3) + (EmbeddedSignalling[1] << 2) + (EmbeddedSignalling[2] << 1) + EmbeddedSignalling[3]);
|
||||
state->color_code_ok = EmbeddedSignallingOk;
|
||||
|
||||
//Power Indicator, not the other PI (header)
|
||||
state->PI = (unsigned int)EmbeddedSignalling[4];
|
||||
state->PI_ok = EmbeddedSignallingOk;
|
||||
|
||||
//Link Control Start Stop Indicator
|
||||
state->LCSS = (unsigned int)((EmbeddedSignalling[5] << 1) + EmbeddedSignalling[6]);
|
||||
state->LCSS_ok = EmbeddedSignallingOk;
|
||||
|
||||
}
|
||||
else skipcount++;
|
||||
|
||||
//Continue Second AMBE Frame, 18 after Sync or EmbeddedSignalling
|
||||
for(i = 0; i < 18; i++)
|
||||
{
|
||||
dibit = getDibit(opts, state);
|
||||
if(opts->inverted_dmr == 1)
|
||||
{
|
||||
dibit = (dibit ^ 2);
|
||||
}
|
||||
state->dmr_stereo_payload[i+90] = dibit;
|
||||
ambe_fr2[*w][*x] = (1 & (dibit >> 1)); // bit 1
|
||||
ambe_fr2[*y][*z] = (1 & dibit); // bit 0
|
||||
|
||||
w++;
|
||||
x++;
|
||||
y++;
|
||||
z++;
|
||||
|
||||
}
|
||||
|
||||
//Setup for Third AMBE Frame
|
||||
//Interleave Schedule
|
||||
w = rW;
|
||||
x = rX;
|
||||
y = rY;
|
||||
z = rZ;
|
||||
|
||||
//Third AMBE Frame, Full 36
|
||||
for(i = 0; i < 36; i++)
|
||||
{
|
||||
dibit = getDibit(opts, state);
|
||||
if(opts->inverted_dmr == 1)
|
||||
{
|
||||
dibit = (dibit ^ 2);
|
||||
}
|
||||
state->dmr_stereo_payload[i+108] = dibit;
|
||||
ambe_fr3[*w][*x] = (1 & (dibit >> 1)); // bit 1
|
||||
ambe_fr3[*y][*z] = (1 & dibit); // bit 0
|
||||
|
||||
w++;
|
||||
x++;
|
||||
y++;
|
||||
z++;
|
||||
|
||||
}
|
||||
|
||||
//reset vc counters to 1 if new voice sync frame on each slot
|
||||
if ( (strcmp (sync, DMR_BS_VOICE_SYNC) == 0) )
|
||||
{
|
||||
if (internalslot == 0)
|
||||
{
|
||||
vc1 = 1;
|
||||
}
|
||||
if (internalslot == 1)
|
||||
{
|
||||
vc2 = 1;
|
||||
}
|
||||
}
|
||||
|
||||
//check for sync pattern here after collected the rest of the payload, decide what to do with it
|
||||
if ( (strcmp (sync, DMR_BS_DATA_SYNC) == 0) )
|
||||
{
|
||||
fprintf (stderr,"%s ", getTime());
|
||||
if (internalslot == 0)
|
||||
{
|
||||
sprintf(state->slot1light, "[slot1]");
|
||||
sprintf(state->slot2light, " slot2 ");
|
||||
//fprintf (stderr,"Sync: +DMR [slot1] slot2 | Color Code=%02d | DMRSTEREO | Data ", state->color_code);
|
||||
fprintf (stderr,"Sync: +DMR ");
|
||||
//constantly reset the vc counter to 1 each data frame in anticipation of new voice frame
|
||||
vc1 = 1;
|
||||
}
|
||||
if (internalslot == 1)
|
||||
{
|
||||
sprintf(state->slot2light, "[slot2]");
|
||||
sprintf(state->slot1light, " slot1 ");
|
||||
//fprintf (stderr,"Sync: +DMR slot1 [slot2] | Color Code=%02d | DMRSTEREO | Data ", state->color_code);
|
||||
fprintf (stderr,"Sync: +DMR ");
|
||||
//constantly reset the vc counter to 1 each data frame in anticipation of new voice frame
|
||||
vc2 = 1;
|
||||
}
|
||||
processDMRdata (opts, state);
|
||||
skipcount++; //after 6 data frames, drop back to getFrameSync and process subsequent data with processDMRdata
|
||||
goto SKIP;
|
||||
}
|
||||
|
||||
if( (strcmp (sync, DMR_BS_DATA_SYNC) != 0) ) //only play voice no data sync // || (strcmp (sync, DMR_MS_DATA_SYNC) != 0)
|
||||
{
|
||||
if (EmbeddedSignallingOk == 0)
|
||||
{
|
||||
//goto END;
|
||||
}
|
||||
skipcount = 0; //reset skip count if processing voice frames
|
||||
fprintf (stderr,"%s ", getTime());
|
||||
if (internalslot == 0)
|
||||
{
|
||||
fprintf (stderr,"Sync: +DMR [slot1] slot2 | Color Code=%02d | DMRSTEREO | VC%d \n", state->color_code, vc1);
|
||||
}
|
||||
|
||||
if (internalslot == 1)
|
||||
{
|
||||
fprintf (stderr,"Sync: +DMR slot1 [slot2] | Color Code=%02d | DMRSTEREO | VC%d \n", state->color_code, vc2);
|
||||
}
|
||||
if (internalslot == 0 && vc1 == 6) //presumably when full (and no sync issues)
|
||||
{
|
||||
//process voice burst
|
||||
ProcessVoiceBurstSync(opts, state);
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
if (internalslot == 1 && vc2 == 6) //presumably when full (and no sync issues)
|
||||
{
|
||||
//process voice burst
|
||||
ProcessVoiceBurstSync(opts, state);
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
processMbeFrame (opts, state, NULL, ambe_fr, NULL);
|
||||
processMbeFrame (opts, state, NULL, ambe_fr2, NULL);
|
||||
processMbeFrame (opts, state, NULL, ambe_fr3, NULL);
|
||||
if (internalslot == 0)
|
||||
{
|
||||
vc1++;
|
||||
}
|
||||
if (internalslot == 1)
|
||||
{
|
||||
vc2++;
|
||||
}
|
||||
}
|
||||
|
||||
// recalibrate center/umid/lmid, not sure this helps or does anything particularly in this case
|
||||
state->center = ((state->max) + (state->min)) / 2;
|
||||
state->umid = (((state->max) - state->center) * 5 / 8) + state->center;
|
||||
state->lmid = (((state->min) - state->center) * 5 / 8) + state->center;
|
||||
|
||||
//Escape conditions to break the loop
|
||||
//7 seems optimal, allows for an extra frame each in case of late entry on dual voices
|
||||
if ( (vc1 > 7 && vc2 > 7) )
|
||||
{
|
||||
goto END;
|
||||
}
|
||||
//14 probably allows a few more in case of a bit of jitter but eventually breaks loop (1 second?)
|
||||
if ( (vc1 > 14 || vc2 > 14) )
|
||||
{
|
||||
goto END;
|
||||
}
|
||||
//using these conditions may cause excessive resyncs IF bad signal,
|
||||
//but still better than getting stuck in a wonk wonk loop for too long.
|
||||
//maybe consider making a opt variable for loose or aggressive resyncing for this sort of thing?
|
||||
if (1 == 1) //set for more aggressive or less aggressive resync during accumulated playback errs
|
||||
{
|
||||
//errors caused due to playing MBE files out of sync, break loop
|
||||
if (state->errs > 2 || state->errsR > 2)
|
||||
{
|
||||
//goto END; //
|
||||
}
|
||||
//errors caused due to playing MBE files out of sync, break loop
|
||||
if (state->errs2 > 4 || state->errs2R > 4)
|
||||
{
|
||||
goto END; //
|
||||
}
|
||||
}
|
||||
|
||||
//earlier skip conditions teleport us here to process further skip conditions before restarting while loop
|
||||
SKIP:
|
||||
if (skipcount > 2) //after 2 consecutive data frames, drop back to getFrameSync and process with processDMRdata
|
||||
{
|
||||
goto END;
|
||||
}
|
||||
|
||||
//since we are in a while loop, run ncursesPrinter here.
|
||||
if (opts->use_ncurses_terminal == 1)
|
||||
{
|
||||
ncursesPrinter(opts, state);
|
||||
}
|
||||
|
||||
} // while loop
|
||||
//Teleport here on END condition, set or reset variables and return to look for new frame sync
|
||||
END:
|
||||
state->dmr_stereo = 0;
|
||||
state->errs2R = 0;
|
||||
state->errs2 = 0;
|
||||
}
|
||||
|
||||
//Only process 2nd half voice payload (3rd frame) and then jump to full BS decoding
|
||||
void dmrBSBootstrap (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
int i, j, k, l, dibit;
|
||||
int *dibit_p;
|
||||
char ambe_fr[4][24] = {0};
|
||||
char ambe_fr2[4][24] = {0};
|
||||
char ambe_fr3[4][24] = {0};
|
||||
const int *w, *x, *y, *z;
|
||||
char sync[25];
|
||||
char syncdata[48];
|
||||
char cachdata[13] = {0};
|
||||
int mutecurrentslot;
|
||||
int msMode;
|
||||
char cc[4];
|
||||
unsigned char EmbeddedSignalling[16];
|
||||
unsigned int EmbeddedSignallingOk;
|
||||
|
||||
//add time to mirror printFrameSync
|
||||
time_t now;
|
||||
char * getTime(void) //get pretty hh:mm:ss timestamp
|
||||
{
|
||||
time_t t = time(NULL);
|
||||
|
||||
char * curr;
|
||||
char * stamp = asctime(localtime( & t));
|
||||
|
||||
curr = strtok(stamp, " ");
|
||||
curr = strtok(NULL, " ");
|
||||
curr = strtok(NULL, " ");
|
||||
curr = strtok(NULL, " ");
|
||||
|
||||
return curr;
|
||||
}
|
||||
|
||||
//skip the 18 dibits of the 2nd frame, since we can't play only half a frame
|
||||
skipDibit (opts, state, 18);
|
||||
|
||||
//Setup for Third AMBE Frame
|
||||
|
||||
//Interleave Schedule
|
||||
w = rW;
|
||||
x = rX;
|
||||
y = rY;
|
||||
z = rZ;
|
||||
|
||||
//Third AMBE Frame, Full 36
|
||||
for(i = 0; i < 36; i++)
|
||||
{
|
||||
dibit = getDibit(opts, state);
|
||||
if(opts->inverted_dmr == 1)
|
||||
{
|
||||
dibit = (dibit ^ 2);
|
||||
}
|
||||
ambe_fr3[*w][*x] = (1 & (dibit >> 1)); // bit 1
|
||||
ambe_fr3[*y][*z] = (1 & dibit); // bit 0
|
||||
|
||||
w++;
|
||||
x++;
|
||||
y++;
|
||||
z++;
|
||||
|
||||
}
|
||||
|
||||
fprintf (stderr,"\n%s ", getTime());
|
||||
fprintf (stderr,"Sync: +DMR | Frame Sync | DMRSTEREO | VC1 FS \n");
|
||||
processMbeFrame (opts, state, NULL, ambe_fr3, NULL);
|
||||
dmrBS (opts, state); //bootstrap into full TDMA frame for BS mode
|
||||
|
||||
}
|
||||
157
src/dmr_data.c
157
src/dmr_data.c
@@ -49,6 +49,12 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
|
||||
bursttype[4] = 0;
|
||||
|
||||
dibit_p = state->dibit_buf_p - 90;
|
||||
//using the estimate_symbol method for the dmr_payload_p buffer causes sync
|
||||
//issues with P25, so only do it when frame_p25p1 == 0, or -fr option
|
||||
if (opts->frame_p25p1 != 1)
|
||||
{
|
||||
dibit_p = state->dmr_payload_p - 90;
|
||||
}
|
||||
|
||||
// CACH
|
||||
for (i = 0; i < 12; i++)
|
||||
@@ -59,6 +65,11 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
dibit = (dibit ^ 2);
|
||||
}
|
||||
if (state->dmr_stereo == 1)
|
||||
{
|
||||
dibit = (int)state->dmr_stereo_payload[i];
|
||||
}
|
||||
//fprintf(stderr, "%X", dibit);
|
||||
cachdata[i] = dibit;
|
||||
if (i == 2)
|
||||
{
|
||||
@@ -79,6 +90,15 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
|
||||
state->slot1light[0] = ' ';
|
||||
state->slot1light[6] = ' ';
|
||||
}
|
||||
//method to only see data from one slot or the other when data occupies both slots or gets cooked by sync
|
||||
state->hardslot = 9; //0 to only listen to slot 0 voice, 1 for slot 1, 9 for both
|
||||
if(state->hardslot != 9 && state->hardslot != state->currentslot)
|
||||
//if(1==1)
|
||||
{
|
||||
fprintf (stderr, " Current Slot = %d", state->currentslot + 1);
|
||||
fprintf (stderr, "\n"); //line break after breaking out of jail
|
||||
//goto JUMP;
|
||||
}
|
||||
}
|
||||
}
|
||||
cachdata[12] = 0;
|
||||
@@ -107,6 +127,10 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
dibit = (dibit ^ 2);
|
||||
}
|
||||
if (state->dmr_stereo == 1)
|
||||
{
|
||||
dibit = (int)state->dmr_stereo_payload[i+12];
|
||||
}
|
||||
trellisdibits[i] = dibit;
|
||||
info[2*i] = (1 & (dibit >> 1)); // bit 1
|
||||
info[(2*i)+1] = (1 & dibit); // bit 0
|
||||
@@ -119,6 +143,10 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
dibit = (dibit ^ 2);
|
||||
}
|
||||
if (state->dmr_stereo == 1)
|
||||
{
|
||||
dibit = (int)state->dmr_stereo_payload[61]; //61, not i+61
|
||||
}
|
||||
cc[0] = (1 & (dibit >> 1)); // bit 1
|
||||
cc[1] = (1 & dibit); // bit 0
|
||||
SlotType[0] = (1 & (dibit >> 1)); // bit 1
|
||||
@@ -130,6 +158,10 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
dibit = (dibit ^ 2);
|
||||
}
|
||||
if (state->dmr_stereo == 1)
|
||||
{
|
||||
dibit = (int)state->dmr_stereo_payload[62];
|
||||
}
|
||||
cc[2] = (1 & (dibit >> 1)); // bit 1
|
||||
cc[3] = (1 & dibit); // bit 0
|
||||
SlotType[2] = (1 & (dibit >> 1)); // bit 1
|
||||
@@ -147,6 +179,10 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
dibit = (dibit ^ 2);
|
||||
}
|
||||
if (state->dmr_stereo == 1) //state
|
||||
{
|
||||
dibit = (int)state->dmr_stereo_payload[63]; //(int)
|
||||
}
|
||||
// burst = (unsigned int)((1 & (dibit >> 1)) << 3);
|
||||
// burst |= (unsigned int)((1 & (dibit >> 0)) << 2);
|
||||
// bursttype[0] = (1 & (dibit >> 1)) + 48; // bit 1
|
||||
@@ -160,6 +196,10 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
dibit = (dibit ^ 2);
|
||||
}
|
||||
if (state->dmr_stereo == 1) //state
|
||||
{
|
||||
dibit = (int)state->dmr_stereo_payload[64]; //(int)
|
||||
}
|
||||
// burst |= (unsigned int)((1 & (dibit >> 1)) << 1);
|
||||
// burst |= (unsigned int)((1 & (dibit >> 0)) << 0);
|
||||
// bursttype[2] = (1 & (dibit >> 1)) + 48; // bit 1
|
||||
@@ -174,6 +214,10 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
dibit = (dibit ^ 2);
|
||||
}
|
||||
if (state->dmr_stereo == 1)
|
||||
{
|
||||
dibit = (int)state->dmr_stereo_payload[65];
|
||||
}
|
||||
SlotType[8] = (1 & (dibit >> 1)); // bit 1
|
||||
SlotType[9] = (1 & dibit); // bit 0
|
||||
|
||||
@@ -186,6 +230,10 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
dibit = (dibit ^ 2);
|
||||
}
|
||||
if (state->dmr_stereo == 1)
|
||||
{
|
||||
dibit = (int)state->dmr_stereo_payload[i+66]; //double check these i+ values make sure we are on the right ones
|
||||
}
|
||||
syncdata[2*i] = (1 & (dibit >> 1)); // bit 1
|
||||
syncdata[(2*i)+1] = (1 & dibit); // bit 0
|
||||
sync[i] = (dibit | 1) + 48;
|
||||
@@ -216,6 +264,7 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
|
||||
sprintf(state->slot2light, "[slot2]");
|
||||
}
|
||||
}
|
||||
|
||||
else if(strcmp (sync, DMR_DIRECT_MODE_TS1_DATA_SYNC) == 0)
|
||||
{
|
||||
state->currentslot = 0;
|
||||
@@ -236,11 +285,18 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
|
||||
// Slot type - Second part - Parity bit
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
dibit = getDibit(opts, state);
|
||||
if (state->dmr_stereo == 0) //only get dibits if not using dmr_stereo method
|
||||
{
|
||||
dibit = getDibit(opts, state);
|
||||
}
|
||||
if (opts->inverted_dmr == 1)
|
||||
{
|
||||
dibit = (dibit ^ 2);
|
||||
}
|
||||
if (state->dmr_stereo == 1)
|
||||
{
|
||||
dibit = (int)state->dmr_stereo_payload[i+90]; //double checked these i+ values make sure we are on the right ones
|
||||
}
|
||||
SlotType[(i*2) + 10] = (1 & (dibit >> 1)); // bit 1
|
||||
SlotType[(i*2) + 11] = (1 & dibit); // bit 0
|
||||
}
|
||||
@@ -250,8 +306,10 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
|
||||
else SlotTypeOk = 0;
|
||||
|
||||
/* Slot Type parity checked => Fill the color code */
|
||||
state->color_code = (unsigned int)((cc[0] << 3) + (cc[1] << 2) + (cc[2] << 1) + cc[3]);
|
||||
//state->color_code = (unsigned int)((cc[0] << 3) + (cc[1] << 2) + (cc[2] << 1) + cc[3]);
|
||||
state->color_code = (SlotType[0] << 3) + (SlotType[1] << 2) +(SlotType[2] << 1) + (SlotType[3] << 0);
|
||||
state->color_code_ok = SlotTypeOk;
|
||||
//fprintf(stderr, "| Color Code=%02d ", (int)state->color_code);
|
||||
|
||||
/* Reconstitute the burst type */
|
||||
burst = (unsigned int)((SlotType[4] << 3) + (SlotType[5] << 2) + (SlotType[6] << 1) + SlotType[7]);
|
||||
@@ -263,13 +321,55 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
|
||||
bursttype[3] = SlotType[7] + '0';
|
||||
bursttype[4] = '\0';
|
||||
|
||||
/* //delete this chunk later
|
||||
if (state->dmr_stereo == 3) //may not need this any longer
|
||||
{
|
||||
burst = (state->dmr_stereo_payload[63] << 2) | (state->dmr_stereo_payload[64]);
|
||||
//this whole split for getting burst and burst type is makes no sense
|
||||
//why not just use burst
|
||||
bursttype[0] = (((state->dmr_stereo_payload[63] >> 1) & 1) + '0');
|
||||
bursttype[1] = (((state->dmr_stereo_payload[63] >> 0) & 1) + '0');
|
||||
bursttype[2] = (((state->dmr_stereo_payload[64] >> 1) & 1) + '0');
|
||||
bursttype[3] = (((state->dmr_stereo_payload[64] >> 0) & 1) + '0');
|
||||
bursttype[4] = '\0';
|
||||
//fprintf(stderr, "BURST1 = %04b ", burst);
|
||||
}
|
||||
//figure out why the sync is wrong when dumping the payload to processDMRdata for MS Data
|
||||
//I think its a conversion issue with the payload(chat) from the dibit buffer (int *)
|
||||
//actually, its the dibit buffer storing as 1 and 3 only (GFSK) when sync drops
|
||||
//made a seperate dmr buffer, but still, when sync loss and regain, takes a few syncs to calibrate center/umid/lmid properly
|
||||
//getting accurate MS data AND leading BS data may be impossible without saving the symbols, calibrating, then going back
|
||||
//and running the buffer payload, but I honestly don't know right now, probably easier to start from stratch than fix this
|
||||
if (state->dmr_ms_mode == 7)
|
||||
{
|
||||
burst = (unsigned int)((SlotType[4] << 3) | (SlotType[5] << 2) | (SlotType[6] << 1) | SlotType[7]);
|
||||
bursttype[0] = SlotType[4] + '0';
|
||||
bursttype[1] = SlotType[5] + '0';
|
||||
bursttype[2] = SlotType[6] + '0';
|
||||
bursttype[3] = SlotType[7] + '0';
|
||||
bursttype[4] = '\0';
|
||||
//fprintf(stderr, "BURST1 = %04b ", burst);
|
||||
}
|
||||
|
||||
if (state->dmr_stereo == 3)
|
||||
{
|
||||
fprintf(stderr, "BURST2 = %b%b%b%b Slot Dump ", SlotType[4], SlotType[5], SlotType[6], SlotType[7] );
|
||||
fprintf(stderr, " Slot Dump = ");
|
||||
for (i = 0; i < 20; i++)
|
||||
{
|
||||
fprintf(stderr, "%b", SlotType[i]);
|
||||
}
|
||||
fprintf(stderr, "\n ");
|
||||
}
|
||||
*/
|
||||
|
||||
if (strcmp (bursttype, "0000") == 0)
|
||||
{
|
||||
sprintf(state->fsubtype, " PI Header ");
|
||||
}
|
||||
else if (strcmp (bursttype, "0001") == 0)
|
||||
{
|
||||
sprintf(state->fsubtype, " VOICE Header ");
|
||||
sprintf(state->fsubtype, " VOICE LC Header ");
|
||||
}
|
||||
else if (strcmp (bursttype, "0010") == 0)
|
||||
{
|
||||
@@ -316,31 +416,55 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
|
||||
//trellis
|
||||
for (i = 0; i < 49; i++)
|
||||
{
|
||||
dibit = getDibit(opts, state);
|
||||
if (state->dmr_stereo == 0) //only get dibits if not using dmr_stereo method
|
||||
{
|
||||
dibit = getDibit(opts, state);
|
||||
}
|
||||
if (opts->inverted_dmr == 1)
|
||||
{
|
||||
dibit = (dibit ^ 2);
|
||||
}
|
||||
if (state->dmr_stereo == 1)
|
||||
{
|
||||
dibit = (int)state->dmr_stereo_payload[i+95]; //double checked these i+ values make sure we are on the right ones
|
||||
}
|
||||
trellisdibits[i+49] = dibit;
|
||||
info[(2*i) + 98] = (1 & (dibit >> 1)); // bit 1
|
||||
info[(2*i) + 99] = (1 & dibit); // bit 0
|
||||
}
|
||||
|
||||
// Skip cach (24 bit = 12 dibit) and next slot 1st half (98 + 10 bit = 49 + 5 dibit)
|
||||
skipDibit (opts, state, 12 + 49 + 5);
|
||||
if (state->dmr_stereo == 0)
|
||||
{
|
||||
skipDibit (opts, state, 12 + 49 + 5);
|
||||
}
|
||||
|
||||
if (opts->errorbars == 1)
|
||||
{
|
||||
/* Print the color code */
|
||||
fprintf(stderr, "| Color Code=%02d ", (int)state->color_code);
|
||||
//if (burst == 0b1001 && state->color_code_ok) //only print on idle for data types, otherwise prints on voice frames.
|
||||
if (SlotTypeOk == 1)
|
||||
{
|
||||
fprintf (stderr, "%s", KCYN);
|
||||
fprintf(stderr, "| Color Code=%02d ", (int)state->color_code);
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
//state->dmr_color_code = state->color_code;
|
||||
}
|
||||
else fprintf(stderr, "| ");
|
||||
|
||||
//if(state->color_code_ok) fprintf(stderr, "(OK) |");
|
||||
if(state->color_code_ok) fprintf(stderr, "(CRC OK ) |"); //add line break
|
||||
else fprintf(stderr, "(CRC ERR) |"); //add line break
|
||||
if(state->color_code_ok) fprintf(stderr, "| (CRC OK ) |"); //add line break
|
||||
else
|
||||
{
|
||||
fprintf (stderr, "%s", KRED);
|
||||
fprintf(stderr, "| (CRC ERR) |");
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
}
|
||||
//fprintf (stderr, "\n"); //print line break
|
||||
if (strcmp (state->fsubtype, " ") == 0)
|
||||
{
|
||||
fprintf(stderr, " Unknown burst type: %s", bursttype);
|
||||
//fprintf(stderr, " Unknown burst type: %s", bursttype);
|
||||
fprintf(stderr, " Unknown");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -368,6 +492,7 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
|
||||
/* Burst = TLC */
|
||||
case 0b0010:
|
||||
{
|
||||
//Not sure if I really care about this in the context of what it shows
|
||||
ProcessDmrTerminaisonLC(opts, state, (uint8_t *)info, (uint8_t *)syncdata, (uint8_t *)SlotType);
|
||||
break;
|
||||
}
|
||||
@@ -375,6 +500,7 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
|
||||
/* Burst = CSBK */
|
||||
case 0b0011:
|
||||
{
|
||||
//going to disable until I can find more useful info to present
|
||||
ProcessCSBK(opts, state, (uint8_t *)info, (uint8_t *)syncdata, (uint8_t *)SlotType);
|
||||
break;
|
||||
}
|
||||
@@ -386,7 +512,7 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Burst = MBC */
|
||||
/* Burst = MBC Continuation*/
|
||||
case 0b0101:
|
||||
{
|
||||
//ProcessMBCData(opts, state, (uint8_t *)info, (uint8_t *)syncdata, (uint8_t *)SlotType);
|
||||
@@ -410,14 +536,15 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
|
||||
/* Burst = RATE 3/4 DATA */
|
||||
case 0b1000:
|
||||
{
|
||||
//disabled until a viable viterbi/trellis decoding solution is worked out
|
||||
//Process34Data(opts, state, trellisdibits, (uint8_t *)syncdata, (uint8_t *)SlotType);
|
||||
//need to keep working on improving the trellis decode, but is partially viable now
|
||||
Process34Data(opts, state, trellisdibits, (uint8_t *)syncdata, (uint8_t *)SlotType);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Burst = Slot idle */
|
||||
case 0b1001:
|
||||
{
|
||||
if(state->color_code_ok) state->dmr_color_code = state->color_code; //try setting this on idle if crc ok
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -428,10 +555,10 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Burst = WTF 1101 Type DATA */
|
||||
/* Burst = Unified Single Block DATA */
|
||||
case 0b1101:
|
||||
{
|
||||
//ProcessWTFData(opts, state, (uint8_t *)info, (uint8_t *)syncdata, (uint8_t *)SlotType);
|
||||
//ProcessUnifiedData(opts, state, (uint8_t *)info, (uint8_t *)syncdata, (uint8_t *)SlotType);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -448,5 +575,5 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
//JUMP:
|
||||
} /* End processDMRdata() */
|
||||
|
||||
672
src/dmr_ms.c
Normal file
672
src/dmr_ms.c
Normal file
@@ -0,0 +1,672 @@
|
||||
#include "dsd.h"
|
||||
#include "dmr_const.h"
|
||||
|
||||
//A subroutine for processing MS voice
|
||||
void dmrMS (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
//fprintf (stderr, "\n Quick DMR Voice Testing\n");
|
||||
int i, j, k, l, dibit;
|
||||
int *dibit_p;
|
||||
char ambe_fr[4][24] = {0};
|
||||
char ambe_fr2[4][24] = {0};
|
||||
char ambe_fr3[4][24] = {0};
|
||||
char t_ambe_fr[4][24] = {9};
|
||||
char t_ambe_fr2[4][24] = {9};
|
||||
char t_ambe_fr3[4][24] = {9};
|
||||
const int *w, *x, *y, *z;
|
||||
char sync[25];
|
||||
char syncdata[48];
|
||||
//standalone inbound rc sync exists on dibits 48-96?
|
||||
//or 44-92? of each potential payload, middle 10 ms or 30 ms frame
|
||||
char rcsync[25];
|
||||
char rcsyncdata[96]; //96 bit RC sync data
|
||||
char cachdata[13] = {0};
|
||||
int mutecurrentslot;
|
||||
int msMode;
|
||||
char cc[4];
|
||||
unsigned char EmbeddedSignalling[16];
|
||||
int EmbeddedSignallingOk;
|
||||
unsigned int internalcolorcode;
|
||||
int internalslot;
|
||||
int activeslot;
|
||||
char redundancyA[36];
|
||||
char redundancyB[36];
|
||||
unsigned short int vc1;
|
||||
unsigned short int vc2;
|
||||
//add time to mirror printFrameSync
|
||||
time_t now;
|
||||
char * getTime(void) //get pretty hh:mm:ss timestamp
|
||||
{
|
||||
time_t t = time(NULL);
|
||||
|
||||
char * curr;
|
||||
char * stamp = asctime(localtime( & t));
|
||||
|
||||
curr = strtok(stamp, " ");
|
||||
curr = strtok(NULL, " ");
|
||||
curr = strtok(NULL, " ");
|
||||
curr = strtok(NULL, " ");
|
||||
|
||||
return curr;
|
||||
}
|
||||
|
||||
//Init the color code status
|
||||
state->color_code_ok = 0;
|
||||
|
||||
vc1 = 2;
|
||||
vc2 = 2;
|
||||
|
||||
short int loop = 1;
|
||||
short int skipcount = 0;
|
||||
|
||||
//Hardset variables for MS
|
||||
state->currentslot = 0;
|
||||
internalslot = 0;
|
||||
activeslot = 0;
|
||||
|
||||
//Run Loop while the getting is good
|
||||
while (loop == 1) {
|
||||
|
||||
// No CACH in MS Mode?
|
||||
for(i = 0; i < 12; i++)
|
||||
{
|
||||
dibit = getDibit(opts, state);
|
||||
if(opts->inverted_dmr == 1)
|
||||
{
|
||||
dibit = (dibit ^ 2);
|
||||
}
|
||||
cachdata[i] = dibit;
|
||||
state->dmr_stereo_payload[i] = dibit;
|
||||
if(i == 2)
|
||||
{
|
||||
//state->currentslot = (1 & (dibit >> 1));
|
||||
//internalslot = (1 & (dibit >> 1));
|
||||
}
|
||||
}
|
||||
|
||||
//Setup for first AMBE Frame
|
||||
//Interleave Schedule
|
||||
w = rW;
|
||||
x = rX;
|
||||
y = rY;
|
||||
z = rZ;
|
||||
|
||||
//First AMBE Frame, Full 36
|
||||
for(i = 0; i < 36; i++)
|
||||
{
|
||||
dibit = getDibit(opts, state);
|
||||
if(opts->inverted_dmr == 1)
|
||||
{
|
||||
dibit = (dibit ^ 2);
|
||||
}
|
||||
state->dmr_stereo_payload[i+12] = dibit;
|
||||
redundancyA[i] = dibit;
|
||||
ambe_fr[*w][*x] = (1 & (dibit >> 1)); // bit 1
|
||||
ambe_fr[*y][*z] = (1 & dibit); // bit 0
|
||||
|
||||
w++;
|
||||
x++;
|
||||
y++;
|
||||
z++;
|
||||
|
||||
}
|
||||
|
||||
//check for repetitive data if caught in a 'no carrier' loop? Just picking random values.
|
||||
//this will test for no carrier (input signal) and return us to no sync state if necessary
|
||||
if (redundancyA[16] == redundancyB[16] && redundancyA[27] == redundancyB[27] &&
|
||||
redundancyA[01] == redundancyB[01] && redundancyA[32] == redundancyB[32] &&
|
||||
redundancyA[03] == redundancyB[03] && redundancyA[33] == redundancyB[33] &&
|
||||
redundancyA[13] == redundancyB[13] && redundancyA[07] == redundancyB[07] )
|
||||
{
|
||||
//goto END;
|
||||
}
|
||||
for(i = 0; i < 36; i++)
|
||||
{
|
||||
redundancyB[i] = redundancyA[i];
|
||||
}
|
||||
|
||||
//Setup for Second AMBE Frame
|
||||
//Interleave Schedule
|
||||
w = rW;
|
||||
x = rX;
|
||||
y = rY;
|
||||
z = rZ;
|
||||
|
||||
//Second AMBE Frame, First Half 18 dibits just before Sync or EmbeddedSignalling
|
||||
for(i = 0; i < 18; i++)
|
||||
{
|
||||
dibit = getDibit(opts, state);
|
||||
if(opts->inverted_dmr == 1)
|
||||
{
|
||||
dibit = (dibit ^ 2);
|
||||
}
|
||||
state->dmr_stereo_payload[i+48] = dibit;
|
||||
ambe_fr2[*w][*x] = (1 & (dibit >> 1)); // bit 1
|
||||
ambe_fr2[*y][*z] = (1 & dibit); // bit 0
|
||||
|
||||
w++;
|
||||
x++;
|
||||
y++;
|
||||
z++;
|
||||
|
||||
}
|
||||
|
||||
// signaling data or sync
|
||||
for(i = 0; i < 24; i++)
|
||||
{
|
||||
dibit = getDibit(opts, state);
|
||||
if(opts->inverted_dmr == 1)
|
||||
{
|
||||
dibit = (dibit ^ 2);
|
||||
}
|
||||
state->dmr_stereo_payload[i+66] = dibit;
|
||||
syncdata[(2*i)] = (1 & (dibit >> 1)); // bit 1
|
||||
syncdata[(2*i)+1] = (1 & dibit); // bit 0
|
||||
sync[i] = (dibit | 1) + 48;
|
||||
|
||||
if (i < 4 || i > 19) //
|
||||
{
|
||||
EmbeddedSignalling[2*i] = (1 & (dibit >> 1)); // bit 1
|
||||
EmbeddedSignalling[2*i+1] = (1 & dibit); // bit 0
|
||||
}
|
||||
|
||||
// load the superframe to do the voiceburstsync processing
|
||||
if(internalslot == 0 && vc1 > 1 && vc1 < 6) //grab on vc1 values 2-5 B C D and E
|
||||
{
|
||||
/* Time slot 1 superframe buffer filling => SYNC data */
|
||||
state->TS1SuperFrame.TimeSlotRawVoiceFrame[vc1-1].Sync[i*2] = (1 & (dibit >> 1)); // bit 1
|
||||
state->TS1SuperFrame.TimeSlotRawVoiceFrame[vc1-1].Sync[i*2+1] = (1 & dibit); // bit 0
|
||||
}
|
||||
if(internalslot == 1 && vc2 > 1 && vc2 < 6) //grab on vc2 values 2-5 B C D and E
|
||||
{
|
||||
/* Time slot 2 superframe buffer filling => SYNC data */
|
||||
state->TS2SuperFrame.TimeSlotRawVoiceFrame[vc2-1].Sync[i*2] = (1 & (dibit >> 1)); // bit 1
|
||||
state->TS2SuperFrame.TimeSlotRawVoiceFrame[vc2-1].Sync[i*2+1] = (1 & dibit); // bit 0
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sync[24] = 0;
|
||||
EmbeddedSignallingOk = -1;
|
||||
if(QR_16_7_6_decode(EmbeddedSignalling))
|
||||
{
|
||||
EmbeddedSignallingOk = 1;
|
||||
}
|
||||
|
||||
internalcolorcode = 69; //set so we know if this value is being set properly
|
||||
if(EmbeddedSignallingOk == 1)
|
||||
{
|
||||
state->color_code = (unsigned int)((EmbeddedSignalling[0] << 3) + (EmbeddedSignalling[1] << 2) + (EmbeddedSignalling[2] << 1) + EmbeddedSignalling[3]);
|
||||
internalcolorcode = (unsigned int)((EmbeddedSignalling[0] << 3) + (EmbeddedSignalling[1] << 2) + (EmbeddedSignalling[2] << 1) + EmbeddedSignalling[3]);
|
||||
state->color_code_ok = EmbeddedSignallingOk;
|
||||
//Power Indicator, not the other PI (header)
|
||||
state->PI = (unsigned int)EmbeddedSignalling[4];
|
||||
state->PI_ok = EmbeddedSignallingOk;
|
||||
//Link Control Start Stop Indicator
|
||||
state->LCSS = (unsigned int)((EmbeddedSignalling[5] << 1) + EmbeddedSignalling[6]);
|
||||
state->LCSS_ok = EmbeddedSignallingOk;
|
||||
|
||||
}
|
||||
//else skipcount++;
|
||||
|
||||
//Continue Second AMBE Frame, 18 after Sync or EmbeddedSignalling
|
||||
for(i = 0; i < 18; i++)
|
||||
{
|
||||
dibit = getDibit(opts, state);
|
||||
if(opts->inverted_dmr == 1)
|
||||
{
|
||||
dibit = (dibit ^ 2);
|
||||
}
|
||||
state->dmr_stereo_payload[i+90] = dibit;
|
||||
ambe_fr2[*w][*x] = (1 & (dibit >> 1)); // bit 1
|
||||
ambe_fr2[*y][*z] = (1 & dibit); // bit 0
|
||||
|
||||
w++;
|
||||
x++;
|
||||
y++;
|
||||
z++;
|
||||
|
||||
//WIP for RC inbound sync data, part 2, second 24 bits (12 dibits)
|
||||
if (i <= 12)
|
||||
{
|
||||
rcsyncdata[i+12] = (dibit | 1) + 48; //test and double check positions for this sync data
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Setup for Third AMBE Frame
|
||||
//Interleave Schedule
|
||||
w = rW;
|
||||
x = rX;
|
||||
y = rY;
|
||||
z = rZ;
|
||||
|
||||
//Third AMBE Frame, Full 36
|
||||
for(i = 0; i < 36; i++)
|
||||
{
|
||||
dibit = getDibit(opts, state);
|
||||
if(opts->inverted_dmr == 1)
|
||||
{
|
||||
dibit = (dibit ^ 2);
|
||||
}
|
||||
state->dmr_stereo_payload[i+108] = dibit;
|
||||
ambe_fr3[*w][*x] = (1 & (dibit >> 1)); // bit 1
|
||||
ambe_fr3[*y][*z] = (1 & dibit); // bit 0
|
||||
|
||||
w++;
|
||||
x++;
|
||||
y++;
|
||||
z++;
|
||||
|
||||
//end early to allow next sync without skipping a voice superframe
|
||||
//only use if only doing 6 VC and nothing else, otherwise, will lose sync
|
||||
if (vc1 == 6 && i == 30)
|
||||
{
|
||||
//i = 36;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( (strcmp (sync, DMR_MS_VOICE_SYNC) == 0) ) //
|
||||
{
|
||||
if (internalslot == 0)
|
||||
{
|
||||
vc1 = 1;
|
||||
fprintf (stderr, "MS Slot 1 Voice Sync \n");
|
||||
//activeslot = 0;
|
||||
|
||||
}
|
||||
if (internalslot == 1)
|
||||
{
|
||||
vc2 = 1;
|
||||
//fprintf (stderr, "MS Slot 2 Voice Sync \n");
|
||||
//activeslot = 1;
|
||||
}
|
||||
state->dmr_ms_mode = 1; //set to 1 here??
|
||||
}
|
||||
|
||||
state->dmr_ms_mode = 1; //set to 1 here?
|
||||
//testing to see if we need to do something to get MS mode working properly,
|
||||
//get proper sync, skip frames, etc.
|
||||
if (state->dmr_ms_mode == 1 ) //&& vc1 < 7
|
||||
{
|
||||
//do something
|
||||
fprintf (stderr, "MS MODE ");
|
||||
}
|
||||
|
||||
//don't know if we will catch an RC sync in here or not, should be on VC6 if it occurs
|
||||
if ( (strcmp (rcsync, DMR_RC_DATA_SYNC) == 0) || (strcmp (sync, DMR_RC_DATA_SYNC) == 0) ) //should be in same position as sync
|
||||
{
|
||||
fprintf (stderr,"%s ", getTime());
|
||||
if (internalslot == 0)
|
||||
{
|
||||
sprintf(state->slot1light, "[slot1]");
|
||||
sprintf(state->slot2light, " slot2 ");
|
||||
fprintf (stderr,"Sync: +DMR [slot1] slot2 | Color Code=%02d | DMRSTEREO | RC ", state->color_code);
|
||||
//test with vc1 reset disabled, if all is well, leave disabled
|
||||
//vc1 = 1;
|
||||
}
|
||||
if (internalslot == 1)
|
||||
{
|
||||
sprintf(state->slot2light, "[slot2]");
|
||||
sprintf(state->slot1light, " slot1 ");
|
||||
fprintf (stderr,"Sync: +DMR slot1 [slot2] | Color Code=%02d | DMRSTEREO | RC ", state->color_code);
|
||||
//test with vc1 reset disabled, if all is well, leave disabled
|
||||
//vc2 = 1;
|
||||
}
|
||||
fprintf (stderr, "\n "); //21 spaces to line up the sync
|
||||
//processDMRdata (opts, state);
|
||||
state->dmr_ms_rc = 1; //don't know what to do with this, if anything...
|
||||
goto SKIP;
|
||||
}
|
||||
|
||||
//check for sync pattern here after collected the rest of the payload, decide what to do with it
|
||||
if ( (strcmp (sync, DMR_MS_DATA_SYNC) == 0) )
|
||||
{
|
||||
fprintf (stderr,"%s ", getTime());
|
||||
if (internalslot == 0)
|
||||
{
|
||||
sprintf(state->slot1light, "[slot1]");
|
||||
sprintf(state->slot2light, " slot2 ");
|
||||
//fprintf (stderr,"Sync: +DMR [slot1] slot2 | Color Code=%02d | DMRSTEREO | MS Data ", state->color_code);
|
||||
fprintf (stderr,"Sync: +DMR ");
|
||||
//test with vc1 reset disabled, if all is well, leave disabled
|
||||
//vc1 = 1;
|
||||
}
|
||||
if (internalslot == 1)
|
||||
{
|
||||
sprintf(state->slot2light, "[slot2]");
|
||||
sprintf(state->slot1light, " slot1 ");
|
||||
//fprintf (stderr,"Sync: +DMR slot1 [slot2] | Color Code=%02d | DMRSTEREO | Data ", state->color_code);
|
||||
fprintf (stderr,"Sync: +DMR ");
|
||||
//test with vc1 reset disabled, if all is well, leave disabled
|
||||
//vc2 = 1;
|
||||
}
|
||||
//fprintf (stderr, "\n "); //21 spaces to line up the sync
|
||||
//fprintf (stderr, " "); //21 spaces to line up the sync
|
||||
state->dmr_ms_mode = 1; //set to 1 here??
|
||||
processDMRdata (opts, state);
|
||||
skipcount++;
|
||||
//goto SKIP;
|
||||
goto END;
|
||||
}
|
||||
|
||||
if( (strcmp (sync, DMR_MS_DATA_SYNC) != 0) && internalslot == activeslot && vc1 < 7) //only play voice no MS Data Sync and vc1 below 6 (no voice resync)
|
||||
{
|
||||
|
||||
skipcount = 0; //reset skip count if processing voice frames
|
||||
fprintf (stderr,"%s ", getTime());
|
||||
if (internalslot == 0)
|
||||
{
|
||||
fprintf (stderr,"Sync: +DMR [slot1] slot2 | Color Code=%02d | DMRSTEREO | VC%d \n", state->color_code, vc1);
|
||||
}
|
||||
|
||||
if (internalslot == 1)
|
||||
{
|
||||
fprintf (stderr,"Sync: +DMR slot1 [slot2] | Color Code=%02d | DMRSTEREO | VC%d \n", state->color_code, vc2);
|
||||
}
|
||||
if (internalslot == 0 && vc1 == 6) //presumably when full (and no sync issues)
|
||||
{
|
||||
//process voice burst
|
||||
ProcessVoiceBurstSync(opts, state);
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
if (internalslot == 1 && vc2 == 6) //presumably when full (and no sync issues)
|
||||
{
|
||||
//process voice burst
|
||||
//ProcessVoiceBurstSync(opts, state);
|
||||
//fprintf (stderr, "\n");
|
||||
}
|
||||
|
||||
processMbeFrame (opts, state, NULL, ambe_fr, NULL);
|
||||
processMbeFrame (opts, state, NULL, ambe_fr2, NULL);
|
||||
processMbeFrame (opts, state, NULL, ambe_fr3, NULL);
|
||||
if (internalslot == 0)
|
||||
{
|
||||
//vc1++;
|
||||
}
|
||||
if (internalslot == 1)
|
||||
{
|
||||
vc2++;
|
||||
}
|
||||
}
|
||||
vc1++;
|
||||
//6 seems optimal for MS, allows to quickly exit and resync if wonky or something
|
||||
if ( (vc1 > 6) || skipcount > 2) //escape to find new sync if deadspins without a renewed voice frame sync inside of loop
|
||||
{
|
||||
goto END;
|
||||
}
|
||||
|
||||
SKIP:
|
||||
skipDibit (opts, state, 144); //skip to next slot?
|
||||
state->dmr_ms_rc = 0;
|
||||
|
||||
//since we are in a repetitive loop, run ncursesPrinter here
|
||||
if (opts->use_ncurses_terminal == 1)
|
||||
{
|
||||
ncursesPrinter(opts, state);
|
||||
}
|
||||
|
||||
} // end while loop
|
||||
//reset these variables when exiting MS mode.
|
||||
END:
|
||||
//get first half payload dibits and store them in the payload for the next repitition
|
||||
skipDibit (opts, state, 144);
|
||||
//CACH + First Half Payload = 12 + 54
|
||||
for (i = 0; i < 66; i++) //66
|
||||
{
|
||||
dibit = getDibit(opts, state);
|
||||
if (opts->inverted_dmr == 1)
|
||||
{
|
||||
dibit = (dibit ^ 2);
|
||||
}
|
||||
state->dmr_stereo_payload[i] = dibit;
|
||||
//fprintf(stderr, "%X", state->dmr_stereo_payload[i]);
|
||||
}
|
||||
|
||||
state->dmr_stereo = 0;
|
||||
state->dmr_ms_mode = 0;
|
||||
state->dmr_ms_rc = 0;
|
||||
|
||||
}
|
||||
|
||||
//Only process 2nd half voice payload (3rd frame) and then jump to full MS Voice decoding.
|
||||
void dmrMSBootstrap (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
int i, j, k, l, dibit;
|
||||
int *dibit_p;
|
||||
char ambe_fr[4][24] = {0};
|
||||
char ambe_fr2[4][24] = {0};
|
||||
char ambe_fr3[4][24] = {0};
|
||||
const int *w, *x, *y, *z;
|
||||
char sync[25];
|
||||
char syncdata[48];
|
||||
char cachdata[13] = {0};
|
||||
int mutecurrentslot;
|
||||
int msMode;
|
||||
char cc[4];
|
||||
unsigned char EmbeddedSignalling[16];
|
||||
unsigned int EmbeddedSignallingOk;
|
||||
|
||||
//add time to mirror sync
|
||||
time_t now;
|
||||
char * getTime(void) //get pretty hh:mm:ss timestamp
|
||||
{
|
||||
time_t t = time(NULL);
|
||||
|
||||
char * curr;
|
||||
char * stamp = asctime(localtime( & t));
|
||||
|
||||
curr = strtok(stamp, " ");
|
||||
curr = strtok(NULL, " ");
|
||||
curr = strtok(NULL, " ");
|
||||
curr = strtok(NULL, " ");
|
||||
|
||||
return curr;
|
||||
}
|
||||
|
||||
dibit_p = state->dmr_payload_p - 90;
|
||||
//payload buffer tests
|
||||
//CACH + First Half Payload + Sync = 12 + 54 + 24
|
||||
//fprintf(stderr, "\n Full DMR Stereo Dump Dibits 90 From Buffer\n");
|
||||
for (i = 0; i < 90; i++) //90
|
||||
{
|
||||
state->dmr_stereo_payload[i] = *dibit_p;
|
||||
dibit_p++;
|
||||
//fprintf(stderr, "%X", state->dmr_stereo_payload[i]);
|
||||
}
|
||||
//end payload buffer test
|
||||
|
||||
for(i = 0; i < 12; i++)
|
||||
{
|
||||
dibit = state->dmr_stereo_payload[i];
|
||||
if(opts->inverted_dmr == 1)
|
||||
{
|
||||
dibit = (dibit ^ 2);
|
||||
}
|
||||
cachdata[i] = dibit;
|
||||
}
|
||||
|
||||
//Setup for first AMBE Frame
|
||||
|
||||
//Interleave Schedule
|
||||
w = rW;
|
||||
x = rX;
|
||||
y = rY;
|
||||
z = rZ;
|
||||
|
||||
//First AMBE Frame, Full 36
|
||||
for(i = 0; i < 36; i++)
|
||||
{
|
||||
dibit = state->dmr_stereo_payload[i+12];
|
||||
if(opts->inverted_dmr == 1)
|
||||
{
|
||||
dibit = (dibit ^ 2);
|
||||
}
|
||||
//state->dmr_stereo_payload[i+12] = dibit;
|
||||
ambe_fr[*w][*x] = (1 & (dibit >> 1)); // bit 1
|
||||
ambe_fr[*y][*z] = (1 & dibit); // bit 0
|
||||
|
||||
w++;
|
||||
x++;
|
||||
y++;
|
||||
z++;
|
||||
|
||||
}
|
||||
|
||||
//Setup for Second AMBE Frame
|
||||
|
||||
//Interleave Schedule
|
||||
w = rW;
|
||||
x = rX;
|
||||
y = rY;
|
||||
z = rZ;
|
||||
|
||||
//Second AMBE Frame, First Half 18 dibits just before Sync or EmbeddedSignalling
|
||||
for(i = 0; i < 18; i++)
|
||||
{
|
||||
dibit = state->dmr_stereo_payload[i+48];
|
||||
if(opts->inverted_dmr == 1)
|
||||
{
|
||||
dibit = (dibit ^ 2);
|
||||
}
|
||||
ambe_fr2[*w][*x] = (1 & (dibit >> 1)); // bit 1
|
||||
ambe_fr2[*y][*z] = (1 & dibit); // bit 0
|
||||
|
||||
w++;
|
||||
x++;
|
||||
y++;
|
||||
z++;
|
||||
|
||||
}
|
||||
|
||||
//Continue Second AMBE Frame, 18 after Sync or EmbeddedSignalling
|
||||
for(i = 0; i < 18; i++)
|
||||
{
|
||||
dibit = getDibit(opts, state);
|
||||
if(opts->inverted_dmr == 1)
|
||||
{
|
||||
dibit = (dibit ^ 2);
|
||||
}
|
||||
ambe_fr2[*w][*x] = (1 & (dibit >> 1)); // bit 1
|
||||
ambe_fr2[*y][*z] = (1 & dibit); // bit 0
|
||||
|
||||
w++;
|
||||
x++;
|
||||
y++;
|
||||
z++;
|
||||
|
||||
}
|
||||
|
||||
//Setup for Third AMBE Frame
|
||||
|
||||
//Interleave Schedule
|
||||
w = rW;
|
||||
x = rX;
|
||||
y = rY;
|
||||
z = rZ;
|
||||
|
||||
//Third AMBE Frame, Full 36
|
||||
for(i = 0; i < 36; i++)
|
||||
{
|
||||
dibit = getDibit(opts, state);
|
||||
if(opts->inverted_dmr == 1)
|
||||
{
|
||||
dibit = (dibit ^ 2);
|
||||
}
|
||||
ambe_fr3[*w][*x] = (1 & (dibit >> 1)); // bit 1
|
||||
ambe_fr3[*y][*z] = (1 & dibit); // bit 0
|
||||
|
||||
w++;
|
||||
x++;
|
||||
y++;
|
||||
z++;
|
||||
|
||||
}
|
||||
|
||||
fprintf (stderr, "MS MODE ");
|
||||
fprintf (stderr,"%s ", getTime());
|
||||
fprintf (stderr,"Sync: +DMR | Color Code=XX | DMRSTEREO | VC1 FS \n");
|
||||
processMbeFrame (opts, state, NULL, ambe_fr, NULL);
|
||||
processMbeFrame (opts, state, NULL, ambe_fr2, NULL);
|
||||
processMbeFrame (opts, state, NULL, ambe_fr3, NULL);
|
||||
skipDibit (opts, state, 144); //skip to next TDMA slot
|
||||
dmrMS (opts, state); //bootstrap into full TDMA frame
|
||||
|
||||
}
|
||||
|
||||
void dmrMSData (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
int i;
|
||||
int dibit;
|
||||
int *dibit_p;
|
||||
unsigned int burst;
|
||||
|
||||
//add time to mirror sync
|
||||
time_t now;
|
||||
char * getTime(void) //get pretty hh:mm:ss timestamp
|
||||
{
|
||||
time_t t = time(NULL);
|
||||
|
||||
char * curr;
|
||||
char * stamp = asctime(localtime( & t));
|
||||
|
||||
curr = strtok(stamp, " ");
|
||||
curr = strtok(NULL, " ");
|
||||
curr = strtok(NULL, " ");
|
||||
curr = strtok(NULL, " ");
|
||||
|
||||
return curr;
|
||||
}
|
||||
|
||||
//CACH + First Half Payload + Sync = 12 + 54 + 24
|
||||
//fprintf(stderr, "\n Full DMR Stereo Dump Dibits 90 From Buffer\n");
|
||||
for (i = 0; i < 90; i++) //90
|
||||
{
|
||||
//fprintf(stderr, "%X", state->dmr_stereo_payload[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < 54; i++)
|
||||
{
|
||||
dibit = getDibit(opts, state);
|
||||
if (opts->inverted_dmr == 1)
|
||||
{
|
||||
dibit = (dibit ^ 2);
|
||||
}
|
||||
state->dmr_stereo_payload[i+90] = dibit;
|
||||
|
||||
}
|
||||
//fprintf(stderr, "\n");
|
||||
//print nice pretty lines
|
||||
fprintf (stderr, "MS MODE ");
|
||||
fprintf (stderr, "%s ", getTime());
|
||||
//fprintf (stderr, "Sync: +MS DATA | Color Code=XX | DMRSTEREO | Data ");
|
||||
fprintf (stderr, "Sync: +DMR ");
|
||||
//fprintf (stderr, "\n ");
|
||||
|
||||
//sprintf for slot 1, doesn't matter, just makes print out of data look uniform setting ahead of time
|
||||
sprintf(state->slot1light, "[slot1]");
|
||||
sprintf(state->slot2light, " slot2 ");
|
||||
|
||||
//process data
|
||||
state->dmr_stereo = 1;
|
||||
state->dmr_ms_mode = 1;
|
||||
processDMRdata (opts, state);
|
||||
state->dmr_stereo = 0;
|
||||
state->dmr_ms_mode = 0;
|
||||
|
||||
//get potential first half payload dibits and store them in the payload for the next repitition, MS voice or data.
|
||||
skipDibit (opts, state, 144);
|
||||
//CACH + First Half Payload = 12 + 54
|
||||
for (i = 0; i < 66; i++) //66
|
||||
{
|
||||
dibit = getDibit(opts, state);
|
||||
if (opts->inverted_dmr == 1)
|
||||
{
|
||||
dibit = (dibit ^ 2);
|
||||
}
|
||||
state->dmr_stereo_payload[i] = dibit;
|
||||
//fprintf(stderr, "%X", state->dmr_stereo_payload[i]);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,6 +19,26 @@
|
||||
#include "dmr_const.h"
|
||||
#include "p25p1_check_hdu.h"
|
||||
//
|
||||
|
||||
//
|
||||
void ProcessDMR (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
uint32_t i, j;
|
||||
uint32_t Frame;
|
||||
TimeSlotVoiceSuperFrame_t * TSVoiceSupFrameL = NULL;
|
||||
TimeSlotVoiceSuperFrame_t * TSVoiceSupFrameR = NULL;
|
||||
TimeSlotVoiceSuperFrame_t * TSVoiceSupFrameRC = NULL; //Reverse Test for MS Backwards
|
||||
|
||||
int *errs;
|
||||
int *errs2;
|
||||
unsigned long long int k;
|
||||
int x;
|
||||
k = 0;
|
||||
|
||||
TSVoiceSupFrameL = &state->TS1SuperFrame;
|
||||
TSVoiceSupFrameR = &state->TS2SuperFrame;
|
||||
|
||||
//
|
||||
int BP[256] = {
|
||||
0x0000, 0x1F00, 0xE300, 0xFC00, 0x2503, 0x3A03, 0xC603, 0xD903,
|
||||
0x4A05, 0x5505, 0xA905, 0xB605, 0x6F06, 0x7006, 0x8C06, 0x9306,
|
||||
@@ -54,71 +74,53 @@ int BP[256] = {
|
||||
0x41F5, 0x5EF5, 0xA2F5, 0xBDF5, 0x64F6, 0x7BF6, 0x87F6, 0x98F6 //255
|
||||
};
|
||||
//
|
||||
void ProcessDMR (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
uint32_t i, j;
|
||||
uint32_t Frame;
|
||||
TimeSlotVoiceSuperFrame_t * TSVoiceSupFrame = NULL;
|
||||
TimeSlotVoiceSuperFrame_t * TSVoiceSupFrameL = NULL;
|
||||
TimeSlotVoiceSuperFrame_t * TSVoiceSupFrameR = NULL;
|
||||
|
||||
int *errs;
|
||||
int *errs2;
|
||||
int *errsR;
|
||||
int *errs2R;
|
||||
unsigned long long int k;
|
||||
int x;
|
||||
k = 0;
|
||||
|
||||
if(state->currentslot == 0)
|
||||
{
|
||||
TSVoiceSupFrame = &state->TS1SuperFrame;
|
||||
}
|
||||
else
|
||||
{
|
||||
TSVoiceSupFrame = &state->TS2SuperFrame;
|
||||
}
|
||||
//TSVoiceSupFrameL = &state->TS1SuperFrame;
|
||||
//TSVoiceSupFrameR = &state->TS2SuperFrame;
|
||||
|
||||
//
|
||||
if (state->K > 0 && state->dmr_so & 0x40 && state->payload_keyid == 0)
|
||||
if (state->currentslot == 0 && state->K > 0 && state->dmr_so & 0x40 && state->payload_keyid == 0)
|
||||
{
|
||||
fprintf (stderr, "%s", KYEL);
|
||||
fprintf(stderr, " BPK %lld", state->K);
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
k = BP[state->K];
|
||||
k = ( ((k & 0xFF0F) << 32 ) + (k << 16) + k );
|
||||
for(Frame = 0; Frame < 6; Frame++)
|
||||
{
|
||||
for(i = 0; i < 3; i++)
|
||||
{
|
||||
for(j = 0; j < 49; j++)
|
||||
{
|
||||
k = BP[state->K];
|
||||
k = ( ((k & 0xFF0F) << 32 ) + (k << 16) + k );
|
||||
{
|
||||
x = ( ((k << j) & 0x800000000000) >> 47 );
|
||||
TSVoiceSupFrame->TimeSlotAmbeVoiceFrame[Frame].AmbeBit[i][j] ^= x;
|
||||
}
|
||||
TSVoiceSupFrameL->TimeSlotAmbeVoiceFrame[Frame].AmbeBit[i][j] ^= x;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (state->currentslot == 1 && state->K > 0 && state->dmr_so & 0x40 && state->payload_keyid == 0)
|
||||
{
|
||||
fprintf (stderr, "%s", KYEL);
|
||||
fprintf(stderr, " BPK %lld", state->K);
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
k = BP[state->K];
|
||||
k = ( ((k & 0xFF0F) << 32 ) + (k << 16) + k );
|
||||
for(Frame = 0; Frame < 6; Frame++)
|
||||
{
|
||||
for(i = 0; i < 3; i++)
|
||||
{
|
||||
for(j = 0; j < 49; j++)
|
||||
{
|
||||
x = ( ((k << j) & 0x800000000000) >> 47 );
|
||||
TSVoiceSupFrameR->TimeSlotAmbeVoiceFrame[Frame].AmbeBit[i][j] ^= x;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
for(Frame = 0; Frame < 6; Frame++)
|
||||
if (state->currentslot == 0)
|
||||
{
|
||||
for(Frame = 0; Frame < 6; Frame++) //6
|
||||
{
|
||||
/* 1 DMR frame contains 3 AMBE voice samples */
|
||||
//fprintf (stderr, "\n 1AMBE ");
|
||||
for(i = 0; i < 3; i++)
|
||||
{
|
||||
|
||||
errs = (int*)&(TSVoiceSupFrame->TimeSlotAmbeVoiceFrame[Frame].errs1[i]);
|
||||
errs2 = (int*)&(TSVoiceSupFrame->TimeSlotAmbeVoiceFrame[Frame].errs2[i]);
|
||||
state->errs = TSVoiceSupFrame->TimeSlotAmbeVoiceFrame[Frame].errs1[i]; //correct placement
|
||||
state->errs2 = TSVoiceSupFrame->TimeSlotAmbeVoiceFrame[Frame].errs2[i]; //correct placement
|
||||
|
||||
mbe_processAmbe2450Dataf (state->audio_out_temp_buf, errs, errs2, state->err_str,
|
||||
TSVoiceSupFrame->TimeSlotAmbeVoiceFrame[Frame].AmbeBit[i],
|
||||
state->cur_mp, state->prev_mp, state->prev_mp_enhanced, opts->uvquality);
|
||||
|
||||
/*
|
||||
if (state->currentslot == 0)
|
||||
{
|
||||
errs = (int*)&(TSVoiceSupFrameL->TimeSlotAmbeVoiceFrame[Frame].errs1[i]);
|
||||
errs2 = (int*)&(TSVoiceSupFrameL->TimeSlotAmbeVoiceFrame[Frame].errs2[i]);
|
||||
state->errs = TSVoiceSupFrameL->TimeSlotAmbeVoiceFrame[Frame].errs1[i]; //correct placement
|
||||
@@ -128,45 +130,16 @@ if (state->K > 0 && state->dmr_so & 0x40 && state->payload_keyid == 0)
|
||||
TSVoiceSupFrameL->TimeSlotAmbeVoiceFrame[Frame].AmbeBit[i],
|
||||
state->cur_mp, state->prev_mp, state->prev_mp_enhanced, opts->uvquality);
|
||||
|
||||
state->debug_audio_errors += *errs2;
|
||||
//state->debug_audio_errors += *errs2R;
|
||||
|
||||
processAudio(opts, state);
|
||||
playSynthesizedVoice (opts, state);
|
||||
}
|
||||
if (state->currentslot == 1)
|
||||
{
|
||||
errsR = (int*)&(TSVoiceSupFrameR->TimeSlotAmbeVoiceFrame[Frame].errs1[i]);
|
||||
errs2R = (int*)&(TSVoiceSupFrameR->TimeSlotAmbeVoiceFrame[Frame].errs2[i]);
|
||||
state->errs = TSVoiceSupFrameR->TimeSlotAmbeVoiceFrame[Frame].errs1[i]; //correct placement
|
||||
state->errs2 = TSVoiceSupFrameR->TimeSlotAmbeVoiceFrame[Frame].errs2[i]; //correct placement
|
||||
//state->audio_out_temp_bufR = state->audio_out_temp_buf;
|
||||
|
||||
mbe_processAmbe2450Dataf (state->audio_out_temp_buf, errsR, errs2R, state->err_strR,
|
||||
TSVoiceSupFrameR->TimeSlotAmbeVoiceFrame[Frame].AmbeBit[i],
|
||||
state->cur_mp, state->prev_mp, state->prev_mp_enhanced, opts->uvquality);
|
||||
|
||||
state->debug_audio_errors += *errs2R;
|
||||
processAudio(opts, state);
|
||||
playSynthesizedVoice (opts, state);
|
||||
}
|
||||
|
||||
mbe_processAmbe2450Dataf (state->audio_out_temp_bufR, errsR, errs2R, state->err_strR,
|
||||
TSVoiceSupFrameR->TimeSlotAmbeVoiceFrame[Frame].AmbeBit[i],
|
||||
state->cur_mp, state->prev_mp, state->prev_mp_enhanced, opts->uvquality);
|
||||
*/
|
||||
|
||||
if (opts->mbe_out_f != NULL)
|
||||
{
|
||||
saveAmbe2450Data (opts, state, TSVoiceSupFrame->TimeSlotAmbeVoiceFrame[Frame].AmbeBit[i]);
|
||||
saveAmbe2450Data (opts, state, TSVoiceSupFrameL->TimeSlotAmbeVoiceFrame[Frame].AmbeBit[i]);
|
||||
}
|
||||
if (opts->errorbars == 1)
|
||||
{
|
||||
fprintf(stderr, "%s", state->err_str);
|
||||
//fprintf(stderr, "%s", state->err_str);
|
||||
}
|
||||
|
||||
state->debug_audio_errors += *errs2;
|
||||
//state->debug_audio_errors += *errs2R;
|
||||
|
||||
processAudio(opts, state);
|
||||
//playSynthesizedVoice (opts, state);
|
||||
@@ -176,14 +149,59 @@ if (state->K > 0 && state->dmr_so & 0x40 && state->payload_keyid == 0)
|
||||
writeSynthesizedVoice (opts, state);
|
||||
}
|
||||
|
||||
if (opts->audio_out == 1 && opts->p25enc != 1) //play only if not equal to enc value, going to set p25enc to 1 if enc detected??
|
||||
//play only if not equal to enc value, going to set p25enc to 1 if enc detected??
|
||||
if (opts->audio_out == 1 && opts->p25enc != 1)
|
||||
{
|
||||
playSynthesizedVoice (opts, state);
|
||||
}
|
||||
} /* End for(i = 0; i < 3; i++) */
|
||||
} /* End for(Frame = 0; Frame < 6; Frame++) */
|
||||
} /* End ProcessDMREncryption() */
|
||||
|
||||
} //End if Current Slot == 0
|
||||
|
||||
if (state->currentslot == 1)
|
||||
{
|
||||
for(Frame = 0; Frame < 6; Frame++)
|
||||
{
|
||||
/* 1 DMR frame contains 3 AMBE voice samples */
|
||||
for(i = 0; i < 3; i++)
|
||||
{
|
||||
errs = (int*)&(TSVoiceSupFrameR->TimeSlotAmbeVoiceFrame[Frame].errs1[i]);
|
||||
errs2 = (int*)&(TSVoiceSupFrameR->TimeSlotAmbeVoiceFrame[Frame].errs2[i]);
|
||||
state->errs = TSVoiceSupFrameR->TimeSlotAmbeVoiceFrame[Frame].errs1[i]; //correct placement
|
||||
state->errs2 = TSVoiceSupFrameR->TimeSlotAmbeVoiceFrame[Frame].errs2[i]; //correct placement
|
||||
|
||||
mbe_processAmbe2450Dataf (state->audio_out_temp_buf, errs, errs2, state->err_str,
|
||||
TSVoiceSupFrameR->TimeSlotAmbeVoiceFrame[Frame].AmbeBit[i],
|
||||
state->cur_mp, state->prev_mp, state->prev_mp_enhanced, opts->uvquality);
|
||||
|
||||
if (opts->mbe_out_f != NULL)
|
||||
{
|
||||
saveAmbe2450Data (opts, state, TSVoiceSupFrameR->TimeSlotAmbeVoiceFrame[Frame].AmbeBit[i]);
|
||||
}
|
||||
if (opts->errorbars == 1)
|
||||
{
|
||||
//fprintf(stderr, "%s", state->err_str);
|
||||
}
|
||||
|
||||
state->debug_audio_errors += *errs2;
|
||||
|
||||
processAudio(opts, state);
|
||||
//playSynthesizedVoice (opts, state);
|
||||
|
||||
if (opts->wav_out_f != NULL)
|
||||
{
|
||||
writeSynthesizedVoice (opts, state);
|
||||
}
|
||||
|
||||
//play only if not equal to enc value, going to set p25enc to 1 if enc detected??
|
||||
if (opts->audio_out == 1 && opts->p25enc != 1)
|
||||
{
|
||||
playSynthesizedVoice (opts, state);
|
||||
}
|
||||
} /* End for(i = 0; i < 3; i++) */
|
||||
} /* End for(Frame = 0; Frame < 6; Frame++) */
|
||||
} //End if Current Slot == 1
|
||||
|
||||
|
||||
} /* End ProcessDMR */
|
||||
/* End of file */
|
||||
|
||||
588
src/dmr_sync.c
588
src/dmr_sync.c
File diff suppressed because it is too large
Load Diff
@@ -115,6 +115,16 @@ void processDMRvoice (dsd_opts * opts, dsd_state * state)
|
||||
state->slot1light[0] = ' ';
|
||||
state->slot1light[6] = ' ';
|
||||
}
|
||||
//method to only listen to a chosen slot when voices occupy both slots simultaneously
|
||||
//method supersceeded by DMRSTEREO
|
||||
//state->hardslot = 9; //0 to only listen to slot 0 voice, 1 for slot 1, 9 for both
|
||||
//if(state->hardslot != 9 && state->hardslot != state->currentslot)
|
||||
//if(1==1)
|
||||
//{
|
||||
//fprintf (stderr, " Current Slot = %d", state->currentslot + 1);
|
||||
//fprintf (stderr, "\n"); //line break after breaking out of jail
|
||||
//goto JUMP;
|
||||
//}
|
||||
}
|
||||
}
|
||||
cachdata[12] = 0;
|
||||
@@ -370,10 +380,23 @@ void processDMRvoice (dsd_opts * opts, dsd_state * state)
|
||||
sprintf(state->slot2light, "[sLoT2]");
|
||||
}
|
||||
|
||||
if((strcmp (sync, DMR_MS_VOICE_SYNC) == 0) || (strcmp (sync, DMR_MS_DATA_SYNC) == 0))
|
||||
//Comment out Below Lines, or switch if/else if if these cause issues.
|
||||
/*
|
||||
else if((strcmp (sync, DMR_MS_VOICE_SYNC) == 0) || (strcmp (sync, DMR_MS_DATA_SYNC) == 0))
|
||||
{
|
||||
msMode = 1;
|
||||
if strcmp (sync, DMR_MS_VOICE_SYNC) == 0)
|
||||
{
|
||||
//quickDMRVoice (opts, state); //or make handler for msvoice seperate
|
||||
//goto JUMP; //quit early when returned here
|
||||
}
|
||||
}
|
||||
else if((strcmp (sync, DMR_BS_VOICE_SYNC) == 0)
|
||||
{
|
||||
//quickDMRVoice (opts, state); //or make handler for msvoice seperate
|
||||
//goto JUMP; //quit early when returned here
|
||||
}
|
||||
*/
|
||||
|
||||
// TODO : To be removed
|
||||
// if((j == 0) && (opts->errorbars == 1))
|
||||
@@ -574,8 +597,9 @@ void processDMRvoice (dsd_opts * opts, dsd_state * state)
|
||||
fprintf(stderr, "%s ", syncbits);
|
||||
#endif
|
||||
|
||||
if(j == 5)
|
||||
if(j == 5) //j == 5
|
||||
{
|
||||
|
||||
// 2nd half next slot
|
||||
skipDibit (opts, state, 54);
|
||||
|
||||
@@ -617,6 +641,7 @@ void processDMRvoice (dsd_opts * opts, dsd_state * state)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} /* End for(j = 0; j < 6; j++) */
|
||||
|
||||
if(opts->errorbars == 1)
|
||||
@@ -624,14 +649,25 @@ void processDMRvoice (dsd_opts * opts, dsd_state * state)
|
||||
fprintf(stderr, "%s %s ", state->slot1light, state->slot2light);
|
||||
|
||||
/* Print the color code */
|
||||
fprintf (stderr, "%s", KCYN);
|
||||
fprintf(stderr, "| Color Code=%02d ", (int)state->color_code);
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
|
||||
//if(state->color_code_ok) fprintf(stderr, "(OK) |");
|
||||
if(state->color_code_ok) fprintf(stderr, "(CRC OK ) |"); //add line break
|
||||
else fprintf(stderr, "(CRC ERR) |"); //add line break
|
||||
if(state->color_code_ok)
|
||||
{
|
||||
fprintf(stderr, "| (CRC OK ) |"); //add line break
|
||||
state->dmr_color_code = state->color_code; //set here when voice? otherwise is set off of idle.
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (stderr, "%s", KRED);
|
||||
fprintf(stderr, "| (CRC ERR) |"); //add line break
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
}
|
||||
|
||||
//fprintf(stderr, " VOICE e: \n");
|
||||
fprintf(stderr, " VOICE ");
|
||||
fprintf(stderr, " VOICE ");
|
||||
}
|
||||
|
||||
/* Perform the SYNC DMR data embedded decoding */
|
||||
@@ -642,9 +678,10 @@ void processDMRvoice (dsd_opts * opts, dsd_state * state)
|
||||
|
||||
/* Print DMR frame (if needed) */
|
||||
//DMRVoiceFrameProcess(opts, state); //HERE HERE, was enabled, disabled so I could build
|
||||
|
||||
//JUMP:
|
||||
if(opts->errorbars == 1)
|
||||
{
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
} /* End processDMRvoice() */
|
||||
|
||||
@@ -163,10 +163,10 @@ void processdPMRvoice (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
dibit = getDibit (opts, state);
|
||||
|
||||
if (opts->inverted_dpmr == 1)
|
||||
{
|
||||
dibit = (dibit ^ 2);
|
||||
}
|
||||
if (opts->inverted_dpmr == 1)
|
||||
{
|
||||
dibit = (dibit ^ 2);
|
||||
}
|
||||
|
||||
ambe_fr[j + 4][*w][*x] = (1 & (dibit >> 1)); // bit 1
|
||||
ambe_fr[j + 4][*y][*z] = (1 & dibit); // bit 0
|
||||
@@ -467,13 +467,17 @@ void processdPMRvoice (dsd_opts * opts, dsd_state * state)
|
||||
//fprintf(stderr, "| TG=%s", CalledID);
|
||||
if(state->dPMRVoiceFS2Frame.CalledIDOk)
|
||||
{
|
||||
fprintf (stderr, "%s", KGRN);
|
||||
fprintf(stderr, "\n| TG=%s", CalledID);
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
//strcpy (state->dpmr_target_id, CalledID); //HERE HERE
|
||||
state->dpmr_target_id = CalledID;
|
||||
//fprintf(stderr, " (CRC OK) ");
|
||||
if(state->dPMRVoiceFS2Frame.ColorCode[0] != (unsigned int)(-1))
|
||||
{
|
||||
fprintf (stderr, "%s", KGRN);
|
||||
fprintf(stderr, " | Color Code=%02d ", (int)state->dPMRVoiceFS2Frame.ColorCode[0]);
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
state->dpmr_color_code = (int)state->dPMRVoiceFS2Frame.ColorCode[0];
|
||||
|
||||
}
|
||||
@@ -488,15 +492,19 @@ void processdPMRvoice (dsd_opts * opts, dsd_state * state)
|
||||
//fprintf(stderr, "| Src=%s", CallingID);
|
||||
if(state->dPMRVoiceFS2Frame.CallingIDOk)
|
||||
{
|
||||
fprintf (stderr, "%s", KGRN);
|
||||
fprintf(stderr, "| Src=%s", CallingID);
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
//strcpy (state->dpmr_caller_id, CallingID);
|
||||
state->dpmr_caller_id = CallingID;
|
||||
|
||||
fprintf(stderr, " (CRC OK) \n");
|
||||
//fprintf(stderr, " (CRC OK) \n");
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (stderr, "%s", KRED);
|
||||
fprintf(stderr, " (CRC ERR) \n");
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
}
|
||||
|
||||
#endif /* (NB_OF_DPMR_VOICE_FRAME_TO_DECODE == 2) */
|
||||
@@ -583,7 +591,7 @@ void ScrambledPMRBit(uint32_t * LfsrValue, uint8_t * BufferIn, uint8_t * BufferO
|
||||
LFSRValue >>= 1;
|
||||
}
|
||||
|
||||
/* There are 72 bit to encrypt for voice and 288 bit for data */
|
||||
/* There are 72 bit to descramble for voice and 288 bit for data */
|
||||
for(i = 0; i < NbOfBitToScramble; i++)
|
||||
{
|
||||
BufferOut[i] = (BufferIn[i] ^ S[0]) & 0x01;
|
||||
@@ -613,8 +621,8 @@ void ScrambledPMRBit(uint32_t * LfsrValue, uint8_t * BufferIn, uint8_t * BufferO
|
||||
} /* End ScrambleDPmrBit() */
|
||||
|
||||
|
||||
/* Scrambler used for dPMR encryption / decryption,
|
||||
* see ETSI TS 102 658 chapter 7.3 for the
|
||||
/* Scrambler used for dPMR scrambling / descrambling,
|
||||
* see ETSI TS 102 658 chapter 7.4 for the
|
||||
* polynomial description.
|
||||
* It is a X^9 + X^5 + 1 polynomial. */
|
||||
void DeInterleave6x12DPmrBit(uint8_t * BufferIn, uint8_t * BufferOut)
|
||||
|
||||
551
src/dsd_audio.c
551
src/dsd_audio.c
@@ -21,8 +21,6 @@ pa_sample_spec ss;
|
||||
pa_sample_spec tt;
|
||||
pa_sample_spec zz;
|
||||
pa_sample_spec cc;
|
||||
//pa_channel_map channel_map;
|
||||
|
||||
|
||||
void openPulseOutput(dsd_opts * opts)
|
||||
{
|
||||
@@ -34,68 +32,39 @@ void openPulseOutput(dsd_opts * opts)
|
||||
tt.format = PA_SAMPLE_S16NE;
|
||||
tt.channels = opts->pulse_digi_out_channels; //doing tests with 2 channels at 22050 for 44100 audio default in pulse
|
||||
tt.rate = opts->pulse_digi_rate_out; //48000, switches to 8000 when using RTL dongle
|
||||
//fprintf (stderr,"digi rate out = %d\n", opts->pulse_digi_rate_out);
|
||||
//pa_channel_map_init_stereo(&channel_map);
|
||||
//ss
|
||||
|
||||
if (opts->monitor_input_audio == 1)
|
||||
//if (opts->frame_dmr == 1 && opts->audio_in_type != 3)
|
||||
{
|
||||
opts->pulse_raw_dev_out = pa_simple_new(NULL, "DSD-FME", PA_STREAM_PLAYBACK, NULL, "Raw Audio", &ss, NULL, NULL, NULL);
|
||||
//opts->pulse_raw_dev_out = pa_simple_new(NULL, "DSD FME", PA_STREAM_PLAYBACK, NULL, "DMR/MOTOTRBO Right", &ss, NULL, NULL, NULL);
|
||||
opts->pulse_raw_dev_out = pa_simple_new(NULL, "DSD-FME", PA_STREAM_PLAYBACK, NULL, "Raw Audio Out", &ss, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
//tt
|
||||
pa_channel_map* left = 0; //NULL and 0 are same in this context
|
||||
pa_channel_map* right = 0; //NULL and 0 are same in this context
|
||||
//pa_channel_map* right;
|
||||
//pa_channel_map_init(right);
|
||||
opts->pulse_digi_dev_out = pa_simple_new(NULL, "DSD-FME", PA_STREAM_PLAYBACK, NULL, opts->output_name, &tt, left, NULL, NULL);
|
||||
//opts->pulse_digi_dev_out = pa_simple_new(NULL, "DSD FME", PA_STREAM_PLAYBACK, NULL, "Digi Audio Out LEFT", &tt, left, NULL, NULL);
|
||||
//opts->pulse_raw_dev_out = pa_simple_new(NULL, "DSD-FME", PA_STREAM_PLAYBACK, NULL, "Digi Audio Out RIGHT", &tt, right, NULL, NULL);
|
||||
|
||||
if (opts->dmr_stereo == 0)
|
||||
{
|
||||
opts->pulse_digi_dev_out = pa_simple_new(NULL, "DSD-FME", PA_STREAM_PLAYBACK, NULL, opts->output_name, &tt, left, NULL, NULL);
|
||||
|
||||
}
|
||||
if (opts->dmr_stereo == 1)
|
||||
{
|
||||
opts->pulse_digi_dev_out = pa_simple_new(NULL, "DSD-FME", PA_STREAM_PLAYBACK, NULL, "DMR/MOTOTRBO LEFT", &tt, left, NULL, NULL);
|
||||
opts->pulse_digi_dev_outR = pa_simple_new(NULL, "DSD-FME", PA_STREAM_PLAYBACK, NULL, "DMR/MOTOTRBO RIGHT", &tt, right, NULL, NULL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void openPulseInput(dsd_opts * opts)
|
||||
{
|
||||
|
||||
zz.format = PA_SAMPLE_S16NE;
|
||||
zz.channels = opts->pulse_raw_in_channels;
|
||||
zz.rate = opts->pulse_raw_rate_in; //48000
|
||||
|
||||
cc.format = PA_SAMPLE_S16NE;
|
||||
cc.channels = opts->pulse_digi_in_channels;
|
||||
cc.rate = opts->pulse_digi_rate_in; //48000
|
||||
|
||||
//zz
|
||||
if (opts->monitor_input_audio == 1)
|
||||
{
|
||||
//opts->pulse_raw_dev_in = pa_simple_new(NULL, "DSD-FME", PA_STREAM_RECORD, NULL, "Raw Audio In", &zz, NULL, NULL, NULL);
|
||||
}
|
||||
//cc
|
||||
opts->pulse_digi_dev_in = pa_simple_new(NULL, "DSD-FME", PA_STREAM_RECORD, NULL, opts->output_name, &cc, NULL, NULL, NULL);
|
||||
|
||||
}
|
||||
//playRawAudio may be obsoleted now that I can run these correctly right inside of dsd_symbol
|
||||
void playRawAudio(dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
short obuf, outl, i, sample2, something;
|
||||
something = state->samplesPerSymbol / 1; //1 for buffer steal loops, 5 for rtl loop
|
||||
//something = 1;
|
||||
if (opts->audio_in_type == 0 && opts->audio_out_type == 0){ //hack, but might as well for this particular type since its nearly perfect
|
||||
for (i=0; i < something; i++){
|
||||
//read (opts->audio_in_fd, &sample2, 2); //reading here seems to get same speed as gfsk modulation
|
||||
//pa_simple_drain(opts->pulse_raw_dev_out, NULL);
|
||||
//pa_simple_read(opts->pulse_raw_dev_in, &state->pulse_raw_out_buffer, 2, NULL );
|
||||
//obuf = state->pulse_raw_out_buffer / 4; //dividing here 'quietens' it down a little bit, helps with clicking and clipping
|
||||
//obuf = state->input_sample_buffer;
|
||||
//obuf = state->pulse_raw_out_buffer;
|
||||
//write (opts->audio_out_fd, (void*)&obuf, 2);
|
||||
//pa_simple_write(opts->pulse_raw_dev_out, (void*)&obuf, 2, NULL);
|
||||
//pa_simple_write(opts->pulse_digi_dev_out, (void*)&obuf, 2, NULL);
|
||||
//pa_simple_drain(opts->pulse_raw_dev_out, NULL);
|
||||
}
|
||||
}
|
||||
} //end playRawAudio
|
||||
|
||||
|
||||
void
|
||||
processAudio (dsd_opts * opts, dsd_state * state)
|
||||
@@ -109,7 +78,6 @@ processAudio (dsd_opts * opts, dsd_state * state)
|
||||
// detect max level
|
||||
max = 0;
|
||||
state->audio_out_temp_buf_p = state->audio_out_temp_buf;
|
||||
//state->audio_out_temp_buf_pR = state->audio_out_temp_bufR;
|
||||
for (n = 0; n < 160; n++)
|
||||
{
|
||||
aout_abs = fabsf (*state->audio_out_temp_buf_p);
|
||||
@@ -118,24 +86,18 @@ processAudio (dsd_opts * opts, dsd_state * state)
|
||||
max = aout_abs;
|
||||
}
|
||||
state->audio_out_temp_buf_p++;
|
||||
//state->audio_out_temp_buf_pR++;
|
||||
}
|
||||
*state->aout_max_buf_p = max;
|
||||
//*state->aout_max_buf_pR = max;
|
||||
|
||||
state->aout_max_buf_p++;
|
||||
//state->aout_max_buf_pR++;
|
||||
|
||||
state->aout_max_buf_idx++;
|
||||
//state->aout_max_buf_idxR++;
|
||||
|
||||
if (state->aout_max_buf_idx > 24)
|
||||
{
|
||||
state->aout_max_buf_idx = 0;
|
||||
state->aout_max_buf_p = state->aout_max_buf;
|
||||
}
|
||||
//if (state->aout_max_buf_idxR > 24)
|
||||
// {
|
||||
// state->aout_max_buf_idxR = 0;
|
||||
// state->aout_max_buf_pR = state->aout_max_bufR;
|
||||
// }
|
||||
|
||||
// lookup max history
|
||||
for (i = 0; i < 25; i++)
|
||||
@@ -241,6 +203,145 @@ processAudio (dsd_opts * opts, dsd_state * state)
|
||||
state->audio_out_idx2++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
processAudioR (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
|
||||
int i, n;
|
||||
float aout_abs, max, gainfactor, gaindelta, maxbuf;
|
||||
if (opts->audio_gainR == (float) 0)
|
||||
{
|
||||
// detect max level
|
||||
max = 0;
|
||||
state->audio_out_temp_buf_pR = state->audio_out_temp_bufR;
|
||||
for (n = 0; n < 160; n++)
|
||||
{
|
||||
aout_abs = fabsf (*state->audio_out_temp_buf_pR);
|
||||
if (aout_abs > max)
|
||||
{
|
||||
max = aout_abs;
|
||||
}
|
||||
state->audio_out_temp_buf_pR++;
|
||||
}
|
||||
*state->aout_max_buf_pR = max;
|
||||
|
||||
state->aout_max_buf_pR++;
|
||||
|
||||
state->aout_max_buf_idxR++;
|
||||
|
||||
if (state->aout_max_buf_idxR > 24)
|
||||
{
|
||||
state->aout_max_buf_idxR = 0;
|
||||
state->aout_max_buf_pR = state->aout_max_bufR;
|
||||
}
|
||||
|
||||
// lookup max history
|
||||
for (i = 0; i < 25; i++)
|
||||
{
|
||||
maxbuf = state->aout_max_bufR[i];
|
||||
if (maxbuf > max)
|
||||
{
|
||||
max = maxbuf;
|
||||
}
|
||||
}
|
||||
|
||||
// determine optimal gain level
|
||||
if (max > (float) 0)
|
||||
{
|
||||
gainfactor = ((float) 30000 / max);
|
||||
}
|
||||
else
|
||||
{
|
||||
gainfactor = (float) 50;
|
||||
}
|
||||
if (gainfactor < state->aout_gainR)
|
||||
{
|
||||
state->aout_gainR = gainfactor;
|
||||
gaindelta = (float) 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gainfactor > (float) 50)
|
||||
{
|
||||
gainfactor = (float) 50;
|
||||
}
|
||||
gaindelta = gainfactor - state->aout_gainR;
|
||||
if (gaindelta > ((float) 0.05 * state->aout_gainR))
|
||||
{
|
||||
gaindelta = ((float) 0.05 * state->aout_gainR);
|
||||
}
|
||||
}
|
||||
gaindelta /= (float) 160;
|
||||
}
|
||||
else
|
||||
{
|
||||
gaindelta = (float) 0;
|
||||
}
|
||||
|
||||
if(opts->audio_gainR >= 0)
|
||||
{
|
||||
// adjust output gain
|
||||
state->audio_out_temp_buf_pR = state->audio_out_temp_bufR;
|
||||
for (n = 0; n < 160; n++)
|
||||
{
|
||||
*state->audio_out_temp_buf_pR = (state->aout_gainR + ((float) n * gaindelta)) * (*state->audio_out_temp_buf_pR);
|
||||
state->audio_out_temp_buf_pR++;
|
||||
}
|
||||
state->aout_gainR += ((float) 160 * gaindelta);
|
||||
}
|
||||
|
||||
// copy audio data to output buffer and upsample if necessary
|
||||
state->audio_out_temp_buf_pR = state->audio_out_temp_bufR;
|
||||
if (opts->split == 0) //shouldn't need splitR
|
||||
{
|
||||
for (n = 0; n < 160; n++)
|
||||
{
|
||||
upsample (state, *state->audio_out_temp_buf_pR);
|
||||
state->audio_out_temp_buf_pR++;
|
||||
state->audio_out_float_buf_pR += 6;
|
||||
state->audio_out_idxR += 6;
|
||||
state->audio_out_idx2R += 6;
|
||||
}
|
||||
state->audio_out_float_buf_pR -= (960 + opts->playoffsetR);
|
||||
// copy to output (short) buffer
|
||||
for (n = 0; n < 960; n++)
|
||||
{
|
||||
if (*state->audio_out_float_buf_pR > 32767.0F)
|
||||
{
|
||||
*state->audio_out_float_buf_pR = 32767.0F;
|
||||
}
|
||||
else if (*state->audio_out_float_buf_pR < -32768.0F)
|
||||
{
|
||||
*state->audio_out_float_buf_pR = -32768.0F;
|
||||
}
|
||||
*state->audio_out_buf_pR = (short) *state->audio_out_float_buf_pR;
|
||||
state->audio_out_buf_pR++;
|
||||
state->audio_out_float_buf_pR++;
|
||||
}
|
||||
state->audio_out_float_buf_pR += opts->playoffsetR;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (n = 0; n < 160; n++)
|
||||
{
|
||||
if (*state->audio_out_temp_buf_pR > 32767.0F)
|
||||
{
|
||||
*state->audio_out_temp_buf_pR = 32767.0F;
|
||||
}
|
||||
else if (*state->audio_out_temp_buf_pR < -32768.0F)
|
||||
{
|
||||
*state->audio_out_temp_buf_pR = -32768.0F;
|
||||
}
|
||||
*state->audio_out_buf_pR = (short) *state->audio_out_temp_buf_pR;
|
||||
state->audio_out_buf_pR++;
|
||||
state->audio_out_temp_buf_pR++;
|
||||
state->audio_out_idxR++;
|
||||
state->audio_out_idx2R++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -310,183 +411,77 @@ playSynthesizedVoice (dsd_opts * opts, dsd_state * state)
|
||||
ssize_t result;
|
||||
|
||||
if (state->audio_out_idx > opts->delay)
|
||||
{
|
||||
// output synthesized speech to sound card
|
||||
{
|
||||
// output synthesized speech to sound card
|
||||
if(opts->audio_out_type == 2)
|
||||
{
|
||||
#ifdef USE_PORTAUDIO
|
||||
PaError err = paNoError;
|
||||
do
|
||||
{
|
||||
long available = Pa_GetStreamWriteAvailable( opts->audio_out_pa_stream );
|
||||
if(available < 0)
|
||||
err = available;
|
||||
//fprintf (stderr,"Frames available: %d\n", available);
|
||||
if( err != paNoError )
|
||||
break;
|
||||
if(available > SAMPLE_RATE_OUT * PA_LATENCY_OUT)
|
||||
{
|
||||
//It looks like this might not be needed for very small latencies. However, it's definitely needed for a bit larger ones.
|
||||
//When PA_LATENCY_OUT == 0.500 I get output buffer underruns if I don't use this. With PA_LATENCY_OUT <= 0.100 I don't see those happen.
|
||||
//But with PA_LATENCY_OUT < 0.100 I run the risk of choppy audio and stream errors.
|
||||
fprintf (stderr,"\nSyncing voice output stream\n");
|
||||
err = Pa_StopStream( opts->audio_out_pa_stream );
|
||||
if( err != paNoError )
|
||||
break;
|
||||
}
|
||||
|
||||
err = Pa_IsStreamActive( opts->audio_out_pa_stream );
|
||||
if(err == 0)
|
||||
{
|
||||
fprintf (stderr,"Start voice output stream\n");
|
||||
err = Pa_StartStream( opts->audio_out_pa_stream );
|
||||
}
|
||||
else if(err == 1)
|
||||
{
|
||||
err = paNoError;
|
||||
}
|
||||
if( err != paNoError )
|
||||
break;
|
||||
|
||||
err = Pa_WriteStream( opts->audio_out_pa_stream, (state->audio_out_buf_p - state->audio_out_idx), state->audio_out_idx );
|
||||
if( err != paNoError )
|
||||
break;
|
||||
} while(0);
|
||||
|
||||
if( err != paNoError )
|
||||
{
|
||||
fprintf (stderr, "An error occured while using the portaudio output stream\n" );
|
||||
fprintf (stderr, "Error number: %d\n", err );
|
||||
fprintf (stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
}
|
||||
|
||||
#endif
|
||||
//go F yourself PA
|
||||
}
|
||||
else
|
||||
if (opts->monitor_input_audio == 1){
|
||||
//pa_simple_flush(opts->pulse_raw_dev_in, NULL);
|
||||
//pa_simple_flush(opts->pulse_raw_dev_out, NULL);
|
||||
//state->pulse_raw_out_buffer = 0;
|
||||
//pa_simple_write(opts->pulse_raw_dev_out, (void*)&state->pulse_raw_out_buffer, 2, NULL);
|
||||
|
||||
}
|
||||
|
||||
//two slot audio testing, still need to seperate channels first internally, but this will play them out of different streams
|
||||
/*
|
||||
if(state->currentslot == 0 && opts->audio_in_type != 3)
|
||||
|
||||
if(state->currentslot == 0 && opts->audio_in_type != 3 && opts->dmr_stereo == 1)
|
||||
{
|
||||
pa_simple_write(opts->pulse_digi_dev_out, (state->audio_out_buf_p - state->audio_out_idx), (state->audio_out_idx * 2), NULL); //Yay! It works.
|
||||
}
|
||||
if(state->currentslot == 1 && opts->audio_in_type != 3)
|
||||
{
|
||||
pa_simple_write(opts->pulse_raw_dev_out, (state->audio_out_buf_p - state->audio_out_idx), (state->audio_out_idx * 2), NULL); //Yay! It works.
|
||||
//pa_simple_write(opts->pulse_raw_dev_out, (state->audio_out_buf_pR - state->audio_out_idxR), (state->audio_out_idxR * 2), NULL); //Yay! It works.
|
||||
state->audio_out_idx = 0;
|
||||
}
|
||||
|
||||
if (opts->audio_in_type == 3)
|
||||
//if input type is rtl dongle or no dmr stereo...do I need it this way still?
|
||||
if (opts->audio_in_type == 3 || opts->dmr_stereo == 0)
|
||||
{
|
||||
pa_simple_write(opts->pulse_digi_dev_out, (state->audio_out_buf_p - state->audio_out_idx), (state->audio_out_idx * 2), NULL); //Yay! It works.
|
||||
state->audio_out_idx = 0;
|
||||
}
|
||||
*/
|
||||
|
||||
pa_simple_write(opts->pulse_digi_dev_out, (state->audio_out_buf_p - state->audio_out_idx), (state->audio_out_idx * 2), NULL); //Yay! It works.
|
||||
state->audio_out_idx = 0;
|
||||
}
|
||||
|
||||
if (state->audio_out_idx2 >= 800000)
|
||||
{
|
||||
state->audio_out_float_buf_p = state->audio_out_float_buf + 100;
|
||||
state->audio_out_buf_p = state->audio_out_buf + 100;
|
||||
memset (state->audio_out_float_buf, 0, 100 * sizeof (float));
|
||||
memset (state->audio_out_buf, 0, 100 * sizeof (short));
|
||||
state->audio_out_idx2 = 0;
|
||||
}
|
||||
{
|
||||
state->audio_out_float_buf_p = state->audio_out_float_buf + 100;
|
||||
state->audio_out_buf_p = state->audio_out_buf + 100;
|
||||
memset (state->audio_out_float_buf, 0, 100 * sizeof (float));
|
||||
memset (state->audio_out_buf, 0, 100 * sizeof (short));
|
||||
state->audio_out_idx2 = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#ifdef USE_PORTAUDIO
|
||||
int getPADevice(char* dev, int input, PaStream** stream)
|
||||
void
|
||||
playSynthesizedVoiceR (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
int devnum = atoi(dev + 3);
|
||||
fprintf (stderr,"Using portaudio device %d.\n", devnum);
|
||||
ssize_t result;
|
||||
|
||||
PaError err;
|
||||
if (state->audio_out_idxR > opts->delay)
|
||||
{
|
||||
// output synthesized speech to sound card
|
||||
if(opts->audio_out_type == 2)
|
||||
{
|
||||
//go F yourself PA
|
||||
}
|
||||
else
|
||||
|
||||
int numDevices = Pa_GetDeviceCount();
|
||||
if( numDevices < 0 )
|
||||
{
|
||||
fprintf (stderr, "ERROR: Pa_GetDeviceCount returned 0x%x\n", numDevices );
|
||||
err = numDevices;
|
||||
goto error;
|
||||
}
|
||||
if( devnum >= numDevices)
|
||||
{
|
||||
fprintf (stderr, "ERROR: Requested device %d is larger than number of devices.\n", devnum );
|
||||
return(1);
|
||||
}
|
||||
//two slot audio testing, still need to seperate channels first internally, but this will play them out of different streams
|
||||
if(opts->dmr_stereo == 1) //state->currentslot == 1 && opts->audio_in_type != 3 && opts->dmr_stereo == 1
|
||||
{
|
||||
pa_simple_write(opts->pulse_digi_dev_outR, (state->audio_out_buf_pR - state->audio_out_idxR), (state->audio_out_idxR * 2), NULL); //Yay! It works.
|
||||
state->audio_out_idxR = 0;
|
||||
}
|
||||
}
|
||||
|
||||
const PaDeviceInfo *deviceInfo = Pa_GetDeviceInfo( devnum );
|
||||
|
||||
/* print device name */
|
||||
#ifdef WIN32
|
||||
{ /* Use wide char on windows, so we can show UTF-8 encoded device names */
|
||||
wchar_t wideName[MAX_PATH];
|
||||
MultiByteToWideChar(CP_UTF8, 0, deviceInfo->name, -1, wideName, MAX_PATH-1);
|
||||
wprintf ( L"Name = %s\n", wideName );
|
||||
}
|
||||
#else
|
||||
fprintf (stderr, "Name = %s\n", deviceInfo->name );
|
||||
#endif
|
||||
if((input == 1) && (deviceInfo->maxInputChannels == 0))
|
||||
{
|
||||
fprintf (stderr, "ERROR: Requested device %d is not an input device.\n", devnum );
|
||||
return(1);
|
||||
}
|
||||
if((input == 0) && (deviceInfo->maxOutputChannels == 0))
|
||||
{
|
||||
fprintf (stderr, "ERROR: Requested device %d is not an output device.\n", devnum );
|
||||
return(1);
|
||||
}
|
||||
|
||||
//Create stream parameters
|
||||
PaStreamParameters parameters;
|
||||
parameters.device = devnum;
|
||||
parameters.channelCount = 1; /* mono */
|
||||
parameters.sampleFormat = paInt16; //Shorts
|
||||
parameters.suggestedLatency = (input == 1) ? PA_LATENCY_IN : PA_LATENCY_OUT;
|
||||
parameters.hostApiSpecificStreamInfo = NULL;
|
||||
|
||||
//Open stream
|
||||
err = Pa_OpenStream(
|
||||
stream,
|
||||
(input == 1) ? ¶meters : NULL,
|
||||
(input == 0) ? ¶meters : NULL,
|
||||
(input == 1) ? SAMPLE_RATE_IN : SAMPLE_RATE_OUT,
|
||||
PA_FRAMES_PER_BUFFER,
|
||||
paClipOff,
|
||||
NULL /*callback*/,
|
||||
NULL );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
fprintf (stderr, "An error occured while initializing a portaudio stream\n" );
|
||||
fprintf (stderr, "Error number: %d\n", err );
|
||||
fprintf (stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
return err;
|
||||
if (state->audio_out_idx2R >= 800000)
|
||||
{
|
||||
state->audio_out_float_buf_pR = state->audio_out_float_bufR + 100;
|
||||
state->audio_out_buf_pR = state->audio_out_bufR + 100;
|
||||
memset (state->audio_out_float_bufR, 0, 100 * sizeof (float));
|
||||
memset (state->audio_out_bufR, 0, 100 * sizeof (short));
|
||||
state->audio_out_idx2R = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
openAudioOutDevice (dsd_opts * opts, int speed)
|
||||
{
|
||||
// get info of device/file
|
||||
/*
|
||||
if(strncmp(opts->audio_out_dev, "pulse", 5) == 0)
|
||||
{
|
||||
opts->audio_out_type == 0;
|
||||
}
|
||||
*/
|
||||
if(strncmp(opts->audio_out_dev, "pa:", 3) == 0)
|
||||
{
|
||||
opts->audio_out_type = 2;
|
||||
@@ -518,70 +513,6 @@ openAudioOutDevice (dsd_opts * opts, int speed)
|
||||
fprintf (stderr,"Error, %s is not a device. use -w filename for wav output.\n", opts->audio_out_dev);
|
||||
exit(1);
|
||||
}
|
||||
/*
|
||||
#ifdef SOLARIS
|
||||
sample_info_t aset, aget;
|
||||
|
||||
opts->audio_out_fd = open (opts->audio_out_dev, O_WRONLY);
|
||||
if (opts->audio_out_fd == -1)
|
||||
{
|
||||
fprintf (stderr,"Error, couldn't open %s\n", opts->audio_out_dev);
|
||||
//exit (1);
|
||||
}
|
||||
|
||||
// get current
|
||||
ioctl (opts->audio_out_fd, AUDIO_GETINFO, &aset);
|
||||
aset.record.sample_rate = speed;
|
||||
aset.play.sample_rate = speed;
|
||||
aset.record.channels = 1;
|
||||
aset.play.channels = 1;
|
||||
aset.record.precision = 16;
|
||||
aset.play.precision = 16;
|
||||
aset.record.encoding = AUDIO_ENCODING_LINEAR;
|
||||
aset.play.encoding = AUDIO_ENCODING_LINEAR;
|
||||
|
||||
if (ioctl (opts->audio_out_fd, AUDIO_SETINFO, &aset) == -1)
|
||||
{
|
||||
fprintf (stderr,"Error setting sample device parameters\n");
|
||||
exit (1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(BSD) && !defined(__APPLE__)
|
||||
|
||||
int fmt;
|
||||
|
||||
opts->audio_out_fd = open (opts->audio_out_dev, O_WRONLY);
|
||||
if (opts->audio_out_fd == -1)
|
||||
{
|
||||
fprintf (stderr,"Error, couldn't open %s\n", opts->audio_out_dev);
|
||||
opts->audio_out = 0;
|
||||
//exit(1);
|
||||
}
|
||||
|
||||
fmt = 0;
|
||||
if (ioctl (opts->audio_out_fd, SNDCTL_DSP_RESET) < 0)
|
||||
{
|
||||
fprintf (stderr,"ioctl reset error \n");
|
||||
}
|
||||
fmt = speed;
|
||||
if (ioctl (opts->audio_out_fd, SNDCTL_DSP_SPEED, &fmt) < 0)
|
||||
{
|
||||
fprintf (stderr,"ioctl speed error \n");
|
||||
}
|
||||
fmt = 0;
|
||||
if (ioctl (opts->audio_out_fd, SNDCTL_DSP_STEREO, &fmt) < 0)
|
||||
{
|
||||
fprintf (stderr,"ioctl stereo error \n");
|
||||
}
|
||||
fmt = AFMT_S16_LE;
|
||||
if (ioctl (opts->audio_out_fd, SNDCTL_DSP_SETFMT, &fmt) < 0)
|
||||
{
|
||||
fprintf (stderr,"ioctl setfmt error \n");
|
||||
}
|
||||
|
||||
#endif
|
||||
*/
|
||||
}
|
||||
fprintf (stderr,"Audio Out Device: %s\n", opts->audio_out_dev);
|
||||
}
|
||||
@@ -661,90 +592,8 @@ openAudioInDevice (dsd_opts * opts)
|
||||
{
|
||||
// this is a device, use old handling, pulse audio now
|
||||
opts->audio_in_type = 0;
|
||||
/*
|
||||
#ifdef SOLARIS
|
||||
sample_info_t aset, aget;
|
||||
int rgain;
|
||||
|
||||
rgain = 64;
|
||||
|
||||
if (opts->split == 1)
|
||||
{
|
||||
opts->audio_in_fd = open (opts->audio_in_dev, O_RDONLY);
|
||||
}
|
||||
else
|
||||
{
|
||||
opts->audio_in_fd = open (opts->audio_in_dev, O_RDWR);
|
||||
}
|
||||
if (opts->audio_in_fd == -1)
|
||||
{
|
||||
fprintf (stderr,"Error, couldn't open %s\n", opts->audio_in_dev);
|
||||
//exit(1);
|
||||
}
|
||||
|
||||
// get current
|
||||
ioctl (opts->audio_in_fd, AUDIO_GETINFO, &aset);
|
||||
|
||||
aset.record.sample_rate = SAMPLE_RATE_IN;
|
||||
aset.play.sample_rate = SAMPLE_RATE_IN;
|
||||
aset.record.channels = 1;
|
||||
aset.play.channels = 1;
|
||||
aset.record.precision = 16;
|
||||
aset.play.precision = 16;
|
||||
aset.record.encoding = AUDIO_ENCODING_LINEAR;
|
||||
aset.play.encoding = AUDIO_ENCODING_LINEAR;
|
||||
aset.record.port = AUDIO_LINE_IN;
|
||||
aset.record.gain = rgain;
|
||||
|
||||
if (ioctl (opts->audio_in_fd, AUDIO_SETINFO, &aset) == -1)
|
||||
{
|
||||
fprintf (stderr,"Error setting sample device parameters\n");
|
||||
exit (1);
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
/*
|
||||
#if defined(BSD) && !defined(__APPLE__)
|
||||
int fmt;
|
||||
|
||||
if (opts->split == 1)
|
||||
{
|
||||
opts->audio_in_fd = open (opts->audio_in_dev, O_RDONLY);
|
||||
}
|
||||
else
|
||||
{
|
||||
opts->audio_in_fd = open (opts->audio_in_dev, O_RDWR);
|
||||
}
|
||||
|
||||
if (opts->audio_in_fd == -1)
|
||||
{
|
||||
fprintf (stderr,"Error, couldn't open %s\n", opts->audio_in_dev);
|
||||
opts->audio_out = 0;
|
||||
}
|
||||
|
||||
fmt = 0;
|
||||
if (ioctl (opts->audio_in_fd, SNDCTL_DSP_RESET) < 0)
|
||||
{
|
||||
fprintf (stderr,"ioctl reset error \n");
|
||||
}
|
||||
fmt = SAMPLE_RATE_IN;
|
||||
if (ioctl (opts->audio_in_fd, SNDCTL_DSP_SPEED, &fmt) < 0)
|
||||
{
|
||||
fprintf (stderr,"ioctl speed error \n");
|
||||
}
|
||||
fmt = 0;
|
||||
if (ioctl (opts->audio_in_fd, SNDCTL_DSP_STEREO, &fmt) < 0)
|
||||
{
|
||||
fprintf (stderr,"ioctl stereo error \n");
|
||||
}
|
||||
fmt = AFMT_S16_LE;
|
||||
if (ioctl (opts->audio_in_fd, SNDCTL_DSP_SETFMT, &fmt) < 0)
|
||||
{
|
||||
fprintf (stderr,"ioctl setfmt error \n");
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (opts->split == 1)
|
||||
|
||||
@@ -185,9 +185,16 @@ use_symbol (dsd_opts* opts, dsd_state* state, int symbol)
|
||||
}
|
||||
|
||||
if (state->dibit_buf_p > state->dibit_buf + 900000)
|
||||
{
|
||||
state->dibit_buf_p = state->dibit_buf + 200;
|
||||
}
|
||||
{
|
||||
state->dibit_buf_p = state->dibit_buf + 200;
|
||||
}
|
||||
|
||||
//dmr buffer
|
||||
if (state->dmr_payload_p > state->dmr_payload_buf + 900000)
|
||||
{
|
||||
state->dmr_payload_p = state->dmr_payload_buf + 200;
|
||||
}
|
||||
//dmr buffer end
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -211,6 +218,7 @@ invert_dibit(int dibit)
|
||||
}
|
||||
|
||||
static int digitize (dsd_opts* opts, dsd_state* state, int symbol)
|
||||
//int digitize (dsd_opts* opts, dsd_state* state, int symbol)
|
||||
{
|
||||
// determine dibit state
|
||||
if ((state->synctype == 6) || (state->synctype == 14)|| (state->synctype == 18))
|
||||
@@ -252,8 +260,10 @@ static int digitize (dsd_opts* opts, dsd_state* state, int symbol)
|
||||
return (0); // +1
|
||||
}
|
||||
}
|
||||
|
||||
else if ((state->synctype == 1) || (state->synctype == 3) || (state->synctype == 5) ||
|
||||
(state->synctype == 9) || (state->synctype == 11) || (state->synctype == 13) || (state->synctype == 17))
|
||||
(state->synctype == 9) || (state->synctype == 11) || (state->synctype == 13) ||
|
||||
(state->synctype == 17) )
|
||||
|
||||
{
|
||||
// 1 -P25p1
|
||||
@@ -263,7 +273,6 @@ static int digitize (dsd_opts* opts, dsd_state* state, int symbol)
|
||||
// 11 -DMR (inverted signal voice frame)
|
||||
// 13 -DMR (inverted signal data frame)
|
||||
// 17 -NXDN (inverted data frame)
|
||||
//
|
||||
|
||||
int valid;
|
||||
int dibit;
|
||||
@@ -361,64 +370,12 @@ static int digitize (dsd_opts* opts, dsd_state* state, int symbol)
|
||||
}
|
||||
|
||||
state->last_dibit = dibit;
|
||||
//test loading up a shift register and printing it to stderr
|
||||
//di-bit shift register for hex values
|
||||
//check for which dibit is equal to which half-nibble
|
||||
if (dibit == 0){state->hexbuf = 0x0;} //+1
|
||||
if (dibit == 1){state->hexbuf = 0x1;} //+3
|
||||
if (dibit == 2){state->hexbuf = 0x2;} //-1
|
||||
if (dibit == 3){state->hexbuf = 0x3;} //-3
|
||||
state->sr_0 = (state->sr_0 << 2) | (state->sr_1 >> 62);
|
||||
state->sr_1 = (state->sr_1 << 2) | (state->sr_2 >> 62);
|
||||
state->sr_2 = (state->sr_2 << 2) | (state->sr_3 >> 62);
|
||||
state->sr_3 = (state->sr_3 << 2) | (state->sr_4 >> 62);
|
||||
state->sr_4 = (state->sr_4 << 2) | (state->sr_5 >> 62);
|
||||
state->sr_5 = (state->sr_5 << 2) | (state->sr_6 >> 62);
|
||||
state->sr_6 = state->sr_6 << 2;
|
||||
state->sr_6 |= state->hexbuf;
|
||||
if (1 == 2) //disable this later on
|
||||
{
|
||||
fprintf (stderr, "\nsr_0 = %16llX \n", state->sr_0);
|
||||
fprintf (stderr, "sr_1 = %16llX \n", state->sr_1);
|
||||
fprintf (stderr, "sr_2 = %16llX \n", state->sr_2);
|
||||
fprintf (stderr, "sr_3 = %16llX \n", state->sr_3);
|
||||
fprintf (stderr, "sr_4 = %16llX \n", state->sr_4);
|
||||
fprintf (stderr, "sr_5 = %16llX \n", state->sr_5);
|
||||
fprintf (stderr, "sr_6 = %16llX \n", state->sr_6);
|
||||
/*
|
||||
printw ("sr_0 = %16llX \n", sr_0);
|
||||
printw ("sr_1 = %16llX \n", sr_1);
|
||||
printw ("sr_2 = %16llX \n", sr_2);
|
||||
printw ("sr_3 = %16llX \n", sr_3);
|
||||
printw ("sr_4 = %16llX \n", sr_4);
|
||||
printw ("sr_5 = %16llX \n", sr_5);
|
||||
printw ("sr_6 = %16llX \n", sr_6);
|
||||
*/
|
||||
}
|
||||
|
||||
if ( state->sr_5 & 0xFFFFF == 0xDDF5D) //disable this later on
|
||||
{
|
||||
fprintf (stderr, "\nsr_0 = %16llX \n", state->sr_0);
|
||||
fprintf (stderr, "sr_1 = %16llX \n", state->sr_1);
|
||||
fprintf (stderr, "sr_2 = %16llX \n", state->sr_2);
|
||||
fprintf (stderr, "sr_3 = %16llX \n", state->sr_3);
|
||||
fprintf (stderr, "sr_4 = %16llX \n", state->sr_4);
|
||||
fprintf (stderr, "sr_5 = %16llX \n", state->sr_5);
|
||||
fprintf (stderr, "sr_6 = %16llX \n", state->sr_6);
|
||||
/*
|
||||
printw ("sr_0 = %16llX \n", sr_0);
|
||||
printw ("sr_1 = %16llX \n", sr_1);
|
||||
printw ("sr_2 = %16llX \n", sr_2);
|
||||
printw ("sr_3 = %16llX \n", sr_3);
|
||||
printw ("sr_4 = %16llX \n", sr_4);
|
||||
printw ("sr_5 = %16llX \n", sr_5);
|
||||
printw ("sr_6 = %16llX \n", sr_6);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
*state->dibit_buf_p = dibit;
|
||||
state->dibit_buf_p++;
|
||||
//dmr buffer
|
||||
*state->dmr_payload_p = dibit;
|
||||
state->dmr_payload_p++;
|
||||
//dmr buffer end
|
||||
return dibit;
|
||||
}
|
||||
}
|
||||
@@ -447,9 +404,7 @@ get_dibit_and_analog_signal (dsd_opts* opts, dsd_state* state, int* out_analog_s
|
||||
|
||||
//
|
||||
state->sbuf[state->sidx] = symbol;
|
||||
//
|
||||
//state->pulse_raw_out_buffer = symbol;
|
||||
//
|
||||
|
||||
if (out_analog_signal != NULL)
|
||||
{
|
||||
*out_analog_signal = symbol;
|
||||
|
||||
@@ -76,7 +76,6 @@ saveAmbe2450Data (dsd_opts * opts, dsd_state * state, char *ambe_d)
|
||||
for (i = 0; i < 7; i++) //using 7 seems to break older amb files where it was 6, need to test 7 on 7 some more
|
||||
{
|
||||
b = 0;
|
||||
|
||||
for (j = 0; j < 8; j++)
|
||||
{
|
||||
b = b << 1;
|
||||
|
||||
@@ -35,14 +35,20 @@ printFrameInfo (dsd_opts * opts, dsd_state * state)
|
||||
}
|
||||
if (state->nac != 0)
|
||||
{
|
||||
fprintf (stderr, "%s", KCYN);
|
||||
fprintf (stderr,"nac: [%4X] ", state->nac);
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
}
|
||||
|
||||
if (opts->verbose > 1)
|
||||
{
|
||||
fprintf (stderr, "%s", KGRN);
|
||||
fprintf (stderr,"src: [%8i] ", state->lastsrc);
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
}
|
||||
fprintf (stderr, "%s", KGRN);
|
||||
fprintf (stderr,"tg: [%5i] ", state->lasttg);
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -168,8 +174,8 @@ processFrame (dsd_opts * opts, dsd_state * state)
|
||||
processDSTAR_HD (opts, state);
|
||||
return;
|
||||
}
|
||||
|
||||
else if ((state->synctype >= 10) && (state->synctype <= 13))
|
||||
//Start DMR Types
|
||||
else if ((state->synctype >= 10) && (state->synctype <= 13) || (state->synctype == 32) || (state->synctype == 33) || (state->synctype == 34) ) //32-34 DMR MS and RC
|
||||
{
|
||||
state->nac = 0;
|
||||
state->lastsrc = 0;
|
||||
@@ -182,21 +188,63 @@ processFrame (dsd_opts * opts, dsd_state * state)
|
||||
//fprintf (stderr,"inlvl: %2i%% ", level);
|
||||
}
|
||||
}
|
||||
if ((state->synctype == 11) || (state->synctype == 12))
|
||||
if ( (state->synctype == 11) || (state->synctype == 12) || (state->synctype == 32) ) //DMR Voice Modes
|
||||
{
|
||||
if ((opts->mbe_out_dir[0] != 0) && (opts->mbe_out_f == NULL))
|
||||
if ((opts->mbe_out_dir[0] != 0) && (opts->mbe_out_f == NULL) && opts->dmr_stereo == 0)
|
||||
{
|
||||
openMbeOutFile (opts, state);
|
||||
}
|
||||
sprintf (state->fsubtype, " VOICE ");
|
||||
processDMRvoice (opts, state);
|
||||
if (opts->dmr_stereo == 0 && state->synctype < 32) // -T option for DMR (TDMA) stereo
|
||||
{
|
||||
processDMRvoice (opts, state);
|
||||
}
|
||||
if (opts->dmr_stereo == 0 && state->synctype == 32)
|
||||
{
|
||||
fprintf (stderr, "%s", KRED);
|
||||
fprintf (stderr, "Please use the -T option to handle MS Mode with DMR Stereo TDMA Handling\n");
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
}
|
||||
if (opts->dmr_stereo == 1)
|
||||
{
|
||||
state->dmr_stereo = 1; //set the state to 1 when handling pure voice frames
|
||||
if (state->synctype > 31 )
|
||||
{
|
||||
dmrMSBootstrap (opts, state); //bootstrap into MS Bootstrap (voice only)
|
||||
}
|
||||
else dmrBSBootstrap (opts, state); //bootstrap into BS Bootstrap
|
||||
}
|
||||
}
|
||||
else if ( (state->synctype == 33) || (state->synctype == 34) ) //MS Data and RC data
|
||||
{
|
||||
if (opts->dmr_stereo == 0)
|
||||
{
|
||||
closeMbeOutFile (opts, state);
|
||||
state->err_str[0] = 0;
|
||||
fprintf (stderr, "%s", KRED);
|
||||
fprintf (stderr, "Please use the -T option to handle MS Mode with DMR Stereo TDMA Handling\n");
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
}
|
||||
if (opts->dmr_stereo == 1)
|
||||
{
|
||||
dmrMSData (opts, state);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (opts->dmr_stereo == 0)
|
||||
{
|
||||
closeMbeOutFile (opts, state);
|
||||
state->err_str[0] = 0;
|
||||
processDMRdata (opts, state);
|
||||
}
|
||||
//switch dmr_stereo to 0 when handling BS data frame syncs with processDMRdata
|
||||
if (opts->dmr_stereo == 1)
|
||||
{
|
||||
state->dmr_stereo = 0; //set the state to zero for handling pure data frames
|
||||
processDMRdata (opts, state);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if ((state->synctype >= 2) && (state->synctype <= 5))
|
||||
@@ -244,7 +292,20 @@ processFrame (dsd_opts * opts, dsd_state * state)
|
||||
processProVoice (opts, state);
|
||||
return;
|
||||
}
|
||||
//LEH dPMR
|
||||
//ysf
|
||||
else if ((state->synctype == 30) || (state->synctype == 31))
|
||||
{
|
||||
//Do stuff
|
||||
//fprintf(stderr, "YSF Sync! \n");
|
||||
if ((opts->mbe_out_dir[0] != 0) && (opts->mbe_out_f == NULL))
|
||||
{
|
||||
//openMbeOutFile (opts, state);
|
||||
}
|
||||
//sprintf(state->fsubtype, " VOICE ");
|
||||
processYSF(opts, state);
|
||||
return;
|
||||
}
|
||||
//dPMR
|
||||
else if ((state->synctype == 20) || (state->synctype == 24))
|
||||
{
|
||||
/* dPMR Frame Sync 1 */
|
||||
@@ -255,7 +316,6 @@ processFrame (dsd_opts * opts, dsd_state * state)
|
||||
/* dPMR Frame Sync 2 */
|
||||
fprintf(stderr, "dPMR Frame Sync 2 ");
|
||||
|
||||
//state->rf_mod = GFSK_MODE;
|
||||
state->nac = 0;
|
||||
state->lastsrc = 0;
|
||||
state->lasttg = 0;
|
||||
@@ -264,7 +324,6 @@ processFrame (dsd_opts * opts, dsd_state * state)
|
||||
if (opts->verbose > 0)
|
||||
{
|
||||
level = (int) state->max / 164;
|
||||
//fprintf(stderr, "inlvl: %2i%% ", level);
|
||||
}
|
||||
}
|
||||
state->nac = 0;
|
||||
@@ -290,7 +349,7 @@ processFrame (dsd_opts * opts, dsd_state * state)
|
||||
fprintf(stderr, "dPMR Frame Sync 4 ");
|
||||
}
|
||||
//dPMR
|
||||
else
|
||||
else //P25
|
||||
{
|
||||
// Read the NAC, 12 bits
|
||||
j = 0;
|
||||
|
||||
@@ -17,9 +17,8 @@
|
||||
|
||||
#include "dsd.h"
|
||||
#include <locale.h>
|
||||
//#include <ncurses.h>
|
||||
|
||||
//borrowed from LEH for 'improved NXDN sync detection'
|
||||
//borrowed from DSDcc for 'improved NXDN sync detection'
|
||||
int strncmperr(const char *s1, const char *s2, size_t size, int MaxErr)
|
||||
{
|
||||
int Compare = -1;
|
||||
@@ -50,7 +49,6 @@ int strncmperr(const char *s1, const char *s2, size_t size, int MaxErr)
|
||||
|
||||
return Compare;
|
||||
} /* End strncmperr() */
|
||||
//end LEH
|
||||
|
||||
time_t now;
|
||||
char * getTime(void) //get pretty hh:mm:ss timestamp
|
||||
@@ -140,15 +138,21 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
* 26 = -dPMR Frame Sync 3
|
||||
* 27 = -dPMR Frame Sync 4
|
||||
* 28 = +NXDN (sync only)
|
||||
* 29 = -NXDN (sync only
|
||||
* 29 = -NXDN (sync only)
|
||||
* 30 = +YSF
|
||||
* 31 = -YSF
|
||||
* 32 = DMR MS Voice
|
||||
* 33 = DMR MS Data
|
||||
* 34 = DMR RC Data
|
||||
*/
|
||||
|
||||
|
||||
int i, j, t, o, dibit, sync, symbol, synctest_pos, lastt;
|
||||
char synctest[25];
|
||||
char synctest12[13]; //LEH DPMR
|
||||
char synctest12[13]; //dPMR
|
||||
char synctest18[19];
|
||||
char synctest32[33];
|
||||
char synctest20[21]; //YSF
|
||||
char modulation[8];
|
||||
char *synctest_p;
|
||||
char synctest_buf[10240];
|
||||
@@ -169,6 +173,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
synctest12[12] = 0;
|
||||
synctest18[18] = 0;
|
||||
synctest32[32] = 0;
|
||||
synctest20[20] = 0;
|
||||
synctest_pos = 0;
|
||||
synctest_p = synctest_buf + 10;
|
||||
sync = 0;
|
||||
@@ -246,9 +251,9 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
}
|
||||
|
||||
if (state->dibit_buf_p > state->dibit_buf + 900000)
|
||||
{
|
||||
state->dibit_buf_p = state->dibit_buf + 200;
|
||||
}
|
||||
{
|
||||
state->dibit_buf_p = state->dibit_buf + 200;
|
||||
}
|
||||
|
||||
//determine dibit state
|
||||
if (symbol > 0)
|
||||
@@ -264,6 +269,49 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
dibit = 51; // '3'
|
||||
}
|
||||
|
||||
//digitize test for storing dibits in buffer correctly for dmr recovery
|
||||
|
||||
if (state->dmr_payload_p > state->dmr_payload_buf + 900000)
|
||||
{
|
||||
state->dmr_payload_p = state->dmr_payload_buf + 200;
|
||||
}
|
||||
|
||||
int valid;
|
||||
//running estimate_symbol causes an issue with P25 syncing properly
|
||||
if (opts->frame_p25p1 != 1)
|
||||
{
|
||||
valid = estimate_symbol(state->rf_mod, &(state->p25_heuristics), state->last_dibit, symbol, &dibit);
|
||||
}
|
||||
|
||||
if (opts->frame_dmr == 1 && valid == 0) //opts->dmr_stereo
|
||||
{
|
||||
if (symbol > state->center)
|
||||
{
|
||||
if (symbol > state->umid)
|
||||
{
|
||||
*state->dmr_payload_p = 1; // +3
|
||||
}
|
||||
else
|
||||
{
|
||||
*state->dmr_payload_p = 0; // +1
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (symbol < state->lmid)
|
||||
{
|
||||
*state->dmr_payload_p = 3; // -3
|
||||
}
|
||||
else
|
||||
{
|
||||
*state->dmr_payload_p = 2; // -1
|
||||
}
|
||||
}
|
||||
state->dmr_payload_p++;
|
||||
|
||||
}
|
||||
// end digitize and dmr buffer testing
|
||||
|
||||
*synctest_p = dibit;
|
||||
if (t >= 18)
|
||||
{
|
||||
@@ -502,7 +550,53 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
}
|
||||
}
|
||||
}
|
||||
//YSF sync
|
||||
strncpy(synctest20, (synctest_p - 19), 20); //double check make sure this is right
|
||||
if(opts->frame_ysf == 1) //(opts->frame_ysf == 1
|
||||
{
|
||||
if (0 == 0) //opts->inverted_ysf == 0
|
||||
{
|
||||
if (strcmp(synctest20, FUSION_SYNC) == 0)
|
||||
{
|
||||
state->carrier = 1;
|
||||
state->offset = synctest_pos;
|
||||
state->max = ((state->max) + lmax) / 2;
|
||||
state->min = ((state->min) + lmin) / 2;
|
||||
fprintf (stderr, "\nYSF FUSION SYNC \n");
|
||||
opts->inverted_ysf = 0; //should we set this here?
|
||||
state->lastsynctype = 30;
|
||||
if ( opts->monitor_input_audio == 1)
|
||||
{
|
||||
|
||||
pa_simple_flush(opts->pulse_raw_dev_out, NULL);
|
||||
}
|
||||
return (30);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(opts->frame_ysf == 1) //(opts->frame_ysf == 1
|
||||
{
|
||||
if (0 == 0) //opts->inverted_ysf == 1
|
||||
{
|
||||
if (strcmp(synctest20, INV_FUSION_SYNC) == 0)
|
||||
{
|
||||
state->carrier = 1;
|
||||
state->offset = synctest_pos;
|
||||
state->max = ((state->max) + lmax) / 2;
|
||||
state->min = ((state->min) + lmin) / 2;
|
||||
fprintf (stderr, "\nINVERTED YSF FUSION SYNC \n");
|
||||
opts->inverted_ysf = 1; //should we set this here?
|
||||
state->lastsynctype = 31;
|
||||
if ( opts->monitor_input_audio == 1)
|
||||
{
|
||||
|
||||
pa_simple_flush(opts->pulse_raw_dev_out, NULL);
|
||||
}
|
||||
return (31);
|
||||
}
|
||||
}
|
||||
}
|
||||
//end YSF sync
|
||||
//dPMR sync
|
||||
strncpy(synctest, (synctest_p - 23), 24);
|
||||
strncpy(synctest12, (synctest_p - 11), 12);
|
||||
@@ -512,7 +606,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
if(strcmp(synctest, DPMR_FRAME_SYNC_1) == 0)
|
||||
{
|
||||
fprintf (stderr, "+dPMR FS1\n");
|
||||
//fprintf (stderr, "+dPMR FS1\n");
|
||||
}
|
||||
if(strcmp(synctest12, DPMR_FRAME_SYNC_2) == 0)
|
||||
{
|
||||
@@ -528,22 +622,26 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
printFrameSync (opts, state, "+dPMR ", synctest_pos + 1, modulation);
|
||||
}
|
||||
state->lastsynctype = 21;
|
||||
if ( opts->monitor_input_audio == 1)
|
||||
{
|
||||
pa_simple_flush(opts->pulse_raw_dev_out, NULL);
|
||||
}
|
||||
return (21);
|
||||
}
|
||||
if(strcmp(synctest12, DPMR_FRAME_SYNC_3) == 0)
|
||||
{
|
||||
fprintf (stderr, "+dPMR FS3 \n");
|
||||
//fprintf (stderr, "+dPMR FS3 \n");
|
||||
}
|
||||
if(strcmp(synctest, DPMR_FRAME_SYNC_4) == 0)
|
||||
{
|
||||
fprintf (stderr, "+dPMR FS4 \n");
|
||||
//fprintf (stderr, "+dPMR FS4 \n");
|
||||
}
|
||||
}
|
||||
if (opts->inverted_dpmr == 1)
|
||||
{
|
||||
if(strcmp(synctest, INV_DPMR_FRAME_SYNC_1) == 0)
|
||||
{
|
||||
fprintf (stderr, "-dPMR FS1 \n");
|
||||
//fprintf (stderr, "-dPMR FS1 \n");
|
||||
}
|
||||
if(strcmp(synctest12, INV_DPMR_FRAME_SYNC_2) == 0)
|
||||
{
|
||||
@@ -560,15 +658,19 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
}
|
||||
|
||||
state->lastsynctype = 25;
|
||||
if ( opts->monitor_input_audio == 1)
|
||||
{
|
||||
pa_simple_flush(opts->pulse_raw_dev_out, NULL);
|
||||
}
|
||||
return (25);
|
||||
}
|
||||
if(strcmp(synctest12, INV_DPMR_FRAME_SYNC_3) == 0)
|
||||
{
|
||||
fprintf (stderr, "-dPMR FS3 \n");
|
||||
//fprintf (stderr, "-dPMR FS3 \n");
|
||||
}
|
||||
if(strcmp(synctest, INV_DPMR_FRAME_SYNC_4) == 0)
|
||||
{
|
||||
fprintf (stderr, "-dPMR FS4 \n");
|
||||
//fprintf (stderr, "-dPMR FS4 \n");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -576,7 +678,97 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
//New DMR Sync
|
||||
if (opts->frame_dmr == 1)
|
||||
{
|
||||
if ((strcmp (synctest, DMR_MS_DATA_SYNC) == 0) || (strcmp (synctest, DMR_BS_DATA_SYNC) == 0))
|
||||
|
||||
if(strcmp (synctest, DMR_MS_DATA_SYNC) == 0)
|
||||
{
|
||||
state->carrier = 1;
|
||||
state->offset = synctest_pos;
|
||||
state->max = ((state->max) + lmax) / 2;
|
||||
state->min = ((state->min) + lmin) / 2;
|
||||
//state->directmode = 0;
|
||||
//fprintf (stderr, "DMR MS Data");
|
||||
if (0 == 0) //opts->inverted_dmr
|
||||
{
|
||||
// data frame
|
||||
sprintf(state->ftype, "DMR MS");
|
||||
if (opts->errorbars == 1)
|
||||
{
|
||||
//printFrameSync (opts, state, "+DMR MS Data", synctest_pos + 1, modulation);
|
||||
}
|
||||
if (state->lastsynctype != 33) //33
|
||||
{
|
||||
//state->firstframe = 1;
|
||||
}
|
||||
state->lastsynctype = 33; //33
|
||||
if ( opts->monitor_input_audio == 1)
|
||||
{
|
||||
pa_simple_flush(opts->pulse_raw_dev_out, NULL);
|
||||
}
|
||||
return (33); //33
|
||||
}
|
||||
}
|
||||
//not sure if this should be here, RC data should only be present in vc6?
|
||||
if(strcmp (synctest, DMR_RC_DATA_SYNC) == 0)
|
||||
{
|
||||
state->carrier = 1;
|
||||
state->offset = synctest_pos;
|
||||
state->max = ((state->max) + lmax) / 2;
|
||||
state->min = ((state->min) + lmin) / 2;
|
||||
//state->directmode = 0;
|
||||
//fprintf (stderr, "DMR RC DATA\n");
|
||||
state->dmr_ms_rc == 1; //set flag for RC data, then process accordingly and reset back to 0 afterwards
|
||||
if (0 == 0) //opts->inverted_dmr
|
||||
{
|
||||
// voice frame
|
||||
sprintf(state->ftype, "DMR RC");
|
||||
if (opts->errorbars == 1)
|
||||
{
|
||||
//printFrameSync (opts, state, "+DMR RC Data", synctest_pos + 1, modulation);
|
||||
}
|
||||
if (state->lastsynctype != 34)
|
||||
{
|
||||
//state->firstframe = 1;
|
||||
}
|
||||
state->lastsynctype = 34;
|
||||
if ( opts->monitor_input_audio == 1)
|
||||
{
|
||||
pa_simple_flush(opts->pulse_raw_dev_out, NULL);
|
||||
}
|
||||
return (34);
|
||||
}
|
||||
}
|
||||
|
||||
if(strcmp (synctest, DMR_MS_VOICE_SYNC) == 0)
|
||||
{
|
||||
state->carrier = 1;
|
||||
state->offset = synctest_pos;
|
||||
state->max = ((state->max) + lmax) / 2;
|
||||
state->min = ((state->min) + lmin) / 2;
|
||||
//state->directmode = 0;
|
||||
//fprintf (stderr, "DMR MS VOICE\n");
|
||||
if (0 == 0) //opts->inverted_dmr
|
||||
{
|
||||
// voice frame
|
||||
sprintf(state->ftype, "DMR MS");
|
||||
if (opts->errorbars == 1)
|
||||
{
|
||||
//printFrameSync (opts, state, "+DMR MS Voice", synctest_pos + 1, modulation);
|
||||
}
|
||||
if (state->lastsynctype != 32)
|
||||
{
|
||||
//state->firstframe = 1;
|
||||
}
|
||||
state->lastsynctype = 32;
|
||||
if ( opts->monitor_input_audio == 1)
|
||||
{
|
||||
pa_simple_flush(opts->pulse_raw_dev_out, NULL);
|
||||
}
|
||||
return (32);
|
||||
}
|
||||
}
|
||||
|
||||
//if ((strcmp (synctest, DMR_MS_DATA_SYNC) == 0) || (strcmp (synctest, DMR_BS_DATA_SYNC) == 0))
|
||||
if (strcmp (synctest, DMR_BS_DATA_SYNC) == 0)
|
||||
{
|
||||
state->carrier = 1;
|
||||
state->offset = synctest_pos;
|
||||
@@ -594,7 +786,6 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
state->lastsynctype = 10;
|
||||
if ( opts->monitor_input_audio == 1)
|
||||
{
|
||||
//pa_simple_drain(opts->pulse_raw_dev_out, NULL);
|
||||
pa_simple_flush(opts->pulse_raw_dev_out, NULL);
|
||||
}
|
||||
return (10);
|
||||
@@ -614,7 +805,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
state->lastsynctype = 11;
|
||||
if ( opts->monitor_input_audio == 1)
|
||||
{
|
||||
pa_simple_drain(opts->pulse_raw_dev_out, NULL);
|
||||
pa_simple_flush(opts->pulse_raw_dev_out, NULL);
|
||||
}
|
||||
return (11);
|
||||
}
|
||||
@@ -638,7 +829,6 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
state->lastsynctype = 10;
|
||||
if ( opts->monitor_input_audio == 1)
|
||||
{
|
||||
//pa_simple_drain(opts->pulse_raw_dev_out, NULL);
|
||||
pa_simple_flush(opts->pulse_raw_dev_out, NULL);
|
||||
}
|
||||
return (10);
|
||||
@@ -649,7 +839,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
sprintf(state->ftype, "DMR ");
|
||||
if (opts->errorbars == 1)
|
||||
{
|
||||
printFrameSync (opts, state, "-DMR ", synctest_pos + 1, modulation);
|
||||
//printFrameSync (opts, state, "-DMR ", synctest_pos + 1, modulation);
|
||||
}
|
||||
if (state->lastsynctype != 11)
|
||||
{
|
||||
@@ -658,7 +848,6 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
state->lastsynctype = 11;
|
||||
if ( opts->monitor_input_audio == 1)
|
||||
{
|
||||
//pa_simple_drain(opts->pulse_raw_dev_out, NULL);
|
||||
pa_simple_flush(opts->pulse_raw_dev_out, NULL);
|
||||
}
|
||||
return (11);
|
||||
@@ -678,12 +867,11 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
sprintf(state->ftype, "DMR ");
|
||||
if (opts->errorbars == 1)
|
||||
{
|
||||
printFrameSync (opts, state, "+DMR ", synctest_pos + 1, modulation);
|
||||
//printFrameSync (opts, state, "+DMR ", synctest_pos + 1, modulation);
|
||||
}
|
||||
state->lastsynctype = 10;
|
||||
if ( opts->monitor_input_audio == 1)
|
||||
{
|
||||
//pa_simple_drain(opts->pulse_raw_dev_out, NULL);
|
||||
pa_simple_flush(opts->pulse_raw_dev_out, NULL);
|
||||
}
|
||||
return (10);
|
||||
@@ -694,7 +882,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
sprintf(state->ftype, "DMR ");
|
||||
if (opts->errorbars == 1)
|
||||
{
|
||||
printFrameSync (opts, state, "-DMR ", synctest_pos + 1, modulation);
|
||||
//printFrameSync (opts, state, "-DMR ", synctest_pos + 1, modulation);
|
||||
}
|
||||
if (state->lastsynctype != 11)
|
||||
{
|
||||
@@ -703,13 +891,14 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
state->lastsynctype = 11;
|
||||
if ( opts->monitor_input_audio == 1)
|
||||
{
|
||||
//pa_simple_drain(opts->pulse_raw_dev_out, NULL);
|
||||
|
||||
pa_simple_flush(opts->pulse_raw_dev_out, NULL);
|
||||
}
|
||||
return (11);
|
||||
}
|
||||
} /* End if(strcmp (synctest, DMR_DIRECT_MODE_TS2_DATA_SYNC) == 0) */
|
||||
if((strcmp (synctest, DMR_MS_VOICE_SYNC) == 0) || (strcmp (synctest, DMR_BS_VOICE_SYNC) == 0))
|
||||
//if((strcmp (synctest, DMR_MS_VOICE_SYNC) == 0) || (strcmp (synctest, DMR_BS_VOICE_SYNC) == 0))
|
||||
if(strcmp (synctest, DMR_BS_VOICE_SYNC) == 0)
|
||||
{
|
||||
state->carrier = 1;
|
||||
state->offset = synctest_pos;
|
||||
@@ -729,8 +918,13 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
state->firstframe = 1;
|
||||
}
|
||||
state->lastsynctype = 12;
|
||||
if ( opts->monitor_input_audio == 1)
|
||||
{
|
||||
pa_simple_flush(opts->pulse_raw_dev_out, NULL);
|
||||
}
|
||||
return (12);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
// inverted data frame
|
||||
@@ -742,7 +936,6 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
state->lastsynctype = 13;
|
||||
if ( opts->monitor_input_audio == 1)
|
||||
{
|
||||
//pa_simple_drain(opts->pulse_raw_dev_out, NULL);
|
||||
pa_simple_flush(opts->pulse_raw_dev_out, NULL);
|
||||
}
|
||||
return (13);
|
||||
@@ -771,7 +964,6 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
state->lastsynctype = 12;
|
||||
if ( opts->monitor_input_audio == 1)
|
||||
{
|
||||
//pa_simple_drain(opts->pulse_raw_dev_out, NULL);
|
||||
pa_simple_flush(opts->pulse_raw_dev_out, NULL);
|
||||
}
|
||||
return (12);
|
||||
@@ -811,7 +1003,6 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
state->lastsynctype = 12;
|
||||
if ( opts->monitor_input_audio == 1)
|
||||
{
|
||||
//pa_simple_drain(opts->pulse_raw_dev_out, NULL);
|
||||
pa_simple_flush(opts->pulse_raw_dev_out, NULL);
|
||||
}
|
||||
return (12);
|
||||
@@ -827,7 +1018,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
state->lastsynctype = 13;
|
||||
if ( opts->monitor_input_audio == 1)
|
||||
{
|
||||
//pa_simple_drain(opts->pulse_raw_dev_out, NULL);
|
||||
|
||||
pa_simple_flush(opts->pulse_raw_dev_out, NULL);
|
||||
}
|
||||
return (13);
|
||||
@@ -835,7 +1026,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
} //End if(strcmp (synctest, DMR_DIRECT_MODE_TS2_VOICE_SYNC) == 0)
|
||||
} //End if (opts->frame_dmr == 1)
|
||||
|
||||
//end LEH DMR Sync
|
||||
//end DMR Sync
|
||||
if (opts->frame_provoice == 1)
|
||||
{
|
||||
strncpy (synctest32, (synctest_p - 31), 32);
|
||||
@@ -855,7 +1046,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
state->lastsynctype = 14;
|
||||
if ( opts->monitor_input_audio == 1)
|
||||
{
|
||||
//pa_simple_drain(opts->pulse_raw_dev_out, NULL);
|
||||
|
||||
pa_simple_flush(opts->pulse_raw_dev_out, NULL);
|
||||
}
|
||||
return (14);
|
||||
@@ -875,7 +1066,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
state->lastsynctype = 15;
|
||||
if ( opts->monitor_input_audio == 1)
|
||||
{
|
||||
//pa_simple_drain(opts->pulse_raw_dev_out, NULL);
|
||||
|
||||
pa_simple_flush(opts->pulse_raw_dev_out, NULL);
|
||||
}
|
||||
return (15);
|
||||
@@ -885,8 +1076,6 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
if ((opts->frame_nxdn96 == 1) || (opts->frame_nxdn48 == 1))
|
||||
{
|
||||
strncpy (synctest18, (synctest_p - 17), 18);
|
||||
//if ((strcmp (synctest18, NXDN_BS_VOICE_SYNC) == 0) || (strcmp (synctest18, NXDN_MS_VOICE_SYNC) == 0)) //or is this the double up test?
|
||||
//borrowing from LEH here WOW! This works so much better, its not even a joke
|
||||
if ((strncmperr (synctest18, NXDN_BS_VOICE_SYNC, 18, 1) == 0) || (strncmperr (synctest18, NXDN_MS_VOICE_SYNC, 18, 1) == 0))
|
||||
{
|
||||
now = time(NULL);
|
||||
@@ -903,7 +1092,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
sprintf (state->ftype, "NXDN48 "); //get rid of spaces
|
||||
if ( opts->monitor_input_audio == 1)
|
||||
{
|
||||
//pa_simple_drain(opts->pulse_raw_dev_out, NULL);
|
||||
|
||||
pa_simple_flush(opts->pulse_raw_dev_out, NULL);
|
||||
}
|
||||
if (opts->errorbars == 1)
|
||||
@@ -917,7 +1106,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
sprintf (state->ftype, "NXDN96");
|
||||
if ( opts->monitor_input_audio == 1)
|
||||
{
|
||||
//pa_simple_drain(opts->pulse_raw_dev_out, NULL);
|
||||
|
||||
pa_simple_flush(opts->pulse_raw_dev_out, NULL);
|
||||
}
|
||||
if (opts->errorbars == 1)
|
||||
@@ -967,7 +1156,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
state->lastsynctype = 9;
|
||||
if ( opts->monitor_input_audio == 1)
|
||||
{
|
||||
//pa_simple_drain(opts->pulse_raw_dev_out, NULL);
|
||||
|
||||
pa_simple_flush(opts->pulse_raw_dev_out, NULL);
|
||||
}
|
||||
return (9);
|
||||
@@ -1009,7 +1198,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
state->lastsynctype = 16;
|
||||
if ( opts->monitor_input_audio == 1)
|
||||
{
|
||||
//pa_simple_drain(opts->pulse_raw_dev_out, NULL);
|
||||
|
||||
pa_simple_flush(opts->pulse_raw_dev_out, NULL);
|
||||
}
|
||||
return (16);
|
||||
@@ -1052,7 +1241,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
state->lastsynctype = 17;
|
||||
if ( opts->monitor_input_audio == 1)
|
||||
{
|
||||
//pa_simple_drain(opts->pulse_raw_dev_out, NULL);
|
||||
|
||||
pa_simple_flush(opts->pulse_raw_dev_out, NULL);
|
||||
}
|
||||
return (17);
|
||||
@@ -1082,7 +1271,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
state->lastsynctype = 6;
|
||||
if ( opts->monitor_input_audio == 1)
|
||||
{
|
||||
//pa_simple_drain(opts->pulse_raw_dev_out, NULL);
|
||||
|
||||
pa_simple_flush(opts->pulse_raw_dev_out, NULL);
|
||||
}
|
||||
return (6);
|
||||
@@ -1102,7 +1291,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
state->lastsynctype = 7;
|
||||
if ( opts->monitor_input_audio == 1)
|
||||
{
|
||||
//pa_simple_drain(opts->pulse_raw_dev_out, NULL);
|
||||
|
||||
pa_simple_flush(opts->pulse_raw_dev_out, NULL);
|
||||
}
|
||||
return (7);
|
||||
@@ -1122,7 +1311,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
state->lastsynctype = 18;
|
||||
if ( opts->monitor_input_audio == 1)
|
||||
{
|
||||
//pa_simple_drain(opts->pulse_raw_dev_out, NULL);
|
||||
|
||||
pa_simple_flush(opts->pulse_raw_dev_out, NULL);
|
||||
}
|
||||
return (18);
|
||||
@@ -1142,7 +1331,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
state->lastsynctype = 19;
|
||||
if ( opts->monitor_input_audio == 1)
|
||||
{
|
||||
//pa_simple_drain(opts->pulse_raw_dev_out, NULL);
|
||||
|
||||
pa_simple_flush(opts->pulse_raw_dev_out, NULL);
|
||||
}
|
||||
return (19);
|
||||
@@ -1212,7 +1401,11 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
|
||||
return (4);
|
||||
}
|
||||
else if ((state->lastsynctype == 11) && ((strcmp (synctest, DMR_BS_VOICE_SYNC) != 0) || (strcmp (synctest, DMR_MS_VOICE_SYNC) != 0)))
|
||||
|
||||
//dmr desync handling, causes issues with TDMA stereo (MS especially), consider removing
|
||||
//may have been because we had BS Voice twice on here, seems okay, continue testing
|
||||
/*
|
||||
else if ((state->lastsynctype == 11) && ((strcmp (synctest, DMR_BS_VOICE_SYNC) != 0) ))
|
||||
{
|
||||
state->carrier = 1;
|
||||
state->offset = synctest_pos;
|
||||
@@ -1221,17 +1414,18 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
sprintf (state->ftype, "(DMR) ");
|
||||
if (opts->errorbars == 1)
|
||||
{
|
||||
printFrameSync (opts, state, "(-DMR) ", synctest_pos + 1, modulation);
|
||||
//printFrameSync (opts, state, "(-DMR) ", synctest_pos + 1, modulation);
|
||||
}
|
||||
state->lastsynctype = -1;
|
||||
if ( opts->monitor_input_audio == 1)
|
||||
{
|
||||
//pa_simple_drain(opts->pulse_raw_dev_out, NULL);
|
||||
pa_simple_flush(opts->pulse_raw_dev_out, NULL);
|
||||
}
|
||||
return (11);
|
||||
}
|
||||
else if ((state->lastsynctype == 12) && ((strcmp (synctest, DMR_BS_DATA_SYNC) != 0) || (strcmp (synctest, DMR_MS_DATA_SYNC) != 0)))
|
||||
*/
|
||||
|
||||
else if ( (state->lastsynctype == 32) && (strcmp (synctest, DMR_MS_VOICE_SYNC) != 0) )
|
||||
{
|
||||
state->carrier = 1;
|
||||
state->offset = synctest_pos;
|
||||
@@ -1240,18 +1434,76 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
sprintf (state->ftype, "(DMR) ");
|
||||
if (opts->errorbars == 1)
|
||||
{
|
||||
printFrameSync (opts, state, "(+DMR) ", synctest_pos + 1, modulation);
|
||||
//printFrameSync (opts, state, "(+DMR) ", synctest_pos + 1, modulation);
|
||||
}
|
||||
state->lastsynctype = -1;
|
||||
if ( opts->monitor_input_audio == 1)
|
||||
{
|
||||
//pa_simple_drain(opts->pulse_raw_dev_out, NULL);
|
||||
pa_simple_flush(opts->pulse_raw_dev_out, NULL);
|
||||
}
|
||||
return (12);
|
||||
return (32); //32
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if ( (state->lastsynctype == 33) && (strcmp (synctest, DMR_MS_DATA_SYNC) != 0) )
|
||||
{
|
||||
state->carrier = 1;
|
||||
state->offset = synctest_pos;
|
||||
state->max = ((state->max) + lmax) / 2;
|
||||
state->min = ((state->min) + lmin) / 2;
|
||||
sprintf (state->ftype, "(DMR) ");
|
||||
if (opts->errorbars == 1)
|
||||
{
|
||||
//printFrameSync (opts, state, "(+DMR) ", synctest_pos + 1, modulation);
|
||||
}
|
||||
state->lastsynctype = -1;
|
||||
if ( opts->monitor_input_audio == 1)
|
||||
{
|
||||
pa_simple_flush(opts->pulse_raw_dev_out, NULL);
|
||||
}
|
||||
return (33); //33
|
||||
}
|
||||
else if ( (state->lastsynctype == 34) && (strcmp (synctest, DMR_RC_DATA_SYNC) != 0) )
|
||||
{
|
||||
state->carrier = 1;
|
||||
state->offset = synctest_pos;
|
||||
state->max = ((state->max) + lmax) / 2;
|
||||
state->min = ((state->min) + lmin) / 2;
|
||||
sprintf (state->ftype, "(DMR) ");
|
||||
if (opts->errorbars == 1)
|
||||
{
|
||||
//printFrameSync (opts, state, "(+DMR) ", synctest_pos + 1, modulation);
|
||||
}
|
||||
state->lastsynctype = -1;
|
||||
if ( opts->monitor_input_audio == 1)
|
||||
{
|
||||
pa_simple_flush(opts->pulse_raw_dev_out, NULL);
|
||||
}
|
||||
return (34); //34
|
||||
}
|
||||
|
||||
else if ((state->lastsynctype == 11) && ((strcmp (synctest, DMR_BS_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, "(DMR) ");
|
||||
if (opts->errorbars == 1)
|
||||
{
|
||||
//printFrameSync (opts, state, "(-DMR) ", synctest_pos + 1, modulation);
|
||||
}
|
||||
state->lastsynctype = -1;
|
||||
if ( opts->monitor_input_audio == 1)
|
||||
{
|
||||
pa_simple_flush(opts->pulse_raw_dev_out, NULL);
|
||||
}
|
||||
return (11); //11
|
||||
}
|
||||
|
||||
//DMR desync
|
||||
|
||||
} //if t == 24
|
||||
} // t >= 18
|
||||
|
||||
if (exitflag == 1)
|
||||
{
|
||||
@@ -1294,12 +1546,9 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
if ( opts->monitor_input_audio == 1 && (time(NULL) - now) > 1 ) //okay, still something going on, latency issues
|
||||
//if ( opts->monitor_input_audio == 1)
|
||||
{
|
||||
//playRawAudio(opts, state); //this is on line 21 in dsd_audio.c
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return (-1);
|
||||
}
|
||||
//1111
|
||||
|
||||
137
src/dsd_main.c
137
src/dsd_main.c
@@ -26,17 +26,6 @@
|
||||
#include "provoice_const.h"
|
||||
#include "git_ver.h"
|
||||
|
||||
//pretty pretty colors
|
||||
|
||||
#define KNRM "\x1B[0m"
|
||||
#define KRED "\x1B[31m"
|
||||
#define KGRN "\x1B[32m"
|
||||
#define KYEL "\x1B[33m"
|
||||
#define KBLU "\x1B[34m"
|
||||
#define KMAG "\x1B[35m"
|
||||
#define KCYN "\x1B[36m"
|
||||
#define KWHT "\x1B[37m"
|
||||
|
||||
int pretty_colors()
|
||||
{
|
||||
fprintf (stderr,"%sred\n", KRED);
|
||||
@@ -84,6 +73,10 @@ noCarrier (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
state->dibit_buf_p = state->dibit_buf + 200;
|
||||
memset (state->dibit_buf, 0, sizeof (int) * 200);
|
||||
//dmr buffer
|
||||
state->dmr_payload_p = state->dibit_buf + 200;
|
||||
memset (state->dmr_payload_buf, 0, sizeof (int) * 200);
|
||||
//dmr buffer end
|
||||
if (opts->mbe_out_f != NULL)
|
||||
{
|
||||
closeMbeOutFile (opts, state);
|
||||
@@ -93,7 +86,7 @@ noCarrier (dsd_opts * opts, dsd_state * state)
|
||||
state->carrier = 0;
|
||||
state->max = 15000;
|
||||
state->min = -15000;
|
||||
state->center = 0;
|
||||
state->center = 0; //quick disable for dmr testing with buffer
|
||||
state->err_str[0] = 0;
|
||||
state->err_strR[0] = 0;
|
||||
sprintf (state->fsubtype, " ");
|
||||
@@ -110,15 +103,26 @@ noCarrier (dsd_opts * opts, dsd_state * state)
|
||||
sprintf (state->slot1light, " slot1 ");
|
||||
state->firstframe = 0;
|
||||
if (opts->audio_gain == (float) 0)
|
||||
{
|
||||
state->aout_gain = 25;
|
||||
}
|
||||
{
|
||||
state->aout_gain = 25;
|
||||
}
|
||||
|
||||
if (opts->audio_gainR == (float) 0)
|
||||
{
|
||||
state->aout_gainR = 25;
|
||||
}
|
||||
memset (state->aout_max_buf, 0, sizeof (float) * 200);
|
||||
state->aout_max_buf_p = state->aout_max_buf;
|
||||
state->aout_max_buf_idx = 0;
|
||||
|
||||
memset (state->aout_max_bufR, 0, sizeof (float) * 200);
|
||||
state->aout_max_buf_pR = state->aout_max_bufR;
|
||||
state->aout_max_buf_idxR = 0;
|
||||
|
||||
sprintf (state->algid, "________");
|
||||
sprintf (state->keyid, "________________");
|
||||
mbe_initMbeParms (state->cur_mp, state->prev_mp, state->prev_mp_enhanced);
|
||||
mbe_initMbeParms (state->cur_mp2, state->prev_mp2, state->prev_mp_enhanced2);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -151,11 +155,13 @@ initOpts (dsd_opts * opts)
|
||||
#endif
|
||||
opts->split = 0;
|
||||
opts->playoffset = 0;
|
||||
opts->playoffsetR = 0;
|
||||
opts->mbe_out_dir[0] = 0;
|
||||
opts->mbe_out_file[0] = 0;
|
||||
opts->mbe_out_path[0] = 0;
|
||||
opts->mbe_out_f = NULL;
|
||||
opts->audio_gain = 0;
|
||||
opts->audio_gainR = 0;
|
||||
opts->audio_out = 1;
|
||||
opts->wav_out_file[0] = 0;
|
||||
opts->wav_out_f = NULL;
|
||||
@@ -163,7 +169,7 @@ initOpts (dsd_opts * opts)
|
||||
opts->serial_baud = 115200;
|
||||
sprintf (opts->serial_dev, "/dev/ttyUSB0");
|
||||
opts->resume = 0;
|
||||
opts->frame_dstar = 1;
|
||||
opts->frame_dstar = 1;
|
||||
opts->frame_x2tdma = 1;
|
||||
opts->frame_p25p1 = 1;
|
||||
opts->frame_nxdn48 = 0;
|
||||
@@ -200,13 +206,14 @@ initOpts (dsd_opts * opts)
|
||||
opts->pulse_digi_in_channels = 1; //2
|
||||
opts->pulse_digi_out_channels = 1; //2
|
||||
|
||||
sprintf (opts->output_name, "Default Channel");
|
||||
sprintf (opts->output_name, "Auto Detect");
|
||||
opts->pulse_flush = 1; //set 0 to flush, 1 for flushed
|
||||
opts->use_ncurses_terminal = 0;
|
||||
opts->payload = 0;
|
||||
|
||||
opts->EncryptionMode = MODE_UNENCRYPTED;
|
||||
opts->inverted_dpmr = 0;
|
||||
opts->dmr_stereo = 0; //change currently only in dsd_frame.c
|
||||
}
|
||||
|
||||
void
|
||||
@@ -218,13 +225,18 @@ initState (dsd_state * state)
|
||||
state->dibit_buf = malloc (sizeof (int) * 1000000);
|
||||
state->dibit_buf_p = state->dibit_buf + 200;
|
||||
memset (state->dibit_buf, 0, sizeof (int) * 200);
|
||||
//dmr buffer -- double check this set up
|
||||
state->dmr_payload_buf = malloc (sizeof (int) * 1000000);
|
||||
state->dmr_payload_p = state->dmr_payload_buf + 200;
|
||||
memset (state->dmr_payload_buf, 0, sizeof (int) * 200);
|
||||
//dmr buffer end
|
||||
state->repeat = 0;
|
||||
state->audio_out_buf = malloc (sizeof (short) * 1000000);
|
||||
state->audio_out_bufR = malloc (sizeof (short) * 1000000);
|
||||
memset (state->audio_out_buf, 0, 100 * sizeof (short));
|
||||
memset (state->audio_out_bufR, 0, 100 * sizeof (short));
|
||||
state->audio_out_buf_p = state->audio_out_buf + 100;
|
||||
state->audio_out_buf_pR = state->audio_out_buf + 100;
|
||||
state->audio_out_buf_pR = state->audio_out_bufR + 100;
|
||||
state->audio_out_float_buf = malloc (sizeof (float) * 1000000);
|
||||
state->audio_out_float_bufR = malloc (sizeof (float) * 1000000);
|
||||
memset (state->audio_out_float_buf, 0, 100 * sizeof (float));
|
||||
@@ -296,6 +308,11 @@ initState (dsd_state * state)
|
||||
memset (state->aout_max_buf, 0, sizeof (float) * 200);
|
||||
state->aout_max_buf_p = state->aout_max_buf;
|
||||
state->aout_max_buf_idx = 0;
|
||||
|
||||
memset (state->aout_max_bufR, 0, sizeof (float) * 200);
|
||||
state->aout_max_buf_pR = state->aout_max_bufR;
|
||||
state->aout_max_buf_idxR = 0;
|
||||
|
||||
state->samplesPerSymbol = 10;
|
||||
state->symbolCenter = 4;
|
||||
sprintf (state->algid, "________");
|
||||
@@ -304,10 +321,17 @@ initState (dsd_state * state)
|
||||
state->cur_mp = malloc (sizeof (mbe_parms));
|
||||
state->prev_mp = malloc (sizeof (mbe_parms));
|
||||
state->prev_mp_enhanced = malloc (sizeof (mbe_parms));
|
||||
|
||||
state->cur_mp2 = malloc (sizeof (mbe_parms));
|
||||
state->prev_mp2 = malloc (sizeof (mbe_parms));
|
||||
state->prev_mp_enhanced2 = malloc (sizeof (mbe_parms));
|
||||
|
||||
mbe_initMbeParms (state->cur_mp, state->prev_mp, state->prev_mp_enhanced);
|
||||
mbe_initMbeParms (state->cur_mp2, state->prev_mp2, state->prev_mp_enhanced2);
|
||||
state->p25kid = 0;
|
||||
|
||||
state->debug_audio_errors = 0;
|
||||
state->debug_audio_errorsR = 0;
|
||||
state->debug_header_errors = 0;
|
||||
state->debug_header_critical_errors = 0;
|
||||
|
||||
@@ -340,6 +364,7 @@ initState (dsd_state * state)
|
||||
sprintf (state->dmr_lrrp[5], "");
|
||||
|
||||
state->K = 0;
|
||||
state->dmr_stereo = 0;
|
||||
|
||||
#ifdef TRACE_DSD
|
||||
state->debug_sample_index = 0;
|
||||
@@ -380,7 +405,7 @@ usage ()
|
||||
fprintf (stderr," -g <num> Audio output gain (default = 0 = auto, disable = -1)\n");
|
||||
fprintf (stderr," -w <file> Output synthesized speech to a .wav file\n");
|
||||
//fprintf (stderr," -a Display port audio devices\n");
|
||||
//fprintf (stderr," -W Monitor Source Audio When No Sync Detected (WIP!)\n");
|
||||
fprintf (stderr," -W Monitor Source Audio When No Sync Detected (WIP!)\n");
|
||||
fprintf (stderr,"\n");
|
||||
fprintf (stderr,"RTL-SDR options:\n");
|
||||
fprintf (stderr," -c <hertz> RTL-SDR Frequency\n");
|
||||
@@ -429,6 +454,9 @@ usage ()
|
||||
fprintf (stderr," -n Reset P25 Heuristics and initState variables on mixed signal decoding\n");
|
||||
fprintf (stderr," Helps when decoding mixed signal types at same time\n");
|
||||
fprintf (stderr," (WiP! May Cause Slow Memory Leak - Experimental)\n");
|
||||
fprintf (stderr," -T Enable DMR TDMA Stereo Voice (Two Slot Dual Voices)\n");
|
||||
fprintf (stderr," This feature will open two streams for slot 1 voice and slot 2 voice\n");
|
||||
fprintf (stderr," (WiP! May Cause DMR sync break resync issues)\n");
|
||||
fprintf (stderr," -Z Log MBE Payload to console\n");
|
||||
fprintf (stderr,"\n");
|
||||
fprintf (stderr,"Report bugs to: https://github.com/lwvmobile/dsd-fme/issues \n");
|
||||
@@ -674,7 +702,7 @@ main (int argc, char **argv)
|
||||
exitflag = 0;
|
||||
signal (SIGINT, sigfun);
|
||||
|
||||
while ((c = getopt (argc, argv, "haep:P:qstv:z:i:o:d:c:g:nw:B:C:R:f:m:u:x:A:S:M:G:D:L:V:U:Y:K:NWrlZ")) != -1)
|
||||
while ((c = getopt (argc, argv, "haep:P:qstv:z:i:o:d:c:g:nw:B:C:R:f:m:u:x:A:S:M:G:D:L:V:U:Y:K:NWrlZT")) != -1)
|
||||
{
|
||||
opterr = 0;
|
||||
switch (c)
|
||||
@@ -771,8 +799,10 @@ main (int argc, char **argv)
|
||||
|
||||
case 'W': //monitor_input_audio if no sync
|
||||
opts.monitor_input_audio = 1;
|
||||
fprintf (stderr, "%s", KRED);
|
||||
fprintf (stderr,"Monitoring Source Audio when carrier present and No Sync Detected.\n");
|
||||
fprintf (stderr," - May cause Pulse Audio Server to crash on some systems.\n");
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
break;
|
||||
|
||||
case 'N':
|
||||
@@ -786,6 +816,17 @@ main (int argc, char **argv)
|
||||
fprintf (stderr,"Logging MBE Payload to console\n");
|
||||
break;
|
||||
|
||||
case 'T':
|
||||
opts.dmr_stereo = 1; //just the end user option
|
||||
state.dmr_stereo = 1; //this values toggles on and off depending on voice or data handling
|
||||
opts.pulse_digi_rate_out = 24000;
|
||||
opts.pulse_digi_out_channels = 2;
|
||||
fprintf (stderr, "%s", KRED);
|
||||
fprintf (stderr,"Experimental DMR Stereo Sync and Functionality. WIP!\n");
|
||||
fprintf (stderr,"DMR Stereo will disable WAV and MBE file saving!\n");
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
break;
|
||||
|
||||
case 'z':
|
||||
sscanf (optarg, "%d", &opts.scoperate);
|
||||
opts.errorbars = 0;
|
||||
@@ -830,13 +871,16 @@ main (int argc, char **argv)
|
||||
{
|
||||
fprintf (stderr,"Setting audio out gain to %f\n", opts.audio_gain);
|
||||
state.aout_gain = opts.audio_gain;
|
||||
state.aout_gainR = opts.audio_gain;
|
||||
}
|
||||
break;
|
||||
case 'n':
|
||||
opts.reset_state = 1;
|
||||
fprintf (stderr, "%s", KRED);
|
||||
fprintf (stderr,"Enabling Automatic Reset of P25 states\n");
|
||||
fprintf (stderr," -Helps with multiple signal type decoding\n");
|
||||
fprintf (stderr," -(WiP! May cause slow memory leak)\n");
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
break;
|
||||
case 'w':
|
||||
strncpy(opts.wav_out_file, optarg, 1023);
|
||||
@@ -866,7 +910,7 @@ main (int argc, char **argv)
|
||||
opts.frame_dmr = 1;
|
||||
opts.frame_dpmr = 0;
|
||||
opts.frame_provoice = 0;
|
||||
sprintf (opts.output_name, "Default Channel");
|
||||
sprintf (opts.output_name, "Auto Detect");
|
||||
}
|
||||
else if (optarg[0] == 'd')
|
||||
{
|
||||
@@ -889,7 +933,7 @@ main (int argc, char **argv)
|
||||
opts.frame_nxdn48 = 0;
|
||||
opts.frame_nxdn96 = 0;
|
||||
opts.frame_dmr = 0;
|
||||
opts.frame_dpmr = 0; //borrow from LEH
|
||||
opts.frame_dpmr = 0;
|
||||
opts.frame_provoice = 0;
|
||||
sprintf (opts.output_name, "X2-TDMA");
|
||||
fprintf (stderr,"Decoding only X2-TDMA frames.\n");
|
||||
@@ -902,7 +946,7 @@ main (int argc, char **argv)
|
||||
opts.frame_nxdn48 = 0;
|
||||
opts.frame_nxdn96 = 0;
|
||||
opts.frame_dmr = 0;
|
||||
opts.frame_dpmr = 0; //borrow from LEH
|
||||
opts.frame_dpmr = 0;
|
||||
opts.frame_provoice = 1;
|
||||
state.samplesPerSymbol = 5;
|
||||
state.symbolCenter = 2;
|
||||
@@ -911,8 +955,7 @@ main (int argc, char **argv)
|
||||
opts.mod_gfsk = 1;
|
||||
state.rf_mod = 2;
|
||||
sprintf (opts.output_name, "ProVoice");
|
||||
//fprintf (stderr,"Setting symbol rate to 9600 / second\n");
|
||||
//fprintf (stderr,"Enabling only GFSK modulation optimizations.\n");
|
||||
fprintf (stderr,"Setting symbol rate to 9600 / second\n");
|
||||
fprintf (stderr,"Decoding only ProVoice frames.\n");
|
||||
}
|
||||
else if (optarg[0] == '1')
|
||||
@@ -942,6 +985,7 @@ main (int argc, char **argv)
|
||||
opts.frame_dmr = 0;
|
||||
opts.frame_dpmr = 0;
|
||||
opts.frame_provoice = 0;
|
||||
opts.frame_ysf = 0;
|
||||
state.samplesPerSymbol = 20;
|
||||
state.symbolCenter = 10;
|
||||
opts.mod_c4fm = 1;
|
||||
@@ -951,9 +995,30 @@ main (int argc, char **argv)
|
||||
sprintf (opts.output_name, "NXDN48");
|
||||
//opts.symboltiming = 2400; //NXDN48 uses 2400 symbol rate
|
||||
fprintf (stderr,"Setting symbol rate to 2400 / second\n");
|
||||
//fprintf (stderr,"Enabling only C4FM modulation optimizations.\n");
|
||||
fprintf (stderr,"Decoding only NXDN 4800 baud frames.\n");
|
||||
}
|
||||
else if (optarg[0] == 'y')
|
||||
{
|
||||
opts.frame_dstar = 0;
|
||||
opts.frame_x2tdma = 0;
|
||||
opts.frame_p25p1 = 0;
|
||||
opts.frame_nxdn48 = 0;
|
||||
opts.frame_nxdn96 = 0;
|
||||
opts.frame_dmr = 0;
|
||||
opts.frame_dpmr = 0;
|
||||
opts.frame_provoice = 0;
|
||||
opts.frame_ysf = 1;
|
||||
state.samplesPerSymbol = 10;
|
||||
//state.symbolCenter = 10;
|
||||
opts.mod_c4fm = 1;
|
||||
opts.mod_qpsk = 0;
|
||||
opts.mod_gfsk = 0;
|
||||
state.rf_mod = 0;
|
||||
sprintf (opts.output_name, "YSF");
|
||||
//opts.symboltiming = 2400; //NXDN48 uses 2400 symbol rate
|
||||
fprintf (stderr,"Setting symbol rate to 2400 / second\n");
|
||||
fprintf (stderr,"Decoding only YSF frames.\nNot working yet!\n");
|
||||
}
|
||||
else if (optarg[0] == 'n')
|
||||
{
|
||||
opts.frame_dstar = 0;
|
||||
@@ -969,7 +1034,6 @@ main (int argc, char **argv)
|
||||
opts.mod_gfsk = 0;
|
||||
state.rf_mod = 0;
|
||||
sprintf (opts.output_name, "NXDN96");
|
||||
//fprintf (stderr,"Enabling only C4FM modulation optimizations.\n");
|
||||
fprintf (stderr,"Decoding only NXDN 9600 baud frames.\n");
|
||||
}
|
||||
else if (optarg[0] == 'r')
|
||||
@@ -986,13 +1050,8 @@ main (int argc, char **argv)
|
||||
opts.mod_qpsk = 0;
|
||||
opts.mod_gfsk = 0; //
|
||||
state.rf_mod = 0; //
|
||||
//opts.pulse_raw_rate_out = 24000; //doing tests with 2 channels at 24000 for 48000 audio default in pulse
|
||||
//opts.pulse_digi_rate_out = 24000; //need to copy this to rtl type in and change rate out to 8000
|
||||
//opts.pulse_raw_out_channels = 2;
|
||||
//opts.pulse_digi_out_channels = 2; //2
|
||||
sprintf (opts.output_name, "DMR/MOTOTRBO");
|
||||
//sprintf (opts.output_name, "DMR/MOTOTRBO Left");
|
||||
fprintf(stderr, "Notice: DMR cannot autodetect polarity. \n Use -xr option if Inverted Signal expected.\n");
|
||||
//fprintf(stderr, "Notice: DMR cannot autodetect polarity. \n Use -xr option if Inverted Signal expected.\n");
|
||||
fprintf (stderr,"Decoding only DMR/MOTOTRBO frames.\n");
|
||||
}
|
||||
else if (optarg[0] == 'm')
|
||||
@@ -1005,6 +1064,7 @@ main (int argc, char **argv)
|
||||
opts.frame_dmr = 0;
|
||||
opts.frame_provoice = 0;
|
||||
opts.frame_dpmr = 1;
|
||||
opts.frame_ysf = 0; //testing with NXDN48 parameters
|
||||
state.samplesPerSymbol = 20; //same as NXDN48 - 20
|
||||
state.symbolCenter = 10; //same as NXDN48 - 10
|
||||
opts.mod_c4fm = 1;
|
||||
@@ -1013,11 +1073,10 @@ main (int argc, char **argv)
|
||||
state.rf_mod = 0;
|
||||
sprintf (opts.output_name, "dPMR");
|
||||
fprintf(stderr, "Notice: dPMR cannot autodetect polarity. \n Use -xd option if Inverted Signal expected.\n");
|
||||
//fprintf(stderr, "Enabling only C4FM modulation optimizations.\n");
|
||||
fprintf(stderr, "Decoding only dPMR frames.\n");
|
||||
}
|
||||
break;
|
||||
//don't mess with the modulations, doesn't really do anything anyways
|
||||
//don't mess with the modulations, doesn't really do anything meaningful anyways
|
||||
case 'm':
|
||||
if (optarg[0] == 'a')
|
||||
{
|
||||
@@ -1127,7 +1186,6 @@ main (int argc, char **argv)
|
||||
if (opts.use_ncurses_terminal == 1)
|
||||
{
|
||||
ncursesOpen();
|
||||
//ncursesPrinter(&opts, &state);
|
||||
}
|
||||
|
||||
if (opts.resume > 0)
|
||||
@@ -1165,6 +1223,7 @@ main (int argc, char **argv)
|
||||
{
|
||||
opts.split = 1;
|
||||
opts.playoffset = 0;
|
||||
opts.playoffsetR = 0;
|
||||
opts.delay = 0;
|
||||
if (strlen(opts.wav_out_file) > 0)
|
||||
{
|
||||
@@ -1179,6 +1238,7 @@ main (int argc, char **argv)
|
||||
{
|
||||
opts.split = 1;
|
||||
opts.playoffset = 0;
|
||||
opts.playoffsetR = 0;
|
||||
opts.delay = 0;
|
||||
if (strlen(opts.wav_out_file) > 0)
|
||||
{
|
||||
@@ -1197,7 +1257,8 @@ main (int argc, char **argv)
|
||||
else
|
||||
{
|
||||
opts.split = 0;
|
||||
opts.playoffset = 25; // 38
|
||||
opts.playoffset = 25; // 38
|
||||
opts.playoffsetR = 25; // 38
|
||||
opts.delay = 0;
|
||||
openAudioInDevice (&opts); //disabled all four instances of openAudio devices, in and out for now
|
||||
opts.audio_out_fd = opts.audio_in_fd;
|
||||
@@ -1214,8 +1275,8 @@ main (int argc, char **argv)
|
||||
else
|
||||
{
|
||||
liveScanner (&opts, &state);
|
||||
|
||||
}
|
||||
|
||||
if (opts.use_ncurses_terminal == 1){
|
||||
//ncursesClose ();
|
||||
}
|
||||
|
||||
@@ -126,44 +126,78 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
|
||||
}
|
||||
else
|
||||
{
|
||||
mbe_processAmbe3600x2450Framef (state->audio_out_temp_buf, &state->errs, &state->errs2, state->err_str, ambe_fr, ambe_d, state->cur_mp, state->prev_mp, state->prev_mp_enhanced, opts->uvquality);
|
||||
#ifdef AMBE_PACKET_OUT
|
||||
|
||||
for(i=0; i<49; i++) {
|
||||
ambe_d_str[i] = ambe_d[i] + '0';
|
||||
//stereo slots and slot 0 (left slot)
|
||||
if (state->currentslot == 0 && opts->dmr_stereo == 1)
|
||||
{
|
||||
mbe_processAmbe3600x2450Framef (state->audio_out_temp_buf, &state->errs, &state->errs2, state->err_str, ambe_fr, ambe_d, state->cur_mp, state->prev_mp, state->prev_mp_enhanced, opts->uvquality);
|
||||
}
|
||||
ambe_d_str[49] = '\0';
|
||||
// print binary string
|
||||
fprintf (stderr, "\n?\t?\t%s\t", ambe_d_str);
|
||||
// print error data
|
||||
fprintf (stderr, "E1: %d; E2: %d; S: %s", state->errs, state->errs2, state->err_str);}
|
||||
#endif
|
||||
if (opts->mbe_out_f != NULL)
|
||||
//stereo slots and slot 1 (right slot)
|
||||
if (state->currentslot == 1 && opts->dmr_stereo == 1)
|
||||
{
|
||||
mbe_processAmbe3600x2450Framef (state->audio_out_temp_bufR, &state->errsR, &state->errs2R, state->err_strR, ambe_fr, ambe_d, state->cur_mp2, state->prev_mp2, state->prev_mp_enhanced2, opts->uvquality);
|
||||
//just put this in here for troubleshooting for now
|
||||
if (opts->mbe_out_f != NULL)
|
||||
{
|
||||
saveAmbe2450Data (opts, state, ambe_d);
|
||||
}
|
||||
}
|
||||
if (opts->dmr_stereo == 0)
|
||||
{
|
||||
mbe_processAmbe3600x2450Framef (state->audio_out_temp_buf, &state->errs, &state->errs2, state->err_str, ambe_fr, ambe_d, state->cur_mp, state->prev_mp, state->prev_mp_enhanced, opts->uvquality);
|
||||
|
||||
if (opts->mbe_out_f != NULL)
|
||||
{
|
||||
saveAmbe2450Data (opts, state, ambe_d);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (opts->errorbars == 1)
|
||||
{
|
||||
//state->err_buf = state->err_str; //make comy to compare, and only print when comparison differs?? THIS HERE HERE
|
||||
//strncpy (state->err_buf, state->err_str, sizeof(state->err_str)); //is this the correct placement for this? want it just before err_str is set?
|
||||
fprintf (stderr, "%s", state->err_str); //this the actual error 'bar' ==== printer, find way to keep this entire string from printing constantly unless err_str changes
|
||||
//fprintf (stderr, "%s", state->err_str); //this the actual error 'bar' ==== printer, find way to keep this entire string from printing constantly unless err_str changes
|
||||
//fprintf (stderr, "%s", state->err_buf);
|
||||
}
|
||||
|
||||
state->debug_audio_errors += state->errs2;
|
||||
|
||||
processAudio (opts, state);
|
||||
if (opts->wav_out_f != NULL)
|
||||
{
|
||||
writeSynthesizedVoice (opts, state);
|
||||
}
|
||||
|
||||
if (opts->audio_out == 1)
|
||||
state->debug_audio_errorsR += state->errs2R;
|
||||
if (opts->dmr_stereo == 1 && state->currentslot == 0)
|
||||
{
|
||||
processAudio (opts, state);
|
||||
if (opts->audio_out == 1)
|
||||
{
|
||||
playSynthesizedVoice (opts, state);
|
||||
}
|
||||
}
|
||||
if (opts->dmr_stereo == 1 && state->currentslot == 1)
|
||||
{
|
||||
processAudioR (opts, state);
|
||||
if (opts->audio_out == 1)
|
||||
{
|
||||
playSynthesizedVoiceR (opts, state);
|
||||
}
|
||||
}
|
||||
if (opts->dmr_stereo == 0)
|
||||
{
|
||||
processAudio (opts, state);
|
||||
if (opts->audio_out == 1)
|
||||
{
|
||||
playSynthesizedVoice (opts, state);
|
||||
}
|
||||
}
|
||||
if (opts->wav_out_f != NULL && opts->dmr_stereo == 0)
|
||||
{
|
||||
writeSynthesizedVoice (opts, state);
|
||||
}
|
||||
/*
|
||||
if (opts->audio_out == 1)
|
||||
{
|
||||
playSynthesizedVoice (opts, state);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
/* This function decipher data */
|
||||
|
||||
@@ -42,6 +42,7 @@ int i = 0;
|
||||
char * s0last = " ";
|
||||
char * s1last = " ";
|
||||
char versionstr[25];
|
||||
char lrrp[6][9999]; //local lrrp storage
|
||||
unsigned long long int call_matrix[33][6]; //0 - sync type; 1 - tg/ran; 2 - rid; 3 - slot; 4 - cc; 5 - time(NULL) ;
|
||||
char * FM_bannerN[9] = {
|
||||
" CTRL + C twice to exit",
|
||||
@@ -54,14 +55,15 @@ char * FM_bannerN[9] = {
|
||||
"https://github.com/lwvmobile/dsd-fme/tree/pulseaudio "
|
||||
};
|
||||
|
||||
char * SyncTypes[30] = {
|
||||
//need to double check these sync types, not quite matching up with frame_sync
|
||||
char * SyncTypes[36] = {
|
||||
"+P25P1",
|
||||
"-P25P1",
|
||||
"+X2TDMA DATA",
|
||||
"-X2TDMA DATA",
|
||||
"+X2TDMA VOICE",
|
||||
"-X2TDMA VOICE",
|
||||
"+DSTARC",
|
||||
"+DSTAR",
|
||||
"-DSTAR",
|
||||
"+NXDN VOICE", //8
|
||||
"-NXDN VOICE", //9
|
||||
@@ -82,7 +84,14 @@ char * SyncTypes[30] = {
|
||||
"-dPMR",
|
||||
"-dPMR",
|
||||
"-dPMR",
|
||||
"-dPMR"
|
||||
"-dPMR",
|
||||
"+NXDN (sync only)",
|
||||
"-NXDN (sync only)",
|
||||
"+YSF",
|
||||
"-YSF",
|
||||
"DMR MS VOICE",
|
||||
"DMR MS DATA",
|
||||
"DMR RC DATA"
|
||||
|
||||
};
|
||||
|
||||
@@ -202,7 +211,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
||||
|
||||
//if (state->dmr_color_code != dcc && (lls == 11 || lls == 13 || lls == 10 || lls == 12) ) //DMR Voice + last two is data
|
||||
//if ( (call_matrix[9][4] != dcc || call_matrix[9][2] != rd) && (lls == 10 || lls == 11 || lls == 12 || lls == 13) ) //DMR
|
||||
if ( (call_matrix[9][4] != dcc || call_matrix[9][2] != rd) && (lls == 12 || lls == 13) ) //DMR, needs work
|
||||
if ( (call_matrix[9][4] != dcc || call_matrix[9][2] != rd) && (lls == 12 || lls == 13 || lls == 32) ) //DMR, needs work
|
||||
{
|
||||
//reset amateur signs on radio id change
|
||||
for (short i = 0; i < 5; i++)
|
||||
@@ -228,6 +237,35 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
||||
call_matrix[9][5] = time(NULL);
|
||||
//i++;
|
||||
}
|
||||
/*
|
||||
//needs work, look at saving just values to part of the state->dmr_lrrp array, or rework for int values
|
||||
if ( (strcmp(state->dmr_lrrp[3], lrrp[3]) != 0) && (lls == 10 || lls == 11) ) //DMR Data LRRP
|
||||
{
|
||||
sprintf (lrrp[1], state->dmr_lrrp[1]);
|
||||
sprintf (lrrp[2], state->dmr_lrrp[2]);
|
||||
sprintf (lrrp[3], state->dmr_lrrp[3]);
|
||||
//lrrp[1] = state->dmr_lrrp[1];
|
||||
//lrrp[2] = state->dmr_lrrp[2];
|
||||
//lrrp[3] = state->dmr_lrrp[3];
|
||||
for (short int k = 0; k < 9; k++)
|
||||
{
|
||||
call_matrix[k][0] = call_matrix[k+1][0];
|
||||
call_matrix[k][1] = call_matrix[k+1][1];
|
||||
call_matrix[k][2] = call_matrix[k+1][2];
|
||||
call_matrix[k][3] = call_matrix[k+1][3];
|
||||
call_matrix[k][4] = call_matrix[k+1][4];
|
||||
call_matrix[k][5] = call_matrix[k+1][5];
|
||||
}
|
||||
|
||||
call_matrix[9][0] = lls;
|
||||
call_matrix[9][1] = (unsigned long long int)&lrrp[3];
|
||||
call_matrix[9][2] = (unsigned long long int)&lrrp[1];
|
||||
call_matrix[9][3] = (unsigned long long int)&lrrp[2];
|
||||
call_matrix[9][4] = dcc;
|
||||
call_matrix[9][5] = time(NULL);
|
||||
//i++;
|
||||
}
|
||||
*/
|
||||
|
||||
//if ( (lls == 0 || lls == 1) && state->lastsrc != rd && state->lastsrc > 0) //find condition to make this work well, probably if last != local last variables
|
||||
if ( (lls == 0 || lls == 1) && call_matrix[9][2] != rd && nc > 0 && tg > 0) //P25
|
||||
@@ -304,9 +342,10 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
||||
|
||||
|
||||
printw ("--Audio Decode----------------------------------------------------------------\n");
|
||||
printw ("| Decoding: %s \n", opts->output_name);
|
||||
printw ("| In Level: [%3i%%] \n", level);
|
||||
printw ("| Voice Error: [%i][%i] \n| Error Bars: [%s] \n", state->errs, state->errs2, state->err_str); //
|
||||
//printw ("| Carrier = %i\n", state->carrier);
|
||||
//printw ("| Voice Error: [%i][%i] \n| Error Bars: [%s] \n", state->errs, state->errs2, state->err_str); //
|
||||
printw ("| Voice Error: [%i][%i] \n", state->errs, state->errs2);
|
||||
printw ("------------------------------------------------------------------------------\n");
|
||||
|
||||
|
||||
@@ -320,11 +359,16 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
||||
// case 3: Ptr = "AES"; break;
|
||||
// default: Ptr = "Unknown Cipher Type"; break;
|
||||
//}
|
||||
|
||||
/*
|
||||
if (state->lastsynctype != -1) //not sure if this will be okay
|
||||
{
|
||||
lls = state->lastsynctype;
|
||||
}
|
||||
*/
|
||||
if (state->synctype > 0 && state->synctype < 34) //not sure if this will be okay
|
||||
{
|
||||
lls = state->synctype;
|
||||
}
|
||||
if (state->nxdn_last_rid > 0 && state->nxdn_last_rid != src);
|
||||
{
|
||||
src = state->nxdn_last_rid;
|
||||
@@ -340,20 +384,20 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
||||
|
||||
//if (state->dmr_color_code > 0 && (lls == 10 || lls == 11 || lls == 12 || lls == 13) ) //DMR, DCC only carried on Data?
|
||||
//if (state->color_code > -1 && (lls == 10 || lls == 11 || lls == 12 || lls == 13) ) //DMR, DCC only carried on Data?
|
||||
if (state->color_code_ok && (lls == 12 || lls == 13) ) //DMR, needs work
|
||||
if (state->color_code_ok && (lls == 12 || lls == 13 || lls == 10 || lls == 11 || lls == 32 || lls == 33) ) //DMR, needs work
|
||||
|
||||
{
|
||||
dcc = state->dmr_color_code;
|
||||
//dcc = state->color_code;
|
||||
}
|
||||
|
||||
if (state->lastsrc > 0 && (lls == 12 || lls == 13 || lls == 0 || lls == 1)) //DMR Voice and P25P1
|
||||
if (state->lastsrc > 0 && (lls == 12 || lls == 13 || lls == 0 || lls == 1 || lls == 32)) //DMR Voice and P25P1
|
||||
{
|
||||
rd = state->lastsrc;
|
||||
opts->p25enc = 0;
|
||||
}
|
||||
|
||||
if (state->lasttg > 0 && (lls == 12 || lls == 13 || lls == 0 || lls == 1)) //DMR Voice and P25P1
|
||||
if (state->lasttg > 0 && (lls == 12 || lls == 13 || lls == 0 || lls == 1 || lls == 32)) //DMR Voice and P25P1
|
||||
{
|
||||
tg = state->lasttg;
|
||||
opts->p25enc = 0;
|
||||
@@ -440,7 +484,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
||||
//printw("| System Type: %s \n", ALGIDS[state->payload_keyid] );
|
||||
}
|
||||
//if (state->lastsynctype == 12 || state->lastsynctype == 13) //DMR Voice Types
|
||||
if (lls == 12 || lls == 13) //DMR Voice Types
|
||||
if (lls == 12 || lls == 13 || lls == 32) //DMR Voice Types
|
||||
{
|
||||
//printw ("| DCC: [%i] FID: [%02X]\n", dcc, state->dmr_fid);
|
||||
//attron(COLOR_PAIR(3));
|
||||
@@ -538,7 +582,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
||||
|
||||
|
||||
//if (state->lastsynctype == 10 || state->lastsynctype == 11) //DMR Data Types
|
||||
if (lls == 10 || lls == 11 ) //DMR Data Types
|
||||
if (lls == 10 || lls == 11 || lls == 33) //DMR Data Types
|
||||
{
|
||||
//printw ("| DCC: [%i]\n", dcc);
|
||||
printw ("| DCC: [%2i] FID: [%02X] SOP: [%02X] \n", dcc, state->dmr_fid, state->dmr_so);
|
||||
@@ -654,7 +698,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
||||
printw ("TG [%4d] ", call_matrix[9-j][4]);
|
||||
printw ("RID [%4d] ", call_matrix[9-j][2]);
|
||||
}
|
||||
if (lls == 0 || lls == 1 || lls == 12 || lls == 13 || lls == 10 || lls == 11 ) //P25 P1 and DMR
|
||||
if (lls == 0 || lls == 1 || lls == 12 || lls == 13 || lls == 10 || lls == 11 || lls == 32 || lls == 33) //P25 P1 and DMR
|
||||
{
|
||||
printw ("TID [%8d] ", call_matrix[9-j][1]);
|
||||
printw ("RID [%8d] ", call_matrix[9-j][2]);
|
||||
|
||||
@@ -300,8 +300,7 @@ getSymbol (dsd_opts * opts, dsd_state * state, int have_sync)
|
||||
|
||||
|
||||
state->lastsample = sample;
|
||||
//steal sample here for rtl input or stdin input
|
||||
state->input_sample_buffer = sample; //sample or sum, honestly this seemt to be best place to grab this sadly, sounds terrible most everywhere else
|
||||
|
||||
}
|
||||
|
||||
symbol = (sum / count);
|
||||
|
||||
@@ -23,8 +23,19 @@ upsample (dsd_state * state, float invalue)
|
||||
|
||||
int i, j, sum;
|
||||
float *outbuf1, c, d;
|
||||
|
||||
outbuf1 = state->audio_out_float_buf_p;
|
||||
if (state->currentslot == 0 && state->dmr_stereo == 1)
|
||||
{
|
||||
outbuf1 = state->audio_out_float_buf_p;
|
||||
}
|
||||
if (state->currentslot == 1 && state->dmr_stereo == 1)
|
||||
{
|
||||
outbuf1 = state->audio_out_float_buf_pR;
|
||||
}
|
||||
if (state->dmr_stereo == 0)
|
||||
{
|
||||
outbuf1 = state->audio_out_float_buf_p;
|
||||
}
|
||||
//outbuf1 = state->audio_out_float_buf_p;
|
||||
outbuf1--;
|
||||
c = *outbuf1;
|
||||
d = invalue;
|
||||
@@ -43,6 +54,33 @@ upsample (dsd_state * state, float invalue)
|
||||
*outbuf1 = d;
|
||||
outbuf1++;
|
||||
|
||||
if (state->currentslot == 1 && state->dmr_stereo == 1)
|
||||
{
|
||||
if (state->audio_out_idx2R > 24)
|
||||
{
|
||||
// smoothing
|
||||
outbuf1 -= 16;
|
||||
for (j = 0; j < 4; j++)
|
||||
{
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
sum = 0;
|
||||
outbuf1 -= 2;
|
||||
sum += (int)*outbuf1;
|
||||
outbuf1 += 2;
|
||||
sum += (int)*outbuf1;
|
||||
outbuf1 += 2;
|
||||
sum += (int)*outbuf1;
|
||||
outbuf1 -= 2;
|
||||
*outbuf1 = (sum / (float) 3);
|
||||
outbuf1++;
|
||||
}
|
||||
outbuf1 -= 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (state->currentslot == 0 && state->dmr_stereo == 1)
|
||||
{
|
||||
if (state->audio_out_idx2 > 24)
|
||||
{
|
||||
// smoothing
|
||||
@@ -65,4 +103,30 @@ upsample (dsd_state * state, float invalue)
|
||||
outbuf1 -= 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (state->dmr_stereo == 0)
|
||||
{
|
||||
if (state->audio_out_idx2 > 24)
|
||||
{
|
||||
// smoothing
|
||||
outbuf1 -= 16;
|
||||
for (j = 0; j < 4; j++)
|
||||
{
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
sum = 0;
|
||||
outbuf1 -= 2;
|
||||
sum += (int)*outbuf1;
|
||||
outbuf1 += 2;
|
||||
sum += (int)*outbuf1;
|
||||
outbuf1 += 2;
|
||||
sum += (int)*outbuf1;
|
||||
outbuf1 -= 2;
|
||||
*outbuf1 = (sum / (float) 3);
|
||||
outbuf1++;
|
||||
}
|
||||
outbuf1 -= 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,14 +128,15 @@ void processDSTAR(dsd_opts * opts, dsd_state * state) {
|
||||
slowdata[0] ^= 0x70;
|
||||
slowdata[1] ^= 0x4f;
|
||||
slowdata[2] ^= 0x93;
|
||||
//fprintf (stderr, "unscrambled- %s",slowdata);
|
||||
//fprintf (stderr, "unscrambled- %c%c%c \n", slowdata[0], slowdata[1], slowdata[2] );
|
||||
|
||||
} else if (framecount == 0) {
|
||||
//fprintf (stderr, "never scrambled-%s\n",slowdata);
|
||||
//fprintf (stderr, "never scrambled-%c\n",slowdata);
|
||||
//fprintf (stderr, "never scrambled- %c%c%c \n", slowdata[0], slowdata[1], slowdata[2] );
|
||||
}
|
||||
|
||||
framecount++;
|
||||
}
|
||||
} //end while loop
|
||||
|
||||
end: if (opts->errorbars == 1) {
|
||||
fprintf (stderr, "\n");
|
||||
|
||||
@@ -66,12 +66,19 @@ void processNXDNData (dsd_opts * opts, dsd_state * state)
|
||||
//fprintf(stderr, "RAN=%02d - Part %d/4 ", RAN, PartOfFrame + 1);
|
||||
if(CrcIsGood)
|
||||
{
|
||||
fprintf (stderr, "%s", KCYN);
|
||||
fprintf (stderr, "RAN=%02d - Part %d/4 ", RAN, PartOfFrame + 1);
|
||||
fprintf (stderr, "(CRC OK) ");
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
//fprintf (stderr, "(CRC OK) ");
|
||||
state->nxdn_last_ran = RAN; //disable, try to grab this in voice instead
|
||||
}
|
||||
|
||||
else fprintf (stderr, "(CRC ERR) ");
|
||||
else
|
||||
{
|
||||
fprintf (stderr, "%s", KRED);
|
||||
fprintf (stderr, "(CRC ERR) ");
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
}
|
||||
|
||||
|
||||
/* Decode the SACCH only when all 4 voice frame
|
||||
|
||||
@@ -732,6 +732,7 @@ void NXDN_decode_VCALL(dsd_opts * opts, dsd_state * state, uint8_t * Message)
|
||||
}
|
||||
|
||||
/* Print the "Call Type" */
|
||||
fprintf (stderr, "%s", KGRN);
|
||||
fprintf(stderr, "\n %s - ", NXDN_Call_Type_To_Str(CallType)); //line break and 1 space
|
||||
//sprintf (state->nxdn_call_type, NXDN_Call_Type_To_Str(CallType)); //fix warning below
|
||||
//warning: format not a string literal and no format arguments [-Wformat-security]
|
||||
@@ -753,12 +754,16 @@ void NXDN_decode_VCALL(dsd_opts * opts, dsd_state * state, uint8_t * Message)
|
||||
/* Print the Key ID */
|
||||
if(CipherType != 0)
|
||||
{
|
||||
fprintf (stderr, "%s", KYEL);
|
||||
fprintf(stderr, "Key ID %u - ", KeyID & 0xFF);
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
//state->nxdn_key = (KeyID & 0xFF);
|
||||
}
|
||||
|
||||
/* Print Source ID and Destination ID (Talk Group or Unit ID) */
|
||||
|
||||
fprintf(stderr, "Src=%u - Dst/TG=%u ", SourceUnitID & 0xFFFF, DestinationID & 0xFFFF);
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
|
||||
|
||||
if(state->NxdnElementsContent.VCallCrcIsGood)
|
||||
@@ -770,18 +775,15 @@ void NXDN_decode_VCALL(dsd_opts * opts, dsd_state * state, uint8_t * Message)
|
||||
state->nxdn_key = (KeyID & 0xFF);
|
||||
state->nxdn_cipher_type = CipherType;
|
||||
}
|
||||
fprintf(stderr, "(CRC OK) ");
|
||||
//fprintf(stderr, "(CRC OK) ");
|
||||
}
|
||||
//fprintf(stderr, " (OK) - ");
|
||||
else fprintf(stderr, "(CRC ERR) ");
|
||||
|
||||
//fprintf(stderr, "\nVCALL = ");
|
||||
|
||||
//for(i = 0; i < 8; i++)
|
||||
//{
|
||||
// fprintf(stderr, "0x%02X, ", ConvertBitIntoBytes(&Message[i * 8], 8) & 0xFF);
|
||||
//}
|
||||
//fprintf(stderr, "\n");
|
||||
else
|
||||
{
|
||||
fprintf (stderr, "%s", KRED);
|
||||
fprintf(stderr, "(CRC ERR) ");
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
}
|
||||
|
||||
} /* End NXDN_decode_VCALL() */
|
||||
|
||||
|
||||
@@ -80,11 +80,18 @@ void processNXDNVoice (dsd_opts * opts, dsd_state * state)
|
||||
//if(CrcIsGood) fprintf(stderr, " (OK) - ");
|
||||
if(CrcIsGood)
|
||||
{
|
||||
fprintf (stderr, "%s", KCYN);
|
||||
fprintf (stderr, "RAN=%02d - Part %d/4 ", RAN, PartOfFrame + 1);
|
||||
fprintf (stderr, "(CRC OK) ");
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
//fprintf (stderr, "(CRC OK) ");
|
||||
state->nxdn_last_ran = RAN; //disable, try to grab this in voice instead
|
||||
}
|
||||
else fprintf(stderr, "(CRC ERR) ");
|
||||
else
|
||||
{
|
||||
fprintf (stderr, "%s", KRED);
|
||||
fprintf(stderr, "(CRC ERR) ");
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
}
|
||||
|
||||
|
||||
/* Determine the current part of superframe
|
||||
|
||||
@@ -469,19 +469,17 @@ processHDU(dsd_opts* opts, dsd_state* state)
|
||||
mihex3 = (unsigned long long int)ConvertBitIntoBytes(&mi[64], 8);
|
||||
}
|
||||
|
||||
//if (state->errs == 0 && algidhex != 0x80)
|
||||
if (1 == 1) //always print hdu alg info
|
||||
//if (opts->payload == 1 && state->errs == 0)
|
||||
if (opts->payload == 1) //print on payload == 1
|
||||
{
|
||||
//fprintf (stderr, " HDU ALG ID: 0x%X KEY ID: 0x%X MI: %s \n", algidhex, kidhex, mi);
|
||||
fprintf (stderr, "%s", KYEL);
|
||||
fprintf (stderr, " HDU ALG ID: 0x%X KEY ID: 0x%X MI: 0x%08llX%08llX%02llX MFID: 0x%02X \n", algidhex, kidhex, mihex1, mihex2, mihex3, state->payload_mfid);
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
}
|
||||
|
||||
if (opts->p25enc == 1 && opts->payload == 0)
|
||||
{
|
||||
algidhex = strtol (algid, NULL, 2);
|
||||
kidhex = strtol (kid, NULL, 2);
|
||||
//fprintf (stderr, "mi: %s algid: $%x kid: $%x\n", mi, algidhex, kidhex);
|
||||
}
|
||||
if (opts->p25lc == 1)
|
||||
{
|
||||
|
||||
@@ -51,7 +51,7 @@ processLDU1 (dsd_opts* opts, dsd_state* state)
|
||||
|
||||
if (opts->errorbars == 1)
|
||||
{
|
||||
fprintf (stderr, "e:");
|
||||
//fprintf (stderr, "e:");
|
||||
}
|
||||
|
||||
// IMBE 1
|
||||
|
||||
@@ -51,7 +51,7 @@ processLDU2 (dsd_opts * opts, dsd_state * state)
|
||||
|
||||
if (opts->errorbars == 1)
|
||||
{
|
||||
fprintf (stderr, "e:");
|
||||
//fprintf (stderr, "e:");
|
||||
}
|
||||
|
||||
// IMBE 1
|
||||
@@ -375,18 +375,16 @@ processLDU2 (dsd_opts * opts, dsd_state * state)
|
||||
mihex3 = (unsigned long long int)ConvertBitIntoBytes(&mi[64], 8);
|
||||
}
|
||||
|
||||
//if (state->errs == 0 && algidhex != 0x80)
|
||||
if (1 == 1) //always print the LDU2 alg info
|
||||
//if (opts->payload == 1 && state->errs == 0)
|
||||
if (opts->payload == 1) //print on payload == 1
|
||||
{
|
||||
//fprintf (stderr, " LDU2 ALG ID: 0x%X KEY ID: 0x%X MI: %s \n", algidhex, kidhex, mi);
|
||||
fprintf (stderr, "%s", KYEL);
|
||||
fprintf (stderr, " LDU2 ALG ID: 0x%X KEY ID: 0x%X MI: 0x%08llX%08llX%02llX\n", algidhex, kidhex, mihex1, mihex2, mihex3);
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
}
|
||||
//if (opts->p25enc == 1 && opts->payload == 0)
|
||||
|
||||
if (opts->payload == 0)
|
||||
{
|
||||
algidhex = strtol (algid, NULL, 2);
|
||||
kidhex = strtol (kid, NULL, 2);
|
||||
//fprintf (stderr, "mi: %s algid: $%x kid: $%x\n", mi, algidhex, kidhex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,9 @@ processTDU (dsd_opts* opts, dsd_state* state)
|
||||
|
||||
// Next we should find an status dibit
|
||||
if (status_count != 35) {
|
||||
fprintf (stderr, "%s", KRED);
|
||||
fprintf (stderr, "*** SYNC ERROR\n");
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
}
|
||||
|
||||
// trailing status symbol
|
||||
|
||||
@@ -114,7 +114,9 @@ read_and_correct_dodeca_word (dsd_opts* opts, dsd_state* state, char* dodeca, in
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (stderr, "%s", KRED);
|
||||
fprintf (stderr, " IRRECOVERABLE");
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
}
|
||||
fprintf (stderr, "\n");
|
||||
#endif
|
||||
@@ -293,7 +295,9 @@ processTDULC (dsd_opts* opts, dsd_state* state)
|
||||
|
||||
// Next we should find an status dibit
|
||||
if (status_count != 35) {
|
||||
fprintf (stderr, "%s", KRED);
|
||||
fprintf (stderr, "*** SYNC ERROR\n");
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
}
|
||||
|
||||
// trailing status symbol
|
||||
|
||||
224
src/trellis.cpp
224
src/trellis.cpp
@@ -1,8 +1,7 @@
|
||||
/*
|
||||
* Copyright (C) 2016 by Jonathan Naylor, G4KLX
|
||||
*
|
||||
* Modifications of original code to work with OP25
|
||||
* Copyright (C) 2019 by Graham J. Norbury
|
||||
* Heavy Modificatins of Original Code to work for DSD-FME
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,7 +13,6 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
#include "dsd.h"
|
||||
//#include "trellis.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cassert>
|
||||
@@ -52,6 +50,23 @@ const unsigned char BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U
|
||||
#define WRITE_BIT(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7])
|
||||
|
||||
unsigned char state = 0U;
|
||||
//rework quickHamming to accept unsigned intergers instead and go bit by bit
|
||||
int quickHamming(unsigned int butt, unsigned int farts)
|
||||
{
|
||||
unsigned int i = 0, count = 0, shit = 0, shart = 0;
|
||||
//fprintf (stderr, "Distance Compare %X - %X \n", butt, farts );
|
||||
for (i; i < 3; i++) //shift three places tops;
|
||||
{
|
||||
shit = (butt >> i) & 0b1;
|
||||
shart = (farts >> i) & 0b1;
|
||||
if (shit != shart)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
bool CDMRTrellisFixCode(unsigned char* points, unsigned int failPos, unsigned char* payload)
|
||||
{
|
||||
@@ -101,44 +116,107 @@ void CDMRTrellisTribitsToBits(const unsigned char* tribits, unsigned char* paylo
|
||||
|
||||
|
||||
// convert bits to bytes
|
||||
//fprintf (stderr, "\n Tribit Binary Sequence\n ");
|
||||
for (short i = 0; i < 144; i++)
|
||||
{
|
||||
//fprintf (stderr, "%b", bits[i]);
|
||||
}
|
||||
for(short int i = 0; i < 18; i++)
|
||||
{
|
||||
payload[i] = (bits[i * 8 + 0] << 7) | (bits[i * 8 + 1] << 6) | (bits[i * 8 + 2] << 5) | (bits[i * 8 + 3] << 4) |
|
||||
(bits[i * 8 + 4] << 3) | (bits[i * 8 + 5] << 2) | (bits[i * 8 + 6] << 1) | (bits[i * 8 + 7] << 0);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 144; i++)
|
||||
payload[i/8] = (payload[i/8] << 1) | bits[i];
|
||||
//for (int i = 0; i < 144; i++)
|
||||
//payload[i/8] = (payload[i/8] << 1) | bits[i];
|
||||
//DmrDataBit[j + 0] = (TrellisReturn[17-i] >> 0) & 0x01; //example
|
||||
|
||||
}
|
||||
|
||||
unsigned int CDMRTrellisCheckCode(const unsigned char* points, unsigned char* tribits)
|
||||
{
|
||||
|
||||
//unsigned char state = 0U; //move outside of function to preserve state for every iteration
|
||||
//let's try reversing the points to pass through the decode table instead of flipping them here,
|
||||
//it may mess up the fixcode and failpos POS
|
||||
state = 0U;
|
||||
for (unsigned int i = 0U; i < 49U; i++) {
|
||||
for (unsigned int i = 0U; i < 49U;) //total number of points to process
|
||||
{
|
||||
tribits[i] = 9U;
|
||||
|
||||
for (unsigned int j = 0U; j < 8U; j++) {
|
||||
//if (points[i] == ENCODE_TABLE[state * 8U + j]) {
|
||||
if (points[i] == DECODE_TABLE[state * 8U + j]) {
|
||||
//if (points[48-i] == DECODE_TABLE[state * 8U + j]) {
|
||||
for (unsigned int j = 0U; j < 8U; j++)
|
||||
{
|
||||
//if (points[i] == DECODE_TABLE[state * 8U + j])
|
||||
//if (points[48-i] == DECODE_TABLE[state * 8U + j])
|
||||
if (points[i] == ENCODE_TABLE[state * 8U + j])
|
||||
{
|
||||
tribits[i] = j;
|
||||
state = tribits[i]; //carry over if found right away
|
||||
i++; //increment i by one value
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//try to find shortest distance for surviving paths and decide on one
|
||||
//seems to be that two paths will have distance value 1, and two will have distance value 2
|
||||
//need to keep totaling up a few rounds before we can eliminate a path and resume?
|
||||
if (tribits[i] == 9U)
|
||||
return i;
|
||||
{
|
||||
int distance = 0;
|
||||
int maxdistance = 99; //random metric for two position distance
|
||||
int pathdistance = 0;
|
||||
unsigned int match = 0;
|
||||
unsigned int nextmatch = 0;
|
||||
unsigned int q = 0;
|
||||
//only 4 possible states for each point, but in 8 (0-7) FSM states
|
||||
char path[99][99] = {0}; //[i][pathcount] = distance
|
||||
int pathcount = 0;
|
||||
for (unsigned int o = 0; o < 64; o++) //check entire state transition table for matches
|
||||
{
|
||||
if (points[i] == ENCODE_TABLE[o]) //ENCODE TABLE
|
||||
{
|
||||
match = o / (unsigned int)8; //get dividend no remainder/decimal I hope, get fsm state 0-7
|
||||
//fprintf (stderr, "\n Point #%d [%d] Match State %d Position %d Tribit Value %d \n", i, points[i], match, o, o % (unsigned int)8);
|
||||
distance = quickHamming(match, state);
|
||||
//fprintf (stderr, "Raw Distance Current %d\n", distance);
|
||||
path[i][pathcount] = distance ; //save which table values (paths) match as possible values and distance
|
||||
for (q; q < 64; q++) //check entire state transition table for next point match
|
||||
{
|
||||
if (points[i+1] == ENCODE_TABLE[q]) //ENCODE TABLE
|
||||
{
|
||||
nextmatch = q / (unsigned int)8;
|
||||
path[i+1][pathcount] = quickHamming(nextmatch, q % (unsigned int)8);
|
||||
//fprintf (stderr, "Raw Distance Next %d\n", path[i+1][pathcount]);
|
||||
pathcount++;
|
||||
//fprintf (stderr, "State 0 Match %d Distance %d \n", o, distance);
|
||||
}
|
||||
}
|
||||
for (short int z = 0; z <= pathcount; z++) //add metrics on paths to find shortest distance
|
||||
{
|
||||
pathdistance = path[i][0] + path[i+1][z];
|
||||
//fprintf (stderr, "Total Path Distance %d\n", pathdistance);
|
||||
if (pathdistance <= maxdistance) //equal too in case of tie?
|
||||
{
|
||||
maxdistance = pathdistance;
|
||||
tribits[i] = o % (unsigned int)8; //remainder value will be tribit value on table
|
||||
if (i < 49) //just in case we are on 49 already, don't want to crash or something.
|
||||
{
|
||||
tribits[i+1] = q % (unsigned int)8; //remainder value will be tribit value on table
|
||||
}
|
||||
|
||||
state = tribits[i];
|
||||
//fprintf (stderr, "Point #%d [%d] - Tribit Candidate %d\n", i, points[i], tribits[i] );
|
||||
//fprintf (stderr, "Point #%d [%d]- Tribit Candidate %d\n", i+1, points[i+1], tribits[i+1] );
|
||||
}
|
||||
}
|
||||
}
|
||||
//fprintf (stderr, "Selected Point #%d [%d] - Tribit Selection %d\n", i, points[i], tribits[i] );
|
||||
//fprintf (stderr, "Selected Point #%d [%d]- Tribit Selection %d\n", i+1, points[i+1], tribits[i+1] );
|
||||
}
|
||||
state = tribits[i+1]; //not quite sure if this will be needed or not, if so, set state to last found value
|
||||
i += 2; //increment i by two since we already got the next tribit value as well;
|
||||
//state = tribits[i]; //not quite sure if this will be needed or not, if so, set state to last found value
|
||||
//i++; //increment i by two since we already got the next tribit value as well;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//if (tribits[48U] != 0U)
|
||||
if (tribits[48U] != 0U) //
|
||||
{
|
||||
return 48U;
|
||||
}
|
||||
|
||||
|
||||
return 999U;
|
||||
}
|
||||
|
||||
@@ -146,7 +224,8 @@ void CDMRTrellisDeinterleave(const unsigned char* data, signed char* dibits)
|
||||
{
|
||||
int n;
|
||||
signed char dibit;
|
||||
|
||||
//can only assume this is giving the correct dibits out, and not inverse or something.
|
||||
/*
|
||||
for (int i = 0; i < 98; i++) {
|
||||
n = i * 2;
|
||||
if (n >= 98) n += 68;
|
||||
@@ -157,19 +236,44 @@ void CDMRTrellisDeinterleave(const unsigned char* data, signed char* dibits)
|
||||
bool b2 = data[n] != 0x0;
|
||||
|
||||
if (!b1 && b2)
|
||||
dibit = +3;
|
||||
dibit = +3; // 1 - 01
|
||||
else if (!b1 && !b2)
|
||||
dibit = +1;
|
||||
dibit = +1; // 0 - 00
|
||||
else if (b1 && !b2)
|
||||
dibit = -1;
|
||||
dibit = -1; // 2 - 10
|
||||
else
|
||||
dibit = -3;
|
||||
dibit = -3; // 3 - 11
|
||||
|
||||
n = INTERLEAVE_TABLE[i]; //should this go in reverse?
|
||||
dibits[n] = dibit;
|
||||
*/
|
||||
//Keep it simple!
|
||||
for (int i = 0; i < 98; i++)
|
||||
{
|
||||
n = INTERLEAVE_TABLE[97-i];
|
||||
//n = i;
|
||||
if (data[i] == 0)
|
||||
{
|
||||
dibits[n] = 1; //1
|
||||
}
|
||||
if (data[i] == 1)
|
||||
{
|
||||
dibits[n] = 3; //3
|
||||
}
|
||||
if (data[i] == 2)
|
||||
{
|
||||
dibits[n] = -1; //-1
|
||||
}
|
||||
if (data[i] == 3)
|
||||
{
|
||||
dibits[n] = -3; //-3
|
||||
}
|
||||
}
|
||||
|
||||
//n = INTERLEAVE_TABLE[i]; //should this go in reverse?
|
||||
//n = INTERLEAVE_TABLE[97-i]; //should this go in reverse?
|
||||
//dibits[n] = dibit; //should this go in reverse too? not sure on this one, but definitely the INTERLEAVE_TABLE
|
||||
//n = INTERLEAVE_TABLE[97-i]; //should this go in reverse?
|
||||
//dibits[97-n] = dibit;
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
||||
void CDMRTrellisDibitsToPoints(const signed char* dibits, unsigned char* points)
|
||||
@@ -324,7 +428,7 @@ bool CDMRTrellisDecode(const unsigned char* data, unsigned char* payload)
|
||||
}
|
||||
signed char dibits[98U];
|
||||
CDMRTrellisDeinterleave(data, dibits);
|
||||
if (1 == 1)
|
||||
if (1 == 2)
|
||||
{
|
||||
fprintf (stderr, "\n Trellis Deinterleaved Dibits inside Decoder (converted to signed)\n ");
|
||||
for (short i = 0; i < 98; i++)
|
||||
@@ -333,8 +437,19 @@ bool CDMRTrellisDecode(const unsigned char* data, unsigned char* payload)
|
||||
}
|
||||
}
|
||||
unsigned char points[49U];
|
||||
unsigned char reverse_points[49U];
|
||||
CDMRTrellisDibitsToPoints(dibits, points);
|
||||
if (1 == 1)
|
||||
//maybe keep point 49 at 49, since its the flush?
|
||||
//fprintf (stderr, "\n Trellis Reverse Points inside Decoder\n ");
|
||||
for (short i = 0; i < 49; i++)
|
||||
{
|
||||
reverse_points[i] = points[48-i];
|
||||
//fprintf (stderr, "#%d [%02u] ", i, reverse_points[i]);
|
||||
}
|
||||
//reverse_points[48] = points[48];
|
||||
//fprintf (stderr, "#%d [%02u] ", 48, reverse_points[48]);
|
||||
|
||||
if (1 == 2)
|
||||
{
|
||||
fprintf (stderr, "\n Trellis Points inside Decoder\n ");
|
||||
for (short i = 0; i < 49; i++)
|
||||
@@ -343,19 +458,11 @@ bool CDMRTrellisDecode(const unsigned char* data, unsigned char* payload)
|
||||
}
|
||||
}
|
||||
// Check the original code
|
||||
unsigned char reverse_points[49U];
|
||||
fprintf (stderr, "\n Trellis Reversed Points inside Decoder\n ");
|
||||
for (short i = 0; i < 49; i++)
|
||||
{
|
||||
reverse_points[i] = points[48-i];
|
||||
fprintf (stderr, "#%d [%02u] ", i, reverse_points[i]);
|
||||
}
|
||||
//unsigned int failPos = CDMRTrellisCheckCode(points, tribits);
|
||||
unsigned int failPos = CDMRTrellisCheckCode(reverse_points, tribits);
|
||||
|
||||
unsigned int failPos = CDMRTrellisCheckCode(points, tribits);
|
||||
//unsigned int failPos = CDMRTrellisCheckCode(reverse_points, tribits); //stack smashing detected terminated
|
||||
|
||||
|
||||
if (1 == 1)
|
||||
if (1 == 2)
|
||||
{
|
||||
fprintf (stderr, "\n Check Code Trellis Tribits inside Decoder\n ");
|
||||
for (short i = 0; i < 49; i++)
|
||||
@@ -367,27 +474,36 @@ bool CDMRTrellisDecode(const unsigned char* data, unsigned char* payload)
|
||||
if (failPos == 999U)
|
||||
{
|
||||
CDMRTrellisTribitsToBits(tribits, payload);
|
||||
if (1 == 1)
|
||||
if (1 == 2)
|
||||
{
|
||||
fprintf (stderr, "\nTrellis Payload Tribits to Bits failPos == 999U\n ");
|
||||
for (short i = 0; i < 18; i++)
|
||||
fprintf (stderr, "\nTrellis Payload Tribits\n %s ", KCYN);
|
||||
for (short i = 0; i < 49; i++)
|
||||
{
|
||||
fprintf (stderr, "#%d [%0u] ", i, tribits[i]); //shouldn't have any values greater that 0x7?
|
||||
}
|
||||
}
|
||||
if (1 == 2)
|
||||
{
|
||||
fprintf (stderr, "\nTrellis Payload Tribits to Bytes inside Decoder\n %s ", KCYN);
|
||||
for (short i = 0; i < 18; i++)
|
||||
{
|
||||
fprintf (stderr, "[%02X]", payload[i]);
|
||||
}
|
||||
fprintf (stderr,"%s", KNRM); //change back to normal
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned char savePoints[49U];
|
||||
for (unsigned int i = 0U; i < 49U; i++)
|
||||
//savePoints[i] = points[i];
|
||||
savePoints[i] = reverse_points[i];
|
||||
savePoints[i] = points[i];
|
||||
//savePoints[i] = reverse_points[i];
|
||||
|
||||
//bool ret = CDMRTrellisFixCode(points, failPos, payload);
|
||||
bool ret = CDMRTrellisFixCode(reverse_points, failPos, payload);
|
||||
bool ret = CDMRTrellisFixCode(points, failPos, payload);
|
||||
//bool ret = CDMRTrellisFixCode(reverse_points, failPos, payload);
|
||||
if (ret){
|
||||
|
||||
if (1 == 1)
|
||||
if (1 == 2)
|
||||
{
|
||||
fprintf (stderr, "\n if return Trellis Tribits inside Decoder\n ");
|
||||
for (short i = 0; i < 49; i++)
|
||||
@@ -396,7 +512,7 @@ bool CDMRTrellisDecode(const unsigned char* data, unsigned char* payload)
|
||||
}
|
||||
}
|
||||
|
||||
if (1 == 1)
|
||||
if (1 == 2)
|
||||
{
|
||||
fprintf (stderr, "\nTrellis Payload Tribits to Bits fix return true\n "); //this one seems to be happening
|
||||
for (short i = 0; i < 18; i++)
|
||||
@@ -408,9 +524,9 @@ bool CDMRTrellisDecode(const unsigned char* data, unsigned char* payload)
|
||||
|
||||
if (failPos == 0U)
|
||||
{
|
||||
if (1 == 1)
|
||||
if (1 == 2)
|
||||
{
|
||||
fprintf (stderr, "\nTrellis Payload Tribits to Bits failPos == 0U\n ");
|
||||
fprintf (stderr, "\nTrellis Payload Tribits to Bytes failPos == 0U\n ");
|
||||
for (short i = 0; i < 18; i++)
|
||||
{
|
||||
fprintf (stderr, "[%02X]", payload[i]);
|
||||
|
||||
287
src/ysf.c
Normal file
287
src/ysf.c
Normal file
@@ -0,0 +1,287 @@
|
||||
/*-------------------------------------------------------------------------------
|
||||
* ysf.c
|
||||
* Yaesu Fusion Decoder for DSD
|
||||
*
|
||||
* LWVMOBILE
|
||||
* 2022-04 DSD-FME Florida Man Edition
|
||||
*-----------------------------------------------------------------------------*/
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "dsd.h"
|
||||
|
||||
const int fichInterleave[100] = {
|
||||
0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95,
|
||||
1, 6, 11, 16, 21, 26, 31, 36, 41, 46, 51, 56, 61, 66, 71, 76, 81, 86, 91, 96,
|
||||
2, 7, 12, 17, 22, 27, 32, 37, 42, 47, 52, 57, 62, 67, 72, 77, 82, 87, 92, 97,
|
||||
3, 8, 13, 18, 23, 28, 33, 38, 43, 48, 53, 58, 63, 68, 73, 78, 83, 88, 93, 98,
|
||||
4, 9, 14, 19, 24, 29, 34, 39, 44, 49, 54, 59, 64, 69, 74, 79, 84, 89, 94, 99,
|
||||
};
|
||||
|
||||
const int vd2Interleave[104] = {
|
||||
0, 26, 52, 78,
|
||||
1, 27, 53, 79,
|
||||
2, 28, 54, 80,
|
||||
3, 29, 55, 81,
|
||||
4, 30, 56, 82,
|
||||
5, 31, 57, 83,
|
||||
6, 32, 58, 84,
|
||||
7, 33, 59, 85,
|
||||
8, 34, 60, 86,
|
||||
9, 35, 61, 87,
|
||||
10, 36, 62, 88,
|
||||
11, 37, 63, 89,
|
||||
12, 38, 64, 90,
|
||||
13, 39, 65, 91,
|
||||
14, 40, 66, 92,
|
||||
15, 41, 67, 93,
|
||||
16, 42, 68, 94,
|
||||
17, 43, 69, 95,
|
||||
18, 44, 70, 96,
|
||||
19, 45, 71, 97,
|
||||
20, 46, 72, 98,
|
||||
21, 47, 73, 99,
|
||||
22, 48, 74, 100,
|
||||
23, 49, 75, 101,
|
||||
24, 50, 76, 102,
|
||||
25, 51, 77, 103
|
||||
};
|
||||
|
||||
const int vfrInterleave[144] = { //IMBE 7200x4400 full rate interleave schedule
|
||||
0, 24, 48, 72, 96, 120, 25, 1, 73, 49, 121, 97,
|
||||
2, 26, 50, 74, 98, 122, 27, 3, 75, 51, 123, 99,
|
||||
4, 28, 52, 76, 100, 124, 29, 5, 77, 53, 125, 101,
|
||||
6, 30, 54, 78, 102, 126, 31, 7, 79, 55, 127, 103,
|
||||
8, 32, 56, 80, 104, 128, 33, 9, 81, 57, 129, 105,
|
||||
10, 34, 58, 82, 106, 130, 35, 11, 83, 59, 131, 107,
|
||||
12, 36, 60, 84, 108, 132, 37, 13, 85, 61, 133, 109,
|
||||
14, 38, 62, 86, 110, 134, 39, 15, 87, 63, 135, 111,
|
||||
16, 40, 64, 88, 112, 136, 41, 17, 89, 65, 137, 113,
|
||||
18, 42, 66, 90, 114, 138, 43, 19, 91, 67, 139, 115,
|
||||
20, 44, 68, 92, 116, 140, 45, 21, 93, 69, 141, 117,
|
||||
22, 46, 70, 94, 118, 142, 47, 23, 95, 71, 143, 119
|
||||
};
|
||||
|
||||
//half-rate ambe3600x2450 interleave schedule
|
||||
const int YSFrW[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
|
||||
};
|
||||
|
||||
// bit index
|
||||
const int YSFrX[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
|
||||
};
|
||||
|
||||
// bit 0
|
||||
// frame index
|
||||
const int YSFrY[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
|
||||
};
|
||||
|
||||
// bit index
|
||||
const int YSFrZ[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
|
||||
};
|
||||
|
||||
void processYSF(dsd_opts * opts, dsd_state * state) //YSF
|
||||
{
|
||||
//480 dibits - 20 dibit sync leaves 460 dibits (920 bits) each 'superframe'
|
||||
fprintf (stderr, "processYSF Function \n");
|
||||
uint32_t i, j, k;
|
||||
unsigned char dibit;
|
||||
const int *w, *x, *y, *z;
|
||||
char ambe_fr[8][4][24];
|
||||
unsigned char storage[8][4][24]; //may expand later
|
||||
unsigned char discard[460]; //just set up for now to hold random dibit grabs with nothing to do but skip them
|
||||
unsigned char vch[4][36]; //correct size array for 4*32 dibit VD2 VCH?
|
||||
unsigned char fich[200]; //store as bits after deinterleaving
|
||||
unsigned char fichraw[100];
|
||||
unsigned char fichdibits[100]; //deinterleaved fich dibits
|
||||
unsigned char fichbytes[26];
|
||||
unsigned int fi = 0;
|
||||
unsigned int cs = 0;
|
||||
unsigned int cm = 0;
|
||||
unsigned int bn = 0;
|
||||
unsigned int bt = 0;
|
||||
unsigned int fn = 0;
|
||||
unsigned int ft = 0;
|
||||
unsigned int mr = 0;
|
||||
unsigned int ip = 0;
|
||||
unsigned int dt = 0; //DT, 2 bytes (according to manual, but has to be two bits)
|
||||
unsigned int sq = 0;
|
||||
unsigned int sc = 0;
|
||||
int vd1 = 1;
|
||||
int vd2 = 0;
|
||||
unsigned int msbI = 0;
|
||||
unsigned int lsbI = 0;
|
||||
unsigned char vd2BitsRaw[104];
|
||||
opts->inverted_ysf = 0; //here for testing purposes, move to main later
|
||||
for (i = 0; i < 100; i++) //100 dibits for fich
|
||||
{
|
||||
dibit = getDibit (opts, state);
|
||||
|
||||
if (opts->inverted_ysf == 1) //opts->inverted_ysf == 1
|
||||
{
|
||||
dibit = (dibit ^ 2);
|
||||
}
|
||||
fichraw[i] = dibit; //raw storage for debug
|
||||
fichdibits[fichInterleave[i]] = dibit; //sort into proper order
|
||||
//fich[i*2] = (1 & (dibit >> 1)); // bit 1
|
||||
//fich[i*2+1] = (1 & dibit); // bit 0
|
||||
fich[i*2] = (fichdibits[fichInterleave[i]] >> 1) & 1;
|
||||
//fprintf (stderr, "%b", fich[i*2]);
|
||||
fich[i*2+1] = fichdibits[fichInterleave[i]] & 1;
|
||||
//fprintf (stderr, "%b", fich[i*2+1]);
|
||||
if (i == 4)
|
||||
{
|
||||
//datatype = dibit;
|
||||
}
|
||||
}
|
||||
//fprintf (stderr, "\nFICH BYTES = ");
|
||||
for (i = 0; i < 25; i++) //bits to bytes
|
||||
{
|
||||
fichbytes[i] = 0; //initialize to see what isn't beign set
|
||||
fichbytes[i] = ( (fich[i*8] << 7) | (fich[i*8+1] << 6) | (fich[i*8+2] << 5) | (fich[i*8+3] << 4) |
|
||||
(fich[i*8+4] << 3) | (fich[i*8+5] << 2) | (fich[i*8+6] << 1) | (fich[i*8+7] << 0) );
|
||||
//fprintf (stderr, "[%02X]", fichbytes[i]);
|
||||
}
|
||||
//fprintf (stderr, "\n");
|
||||
//datatype = (fich[8] << 1) + fich[9];
|
||||
dt = fichbytes[2] & 0x03;
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
//datatype << 1;
|
||||
//datatype = datatype | fichraw[i+8];
|
||||
//fprintf (stderr, "%02b", fichdibits[i+4]);
|
||||
//fprintf (stderr, "%02b", fichdibits[i+11]);
|
||||
}
|
||||
//fprintf (stderr, "Datatype = %02b\n", dt);
|
||||
//quick dirty VD1 method?
|
||||
if (0 == 0) //dt == 0 for VD1
|
||||
{
|
||||
fprintf (stderr, "processYSF VD1 \n");
|
||||
for (j = 0; j < 5; j++) //5 DCH and VCH
|
||||
{
|
||||
w = YSFrW;
|
||||
x = YSFrX;
|
||||
y = YSFrY;
|
||||
z = YSFrZ;
|
||||
k = 0;
|
||||
for (i = 0; i < 36; i++)
|
||||
{
|
||||
dibit = getDibit (opts, state);
|
||||
|
||||
if (opts->inverted_ysf == 1) //opts->inverted_ysf == 1
|
||||
{
|
||||
dibit = (dibit ^ 2);
|
||||
}
|
||||
|
||||
storage[j][*w][*x] = (1 & (dibit >> 1)); // bit 1
|
||||
storage[j][*y][*z] = (1 & dibit); // bit 0
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//AMBE VCH
|
||||
for (i = 0; i < 36; i++)
|
||||
{
|
||||
dibit = getDibit (opts, state);
|
||||
|
||||
if (opts->inverted_ysf == 1) //opts->inverted_ysf == 1
|
||||
{
|
||||
dibit = (dibit ^ 2);
|
||||
}
|
||||
|
||||
ambe_fr[j][*w][*x] = (1 & (dibit >> 1)); // bit 1
|
||||
ambe_fr[j][*y][*z] = (1 & dibit); // bit 0
|
||||
w++;
|
||||
x++;
|
||||
y++;
|
||||
z++;
|
||||
}
|
||||
//processMbeFrame (opts, state, NULL, ambe_fr[j], NULL);
|
||||
} //end j < 4 loop
|
||||
} //end VD1
|
||||
//move processMbeFrame to outside of dibit loop to prevent slip
|
||||
for (j = 0; j < 5; j++)
|
||||
{
|
||||
//processMbeFrame (opts, state, NULL, ambe_fr[j], NULL);
|
||||
}
|
||||
//VD2 method
|
||||
if (0 == 3) //dt == 3
|
||||
{
|
||||
fprintf (stderr, "processYSF VD2 \n");
|
||||
for (j = 0; j < 4; j++)
|
||||
{
|
||||
//VCH[j] and VeCH[j]
|
||||
for (i = 0; i < 20; i++) //32?
|
||||
{
|
||||
dibit = getDibit (opts, state);
|
||||
|
||||
if (opts->inverted_ysf == 1) //opts->inverted_ysf == 1
|
||||
{
|
||||
dibit = (dibit ^ 2);
|
||||
}
|
||||
//collect dibits into array for processing
|
||||
vch[j][i] = dibit;
|
||||
w = YSFrW;
|
||||
x = YSFrX;
|
||||
y = YSFrY;
|
||||
z = YSFrZ;
|
||||
msbI = vd2Interleave[(j+1)*i]; //don't this this is remotely correct, really could use the manual right about now
|
||||
lsbI = vd2Interleave[(j+1)*i+1];
|
||||
vd2BitsRaw[msbI] = ((vch[j][i] >> 1) & 1);
|
||||
vd2BitsRaw[lsbI] = (vch[j][i] & 1);
|
||||
} // VCH[j]
|
||||
//DCH[j]
|
||||
for (i = 0; i < 20; i++) //32?
|
||||
{
|
||||
dibit = getDibit (opts, state);
|
||||
|
||||
if (opts->inverted_ysf == 1) //opts->inverted_ysf == 1
|
||||
{
|
||||
dibit = (dibit ^ 2);
|
||||
}
|
||||
discard[i] = dibit;
|
||||
} //end DCH[j]
|
||||
} //end for j loop
|
||||
|
||||
} //end VD2
|
||||
|
||||
} //end processYSF
|
||||
Reference in New Issue
Block a user