次は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;
}