// File: /workspace/github_cpp_makefile_star2_O2/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:
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 0x58(%rdi), %r12
leaq 0x10(%rdi), %r13
xorl %ebp, %ebp
cmpq %rbp, %rbx
je 0x7c84
movss (%r14,%rbp,4), %xmm0
incq (%r15)
movss 0x84(%r15), %xmm1
movss 0x88(%r15), %xmm2
mulss %xmm1, %xmm2
cvtss2sd %xmm1, %xmm1
movsd 0x819(%rip), %xmm3      # 0x82f8
subsd %xmm1, %xmm3
movaps %xmm0, %xmm1
andps 0x7d3(%rip), %xmm1      # 0x82c0
cvtss2sd %xmm1, %xmm1
mulsd %xmm3, %xmm1
cvtss2sd %xmm2, %xmm2
addsd %xmm1, %xmm2
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 %r13, %rdi
callq 0x77ae
testb %al, %al
je 0x7bf6
movq %r12, %rdi
callq 0x7d04
movaps %xmm0, 0x10(%rsp)
movq %r12, %rdi
callq 0x7d48
movq 0x8(%r15), %rcx
testq %rcx, %rcx
js 0x7b59
cvtsi2ss %rcx, %xmm0
jmp 0x7b6e
movq %rcx, %rdx
shrq %rdx
andl $0x1, %ecx
orq %rdx, %rcx
cvtsi2ss %rcx, %xmm0
addss %xmm0, %xmm0
movss 0x88(%r15), %xmm1
divss %xmm0, %xmm1
movq (%r15), %rsi
cvtss2sd %xmm1, %xmm0
mulsd 0x2076(%rip), %xmm0     # 0x9c00
mulss 0x2036(%rip), %xmm1     # 0x9bc8
testb %al, %al
je 0x7b9a
cvtsd2ss %xmm0, %xmm1
movaps 0x10(%rsp), %xmm0
andps 0x71a(%rip), %xmm0      # 0x82c0
cmpq $0x1555c, %rsi          # imm = 0x1555C
jb 0x7bdb
xorl %edx, %edx
ucomiss %xmm1, %xmm0
seta %dl
leaq 0x204a(%rip), %rdi      # 0x9c08
xorl %eax, %eax
movaps %xmm0, 0x10(%rsp)
movss %xmm1, 0xc(%rsp)
callq 0x2040
movss 0xc(%rsp), %xmm1
movaps 0x10(%rsp), %xmm0
movq 0x90(%r15), %rdi
testq %rdi, %rdi
je 0x7bf6
xorl %esi, %esi
ucomiss %xmm1, %xmm0
seta %sil
movq (%rdi), %rax
callq *0x10(%rax)
cmpb $0x0, 0x80(%r15)
je 0x7c35
decq 0x78(%r15)
jne 0x7c7c
movb $0x0, 0x80(%r15)
movq 0x90(%r15), %rax
leaq 0x200d(%rip), %rdi      # 0x9c29
testq %rax, %rax
je 0x7c72
movq (%rax), %rcx
movq %rax, %rdi
xorl %esi, %esi
callq *0x20(%rcx)
leaq 0x1ff6(%rip), %rdi      # 0x9c29
jmp 0x7c72
movq 0x90(%r15), %rdi
testq %rdi, %rdi
je 0x7c7c
movq (%rdi), %rax
callq *0x18(%rax)
testb %al, %al
je 0x7c7c
movb $0x1, 0x80(%r15)
movq 0x70(%r15), %rax
movq 0x90(%r15), %rdi
movq %rax, 0x78(%r15)
movq (%rdi), %rax
pushq $0x1
popq %rsi
callq *0x20(%rax)
leaq 0x1fa4(%rip), %rdi      # 0x9c16
movq (%r15), %rsi
xorl %eax, %eax
callq 0x2040
incq %rbp
jmp 0x7aab
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop