⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stft.pkg

📁 LastWave
💻 PKG
字号:
#;; -*- Mode: Tcl -*-#..........................................................................#                                                                         #      L a s t W a v e    P a c k a g e 'stft' 2.0##      Author Remi Gribonval#      #      File associated to the stft package#                                                                    #..........................................................................# Set the tabulation directory for # the short time fourier transforms # (and the matching pursuit)StftTabulationDirectory=_scriptDirectory[0]+'/stft/tabulation'## Dealing with STFT graphs## The default position of stft windowsdisp.stft.rect={370 55 600 400}# Perform zoom on stfts with the mouseSetZoomBindings GraphStft {'rect' 'xrect'}## Perform cursor displaying on stfts## # Regular cursor #setproc _CursorTextGraphStft {}  {  stft=[setg @object -graph]  # The 'x' coordinate in sample-coordinate   index = int((@x-stft.x0)/stft.dx+.5)  if (index < 0) {index=0}   if (index > (stft.signalSize-1)) {index=stft.signalSize-1}   # The 'y' coordinate in sample coordinate  freq = int(@y*2*stft.freqIdNyquist*stft.dx+.5)  if (freq < 0) {freq=0}   if (freq > stft.freqIdNyquist) {freq=stft.freqIdNyquist}   # The time-frequency grid  {tr tl fr fl} = stft.grid  T = tr*round(index/tr)  F = fr*round(freq/fr)  if ((T>=0) && (T<stft.signalSize) && (F>=0) && (F<=stft.freqIdNyquist) ) {      a=[stftmax stft -T T T -F F F][0]  } else {      a=0  }#  stftbest stft atom -T index index -F freq freq]#  c = [bestchirp atom stft]  return "$@objname : ($@x,$@y) [id = ($index,$freq)] val = $a"}setproc _DrawCursorNoneGraphStft {{&var cursor}} {  cursor.erase=null  return [_CursorTextGraphStft]}setproc _DrawCursorGraphStft {{&var cursor}}  {  _ViewDrawCrossHair cursor.view $@x $@y  cursor.erase=%%`_ViewDrawCrossHair '$cursor.view' $@x $@y`  return [_CursorTextGraphStft]}SetCursorBindings GraphStft {%_DrawCursorNoneGraphStft %_DrawCursorGraphStft}###################################################### Vertical and Horizontal sections of Stft displays#####################################################  binding delete 'stftsection'setproc _StftSection {flagVertical} {     # Get the stft  stft=[setg $@objname -graph]  if (flagVertical) {      # Get the right time index      index=int((@x-stft.x0)/stft.dx+.5)      {tr tl fr fl} = stft.grid      index=tr*int(index/tr+0.5)      if (index < 0) {index=0}      if (index >= tr*tl) {index=tr*(tl-1)}  } else {      # Get the right freq index      index=int(@y*stft.dx*2*stft.freqIdNyquist+.5)      {tr tl fr fl} = stft.grid      index=fr*int(index/fr+0.5)      if (index < 0) {index=0}      if (index >= fr*fl) {index=fr*(fl-1)}  }  # If the stft is zero don't display anything  {max maxt maxf}=[stftmax stft]  dynamic=[setg $@objname -expo]  if ($max==0) {    errorf "_StftSection : the displayed stft is uniformly zero"  }  type=stft.type  if (type=="complex") {      if (flagVertical) {	  {coeffR coeffI} = ${index}stft      } else {	  {coeffR coeffI} = .${index}stft      }      section=coeffR*coeffR+coeffI*coeffI  } elseif (type=="real") {      if (flagVertical) {	  section = ${index}stft      } else {	  section = .${index}stft      }  } elseif (type=="phase") {      if (flagVertical) {	  section = ${index}stft      } else {	  section = .${index}stft      }# We should unwrap the phase !  } else {      errorf "Unnown type %s" type  }  if (flagVertical) {      xLabel="Hz"  } else {      xLabel = "seconds"  }  # In any case except for a phase display, we must  # convert to decibel display, relative to the max  # with the right dynamic range  if (type!="phase") {    threshold=((abs(section)/$max)>=10^(-dynamic/10))    section= threshold*abs(section)/$max+10^(-dynamic/10)*(1-threshold)     section= 10*log(section)/log(10)     # Then just display the energy    yLabel="dB"  } else {    yLabel="phi"  }  # Case the window already exists    if ([msge stftWindow exist]) {      import args 1 &array bindings.GraphStft.StftSection      updatexaxis=0      updateyaxis=0            if (StftSection.type!=flagVertical) {	  updatexaxis=1	  StftSection.type=flagVertical      } else {	  {x0 x1 y0 y1}=[setg stftWindow.fv1.view -bound]	  {imin imax}=[stats minmax section]	  ymin=section.Y[imin]	  ymax=section.Y[imax]	  if (y0 > ymin) {	      y0=ymin	      updateyaxis=1	  }	  if (y1 < ymax) {	      y1=ymax	      updateyaxis=1	  }      }      if (updatexaxis) {	  disp stftWindow section	  setgu ..fv1 -xLabel xLabel	  setgu ..fv1 -yLabel yLabel      } elseif (updateyaxis) {	  setgu stftWindow.fv1 -graph1 section "1" -xLabel xLabel -yLabel yLabel -bound '*' '*' y0 y1      } else {	  setgu stftWindow.fv1 -graph1 section "1" -xLabel xLabel -yLabel yLabel      }  } else {      import args 1 &array bindings.GraphStft.StftSection      StftSection.type=flagVertical      disp stftWindow section      setgu ..fv1 -xLabel xLabel      setgu ..fv1 -yLabel yLabel  }  }setbinding 'stftsection' "{{Shift + Middle button = vertical (decibel) section}} \{{Ctrl + Middle button = horizontal (decibel) section}}"setbinding 'stftsection' GraphStft middleButtonDown shift {_StftSection 0}setbinding 'stftsection' GraphStft middleButtonMotion shift {_StftSection 0}setbinding 'stftsection' GraphStft middleButtonDown ctrl {_StftSection 1}setbinding 'stftsection' GraphStft middleButtonMotion ctrl {_StftSection 1}binding activate 'stftsection'################################################# Vertical sections################################################  binding delete 'fftsection'setproc _FFTSection {} {     # Get the signal  sig=[setg $@objname -graph]  # Get the FFT parameters  import args 1 bindings.GraphSignal.FftSection.windowType  import args 1 bindings.GraphSignal.FftSection.windowSize  import args 1 bindings.GraphSignal.FftSection.windowPaddSize  import args 1 bindings.GraphSignal.FftSection.dynamic  # Get the right time index  x0    = sig.x0  dx    = sig.dx  index = int((@x-x0)/dx+.5)  # Should test whether ..select1 exists, and return with no action if not  l = [msge ${@objname}.^ list 'select*']  if (l.length == 0) {    printf "You should select a region first to specify the window size\n"    return  }  s = l[0]  {i j di dj} = [setg ..$s -rect]  windowType     ='hamming'  windowSize     = int(di/dx)  windowSize = 2^(ceil(log(windowSize)/log(2)))  windowPaddSize = min(2048,2*windowSize)  dynamic        = 90  # Get the spectrum  window   =[new &signal]  fftR     =[new &signal]  fftI     =[new &signal]  fft      =[new &signal]  threshold=[new &signal]  # Extract and window the piece of signal  extract=sig[*b0,(index-windowSize//2):(index-windowSize//2+windowSize-1)]  window = [stft window windowType windowSize]  extract*=window  # Zero padding  extract1=extract[*b0,0:!windowPaddSize]  # Fft  fft extract1 fftR fftI  fft=fftR*fftR+fftI*fftI  # Size the dynamic range  threshold = fft>= 10^(-dynamic/10)  fft       = threshold*fft+10^(-dynamic/10)*(1-threshold)  fft       = 10*log(fft)/log(10)  # Then just display the energy  xLabel = "Hz"  yLabel = "dB"  # Case the window already exists    if ([msge fftWindow exist]) {    {x0 x1 y0 y1} = [setg fftWindow.fv1.view -bound]    {imin imax}   = [stats minmax fft]    ymin = fft.Y[imin]    ymax = fft.Y[imax]    update=0    if (y0 > ymin) {	y0=ymin	update=1    }    if (y1 < ymax) {	y1=ymax	update=1    }    if (update) {	setgu fftWindow.fv1 -graph1 fft  "1" -bound '*' '*' y0 y1    } else {	setgu fftWindow.fv1 -graph1 fft "1"    }  } else {      disp fftWindow fft -..fv1 -yLabel yLabel -xLabel xLabel -..fv1.view -bound '*' '*' '?' '*'# If we replace the above line with the following lines# we are supposed to shift the fftWindow so as# not to overlap the signal window.# However there is a bug so far that locks the mouse# in the signal window whenever the fftWindow is deleted#    {hsize vsize}=[setg . -size]#    {hpos vpos}  = [setg . -pos]#      disp fftWindow fft -pos [= $hpos+$hsize] $vpos -..fv1 -yLabel yLabel -xLabel xLabel -..fv1.view -bound * * ? *  }  }setbinding 'fftsection' "{{Shift + Right button = FFT spectrum}}"setbinding 'fftsection' GraphSignal rightButtonDown shift {_FFTSection}setbinding 'fftsection' GraphSignal rightButtonMotion shift {_FFTSection}binding activate 'fftsection'

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -