diff --git a/include/dsd.h b/include/dsd.h index 28646c3..b69abaa 100644 --- a/include/dsd.h +++ b/include/dsd.h @@ -70,39 +70,6 @@ typedef struct char groupName[50]; } groupinfo; -typedef struct -{ - uint8_t RFChannelType; - uint8_t FunctionnalChannelType; - uint8_t Option; - uint8_t Direction; - uint8_t CompleteLich; /* 7 bits of LICH without parity */ - uint8_t PreviousCompleteLich; /* 7 bits of previous LICH without parity */ -} NxdnLich_t; - - -typedef struct -{ - uint8_t StructureField; - uint8_t RAN; - uint8_t Data[18]; - uint8_t CrcIsGood; -} NxdnSacchRawPart_t; - - -typedef struct -{ - uint8_t Data[80]; - uint8_t CrcIsGood; -} NxdnFacch1RawPart_t; - - -typedef struct -{ - uint8_t Data[184]; - uint8_t CrcIsGood; -} NxdnFacch2RawPart_t; - typedef struct { @@ -143,11 +110,11 @@ typedef struct uint8_t NextIVComputed[8]; } NxdnElementsContent_t; -//Read Solomon (12,9) constant +//Reed Solomon (12,9) constant #define RS_12_9_DATASIZE 9 #define RS_12_9_CHECKSUMSIZE 3 -//Read Solomon (12,9) struct +//Reed Solomon (12,9) struct typedef struct { uint8_t data[RS_12_9_DATASIZE+RS_12_9_CHECKSUMSIZE]; @@ -255,14 +222,14 @@ typedef struct int p25status; int p25tg; int scoperate; - char audio_in_dev[2048]; //increase size for super long directory/file names? + char audio_in_dev[2048]; //increase size for super long directory/file names int audio_in_fd; SNDFILE *audio_in_file; SF_INFO *audio_in_file_info; uint32_t rtlsdr_center_freq; - int rtlsdr_ppm_error; //was int, changed to float - int audio_in_type; // 0 for device, 1 for file, 3 for rtlsdr + int rtlsdr_ppm_error; + int audio_in_type; char audio_out_dev[1024]; int audio_out_fd; SNDFILE *audio_out_file; @@ -390,7 +357,7 @@ typedef struct int wav_interpolator; int wav_decimator; - int p25_trunk; //enable experimental P25 trunking with RIGCTL (or RTLFM) + int p25_trunk; //experimental P25 trunking with RIGCTL (or RTLFM) int p25_is_tuned; //set to 1 if currently on VC, set back to 0 if on CC //csv import filenames @@ -423,7 +390,6 @@ typedef struct int audio_out_idx2; int audio_out_idxR; int audio_out_idx2R; - //int wav_out_bytes; int center; int jitter; int synctype; @@ -470,7 +436,6 @@ typedef struct int numtdulc; int firstframe; char slot0light[8]; - //char slot1light[8]; float aout_gain; float aout_gainR; float aout_max_buf[200]; @@ -537,16 +502,10 @@ typedef struct unsigned int nxdn_key; char nxdn_call_type[1024]; char dmr_callsign[2][6][99]; //plenty of room in case of overflow; - char dmr_lrrp[2][6][9999]; //memory hog + char dmr_lrrp[2][6][9999]; //need to fix this unsigned long long int dmr_lrrp_source[2]; - NxdnSacchRawPart_t NxdnSacchRawPart[4]; - NxdnFacch1RawPart_t NxdnFacch1RawPart[2]; - NxdnFacch2RawPart_t NxdnFacch2RawPart; NxdnElementsContent_t NxdnElementsContent; - NxdnLich_t NxdnLich; - - int printNXDNAmbeVoiceSampleHex; char ambe_ciphered[49]; char ambe_deciphered[49]; @@ -670,7 +629,7 @@ typedef struct //trunking group and lcn freq list long int trunk_lcn_freq[26]; //max number on an EDACS system, should be enough on DMR too hopefully - groupinfo group_array[0x3FF]; //max supported by Cygwin is 3FFF (signed vs unsigned?) + groupinfo group_array[0x3FF]; //max supported by Cygwin is 3FFF, I hope nobody actually tries to import this many groups unsigned int group_tally; //tally number of groups imported from CSV file for referencing later int lcn_freq_count; int lcn_freq_roll; //number we have 'rolled' to in search of the CC @@ -684,7 +643,7 @@ typedef struct uint8_t nxdn_sacch_frame_segment[4][18]; //part of frame by 18 bits uint8_t nxdn_sacch_frame_segcrc[4]; uint8_t nxdn_alias_block_number; - char nxdn_alias_block_segment[4][4][8]; //might be too large? maybe just an 8? + char nxdn_alias_block_segment[4][4][8]; } dsd_state; @@ -840,45 +799,47 @@ void processP2(dsd_opts * opts, dsd_state * state); //P2 void processTSBK(dsd_opts * opts, dsd_state * state); short dmr_filter(short sample); short nxdn_filter(short sample); +short dpmr_filter(short sample); int strncmperr(const char *s1, const char *s2, size_t size, int MaxErr); -/* Global functions */ //also borrowed +/* Global functions */ uint32_t ConvertBitIntoBytes(uint8_t * BufferIn, uint32_t BitLength); -uint32_t ConvertAsciiToByte(uint8_t AsciiMsbByte, uint8_t AsciiLsbByte, uint8_t * OutputByte); -void Convert49BitSampleInto7Bytes(char * InputBit, char * OutputByte); -void Convert7BytesInto49BitSample(char * InputByte, char * OutputBit); void ncursesOpen (dsd_opts * opts, dsd_state * state); void ncursesPrinter (dsd_opts * opts, dsd_state * state); void ncursesClose (); -/* 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); -void ProcessNxdnRTCHFrame(dsd_opts * opts, dsd_state * state, uint8_t Inverted); -void ProcessNxdnRDCHFrame(dsd_opts * opts, dsd_state * state, uint8_t Inverted); -void ProcessNxdnRTCH_C_Frame(dsd_opts * opts, dsd_state * state, uint8_t Inverted); -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 +//new NXDN Functions start here! +void nxdn_frame (dsd_opts * opts, dsd_state * state); +void nxdn_descramble (uint8_t dibits[], int len); +void nxdn_deperm_facch (dsd_opts * opts, dsd_state * state, uint8_t bits[144]); +void nxdn_deperm_sacch (dsd_opts * opts, dsd_state * state, uint8_t bits[60]); +void nxdn_deperm_cac (dsd_opts * opts, dsd_state * state, uint8_t bits[300]); +void nxdn_deperm_facch2_udch (dsd_opts * opts, dsd_state * state, uint8_t bits[348]); +void nxdn_message_type (dsd_opts * opts, dsd_state * state, uint8_t MessageType); +void nxdn_voice (dsd_opts * opts, dsd_state * state, int voice, uint8_t dbuf[182]); + +//utility functions from OP25 needed by NXDN frame handler +static inline int load_i(const uint8_t val[], int len); +static inline void cfill(uint8_t result[], const uint8_t src[], int len); + +static inline void trellis_encode(uint8_t result[], const uint8_t source[], int result_len, int reg); +static inline void trellis_decode(uint8_t result[], const uint8_t source[], int result_len); + +//OP25 CRC functions +static uint8_t crc6(const uint8_t buf[], int len); +static uint16_t crc12f(const uint8_t buf[], int len); +static uint16_t crc15(const uint8_t buf[], int len); +static uint16_t crc16cac(const uint8_t buf[], int len); /* NXDN functions */ void CNXDNConvolution_start(void); void CNXDNConvolution_decode(uint8_t s0, uint8_t s1); void CNXDNConvolution_chainback(unsigned char* out, unsigned int nBits); void CNXDNConvolution_encode(const unsigned char* in, unsigned char* out, unsigned int nBits); -uint8_t NXDN_decode_LICH(uint8_t InputLich[8], - uint8_t * RFChannelType, - uint8_t * FunctionnalChannelType, - uint8_t * Option, - uint8_t * Direction, - uint8_t * CompleteLichBinaryFormat, - uint8_t Inverted); -uint8_t NXDN_SACCH_raw_part_decode(uint8_t * Input, uint8_t * Output); + +//keeping these void NXDN_SACCH_Full_decode(dsd_opts * opts, dsd_state * state); -uint8_t NXDN_FACCH1_decode(uint8_t * Input, uint8_t * Output); -uint8_t NXDN_UDCH_decode(uint8_t * Input, uint8_t * Output); void NXDN_Elements_Content_decode(dsd_opts * opts, dsd_state * state, uint8_t CrcCorrect, uint8_t * ElementsContent); void NXDN_decode_VCALL(dsd_opts * opts, dsd_state * state, uint8_t * Message); @@ -886,9 +847,7 @@ void NXDN_decode_VCALL_IV(dsd_opts * opts, dsd_state * state, uint8_t * Message) char * NXDN_Call_Type_To_Str(uint8_t CallType); void NXDN_Voice_Call_Option_To_Str(uint8_t VoiceCallOption, uint8_t * Duplex, uint8_t * TransmissionMode); char * NXDN_Cipher_Type_To_Str(uint8_t CipherType); -uint16_t CRC15BitNXDN(uint8_t * BufferIn, uint32_t BitLength); -uint16_t CRC12BitNXDN(uint8_t * BufferIn, uint32_t BitLength); -uint8_t CRC6BitNXDN(uint8_t * BufferIn, uint32_t BitLength); +void NXDN_decode_Alias(dsd_opts * opts, dsd_state * state, uint8_t * Message); void dPMRVoiceFrameProcess(dsd_opts * opts, dsd_state * state); void printdPMRAmbeVoiceSample(dsd_opts * opts, dsd_state * state); @@ -911,7 +870,7 @@ uint32_t BPTC_196x96_Extract_Data(uint8_t InputDeInteleavedData[196], uint8_t DM uint32_t BPTC_128x77_Extract_Data(uint8_t InputDataMatrix[8][16], uint8_t DMRDataExtracted[77]); uint32_t BPTC_16x2_Extract_Data(uint8_t InputInterleavedData[32], uint8_t DMRDataExtracted[32]); -//Read Solomon (12,9) functions +//Reed Solomon (12,9) functions void rs_12_9_calc_syndrome(rs_12_9_codeword_t *codeword, rs_12_9_poly_t *syndrome); uint8_t rs_12_9_check_syndrome(rs_12_9_poly_t *syndrome); rs_12_9_correct_errors_result_t rs_12_9_correct_errors(rs_12_9_codeword_t *codeword, rs_12_9_poly_t *syndrome, uint8_t *errors_found); @@ -1014,7 +973,7 @@ bool GetSignalLevelEx(int sockfd, double *dBFS, int n_samp); //UDP socket connection int UDPBind (char *hostname, int portno); -//Edacs +//EDACS void edacs(dsd_opts * opts, dsd_state * state); unsigned long long int edacs_bch (unsigned long long int message); @@ -1032,10 +991,9 @@ void cleanup_rtlsdr_stream(); void get_rtlsdr_sample(int16_t *sample, dsd_opts * opts, dsd_state * state); void rtlsdr_sighandler(); #endif -//TRELLIS +//DMR TRELLIS void CDMRTrellisTribitsToBits(const unsigned char* tribits, unsigned char* payload); unsigned int CDMRTrellisCheckCode(const unsigned char* points, unsigned char* tribits); -//unsigned int CDMRTrellisCheckCode(const unsigned char* points, unsigned char* state, unsigned char* tribits); bool CDMRTrellisFixCode(unsigned char* points, unsigned int failPos, unsigned char* payload); void CDMRTrellisDeinterleave(const unsigned char* data, signed char* dibits); void CDMRTrellisDibitsToPoints(const signed char* dibits, unsigned char* points); @@ -1049,7 +1007,6 @@ int ez_rs28_facch (int payload[156], int parity[114]); //ezpwd bridge for FME int ez_rs28_sacch (int payload[180], int parity[132]); //ezpwd bridge for FME unsigned long long int isch_lookup (unsigned long long int isch); //isch map lookup int bd_bridge (int payload[196], uint8_t decoded[12]); //bridge to Michael Ossmann Block De-interleaver and 1/2 rate trellis decoder -// uint16_t crc16(uint8_t buf[], int len); int crc16_lb_bridge (int payload[190], int len); int crc12_xb_bridge (int payload[190], int len); diff --git a/src/dmr_sync.c b/src/dmr_sync.c index 85b3b9e..cd79173 100644 --- a/src/dmr_sync.c +++ b/src/dmr_sync.c @@ -15,6 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ + //Originally found at - https://github.com/LouisErigHerve/dsd + //Modified for use in DSD-FME + #include "dsd.h" char * getTimeL(void) //get pretty hh:mm:ss timestamp @@ -2919,4 +2922,18 @@ uint8_t ComputeCrc5Bit(uint8_t * DMRData) return CRC; } /* End ComputeCrc5Bit() */ +uint32_t ConvertBitIntoBytes(uint8_t * BufferIn, uint32_t BitLength) + { + uint32_t Output = 0; + uint32_t i; + + for(i = 0; i < BitLength; i++) + { + Output <<= 1; + Output |= (uint32_t)(BufferIn[i] & 1); + } + + return Output; + } /* End ConvertBitIntoBytes() */ + /* End of file */ diff --git a/src/dpmr_voice.c b/src/dpmr_voice.c index 7a04856..1b4ab8d 100644 --- a/src/dpmr_voice.c +++ b/src/dpmr_voice.c @@ -177,10 +177,8 @@ void processdPMRvoice (dsd_opts * opts, dsd_state * state) x++; y++; z++; - if (j == 3 && i == 28) //find sweet spot to cut off early - { - i = 40; //break early so FS2 sync can resync - } + //should be fixed now with the frame_sync t_max setup + //no more early breaking required } } diff --git a/src/dsd_dibit.c b/src/dsd_dibit.c index 24db757..a92ab0d 100644 --- a/src/dsd_dibit.c +++ b/src/dsd_dibit.c @@ -265,7 +265,7 @@ static int digitize (dsd_opts* opts, dsd_state* state, int symbol) 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 == 36) ) + (state->synctype == 17) || (state->synctype == 29) || (state->synctype == 36) ) { // 1 -P25p1 @@ -275,6 +275,8 @@ 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) + // 29 -NXDN (inverted FSW) + // 36 -P25p2 int valid; int dibit; @@ -284,7 +286,7 @@ static int digitize (dsd_opts* opts, dsd_state* state, int symbol) if (state->synctype == 1) { // Use the P25 heuristics if available - valid = estimate_symbol(state->rf_mod, &(state->inv_p25_heuristics), state->last_dibit, symbol, &dibit); + //valid = estimate_symbol(state->rf_mod, &(state->inv_p25_heuristics), state->last_dibit, symbol, &dibit); } if (valid == 0) @@ -336,6 +338,8 @@ static int digitize (dsd_opts* opts, dsd_state* state, int symbol) // 10 +DMR (non inverted signal data frame) // 12 +DMR (non inverted signal voice frame) // 16 +NXDN (non inverted data frame) + // 28 +NXND (FSW) + // 35 +p25p2 int valid; int dibit; @@ -345,7 +349,7 @@ static int digitize (dsd_opts* opts, dsd_state* state, int symbol) if (state->synctype == 0) { // Use the P25 heuristics if available - valid = estimate_symbol(state->rf_mod, &(state->p25_heuristics), state->last_dibit, symbol, &dibit); + //valid = estimate_symbol(state->rf_mod, &(state->p25_heuristics), state->last_dibit, symbol, &dibit); } if (valid == 0) diff --git a/src/dsd_filters.c b/src/dsd_filters.c index 5edeb75..3a95941 100644 --- a/src/dsd_filters.c +++ b/src/dsd_filters.c @@ -1,4 +1,4 @@ -// DMR filter +// Original DMR filter #define NZEROS 60 float ngain = 7.423339364f; static float xv[NZEROS+1]; @@ -21,70 +21,48 @@ float xcoeffs[] = -0.0083649323f, }; -// NXDN48 filter -//#define NXZEROS 134 -//float nxgain = 15.95930463f; - -#define NXZEROS 91 //Osmocom OP25 -float nxgain = 1.0f; //Osmocom OP25 - +//reverted to original NXDN filters, do better with LICH/Data handling +// NXDN48 filter - Original Version +#define NXZEROS 134 +float nxgain = 15.95930463f; static float nxv[NXZEROS+1]; -//OP25 Osmocom NXDN48 Coeffs seem to do well, will want to do some VS testing float nxcoeffs[] = -{ 0.00203767f, 0.00491622f, 0.00748189f, 0.00934561f, 0.01017049f, 0.00972167f, - 0.00790748f, 0.00480597f, 0.00067202f, -0.00407743f, -0.00890019f, -0.01318478f, - -0.01632047f, -0.01777371f, -0.01716241f, -0.01431852f, -0.00933066f, -0.00255979f, - 0.00537624f, 0.01364992f, 0.02130038f, 0.02733235f, 0.03082824f, 0.03106179f, - 0.02760061f, 0.02038545f, 0.00977572f, -0.0034462f, -0.01811514f, -0.03276675f, - -0.04575844f, -0.05541762f, -0.06020353f, -0.0588669f, -0.05059129f, -0.03510097f, - -0.01272309f, 0.01560398f, 0.04837926f, 0.08364189f, 0.11912012f, 0.15241359f, - 0.18119246f, 0.20339503f, 0.21740525f, 0.2221932f, 0.21740525f, 0.20339503f, - 0.18119246f, 0.15241359f, 0.11912012f, 0.08364189f, 0.04837926f, 0.01560398f, - -0.01272309f, -0.03510097f, -0.05059129f, -0.0588669f, -0.06020353f, -0.05541762f, - -0.04575844f, -0.03276675f, -0.01811514f, -0.0034462f, 0.00977572f, 0.02038545f, - 0.02760061f, 0.03106179f, 0.03082824f, 0.02733235f, 0.02130038f, 0.01364992f, - 0.00537624f, -0.00255979f, -0.00933066f, -0.01431852f, -0.01716241f, -0.01777371f, - -0.01632047f, -0.01318478f, -0.00890019f, -0.00407743f, 0.00067202f, 0.00480597f, - 0.00790748f, 0.00972167f, 0.01017049f, 0.00934561f, 0.00748189f, 0.00491622f, - 0.00203767f}; - -//OLD nxCOEFFS -// { +0.031462429f, +0.031747267f, +0.030401148f, +0.027362877f, -// +0.022653298f, +0.016379869f, +0.008737200f, +0.000003302f, -// -0.009468531f, -0.019262057f, -0.028914291f, -0.037935027f, -// -0.045828927f, -0.052119261f, -0.056372283f, -0.058221106f, -// -0.057387924f, -0.053703443f, -0.047122444f, -0.037734535f, -// -0.025769308f, -0.011595336f, +0.004287292f, +0.021260954f, -// +0.038610717f, +0.055550276f, +0.071252765f, +0.084885375f, -// +0.095646450f, +0.102803611f, +0.105731303f, +0.103946126f, -// +0.097138329f, +0.085197939f, +0.068234131f, +0.046586711f, -// +0.020828821f, -0.008239664f, -0.039608255f, -0.072081234f, -// -0.104311776f, -0.134843790f, -0.162160200f, -0.184736015f, -// -0.201094346f, -0.209863285f, -0.209831516f, -0.200000470f, -// -0.179630919f, -0.148282051f, -0.105841323f, -0.052543664f, -// +0.011020985f, +0.083912428f, +0.164857408f, +0.252278939f, -// +0.344336996f, +0.438979335f, +0.534000832f, +0.627109358f, -// +0.715995947f, +0.798406824f, +0.872214756f, +0.935487176f, -// +0.986548646f, +1.024035395f, +1.046939951f, +1.054644241f, -// +1.046939951f, +1.024035395f, +0.986548646f, +0.935487176f, -// +0.872214756f, +0.798406824f, +0.715995947f, +0.627109358f, -// +0.534000832f, +0.438979335f, +0.344336996f, +0.252278939f, -// +0.164857408f, +0.083912428f, +0.011020985f, -0.052543664f, -// -0.105841323f, -0.148282051f, -0.179630919f, -0.200000470f, -// -0.209831516f, -0.209863285f, -0.201094346f, -0.184736015f, -// -0.162160200f, -0.134843790f, -0.104311776f, -0.072081234f, -// -0.039608255f, -0.008239664f, +0.020828821f, +0.046586711f, -// +0.068234131f, +0.085197939f, +0.097138329f, +0.103946126f, -// +0.105731303f, +0.102803611f, +0.095646450f, +0.084885375f, -// +0.071252765f, +0.055550276f, +0.038610717f, +0.021260954f, -// +0.004287292f, -0.011595336f, -0.025769308f, -0.037734535f, -// -0.047122444f, -0.053703443f, -0.057387924f, -0.058221106f, -// -0.056372283f, -0.052119261f, -0.045828927f, -0.037935027f, -// -0.028914291f, -0.019262057f, -0.009468531f, +0.000003302f, -// +0.008737200f, +0.016379869f, +0.022653298f, +0.027362877f, -// +0.030401148f, +0.031747267f, +0.031462429f, -// }; +{ +0.031462429f, +0.031747267f, +0.030401148f, +0.027362877f, ++0.022653298f, +0.016379869f, +0.008737200f, +0.000003302f, +-0.009468531f, -0.019262057f, -0.028914291f, -0.037935027f, +-0.045828927f, -0.052119261f, -0.056372283f, -0.058221106f, +-0.057387924f, -0.053703443f, -0.047122444f, -0.037734535f, +-0.025769308f, -0.011595336f, +0.004287292f, +0.021260954f, ++0.038610717f, +0.055550276f, +0.071252765f, +0.084885375f, ++0.095646450f, +0.102803611f, +0.105731303f, +0.103946126f, ++0.097138329f, +0.085197939f, +0.068234131f, +0.046586711f, ++0.020828821f, -0.008239664f, -0.039608255f, -0.072081234f, +-0.104311776f, -0.134843790f, -0.162160200f, -0.184736015f, +-0.201094346f, -0.209863285f, -0.209831516f, -0.200000470f, +-0.179630919f, -0.148282051f, -0.105841323f, -0.052543664f, ++0.011020985f, +0.083912428f, +0.164857408f, +0.252278939f, ++0.344336996f, +0.438979335f, +0.534000832f, +0.627109358f, ++0.715995947f, +0.798406824f, +0.872214756f, +0.935487176f, ++0.986548646f, +1.024035395f, +1.046939951f, +1.054644241f, ++1.046939951f, +1.024035395f, +0.986548646f, +0.935487176f, ++0.872214756f, +0.798406824f, +0.715995947f, +0.627109358f, ++0.534000832f, +0.438979335f, +0.344336996f, +0.252278939f, ++0.164857408f, +0.083912428f, +0.011020985f, -0.052543664f, +-0.105841323f, -0.148282051f, -0.179630919f, -0.200000470f, +-0.209831516f, -0.209863285f, -0.201094346f, -0.184736015f, +-0.162160200f, -0.134843790f, -0.104311776f, -0.072081234f, +-0.039608255f, -0.008239664f, +0.020828821f, +0.046586711f, ++0.068234131f, +0.085197939f, +0.097138329f, +0.103946126f, ++0.105731303f, +0.102803611f, +0.095646450f, +0.084885375f, ++0.071252765f, +0.055550276f, +0.038610717f, +0.021260954f, ++0.004287292f, -0.011595336f, -0.025769308f, -0.037734535f, +-0.047122444f, -0.053703443f, -0.057387924f, -0.058221106f, +-0.056372283f, -0.052119261f, -0.045828927f, -0.037935027f, +-0.028914291f, -0.019262057f, -0.009468531f, +0.000003302f, ++0.008737200f, +0.016379869f, +0.022653298f, +0.027362877f, ++0.030401148f, +0.031747267f, +0.031462429f, +}; // DMR filter F4EXB #define DMRNZEROS 60 @@ -110,6 +88,52 @@ const float dmrcoeffs[] = 0.0147202645, -0.0186176083, -0.0428325003, -0.0543747957, -0.0528141756, -0.0404938748, -0.0216605133, -0.0013114705, 0.0159662432, 0.0269200615, 0.0301506278}; +// dPMR filter, version of F4EXB +static float dpmrxv[NXZEROS+1]; + +// dPMR filter, version of F4EXB +#define DPMRNZEROS 134 + +// dPMR filter, version of F4EXB +const float dpmrgain = 14.6083498224f; + +// dPMR filter - root raised cosine alpha=0.2 Ts = 3325 S/s Fc = 48 kHz - zero at boundaries appears to be slightly better +const float dpmrcoeffs[] = +{-0.0000983004, 0.0058388841, 0.0119748846, 0.0179185547, 0.0232592816, + 0.0275919612, 0.0305433586, 0.0317982965, 0.0311240307, + 0.0283911865, 0.0235897433, 0.0168387650, 0.0083888763, +-0.0013831396, -0.0119878087, -0.0228442151, -0.0333082708, +-0.0427067804, -0.0503756642, -0.0557003599, -0.0581561791, +-0.0573462646, -0.0530347941, -0.0451732069, -0.0339174991, +-0.0196350217, -0.0028997157, 0.0155246961, 0.0347134030, + 0.0536202583, 0.0711271166, 0.0861006725, 0.0974542022, + 0.1042112035, 0.1055676660, 0.1009496091, 0.0900625944, + 0.0729301774, 0.0499186839, 0.0217462748, -0.0105250265, +-0.0455148664, -0.0815673067, -0.1168095612, -0.1492246435, +-0.1767350726, -0.1972941202, -0.2089805758, -0.2100926829, +-0.1992367833, -0.1754063031, -0.1380470370, -0.0871052089, +-0.0230554989, 0.0530929052, 0.1398131936, 0.2351006721, + 0.3365341927, 0.4413570929, 0.5465745033, 0.6490630781, + 0.7456885564, 0.8334261381, 0.9094784589, 0.9713859928, + 1.0171250045, 1.0451886943, 1.0546479089, 1.0451886943, + 1.0171250045, 0.9713859928, 0.9094784589, 0.8334261381, + 0.7456885564, 0.6490630781, 0.5465745033, 0.4413570929, + 0.3365341927, 0.2351006721, 0.1398131936, 0.0530929052, +-0.0230554989, -0.0871052089, -0.1380470370, -0.1754063031, +-0.1992367833, -0.2100926829, -0.2089805758, -0.1972941202, +-0.1767350726, -0.1492246435, -0.1168095612, -0.0815673067, +-0.0455148664, -0.0105250265, 0.0217462748, 0.0499186839, + 0.0729301774, 0.0900625944, 0.1009496091, 0.1055676660, + 0.1042112035, 0.0974542022, 0.0861006725, 0.0711271166, + 0.0536202583, 0.0347134030, 0.0155246961, -0.0028997157, +-0.0196350217, -0.0339174991, -0.0451732069, -0.0530347941, +-0.0573462646, -0.0581561791, -0.0557003599, -0.0503756642, +-0.0427067804, -0.0333082708, -0.0228442151, -0.0119878087, +-0.0013831396, 0.0083888763, 0.0168387650, 0.0235897433, + 0.0283911865, 0.0311240307, 0.0317982965, 0.0305433586, + 0.0275919612, 0.0232592816, 0.0179185547, 0.0119748846, + 0.0058388841, -0.0000983004}; + short dsd_input_filter(short sample, int mode); @@ -123,7 +147,13 @@ dmr_filter(short sample) short nxdn_filter(short sample) { - return dsd_input_filter(sample, 2); + return dsd_input_filter(sample, 2); +} + +short +dpmr_filter(short sample) +{ + return dsd_input_filter(sample, 4); } @@ -144,7 +174,7 @@ dsd_input_filter(short sample, int mode) case 2: gain = nxgain; v = nxv; - coeffs = nxcoeffs; + coeffs = (float *)nxcoeffs; zeros = NXZEROS; break; case 3: @@ -153,6 +183,12 @@ dsd_input_filter(short sample, int mode) coeffs = (float *)dmrcoeffs; zeros = DMRNZEROS; break; + case 4: + gain = dpmrgain; + v = dpmrxv; + coeffs = (float *)dpmrcoeffs; + zeros = DPMRNZEROS; + break; default: return sample; } diff --git a/src/dsd_frame.c b/src/dsd_frame.c index 0cc55c7..badc17e 100644 --- a/src/dsd_frame.c +++ b/src/dsd_frame.c @@ -84,54 +84,13 @@ processFrame (dsd_opts * opts, dsd_state * state) state->minref = state->min; } - if ((state->synctype == 8) || (state->synctype == 9)) //NXDN Voice - { - //state->rf_mod = 2; //wrong type of modulation HERE HERE - state->nac = 0; - state->lastsrc = 0; - state->lasttg = 0; - if (opts->errorbars == 1) - { - if (opts->verbose > 0) - { - level = (int) state->max / 164; - //fprintf (stderr, "inlvl: %2i%% ", level); - } - } - state->nac = 0; - if ((opts->mbe_out_dir[0] != 0) && (opts->mbe_out_f == NULL)) - { - openMbeOutFile (opts, state); - } - sprintf (state->fsubtype, " VOICE "); - processNXDNVoice (opts, state); - //ProcessNXDNFrame (opts, state, 0); - return; - } - else if ((state->synctype == 16) || (state->synctype == 17)) //NXDN Data - { - //state->rf_mod = 2; - state->nac = 0; - state->lastsrc = 0; - state->lasttg = 0; - if (opts->errorbars == 1) - { - if (opts->verbose > 0) - { - level = (int) state->max / 164; - //fprintf (stderr, "inlvl: %2i%% ", level); - } - } - state->nac = 0; - if ((opts->mbe_out_dir[0] != 0) && (opts->mbe_out_f == NULL)) - { - openMbeOutFile (opts, state); - } - sprintf (state->fsubtype, " DATA "); - processNXDNData (opts, state); - //ProcessNXDNFrame (opts, state, 0); - return; - } + //NXDN FSW + if ((state->synctype == 28) || (state->synctype == 29)) + { + nxdn_frame (opts, state); + //no MBEout...use symbol capture bin instead! + return; + } else if ((state->synctype == 6) || (state->synctype == 7)) { state->nac = 0; diff --git a/src/dsd_frame_sync.c b/src/dsd_frame_sync.c index dc877fe..7d5363e 100644 --- a/src/dsd_frame_sync.c +++ b/src/dsd_frame_sync.c @@ -21,6 +21,7 @@ //borrowed from DSDcc for 'improved NXDN sync detection' int strncmperr(const char *s1, const char *s2, size_t size, int MaxErr) { + //MaxErr = 0; //force to zero for NXDN testing int Compare = -1; size_t i = 0; int err = 0; @@ -50,7 +51,6 @@ int strncmperr(const char *s1, const char *s2, size_t size, int MaxErr) return Compare; } /* End strncmperr() */ -time_t now; char * getTime(void) //get pretty hh:mm:ss timestamp { time_t t = time(NULL); @@ -90,19 +90,16 @@ printFrameSync (dsd_opts * opts, dsd_state * state, char *frametype, int offset, if (opts->verbose > 2) { //fprintf (stderr,"o: %4i ", offset); - //printw("o: %4i ", offset); } if (opts->verbose > 1) { - //fprintf (stderr,"mod: %s ", modulation); //disabled, don't like looking at incorrect mod types anyways, and it eats up space on the console - //printw("mod: %s ", modulation); + //fprintf (stderr,"mod: %s ", modulation); } if (opts->verbose > 2) { //fprintf (stderr,"g: %f ", state->aout_gain); - //printw("g: %f ", state->aout_gain); } - //refresh(); + } int @@ -150,6 +147,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state) * 38 = -EDACS */ + //start control channel hunting if using trunking, time needs updating on each successful sync //will need to assign frequencies to a CC array for P25 since that isn't imported from CSV if (opts->p25_is_tuned == 0 && opts->p25_trunk == 1 && time(NULL) - state->last_cc_sync_time > 3) @@ -184,7 +182,6 @@ getFrameSync (dsd_opts * opts, dsd_state * state) state->last_cc_sync_time = time(NULL); //set again to give another x seconds } - int i, j, t, o, dibit, sync, symbol, synctest_pos, lastt; char synctest[25]; char synctest12[13]; //dPMR @@ -192,29 +189,63 @@ getFrameSync (dsd_opts * opts, dsd_state * state) char synctest18[19]; char synctest32[33]; char synctest20[21]; //YSF + char synctest21[22]; //P25 S-OEMI (SACCH) char synctest48[49]; //EDACS char modulation[8]; char *synctest_p; - char synctest_buf[10240]; + int symboltest_pos; //symbol test position, match to synctest_pos + int symboltest_p[10240]; //make this an array instead + char synctest_buf[10240]; //what actually is assigned to this, can't find its use anywhere? int lmin, lmax, lidx; - int lbuf[24], lbuf2[24]; + + //assign t_max value based on decoding type expected (all non-auto decodes first) + int t_max; //maximum values allowed for t will depend on decoding type - NXDN will be 10, others will be more + if (opts->frame_nxdn48 == 1 || opts->frame_nxdn96 == 1) + { + t_max = 10; + } + //else if dPMR, need condition here when we can test what it'll need + else if (opts->frame_dpmr == 1) + { + t_max = 12; //based on Frame_Sync_2 pattern + } + //if Phase 2 (or YSF in future), then only 20 + else if (state->lastsynctype == 35 || state->lastsynctype == 36) //P2 + { + t_max = 20; + } + else t_max = 24; //was 18, but everything else seems to be based on 24 dibit sync pattern + + //int lbuf[11], lbuf2[11]; //24 each //10 was woking good on NXDN, but not going well on P25, probably others too + int lbuf[t_max], lbuf2[t_max]; int lsum; char spectrum[64]; + //init the lbuf + memset (lbuf, 0, sizeof(lbuf)); + memset (lbuf2, 0, sizeof(lbuf2)); - for (i = 18; i < 24; i++) - { - lbuf[i] = 0; - lbuf2[i] = 0; - } + + //test changing these values, and the qsort and other values down below sync + //also, add max min shit to the sync pattern for NXDN FSW + //and maybe also try making a more variable based t >= and also user opt filters (op25, original) + + //also also, go back to post commit version of this file, and try to copy shit back again and not + //break things this time, this version is a shim from BJ + // for (i = 18; i < 24; i++) //was 18, changing to 10, revert if issues arise + // { + // lbuf[i] = 0; + // lbuf2[i] = 0; + // } // detect frame sync t = 0; + synctest10[10] = 0; synctest[24] = 0; synctest12[12] = 0; synctest18[18] = 0; + synctest48[48] = 0; synctest32[32] = 0; synctest20[20] = 0; - synctest48[48] = 0; synctest_pos = 0; synctest_p = synctest_buf + 10; sync = 0; @@ -239,11 +270,12 @@ getFrameSync (dsd_opts * opts, dsd_state * state) { t++; + symbol = getSymbol (opts, state, 0); lbuf[lidx] = symbol; state->sbuf[state->sidx] = symbol; - if (lidx == 23) + if ( lidx == (t_max - 1) ) //23 //9 for NXDN { lidx = 0; } @@ -260,7 +292,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state) state->sidx++; } - if (lastt == 23) + if (lastt == 23) //issue for QPSK on shorter sync pattern? { lastt = 0; if (state->numflips > opts->mod_threshold) @@ -311,7 +343,8 @@ getFrameSync (dsd_opts * opts, dsd_state * state) } //this is needed to capture dibits and convert them to appropriate format for a symbol bin - if (opts->symbol_out == 1 && symbol != 0) //is 0 a valid symbol from dsd? //&& symbol != 0 + //HERE HERE i REMOVED THE SYMBOL != 0 BIT, IF THAT CAUSES ISSUES, THEN PUT IT BACK!!!!! + if (opts->symbol_out == 1 && dibit != 0) //is 0 a valid symbol from dsd? //&& symbol != 0 //&& symbol != 0 { int csymbol = 0; if (dibit == 49) @@ -327,13 +360,10 @@ getFrameSync (dsd_opts * opts, dsd_state * state) } //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; + state->dmr_payload_p = state->dmr_payload_buf + 200; } - - if (1 == 1) { if (symbol > state->center) @@ -358,27 +388,56 @@ getFrameSync (dsd_opts * opts, dsd_state * state) *state->dmr_payload_p = 2; // -1 } } - state->dmr_payload_p++; - } + //if this part were working, we shouldn't have to worry about flipping dibits in dmr, just pull them right off the buffer + //but that has caused issues due to various reasons, probably forgot to flip something somehwere else, so just leave it Disabled + //since we can get the same result by flipping them later on + if (0 == 1) + { + if (symbol > state->center) + { + if (symbol > state->umid) + { + *state->dmr_payload_p = 3; // +3 + } + else + { + *state->dmr_payload_p = 2; // +1 + } + } + else + { + if (symbol < state->lmid) + { + *state->dmr_payload_p = 1; // -3 + } + else + { + *state->dmr_payload_p = 0; // -1 + } + } + } + + // *state->dmr_payload_p = 1; //test just setting all sync with 3, see if it gets rejected by fec + state->dmr_payload_p++; // end digitize and dmr buffer testing - *synctest_p = dibit; - if (t >= 10) //t >= 18 + *synctest_p = dibit; //here's your problem, lady! well, more like the assignment dibit gets up above + if (t >= t_max) //works excelent now with short sync patterns, and no issues with large ones! { - for (i = 0; i < 24; i++) + for (i = 0; i < t_max; i++) //24 { lbuf2[i] = lbuf[i]; } - qsort (lbuf2, 24, sizeof (int), comp); - lmin = (lbuf2[2] + lbuf2[3] + lbuf2[4]) / 3; - lmax = (lbuf2[21] + lbuf2[20] + lbuf2[19]) / 3; + qsort (lbuf2, t_max, sizeof (int), comp); //24 + lmin = (lbuf2[1] + lbuf2[2] + lbuf2[3]) / 3; + lmax = (lbuf2[t_max - 3] + lbuf2[t_max - 2] + lbuf2[t_max - 1]) / 3; //7,8,9 for NXDN if (state->rf_mod == 1) { state->minbuf[state->midx] = lmin; state->maxbuf[state->midx] = lmax; - if (state->midx == (opts->msize - 1)) + if (state->midx == (opts->msize - 1)) //-1 { state->midx = 0; } @@ -408,105 +467,32 @@ getFrameSync (dsd_opts * opts, dsd_state * state) state->minref = state->min; } - if (state->rf_mod == 0) - { - sprintf (modulation, "C4FM"); - } - else if (state->rf_mod == 1) - { - sprintf (modulation, "QPSK"); - } - else if (state->rf_mod == 2) - { - sprintf (modulation, "GFSK"); - } - - if (opts->datascope == 1) - { - if (lidx == 0) - { - for (i = 0; i < 64; i++) - { - spectrum[i] = 0; - } - for (i = 0; i < 24; i++) - { - o = (lbuf2[i] + 32768) / 1024; - spectrum[o]++; - } - if (state->symbolcnt > (4800 / opts->scoperate)) - { - state->symbolcnt = 0; - fprintf (stderr,"\n"); - fprintf (stderr,"Demod mode: %s Nac: %4X\n", modulation, state->nac); - fprintf (stderr,"Frame Type: %s Talkgroup: %7i\n", state->ftype, state->lasttg); - fprintf (stderr,"Frame Subtype: %s Source: %12i\n", state->fsubtype, state->lastsrc); - fprintf (stderr,"TDMA activity: %s %s Voice errors: %s\n", state->slot1light, state->slot2light, state->err_str); - fprintf (stderr,"+----------------------------------------------------------------+\n"); - for (i = 0; i < 10; i++) - { - fprintf (stderr,"|"); - for (j = 0; j < 64; j++) - { - if (i == 0) - { - if ((j == ((state->min) + 32768) / 1024) || (j == ((state->max) + 32768) / 1024)) - { - fprintf (stderr,"#"); - } - else if (j == (state->center + 32768) / 1024) - { - fprintf (stderr,"!"); - } - else - { - if (j == 32) - { - fprintf (stderr,"|"); - } - else - { - fprintf (stderr," "); - } - } - } - else - { - if (spectrum[j] > 9 - i) - { - fprintf (stderr,"*"); - } - else - { - if (j == 32) - { - fprintf (stderr,"|"); - } - else - { - fprintf (stderr," "); - } - } - } - } - fprintf (stderr,"|\n"); - } - fprintf (stderr,"+----------------------------------------------------------------+\n"); - } - } - } + // if (state->rf_mod == 0) + // { + // sprintf (modulation, "C4FM"); + // } + // else if (state->rf_mod == 1) + // { + // sprintf (modulation, "QPSK"); + // } + // else if (state->rf_mod == 2) + // { + // sprintf (modulation, "GFSK"); + // } + //tempted to shitcan this datascope strncpy (synctest, (synctest_p - 23), 24); if (opts->frame_p25p1 == 1) { if (strcmp (synctest, P25P1_SYNC) == 0) { - now = time(NULL); state->carrier = 1; state->offset = synctest_pos; state->max = ((state->max) + lmax) / 2; state->min = ((state->min) + lmin) / 2; state->dmrburstR = 17; + state->payload_algidR = 0; + state->dmr_stereo = 1; //check to see if this causes dmr data issues later on during mixed sync types sprintf (state->ftype, "P25 Phase 1"); if (opts->errorbars == 1) { @@ -518,12 +504,13 @@ getFrameSync (dsd_opts * opts, dsd_state * state) } if (strcmp (synctest, INV_P25P1_SYNC) == 0) { - now = time(NULL); state->carrier = 1; state->offset = synctest_pos; state->max = ((state->max) + lmax) / 2; state->min = ((state->min) + lmin) / 2; state->dmrburstR = 17; + state->payload_algidR = 0; + state->dmr_stereo = 1; //check to see if this causes dmr data issues later on during mixed sync types sprintf (state->ftype, "P25 Phase 1"); if (opts->errorbars == 1) { @@ -538,7 +525,6 @@ getFrameSync (dsd_opts * opts, dsd_state * state) { if ((strcmp (synctest, X2TDMA_BS_DATA_SYNC) == 0) || (strcmp (synctest, X2TDMA_MS_DATA_SYNC) == 0)) { - now = time(NULL); state->carrier = 1; state->offset = synctest_pos; state->max = ((state->max) + (lmax)) / 2; @@ -572,7 +558,6 @@ getFrameSync (dsd_opts * opts, dsd_state * state) } if ((strcmp (synctest, X2TDMA_BS_VOICE_SYNC) == 0) || (strcmp (synctest, X2TDMA_MS_VOICE_SYNC) == 0)) { - now = time(NULL); state->carrier = 1; state->offset = synctest_pos; state->max = ((state->max) + lmax) / 2; @@ -622,7 +607,6 @@ getFrameSync (dsd_opts * opts, dsd_state * state) state->lastsynctype = 30; if ( opts->monitor_input_audio == 1) { - pa_simple_flush(opts->pulse_raw_dev_out, NULL); } return (30); @@ -644,7 +628,6 @@ getFrameSync (dsd_opts * opts, dsd_state * state) state->lastsynctype = 31; if ( opts->monitor_input_audio == 1) { - pa_simple_flush(opts->pulse_raw_dev_out, NULL); } return (31); @@ -671,16 +654,11 @@ getFrameSync (dsd_opts * opts, dsd_state * state) { printFrameSync (opts, state, "+P25p2 SISCH", synctest_pos + 1, modulation); } - if (state->p2_wacn != 0 && state->p2_cc != 0 && state->p2_sysid != 0 && - state->p2_wacn != 0xFFFFF && state->p2_cc != 0xFFF && state->p2_sysid != 0xFFF) + if (state->p2_wacn != 0 && state->p2_cc != 0 && state->p2_sysid != 0) { + //fprintf (stderr, "%s", KCYN); fprintf (stderr, " WACN [%05llX] SYS [%03llX] NAC [%03llX] ", state->p2_wacn, state->p2_sysid, state->p2_cc); - } - else if (state->p2_wacn == 0xFFFFF || state->p2_cc == 0xFFF || state->p2_sysid == 0xFFF) - { - fprintf (stderr, "%s", KRED); - fprintf (stderr, " P2 Invalid Parameters "); - fprintf (stderr, "%s", KNRM); + //fprintf (stderr, "%s", KNRM); } else { @@ -713,16 +691,11 @@ getFrameSync (dsd_opts * opts, dsd_state * state) { printFrameSync (opts, state, "-P25p2 SISCH", synctest_pos + 1, modulation); } - if (state->p2_wacn != 0 && state->p2_cc != 0 && state->p2_sysid != 0 && - state->p2_wacn != 0xFFFFF && state->p2_cc != 0xFFF && state->p2_sysid != 0xFFF) + if (state->p2_wacn != 0 && state->p2_cc != 0 && state->p2_sysid != 0) { + //fprintf (stderr, "%s", KCYN); fprintf (stderr, " WACN [%05llX] SYS [%03llX] NAC [%03llX] ", state->p2_wacn, state->p2_sysid, state->p2_cc); - } - else if (state->p2_wacn == 0xFFFFF || state->p2_cc == 0xFFF || state->p2_sysid == 0xFFF) - { - fprintf (stderr, "%s", KRED); - fprintf (stderr, " P2 Invalid Parameters "); - fprintf (stderr, "%s", KNRM); + //fprintf (stderr, "%s", KNRM); } else { @@ -992,7 +965,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state) { //printFrameSync (opts, state, "+DMR ", synctest_pos + 1, modulation); } - //state->lastsynctype = 10; + state->lastsynctype = 33; if ( opts->monitor_input_audio == 1) { pa_simple_flush(opts->pulse_raw_dev_out, NULL); @@ -1011,7 +984,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state) { state->firstframe = 1; } - //state->lastsynctype = 11; + state->lastsynctype = 32; if ( opts->monitor_input_audio == 1) { pa_simple_flush(opts->pulse_raw_dev_out, NULL); @@ -1035,7 +1008,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state) { //printFrameSync (opts, state, "+DMR ", synctest_pos + 1, modulation); } - //state->lastsynctype = 10; + state->lastsynctype = 33; if ( opts->monitor_input_audio == 1) { pa_simple_flush(opts->pulse_raw_dev_out, NULL); @@ -1054,7 +1027,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state) { state->firstframe = 1; } - //state->lastsynctype = 11; + state->lastsynctype = 32; if ( opts->monitor_input_audio == 1) { pa_simple_flush(opts->pulse_raw_dev_out, NULL); @@ -1126,7 +1099,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state) { state->firstframe = 1; } - state->lastsynctype = 12; + state->lastsynctype = 32; if ( opts->monitor_input_audio == 1) { pa_simple_flush(opts->pulse_raw_dev_out, NULL); @@ -1141,7 +1114,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state) { //printFrameSync (opts, state, "-DMR ", synctest_pos + 1, modulation); } - state->lastsynctype = 13; + state->lastsynctype = 33; return (33); } } /* End if(strcmp (synctest, DMR_DIRECT_MODE_TS1_VOICE_SYNC) == 0) */ @@ -1151,7 +1124,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state) state->offset = synctest_pos; state->max = ((state->max) + lmax) / 2; state->min = ((state->min) + lmin) / 2; - //state->currentslot = 1; + // state->currentslot = 1; state->directmode = 1; //Direct mode if (opts->inverted_dmr == 0) //&& opts->dmr_stereo == 1 { @@ -1165,7 +1138,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state) { state->firstframe = 1; } - //state->lastsynctype = 12; + state->lastsynctype = 32; if ( opts->monitor_input_audio == 1) { pa_simple_flush(opts->pulse_raw_dev_out, NULL); @@ -1180,7 +1153,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state) { //printFrameSync (opts, state, "-DMR ", synctest_pos + 1, modulation); } - //state->lastsynctype = 13; + state->lastsynctype = 33; if ( opts->monitor_input_audio == 1) { pa_simple_flush(opts->pulse_raw_dev_out, NULL); @@ -1194,250 +1167,66 @@ getFrameSync (dsd_opts * opts, dsd_state * state) //ProVoice and EDACS sync if (opts->frame_provoice == 1) - { - strncpy (synctest32, (synctest_p - 31), 32); - strncpy (synctest48, (synctest_p - 47), 48); - if ((strcmp (synctest32, PROVOICE_SYNC) == 0) || (strcmp (synctest32, PROVOICE_EA_SYNC) == 0)) { - state->last_cc_sync_time = time(NULL); - state->carrier = 1; - state->offset = synctest_pos; - state->max = ((state->max) + lmax) / 2; - state->min = ((state->min) + lmin) / 2; - sprintf (state->ftype, "ProVoice "); - if (opts->errorbars == 1) - printFrameSync (opts, state, "+PV ", synctest_pos + 1, modulation); - state->lastsynctype = 14; - state->last_cc_sync_time = time(NULL); - return (14); - } - else if ((strcmp (synctest32, INV_PROVOICE_SYNC) == 0) || (strcmp (synctest32, INV_PROVOICE_EA_SYNC) == 0)) - { - state->last_cc_sync_time = time(NULL); - state->carrier = 1; - state->offset = synctest_pos; - state->max = ((state->max) + lmax) / 2; - state->min = ((state->min) + lmin) / 2; - sprintf (state->ftype, "ProVoice "); - printFrameSync (opts, state, "-PV ", synctest_pos + 1, modulation); - state->lastsynctype = 15; - state->last_cc_sync_time = time(NULL); - return (15); - } - - else if ( strcmp (synctest48, EDACS_SYNC) == 0) - { - state->last_cc_sync_time = time(NULL); - state->carrier = 1; - state->offset = synctest_pos; - state->max = ((state->max) + lmax) / 2; - state->min = ((state->min) + lmin) / 2; - printFrameSync (opts, state, "-EDACS", synctest_pos + 1, modulation); - state->lastsynctype = 38; - state->last_cc_sync_time = time(NULL); - return (38); - } - else if ( strcmp (synctest48, INV_EDACS_SYNC) == 0) - { - state->last_cc_sync_time = time(NULL); - state->carrier = 1; - state->offset = synctest_pos; - state->max = ((state->max) + lmax) / 2; - state->min = ((state->min) + lmin) / 2; - printFrameSync (opts, state, "+EDACS", synctest_pos + 1, modulation); - state->lastsynctype = 37; - state->last_cc_sync_time = time(NULL); - return (37); - } + strncpy (synctest32, (synctest_p - 31), 32); + strncpy (synctest48, (synctest_p - 47), 48); + if ((strcmp (synctest32, PROVOICE_SYNC) == 0) || (strcmp (synctest32, PROVOICE_EA_SYNC) == 0)) + { + state->last_cc_sync_time = time(NULL); + state->carrier = 1; + state->offset = synctest_pos; + state->max = ((state->max) + lmax) / 2; + state->min = ((state->min) + lmin) / 2; + sprintf (state->ftype, "ProVoice "); + if (opts->errorbars == 1) + printFrameSync (opts, state, "+PV ", synctest_pos + 1, modulation); + state->lastsynctype = 14; + return (14); + } + else if ((strcmp (synctest32, INV_PROVOICE_SYNC) == 0) || (strcmp (synctest32, INV_PROVOICE_EA_SYNC) == 0)) + { + state->last_cc_sync_time = time(NULL); + state->carrier = 1; + state->offset = synctest_pos; + state->max = ((state->max) + lmax) / 2; + state->min = ((state->min) + lmin) / 2; + sprintf (state->ftype, "ProVoice "); + printFrameSync (opts, state, "-PV ", synctest_pos + 1, modulation); + state->lastsynctype = 15; + return (15); + } + //had error in return type, apparently, local EDACS site is indeed pos polarity, + //so had to flip return syncs + //fixed edacs sync on bin files, was only converting symbols on synctype > 0, didn't need to do that + else if ( strcmp (synctest48, EDACS_SYNC) == 0) + { + state->last_cc_sync_time = time(NULL); + state->carrier = 1; + state->offset = synctest_pos; + state->max = ((state->max) + lmax) / 2; + state->min = ((state->min) + lmin) / 2; + printFrameSync (opts, state, "-EDACS", synctest_pos + 1, modulation); + state->lastsynctype = 38; //14 + return (38); + } + else if ( strcmp (synctest48, INV_EDACS_SYNC) == 0) + { + state->last_cc_sync_time = time(NULL); + state->carrier = 1; + state->offset = synctest_pos; + state->max = ((state->max) + lmax) / 2; + state->min = ((state->min) + lmin) / 2; + printFrameSync (opts, state, "+EDACS", synctest_pos + 1, modulation); + state->lastsynctype = 37; //15 + return (37); + } } - - if ((opts->frame_nxdn96 == 1) || (opts->frame_nxdn48 == 1)) - { - strncpy (synctest18, (synctest_p - 17), 18); - if ((strncmperr (synctest18, NXDN_BS_VOICE_SYNC, 18, 1) == 0) || (strncmperr (synctest18, NXDN_MS_VOICE_SYNC, 18, 1) == 0)) - { - now = time(NULL); - if ((state->lastsynctype == 8) || (state->lastsynctype == 16)) - { - state->carrier = 1; - state->offset = synctest_pos; - state->max = ((state->max) + lmax) / 2; - state->min = ((state->min) + lmin) / 2; - - if (state->samplesPerSymbol == 20) - { - //sprintf (state->ftype, " NXDN48 "); - sprintf (state->ftype, "NXDN48 "); //get rid of spaces - if ( opts->monitor_input_audio == 1) - { - - pa_simple_flush(opts->pulse_raw_dev_out, NULL); - } - if (opts->errorbars == 1) - { - //printFrameSync (opts, state, " +NXDN48 ", synctest_pos + 1, modulation); - printFrameSync (opts, state, "+NXDN48 ", synctest_pos + 1, modulation); - } - } - else - { - sprintf (state->ftype, "NXDN96"); - if ( opts->monitor_input_audio == 1) - { - - pa_simple_flush(opts->pulse_raw_dev_out, NULL); - } - if (opts->errorbars == 1) - { - printFrameSync (opts, state, "+NXDN96 ", synctest_pos + 1, modulation); - } - } - state->lastsynctype = 8; - - return (8); - } - else - { - state->lastsynctype = 8; - } - } - - else if ((strncmperr (synctest18, INV_NXDN_BS_VOICE_SYNC, 18, 1) == 0) || (strncmperr (synctest18, INV_NXDN_MS_VOICE_SYNC, 18, 1) == 0)) //supposed to be voice, not data? - - { - now = time(NULL); //here, or down more - if ((state->lastsynctype == 9) || (state->lastsynctype == 17)) - //if ( (opts->frame_nxdn96 == 1) ||(opts->frame_nxdn48 == 1)) //again, skip the double up - { - state->carrier = 1; - state->offset = synctest_pos; - state->max = ((state->max) + lmax) / 2; - state->min = ((state->min) + lmin) / 2; - if (state->samplesPerSymbol == 20) - { - //sprintf (state->ftype, " NXDN48 "); - sprintf (state->ftype, "NXDN48 "); - if (opts->errorbars == 1) - { - //printFrameSync (opts, state, " -NXDN48 ", synctest_pos + 1, modulation); - printFrameSync (opts, state, " -NXDN48", synctest_pos + 1, modulation); - } - } - else - { - sprintf (state->ftype, "NXDN96 "); - if (opts->errorbars == 1) - { - printFrameSync (opts, state, "-NXDN96 ", synctest_pos + 1, modulation); - } - } - state->lastsynctype = 9; - if ( opts->monitor_input_audio == 1) - { - - pa_simple_flush(opts->pulse_raw_dev_out, NULL); - } - return (9); - } - else - { - state->lastsynctype = 9; - } - } - - else if ((strncmperr (synctest18, NXDN_BS_DATA_SYNC, 18, 1) == 0) || (strncmperr (synctest18, NXDN_MS_DATA_SYNC, 18, 1) == 0)) - { - now = time(NULL); - if ((state->lastsynctype == 8) || (state->lastsynctype == 16)) - //if ( (opts->frame_nxdn96 == 1) ||(opts->frame_nxdn48 == 1)) - { - state->carrier = 1; - state->offset = synctest_pos; - state->max = ((state->max) + lmax) / 2; - state->min = ((state->min) + lmin) / 2; - if (state->samplesPerSymbol == 20) - { - //sprintf (state->ftype, " NXDN48 "); - sprintf (state->ftype, "NXDN48 "); - if (opts->errorbars == 1) - { - //printFrameSync (opts, state, " +NXDN48 ", synctest_pos + 1, modulation); - printFrameSync (opts, state, "+NXDN48 ", synctest_pos + 1, modulation); - } - } - else - { - sprintf (state->ftype, "NXDN96 "); - if (opts->errorbars == 1) - { - printFrameSync (opts, state, "+NXDN96 ", synctest_pos + 1, modulation); - } - } - state->lastsynctype = 16; - if ( opts->monitor_input_audio == 1) - { - - pa_simple_flush(opts->pulse_raw_dev_out, NULL); - } - return (16); - } - else - { - state->lastsynctype = 16; - } - } - - else if ((strncmperr (synctest18, INV_NXDN_BS_DATA_SYNC, 18, 1) == 0) || (strncmperr (synctest18, INV_NXDN_MS_DATA_SYNC, 18, 1) == 0)) - { - now = time(NULL); - if ((state->lastsynctype == 9) || (state->lastsynctype == 17)) - //if ( (opts->frame_nxdn96 == 1) ||(opts->frame_nxdn48 == 1)) - { - state->carrier = 1; - state->offset = synctest_pos; - state->max = ((state->max) + lmax) / 2; - state->min = ((state->min) + lmin) / 2; - //sprintf (state->ftype, " NXDN "); - sprintf (state->ftype, "NXDN "); - if (state->samplesPerSymbol == 20) - { - sprintf (state->ftype, "NXDN48 "); - //sprintf (state->ftype, "NXDN48"); - if (opts->errorbars == 1) - { - printFrameSync (opts, state, "-NXDN48 ", synctest_pos + 1, modulation); - } - } - else - { - sprintf (state->ftype, "NXDN96 "); - if (opts->errorbars == 1) - { - printFrameSync (opts, state, "-NXDN96 ", synctest_pos + 1, modulation); - } - } - state->lastsynctype = 17; - if ( opts->monitor_input_audio == 1) - { - - pa_simple_flush(opts->pulse_raw_dev_out, NULL); - } - return (17); - } - else - { - state->lastsynctype = 17; - - } - } - - } - if (opts->frame_dstar == 1) + + else if (opts->frame_dstar == 1) { if (strcmp (synctest, DSTAR_SYNC) == 0) { - now = time(NULL); state->carrier = 1; state->offset = synctest_pos; state->max = ((state->max) + lmax) / 2; @@ -1457,7 +1246,6 @@ getFrameSync (dsd_opts * opts, dsd_state * state) } if (strcmp (synctest, INV_DSTAR_SYNC) == 0) { - now = time(NULL); state->carrier = 1; state->offset = synctest_pos; state->max = ((state->max) + lmax) / 2; @@ -1477,7 +1265,6 @@ getFrameSync (dsd_opts * opts, dsd_state * state) } if (strcmp (synctest, DSTAR_HD) == 0) { - now = time(NULL); state->carrier = 1; state->offset = synctest_pos; state->max = ((state->max) + lmax) / 2; @@ -1497,7 +1284,6 @@ getFrameSync (dsd_opts * opts, dsd_state * state) } if (strcmp (synctest, INV_DSTAR_HD) == 0) { - now = time(NULL); state->carrier = 1; state->offset = synctest_pos; state->max = ((state->max) + lmax) / 2; @@ -1517,172 +1303,48 @@ getFrameSync (dsd_opts * opts, dsd_state * state) } } - - if ((t == 24) && (state->lastsynctype != -1)) + + //Testing NXDN FSW sync and handling - moved to very bottom of sync stack for falsing sanity + //move printframesync to inside of new nxdn handling when its set up, only run when not bad lich, etc + else if ((opts->frame_nxdn96 == 1) || (opts->frame_nxdn48 == 1)) + { + strncpy (synctest10, (synctest_p - 9), 10); + if ( (strncmperr (synctest10, NXDN_FSW, 10, 1) == 0) ) + //if (strcmp (synctest10, NXDN_FSW) == 0) //this seems to work well on some samples { - // if ((state->lastsynctype == 0) && ((state->lastp25type == 1) || (state->lastp25type == 2))) - // { - // state->carrier = 1; - // state->offset = synctest_pos; - // state->max = ((state->max) + (lmax)) / 2; - // state->min = ((state->min) + (lmin)) / 2; - // sprintf (state->ftype, "(P25 Phase 1) "); - // if (opts->errorbars == 1) - // { - // printFrameSync (opts, state, "(+P25p1) ", synctest_pos + 1, modulation); - // } - // state->lastsynctype = -1; + state->carrier = 1; + state->offset = synctest_pos; + state->max = ((state->max) + lmax) / 2; + state->min = ((state->min) + lmin) / 2; - // return (0); - // } - // else if ((state->lastsynctype == 1) && ((state->lastp25type == 1) || (state->lastp25type == 2))) - // { - // state->carrier = 1; - // state->offset = synctest_pos; - // state->max = ((state->max) + lmax) / 2; - // state->min = ((state->min) + lmin) / 2; - // sprintf (state->ftype, "(P25 Phase 1) "); - // if (opts->errorbars == 1) - // { - // printFrameSync (opts, state, "(-P25p1) ", synctest_pos + 1, modulation); - // } - // state->lastsynctype = -1; + if (state->lastsynctype == 28) + { + state->last_cc_sync_time = time(NULL); + return (28); + } + state->lastsynctype = 28; //need two consecutive patterns to continue - // return (1); - // } - // else if ((state->lastsynctype == 3) && ((strcmp (synctest, X2TDMA_BS_VOICE_SYNC) != 0) || (strcmp (synctest, X2TDMA_MS_VOICE_SYNC) != 0))) - // { - // state->carrier = 1; - // state->offset = synctest_pos; - // state->max = ((state->max) + lmax) / 2; - // state->min = ((state->min) + lmin) / 2; - // sprintf (state->ftype, "(X2-TDMA) "); - // if (opts->errorbars == 1) - // { - // printFrameSync (opts, state, "(-X2-TDMA) ", synctest_pos + 1, modulation); - // } - // state->lastsynctype = -1; + } - // return (3); - // } - // else if ((state->lastsynctype == 4) && ((strcmp (synctest, X2TDMA_BS_DATA_SYNC) != 0) || (strcmp (synctest, X2TDMA_MS_DATA_SYNC) != 0))) - // { - // state->carrier = 1; - // state->offset = synctest_pos; - // state->max = ((state->max) + lmax) / 2; - // state->min = ((state->min) + lmin) / 2; - // sprintf (state->ftype, "(X2-TDMA)"); - // if (opts->errorbars == 1) - // { - // printFrameSync (opts, state, "(+X2-TDMA) ", synctest_pos + 1, modulation); - // } - // state->lastsynctype = -1; + if ( (strncmperr (synctest10, INV_NXDN_FSW, 10, 1) == 0) ) + //if (strcmp (synctest10, INV_NXDN_FSW) == 0) //not so well on others though + { + state->carrier = 1; + state->offset = synctest_pos; + state->max = ((state->max) + lmax) / 2; + state->min = ((state->min) + lmin) / 2; - // return (4); - // } + if (state->lastsynctype == 29) + { + state->last_cc_sync_time = time(NULL); + return (29); + } + state->lastsynctype = 29; //need two consecutive patterns to continue - //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; - 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); - } - */ + } + } - // else if ( (state->lastsynctype == 32) && (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; - // 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 (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 + } // t >= 10 if (exitflag == 1) { @@ -1693,6 +1355,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state) { synctest_pos++; synctest_p++; + } else { @@ -1715,12 +1378,14 @@ getFrameSync (dsd_opts * opts, dsd_state * state) } noCarrier (opts, state); + return (-1); } - } + } } return (-1); + } -//1111 + diff --git a/src/dsd_mbe.c b/src/dsd_mbe.c index 6d19eb4..d1ced58 100644 --- a/src/dsd_mbe.c +++ b/src/dsd_mbe.c @@ -201,7 +201,7 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a saveAmbe2450Data (opts, state, ambe_d); } } - else if ((state->synctype == 8) || (state->synctype == 9)) + else if ((state->synctype == 28) || (state->synctype == 29)) //was 8 and 9 { state->errs = mbe_eccAmbe3600x2450C0 (ambe_fr); diff --git a/src/dsd_symbol.c b/src/dsd_symbol.c index 9e56b04..cbc7203 100644 --- a/src/dsd_symbol.c +++ b/src/dsd_symbol.c @@ -178,18 +178,25 @@ getSymbol (dsd_opts * opts, dsd_state * state, int have_sync) state->lastsynctype == 20 || state->lastsynctype == 21 || state->lastsynctype == 22 || state->lastsynctype == 23 || state->lastsynctype == 24 || state->lastsynctype == 25 || - state->lastsynctype == 26 || state->lastsynctype == 27 ) //|| - //state->lastsynctype == 35 || state->lastsynctype == 36) //phase 2 + state->lastsynctype == 26 || state->lastsynctype == 27 || + state->lastsynctype == 28 || state->lastsynctype == 29 ) //|| + //state->lastsynctype == 35 || state->lastsynctype == 36) //phase 2 C4FM disc tap input { - if(state->samplesPerSymbol == 20) + //if(state->samplesPerSymbol == 20) + if(opts->frame_nxdn48 == 1) { sample = nxdn_filter(sample); } + //else if (state->lastsynctype >= 20 && state->lastsynctype <=27) //this the right range? + else if (opts->frame_dpmr == 1) + { + sample = dpmr_filter(sample); + } else if (state->samplesPerSymbol == 8) //phase 2 cqpsk { //sample = dmr_filter(sample); //work on filter later } - else // the 12.5KHz NXDN filter is the same as the DMR filter + else // the 12.5KHz NXDN filter is the same as the DMR filter...hopefully { sample = dmr_filter(sample); }