// File: probonopd[P]decodeir/DecodeIR.cpp
// Function: Signal::decodeAsync(float*, int, int, double, double, int, int)
int Signal::decodeAsync(
                        float *pData,
                        int bits,   // previously decoded bits
                        int sizes,  // Bitmask of integerized durations seen
                        double dBitMin,
                        double dBitMax,
                        int bitsPerByte, // 10 or 11 = start + 8 data + 1 or 2 stop
                        int minTotBits )
{
	if (bits >= (int)sizeof(cBits)*bitsPerByte)
		return 0;
	int phase = bits % bitsPerByte;
	int pole = ( pData - pFrame ) & 1;  // 0==pulse  1==gap
	int minBits = (int)(*pData / dBitMax + .69999);  // fewest bits this value might be
	if ( minBits == 0 )
		minBits = 1;
	int maxB = (pole ? bitsPerByte : 9 ) - phase;    // most bits that would be valid here
	int maxBits = (int)(*pData / dBitMin + .30001);  // most bits this value might be
	if ( pData == pFrameEnd )
	{
		if (bits < minTotBits || maxBits <= maxB)
			return 0;
		sizes &= sizes - 1; // clear one bit
		if ( ( sizes & (sizes-1) ) == 0 )
			return 0;  // Need to see at least three sizes
		int bytes = bits/bitsPerByte + 1;
		memset(cBits,0xFF,bytes);
		nMinShort = floor(dBitMin);
		nMaxShort = ceil(dBitMax);
		return bytes;
	}
	if ( maxBits > maxB )
		maxBits = maxB;
	for (int nGuess = minBits; nGuess <= maxBits; ++nGuess)
	{
		if (pole && nGuess+phase > 8 && nGuess < maxB)
			continue;
		double dNewMin = *pData / (nGuess+.3);
		if (dNewMin < dBitMin)
			dNewMin = dBitMin;
		double dNewMax = *pData / (nGuess-.3);
		if (dNewMax > dBitMax)
			dNewMax = dBitMax;
		if ( dNewMin <= dNewMax )
		{
			int result = decodeAsync(pData+1, bits+nGuess, sizes | (1<<nGuess), dNewMin, dNewMax, bitsPerByte, minTotBits);
			if (result)
			{
				if (!pole)
					cBits[bits/bitsPerByte] &= (unsigned char)( ((((0xFF<<nGuess)+1)<<phase) - 1) >>1 ); 
				return result;
			}
		}
	}
	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x80, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movl %edx, -0x1c(%rbp)
movl %ecx, -0x20(%rbp)
movsd %xmm0, -0x28(%rbp)
movsd %xmm1, -0x30(%rbp)
movl %r8d, -0x34(%rbp)
movl %r9d, -0x38(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x78(%rbp)
movl -0x1c(%rbp), %eax
movl -0x34(%rbp), %ecx
shll $0x4, %ecx
cmpl %ecx, %eax
jl 0x167bc
movl $0x0, -0x4(%rbp)
jmp 0x16a88
movq -0x78(%rbp), %rcx
movl -0x1c(%rbp), %eax
cltd
idivl -0x34(%rbp)
movl %edx, -0x3c(%rbp)
movq -0x18(%rbp), %rax
movq 0x38(%rcx), %rcx
subq %rcx, %rax
sarq $0x2, %rax
andq $0x1, %rax
movl %eax, -0x40(%rbp)
movq -0x18(%rbp), %rax
movss (%rax), %xmm0
cvtss2sd %xmm0, %xmm0
divsd -0x30(%rbp), %xmm0
movsd 0x3f4f(%rip), %xmm1     # 0x1a748
addsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
movl %eax, -0x44(%rbp)
cmpl $0x0, -0x44(%rbp)
jne 0x16811
movl $0x1, -0x44(%rbp)
cmpl $0x0, -0x40(%rbp)
je 0x1681f
movl -0x34(%rbp), %eax
movl %eax, -0x7c(%rbp)
jmp 0x16829
movl $0x9, %eax
movl %eax, -0x7c(%rbp)
jmp 0x16829
movq -0x78(%rbp), %rcx
movl -0x7c(%rbp), %eax
subl -0x3c(%rbp), %eax
movl %eax, -0x48(%rbp)
movq -0x18(%rbp), %rax
movss (%rax), %xmm0
cvtss2sd %xmm0, %xmm0
divsd -0x28(%rbp), %xmm0
movsd 0x3f01(%rip), %xmm1     # 0x1a750
addsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
movl %eax, -0x4c(%rbp)
movq -0x18(%rbp), %rax
cmpq 0x40(%rcx), %rax
jne 0x16911
movl -0x1c(%rbp), %eax
cmpl -0x38(%rbp), %eax
jl 0x16878
movl -0x4c(%rbp), %eax
cmpl -0x48(%rbp), %eax
jg 0x16884
movl $0x0, -0x4(%rbp)
jmp 0x16a88
movl -0x20(%rbp), %eax
subl $0x1, %eax
andl -0x20(%rbp), %eax
movl %eax, -0x20(%rbp)
movl -0x20(%rbp), %eax
movl -0x20(%rbp), %ecx
subl $0x1, %ecx
andl %ecx, %eax
cmpl $0x0, %eax
jne 0x168ac
movl $0x0, -0x4(%rbp)
jmp 0x16a88
movq -0x78(%rbp), %rdi
movl -0x1c(%rbp), %eax
cltd
idivl -0x34(%rbp)
addl $0x1, %eax
movl %eax, -0x50(%rbp)
addq $0xa0, %rdi
movslq -0x50(%rbp), %rdx
movl $0xff, %esi
callq 0x20c0
movsd -0x28(%rbp), %xmm0
callq 0x2200
movq -0x78(%rbp), %rax
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0xe4(%rax)
movsd -0x30(%rbp), %xmm0
callq 0x2050
movq -0x78(%rbp), %rax
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0xe8(%rax)
movl -0x50(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x16a88
movl -0x4c(%rbp), %eax
cmpl -0x48(%rbp), %eax
jle 0x1691f
movl -0x48(%rbp), %eax
movl %eax, -0x4c(%rbp)
movl -0x44(%rbp), %eax
movl %eax, -0x54(%rbp)
movl -0x54(%rbp), %eax
cmpl -0x4c(%rbp), %eax
jg 0x16a81
cmpl $0x0, -0x40(%rbp)
je 0x1694f
movl -0x54(%rbp), %eax
addl -0x3c(%rbp), %eax
cmpl $0x8, %eax
jle 0x1694f
movl -0x54(%rbp), %eax
cmpl -0x48(%rbp), %eax
jge 0x1694f
jmp 0x16a73
movq -0x18(%rbp), %rax
movss (%rax), %xmm0
cvtss2sd %xmm0, %xmm0
cvtsi2sdl -0x54(%rbp), %xmm1
movsd 0x3908(%rip), %xmm2     # 0x1a270
addsd %xmm2, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0x60(%rbp)
movsd -0x60(%rbp), %xmm1
movsd -0x28(%rbp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x1698f
movsd -0x28(%rbp), %xmm0
movsd %xmm0, -0x60(%rbp)
movq -0x18(%rbp), %rax
movss (%rax), %xmm0
cvtss2sd %xmm0, %xmm0
cvtsi2sdl -0x54(%rbp), %xmm1
movsd 0x38c8(%rip), %xmm2     # 0x1a270
subsd %xmm2, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0x68(%rbp)
movsd -0x68(%rbp), %xmm0
ucomisd -0x30(%rbp), %xmm0
jbe 0x169cb
movsd -0x30(%rbp), %xmm0
movsd %xmm0, -0x68(%rbp)
movsd -0x60(%rbp), %xmm1
movsd -0x68(%rbp), %xmm0
ucomisd %xmm1, %xmm0
jb 0x16a71
movq -0x78(%rbp), %rdi
movq -0x18(%rbp), %rsi
addq $0x4, %rsi
movl -0x1c(%rbp), %edx
addl -0x54(%rbp), %edx
movl -0x20(%rbp), %eax
movl %eax, -0x80(%rbp)
movl -0x54(%rbp), %ecx
movl $0x1, %eax
shll %cl, %eax
movl -0x80(%rbp), %ecx
orl %eax, %ecx
movsd -0x60(%rbp), %xmm0
movsd -0x68(%rbp), %xmm1
movl -0x34(%rbp), %r8d
movl -0x38(%rbp), %r9d
callq 0x16770
movl %eax, -0x6c(%rbp)
cmpl $0x0, -0x6c(%rbp)
je 0x16a6f
cmpl $0x0, -0x40(%rbp)
jne 0x16a67
movl -0x54(%rbp), %ecx
movl $0xff, %eax
shll %cl, %eax
addl $0x1, %eax
movl -0x3c(%rbp), %ecx
shll %cl, %eax
subl $0x1, %eax
sarl %eax
movzbl %al, %esi
movl -0x1c(%rbp), %eax
cltd
idivl -0x34(%rbp)
movl %eax, %ecx
movq -0x78(%rbp), %rax
movslq %ecx, %rcx
movzbl 0xa0(%rax,%rcx), %edx
andl %esi, %edx
movb %dl, 0xa0(%rax,%rcx)
movl -0x6c(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x16a88
jmp 0x16a71
jmp 0x16a73
movl -0x54(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x54(%rbp)
jmp 0x16925
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x80, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)