// File: /workspace/github_cpp_makefile_star2_O3/ke6jjj[P]r-dat/RDATSlopeDecoder.cc
// Function: RDATSlopeDecoder::Process(float*, unsigned long)
void
RDATSlopeDecoder::Process(float *samples, size_t count)
{
  size_t i;
  float signal;
  
  for (i = 0; i < count; i++) {
    //
    // Look at the sample.
    //
    signal = samples[i];
    mSampleNumber++;

    //
    // Update the overall signal level.
    //
    mOverallSignalLevel *= mAlpha;
    mOverallSignalLevel += (1.0 - mAlpha) * fabs(signal);

    //
    // Store the new sample in the symbol window
    //
    mSymbolWindow.Add(signal);

    //
    // Ask the clock detector if now is a good time to sample the signal.
    //
    // This clock detection algorithm needs to be 180 degrees out of phase
    // with the symbol period so that any magnetic pulse picked up by the
    // read head will be centered within the sample period.
    //
    if (mClockDetector.AddAndDetect(signal)) {
      //
      // Evaluate all the samples in the sample window to determine the
      // average slope amonst them.
      //
      float slope = mSymbolWindow.Slope();

      bool zeroCrossed = mSymbolWindow.CrossesZero();

      //
      // If the slope exceeds the detection threshold, mark that we've found
      // a pulse.
      //
      float threshold;
      if (zeroCrossed) {
        threshold = mOverallSignalLevel / mkSamplesPerSymbol * 0.72;
      } else {
        threshold = mOverallSignalLevel / mkSamplesPerSymbol * 3;
      }

      bool pulse = fabs(slope) > threshold;

#if 1
      if (mSampleNumber > 87387) {
#if 0
        printf("%zd overall %g, slope %g, target %g\n",
          mSampleNumber,
          mOverallSignalLevel,
          fabs(slope),
          threshold
        );
#endif
#if 1
        printf(" %zd pulse %d", mSampleNumber, pulse ? 1 : 0);
#endif
      }
#endif
     
      //
      // Signal the decision.
      //
      if (mDecoder != NULL)
        mDecoder->ReceiveBit(pulse);
    }

    //
    // If there's no track in progress, see if a new one has perhaps
    // started.
    //
    if (!mTrackInProgress) {
      //
      // We're in the idle time between tracks. Check if a track has started.
      //
      if (mDecoder != NULL && mDecoder->PreambleDetected()) {
        //
        // A track appears to have started. Start the track progress timer.
        //
        mTrackInProgress = true;
        mTrackSampleCount = mTrackDuration;

        //
        // Notify the downstream decoder.
        //
        mDecoder->TrackDetected(true);
#if 1
        printf("%zd Track started\n", mSampleNumber);
#endif
      }
    } else {
      //
      // There's a track in progress. See if the track timer has expired.
      //
      mTrackSampleCount--;
      if (mTrackSampleCount == 0) {
        //
        // The track should have ended by now. Declare it over.
        //
        mTrackInProgress = false;
        if (mDecoder != NULL)
          mDecoder->TrackDetected(false);
#if 1
        printf("%zd Track stopped\n", mSampleNumber);
#endif
      }
    }
  }
}

// Assembly:
testq %rdx, %rdx
je 0x8017
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rdx, %rbx
movq %rsi, %r14
movq %rdi, %r15
leaq 0x10(%rdi), %r12
leaq 0x2e5a(%rip), %rbp      # 0xac39
xorl %r13d, %r13d
movss (%r14,%r13,4), %xmm0
incq (%r15)
movss 0x84(%r15), %xmm1
movss 0x88(%r15), %xmm2
mulss %xmm1, %xmm2
cvtss2sd %xmm1, %xmm1
movsd 0x14eb(%rip), %xmm3     # 0x92f8
subsd %xmm1, %xmm3
movaps %xmm0, %xmm1
andps 0x14a5(%rip), %xmm1     # 0x92c0
cvtss2sd %xmm1, %xmm1
mulsd %xmm3, %xmm1
cvtss2sd %xmm2, %xmm2
addsd %xmm1, %xmm2
xorps %xmm1, %xmm1
cvtsd2ss %xmm2, %xmm1
movss %xmm1, 0x88(%r15)
movq 0x60(%r15), %rcx
movq 0x68(%r15), %rax
movss %xmm0, (%rcx,%rax,4)
incq %rax
xorl %edx, %edx
divq 0x58(%r15)
movq %rdx, 0x68(%r15)
movq %r12, %rdi
callq 0x7a6c
testb %al, %al
je 0x7f7d
movq 0x68(%r15), %rcx
leaq -0x1(%rcx), %rax
movq 0x58(%r15), %rsi
xorl %edx, %edx
divq %rsi
testq %rsi, %rsi
js 0x7e85
xorps %xmm0, %xmm0
cvtsi2ss %rsi, %xmm0
jmp 0x7e9d
movq %rsi, %rax
shrq %rax
andl $0x1, %esi
orq %rax, %rsi
xorps %xmm0, %xmm0
cvtsi2ss %rsi, %xmm0
addss %xmm0, %xmm0
movq 0x60(%r15), %rax
movss (%rax,%rdx,4), %xmm4
movss (%rax,%rcx,4), %xmm1
movss 0x88(%r15), %xmm5
movq (%r15), %rsi
movq 0x8(%r15), %rax
testq %rax, %rax
js 0x7eca
xorps %xmm2, %xmm2
cvtsi2ss %rax, %xmm2
jmp 0x7ee2
movq %rax, %rcx
shrq %rcx
andl $0x1, %eax
orq %rcx, %rax
xorps %xmm2, %xmm2
cvtsi2ss %rax, %xmm2
addss %xmm2, %xmm2
divss %xmm2, %xmm5
xorps %xmm2, %xmm2
cmpltps %xmm4, %xmm2
xorpd %xmm3, %xmm3
cmpltps %xmm1, %xmm3
xorps %xmm2, %xmm3
movd %xmm3, %eax
xorps %xmm2, %xmm2
cvtss2sd %xmm5, %xmm2
mulsd 0x2d05(%rip), %xmm2     # 0xac10
mulss 0x2cc5(%rip), %xmm5     # 0xabd8
testb $0x1, %al
je 0x7f1e
xorps %xmm5, %xmm5
cvtsd2ss %xmm2, %xmm5
subss %xmm1, %xmm4
divss %xmm0, %xmm4
andps 0x1393(%rip), %xmm4     # 0x92c0
cmpq $0x1555c, %rsi          # imm = 0x1555C
jb 0x7f62
xorl %edx, %edx
ucomiss %xmm5, %xmm4
seta %dl
leaq 0x2cd3(%rip), %rdi      # 0xac18
xorl %eax, %eax
movaps %xmm4, 0x10(%rsp)
movss %xmm5, 0xc(%rsp)
callq 0x2040
movss 0xc(%rsp), %xmm5
movaps 0x10(%rsp), %xmm4
movq 0x90(%r15), %rdi
testq %rdi, %rdi
je 0x7f7d
xorl %esi, %esi
ucomiss %xmm5, %xmm4
seta %sil
movq (%rdi), %rax
callq *0x10(%rax)
cmpb $0x0, 0x80(%r15)
je 0x7fb4
decq 0x78(%r15)
jne 0x7ffd
movb $0x0, 0x80(%r15)
movq 0x90(%r15), %rax
movq %rbp, %rdi
testq %rax, %rax
je 0x7ff3
movq (%rax), %rcx
movq %rax, %rdi
xorl %esi, %esi
callq *0x20(%rcx)
movq %rbp, %rdi
jmp 0x7ff3
movq 0x90(%r15), %rdi
testq %rdi, %rdi
je 0x7ffd
movq (%rdi), %rax
callq *0x18(%rax)
testb %al, %al
je 0x7ffd
movb $0x1, 0x80(%r15)
movq 0x70(%r15), %rax
movq 0x90(%r15), %rdi
movq %rax, 0x78(%r15)
movq (%rdi), %rax
movl $0x1, %esi
callq *0x20(%rax)
leaq 0x2c33(%rip), %rdi      # 0xac26
movq (%r15), %rsi
xorl %eax, %eax
callq 0x2040
incq %r13
cmpq %r13, %rbx
jne 0x7de2
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq