virtual void onSizeChange() {
        this->INHERITED::onSizeChange();

        fNext->setSize(this->width(), this->height());
        fPrev->setSize(this->width(), this->height());

        SkScalar lr = 0, ud = 0;
        if (fAnimationDirection & (kLeftDirection|kULDirection|kDLDirection))
            lr = this->width();
        if (fAnimationDirection & (kRightDirection|kURDirection|kDRDirection))
            lr = -this->width();
        if (fAnimationDirection & (kUpDirection|kULDirection|kURDirection))
            ud = this->height();
        if (fAnimationDirection & (kDownDirection|kDLDirection|kDRDirection))
            ud = -this->height();

        fBegin[kPrevX] = fBegin[kPrevY] = 0;
        fBegin[kNextX] = lr;
        fBegin[kNextY] = ud;
        fNext->setLocX(lr);
        fNext->setLocY(ud);

        if (is_transition(fPrev))
            lr = ud = 0;
        fEnd[kPrevX] = -lr;
        fEnd[kPrevY] = -ud;
        fEnd[kNextX] = fEnd[kNextY] = 0;
        SkScalar blend[] = { SkFloatToScalar(0.8f), SkFloatToScalar(0.0f),
                             SkFloatToScalar(0.0f), SK_Scalar1 };
        fInterp.setKeyFrame(0, SkTime::GetMSecs(), fBegin, blend);
        fInterp.setKeyFrame(1, SkTime::GetMSecs()+kDurationMS, fEnd, blend);
    }
Esempio n. 2
0
/**
 * ir_rc6_decode() - Decode one RC6 pulse or space
 * @dev:	the struct rc_dev descriptor of the device
 * @ev:		the struct ir_raw_event descriptor of the pulse/space
 *
 * This function returns -EINVAL if the pulse violates the state machine
 */
static int ir_rc6_decode(struct rc_dev *dev, struct ir_raw_event ev)
{
	struct rc6_dec *data = &dev->raw->rc6;
	u32 scancode;
	u8 toggle;
	enum rc_proto protocol;

	if (!is_timing_event(ev)) {
		if (ev.reset)
			data->state = STATE_INACTIVE;
		return 0;
	}

	if (!geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2))
		goto out;

again:
	IR_dprintk(2, "RC6 decode started at state %i (%uus %s)\n",
		   data->state, TO_US(ev.duration), TO_STR(ev.pulse));

	if (!geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2))
		return 0;

	switch (data->state) {

	case STATE_INACTIVE:
		if (!ev.pulse)
			break;

		/* Note: larger margin on first pulse since each RC6_UNIT
		   is quite short and some hardware takes some time to
		   adjust to the signal */
		if (!eq_margin(ev.duration, RC6_PREFIX_PULSE, RC6_UNIT))
			break;

		data->state = STATE_PREFIX_SPACE;
		data->count = 0;
		return 0;

	case STATE_PREFIX_SPACE:
		if (ev.pulse)
			break;

		if (!eq_margin(ev.duration, RC6_PREFIX_SPACE, RC6_UNIT / 2))
			break;

		data->state = STATE_HEADER_BIT_START;
		data->header = 0;
		return 0;

	case STATE_HEADER_BIT_START:
		if (!eq_margin(ev.duration, RC6_BIT_START, RC6_UNIT / 2))
			break;

		data->header <<= 1;
		if (ev.pulse)
			data->header |= 1;
		data->count++;
		data->state = STATE_HEADER_BIT_END;
		return 0;

	case STATE_HEADER_BIT_END:
		if (!is_transition(&ev, &dev->raw->prev_ev))
			break;

		if (data->count == RC6_HEADER_NBITS)
			data->state = STATE_TOGGLE_START;
		else
			data->state = STATE_HEADER_BIT_START;

		decrease_duration(&ev, RC6_BIT_END);
		goto again;

	case STATE_TOGGLE_START:
		if (!eq_margin(ev.duration, RC6_TOGGLE_START, RC6_UNIT / 2))
			break;

		data->toggle = ev.pulse;
		data->state = STATE_TOGGLE_END;
		return 0;

	case STATE_TOGGLE_END:
		if (!is_transition(&ev, &dev->raw->prev_ev) ||
		    !geq_margin(ev.duration, RC6_TOGGLE_END, RC6_UNIT / 2))
			break;

		if (!(data->header & RC6_STARTBIT_MASK)) {
			IR_dprintk(1, "RC6 invalid start bit\n");
			break;
		}

		data->state = STATE_BODY_BIT_START;
		decrease_duration(&ev, RC6_TOGGLE_END);
		data->count = 0;
		data->body = 0;

		switch (rc6_mode(data)) {
		case RC6_MODE_0:
			data->wanted_bits = RC6_0_NBITS;
			break;
		case RC6_MODE_6A:
			data->wanted_bits = RC6_6A_NBITS;
			break;
		default:
			IR_dprintk(1, "RC6 unknown mode\n");
			goto out;
		}
		goto again;

	case STATE_BODY_BIT_START:
		if (eq_margin(ev.duration, RC6_BIT_START, RC6_UNIT / 2)) {
			/* Discard LSB's that won't fit in data->body */
			if (data->count++ < CHAR_BIT * sizeof data->body) {
				data->body <<= 1;
				if (ev.pulse)
					data->body |= 1;
			}
			data->state = STATE_BODY_BIT_END;
			return 0;
		} else if (RC6_MODE_6A == rc6_mode(data) && !ev.pulse &&
				geq_margin(ev.duration, RC6_SUFFIX_SPACE, RC6_UNIT / 2)) {
			data->state = STATE_FINISHED;
			goto again;
		}
		break;

	case STATE_BODY_BIT_END:
		if (!is_transition(&ev, &dev->raw->prev_ev))
			break;

		if (data->count == data->wanted_bits)
			data->state = STATE_FINISHED;
		else
			data->state = STATE_BODY_BIT_START;

		decrease_duration(&ev, RC6_BIT_END);
		goto again;

	case STATE_FINISHED:
		if (ev.pulse)
			break;

		switch (rc6_mode(data)) {
		case RC6_MODE_0:
			scancode = data->body;
			toggle = data->toggle;
			protocol = RC_PROTO_RC6_0;
			IR_dprintk(1, "RC6(0) scancode 0x%04x (toggle: %u)\n",
				   scancode, toggle);
			break;

		case RC6_MODE_6A:
			if (data->count > CHAR_BIT * sizeof data->body) {
				IR_dprintk(1, "RC6 too many (%u) data bits\n",
					data->count);
				goto out;
			}

			scancode = data->body;
			switch (data->count) {
			case 20:
				protocol = RC_PROTO_RC6_6A_20;
				toggle = 0;
				break;
			case 24:
				protocol = RC_PROTO_RC6_6A_24;
				toggle = 0;
				break;
			case 32:
				if ((scancode & RC6_6A_LCC_MASK) == RC6_6A_MCE_CC) {
					protocol = RC_PROTO_RC6_MCE;
					toggle = !!(scancode & RC6_6A_MCE_TOGGLE_MASK);
					scancode &= ~RC6_6A_MCE_TOGGLE_MASK;
				} else {
					protocol = RC_PROTO_RC6_6A_32;
					toggle = 0;
				}
				break;
			default:
				IR_dprintk(1, "RC6(6A) unsupported length\n");
				goto out;
			}

			IR_dprintk(1, "RC6(6A) proto 0x%04x, scancode 0x%08x (toggle: %u)\n",
				   protocol, scancode, toggle);
			break;
		default:
			IR_dprintk(1, "RC6 unknown mode\n");
			goto out;
		}

		rc_keydown(dev, protocol, scancode, toggle);
		data->state = STATE_INACTIVE;
		return 0;
	}

out:
	IR_dprintk(1, "RC6 decode failed at state %i (%uus %s)\n",
		   data->state, TO_US(ev.duration), TO_STR(ev.pulse));
	data->state = STATE_INACTIVE;
	return -EINVAL;
}
Esempio n. 3
0
/**
 * ir_rc5_decode() - Decode one RC-5 pulse or space
 * @dev:	the struct rc_dev descriptor of the device
 * @ev:		the struct ir_raw_event descriptor of the pulse/space
 *
 * This function returns -EINVAL if the pulse violates the state machine
 */
static int ir_rc5_decode(struct rc_dev *dev, struct ir_raw_event ev)
{
	struct rc5_dec *data = &dev->raw->rc5;
	u8 toggle;
	u32 scancode;

        if (!(dev->raw->enabled_protocols & RC_TYPE_RC5))
                return 0;

	if (!is_timing_event(ev)) {
		if (ev.reset)
			data->state = STATE_INACTIVE;
		return 0;
	}

	if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2))
		goto out;

again:
	IR_dprintk(2, "RC5(x) decode started at state %i (%uus %s)\n",
		   data->state, TO_US(ev.duration), TO_STR(ev.pulse));

	if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2))
		return 0;

	switch (data->state) {

	case STATE_INACTIVE:
		if (!ev.pulse)
			break;

		data->state = STATE_BIT_START;
		data->count = 1;
		/* We just need enough bits to get to STATE_CHECK_RC5X */
		data->wanted_bits = RC5X_NBITS;
		decrease_duration(&ev, RC5_BIT_START);
		goto again;

	case STATE_BIT_START:
		if (!eq_margin(ev.duration, RC5_BIT_START, RC5_UNIT / 2))
			break;

		data->bits <<= 1;
		if (!ev.pulse)
			data->bits |= 1;
		data->count++;
		data->state = STATE_BIT_END;
		return 0;

	case STATE_BIT_END:
		if (!is_transition(&ev, &dev->raw->prev_ev))
			break;

		if (data->count == data->wanted_bits)
			data->state = STATE_FINISHED;
		else if (data->count == CHECK_RC5X_NBITS)
			data->state = STATE_CHECK_RC5X;
		else
			data->state = STATE_BIT_START;

		decrease_duration(&ev, RC5_BIT_END);
		goto again;

	case STATE_CHECK_RC5X:
		if (!ev.pulse && geq_margin(ev.duration, RC5X_SPACE, RC5_UNIT / 2)) {
			/* RC5X */
			data->wanted_bits = RC5X_NBITS;
			decrease_duration(&ev, RC5X_SPACE);
		} else {
			/* RC5 */
			data->wanted_bits = RC5_NBITS;
		}
		data->state = STATE_BIT_START;
		goto again;

	case STATE_FINISHED:
		if (ev.pulse)
			break;

		if (data->wanted_bits == RC5X_NBITS) {
			/* RC5X */
			u8 xdata, command, system;
			xdata    = (data->bits & 0x0003F) >> 0;
			command  = (data->bits & 0x00FC0) >> 6;
			system   = (data->bits & 0x1F000) >> 12;
			toggle   = (data->bits & 0x20000) ? 1 : 0;
			command += (data->bits & 0x01000) ? 0 : 0x40;
			scancode = system << 16 | command << 8 | xdata;

			IR_dprintk(1, "RC5X scancode 0x%06x (toggle: %u)\n",
				   scancode, toggle);

		} else {
Esempio n. 4
0
    /**
     * ir_rc6_decode() - Decode one RC6 pulse or space
     * @input_dev:	the struct input_dev descriptor of the device
     * @ev:		the struct ir_raw_event descriptor of the pulse/space
     *
     * This function returns -EINVAL if the pulse violates the state machine
     */
    static int ir_rc6_decode(struct input_dev *input_dev, struct ir_raw_event ev)
{
    struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
    struct rc6_dec *data = &ir_dev->raw->rc6;
    u32 scancode;
    u8 toggle;

    if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC6))
        return 0;

    if (IS_RESET(ev)) {
        data->state = STATE_INACTIVE;
        return 0;
    }

    if (!geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2))
        goto out;

again:
    IR_dprintk(2, "RC6 decode started at state %i (%uus %s)\n",
               data->state, TO_US(ev.duration), TO_STR(ev.pulse));

    if (!geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2))
        return 0;

    switch (data->state) {

    case STATE_INACTIVE:
        if (!ev.pulse)
            break;

        /* Note: larger margin on first pulse since each RC6_UNIT
           is quite short and some hardware takes some time to
           adjust to the signal */
        if (!eq_margin(ev.duration, RC6_PREFIX_PULSE, RC6_UNIT))
            break;

        data->state = STATE_PREFIX_SPACE;
        data->count = 0;
        return 0;

    case STATE_PREFIX_SPACE:
        if (ev.pulse)
            break;

        if (!eq_margin(ev.duration, RC6_PREFIX_SPACE, RC6_UNIT / 2))
            break;

        data->state = STATE_HEADER_BIT_START;
        return 0;

    case STATE_HEADER_BIT_START:
        if (!eq_margin(ev.duration, RC6_BIT_START, RC6_UNIT / 2))
            break;

        data->header <<= 1;
        if (ev.pulse)
            data->header |= 1;
        data->count++;
        data->state = STATE_HEADER_BIT_END;
        return 0;

    case STATE_HEADER_BIT_END:
        if (!is_transition(&ev, &ir_dev->raw->prev_ev))
            break;

        if (data->count == RC6_HEADER_NBITS)
            data->state = STATE_TOGGLE_START;
        else
            data->state = STATE_HEADER_BIT_START;

        decrease_duration(&ev, RC6_BIT_END);
        goto again;

    case STATE_TOGGLE_START:
        if (!eq_margin(ev.duration, RC6_TOGGLE_START, RC6_UNIT / 2))
            break;

        data->toggle = ev.pulse;
        data->state = STATE_TOGGLE_END;
        return 0;

    case STATE_TOGGLE_END:
        if (!is_transition(&ev, &ir_dev->raw->prev_ev) ||
                !geq_margin(ev.duration, RC6_TOGGLE_END, RC6_UNIT / 2))
            break;

        if (!(data->header & RC6_STARTBIT_MASK)) {
            IR_dprintk(1, "RC6 invalid start bit\n");
            break;
        }

        data->state = STATE_BODY_BIT_START;
        decrease_duration(&ev, RC6_TOGGLE_END);
        data->count = 0;

        switch (rc6_mode(data)) {
        case RC6_MODE_0:
            data->wanted_bits = RC6_0_NBITS;
            break;
        case RC6_MODE_6A:
            /* This might look weird, but we basically
               check the value of the first body bit to
               determine the number of bits in mode 6A */
            if ((!ev.pulse && !geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2)) ||
                    geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2))
                data->wanted_bits = RC6_6A_LARGE_NBITS;
            else
                data->wanted_bits = RC6_6A_SMALL_NBITS;
            break;
        default:
            IR_dprintk(1, "RC6 unknown mode\n");
            goto out;
        }
        goto again;

    case STATE_BODY_BIT_START:
        if (!eq_margin(ev.duration, RC6_BIT_START, RC6_UNIT / 2))
            break;

        data->body <<= 1;
        if (ev.pulse)
            data->body |= 1;
        data->count++;
        data->state = STATE_BODY_BIT_END;
        return 0;

    case STATE_BODY_BIT_END:
        if (!is_transition(&ev, &ir_dev->raw->prev_ev))
            break;

        if (data->count == data->wanted_bits)
            data->state = STATE_FINISHED;
        else
            data->state = STATE_BODY_BIT_START;

        decrease_duration(&ev, RC6_BIT_END);
        goto again;

    case STATE_FINISHED:
        if (ev.pulse)
            break;

        switch (rc6_mode(data)) {
        case RC6_MODE_0:
            scancode = data->body & 0xffff;
            toggle = data->toggle;
            IR_dprintk(1, "RC6(0) scancode 0x%04x (toggle: %u)\n",
                       scancode, toggle);
            break;
        case RC6_MODE_6A:
            if (data->wanted_bits == RC6_6A_LARGE_NBITS) {
                toggle = data->body & RC6_6A_MCE_TOGGLE_MASK ? 1 : 0;
                scancode = data->body & ~RC6_6A_MCE_TOGGLE_MASK;
            } else {
                toggle = 0;
                scancode = data->body & 0xffffff;
            }

            IR_dprintk(1, "RC6(6A) scancode 0x%08x (toggle: %u)\n",
                       scancode, toggle);
            break;
        default:
            IR_dprintk(1, "RC6 unknown mode\n");
            goto out;
        }

        ir_keydown(input_dev, scancode, toggle);
        data->state = STATE_INACTIVE;
        return 0;
    }

out:
    IR_dprintk(1, "RC6 decode failed at state %i (%uus %s)\n",
               data->state, TO_US(ev.duration), TO_STR(ev.pulse));
    data->state = STATE_INACTIVE;
    return -EINVAL;
}
Esempio n. 5
0
/**
 * ir_rc5_decode() - Decode one RC-5 pulse or space
 * @dev:	the struct rc_dev descriptor of the device
 * @ev:		the struct ir_raw_event descriptor of the pulse/space
 *
 * This function returns -EINVAL if the pulse violates the state machine
 */
static int ir_rc5_decode(struct rc_dev *dev, struct ir_raw_event ev)
{
	struct rc5_dec *data = &dev->raw->rc5;
	u8 toggle;
	u32 scancode;
	enum rc_type protocol;

	if (!is_timing_event(ev)) {
		if (ev.reset)
			data->state = STATE_INACTIVE;
		return 0;
	}

	if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2))
		goto out;

again:
	IR_dprintk(2, "RC5(x/sz) decode started at state %i (%uus %s)\n",
		   data->state, TO_US(ev.duration), TO_STR(ev.pulse));

	if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2))
		return 0;

	switch (data->state) {

	case STATE_INACTIVE:
		if (!ev.pulse)
			break;

		data->state = STATE_BIT_START;
		data->count = 1;
		decrease_duration(&ev, RC5_BIT_START);
		goto again;

	case STATE_BIT_START:
		if (!ev.pulse && geq_margin(ev.duration, RC5_TRAILER, RC5_UNIT / 2)) {
			data->state = STATE_FINISHED;
			goto again;
		}

		if (!eq_margin(ev.duration, RC5_BIT_START, RC5_UNIT / 2))
			break;

		data->bits <<= 1;
		if (!ev.pulse)
			data->bits |= 1;
		data->count++;
		data->state = STATE_BIT_END;
		return 0;

	case STATE_BIT_END:
		if (!is_transition(&ev, &dev->raw->prev_ev))
			break;

		if (data->count == CHECK_RC5X_NBITS)
			data->state = STATE_CHECK_RC5X;
		else
			data->state = STATE_BIT_START;

		decrease_duration(&ev, RC5_BIT_END);
		goto again;

	case STATE_CHECK_RC5X:
		if (!ev.pulse && geq_margin(ev.duration, RC5X_SPACE, RC5_UNIT / 2)) {
			data->is_rc5x = true;
			decrease_duration(&ev, RC5X_SPACE);
		} else
			data->is_rc5x = false;
		data->state = STATE_BIT_START;
		goto again;

	case STATE_FINISHED:
		if (ev.pulse)
			break;

		if (data->is_rc5x && data->count == RC5X_NBITS) {
			/* RC5X */
			u8 xdata, command, system;
			if (!(dev->enabled_protocols & RC_BIT_RC5X)) {
				data->state = STATE_INACTIVE;
				return 0;
			}
			xdata    = (data->bits & 0x0003F) >> 0;
			command  = (data->bits & 0x00FC0) >> 6;
			system   = (data->bits & 0x1F000) >> 12;
			toggle   = (data->bits & 0x20000) ? 1 : 0;
			command += (data->bits & 0x01000) ? 0 : 0x40;
			scancode = system << 16 | command << 8 | xdata;
			protocol = RC_TYPE_RC5X;

		} else if (!data->is_rc5x && data->count == RC5_NBITS) {
Esempio n. 6
0
void init_params_R1 (BNTree *bntree) {
  int i, j;
  int dimer_pair_num = 0;
  int param_idx = 0;
  int types[] = {0,   1,  2,  3, 16, 17,
		 4,   5,  6,  7, 16, 17,
		 8,   9, 10, 11, 16, 17,
		 12, 13, 14, 15, 16, 17,
		 18, 18, 18, 18, 19, 20,
		 21, 21, 21, 21, 22, 23};

  for (i=0; i<36; i++) {
    for (j=0; j<36; j++) {
      int type1 = types[i];
      int type2 = types[j];
      int char1 = i / 6;
      int char2 = i % 6;
      int char3 = j / 6;
      int char4 = j % 6;

      if (i == j) continue;

      if (type1 < 16 && type2 < 16) { /* base dimer to base dimer substitution */
	if (i > j) continue;  /* already took care of these */

	param_idx = dimer_pair_num++;
	bntree->param_map[i][j] = param_idx;
	bntree->param_map[j][i] = param_idx;
	
	bntree->weight_idx[i][j] = j;
	bntree->weight_idx[j][i] = i;
      }

      else if (type1 == type2 && (char1 != char3 || char2 != char4)) {
	/* mutation in a gap pattern base with no change in pattern */
	if (type1 == 16) {
	  if (is_transition (char1, char3))
	    param_idx = 192;
	  else
	    param_idx = 193;
	}
	else if (type1 == 17) {
	  if (is_transition (char1, char3))
	    param_idx = 194;
	  else
	    param_idx = 195;

	}
	else if (type1 == 18) {
	  if (is_transition (char2, char4))
	    param_idx = 196;
	  else
	    param_idx = 197;
	}
	else if (type1 == 21) {
	  if (is_transition (char2, char4))
	    param_idx = 198;
	  else
	    param_idx = 199;
	}
	bntree->param_map[i][j] = param_idx;	
	bntree->weight_idx[i][j] = -1;
      }

      else { /* gap pattern to different gap pattern */
	param_idx = 120 + 8 * int_max(type1 - 15, 0) + int_max(type2 - 15, 0); 
	if (type1 < type2)
	  param_idx--;

	bntree->param_map[i][j] = param_idx;	

	if (type2 < 16)
	  bntree->weight_idx[i][j] = j;
	else
	  bntree->weight_idx[i][j] = -1;
      }
    }
  }

  /* self substitutions */
  for (i=0; i<36; i++) {
    bntree->param_map[i][i] = 200 + i;
    bntree->weight_idx[i][i] = -1;
  }

  assert (dimer_pair_num == 120);
}
Esempio n. 7
0
static int ir_rc6_decode(struct rc6_ir *data, struct ir_signal signal,
		struct ir_protocol *ip)
{
	int i;
	i = ip->priv;
	if (i >= MAX_RC6_INFR_NR)
		goto out;

	if (!geq_margin(signal.duration, RC6_UNIT, RC6_UNIT / 2))
		goto out;
		
again:
	hiir_debug("RC6 decode started at state %i (%uus %s) "
		"count %d header 0x%x bits 0x%llx, count:%d\n",
		data->state, signal.duration, TO_STR(signal.pulse),
		data->count, data->header, data->bits, data->count);

	if (!geq_margin(signal.duration, RC6_UNIT, RC6_UNIT / 2))
		return 0;

	switch (data->state) {
	case STATE_INACTIVE:
		if (!signal.pulse)
			break;

		if (!eq_margin(signal.duration, RC6_PREFIX_PULSE, RC6_UNIT))
			break;

		data->state = STATE_PREFIX_SPACE;
		data->bits = 0;
		data->count = 0;
		data->header = 0;
		memset(&data->this_key, 0, sizeof(struct key_attr));
		return 0;

	case STATE_PREFIX_SPACE:
		if (signal.pulse)
			break;

		if (!eq_margin(signal.duration, RC6_PREFIX_SPACE,
			RC6_UNIT / 2))
			break;

		data->state = STATE_HEADER_BIT_START;
		return 0;

	case STATE_HEADER_BIT_START:
		if (!eq_margin(signal.duration, RC6_BIT_START,
			RC6_UNIT / 2))
			break;

		data->header <<= 1;
		if (signal.pulse)
			data->header |= 1;

		data->count++;
		data->state = STATE_HEADER_BIT_END;
		return 0;

	case STATE_HEADER_BIT_END:
		if (!is_transition(&signal, &data->prev_signal))
			break;

		if (data->count == RC6_HEADER_NBITS)
			data->state = STATE_TOGGLE_START;
		else
			data->state = STATE_HEADER_BIT_START;

		decrease_duration(&signal, RC6_BIT_END);
		goto again;

	case STATE_TOGGLE_START:
		if (!eq_margin(signal.duration, RC6_TOGGLE_START, RC6_UNIT / 2))
			break;

		data->state = STATE_TOGGLE_END;
		return 0;

	case STATE_TOGGLE_END:
		if (!is_transition(&signal, &data->prev_signal) 
			|| !geq_margin(signal.duration, RC6_TOGGLE_END,
				RC6_UNIT / 2))
			break;

		data->state = STATE_BIT_START;
		decrease_duration(&signal, RC6_TOGGLE_END);
		data->count = 0;

		goto again;

	case STATE_BIT_START:
		if (!eq_margin(signal.duration, RC6_BIT_START, RC6_UNIT / 2))
			break;
		
		data->bits <<= 1;
		if (signal.pulse)
			data->bits |= 1;
		data->count++;
		data->state = STATE_BIT_END;
		return 0;

	case STATE_BIT_END:
		if (!is_transition(&signal, &data->prev_signal))
			break;

		if (data->count == ip->attr.wanna_bits) {
			data->scancode = data->bits;
			data->this_key.lower = (data->scancode & (~RC6_TOGGLE_MASK));
			data->this_key.upper = 0;
			data->state = STATE_FINISHED;
			return 0;
		} else
			data->state = STATE_BIT_START;

		decrease_duration(&signal, RC6_BIT_END);
		goto again;

	case STATE_FINISHED:
		if (signal.pulse)
			break;

		data->state = STATE_INACTIVE;
		return 0;
	}

out:
	hiir_info("RC6 decode failed at state %i (%uus %s), bits received:%d\n",
		   data->state, signal.duration, TO_STR(signal.pulse), data->count);
	data->state = STATE_INACTIVE;
	return -EINVAL;
}
Esempio n. 8
0
/**
 * ir_rc5_sz_decode() - Decode one RC-5 Streamzap pulse or space
 * @input_dev:	the struct input_dev descriptor of the device
 * @ev:		the struct ir_raw_event descriptor of the pulse/space
 *
 * This function returns -EINVAL if the pulse violates the state machine
 */
static int ir_rc5_sz_decode(struct input_dev *input_dev, struct ir_raw_event ev)
{
	struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
	struct rc5_sz_dec *data = &ir_dev->raw->rc5_sz;
	u8 toggle, command, system;
	u32 scancode;

        if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC5_SZ))
                return 0;

	if (!is_timing_event(ev)) {
		if (ev.reset)
			data->state = STATE_INACTIVE;
		return 0;
	}

	if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2))
		goto out;

again:
	IR_dprintk(2, "RC5-sz decode started at state %i (%uus %s)\n",
		   data->state, TO_US(ev.duration), TO_STR(ev.pulse));

	if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2))
		return 0;

	switch (data->state) {

	case STATE_INACTIVE:
		if (!ev.pulse)
			break;

		data->state = STATE_BIT_START;
		data->count = 1;
		data->wanted_bits = RC5_SZ_NBITS;
		decrease_duration(&ev, RC5_BIT_START);
		goto again;

	case STATE_BIT_START:
		if (!eq_margin(ev.duration, RC5_BIT_START, RC5_UNIT / 2))
			break;

		data->bits <<= 1;
		if (!ev.pulse)
			data->bits |= 1;
		data->count++;
		data->state = STATE_BIT_END;
		return 0;

	case STATE_BIT_END:
		if (!is_transition(&ev, &ir_dev->raw->prev_ev))
			break;

		if (data->count == data->wanted_bits)
			data->state = STATE_FINISHED;
		else
			data->state = STATE_BIT_START;

		decrease_duration(&ev, RC5_BIT_END);
		goto again;

	case STATE_FINISHED:
		if (ev.pulse)
			break;

		/* RC5-sz */
		command  = (data->bits & 0x0003F) >> 0;
		system   = (data->bits & 0x02FC0) >> 6;
		toggle   = (data->bits & 0x01000) ? 1 : 0;
		scancode = system << 6 | command;

		IR_dprintk(1, "RC5-sz scancode 0x%04x (toggle: %u)\n",
			   scancode, toggle);

		ir_keydown(input_dev, scancode, toggle);
		data->state = STATE_INACTIVE;
		return 0;
	}

out:
	IR_dprintk(1, "RC5-sz decode failed at state %i (%uus %s)\n",
		   data->state, TO_US(ev.duration), TO_STR(ev.pulse));
	data->state = STATE_INACTIVE;
	return -EINVAL;
}
static int ir_rc6_decode(struct rc_dev *dev, struct ir_raw_event ev)
{
	struct rc6_dec *data = &dev->raw->rc6;
	u32 scancode;
	u8 toggle;

	if (!(dev->raw->enabled_protocols & RC_TYPE_RC6))
		return 0;

	if (!is_timing_event(ev)) {
		if (ev.reset)
			data->state = STATE_INACTIVE;
		return 0;
	}

	if (!geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2))
		goto out;

again:
	IR_dprintk(2, "RC6 decode started at state %i (%uus %s)\n",
		   data->state, TO_US(ev.duration), TO_STR(ev.pulse));

	if (!geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2))
		return 0;

	switch (data->state) {

	case STATE_INACTIVE:
		if (!ev.pulse)
			break;

		if (!eq_margin(ev.duration, RC6_PREFIX_PULSE, RC6_UNIT))
			break;

		data->state = STATE_PREFIX_SPACE;
		data->count = 0;
		return 0;

	case STATE_PREFIX_SPACE:
		if (ev.pulse)
			break;

		if (!eq_margin(ev.duration, RC6_PREFIX_SPACE, RC6_UNIT / 2))
			break;

		data->state = STATE_HEADER_BIT_START;
		data->header = 0;
		return 0;

	case STATE_HEADER_BIT_START:
		if (!eq_margin(ev.duration, RC6_BIT_START, RC6_UNIT / 2))
			break;

		data->header <<= 1;
		if (ev.pulse)
			data->header |= 1;
		data->count++;
		data->state = STATE_HEADER_BIT_END;
		return 0;

	case STATE_HEADER_BIT_END:
		if (!is_transition(&ev, &dev->raw->prev_ev))
			break;

		if (data->count == RC6_HEADER_NBITS)
			data->state = STATE_TOGGLE_START;
		else
			data->state = STATE_HEADER_BIT_START;

		decrease_duration(&ev, RC6_BIT_END);
		goto again;

	case STATE_TOGGLE_START:
		if (!eq_margin(ev.duration, RC6_TOGGLE_START, RC6_UNIT / 2))
			break;

		data->toggle = ev.pulse;
		data->state = STATE_TOGGLE_END;
		return 0;

	case STATE_TOGGLE_END:
		if (!is_transition(&ev, &dev->raw->prev_ev) ||
		    !geq_margin(ev.duration, RC6_TOGGLE_END, RC6_UNIT / 2))
			break;

		if (!(data->header & RC6_STARTBIT_MASK)) {
			IR_dprintk(1, "RC6 invalid start bit\n");
			break;
		}

		data->state = STATE_BODY_BIT_START;
		decrease_duration(&ev, RC6_TOGGLE_END);
		data->count = 0;
		data->body = 0;

		switch (rc6_mode(data)) {
		case RC6_MODE_0:
			data->wanted_bits = RC6_0_NBITS;
			break;
		case RC6_MODE_6A:
			data->wanted_bits = RC6_6A_NBITS;
			break;
		default:
			IR_dprintk(1, "RC6 unknown mode\n");
			goto out;
		}
		goto again;

	case STATE_BODY_BIT_START:
		if (eq_margin(ev.duration, RC6_BIT_START, RC6_UNIT / 2)) {
			
			if (data->count++ < CHAR_BIT * sizeof data->body) {
				data->body <<= 1;
				if (ev.pulse)
					data->body |= 1;
			}
			data->state = STATE_BODY_BIT_END;
			return 0;
		} else if (RC6_MODE_6A == rc6_mode(data) && !ev.pulse &&
				geq_margin(ev.duration, RC6_SUFFIX_SPACE, RC6_UNIT / 2)) {
			data->state = STATE_FINISHED;
			goto again;
		}
		break;

	case STATE_BODY_BIT_END:
		if (!is_transition(&ev, &dev->raw->prev_ev))
			break;

		if (data->count == data->wanted_bits)
			data->state = STATE_FINISHED;
		else
			data->state = STATE_BODY_BIT_START;

		decrease_duration(&ev, RC6_BIT_END);
		goto again;

	case STATE_FINISHED:
		if (ev.pulse)
			break;

		switch (rc6_mode(data)) {
		case RC6_MODE_0:
			scancode = data->body;
			toggle = data->toggle;
			IR_dprintk(1, "RC6(0) scancode 0x%04x (toggle: %u)\n",
				   scancode, toggle);
			break;
		case RC6_MODE_6A:
			if (data->count > CHAR_BIT * sizeof data->body) {
				IR_dprintk(1, "RC6 too many (%u) data bits\n",
					data->count);
				goto out;
			}

			scancode = data->body;
			if (data->count == RC6_6A_32_NBITS &&
					(scancode & RC6_6A_LCC_MASK) == RC6_6A_MCE_CC) {
				
				toggle = (scancode & RC6_6A_MCE_TOGGLE_MASK) ? 1 : 0;
				scancode &= ~RC6_6A_MCE_TOGGLE_MASK;
			} else {
				toggle = 0;
			}
			IR_dprintk(1, "RC6(6A) scancode 0x%08x (toggle: %u)\n",
				   scancode, toggle);
			break;
		default:
			IR_dprintk(1, "RC6 unknown mode\n");
			goto out;
		}

		rc_keydown(dev, scancode, toggle);
		data->state = STATE_INACTIVE;
		return 0;
	}

out:
	IR_dprintk(1, "RC6 decode failed at state %i (%uus %s)\n",
		   data->state, TO_US(ev.duration), TO_STR(ev.pulse));
	data->state = STATE_INACTIVE;
	return -EINVAL;
}
int main(int argc, char* argv[]) {
  FILE* F;
  TreeModel *model;
  int i, j, k, alph_size, nstates, do_eqfreqs = 0, exch_mode = 0, 
    list_mode = 0, latex_mode = 0, suppress_diag = 0, ti_tv = 0, 
    scientific_mode = 0,
    induced_aa = 0, do_stop_codons = 0, do_zeroes = 0, symmetric = 0, 
    context_ti_tv = 0, all_branches = 0;
  int startcol, endcol, ncols, branch_no = 0, matrix_idx = 0;
/*   int aa_inv[256]; */
  double t = -1, total_ti = 0, total_tv = 0, rho_s = 0, cpg_ti = 0, 
    cpg_tv = 0, non_cpg_ti = 0, non_cpg_tv = 0, cpg_eqfreq = 0;
  char *rate_format_string = "%8.6f";
  MarkovMatrix *M;
  char c;
  char tuple[5], tuple2[5]; /* , aa_alph[50]; */
  char *subst_mat_fname = NULL, *subst_score_fname = NULL, 
    *subst_mat_fname_paml = NULL, *order1_mod_fname = NULL;
  Matrix *subst_mat = NULL;
  List *matrix_list = lst_new_ptr(20), *traversal = NULL;

  while ((c = (char)getopt(argc, argv, "t:fedlLiM:N:A:B:aszSECh")) != -1) {
   switch(c) {
    case 't':
      if (optarg[0] == 'A') all_branches = 1;
      else t = get_arg_dbl_bounds(optarg, 0, INFTY);
      break;
    case 'f':
      do_eqfreqs = 1;
      break;
    case 'e':
      exch_mode = 1;
      break;
    case 'd':
      suppress_diag = 1;
      break;
    case 'l':
      list_mode = 1;
      break;
    case 'L':
      latex_mode = 1;
      break;
    case 'i':
      ti_tv = 1;
      break;
    case 'M':
      subst_mat_fname = optarg;
      induced_aa = 1;
      break;
    case 'N':
      subst_mat_fname_paml = optarg;
      induced_aa = 1;
      break;
    case 'A':
      subst_score_fname = optarg;
      break;
    case 'B':
      order1_mod_fname = optarg;
      break;
    case 'a':
      induced_aa = 1;
      do_zeroes = 1;
      break;
    case 's':
      do_stop_codons = 1;
      break;
    case 'z':
      do_zeroes = 1;
      break;
    case 'S':
      symmetric = 1;
      break;
    case 'E':
      scientific_mode = 1;
      rate_format_string = "%13.6e";
      break;
    case 'C':
      context_ti_tv = 1;
      break;
    case 'h':
      print_usage();
      exit(0);
    case '?':
      die("Unrecognized option.  Try \"display_rate_matrix -h\" for help.\n");
    }
  }

  set_seed(-1);

  if ((t >= 0 && exch_mode) || (latex_mode && list_mode) || 
      ((ti_tv || subst_mat_fname != NULL || subst_score_fname != NULL || 
        subst_mat_fname_paml != NULL || scientific_mode) && !list_mode) || 
      (subst_mat_fname != NULL && subst_score_fname != NULL) || 
      (subst_score_fname != NULL && subst_mat_fname_paml != NULL) || 
      (subst_mat_fname != NULL && subst_mat_fname_paml != NULL) || 
      optind != argc - 1) {
    die("ERROR: missing required arguments or illegal combination of arguments.\nTry \"display_rate_matrix -h\" for help.\n");
  }

  F = phast_fopen(argv[optind], "r");
  model = tm_new_from_file(F, 1);

  if (context_ti_tv) {
    /* this option requires completely different handling from the others */
    if (model->order != 2) { 
      die("ERROR: -C requires a model of order 3.\n");
    }
    do_context_dependent_ti_tv(model);
    exit(0);
  }

  if (induced_aa) {
    TreeModel *aa_model = tm_induced_aa(model);
    char *codon_to_aa = get_codon_mapping(model->rate_matrix->states);

    /* before freeing model, grab the expected rate of synonymous
       subst, rho_s */
    for (i = 0; i < model->rate_matrix->size; i++)
      for (j = 0; j < model->rate_matrix->size; j++)
        if (i != j && codon_to_aa[i] == codon_to_aa[j])
          rho_s += mm_get(model->rate_matrix, i, j) * 
            vec_get(model->backgd_freqs, i);

    sfree(codon_to_aa);

    tm_free(model);
    model = aa_model;
  }

  if (all_branches) {
    traversal = tr_inorder(model->tree);
    for (matrix_idx = 0; matrix_idx < lst_size(traversal); matrix_idx++) {
      TreeNode *n = lst_get_ptr(traversal, matrix_idx);
      if (n->parent == NULL) { lst_push_ptr(matrix_list, NULL); continue; }
      M = mm_new(model->rate_matrix->size, model->rate_matrix->states, DISCRETE);
      mm_exp(M, model->rate_matrix, n->dparent);
      lst_push_ptr(matrix_list, M);      
    }
  }
  else if (t >= 0) {
    M = mm_new(model->rate_matrix->size, model->rate_matrix->states, DISCRETE);
    mm_exp(M, model->rate_matrix, t);
    lst_push_ptr(matrix_list, M);
  }
  else 
    lst_push_ptr(matrix_list, model->rate_matrix);

  alph_size = (int)strlen(model->rate_matrix->states);
  nstates = model->rate_matrix->size;

  if (subst_mat_fname != NULL) {
    if ((F = fopen(subst_mat_fname, "r")) == NULL) {
      die("ERROR: Can't open %s.\n", subst_mat_fname);
    }    
    subst_mat = read_subst_mat(F, AA_ALPHABET); 
  }
  else if (subst_mat_fname_paml != NULL) {
    if ((F = fopen(subst_mat_fname_paml, "r")) == NULL) {
      die("ERROR: Can't open %s.\n", subst_mat_fname_paml);
    }    
    subst_mat = read_paml_matrix(F, AA_ALPHABET); 
  }
  else if (subst_score_fname != NULL) {
    if ((F = fopen(subst_score_fname, "r")) == NULL) {
      die("ERROR: Can't open %s.\n", subst_score_fname);
    }    
    subst_mat = read_subst_scores(model, F);
  }
  else if (order1_mod_fname != NULL) {
    if ((F = fopen(order1_mod_fname, "r")) == NULL) {
      die("ERROR: Can't open %s.\n", order1_mod_fname);
    }    
    subst_mat = unproject_rates(model, tm_new_from_file(F, 1));
  }

  /* loop through matrices to print */
  for (matrix_idx = 0; matrix_idx < lst_size(matrix_list); matrix_idx++) {
    M = lst_get_ptr(matrix_list, matrix_idx);

    if (all_branches) {
      if (M == NULL) continue;  /* root */
      printf("BRANCH %d (t = %.6f)\n", ++branch_no,
             ((TreeNode*)lst_get_ptr(traversal, matrix_idx))->dparent);
    }

  /* print no more than 16 columns at a time (except with -a) */
  ncols = (induced_aa ? nstates : 16);
  for (startcol = 0; startcol < nstates; startcol += ncols) {
    endcol = min(nstates, startcol+ncols);

    /* table header */
    if (! list_mode) {
      if (latex_mode) {
        printf("\\begin{tabular}{|c|");
        for (i = startcol; i < endcol; i++) printf("r");
        printf("|}\n\\hline\n");
      }
      printf("%-5s ", "");
      if (latex_mode) printf("& ");
      for (i = startcol; i < endcol; i++) {
        get_state_tuple(model, tuple, i);
        if (latex_mode) {
          printf("{\\bf %s}", tuple);
          if (i < endcol-1) printf("& ");
        }
        else printf("%8s ", tuple);
    }
      if (latex_mode) printf("\\\\\n\\hline\n");
      else printf("\n");
    }

    /* table or list contents */
    for (i = 0; i < nstates; i++) {
      if (induced_aa && AA_ALPHABET[i] == '$' && !do_stop_codons) continue;
      get_state_tuple(model, tuple, i);

      /* get total eq freq of tuples containing CpG dinucs */
      for (k = 0; k < model->order; k++) {
        if (tuple[k] == 'C' && tuple[k+1] == 'G') {
          cpg_eqfreq += vec_get(model->backgd_freqs, i);
/*           printf("***CPG***"); */
          break;
        }
      }

      if (latex_mode) printf("{\\bf %s}& ", tuple);
      else if (!list_mode) printf("%-5s ", tuple);
      for (j = startcol; j < endcol; j++) {
        if (induced_aa && AA_ALPHABET[j] == '$' && !do_stop_codons) continue;
        if (latex_mode) printf("$");
        if (list_mode) {
          if (symmetric && j <= i) continue;
          else if ((t < 0 && ! all_branches) 
		   && (i == j || (!do_zeroes && mm_get(M, i, j) == 0))) 
            continue;
          get_state_tuple(model, tuple2, j);
          printf("%-5s %-5s ", tuple, tuple2);
        }
        if (i == j && suppress_diag && !list_mode) printf("%-7s", "-");
        else { 
	  /* get rate or probability */
	  double val = exch_mode == 0 ? mm_get(M, i, j) : 
	    safediv(mm_get(M, i, j), vec_get(model->backgd_freqs,j));
	  /* print value in format %8.6f or %13.6e */
	  printf(rate_format_string, val); 
	  printf(" ");
	}
        if (latex_mode) {
          printf("$");
          if (j < endcol-1) printf("& ");
        }
        else if (list_mode) {
          int ti, is_cpg;
          if (ti_tv) {
            ti = -1;
            is_cpg = 0;
            for (k = 0; k <= model->order; k++) {
              int dig_i = (i % int_pow(alph_size, k+1)) / int_pow(alph_size, k);
              int dig_j = (j % int_pow(alph_size, k+1)) / int_pow(alph_size, k);
              char next_char = '\0', prev_char = '\0';
              if (dig_i != dig_j) {
                ti = is_transition(M->states[dig_i], M->states[dig_j]);
                if (k != model->order)
                  prev_char = M->states[(i % int_pow(alph_size, k+2)) / 
                                        int_pow(alph_size, k+1)];
                if (k != 0)
                  next_char = M->states[(i % int_pow(alph_size, k)) / 
                                        int_pow(alph_size, k-1)];
                if ((M->states[dig_i] == 'C' && next_char == 'G') || 
                    (M->states[dig_i] == 'G' && prev_char == 'C')) 
                  is_cpg = 1;
              }
            }
	    if (ti == -1)
	      die("ERROR ti=-1\n");
            printf("%5s ", ti ? "ti" : "tv");
/*             printf("%5s ", is_cpg ? "CPG" : "-"); */
            if (ti) {
              total_ti += mm_get(M, i, j) * 
                vec_get(model->backgd_freqs, i);
              if (is_cpg) 
                cpg_ti += mm_get(M, i, j) * 
                  vec_get(model->backgd_freqs, i);
              else non_cpg_ti += mm_get(M, i, j) * 
                     vec_get(model->backgd_freqs, i);
            }
            else {
              total_tv += mm_get(M, i, j) * 
                vec_get(model->backgd_freqs, i);
              if (is_cpg)
                cpg_tv += mm_get(M, i, j) * 
                  vec_get(model->backgd_freqs, i);
              else non_cpg_tv += mm_get(M, i, j) * 
                     vec_get(model->backgd_freqs, i);
            }
          }
          if (subst_mat != NULL) {
            if (mat_get(subst_mat, i, j) == NEGINFTY) 
              printf("%8s", "-"); 
            else printf("%8.4f", mat_get(subst_mat, i, j)); 
          }
          printf("\n");
        }
      }
      if (latex_mode) printf("\\\\\n");
      else if (!list_mode) printf("\n");
    }
    
    /* equilibrium freqs (table case only) */
    if (do_eqfreqs && ! list_mode) {
      if (latex_mode) 
        printf("\\hline\n$\\boldsymbol{\\mathbf{\\pi}}$&");
      else 
        printf("%-5s ", "pi");
      for (i = startcol; i < endcol; i++) {
        if (latex_mode) 
          printf("$%8.4f$ ", vec_get(model->backgd_freqs, i));      
        else 
          printf("%8.4f ", vec_get(model->backgd_freqs, i));      
        if (latex_mode && i < endcol-1) printf("& ");
      }
      if (latex_mode) printf("\\\\\n");
      else printf("\n");
    }

    if (latex_mode) printf("\\hline\n\\end{tabular}\n\n");
  }

  /* equilibrium freqs (list case only) */
  if (do_eqfreqs &&  list_mode) {
    for (i = 0; i < nstates; i++) {
      get_state_tuple(model, tuple, i);
      printf("%-5s %-5s ", "-", tuple); //!!
      printf(rate_format_string, vec_get(model->backgd_freqs, i)); 
      printf("\n");
    }
  }
  
  if (ti_tv && list_mode) {
    printf("\n#Total ti/tv = %.4f\n", total_ti/total_tv);
    printf("#CpG ti ratio = %.4f, CpG tv ratio = %.4f\n", 
           cpg_ti/non_cpg_ti /* * (1 - cpg_eqfreq) */ / cpg_eqfreq, 
           cpg_tv/non_cpg_tv /* * (1 - cpg_eqfreq) */ / cpg_eqfreq);
  }
  else if (induced_aa) 
    printf("\n#Total rho_s/rho_v = %.4f\n", rho_s/(3-rho_s));

  if (all_branches == 1) printf("\n\n");
  }

  tm_free(model);
  lst_free(matrix_list);

  return 0;
}
/* this function implements the -C option */
void do_context_dependent_ti_tv(TreeModel *mod) {
  char *alph = mod->rate_matrix->states;
  int alph_size = (int)strlen(alph);
  char tuple_i[mod->order+2], tuple_j[mod->order+2];
  double context_ti[alph_size][alph_size], context_tv[alph_size][alph_size],
    ti_AT_5_pyrim[3][3], tv_AT_5_pyrim[3][3],
    all_ti, all_tv, expected_rate;
  int mid_src, mid_targ, first, last, at_states[2], gc_states[2], i, j, 
    num_5_pyrim;
  if (mod->order != 2)
    die("ERROR do_context_dependent_ti_tv: mod->order (%i) should be 2\n",
	mod->order);
  if (alph_size != 4)
    die("ERROR do_contect_dependent_ti_tv: alph_size (%i) should be 4\n", 
	alph_size);

  tuple_i[mod->order+1] = tuple_j[mod->order+1] = '\0';

  /* We only care about substitutions at the middle position */
  for (first = 0; first < alph_size; first++) {
    for (last = 0; last < alph_size; last++) {
      context_ti[first][last] = context_tv[first][last] = 0;
      for (mid_src = 0; mid_src < alph_size; mid_src++) {
        for (mid_targ = 0; mid_targ < alph_size; mid_targ++) {
          if (mid_src == mid_targ) continue;

          i = last + mid_src*alph_size + first*alph_size*alph_size;
          j = last + mid_targ*alph_size + first*alph_size*alph_size;
          expected_rate = mm_get(mod->rate_matrix, i, j) * 
            vec_get(mod->backgd_freqs, i);

/*           get_tuple_str(tuple_i, i, mod->order+1,  */
/*                         mod->rate_matrix->states); */
/*           get_tuple_str(tuple_j, j, mod->order+1,  */
/*                         mod->rate_matrix->states); */

/*           if ((tuple_i[1] == 'C' && tuple_i[2] == 'G') || tuple_i[0] == 'C' && tuple_i[1] == 'G') continue; */

          if (is_transition(alph[mid_src], alph[mid_targ]))
            context_ti[first][last] += expected_rate;
          else if (i != j)
            context_tv[first][last] += expected_rate;
        }
      }
    }
  }

  /* first print equivalent of table 2 */

  /* get "states" associated with A+T bases and G+C bases */
  at_states[0] = mod->rate_matrix->inv_states['A'];
  at_states[1] = mod->rate_matrix->inv_states['T'];
  gc_states[0] = mod->rate_matrix->inv_states['C'];
  gc_states[1] = mod->rate_matrix->inv_states['G'];

  /* header */
  printf("%5s %5s %5s %8s %8s %8s\n", "A+T", "5'", "3'", "Ts", "Tv", "Tv/(Tv+Ts)");

  for (i = 0; i < 3; i++)
    for (j = 0; j < 3; j++)
      ti_AT_5_pyrim[i][j] = tv_AT_5_pyrim[i][j] = 0;

  /* AT content 0 (GC either side) */
  all_ti = all_tv = 0;
  for (first = 0; first < 2; first++) {
    for (last = 0; last < 2; last++) {
      printf("%5d %5c %5c %8.4f %8.4f %8.4f\n", 0, 
             alph[(int)gc_states[first]], 
             alph[(int)gc_states[last]], 
             context_ti[gc_states[first]][gc_states[last]],
             context_tv[gc_states[first]][gc_states[last]],
             context_tv[gc_states[first]][gc_states[last]] /
             (context_ti[gc_states[first]][gc_states[last]] +
              context_tv[gc_states[first]][gc_states[last]]));
      all_ti += context_ti[gc_states[first]][gc_states[last]];
      all_tv += context_tv[gc_states[first]][gc_states[last]];
      
      num_5_pyrim = IS_PYRIMIDINE(alph[(int)gc_states[first]]);
      num_5_pyrim += IS_PYRIMIDINE(msa_compl_char(alph[(int)gc_states[last]]));
      ti_AT_5_pyrim[0][num_5_pyrim] += 
        context_ti[gc_states[first]][gc_states[last]];
      tv_AT_5_pyrim[0][num_5_pyrim] += 
        context_tv[gc_states[first]][gc_states[last]];
    }
  }
  printf("%5d %5s %5s %8.4f %8.4f %8.4f\n", 0, "all", "all", all_ti, 
         all_tv, all_tv / (all_ti + all_tv));
      
  /* AT content 1 (AT one side, GC other side) */
  all_ti = all_tv = 0;
  for (first = 0; first < 2; first++) {
    for (last = 0; last < 2; last++) {
      printf("%5d %5c %5c %8.4f %8.4f %8.4f\n", 1, 
             alph[(int)at_states[first]], 
             alph[(int)gc_states[last]], 
             context_ti[at_states[first]][gc_states[last]],
             context_tv[at_states[first]][gc_states[last]],
             context_tv[at_states[first]][gc_states[last]] /
             (context_ti[at_states[first]][gc_states[last]] +
              context_tv[at_states[first]][gc_states[last]]));
      printf("%5d %5c %5c %8.4f %8.4f %8.4f\n", 1, 
             alph[(int)gc_states[first]], 
             alph[(int)at_states[last]], 
             context_ti[gc_states[first]][at_states[last]],
             context_tv[gc_states[first]][at_states[last]],
             context_tv[gc_states[first]][at_states[last]] /
             (context_ti[gc_states[first]][at_states[last]] +
              context_tv[gc_states[first]][at_states[last]]));
      all_ti += context_ti[at_states[first]][gc_states[last]] +
        context_ti[gc_states[first]][at_states[last]];
      all_tv += context_tv[at_states[first]][gc_states[last]] +
        context_tv[gc_states[first]][at_states[last]];

      num_5_pyrim = IS_PYRIMIDINE(alph[(int)at_states[first]]);
      num_5_pyrim += IS_PYRIMIDINE(msa_compl_char(alph[(int)gc_states[last]]));
      ti_AT_5_pyrim[1][num_5_pyrim] += 
        context_ti[at_states[first]][gc_states[last]];
      tv_AT_5_pyrim[1][num_5_pyrim] += 
        context_tv[at_states[first]][gc_states[last]];

      num_5_pyrim = IS_PYRIMIDINE(alph[(int)gc_states[first]]);
      num_5_pyrim += IS_PYRIMIDINE(msa_compl_char(alph[(int)at_states[last]]));
      ti_AT_5_pyrim[1][num_5_pyrim] += 
        context_ti[gc_states[first]][at_states[last]];
      tv_AT_5_pyrim[1][num_5_pyrim] += 
        context_tv[gc_states[first]][at_states[last]];
    }
  }
  printf("%5d %5s %5s %8.4f %8.4f %8.4f\n", 1, "all", "all", all_ti, 
         all_tv, all_tv / (all_ti + all_tv));

  /* AT content 2 (AT both sides) */
  all_ti = all_tv = 0;
  for (first = 0; first < 2; first++) {
    for (last = 0; last < 2; last++) {
      printf("%5d %5c %5c %8.4f %8.4f %8.4f\n", 2, 
             alph[(int)at_states[first]], 
             alph[(int)at_states[last]], 
             context_ti[at_states[first]][at_states[last]],
             context_tv[at_states[first]][at_states[last]],
             context_tv[at_states[first]][at_states[last]] /
             (context_ti[at_states[first]][at_states[last]] +
              context_tv[at_states[first]][at_states[last]]));
      all_ti += context_ti[at_states[first]][at_states[last]];
      all_tv += context_tv[at_states[first]][at_states[last]];

      num_5_pyrim = IS_PYRIMIDINE(alph[(int)at_states[first]]);
      num_5_pyrim += IS_PYRIMIDINE(msa_compl_char(alph[(int)at_states[last]]));
      ti_AT_5_pyrim[2][num_5_pyrim] += 
        context_ti[at_states[first]][at_states[last]];
      tv_AT_5_pyrim[2][num_5_pyrim] += 
        context_tv[at_states[first]][at_states[last]];
    }
  }
  printf("%5d %5s %5s %8.4f %8.4f %8.4f\n", 2, "all", "all", all_ti, 
         all_tv, all_tv / (all_ti + all_tv));

  /* now print equivalent of table 3 */
  printf("\n\n%5s %5s %8s %8s %8s\n", "A+T", "5'Y", "Ts", "Tv", "Tv/(Tv+Ts)");
  for (i = 0; i < 3; i++) 
    for (j = 0; j < 3; j++) 
      printf("%5d %5d %8.4f %8.4f %8.4f\n", i, j, ti_AT_5_pyrim[i][j], tv_AT_5_pyrim[i][j], tv_AT_5_pyrim[i][j]/(tv_AT_5_pyrim[i][j] + ti_AT_5_pyrim[i][j]));
  for (j = 0; j < 3; j++) {
    double all_ti = ti_AT_5_pyrim[0][j] + ti_AT_5_pyrim[1][j] + 
      ti_AT_5_pyrim[2][j];
    double all_tv = tv_AT_5_pyrim[0][j] + tv_AT_5_pyrim[1][j] + 
      tv_AT_5_pyrim[2][j];
    printf("%5s %5d %8.4f %8.4f %8.4f\n", "all", j, all_ti, all_tv, all_tv/(all_tv + all_ti));
  }
}