!******************************************************************************!
! Tests the TUNER OutputIF fix and /WIND
!
! Arguments: None
!
! @issue    NXM-4055 DSP TUNER regression breaks Output IF band center
! @since    NeXtMidas 4.1.4
! @author:  Jeanette McCall
!******************************************************************************
startmacro
  switch INTERACTIVE interAct GET DEF=TRUE  SDEF=TRUE  ! for normal interactive test(s)
  switch BASELINE    baseline GET DEF=FALSE SDEF=TRUE  ! for defects or more obscure test case(s)

  res fn_prefix "test_tuner_outif_"

  call test_outputif-1
  call test_tuner_filters ! depends on waveforms from test_outputif-1

  if interAct then
    lookandfeel gear4
    set instructions "PLOTs are for visualization.\n&
                      Automated tests provide needed testing.\n\n&
                      OutputIF plots on LEFT:\n&
                      SF signal - 3Hz\n&
                      Center band tune of SF - 5Hz\n&
                      CF signal - 4Hz\n&
                      Center band tune of CF - 0Hz\n\n&
                      TUNER WIND and FIRWIND plots on RIGHT\n&
                      (Plots should overlap - only see blue)\n&
                      SF HANN\n&
                      SF BH61\n&
                      CF HAMM\n&
                      CF BH92."


    pipe on
      panel/msgid=MAIN/setup/controls=gc
      gcontrol label macro "Test MACRO"
      gcontrol menu  main "Exit with Status =" "PASS,FAIL" TABLE={ItemColors={PASS="GREEN",FAIL="RED"}} /tleft

      gcontrol text  idtext "Instructions" instructions 24 20 /title

      plot/id=sf          fft_sf
      plot/id=sf_outif_1  fft_tune_outif_1_sf

      plot/id=cf          fft_cf
      plot/id=cf_outif_1  fft_tune_outif_1_cf

      plot/id=sf_hann     sf_tune_filtout_hann|sf_firwind_filtout_hann
      plot/id=sf_bh61     sf_tune_filtout_bh61|sf_firwind_filtout_bh61
      plot/id=cf_hamm     cf_tune_filtout_hamm|cf_firwind_filtout_hamm
      plot/id=cf_bh92     cf_tune_filtout_bh92|cf_firwind_filtout_bh92

    pipe off
  endif

  files/e ^{fn_prefix}*
endmacro

!******************************************************************************!
! Main process message for this macro. Should be right after the ENDMACRO.
!******************************************************************************!
procedure processMessage m:msg
  if msg.name eqs "MAIN" then
    assert/text="^reg.main.name: User indicated tests" msg.data eqss "PASS"
    pipe stop
  elseif msg.name eqs "LAYERS" then
    invoke filtName msg.data.replace("TUNER_","FILT")
    invoke psdName  msg.data.replace("TUNER_","PSD")

    set reg.TIME_PLOT.layers.^{filtName}.enable ~Global
    set reg.FREQ_PLOT.layers.^{psdName}.enable  ~Global
  else
    say "Unhandled message name: ^msg.name from fid: ^msg.fid data: ^msg.data"
  endif
return

!******************************************************************************!
! If an unexpected exception is caught, mark test as failed, unless it is expected
!******************************************************************************!
procedure processException m:emsg
  if expectedException REXISTS then
    assert/text="^reg.main.name: Expected ERROR starts with: ^{expectedException}" expectedException EQSS emsg.data.message
    remove expectedException
  else
    assert/text="^reg.main.name: Caught unexpected exception ^{emsg.data}" "FALSE" isTrue
    if "Trace" SUBS ENV.DEBUG then invoke ,, emsg.data.printStackTrace()
  endif
return

!******************************************************************************!
! Tests for OUTPUTIF=-1
!******************************************************************************!
procedure test_outputif-1

  ! REAL SIGNAL
  res sf_sig               "^{fn_prefix}sf_sig.tmp"
  res tune_outif_1_sf      "^{fn_prefix}tune_outif-1_sf_sig.tmp"
  res fft_sf               "^{fn_prefix}fft_sf_sig.tmp"
  res fft_tune_outif_1_sf  "^{fn_prefix}fft_tune_outif-1_sf_sig.tmp"
  ! COMPLEX SIGNAL
  res cf_sig               "^{fn_prefix}cf_sig.tmp"
  res tune_outif_1_cf      "^{fn_prefix}tune_outif-1_cf_sig.tmp"
  res fft_cf               "^{fn_prefix}fft_cf_sig.tmp"
  res fft_tune_outif_1_cf  "^{fn_prefix}fft_tune_outif-1_cf_sig.tmp"

  res  sf_freq   3.0
  res  cf_freq   4.0
  res  delta     0.05
  calc fsdiv4    0.25 delta /
  res  exp_real  fsdiv4
  res  exp_cmplx 0.0
  res  nelem     100k
  res  amp       1
  res  nfft      1k
  res  sf_bw     0.1
  res  cf_bw     0.05

  waveform sf_sig form=SF shape=sin elem=nelem amp=amp freq=sf_freq delta=delta
  tuner input=sf_sig output=tune_outif_1_sf inputif=sf_freq outputif=-1 bandwidth=sf_bw
  SIGSTAT/KWMODE=JICD/IF/RVCR_BW=10/id=sigstat1/res=sf_sigstat IN=sf_sig FFT=fft_sf NFFT=nfft
  res d:freq sf_sigstat.freq
  assert/text="^reg.main.name: Frequency of Real Input signal" sf_freq EQ freq
  SIGSTAT/KWMODE=JICD/IF/RVCR_BW=10/id=sigstat1/res=sf_outif_sigstat IN=tune_outif_1_sf FFT=fft_tune_outif_1_sf NFFT=nfft
  res d:actfreq sf_outif_sigstat.freq
  assert/text="^reg.main.name: OutputIF -1 of real signal is fs/4" fsdiv4 EQ actfreq

  waveform cf_sig form=CF shape=sin elem=nelem amp=amp freq=cf_freq delta=delta
  tuner input=cf_sig output=tune_outif_1_cf inputif=cf_freq outputif=-1 bandwidth=cf_bw
  info "Expect WARN: Signal bandwidth (0.0 Hz) is .... below"
  SIGSTAT/KWMODE=JICD/IF/RVCR_BW=20/id=sigstat2/res=cf_sigstat IN=cf_sig FFT=fft_cf NFFT=nfft
  res d:actfreq cf_sigstat.freq
  assert/text="^reg.main.name: Frequency of Complex Input signal" cf_freq EQ actfreq
  info "Expect WARN: Signal bandwidth (0.0 Hz) is .... below"
  SIGSTAT/KWMODE=JICD/IF/RVCR_BW=20/id=sigstat1/res=outif_sigstat_cf IN=tune_outif_1_cf FFT=fft_tune_outif_1_cf NFFT=nfft
  res d:actfreq outif_sigstat_cf.freq
  assert/text="^reg.main.name: OutputIF -1 of complex signal is ^exp_cmplx" exp_cmplx EQ actfreq

return

!******************************************************************************!
! Tests tuner support for generating different filter types
!******************************************************************************!
procedure test_tuner_filters

  ! HANNING
  res sf_tune_filtout_hann     "^{fn_prefix}sf_tune_filtout_hann.tmp"
  res sf_firwind_filtout_hann  "^{fn_prefix}sf_firwind_filtout_hann.tmp"
  res cf_tune_filtout_hann     "^{fn_prefix}cf_tune_filtout_hann.tmp"
  res cf_firwind_filtout_hann  "^{fn_prefix}cf_firwind_filtout_hann.tmp"
  ! HAMMING
  res sf_tune_filtout_hamm     "^{fn_prefix}sf_tune_filtout_hamm.tmp"
  res sf_firwind_filtout_hamm  "^{fn_prefix}sf_firwind_filtout_hamm.tmp"
  res cf_tune_filtout_hamm     "^{fn_prefix}cf_tune_filtout_hamm.tmp"
  res cf_firwind_filtout_hamm  "^{fn_prefix}cf_firwind_filtout_hamm.tmp"
  ! BH61
  res sf_tune_filtout_bh61     "^{fn_prefix}sf_tune_filtout_bh61.tmp"
  res sf_firwind_filtout_bh61  "^{fn_prefix}sf_firwind_filtout_bh61.tmp"
  res cf_tune_filtout_bh61     "^{fn_prefix}cf_tune_filtout_bh61.tmp"
  res cf_firwind_filtout_bh61  "^{fn_prefix}cf_firwind_filtout_bh61.tmp"
  ! BH92
  res sf_tune_filtout_bh92     "^{fn_prefix}sf_tune_filtout_bh92.tmp"
  res sf_firwind_filtout_bh92  "^{fn_prefix}sf_firwind_filtout_bh92.tmp"
  res cf_tune_filtout_bh92     "^{fn_prefix}cf_tune_filtout_bh92.tmp"
  res cf_firwind_filtout_bh92  "^{fn_prefix}cf_firwind_filtout_bh92.tmp"

!FIRWIND - designs a finite impulse response (FIR) filter using the window method

!<OUT>     Filter impulse response output file name
!<TYPE>    Filter Type: LOWPASS, HIGHPASS, BANDPASS, or STOPBAND
!<WIND>    Window type (see WINDOW primitive), or NONE
!<NTAP>    Number of filter taps or Impulse response length (power of 2)
!<FREQ1>   First transition frequency, Hz
!<FREQ2>   Second transition frequency, Hz
!<FREQF>   Folding frequency, Hz  or file(name).nyquist
!nM> tuner/WIND=HANN input=sf_sig output=tune_outif_1_sf inputif=sf_freq outputif=-1 bandwidth=0.1
!FilterFIR type:BandPass ntaps:1024 freq1:2.95 freq2:3.05 freqF:10.0
!          complex:true symmetric:true windowName:HANN scaleFact:1.0
!  double freq1 = cfreq - bw/2;
!    double freq2 = cfreq + bw/2;
!   double freqF = nyquist;

  !****** REAL INPUT ******
  calc half_bw sf_bw 2 /
  calc sf_freq1 sf_freq half_bw -
  calc sf_freq2 sf_freq half_bw +

  tuner/WIND=HANN input=sf_sig output=tune_outif_1_sf inputif=sf_freq outputif=-1 bandwidth=sf_bw filtout=sf_tune_filtout_hann
  firwind/CMPLX/FILTER_SYM=true out=sf_firwind_filtout_hann type=BANDPASS WIND=HANN ntap=nfft freq1=sf_freq1 freq2=sf_freq2 freqf=file(sf_sig).nyq
  assert/text="^reg.main.name: Tuner SF HANN filter matches FirWind" sf_tune_filtout_hann FEQ/D sf_firwind_filtout_hann

  tuner/WIND=HAMM input=sf_sig output=tune_outif_1_sf inputif=sf_freq outputif=-1 bandwidth=sf_bw filtout=sf_tune_filtout_hamm
  firwind/CMPLX/FILTER_SYM=true out=sf_firwind_filtout_hamm type=BANDPASS WIND=HAMM ntap=nfft freq1=sf_freq1 freq2=sf_freq2 freqf=file(sf_sig).nyq
  assert/text="^reg.main.name: Tuner SF HAMM filter matches FirWind" sf_tune_filtout_hamm FEQ/D sf_firwind_filtout_hamm

  tuner/WIND=BH61 input=sf_sig output=tune_outif_1_sf inputif=sf_freq outputif=-1 bandwidth=sf_bw filtout=sf_tune_filtout_bh61
  firwind/CMPLX/FILTER_SYM=true out=sf_firwind_filtout_bh61 type=BANDPASS WIND=BH61 ntap=nfft freq1=sf_freq1 freq2=sf_freq2 freqf=file(sf_sig).nyq
  assert/text="^reg.main.name: Tuner SF BH61 filter matches FirWind" sf_tune_filtout_bh61 FEQ/D sf_firwind_filtout_bh61

  tuner/WIND=BH921 input=sf_sig output=tune_outif_1_sf inputif=sf_freq outputif=-1 bandwidth=sf_bw filtout=sf_tune_filtout_bh92
  firwind/CMPLX/FILTER_SYM=true out=sf_firwind_filtout_bh92 type=BANDPASS WIND=BH92 ntap=nfft freq1=sf_freq1 freq2=sf_freq2 freqf=file(sf_sig).nyq
  assert/text="^reg.main.name: Tuner SF BH92 filter matches FirWind" sf_tune_filtout_bh92 FEQ/D sf_firwind_filtout_bh92

  !****** COMPLEX INPUT ******
  calc half_bw cf_bw 2 /
  calc cf_freq1 cf_freq half_bw -
  calc cf_freq2 cf_freq half_bw +

  tuner/WIND=HANN input=cf_sig output=tune_outif_1_cf inputif=cf_freq outputif=-1 bandwidth=cf_bw filtout=cf_tune_filtout_hann
  firwind/CMPLX/FILTER_SYM=true out=cf_firwind_filtout_hann type=BANDPASS WIND=HANN ntap=nfft freq1=cf_freq1 freq2=cf_freq2 freqf=file(cf_sig).nyq
  assert/text="^reg.main.name: Tuner CF HANN filter matches FirWind" cf_tune_filtout_hann FEQ/D cf_firwind_filtout_hann

  tuner/WIND=HAMM input=cf_sig output=tune_outif_1_cf inputif=cf_freq outputif=-1 bandwidth=cf_bw filtout=cf_tune_filtout_hamm
  firwind/CMPLX/FILTER_SYM=true out=cf_firwind_filtout_hamm type=BANDPASS WIND=HAMM ntap=nfft freq1=cf_freq1 freq2=cf_freq2 freqf=file(sf_sig).nyq
  assert/text="^reg.main.name: Tuner CF HAMM filter matches FirWind" cf_tune_filtout_hamm FEQ/D cf_firwind_filtout_hamm

  tuner/WIND=BH61 input=cf_sig output=tune_outif_1_cf inputif=cf_freq outputif=-1 bandwidth=cf_bw filtout=cf_tune_filtout_bh61
  firwind/CMPLX/FILTER_SYM=true out=cf_firwind_filtout_bh61 type=BANDPASS WIND=BH61 ntap=nfft freq1=cf_freq1 freq2=cf_freq2 freqf=file(sf_sig).nyq
  assert/text="^reg.main.name: Tuner CF BH61 filter matches FirWind" cf_tune_filtout_bh61 FEQ/D cf_firwind_filtout_bh61

  tuner/WIND=BH921 input=cf_sig output=tune_outif_1_cf inputif=cf_freq outputif=-1 bandwidth=cf_bw filtout=cf_tune_filtout_bh92
  firwind/CMPLX/FILTER_SYM=true out=cf_firwind_filtout_bh92 type=BANDPASS WIND=BH92 ntap=nfft freq1=cf_freq1 freq2=cf_freq2 freqf=file(sf_sig).nyq
  assert/text="^reg.main.name: Tuner CF BH92 filter matches FirWind" cf_tune_filtout_bh92 FEQ/D cf_firwind_filtout_bh92

return
