// File: /workspace/github_c_makefile_star2_O2/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 0x13e0
movq %rbx, %rdi
callq 0x144d
movzbl 0x26(%rbx), %ecx
cmpw %cx, %ax
jbe 0x197c
xorps %xmm1, %xmm1
xorl %r15d, %r15d
xorps %xmm3, %xmm3
movzbl %cl, %eax
cmpw %ax, %r15w
ja 0x1835
movss 0x2c(%rbx), %xmm0
movaps %xmm0, (%rsp)
movzwl %r15w, %ebp
movq %rbx, %rdi
movl %ebp, %esi
movaps %xmm3, 0x10(%rsp)
movaps %xmm1, 0x20(%rsp)
callq 0x1402
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 0x1402
movaps (%rsp), %xmm1
movaps 0x10(%rsp), %xmm3
mulps %xmm3, %xmm1
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), %xmm1
movaps %xmm1, %xmm2
psrad $0x18, %xmm0
movaps %xmm3, %xmm1
cvtdq2ps %xmm0, %xmm0
addps %xmm2, %xmm0
incl %r15d
movb 0x26(%rbx), %cl
movaps %xmm0, %xmm3
jmp 0x179c
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
cvtsi2ss %eax, %xmm1
shufps $0x55, %xmm3, %xmm0     # xmm0 = xmm0[1,1],xmm3[1,1]
subss %xmm0, %xmm3
ucomiss %xmm1, %xmm3
cvtss2sd %xmm3, %xmm0
cvtsi2sd %eax, %xmm1
jbe 0x1880
mulsd 0x17b2(%rip), %xmm1     # 0x3028
movsd 0x17b2(%rip), %xmm2     # 0x3030
jmp 0x1890
mulsd 0x1790(%rip), %xmm1     # 0x3018
movsd 0x1790(%rip), %xmm2     # 0x3020
mulsd %xmm0, %xmm2
addsd %xmm1, %xmm2
cvttsd2si %xmm2, %eax
movl %eax, 0x50(%rbx)
movl 0x54(%rbx), %ecx
cvtsi2ss %ecx, %xmm1
ucomiss %xmm3, %xmm1
cvtsi2sd %ecx, %xmm1
jbe 0x18c1
mulsd 0x1771(%rip), %xmm1     # 0x3028
mulsd 0x1771(%rip), %xmm0     # 0x3030
jmp 0x18d1
mulsd 0x174f(%rip), %xmm1     # 0x3018
mulsd 0x174f(%rip), %xmm0     # 0x3020
addsd %xmm1, %xmm0
cvttsd2si %xmm0, %ecx
subl %ecx, %eax
cvtsi2ss %eax, %xmm0
movl %ecx, 0x54(%rbx)
mulss 0x34(%rbx), %xmm0
cvttps2dq %xmm0, %xmm0
cvtdq2ps %xmm0, %xmm0
subss %xmm0, %xmm3
movaps %xmm3, 0x10(%rsp)
movq %rbx, %rdi
callq 0x141d
leaq 0x10(%rbx), %r14
movq %r14, %rdi
movaps 0x10(%rsp), %xmm0
callq 0x133d
movq %r14, %rdi
callq 0x13a9
movzbl 0x26(%rbx), %ecx
shrl %ecx
cmpw %cx, %ax
jbe 0x197c
movzwl %ax, %ebp
xorpd %xmm1, %xmm1
xorl %r15d, %r15d
movswl %r15w, %eax
cmpl %ebp, %eax
jge 0x1954
movzwl %r15w, %esi
movq %r14, %rdi
movss %xmm1, (%rsp)
callq 0x135c
movss (%rsp), %xmm1
addss %xmm0, %xmm1
incl %r15d
jmp 0x192d
cvtsi2ss %ebp, %xmm0
divss %xmm0, %xmm1
movss %xmm1, (%rsp)
movq %r14, %rdi
callq 0x1379
xorps %xmm0, %xmm0
ucomiss (%rsp), %xmm0
seta %al
cmpb %al, 0x58(%rbx)
jne 0x1991
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
cvtsi2ss %eax, %xmm0
movzbl 0x3e(%rbx), %eax
cvtsi2ss %eax, %xmm1
divss %xmm1, %xmm0
cvtss2sd %xmm0, %xmm0
addsd 0x1654(%rip), %xmm0     # 0x3008
cvttsd2si %xmm0, %ebp
cmpb $0x0, 0x59(%rbx)
jne 0x19c9
leaq 0x40(%rbx), %rdi
xorl %esi, %esi
callq 0x13e0
movb $0x0, 0x59(%rbx)
decl %ebp
movzbl %bpl, %r12d
cmpl $0x6, %r12d
jb 0x1a1f
leaq 0x60(%rbx), %r15
movq %r15, %rdi
callq 0x130a
cmpw $0x11, %ax
jb 0x1a4a
movl %eax, %ebp
movq 0x68(%rbx), %r12
pushq $0x10
popq %rdi
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 0x1a4d
cmpl $0x5, %r12d
jne 0x1a29
movb $0x1, 0x59(%rbx)
leaq 0x40(%rbx), %r15
xorl %r14d, %r14d
pushq $0x1
popq %rbp
xorl %r13d, %r13d
cmpl %r13d, %r12d
jbe 0x1a62
movq %r15, %rdi
movl %ebp, %esi
callq 0x13e0
incl %r13d
jmp 0x1a36
xorl %r14d, %r14d
leaq 0x40(%rbx), %rdi
callq 0x1448
movq %r15, %rdi
callq 0x130f
movb $0x1, 0x59(%rbx)
leaq 0x40(%rbx), %r15
movq %r15, %rdi
callq 0x144d
cmpw $0x8, %ax
jb 0x1ab5
movw $0x7, %r12w
xorl %ebp, %ebp
testw %r12w, %r12w
js 0x1a9d
addb %bpl, %bpl
movzwl %r12w, %esi
movq %r15, %rdi
callq 0x1402
testb %al, %al
setne %al
orb %al, %bpl
decl %r12d
jmp 0x1a7b
pushq $0x8
popq %rsi
movq %r15, %rdi
callq 0x1430
leaq 0x60(%rbx), %rdi
movsbl %bpl, %esi
callq 0x1295
andw $0x0, 0x3c(%rbx)
jmp 0x197f