! Test switching of pipe inputs and make sure that the pipe does not block
! following a switching of pipe inputs by a primitive during restart. This
! is a simplified version of the interactive %TEST_RESTART_BLOCKING test that
! can be run non-interactive.
!
! Author:  J. Czechowski IV
! Version: $Id: test_restart_blocking2.mm,v 1.9 2015/12/21 20:47:47 ntn Exp $
!******************************************************************************!
startmacro
  switch INTERACTIVE interAct GET DEF=TRUE  SDEF=TRUE
  switch BASELINE    baseline GET DEF=FALSE SDEF=TRUE

  sedit opt.path dspIndex "PARSEDIndex" DSP
  if baseline OR dspIndex ge 0 then
    ! updated in 3.3.1 to use the new peakpick;DSP (for Bug 2660)
    set savedPath "^opt.path"
    if dspIndex eq -1 then
      path put DSP
    endif
    if nxm.dsp.prim.peakpick.class nfexist then
      if baseline then
        build peakpick;dsp
      else
        INFO "^reg.main.name: SKIPPING test since PEAKPICK;DSP has not been compiled, run with /BASELINE to enabled it."

        ! restore path if different before stopping this test case
        if savePath neqs opt.path then
          path set ^savedPath
        endif
        stop
      endif
    endif

    ! FFT is not exact, the following is the level of tolerance we will allow when checking the frequency after FFT.
    set toleranceRange 20.0

    calc sfreq1 1000
    calc sfreq2 4000

    ! JC4: I've noticed a few times where this test runs fast enough that the warning is
    ! never output, when we take out the "pause 1" after requesting the restart.
    info "This test may produce warnings saying 'NOOP restarted, but did not reconnect...'."

    pipe on
      waveform/id=wave1/throttle=real _wave1 "SF" Inf sin freq=sfreq1 amp=1e4 delta=1e-4
      waveform/id=wave2/throttle=real _wave2 "SF" Inf sin freq=sfreq2 amp=1e4 delta=1e-4

      noop/tl=1 _wave1 _noop

      fft/dbf _noop _fft{form=sb} nfft=1k over=0

      call get_peaks    ! updated in 3.3.1 for Bug 2660

      message send main NAME="CHANGE_INPUT1" INFO=1
    pipe off

    ! restore path if different
    if savePath neqs opt.path then
      path set ^savedPath
    endif

  else
    ! added to ensure that the DSP option tree can be added to the path (when it is NOT in current PATH)
    INFO "^reg.main.name: Since 3.3.1, specify /BASELINE or put DSP in path to run this test case. SKIPPING"
  endif
endmacro

!******************************************************************************!
procedure processMessage m:msg

  if msg.name eqs "CHANGE_INPUT1" then
    call checkFreq msg "_wave1" sfreq1 "CHANGE_INPUT2" "_wave2"

  elseif msg.name eqs "CHANGE_INPUT2" then
    call checkFreq msg "_wave2" sfreq2 "CHANGE_INPUT3" "_wave1"

  elseif msg.name eqs "CHANGE_INPUT3" then
    call checkFreq msg "_wave1" sfreq1 "" ""

  else
    warn "Unhandled message name=^msg.name info=^msg.info fid=^msg.fid data=^msg.data"
  endif
return

!******************************************************************************!
! It takes some time for the restart to flow through NOOP, FFT and PEAKPICK and
! then for PEAKPICK to get a new frame of data to process. To account for this
! we check to see if the frequency is within an acceptable range.
!
procedure checkFreq o:msg s:input d:freq s:nextmsg s:nextpipe
  assert/text="^reg.main.name: FFT is still running"      reg.fft   rexists
  assert/text="^reg.main.name: PEAKPICK is still running" reg.peaks rexists
  assert/text="^reg.main.name: _FFT pipe still exists"    ram._fft  rexists
  calc delta freq reg.peaks.peakabscissa - abs

  if delta lt toleranceRange then
    assert/text="^reg.main.name: Output from NOOP matches ^{input}. curMsg=^msg.name nextMsg=^nextmsg nextPipe=^nextpipe freq=^freq delta=^delta" TRUE

    if nextmsg eqs "" then
      pipe stop
    else
      set reg.noop.setArg("IN") ^nextpipe
      set reg.noop.setState     "Restart"
      message send main NAME="^nextmsg" INFO=1
      pause 1.0 ! Give it a little time to reconnect
    endif

  elseif msg.info gt 9 then
    assert/text="^reg.main.name: Output from NOOP matches ^input (timed out? ^{msg.info} secs). curMsg=^msg.name nextMsg=^nextmsg nextPipe=^nextpipe freq=^freq delta=^delta." FALSE
    warn "^reg.main.name: Failed tests, aborting"
    pipe stop

  else
    pause 1
    calc L:info msg.info 1 +
    message send main NAME="^msg.name" INFO=^info
  endif
return

!******************************************************************************!
! Run PEAKPICK
!           requires nxm.dsp.prim.peakpick (i.e. DSP in path)
!******************************************************************************!
procedure get_peaks
  peakpick;dsp/id=peaks IN=_fft
return
