aboutsummaryrefslogtreecommitdiff
path: root/src/freedv_vhf_framing.c
diff options
context:
space:
mode:
authordrowe67 <[email protected]>2023-07-20 08:59:48 +0930
committerGitHub <[email protected]>2023-07-20 08:59:48 +0930
commit06d4c11e699b0351765f10398abb4f663a984f36 (patch)
tree33e22af0814c5b6c3d676f096ae8c2ac8a3ed9f0 /src/freedv_vhf_framing.c
parent6588e77f38bdebd7adffe091b22e7760d95d0ccb (diff)
parent4d6c143c0abec15e1d6ed1fd95d36f80e6cb7df8 (diff)
Merge pull request #3 from drowe67/dr-cleanup21.2.0
Cleanup Part 2
Diffstat (limited to 'src/freedv_vhf_framing.c')
-rw-r--r--src/freedv_vhf_framing.c1503
1 files changed, 754 insertions, 749 deletions
diff --git a/src/freedv_vhf_framing.c b/src/freedv_vhf_framing.c
index 6e2ed93..d596025 100644
--- a/src/freedv_vhf_framing.c
+++ b/src/freedv_vhf_framing.c
@@ -34,833 +34,838 @@
along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "freedv_vhf_framing.h"
+#include <assert.h>
#include <stdint.h>
-#include <stdlib.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
-#include <assert.h>
-#include "freedv_vhf_framing.h"
+
#include "freedv_api_internal.h"
/* The voice UW of the VHF type A frame */
-static const uint8_t A_uw_v[] = {0,1,1,0,0,1,1,1,
- 1,0,1,0,1,1,0,1};
+static const uint8_t A_uw_v[] = {0, 1, 1, 0, 0, 1, 1, 1,
+ 1, 0, 1, 0, 1, 1, 0, 1};
/* The data UW of the VHF type A frame */
-static const uint8_t A_uw_d[] = {1,1,1,1,0,0,0,1,
- 1,1,1,1,1,1,0,0};
+static const uint8_t A_uw_d[] = {1, 1, 1, 1, 0, 0, 0, 1,
+ 1, 1, 1, 1, 1, 1, 0, 0};
/* Blank VHF type A frame */
-static const uint8_t A_blank[] = {1,0,1,0,0,1,1,1, /* Padding[0:3] Proto[0:3] */
- 1,0,1,0,0,1,1,1, /* Proto[4:11] */
- 0,0,0,0,0,0,0,0, /* Voice[0:7] */
- 0,0,0,0,0,0,0,0, /* Voice[8:15] */
- 0,0,0,0,0,0,0,0, /* Voice[16:23] */
- 0,1,1,0,0,1,1,1, /* UW[0:7] */
- 1,0,1,0,1,1,0,1, /* UW[8:15] */
- 0,0,0,0,0,0,0,0, /* Voice[24:31] */
- 0,0,0,0,0,0,0,0, /* Voice[32:39] */
- 0,0,0,0,0,0,0,0, /* Voice[40:47] */
- 0,0,0,0,0,0,1,0, /* Voice[48:51] Proto[12:15] */
- 0,1,1,1,0,0,1,0};/* Proto[16:19] Padding[4:7] */
-
+static const uint8_t A_blank[] = {
+ 1, 0, 1, 0, 0, 1, 1, 1, /* Padding[0:3] Proto[0:3] */
+ 1, 0, 1, 0, 0, 1, 1, 1, /* Proto[4:11] */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* Voice[0:7] */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* Voice[8:15] */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* Voice[16:23] */
+ 0, 1, 1, 0, 0, 1, 1, 1, /* UW[0:7] */
+ 1, 0, 1, 0, 1, 1, 0, 1, /* UW[8:15] */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* Voice[24:31] */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* Voice[32:39] */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* Voice[40:47] */
+ 0, 0, 0, 0, 0, 0, 1, 0, /* Voice[48:51] Proto[12:15] */
+ 0, 1, 1, 1, 0, 0, 1, 0}; /* Proto[16:19] Padding[4:7] */
+
/* Blank VHF type AT (A for TDMA; padding bits not transmitted) frame */
-static const uint8_t AT_blank[] = { 0,1,1,1, /* Proto[0:3] */
- 1,0,1,0,0,1,1,1, /* Proto[4:11] */
- 0,0,0,0,0,0,0,0, /* Voice[0:7] */
- 0,0,0,0,0,0,0,0, /* Voice[8:15] */
- 0,0,0,0,0,0,0,0, /* Voice[16:23] */
- 0,1,1,0,0,1,1,1, /* UW[0:7] */
- 1,0,1,0,1,1,0,1, /* UW[8:15] */
- 0,0,0,0,0,0,0,0, /* Voice[24:31] */
- 0,0,0,0,0,0,0,0, /* Voice[32:39] */
- 0,0,0,0,0,0,0,0, /* Voice[40:47] */
- 0,0,0,0,0,0,1,0, /* Voice[48:51] Proto[12:15] */
- 0,1,1,1 };/* Proto[16:19] */
+static const uint8_t AT_blank[] = {
+ 0, 1, 1, 1, /* Proto[0:3] */
+ 1, 0, 1, 0, 0, 1, 1, 1, /* Proto[4:11] */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* Voice[0:7] */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* Voice[8:15] */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* Voice[16:23] */
+ 0, 1, 1, 0, 0, 1, 1, 1, /* UW[0:7] */
+ 1, 0, 1, 0, 1, 1, 0, 1, /* UW[8:15] */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* Voice[24:31] */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* Voice[32:39] */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* Voice[40:47] */
+ 0, 0, 0, 0, 0, 0, 1, 0, /* Voice[48:51] Proto[12:15] */
+ 0, 1, 1, 1}; /* Proto[16:19] */
/* HF Type B voice UW */
-static const uint8_t B_uw_v[] = {0,1,1,0,0,1,1,1};
+static const uint8_t B_uw_v[] = {0, 1, 1, 0, 0, 1, 1, 1};
/* HF Type B data UW */
-static const uint8_t B_uw_d[] = {1,1,1,1,0,0,1,0};
-
+static const uint8_t B_uw_d[] = {1, 1, 1, 1, 0, 0, 1, 0};
+
/* Blank HF type B frame */
-static const uint8_t B_blank[] = {0,1,1,0,0,1,1,1, /* UW[0:7] */
- 0,0,0,0,0,0,0,0, /* Voice1[0:7] */
- 0,0,0,0,0,0,0,0, /* Voice1[8:15] */
- 0,0,0,0,0,0,0,0, /* Voice1[16:23] */
- 0,0,0,0,0,0,0,0, /* Voice1[24:28] Voice2[0:3] */
- 0,0,0,0,0,0,0,0, /* Voice2[4:11] */
- 0,0,0,0,0,0,0,0, /* Voice2[12:19] */
- 0,0,0,0,0,0,0,0};/* Voice2[20:28] */
+static const uint8_t B_blank[] = {
+ 0, 1, 1, 0, 0, 1, 1, 1, /* UW[0:7] */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* Voice1[0:7] */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* Voice1[8:15] */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* Voice1[16:23] */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* Voice1[24:28] Voice2[0:3] */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* Voice2[4:11] */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* Voice2[12:19] */
+ 0, 0, 0, 0, 0, 0, 0, 0}; /* Voice2[20:28] */
/* States */
#define ST_NOSYNC 0 /* Not synchronized */
#define ST_SYNC 1 /* Synchronized */
/* Get a single bit out of an MSB-first packed byte array */
-#define UNPACK_BIT_MSBFIRST(bytes,bitidx) ((bytes)[(bitidx)>>3]>>(7-((bitidx)&0x7)))&0x1
+#define UNPACK_BIT_MSBFIRST(bytes, bitidx) \
+ ((bytes)[(bitidx) >> 3] >> (7 - ((bitidx)&0x7))) & 0x1
enum frame_payload_type {
- FRAME_PAYLOAD_TYPE_VOICE,
- FRAME_PAYLOAD_TYPE_DATA,
+ FRAME_PAYLOAD_TYPE_VOICE,
+ FRAME_PAYLOAD_TYPE_DATA,
};
/* Place codec and other bits into a frame */
-void fvhff_frame_bits( int frame_type,
- uint8_t bits_out[],
- uint8_t codec2_in[],
- uint8_t proto_in[],
- uint8_t vc_in[]){
- int i,ibit;
- if(frame_type == FREEDV_VHF_FRAME_A){
- /* Fill out frame with blank frame prototype */
- for(i=0; i<96; i++)
- bits_out[i] = A_blank[i];
-
- /* Fill in protocol bits, if present */
- if(proto_in!=NULL){
- ibit = 0;
- /* First half of protocol bits */
- /* Extract and place in frame, MSB first */
- for(i=4 ; i<16; i++){
- bits_out[i] = UNPACK_BIT_MSBFIRST(proto_in,ibit);
- ibit++;
- }
- /* Last set of protocol bits */
- for(i=84; i<92; i++){
- bits_out[i] = UNPACK_BIT_MSBFIRST(proto_in,ibit);
- ibit++;
- }
- }
-
- /* Fill in varicode bits, if present */
- if(vc_in!=NULL){
- bits_out[90] = vc_in[0];
- bits_out[91] = vc_in[1];
- }
-
- /* Fill in codec2 bits, present or not */
- ibit = 0;
- for(i=16; i<40; i++){ /* First half */
- bits_out[i] = UNPACK_BIT_MSBFIRST(codec2_in,ibit);
- ibit++;
- }
- for(i=56; i<84; i++){ /* Second half */
- bits_out[i] = UNPACK_BIT_MSBFIRST(codec2_in,ibit);
- ibit++;
- }
- }else if(frame_type == FREEDV_HF_FRAME_B){
- /* Pointers to both c2 frames so the bit unpack macro works */
- uint8_t * codec2_in1 = &codec2_in[0];
- uint8_t * codec2_in2 = &codec2_in[4];
- /* Fill out frame with blank prototype */
- for(i=0; i<64; i++)
- bits_out[i] = B_blank[i];
-
- /* Fill out first codec2 block */
- ibit=0;
- for(i=8; i<36; i++){
- bits_out[i] = UNPACK_BIT_MSBFIRST(codec2_in1,ibit);
- ibit++;
- }
- /* Fill out second codec2 block */
- ibit=0;
- for(i=36; i<64; i++){
- bits_out[i] = UNPACK_BIT_MSBFIRST(codec2_in2,ibit);
- ibit++;
- }
- }else if(frame_type == FREEDV_VHF_FRAME_AT){
- /* Fill out frame with blank frame prototype */
- for(i=0; i<88; i++)
- bits_out[i] = AT_blank[i];
-
- /* Fill in protocol bits, if present */
- if(proto_in!=NULL){
- ibit = 0;
- /* First half of protocol bits */
- /* Extract and place in frame, MSB first */
- for(i=0 ; i<12; i++){
- bits_out[i] = UNPACK_BIT_MSBFIRST(proto_in,ibit);
- ibit++;
- }
- /* Last set of protocol bits */
- for(i=80; i<88; i++){
- bits_out[i] = UNPACK_BIT_MSBFIRST(proto_in,ibit);
- ibit++;
- }
- }
-
- /* Fill in varicode bits, if present */
- if(vc_in!=NULL){
- bits_out[86] = vc_in[0];
- bits_out[87] = vc_in[1];
- }
-
- /* Fill in codec2 bits, present or not */
- ibit = 0;
- for(i=12; i<36; i++){ /* First half */
- bits_out[i] = UNPACK_BIT_MSBFIRST(codec2_in,ibit);
- ibit++;
- }
- for(i=52; i<80; i++){ /* Second half */
- bits_out[i] = UNPACK_BIT_MSBFIRST(codec2_in,ibit);
- ibit++;
- }
+void fvhff_frame_bits(int frame_type, uint8_t bits_out[], uint8_t codec2_in[],
+ uint8_t proto_in[], uint8_t vc_in[]) {
+ int i, ibit;
+ if (frame_type == FREEDV_VHF_FRAME_A) {
+ /* Fill out frame with blank frame prototype */
+ for (i = 0; i < 96; i++) bits_out[i] = A_blank[i];
+
+ /* Fill in protocol bits, if present */
+ if (proto_in != NULL) {
+ ibit = 0;
+ /* First half of protocol bits */
+ /* Extract and place in frame, MSB first */
+ for (i = 4; i < 16; i++) {
+ bits_out[i] = UNPACK_BIT_MSBFIRST(proto_in, ibit);
+ ibit++;
+ }
+ /* Last set of protocol bits */
+ for (i = 84; i < 92; i++) {
+ bits_out[i] = UNPACK_BIT_MSBFIRST(proto_in, ibit);
+ ibit++;
+ }
+ }
+
+ /* Fill in varicode bits, if present */
+ if (vc_in != NULL) {
+ bits_out[90] = vc_in[0];
+ bits_out[91] = vc_in[1];
+ }
+
+ /* Fill in codec2 bits, present or not */
+ ibit = 0;
+ for (i = 16; i < 40; i++) { /* First half */
+ bits_out[i] = UNPACK_BIT_MSBFIRST(codec2_in, ibit);
+ ibit++;
+ }
+ for (i = 56; i < 84; i++) { /* Second half */
+ bits_out[i] = UNPACK_BIT_MSBFIRST(codec2_in, ibit);
+ ibit++;
+ }
+ } else if (frame_type == FREEDV_HF_FRAME_B) {
+ /* Pointers to both c2 frames so the bit unpack macro works */
+ uint8_t *codec2_in1 = &codec2_in[0];
+ uint8_t *codec2_in2 = &codec2_in[4];
+ /* Fill out frame with blank prototype */
+ for (i = 0; i < 64; i++) bits_out[i] = B_blank[i];
+
+ /* Fill out first codec2 block */
+ ibit = 0;
+ for (i = 8; i < 36; i++) {
+ bits_out[i] = UNPACK_BIT_MSBFIRST(codec2_in1, ibit);
+ ibit++;
}
+ /* Fill out second codec2 block */
+ ibit = 0;
+ for (i = 36; i < 64; i++) {
+ bits_out[i] = UNPACK_BIT_MSBFIRST(codec2_in2, ibit);
+ ibit++;
+ }
+ } else if (frame_type == FREEDV_VHF_FRAME_AT) {
+ /* Fill out frame with blank frame prototype */
+ for (i = 0; i < 88; i++) bits_out[i] = AT_blank[i];
+
+ /* Fill in protocol bits, if present */
+ if (proto_in != NULL) {
+ ibit = 0;
+ /* First half of protocol bits */
+ /* Extract and place in frame, MSB first */
+ for (i = 0; i < 12; i++) {
+ bits_out[i] = UNPACK_BIT_MSBFIRST(proto_in, ibit);
+ ibit++;
+ }
+ /* Last set of protocol bits */
+ for (i = 80; i < 88; i++) {
+ bits_out[i] = UNPACK_BIT_MSBFIRST(proto_in, ibit);
+ ibit++;
+ }
+ }
+
+ /* Fill in varicode bits, if present */
+ if (vc_in != NULL) {
+ bits_out[86] = vc_in[0];
+ bits_out[87] = vc_in[1];
+ }
+
+ /* Fill in codec2 bits, present or not */
+ ibit = 0;
+ for (i = 12; i < 36; i++) { /* First half */
+ bits_out[i] = UNPACK_BIT_MSBFIRST(codec2_in, ibit);
+ ibit++;
+ }
+ for (i = 52; i < 80; i++) { /* Second half */
+ bits_out[i] = UNPACK_BIT_MSBFIRST(codec2_in, ibit);
+ ibit++;
+ }
+ }
}
/* Place data and other bits into a frame */
-void fvhff_frame_data_bits(struct freedv_vhf_deframer * def, int frame_type,
- uint8_t bits_out[]){
- int i,ibit;
- if(frame_type == FREEDV_VHF_FRAME_A){
- uint8_t data[8];
- int end_bits;
- int from_bit;
- int bcast_bit;
- int crc_bit;
-
- /* Fill out frame with blank frame prototype */
- for(i=0; i<4; i++)
- bits_out[i] = A_blank[i];
- for(i=92; i<96; i++)
- bits_out[i] = A_blank[i];
-
- /* UW data */
- for (i=0; i < 16; i++)
- bits_out[40 + i] = A_uw_d[i];
-
- if (def->fdc)
- freedv_data_channel_tx_frame(def->fdc, data, 8, &from_bit, &bcast_bit, &crc_bit, &end_bits);
- else
- return;
-
- bits_out[4] = from_bit;
- bits_out[5] = bcast_bit;
- bits_out[6] = 0; /* unused */
- bits_out[7] = 0; /* unused */
-
- /* Fill in data bits */
- ibit = 0;
- for(i=8; i<40; i++){ /* First half */
- bits_out[i] = UNPACK_BIT_MSBFIRST(data,ibit);
- ibit++;
- }
- for(i=56; i<88; i++){ /* Second half */
- bits_out[i] = UNPACK_BIT_MSBFIRST(data,ibit);
- ibit++;
- }
+void fvhff_frame_data_bits(struct freedv_vhf_deframer *def, int frame_type,
+ uint8_t bits_out[]) {
+ int i, ibit;
+ if (frame_type == FREEDV_VHF_FRAME_A) {
+ uint8_t data[8];
+ int end_bits;
+ int from_bit;
+ int bcast_bit;
+ int crc_bit;
+
+ /* Fill out frame with blank frame prototype */
+ for (i = 0; i < 4; i++) bits_out[i] = A_blank[i];
+ for (i = 92; i < 96; i++) bits_out[i] = A_blank[i];
+
+ /* UW data */
+ for (i = 0; i < 16; i++) bits_out[40 + i] = A_uw_d[i];
+
+ if (def->fdc)
+ freedv_data_channel_tx_frame(def->fdc, data, 8, &from_bit, &bcast_bit,
+ &crc_bit, &end_bits);
+ else
+ return;
+
+ bits_out[4] = from_bit;
+ bits_out[5] = bcast_bit;
+ bits_out[6] = 0; /* unused */
+ bits_out[7] = 0; /* unused */
+
+ /* Fill in data bits */
+ ibit = 0;
+ for (i = 8; i < 40; i++) { /* First half */
+ bits_out[i] = UNPACK_BIT_MSBFIRST(data, ibit);
+ ibit++;
+ }
+ for (i = 56; i < 88; i++) { /* Second half */
+ bits_out[i] = UNPACK_BIT_MSBFIRST(data, ibit);
+ ibit++;
+ }
- for (i = 0; i < 4; i++)
- bits_out[88 + i] = (end_bits >> (3-i)) & 0x1;
- } else if (frame_type == FREEDV_HF_FRAME_B){
- uint8_t data[6];
- int end_bits;
- int from_bit;
- int bcast_bit;
- int crc_bit;
-
- /* Fill out frame with blank prototype */
- for(i=0; i<64; i++)
- bits_out[i] = B_blank[i];
-
- /* UW data */
- for (i=0; i < 8; i++)
- bits_out[0 + i] = B_uw_d[i];
-
- if (def->fdc)
- freedv_data_channel_tx_frame(def->fdc, data, 6, &from_bit, &bcast_bit, &crc_bit, &end_bits);
- else
- return;
-
- bits_out[56] = from_bit;
- bits_out[57] = bcast_bit;
- bits_out[58] = crc_bit;
- bits_out[59] = 0; /* unused */
-
- /* Fill in data bits */
- ibit = 0;
- for(i=8; i<56; i++){ /* First half */
- bits_out[i] = UNPACK_BIT_MSBFIRST(data,ibit);
- ibit++;
- }
- for (i = 0; i < 4; i++)
- bits_out[60 + i] = (end_bits >> (3-i)) & 0x1;
+ for (i = 0; i < 4; i++) bits_out[88 + i] = (end_bits >> (3 - i)) & 0x1;
+ } else if (frame_type == FREEDV_HF_FRAME_B) {
+ uint8_t data[6];
+ int end_bits;
+ int from_bit;
+ int bcast_bit;
+ int crc_bit;
+
+ /* Fill out frame with blank prototype */
+ for (i = 0; i < 64; i++) bits_out[i] = B_blank[i];
+
+ /* UW data */
+ for (i = 0; i < 8; i++) bits_out[0 + i] = B_uw_d[i];
+
+ if (def->fdc)
+ freedv_data_channel_tx_frame(def->fdc, data, 6, &from_bit, &bcast_bit,
+ &crc_bit, &end_bits);
+ else
+ return;
+
+ bits_out[56] = from_bit;
+ bits_out[57] = bcast_bit;
+ bits_out[58] = crc_bit;
+ bits_out[59] = 0; /* unused */
+
+ /* Fill in data bits */
+ ibit = 0;
+ for (i = 8; i < 56; i++) { /* First half */
+ bits_out[i] = UNPACK_BIT_MSBFIRST(data, ibit);
+ ibit++;
}
+ for (i = 0; i < 4; i++) bits_out[60 + i] = (end_bits >> (3 - i)) & 0x1;
+ }
}
/* Init and allocate memory for a freedv-vhf framer/deframer */
-struct freedv_vhf_deframer * fvhff_create_deframer(uint8_t frame_type, int enable_bit_flip){
- struct freedv_vhf_deframer * deframer;
- uint8_t *bits,*invbits;
- int frame_size;
- int uw_size;
-
- assert( (frame_type == FREEDV_VHF_FRAME_A) || (frame_type == FREEDV_HF_FRAME_B) );
-
- /* It's a Type A frame */
- if(frame_type == FREEDV_VHF_FRAME_A){
- frame_size = 96;
- uw_size = 16;
- }else if(frame_type == FREEDV_HF_FRAME_B){
- frame_size = 64;
- uw_size = 8;
- }else{
- return NULL;
- }
-
- /* Allocate memory for the thing */
- deframer = malloc(sizeof(struct freedv_vhf_deframer));
- if(deframer == NULL)
- return NULL;
-
- /* Allocate the not-bit buffer */
- if(enable_bit_flip){
- invbits = malloc(sizeof(uint8_t)*frame_size);
- if(invbits == NULL) {
- free(deframer);
- return NULL;
- }
- }else{
- invbits = NULL;
- }
-
- /* Allocate the bit buffer */
- bits = malloc(sizeof(uint8_t)*frame_size);
- if(bits == NULL) {
- free(deframer);
- return NULL;
- }
-
- deframer->bits = bits;
- deframer->invbits = invbits;
- deframer->ftype = frame_type;
- deframer->state = ST_NOSYNC;
- deframer->bitptr = 0;
- deframer->last_uw = 0;
- deframer->miss_cnt = 0;
- deframer->frame_size = frame_size;
- deframer->uw_size = uw_size;
- deframer->on_inv_bits = 0;
- deframer->sym_size = 1;
-
- deframer->ber_est = 0;
- deframer->total_uw_bits = 0;
- deframer->total_uw_err = 0;
-
- deframer->fdc = NULL;
-
- return deframer;
+struct freedv_vhf_deframer *fvhff_create_deframer(uint8_t frame_type,
+ int enable_bit_flip) {
+ struct freedv_vhf_deframer *deframer;
+ uint8_t *bits, *invbits;
+ int frame_size;
+ int uw_size;
+
+ assert((frame_type == FREEDV_VHF_FRAME_A) ||
+ (frame_type == FREEDV_HF_FRAME_B));
+
+ /* It's a Type A frame */
+ if (frame_type == FREEDV_VHF_FRAME_A) {
+ frame_size = 96;
+ uw_size = 16;
+ } else if (frame_type == FREEDV_HF_FRAME_B) {
+ frame_size = 64;
+ uw_size = 8;
+ } else {
+ return NULL;
+ }
+
+ /* Allocate memory for the thing */
+ deframer = malloc(sizeof(struct freedv_vhf_deframer));
+ if (deframer == NULL) return NULL;
+
+ /* Allocate the not-bit buffer */
+ if (enable_bit_flip) {
+ invbits = malloc(sizeof(uint8_t) * frame_size);
+ if (invbits == NULL) {
+ free(deframer);
+ return NULL;
+ }
+ } else {
+ invbits = NULL;
+ }
+
+ /* Allocate the bit buffer */
+ bits = malloc(sizeof(uint8_t) * frame_size);
+ if (bits == NULL) {
+ free(deframer);
+ return NULL;
+ }
+
+ deframer->bits = bits;
+ deframer->invbits = invbits;
+ deframer->ftype = frame_type;
+ deframer->state = ST_NOSYNC;
+ deframer->bitptr = 0;
+ deframer->last_uw = 0;
+ deframer->miss_cnt = 0;
+ deframer->frame_size = frame_size;
+ deframer->uw_size = uw_size;
+ deframer->on_inv_bits = 0;
+ deframer->sym_size = 1;
+
+ deframer->ber_est = 0;
+ deframer->total_uw_bits = 0;
+ deframer->total_uw_err = 0;
+
+ deframer->fdc = NULL;
+
+ return deframer;
}
/* Get size of frame in bits */
-int fvhff_get_frame_size(struct freedv_vhf_deframer * def){
- return def->frame_size;
+int fvhff_get_frame_size(struct freedv_vhf_deframer *def) {
+ return def->frame_size;
}
/* Codec2 size in bytes */
-int fvhff_get_codec2_size(struct freedv_vhf_deframer * def){
- if(def->ftype == FREEDV_VHF_FRAME_A){
- return 7;
- } else if(def->ftype == FREEDV_HF_FRAME_B){
- return 8;
- } else{
- return 0;
- }
+int fvhff_get_codec2_size(struct freedv_vhf_deframer *def) {
+ if (def->ftype == FREEDV_VHF_FRAME_A) {
+ return 7;
+ } else if (def->ftype == FREEDV_HF_FRAME_B) {
+ return 8;
+ } else {
+ return 0;
+ }
}
/* Protocol bits in bits */
-int fvhff_get_proto_size(struct freedv_vhf_deframer * def){
- if(def->ftype == FREEDV_VHF_FRAME_A){
- return 20;
- } else if(def->ftype == FREEDV_HF_FRAME_B){
- return 0;
- } else{
- return 0;
- }
+int fvhff_get_proto_size(struct freedv_vhf_deframer *def) {
+ if (def->ftype == FREEDV_VHF_FRAME_A) {
+ return 20;
+ } else if (def->ftype == FREEDV_HF_FRAME_B) {
+ return 0;
+ } else {
+ return 0;
+ }
}
/* Varicode bits in bits */
-int fvhff_get_varicode_size(struct freedv_vhf_deframer * def){
- if(def->ftype == FREEDV_VHF_FRAME_A){
- return 2;
- } else if(def->ftype == FREEDV_HF_FRAME_B){
- return 0;
- } else{
- return 0;
- }
+int fvhff_get_varicode_size(struct freedv_vhf_deframer *def) {
+ if (def->ftype == FREEDV_VHF_FRAME_A) {
+ return 2;
+ } else if (def->ftype == FREEDV_HF_FRAME_B) {
+ return 0;
+ } else {
+ return 0;
+ }
}
-void fvhff_destroy_deframer(struct freedv_vhf_deframer * def){
- freedv_data_channel_destroy(def->fdc);
- free(def->bits);
- free(def);
+void fvhff_destroy_deframer(struct freedv_vhf_deframer *def) {
+ freedv_data_channel_destroy(def->fdc);
+ free(def->bits);
+ free(def);
}
-int fvhff_synchronized(struct freedv_vhf_deframer * def){
- return (def->state) == ST_SYNC;
+int fvhff_synchronized(struct freedv_vhf_deframer *def) {
+ return (def->state) == ST_SYNC;
}
/* Search for a complete UW in a buffer of bits */
-size_t fvhff_search_uw(const uint8_t bits[],size_t nbits,
- const uint8_t uw[], size_t uw_len,
- size_t * delta_out, size_t bits_per_sym){
-
- size_t ibits,iuw;
- size_t delta_min = uw_len;
- size_t delta;
- size_t offset_min = 0;
- /* Walk through buffer bits */
- for(ibits = 0; ibits < nbits-uw_len; ibits+=bits_per_sym){
- delta = 0;
- for(iuw = 0; iuw < uw_len; iuw++){
- if(bits[ibits+iuw] != uw[iuw]) delta++;
- }
- if( delta < delta_min ){
- delta_min = delta;
- offset_min = ibits;
- }
+size_t fvhff_search_uw(const uint8_t bits[], size_t nbits, const uint8_t uw[],
+ size_t uw_len, size_t *delta_out, size_t bits_per_sym) {
+ size_t ibits, iuw;
+ size_t delta_min = uw_len;
+ size_t delta;
+ size_t offset_min = 0;
+ /* Walk through buffer bits */
+ for (ibits = 0; ibits < nbits - uw_len; ibits += bits_per_sym) {
+ delta = 0;
+ for (iuw = 0; iuw < uw_len; iuw++) {
+ if (bits[ibits + iuw] != uw[iuw]) delta++;
+ }
+ if (delta < delta_min) {
+ delta_min = delta;
+ offset_min = ibits;
}
- if(delta_out != NULL) *delta_out = delta_min;
- return offset_min;
+ }
+ if (delta_out != NULL) *delta_out = delta_min;
+ return offset_min;
}
-/* See if the UW is where it should be, to within a tolerance, in a bit buffer */
-static int fvhff_match_uw(struct freedv_vhf_deframer * def,uint8_t bits[],int tol,int *rdiff, enum frame_payload_type *pt){
- int frame_type = def->ftype;
- int bitptr = def->bitptr;
- int frame_size = def->frame_size;
- int uw_len = def->uw_size;
- int iuw,ibit;
- const uint8_t * uw[2];
- int uw_offset;
- int diff[2] = { 0, 0 };
- int i;
- int match[2];
- int r;
-
- /* defaults to make compiler happy on -O3 */
-
- *pt = FRAME_PAYLOAD_TYPE_VOICE;
- *rdiff = 0;
-
- /* Set up parameters for the standard type of frame */
- if(frame_type == FREEDV_VHF_FRAME_A){
- uw[0] = A_uw_v;
- uw[1] = A_uw_d;
- uw_len = 16;
- uw_offset = 40;
- } else if(frame_type == FREEDV_HF_FRAME_B){
- uw[0] = B_uw_v;
- uw[1] = B_uw_d;
- uw_len = 8;
- uw_offset = 0;
- } else {
- return 0;
- }
-
- /* Check both the voice and data UWs */
- for (i = 0; i < 2; i++) {
- /* Start bit pointer where UW should be */
- ibit = bitptr + uw_offset;
- if(ibit >= frame_size) ibit -= frame_size;
- /* Walk through and match bits in frame with bits of UW */
- for(iuw=0; iuw<uw_len; iuw++){
- if(bits[ibit] != uw[i][iuw]) diff[i]++;
- ibit++;
- if(ibit >= frame_size) ibit = 0;
- }
- match[i] = diff[i] <= tol;
- //fprintf(stderr, "diff[%d]: %d tol: %d\n", i, diff[i], tol);
+/* See if the UW is where it should be, to within a tolerance, in a bit buffer
+ */
+static int fvhff_match_uw(struct freedv_vhf_deframer *def, uint8_t bits[],
+ int tol, int *rdiff, enum frame_payload_type *pt) {
+ int frame_type = def->ftype;
+ int bitptr = def->bitptr;
+ int frame_size = def->frame_size;
+ int uw_len = def->uw_size;
+ int iuw, ibit;
+ const uint8_t *uw[2];
+ int uw_offset;
+ int diff[2] = {0, 0};
+ int i;
+ int match[2];
+ int r;
+
+ /* defaults to make compiler happy on -O3 */
+
+ *pt = FRAME_PAYLOAD_TYPE_VOICE;
+ *rdiff = 0;
+
+ /* Set up parameters for the standard type of frame */
+ if (frame_type == FREEDV_VHF_FRAME_A) {
+ uw[0] = A_uw_v;
+ uw[1] = A_uw_d;
+ uw_len = 16;
+ uw_offset = 40;
+ } else if (frame_type == FREEDV_HF_FRAME_B) {
+ uw[0] = B_uw_v;
+ uw[1] = B_uw_d;
+ uw_len = 8;
+ uw_offset = 0;
+ } else {
+ return 0;
+ }
+
+ /* Check both the voice and data UWs */
+ for (i = 0; i < 2; i++) {
+ /* Start bit pointer where UW should be */
+ ibit = bitptr + uw_offset;
+ if (ibit >= frame_size) ibit -= frame_size;
+ /* Walk through and match bits in frame with bits of UW */
+ for (iuw = 0; iuw < uw_len; iuw++) {
+ if (bits[ibit] != uw[i][iuw]) diff[i]++;
+ ibit++;
+ if (ibit >= frame_size) ibit = 0;
}
- /* Pick the best matching UW */
+ match[i] = diff[i] <= tol;
+ // fprintf(stderr, "diff[%d]: %d tol: %d\n", i, diff[i], tol);
+ }
+ /* Pick the best matching UW */
+
+ if (diff[0] < diff[1]) {
+ r = match[0];
+ *rdiff = diff[0];
+ *pt = FRAME_PAYLOAD_TYPE_VOICE;
+ } else {
+ r = match[1];
+ *rdiff = diff[1];
+ *pt = FRAME_PAYLOAD_TYPE_DATA;
+ }
+
+ return r;
+}
- if (diff[0] < diff[1]) {
- r = match[0];
- *rdiff = diff[0];
- *pt = FRAME_PAYLOAD_TYPE_VOICE;
- } else {
- r = match[1];
- *rdiff = diff[1];
- *pt = FRAME_PAYLOAD_TYPE_DATA;
+static void fvhff_extract_frame_voice(struct freedv_vhf_deframer *def,
+ uint8_t bits[], uint8_t codec2_out[],
+ uint8_t proto_out[], uint8_t vc_out[]) {
+ int frame_type = def->ftype;
+ int bitptr = def->bitptr;
+ int frame_size = def->frame_size;
+ int iframe, ibit;
+
+ if (frame_type == FREEDV_VHF_FRAME_A) {
+ /* Extract codec2 bits */
+ memset(codec2_out, 0, 7);
+ ibit = 0;
+ /* Extract and pack first half, MSB first */
+ iframe = bitptr + 16;
+ if (iframe >= frame_size) iframe -= frame_size;
+ for (; ibit < 24; ibit++) {
+ codec2_out[ibit >> 3] |= (bits[iframe] & 0x1) << (7 - (ibit & 0x7));
+ iframe++;
+ if (iframe >= frame_size) iframe = 0;
}
-
- return r;
-}
-static void fvhff_extract_frame_voice(struct freedv_vhf_deframer * def,uint8_t bits[],
- uint8_t codec2_out[],uint8_t proto_out[],uint8_t vc_out[]){
- int frame_type = def->ftype;
- int bitptr = def->bitptr;
- int frame_size = def->frame_size;
- int iframe,ibit;
-
- if(frame_type == FREEDV_VHF_FRAME_A){
- /* Extract codec2 bits */
- memset(codec2_out,0,7);
- ibit = 0;
- /* Extract and pack first half, MSB first */
- iframe = bitptr+16;
- if(iframe >= frame_size) iframe-=frame_size;
- for(;ibit<24;ibit++){
- codec2_out[ibit>>3] |= (bits[iframe]&0x1)<<(7-(ibit&0x7));
- iframe++;
- if(iframe >= frame_size) iframe=0;
- }
-
- /* Extract and pack last half, MSB first */
- iframe = bitptr+56;
- if(iframe >= frame_size) iframe-=frame_size;
- for(;ibit<52;ibit++){
- codec2_out[ibit>>3] |= (bits[iframe]&0x1)<<(7-(ibit&0x7));
- iframe++;
- if(iframe >= frame_size) iframe=0;
- }
- /* Extract varicode bits, if wanted */
- if(vc_out!=NULL){
- iframe = bitptr+90;
- if(iframe >= frame_size) iframe-=frame_size;
- vc_out[0] = bits[iframe];
- iframe++;
- vc_out[1] = bits[iframe];
- }
- /* Extract protocol bits, if proto is passed through */
- if(proto_out!=NULL){
- /* Clear protocol bit array */
- memset(proto_out,0,3);
- ibit = 0;
- /* Extract and pack first half, MSB first */
- iframe = bitptr+4;
- if(iframe >= frame_size) iframe-=frame_size;
- for(;ibit<12;ibit++){
- proto_out[ibit>>3] |= (bits[iframe]&0x1)<<(7-(ibit&0x7));
- iframe++;
- if(iframe >= frame_size) iframe=0;
- }
-
- /* Extract and pack last half, MSB first */
- iframe = bitptr+84;
- if(iframe >= frame_size) iframe-=frame_size;
- for(;ibit<20;ibit++){
- proto_out[ibit>>3] |= (bits[iframe]&0x1)<<(7-(ibit&0x7));
- iframe++;
- if(iframe >= frame_size) iframe=0;
- }
- }
+ /* Extract and pack last half, MSB first */
+ iframe = bitptr + 56;
+ if (iframe >= frame_size) iframe -= frame_size;
+ for (; ibit < 52; ibit++) {
+ codec2_out[ibit >> 3] |= (bits[iframe] & 0x1) << (7 - (ibit & 0x7));
+ iframe++;
+ if (iframe >= frame_size) iframe = 0;
+ }
+ /* Extract varicode bits, if wanted */
+ if (vc_out != NULL) {
+ iframe = bitptr + 90;
+ if (iframe >= frame_size) iframe -= frame_size;
+ vc_out[0] = bits[iframe];
+ iframe++;
+ vc_out[1] = bits[iframe];
+ }
+ /* Extract protocol bits, if proto is passed through */
+ if (proto_out != NULL) {
+ /* Clear protocol bit array */
+ memset(proto_out, 0, 3);
+ ibit = 0;
+ /* Extract and pack first half, MSB first */
+ iframe = bitptr + 4;
+ if (iframe >= frame_size) iframe -= frame_size;
+ for (; ibit < 12; ibit++) {
+ proto_out[ibit >> 3] |= (bits[iframe] & 0x1) << (7 - (ibit & 0x7));
+ iframe++;
+ if (iframe >= frame_size) iframe = 0;
+ }
+
+ /* Extract and pack last half, MSB first */
+ iframe = bitptr + 84;
+ if (iframe >= frame_size) iframe -= frame_size;
+ for (; ibit < 20; ibit++) {
+ proto_out[ibit >> 3] |= (bits[iframe] & 0x1) << (7 - (ibit & 0x7));
+ iframe++;
+ if (iframe >= frame_size) iframe = 0;
+ }
+ }
- }else if(frame_type == FREEDV_HF_FRAME_B){
- /* Pointers to both c2 frames */
- uint8_t * codec2_out1 = &codec2_out[0];
- uint8_t * codec2_out2 = &codec2_out[4];
-
- /* Extract codec2 bits */
- memset(codec2_out,0,8);
- ibit = 0;
-
- /* Extract and pack first c2 frame, MSB first */
- iframe = bitptr+8;
- if(iframe >= frame_size) iframe-=frame_size;
- for(;ibit<28;ibit++){
- codec2_out1[ibit>>3] |= (bits[iframe]&0x1)<<(7-(ibit&0x7));
- iframe++;
- if(iframe >= frame_size) iframe=0;
- }
-
- /* Extract and pack second c2 frame, MSB first */
- iframe = bitptr+36;
- ibit = 0;
- if(iframe >= frame_size) iframe-=frame_size;
- for(;ibit<28;ibit++){
- codec2_out2[ibit>>3] |= (bits[iframe]&0x1)<<(7-(ibit&0x7));
- iframe++;
- if(iframe >= frame_size) iframe=0;
- }
- }else if(frame_type == FREEDV_VHF_FRAME_AT){
- /* Extract codec2 bits */
- memset(codec2_out,0,7);
- ibit = 0;
- /* Extract and pack first half, MSB first */
- iframe = bitptr+12;
- if(iframe >= frame_size) iframe-=frame_size;
- for(;ibit<24;ibit++){
- codec2_out[ibit>>3] |= (bits[iframe]&0x1)<<(7-(ibit&0x7));
- iframe++;
- if(iframe >= frame_size) iframe=0;
- }
-
- /* Extract and pack last half, MSB first */
- iframe = bitptr+52;
- if(iframe >= frame_size) iframe-=frame_size;
- for(;ibit<52;ibit++){
- codec2_out[ibit>>3] |= (bits[iframe]&0x1)<<(7-(ibit&0x7));
- iframe++;
- if(iframe >= frame_size) iframe=0;
- }
- /* Extract varicode bits, if wanted */
- if(vc_out!=NULL){
- iframe = bitptr+86;
- if(iframe >= frame_size) iframe-=frame_size;
- vc_out[0] = bits[iframe];
- iframe++;
- vc_out[1] = bits[iframe];
- }
- /* Extract protocol bits, if proto is passed through */
- if(proto_out!=NULL){
- /* Clear protocol bit array */
- memset(proto_out,0,3);
- ibit = 0;
- /* Extract and pack first half, MSB first */
- iframe = bitptr+4;
- if(iframe >= frame_size) iframe-=frame_size;
- for(;ibit<12;ibit++){
- proto_out[ibit>>3] |= (bits[iframe]&0x1)<<(7-(ibit&0x7));
- iframe++;
- if(iframe >= frame_size) iframe=0;
- }
-
- /* Extract and pack last half, MSB first */
- iframe = bitptr+84;
- if(iframe >= frame_size) iframe-=frame_size;
- for(;ibit<20;ibit++){
- proto_out[ibit>>3] |= (bits[iframe]&0x1)<<(7-(ibit&0x7));
- iframe++;
- if(iframe >= frame_size) iframe=0;
- }
- }
+ } else if (frame_type == FREEDV_HF_FRAME_B) {
+ /* Pointers to both c2 frames */
+ uint8_t *codec2_out1 = &codec2_out[0];
+ uint8_t *codec2_out2 = &codec2_out[4];
+
+ /* Extract codec2 bits */
+ memset(codec2_out, 0, 8);
+ ibit = 0;
+
+ /* Extract and pack first c2 frame, MSB first */
+ iframe = bitptr + 8;
+ if (iframe >= frame_size) iframe -= frame_size;
+ for (; ibit < 28; ibit++) {
+ codec2_out1[ibit >> 3] |= (bits[iframe] & 0x1) << (7 - (ibit & 0x7));
+ iframe++;
+ if (iframe >= frame_size) iframe = 0;
+ }
+ /* Extract and pack second c2 frame, MSB first */
+ iframe = bitptr + 36;
+ ibit = 0;
+ if (iframe >= frame_size) iframe -= frame_size;
+ for (; ibit < 28; ibit++) {
+ codec2_out2[ibit >> 3] |= (bits[iframe] & 0x1) << (7 - (ibit & 0x7));
+ iframe++;
+ if (iframe >= frame_size) iframe = 0;
+ }
+ } else if (frame_type == FREEDV_VHF_FRAME_AT) {
+ /* Extract codec2 bits */
+ memset(codec2_out, 0, 7);
+ ibit = 0;
+ /* Extract and pack first half, MSB first */
+ iframe = bitptr + 12;
+ if (iframe >= frame_size) iframe -= frame_size;
+ for (; ibit < 24; ibit++) {
+ codec2_out[ibit >> 3] |= (bits[iframe] & 0x1) << (7 - (ibit & 0x7));
+ iframe++;
+ if (iframe >= frame_size) iframe = 0;
}
-}
-static void fvhff_extract_frame_data(struct freedv_vhf_deframer * def,uint8_t bits[]){
- int frame_type = def->ftype;
- int bitptr = def->bitptr;
- int frame_size = def->frame_size;
- int iframe,ibit;
-
- if(frame_type == FREEDV_VHF_FRAME_A){
- uint8_t data[8];
- int end_bits = 0;
- int from_bit;
- int bcast_bit;
-
- iframe = bitptr+4;
- if(iframe >= frame_size) iframe-=frame_size;
- from_bit = bits[iframe];
+ /* Extract and pack last half, MSB first */
+ iframe = bitptr + 52;
+ if (iframe >= frame_size) iframe -= frame_size;
+ for (; ibit < 52; ibit++) {
+ codec2_out[ibit >> 3] |= (bits[iframe] & 0x1) << (7 - (ibit & 0x7));
+ iframe++;
+ if (iframe >= frame_size) iframe = 0;
+ }
+ /* Extract varicode bits, if wanted */
+ if (vc_out != NULL) {
+ iframe = bitptr + 86;
+ if (iframe >= frame_size) iframe -= frame_size;
+ vc_out[0] = bits[iframe];
+ iframe++;
+ vc_out[1] = bits[iframe];
+ }
+ /* Extract protocol bits, if proto is passed through */
+ if (proto_out != NULL) {
+ /* Clear protocol bit array */
+ memset(proto_out, 0, 3);
+ ibit = 0;
+ /* Extract and pack first half, MSB first */
+ iframe = bitptr + 4;
+ if (iframe >= frame_size) iframe -= frame_size;
+ for (; ibit < 12; ibit++) {
+ proto_out[ibit >> 3] |= (bits[iframe] & 0x1) << (7 - (ibit & 0x7));
iframe++;
- if(iframe >= frame_size) iframe-=frame_size;
- bcast_bit = bits[iframe];
-
- /* Extract data bits */
- memset(data,0,8);
- ibit = 0;
- /* Extract and pack first half, MSB first */
- iframe = bitptr+8;
- if(iframe >= frame_size) iframe-=frame_size;
- for(;ibit<32;ibit++){
- data[ibit>>3] |= (bits[iframe]&0x1)<<(7-(ibit&0x7));
- iframe++;
- if(iframe >= frame_size) iframe=0;
- }
-
- /* Extract and pack last half, MSB first */
- iframe = bitptr+56;
- if(iframe >= frame_size) iframe-=frame_size;
- for(;ibit<64;ibit++){
- data[ibit>>3] |= (bits[iframe]&0x1)<<(7-(ibit&0x7));
- iframe++;
- if(iframe >= frame_size) iframe=0;
- }
+ if (iframe >= frame_size) iframe = 0;
+ }
+
+ /* Extract and pack last half, MSB first */
+ iframe = bitptr + 84;
+ if (iframe >= frame_size) iframe -= frame_size;
+ for (; ibit < 20; ibit++) {
+ proto_out[ibit >> 3] |= (bits[iframe] & 0x1) << (7 - (ibit & 0x7));
+ iframe++;
+ if (iframe >= frame_size) iframe = 0;
+ }
+ }
+ }
+}
- /* Extract endbits value, MSB first*/
- iframe = bitptr+88;
- ibit = 0;
- if(iframe >= frame_size) iframe-=frame_size;
- for(;ibit<4;ibit++){
- end_bits |= (bits[iframe]&0x1)<<(3-(ibit));
- iframe++;
- if(iframe >= frame_size) iframe=0;
- }
-
- if (def->fdc) {
- freedv_data_channel_rx_frame(def->fdc, data, 8, from_bit, bcast_bit, 0, end_bits);
- }
- } else if(frame_type == FREEDV_HF_FRAME_B){
- uint8_t data[6];
- int end_bits = 0;
- int from_bit;
- int bcast_bit;
- int crc_bit;
-
- ibit = 0;
- memset(data,0,6);
-
- /* Extract and pack first c2 frame, MSB first */
- iframe = bitptr+8;
- if(iframe >= frame_size) iframe-=frame_size;
- for(;ibit<48;ibit++){
- data[ibit>>3] |= (bits[iframe]&0x1)<<(7-(ibit&0x7));
- iframe++;
- if(iframe >= frame_size) iframe=0;
- }
+static void fvhff_extract_frame_data(struct freedv_vhf_deframer *def,
+ uint8_t bits[]) {
+ int frame_type = def->ftype;
+ int bitptr = def->bitptr;
+ int frame_size = def->frame_size;
+ int iframe, ibit;
+
+ if (frame_type == FREEDV_VHF_FRAME_A) {
+ uint8_t data[8];
+ int end_bits = 0;
+ int from_bit;
+ int bcast_bit;
+
+ iframe = bitptr + 4;
+ if (iframe >= frame_size) iframe -= frame_size;
+ from_bit = bits[iframe];
+ iframe++;
+ if (iframe >= frame_size) iframe -= frame_size;
+ bcast_bit = bits[iframe];
+
+ /* Extract data bits */
+ memset(data, 0, 8);
+ ibit = 0;
+ /* Extract and pack first half, MSB first */
+ iframe = bitptr + 8;
+ if (iframe >= frame_size) iframe -= frame_size;
+ for (; ibit < 32; ibit++) {
+ data[ibit >> 3] |= (bits[iframe] & 0x1) << (7 - (ibit & 0x7));
+ iframe++;
+ if (iframe >= frame_size) iframe = 0;
+ }
- iframe = bitptr+56;
- if(iframe >= frame_size) iframe-=frame_size;
- from_bit = bits[iframe];
- iframe++;
- if(iframe >= frame_size) iframe-=frame_size;
- bcast_bit = bits[iframe];
- iframe++;
- if(iframe >= frame_size) iframe-=frame_size;
- crc_bit = bits[iframe];
-
- /* Extract endbits value, MSB first*/
- iframe = bitptr+60;
- ibit = 0;
- if(iframe >= frame_size) iframe-=frame_size;
- for(;ibit<4;ibit++){
- end_bits |= (bits[iframe]&0x1)<<(3-(ibit));
- iframe++;
- if(iframe >= frame_size) iframe=0;
- }
+ /* Extract and pack last half, MSB first */
+ iframe = bitptr + 56;
+ if (iframe >= frame_size) iframe -= frame_size;
+ for (; ibit < 64; ibit++) {
+ data[ibit >> 3] |= (bits[iframe] & 0x1) << (7 - (ibit & 0x7));
+ iframe++;
+ if (iframe >= frame_size) iframe = 0;
+ }
- if (def->fdc) {
- freedv_data_channel_rx_frame(def->fdc, data, 6, from_bit, bcast_bit, crc_bit, end_bits);
- }
+ /* Extract endbits value, MSB first*/
+ iframe = bitptr + 88;
+ ibit = 0;
+ if (iframe >= frame_size) iframe -= frame_size;
+ for (; ibit < 4; ibit++) {
+ end_bits |= (bits[iframe] & 0x1) << (3 - (ibit));
+ iframe++;
+ if (iframe >= frame_size) iframe = 0;
}
+
+ if (def->fdc) {
+ freedv_data_channel_rx_frame(def->fdc, data, 8, from_bit, bcast_bit, 0,
+ end_bits);
+ }
+ } else if (frame_type == FREEDV_HF_FRAME_B) {
+ uint8_t data[6];
+ int end_bits = 0;
+ int from_bit;
+ int bcast_bit;
+ int crc_bit;
+
+ ibit = 0;
+ memset(data, 0, 6);
+
+ /* Extract and pack first c2 frame, MSB first */
+ iframe = bitptr + 8;
+ if (iframe >= frame_size) iframe -= frame_size;
+ for (; ibit < 48; ibit++) {
+ data[ibit >> 3] |= (bits[iframe] & 0x1) << (7 - (ibit & 0x7));
+ iframe++;
+ if (iframe >= frame_size) iframe = 0;
+ }
+
+ iframe = bitptr + 56;
+ if (iframe >= frame_size) iframe -= frame_size;
+ from_bit = bits[iframe];
+ iframe++;
+ if (iframe >= frame_size) iframe -= frame_size;
+ bcast_bit = bits[iframe];
+ iframe++;
+ if (iframe >= frame_size) iframe -= frame_size;
+ crc_bit = bits[iframe];
+
+ /* Extract endbits value, MSB first*/
+ iframe = bitptr + 60;
+ ibit = 0;
+ if (iframe >= frame_size) iframe -= frame_size;
+ for (; ibit < 4; ibit++) {
+ end_bits |= (bits[iframe] & 0x1) << (3 - (ibit));
+ iframe++;
+ if (iframe >= frame_size) iframe = 0;
+ }
+
+ if (def->fdc) {
+ freedv_data_channel_rx_frame(def->fdc, data, 6, from_bit, bcast_bit,
+ crc_bit, end_bits);
+ }
+ }
}
-static void fvhff_extract_frame(struct freedv_vhf_deframer * def,uint8_t bits[],uint8_t codec2_out[],
- uint8_t proto_out[],uint8_t vc_out[],enum frame_payload_type pt){
- switch (pt) {
- case FRAME_PAYLOAD_TYPE_VOICE:
- fvhff_extract_frame_voice(def, bits, codec2_out, proto_out, vc_out);
- break;
+static void fvhff_extract_frame(struct freedv_vhf_deframer *def, uint8_t bits[],
+ uint8_t codec2_out[], uint8_t proto_out[],
+ uint8_t vc_out[], enum frame_payload_type pt) {
+ switch (pt) {
+ case FRAME_PAYLOAD_TYPE_VOICE:
+ fvhff_extract_frame_voice(def, bits, codec2_out, proto_out, vc_out);
+ break;
case FRAME_PAYLOAD_TYPE_DATA:
- fvhff_extract_frame_data(def, bits);
- break;
- }
+ fvhff_extract_frame_data(def, bits);
+ break;
+ }
}
/*
- * Try to find the UW and extract codec/proto/vc bits in def->frame_size bits
+ * Try to find the UW and extract codec/proto/vc bits in def->frame_size bits
*/
-int fvhff_deframe_bits(struct freedv_vhf_deframer * def,uint8_t codec2_out[],uint8_t proto_out[],
- uint8_t vc_out[],uint8_t bits_in[]){
- uint8_t * strbits = def->bits;
- uint8_t * invbits = def->invbits;
- uint8_t * bits;
- int on_inv_bits = def->on_inv_bits;
- int frame_type = def->ftype;
- int state = def->state;
- int bitptr = def->bitptr;
- int last_uw = def->last_uw;
- int miss_cnt = def->miss_cnt;
- int frame_size = def->frame_size;
- int uw_size = def->uw_size;
- int uw_diff;
- int i;
- int uw_first_tol;
- int uw_sync_tol;
- int miss_tol;
- int extracted_frame = 0;
- enum frame_payload_type pt = FRAME_PAYLOAD_TYPE_VOICE;
-
- /* Possibly set up frame-specific params here */
- if(frame_type == FREEDV_VHF_FRAME_A){
- uw_first_tol = 1; /* The UW bit-error tolerance for the first frame */
- uw_sync_tol = 3; /* The UW bit error tolerance for frames after sync */
- miss_tol = 4; /* How many UWs may be missed before going into the de-synced state */
- }else if(frame_type == FREEDV_HF_FRAME_B){
- uw_first_tol = 0; /* The UW bit-error tolerance for the first frame */
- uw_sync_tol = 1; /* The UW bit error tolerance for frames after sync */
- miss_tol = 3; /* How many UWs may be missed before going into the de-synced state */
- }else{
- return 0;
- }
-
- /* Skip N bits for multi-bit symbol modems */
- for(i=0; i<frame_size; i++){
- /* Put a bit in the buffer */
- strbits[bitptr] = bits_in[i];
- /* If we're checking the inverted bitstream, put a bit in it */
- if(invbits!=NULL)
- invbits[bitptr] = bits_in[i]?0:1;
-
- bitptr++;
- if(bitptr >= frame_size) bitptr -= frame_size;
- def->bitptr = bitptr;
- /* Enter state machine */
- if(state==ST_SYNC){
- /* Already synchronized, just wait till UW is back where it should be */
- last_uw++;
- if(invbits!=NULL){
- if(on_inv_bits)
- bits = invbits;
- else
- bits = strbits;
- }else{
- bits=strbits;
- }
- /* UW should be here. We're sunk, so deframe anyway */
- if(last_uw == frame_size){
- last_uw = 0;
-
- if(!fvhff_match_uw(def,bits,uw_sync_tol,&uw_diff, &pt))
- miss_cnt++;
- else
- miss_cnt=0;
-
- /* If we go over the miss tolerance, go into no-sync */
- if(miss_cnt>miss_tol){
- state = ST_NOSYNC;
- }
- /* Extract the bits */
- extracted_frame = 1;
- fvhff_extract_frame(def,bits,codec2_out,proto_out,vc_out,pt);
-
- /* Update BER estimate */
- def->ber_est = (.995*def->ber_est) + (.005*((float)uw_diff)/((float)uw_size));
- def->total_uw_bits += uw_size;
- def->total_uw_err += uw_diff;
- }
- /* Not yet sunk */
- }else{
- /* It's a sync!*/
- if(invbits!=NULL){
- if(fvhff_match_uw(def,invbits,uw_first_tol, &uw_diff, &pt)){
- state = ST_SYNC;
- last_uw = 0;
- miss_cnt = 0;
- extracted_frame = 1;
- on_inv_bits = 1;
- fvhff_extract_frame(def,invbits,codec2_out,proto_out,vc_out,pt);
- /* Update BER estimate */
- def->ber_est = (.995*def->ber_est) + (.005*((float)uw_diff)/((float)uw_size));
- def->total_uw_bits += uw_size;
- def->total_uw_err += uw_diff;
- }
- }
- if(fvhff_match_uw(def,strbits,uw_first_tol, &uw_diff, &pt)){
- state = ST_SYNC;
- last_uw = 0;
- miss_cnt = 0;
- extracted_frame = 1;
- on_inv_bits = 0;
- fvhff_extract_frame(def,strbits,codec2_out,proto_out,vc_out,pt);
- /* Update BER estimate */
- def->ber_est = (.995*def->ber_est) + (.005*((float)uw_diff)/((float)uw_size));
- def->total_uw_bits += uw_size;
- def->total_uw_err += uw_diff;
- }
- }
+int fvhff_deframe_bits(struct freedv_vhf_deframer *def, uint8_t codec2_out[],
+ uint8_t proto_out[], uint8_t vc_out[],
+ uint8_t bits_in[]) {
+ uint8_t *strbits = def->bits;
+ uint8_t *invbits = def->invbits;
+ uint8_t *bits;
+ int on_inv_bits = def->on_inv_bits;
+ int frame_type = def->ftype;
+ int state = def->state;
+ int bitptr = def->bitptr;
+ int last_uw = def->last_uw;
+ int miss_cnt = def->miss_cnt;
+ int frame_size = def->frame_size;
+ int uw_size = def->uw_size;
+ int uw_diff;
+ int i;
+ int uw_first_tol;
+ int uw_sync_tol;
+ int miss_tol;
+ int extracted_frame = 0;
+ enum frame_payload_type pt = FRAME_PAYLOAD_TYPE_VOICE;
+
+ /* Possibly set up frame-specific params here */
+ if (frame_type == FREEDV_VHF_FRAME_A) {
+ uw_first_tol = 1; /* The UW bit-error tolerance for the first frame */
+ uw_sync_tol = 3; /* The UW bit error tolerance for frames after sync */
+ miss_tol = 4; /* How many UWs may be missed before going into the de-synced
+ state */
+ } else if (frame_type == FREEDV_HF_FRAME_B) {
+ uw_first_tol = 0; /* The UW bit-error tolerance for the first frame */
+ uw_sync_tol = 1; /* The UW bit error tolerance for frames after sync */
+ miss_tol = 3; /* How many UWs may be missed before going into the de-synced
+ state */
+ } else {
+ return 0;
+ }
+
+ /* Skip N bits for multi-bit symbol modems */
+ for (i = 0; i < frame_size; i++) {
+ /* Put a bit in the buffer */
+ strbits[bitptr] = bits_in[i];
+ /* If we're checking the inverted bitstream, put a bit in it */
+ if (invbits != NULL) invbits[bitptr] = bits_in[i] ? 0 : 1;
+
+ bitptr++;
+ if (bitptr >= frame_size) bitptr -= frame_size;
+ def->bitptr = bitptr;
+ /* Enter state machine */
+ if (state == ST_SYNC) {
+ /* Already synchronized, just wait till UW is back where it should be */
+ last_uw++;
+ if (invbits != NULL) {
+ if (on_inv_bits)
+ bits = invbits;
+ else
+ bits = strbits;
+ } else {
+ bits = strbits;
+ }
+ /* UW should be here. We're sunk, so deframe anyway */
+ if (last_uw == frame_size) {
+ last_uw = 0;
+
+ if (!fvhff_match_uw(def, bits, uw_sync_tol, &uw_diff, &pt))
+ miss_cnt++;
+ else
+ miss_cnt = 0;
+
+ /* If we go over the miss tolerance, go into no-sync */
+ if (miss_cnt > miss_tol) {
+ state = ST_NOSYNC;
+ }
+ /* Extract the bits */
+ extracted_frame = 1;
+ fvhff_extract_frame(def, bits, codec2_out, proto_out, vc_out, pt);
+
+ /* Update BER estimate */
+ def->ber_est = (.995 * def->ber_est) +
+ (.005 * ((float)uw_diff) / ((float)uw_size));
+ def->total_uw_bits += uw_size;
+ def->total_uw_err += uw_diff;
+ }
+ /* Not yet sunk */
+ } else {
+ /* It's a sync!*/
+ if (invbits != NULL) {
+ if (fvhff_match_uw(def, invbits, uw_first_tol, &uw_diff, &pt)) {
+ state = ST_SYNC;
+ last_uw = 0;
+ miss_cnt = 0;
+ extracted_frame = 1;
+ on_inv_bits = 1;
+ fvhff_extract_frame(def, invbits, codec2_out, proto_out, vc_out, pt);
+ /* Update BER estimate */
+ def->ber_est = (.995 * def->ber_est) +
+ (.005 * ((float)uw_diff) / ((float)uw_size));
+ def->total_uw_bits += uw_size;
+ def->total_uw_err += uw_diff;
+ }
+ }
+ if (fvhff_match_uw(def, strbits, uw_first_tol, &uw_diff, &pt)) {
+ state = ST_SYNC;
+ last_uw = 0;
+ miss_cnt = 0;
+ extracted_frame = 1;
+ on_inv_bits = 0;
+ fvhff_extract_frame(def, strbits, codec2_out, proto_out, vc_out, pt);
+ /* Update BER estimate */
+ def->ber_est = (.995 * def->ber_est) +
+ (.005 * ((float)uw_diff) / ((float)uw_size));
+ def->total_uw_bits += uw_size;
+ def->total_uw_err += uw_diff;
+ }
}
- def->state = state;
- def->last_uw = last_uw;
- def->miss_cnt = miss_cnt;
- def->on_inv_bits = on_inv_bits;
- /* return sync state and presence of extracted voice bits.
- only sync for data frames, they are already handled by callback */
- return (extracted_frame ? FREEDV_RX_SYNC : 0) | (pt == FRAME_PAYLOAD_TYPE_VOICE ? FREEDV_RX_BITS : 0);
+ }
+ def->state = state;
+ def->last_uw = last_uw;
+ def->miss_cnt = miss_cnt;
+ def->on_inv_bits = on_inv_bits;
+ /* return sync state and presence of extracted voice bits.
+ only sync for data frames, they are already handled by callback */
+ return (extracted_frame ? FREEDV_RX_SYNC : 0) |
+ (pt == FRAME_PAYLOAD_TYPE_VOICE ? FREEDV_RX_BITS : 0);
}