// File: /workspace/github_c_makefile_star2_O3/DrYerzinia[P]C_DigiMode/src/packet/AFSK_Demodulator.c
// Function: AFSK_Demodulator_proccess_byte
char_array* AFSK_Demodulator_proccess_byte(AFSK_Demodulator *self, int8_t data_point){

	char_array* new_data = NULL;

	char_ring_buffer_put(&self->input_buffer, data_point);

	if(char_ring_buffer_avail(&self->input_buffer) > self->window){

		float q1_0 = 0;
		float q1_1 = 0;
		float q2_0 = 0;
		float q2_1 = 0;

		int16_t i;
		for(i = 0; i <= self->window; i++){

			float q0_0 = self->coeff0*q1_0 - q2_0 + char_ring_buffer_get(&self->input_buffer, i);
			float q0_1 = self->coeff1*q1_1 - q2_1 + char_ring_buffer_get(&self->input_buffer, i);
			q2_0 = q1_0;
			q2_1 = q1_1;
			q1_0 = q0_0;
			q1_1 = q0_1;

		}

		float fc1 = q1_0*q1_0 + q2_0*q2_0 - q1_0*q2_0*self->coeff0;
		float fc2 = q1_1*q1_1 + q2_1*q2_1 - q1_1*q2_1*self->coeff1;

		float fcd = fc1 - fc2;

		if(fcd > self->fcMax)
			self->fcMax = fcd*0.85 + self->fcMax*0.15;
		else
			self->fcMax = fcd*0.00015 + self->fcMax*0.99985;

		if(fcd < self->fcMin)
			self->fcMin = fcd*0.85 + self->fcMin*0.15;
		else
			self->fcMin = fcd*0.00015 + self->fcMin*0.99985;

		int generated_offset = (self->fcMax-self->fcMin)*self->offset;

		fcd -= generated_offset;

		char_ring_buffer_pop(&self->input_buffer);

		float_ring_buffer_put(&self->fcd_buffer, fcd);

		uint16_t avail = float_ring_buffer_avail(&self->fcd_buffer);
		if(avail > self->window/2){

			float fcd_avg = 0;
			for(i = 0; i < avail; i++)
				fcd_avg += float_ring_buffer_get(&self->fcd_buffer, i);
			fcd_avg /= avail;

			float_ring_buffer_pop(&self->fcd_buffer);

			/* Debug code to dump averaged Fourier coefficients to raw data
			 * file for analysis
			 */
			#ifdef __DEBUG
				fputc(fcd_avg, fourier_coefficient_debug);
			#endif

			uint8_t current_value = 0;
			if(fcd_avg < 0)
				current_value = 1;

			if(current_value != self->last_bit){

				self->last_bit = current_value;

				// Calculate how many bit lengths there are to the transition
				uint8_t new_bits = (int)((((float)self->count_last)/((float)self->bitwidth))+0.5);

				// If we are not bit stuffing Add a 0
				if(!self->bit_stuffing)
					char_ring_buffer_put(&self->bit_sequence, 0);

				// If we where bit stuffing stop now
				self->bit_stuffing = false;

				// Decrement new_bits
				new_bits--;

				// If new_bits > 5 we just found a preamble
				if(new_bits > 5){

					/* Mark the output waveform anytime we see a Preamble
					 */
					#ifdef __DEBUG
						fputc(127, fourier_coefficient_debug);
					#endif

					// Preamble related things

					uint16_t len = char_array_expandable_size(&self->byte_sequence);
					if(len >= 17){

						signed char *data = self->byte_sequence.data;
						new_data = (char_array*) malloc(sizeof(char_array));
						new_data->len = len;
						new_data->data = (signed char*) malloc(sizeof(char)*len);
						memcpy(new_data->data, data, len);

					}

					char_ring_buffer_clear(&self->bit_sequence);
					char_array_expandable_clear(&self->byte_sequence);

					// Set bit stuffing true so last bit of preamble will be removed
					self->bit_stuffing = true;

				}

				// If its not a preamble
				else {

					// If new_bits == 5 bit stuffing is occurring
					if(new_bits == 5)
						self->bit_stuffing = true;

					// Add the rest of the bits as 1's
					for(i = 0; i < new_bits; i++)
						char_ring_buffer_put(&self->bit_sequence, 1);

				}

				// Add bits to the sequence
				avail = char_ring_buffer_avail(&self->bit_sequence);
				if(avail >= 8){

					signed char byte = 0;
					for(i = 7; i >= 0; i--){
						byte <<= 1;
						if(char_ring_buffer_get(&self->bit_sequence, i)) byte |= 1;
					}

					char_ring_buffer_remove(&self->bit_sequence, 8);
					char_array_expandable_put(&self->byte_sequence, byte);

				}

				self->count_last = 0;

			} else
				self->count_last++;

		}

	}

	return new_data;

}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rdi, %rbx
callq 0x147f
movq %rbx, %rdi
callq 0x14f0
movzbl 0x26(%rbx), %ecx
cmpw %cx, %ax
jbe 0x1a3d
xorps %xmm3, %xmm3
xorl %r15d, %r15d
xorps %xmm1, %xmm1
movaps %xmm1, 0x20(%rsp)
movaps %xmm3, 0x10(%rsp)
movss 0x2c(%rbx), %xmm0
movaps %xmm0, (%rsp)
movzwl %r15w, %ebp
movq %rbx, %rdi
movl %ebp, %esi
callq 0x14a2
movl %eax, %r14d
movd 0x30(%rbx), %xmm0
movdqa (%rsp), %xmm1
punpckldq %xmm0, %xmm1    # xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
movdqa %xmm1, (%rsp)
movq %rbx, %rdi
movl %ebp, %esi
callq 0x14a2
movaps 0x10(%rsp), %xmm1
movaps (%rsp), %xmm2
mulps %xmm1, %xmm2
movzbl %r14b, %ecx
shll $0x8, %ecx
pxor %xmm0, %xmm0
pinsrw $0x1, %ecx, %xmm0
movzbl %al, %eax
shll $0x8, %eax
pinsrw $0x3, %eax, %xmm0
subps 0x20(%rsp), %xmm2
psrad $0x18, %xmm0
cvtdq2ps %xmm0, %xmm3
addps %xmm2, %xmm3
incl %r15d
movswl %r15w, %eax
movzbl 0x26(%rbx), %ecx
cmpl %ecx, %eax
jle 0x185a
movaps %xmm1, %xmm0
mulps %xmm1, %xmm0
mulps %xmm3, %xmm1
mulps %xmm3, %xmm3
addps %xmm0, %xmm3
movsd 0x2c(%rbx), %xmm0
mulps %xmm1, %xmm0
subps %xmm0, %xmm3
movaps %xmm3, %xmm0
movl 0x50(%rbx), %eax
xorps %xmm1, %xmm1
cvtsi2ss %eax, %xmm1
shufps $0x55, %xmm3, %xmm0     # xmm0 = xmm0[1,1],xmm3[1,1]
subss %xmm0, %xmm3
ucomiss %xmm1, %xmm3
xorps %xmm0, %xmm0
cvtss2sd %xmm3, %xmm0
xorps %xmm1, %xmm1
cvtsi2sd %eax, %xmm1
jbe 0x1939
mulsd 0x16f9(%rip), %xmm1     # 0x3028
movsd 0x16f9(%rip), %xmm2     # 0x3030
jmp 0x1949
mulsd 0x16d7(%rip), %xmm1     # 0x3018
movsd 0x16d7(%rip), %xmm2     # 0x3020
mulsd %xmm0, %xmm2
addsd %xmm1, %xmm2
cvttsd2si %xmm2, %eax
movl %eax, 0x50(%rbx)
movl 0x54(%rbx), %ecx
xorps %xmm1, %xmm1
cvtsi2ss %ecx, %xmm1
ucomiss %xmm3, %xmm1
xorps %xmm1, %xmm1
cvtsi2sd %ecx, %xmm1
jbe 0x1980
mulsd 0x16b2(%rip), %xmm1     # 0x3028
mulsd 0x16b2(%rip), %xmm0     # 0x3030
jmp 0x1990
mulsd 0x1690(%rip), %xmm1     # 0x3018
mulsd 0x1690(%rip), %xmm0     # 0x3020
addsd %xmm1, %xmm0
cvttsd2si %xmm0, %ecx
subl %ecx, %eax
xorps %xmm0, %xmm0
cvtsi2ss %eax, %xmm0
movl %ecx, 0x54(%rbx)
mulss 0x34(%rbx), %xmm0
cvttps2dq %xmm0, %xmm0
cvtdq2ps %xmm0, %xmm0
subss %xmm0, %xmm3
movaps %xmm3, (%rsp)
movq %rbx, %rdi
callq 0x14bd
leaq 0x10(%rbx), %r14
movq %r14, %rdi
movaps (%rsp), %xmm0
callq 0x13d8
movq %r14, %rdi
callq 0x1448
movzbl 0x26(%rbx), %ecx
shrl %ecx
cmpw %cx, %ax
jbe 0x1a3d
movzwl %ax, %ebp
xorpd %xmm1, %xmm1
xorl %r15d, %r15d
movss %xmm1, (%rsp)
movzwl %r15w, %esi
movq %r14, %rdi
callq 0x13f8
movss (%rsp), %xmm1
addss %xmm0, %xmm1
incl %r15d
movswl %r15w, %eax
cmpl %ebp, %eax
jl 0x19ed
xorps %xmm0, %xmm0
cvtsi2ss %ebp, %xmm0
divss %xmm0, %xmm1
movss %xmm1, (%rsp)
movq %r14, %rdi
callq 0x1415
xorps %xmm0, %xmm0
ucomiss (%rsp), %xmm0
seta %al
cmpb %al, 0x58(%rbx)
jne 0x1a52
incw 0x3c(%rbx)
xorl %r14d, %r14d
movq %r14, %rax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movb %al, 0x58(%rbx)
movzwl 0x3c(%rbx), %eax
xorps %xmm0, %xmm0
cvtsi2ss %eax, %xmm0
movzbl 0x3e(%rbx), %eax
xorps %xmm1, %xmm1
cvtsi2ss %eax, %xmm1
divss %xmm1, %xmm0
cvtss2sd %xmm0, %xmm0
addsd 0x158d(%rip), %xmm0     # 0x3008
cvttsd2si %xmm0, %ebp
cmpb $0x0, 0x59(%rbx)
jne 0x1a90
leaq 0x40(%rbx), %rdi
xorl %esi, %esi
callq 0x147f
movb $0x0, 0x59(%rbx)
decl %ebp
movzbl %bpl, %ebp
cmpl $0x6, %ebp
jb 0x1ae7
leaq 0x60(%rbx), %r15
movq %r15, %rdi
callq 0x13a1
cmpw $0x11, %ax
jb 0x1b1a
movl %eax, %ebp
movq 0x68(%rbx), %r12
movl $0x10, %edi
callq 0x1100
movq %rax, %r14
movw %bp, (%rax)
movzwl %bp, %r13d
movq %r13, %rdi
callq 0x1100
movq %rax, 0x8(%r14)
movq %rax, %rdi
movq %r12, %rsi
movq %r13, %rdx
callq 0x10f0
jmp 0x1b1d
testl %ebp, %ebp
je 0x1b34
cmpl $0x5, %ebp
jne 0x1af4
movb $0x1, 0x59(%rbx)
leaq 0x40(%rbx), %r15
movw $0x1, %r12w
xorl %r14d, %r14d
movq %r15, %rdi
movl $0x1, %esi
callq 0x147f
movswl %r12w, %eax
incl %r12d
cmpl %eax, %ebp
jg 0x1b00
jmp 0x1b37
xorl %r14d, %r14d
leaq 0x40(%rbx), %rdi
callq 0x14e8
movq %r15, %rdi
callq 0x13a6
movb $0x1, 0x59(%rbx)
jmp 0x1b37
xorl %r14d, %r14d
leaq 0x40(%rbx), %r15
movq %r15, %rdi
callq 0x14f0
cmpw $0x8, %ax
jb 0x1b8c
movw $0x7, %bp
xorl %r12d, %r12d
movl %r12d, %r13d
addb %r12b, %r13b
movzwl %bp, %ebp
movq %r15, %rdi
movl %ebp, %esi
callq 0x14a2
testb %al, %al
setne %r12b
orb %r13b, %r12b
addw $-0x1, %bp
jb 0x1b50
movq %r15, %rdi
movl $0x8, %esi
callq 0x14d0
leaq 0x60(%rbx), %rdi
movsbl %r12b, %esi
callq 0x1326
movw $0x0, 0x3c(%rbx)
jmp 0x1a40