2012年12月31日月曜日

リモコンフォーマットの解析と展開(SONY)

次はSONYフォーマットの解析部分と展開部分です。

-----

/*
 code[0],code[1]    = ID
 code[2],code[3]    = length
 code[4]            = FormatSONY 0x03
 code[5]            = 1TCLK
 code[6]            = AddrLen (5/8/13)
 code[7] - code[31] = reserve
 code[32]           = Data
 code[33],code[34]  = Address
 */
int FormatAnalyzeSONY(unsigned int *buf, int bufSize, unsigned char *code, int codeSize) {

  int last = -1;
  int n = 0;
  int c = 0;
  int on = 0;
  int off = 0;
  int t = 1000;
  int r = 0;
  memset(code, 0, codeSize);
  for(int i = 0; i < bufSize * 32; i++) {
    int d = (buf[i / 32] >> (31 - (i % 32))) & 1;
    if((last < 0) && (d == 1)) continue; // skip nosignal

    if(d != last) { // data edge
      if(c && (last == 0)) {
        on = c;
        if(!n) { // leader
           t = on / 4;
        } else { // customer/data code
          if(((off + t / 2) / t) != 1) return -1;
          if(((on + t / 2) / t) == 2) {
            code[32 + (n-1)/8 + r * 4] |= 1 << ((n-1)%8);
          } else if(((on + t / 2) / t) != 1) {
            return -1;
          }
        }
        n++;
        if(n == 8) n++;
      } else if(c) {
        off = c;
      }
      c = 1;
    } else { // data continue
      c++;
      if(c > t * 20) { // trailer
        if(n) {
          code[32 + 3 + r * 4] = n;
          r++;
        }
        n = 0;
      }
    }
    last = d;
  }
  if(r < 3) return -1;
  n = code[32 + 3];
  if((n != (1 + 8 + 5)) && (n != (1 + 8 + 8)) && (n != (1 + 8 + 13))) return -1;
  if(memcmp(&code[32], &code[36], 3) || memcmp(&code[32], &code[40], 3)) return -1;

  code[3] = 32 + 3;
  code[4] = 3;
  code[5] = t;
  code[6] = n - 8 - 1;
  return 32 + 3;
}

int CodeExpandSONY(unsigned char *code, int codeSize, unsigned int *buf, int bufSize) {

  memset(buf, 0, bufSize * 4);
  int len = (((code[2] << 8) | code[3]) - 32) / 2;
  int t = code[5];
  int alen = code[6];

  int p = 0;
  for(int i = 0; i < 3; i++) {
    // leader
    for(int j = 0; j < 4 * t; j++) {
      if(!(p & 1)) buf[p / 32] |= (1 << (31 - (p % 32)));
      p++;
    }

    //Data
    for(int j = 0; j < 7; j++) {
      int d = (code[32] >> j) & 1;
      p += t;
      for(int k = 0; k < (d?t*2:t); k++) {
        if(!(p & 1)) buf[p / 32] |= (1 << (31 - (p % 32)));
        p++;
      }
    }

    //Addr
    for(int j = 0; j < alen; j++) {
      int d = (code[33 + (j / 8)] >> (j % 8)) & 1;
      p += t;
      for(int k = 0; k < (d?t*2:t); k++) {
        if(!(p & 1)) buf[p / 32] |= (1 << (31 - (p % 32)));
        p++;
      }
    }
    p = 3420 * i;
  }
  p += 31;
  return p / 32;
}

0 件のコメント:

コメントを投稿