/*==================================================================================== EVS Codec 3GPP TS26.443 Jun 30, 2015. Version CR 26.443-0006 ====================================================================================*/ #include "g192.h" #include #include #include #include #ifndef _WIN32 #include #include #else #include typedef unsigned short uint16_t; typedef signed short int16_t; typedef unsigned int uint32_t; typedef signed int int32_t; typedef unsigned __int64 uint64_t; typedef signed __int64 int64_t; #endif #ifdef _MSC_VER #pragma warning( disable : 4996 ) #endif #define G192_SYNC_GOOD_FRAME (unsigned short) 0x6B21 #define G192_SYNC_BAD_FRAME (unsigned short) 0x6B20 #define G192_BIT0 (unsigned short) 0x007F #define G192_BIT1 (unsigned short) 0x0081 #define RTP_HEADER_PART1 (short)22 /* magic number by network simulator */ #ifndef MAX_BITS_PER_FRAME #define MAX_BITS_PER_FRAME 2560 #endif /* * Structures */ /* main handle */ struct __G192 { FILE * file; }; /* * Functions */ G192_ERROR G192_Reader_Open(G192_HANDLE* phG192, FILE * filename) { /* create handle */ *phG192 = (G192_HANDLE) calloc(1, sizeof(struct __G192) ); if ( !phG192 ) return G192_MEMORY_ERROR; memset(*phG192, 0, sizeof(struct __G192)); /* associate file stream */ (*phG192)->file = filename; if( (*phG192)->file == NULL ) { return G192_FILE_NOT_FOUND; } return G192_NO_ERROR; } G192_ERROR G192_ReadVoipFrame_compact(G192_HANDLE const hG192, unsigned char * const serial, short * const num_bits, unsigned short * const rtpSequenceNumber, unsigned int * const rtpTimeStamp, unsigned int * const rcvTime_ms) { short short_serial [MAX_BITS_PER_FRAME]; G192_ERROR err; short i; err = G192_ReadVoipFrame_short(hG192, short_serial, num_bits, rtpSequenceNumber, rtpTimeStamp, rcvTime_ms); if(err != G192_NO_ERROR) return err; for(i=0; i<*num_bits; i++) { unsigned char bit = (short_serial[i] == G192_BIT1) ? 1 : 0; unsigned char bitinbyte = bit << (7- (i&0x7)); if(!(i&0x7)) serial[i>>3] = 0; serial[i>>3] |= bitinbyte; } return G192_NO_ERROR; } G192_ERROR G192_ReadVoipFrame_short(G192_HANDLE const hG192, short * const serial, short * const num_bits, unsigned short * const rtpSequenceNumber, unsigned int * const rtpTimeStamp, unsigned int * const rcvTime_ms) { uint32_t rtpPacketSize; uint16_t rtpPacketHeaderPart1; uint32_t ssrc; uint16_t rtpPayloadG192[2]; uint16_t rtpPayloadSize; /* RTP packet size */ if(fread(&rtpPacketSize, sizeof(rtpPacketSize), 1, hG192->file) != 1) return G192_READ_ERROR; if(rtpPacketSize <= 12) { fprintf(stderr, "RTP Packet size too small: %ud\n", rtpPacketSize); return G192_READ_ERROR; } /* RTP packet arrival time */ if(fread(rcvTime_ms, sizeof(*rcvTime_ms), 1, hG192->file) != 1) return G192_READ_ERROR; /* RTP packet header (part without sequence number) */ if(fread(&rtpPacketHeaderPart1, sizeof(rtpPacketHeaderPart1), 1, hG192->file) != 1) return G192_READ_ERROR; if(rtpPacketHeaderPart1 != RTP_HEADER_PART1) { fprintf(stderr, "Unexpected RTP Packet header\n"); return G192_READ_ERROR; } /* RTP sequence number */ if(fread(rtpSequenceNumber, sizeof(*rtpSequenceNumber), 1, hG192->file) != 1) return G192_READ_ERROR; *rtpSequenceNumber = ntohs(*rtpSequenceNumber); /* RTP timestamp */ if(fread(rtpTimeStamp, sizeof(*rtpTimeStamp), 1, hG192->file) != 1) return G192_READ_ERROR; *rtpTimeStamp = ntohl(*rtpTimeStamp); /* RTP ssrc */ if(fread(&ssrc, sizeof(ssrc), 1, hG192->file) != 1) return G192_READ_ERROR; /* RTP payload size */ rtpPayloadSize = rtpPacketSize - 12; if(rtpPayloadSize <= 2) { fprintf(stderr, "RTP payload size too small: %u\n", rtpPayloadSize); return G192_READ_ERROR; } /* RTP payload */ if(fread(rtpPayloadG192, sizeof(short), 2, hG192->file) != 2) { fprintf(stderr, "Premature end of file, cannot read G.192 header\n"); return G192_READ_ERROR; } if(rtpPayloadG192[0] != G192_SYNC_GOOD_FRAME) { fprintf(stderr, "G192_SYNC_WORD missing from RTP payload!"); return G192_READ_ERROR; } *num_bits = rtpPayloadG192[1]; if(*num_bits == 0u || *num_bits + 2u != rtpPayloadSize || *num_bits > MAX_BITS_PER_FRAME) { fprintf(stderr, "error in parsing RTP payload: rtpPayloadSize=%u nBits=%d", rtpPayloadSize, *num_bits); return G192_READ_ERROR; } if( fread(serial, sizeof(short), *num_bits, hG192->file) != (unsigned short)*num_bits) { fprintf(stderr, "Premature end of file, cannot read G.192 payload\n"); return G192_READ_ERROR; } return G192_NO_ERROR; } G192_ERROR G192_Reader_Close(G192_HANDLE* phG192) { if(phG192 == NULL || *phG192 == NULL) return G192_NO_ERROR; free( *phG192 ); *phG192 = NULL; phG192 = NULL; return G192_NO_ERROR; }