<commit_before>#include "blockstream.h"

#define MASK_5BIT  0x000001F
#define MASK_10BIT 0x00003FF
#define MASK_16BIT 0x000FFFF
#define MASK_26BIT 0x3FFFFFF
#define MASK_28BIT 0xFFFFFFF

namespace redsea {

uint16_t syndrome(int vec) {

  uint16_t synd_reg = 0x000;
  int bit,l;

  for (int k=25; k>=0; k--) {
    bit       = (vec & (1 << k));
    l         = (synd_reg & 0x200);      // Store lefmost bit of register
    synd_reg  = (synd_reg << 1) & 0x3FF; // Rotate register
    synd_reg ^= (bit ? 0x31B : 0x00);    // Premultiply input by x^325 mod g(x)
    synd_reg ^= (l   ? 0x1B9 : 0x00);    // Division mod 2 by g(x)
  }

  return synd_reg;
}

BlockStream::BlockStream() : has_sync_for_(5), group_data_(4), has_block_(5),
  bitcount_(0), left_to_read_(0), bit_stream_(), wideblock_(0), block_has_errors_(50)

{

  offset_word_ = {0x0FC, 0x198, 0x168, 0x350, 0x1B4};

  block_for_offset_ = {0, 1, 2, 2, 3};

  error_lookup_ = {
    {0x200, 0b1000000000000000},
    {0x300, 0b1100000000000000},
    {0x180, 0b0110000000000000},
    {0x0c0, 0b0011000000000000},
    {0x060, 0b0001100000000000},
    {0x030, 0b0000110000000000},
    {0x018, 0b0000011000000000},
    {0x00c, 0b0000001100000000},
    {0x006, 0b0000000110000000},
    {0x003, 0b0000000011000000},
    {0x2dd, 0b0000000001100000},
    {0x3b2, 0b0000000000110000},
    {0x1d9, 0b0000000000011000},
    {0x230, 0b0000000000001100},
    {0x118, 0b0000000000000110},
    {0x08c, 0b0000000000000011},
    {0x046, 0b0000000000000001}
  };
}

void BlockStream::uncorrectable() {
  printf(":offset %d not received\n",expected_offset_);
  int data_length = 0;

  // TODO: return partial group
  /*if (has_block_[A]) {
    data_length = 1;

    if (has_block_[B]) {
      data_length = 2;

      if (has_block_[C] || has_block_[CI]) {
        data_length = 3;
      }
    }
  }*/

  block_has_errors_[block_counter_ % block_has_errors_.size()] = true;

  int erroneous_blocks = 0;
  for (bool e : block_has_errors_) {
    if (e)
      erroneous_blocks ++;
  }

  // Sync is lost when >45 out of last 50 blocks are erroneous (Section C.1.2)
  if (is_in_sync_ && erroneous_blocks > 45) {
    is_in_sync_ = false;
    for (int i=0; i<(int)block_has_errors_.size(); i++)
      block_has_errors_[i] = false;
    pi_ = 0x0000;
    printf(":too many errors, sync lost\n");
  }

  for (int o=A; o<=D; o++)
    has_block_[o] = false;

}

std::vector<uint16_t> BlockStream::getNextGroup() {

  has_whole_group_ = false;

  while (!has_whole_group_ && !isEOF()) {

    // Compensate for clock slip corrections
    bitcount_ += 26 - left_to_read_;

    // Read from radio
    for (int i=0; i < (is_in_sync_ ? left_to_read_ : 1); i++, bitcount_++) {
      wideblock_ = (wideblock_ << 1) + bit_stream_.getNextBit();
    }

    left_to_read_ = 26;
    wideblock_ &= MASK_28BIT;

    int block = (wideblock_ >> 1) & MASK_26BIT;
<commit_msg>better way to formulate condition<commit_after>#include "blockstream.h"

#define MASK_5BIT  0x000001F
#define MASK_10BIT 0x00003FF
#define MASK_16BIT 0x000FFFF
#define MASK_26BIT 0x3FFFFFF
#define MASK_28BIT 0xFFFFFFF

namespace redsea {

uint16_t syndrome(int vec) {

  uint16_t synd_reg = 0x000;
  int bit,l;

  for (int k=25; k>=0; k--) {
    bit       = (vec & (1 << k));
    l         = (synd_reg & 0x200);      // Store lefmost bit of register
    synd_reg  = (synd_reg << 1) & 0x3FF; // Rotate register
    synd_reg ^= (bit ? 0x31B : 0x00);    // Premultiply input by x^325 mod g(x)
    synd_reg ^= (l   ? 0x1B9 : 0x00);    // Division mod 2 by g(x)
  }

  return synd_reg;
}

BlockStream::BlockStream() : has_sync_for_(5), group_data_(4), has_block_(5),
  bitcount_(0), left_to_read_(0), bit_stream_(), wideblock_(0), block_has_errors_(50)

{

  offset_word_ = {0x0FC, 0x198, 0x168, 0x350, 0x1B4};

  block_for_offset_ = {0, 1, 2, 2, 3};

  error_lookup_ = {
    {0x200, 0b1000000000000000},
    {0x300, 0b1100000000000000},
    {0x180, 0b0110000000000000},
    {0x0c0, 0b0011000000000000},
    {0x060, 0b0001100000000000},
    {0x030, 0b0000110000000000},
    {0x018, 0b0000011000000000},
    {0x00c, 0b0000001100000000},
    {0x006, 0b0000000110000000},
    {0x003, 0b0000000011000000},
    {0x2dd, 0b0000000001100000},
    {0x3b2, 0b0000000000110000},
    {0x1d9, 0b0000000000011000},
    {0x230, 0b0000000000001100},
    {0x118, 0b0000000000000110},
    {0x08c, 0b0000000000000011},
    {0x046, 0b0000000000000001}
  };
}

void BlockStream::uncorrectable() {
  printf(":offset %d not received\n",expected_offset_);
  int data_length = 0;

  // TODO: return partial group
  /*if (has_block_[A]) {
    data_length = 1;

    if (has_block_[B]) {
      data_length = 2;

      if (has_block_[C] || has_block_[CI]) {
        data_length = 3;
      }
    }
  }*/

  block_has_errors_[block_counter_ % block_has_errors_.size()] = true;

  int erroneous_blocks = 0;
  for (bool e : block_has_errors_) {
    if (e)
      erroneous_blocks ++;
  }

  // Sync is lost when >45 out of last 50 blocks are erroneous (Section C.1.2)
  if (is_in_sync_ && erroneous_blocks > 45) {
    is_in_sync_ = false;
    for (int i=0; i<(int)block_has_errors_.size(); i++)
      block_has_errors_[i] = false;
    pi_ = 0x0000;
    printf(":too many errors, sync lost\n");
  }

  for (int o=A; o<=D; o++)
    has_block_[o] = false;

}

std::vector<uint16_t> BlockStream::getNextGroup() {

  has_whole_group_ = false;

  while (!(has_whole_group_ || isEOF())) {

    // Compensate for clock slip corrections
    bitcount_ += 26 - left_to_read_;

    // Read from radio
    for (int i=0; i < (is_in_sync_ ? left_to_read_ : 1); i++, bitcount_++) {
      wideblock_ = (wideblock_ << 1) + bit_stream_.getNextBit();
    }

    left_to_read_ = 26;
    wideblock_ &= MASK_28BIT;

    int block = (wideblock_ >> 1) & MASK_26BIT;

{'fraction_non_alphanumeric': 0.13608853536226873, 'fraction_numerical': 0.16496628047726095, 'mean_word_length': 3.3325842696629215, 'pattern_counts': {'":': 4, '<': 23, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 38, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '722674', 'n_tokens_mistral': 3030, 'n_tokens_neox': 2303, 'n_words': 498}