Data AcQuisition And Real-Time AnalysisScope - Spectrum - Spectrogram - Signal Generator
Software for Windows
Science with your Sound Card!
Contact us about
File Navigator Mini-App
Note that File_Nav expects you to have already opened an existing DDisk (long, multi-screen) file for reading. If not, it will respond with a "No File Open" message. If a file is open, but it is shorter than 2 screens, File_Nav responds with "File Too Small".
You can right-click any File_Nav message to open this Help topic.
File_Nav shows the complete file waveform, compressed laterally to fit on a single screen. This is shown in orange and is shifted up by a half-screen. The normal uncompressed raw waveform (or Spectrum... see below) is shown below it.
The dotted cursor shows the relative position of the raw waveform in the total file. If you have just opened the file, the raw waveform will show the first screen of data, and the dotted cursor will be at the left edge of the display area. Dragging the dotted cursor along the compressed display causes the raw display to move to the equivalent position in the file.
If you use the file navigation keys (<>, SHIFT+<>, ALT+<>, Home, or End to move through the file, the dotted cursor will move correspondingly. Likewise if you directly enter a value into the file position readout below the right end of the display area. Note that if the file is very long, small changes in the file position (less than about 0.2% of the total length) may not cause a visible dotted cursor motion. But dotted cursor motion will always change the file position.
The solid cursors are always independent, and only pertain to the raw view. In fact, the dotted cursor readouts still read the raw data values, as do the Delta and Sigma readouts. However, these are unlikely to be useful while File_Nav is active, since you can't move the dotted cursor to a position on the raw waveform without causing a file position change... which moves the waveform you are trying to measure!
The solution for that is to simply toggle File_Nav off while you make measurments with the dotted cursor. (You can either double-click on it in the Macro List, or hit the Macro Run button if File_Nav is already highlighted.) When you later toggle File_Nav back on, the dotted cursor will jump back to its prior location, showing the file position.
In Spectrum display mode the compressed waveform is still shown in the upper half of the screen, but it is coarser than in waveform display mode. That's because Spectrum mode normally shows only the 512 spectrum (frequency) points obtained from an FFT of 1024 waveform time points, and anything shown on the Spectrum display must be compatible. (See below for a description of this conversion.)
The Spectrum mode cursors are normally completely independent of the waveform cursors, but with File_Nav active the dotted cursors are forced to track in both modes. So if you slide the dotted cursor to show a certain part of the file while viewing the waveform, and then toggle to Spectrum mode, you will see the spectrum of that same part of the file. The dotted cursor will still be at the same place on the compressed view in both modes.
File_Nav does nothing in Spectrogram mode, which doesn't have a cursor display, or support for display of macro array buffers. But when you toggle back to waveform (Sgram off) or Spectrum display, File_Nav will show the view of the same part of the file that was at the start of the last spectrogram screen (as indicated by its file position readout).
File_Nav automatically exits when you close the file.
File_Nav at its conceptual simplest must perform only two basic tasks: It must show a compressed view of the file that fills a single screen, and it must allow dotted cursor position to control the file position. The main File_Nav macro creates the view when first toggled on, then installs _File_Nav_Task to handle the cursor motion.
File_Nav first reads the total file size in samples via QN=FileInfo?S, then QX=QN/1024 - 1 divides by the number of samples per screen (1024) to get the number of screens (less one, to insure that the compressed view takes a bit more than one screen for display purposes). It uses this QX value to set the decimate factor, which is the amount by which the data must be compressed, in DecX=QX. This means that the first QX samples are combined to obtain the first compressed time point, the next QX samples go into the next point, and so on.
However, simple decimation has a low-pass filter effect that smooths out peaks. Instead, File_Nav uses X_Env=1 to set Envelope mode, which preserves the most-positive and most-negative peaks of the QX samples in each compressed time point. Then Decimate=1 turns on the decimated display of the file, but only long enough to copy the data points into macro array Buf0 via Buf0="<=W(Ch?c)".
The Ch?c inside the parentheses means "use the lowest-numbered channel being displayed", so if you have (say) a stereo input file it will default to Left In. Toggle that channel off via its display channel button at the lower left of the display area, and the next-lowest Right In will be shown instead.
Next, Buf0="<dWB(255,128,0)" sets Buf0 to be displayed in orange as a bipolar waveform (whenever waveform mode is active), and Buf0#Z=64 sets the vertical (zero) position up by 64/128 = 1/2 screen. Then Decimate is toggled off via Decimate=0, and the compressed display remains visible while the raw data is shown normally.
That's the basic process, but the actual File_Nav macro includes tests to see if it is already running, and if so to treat a toggle attempt as a toggle-off. If it's going on, it tests to make sure a file is open and that it is long enough to decimate and display properly.
In case the file is not only open, but has also been scrolled past the start, the current file position is first saved via QP=FilePosn?S, then QW=QP*1024/QN finds the relative waveform position as a fraction of the total length. The file is forced to the start via FilePosn#S=0 so that the Decimate compressed view will include the whole file. Then after the compressed view has been saved and displayed, and Decimate toggled off, the file is set back to the original position with FilePosn#S=QP, and the dotted cursor set via CursDotN=QW.
The above discussion considers only waveform display, but you may want to toggle between waveform and Spectrum views. However, a spectrum only has half as many frequency magnitude points as the waveform time points used to create it, so to show the compressed waveform in Spectrum mode requires a reduction from 1024 to 512 points.
The WHILE loop in File_Nav performs this conversion. The Decimate Envelope mode used to fill Buf0 with 1024 compressed data points actually has 512 pairs of positive and negative peaks, one pair per time point, for 512 total time points. The WHILE loop takes the larger of the first positive peak of the Buf0 waveform (Buf0) and the second positive peak (Buf0) to get the first Buf1 positive peak (Buf1) for Spectrum mode. Then it finds the most-negative of Buf0 and Buf0 to get Buf1, and so on through the buffers.
Buf1 is then set to be shown in orange when Spectrum is active via Buf1="<dSB(255,128,0)", offset up as for Buf0 via Buf1#Z=64.
File_Nav saves the current Spectrum state in Qs (0 = waveform, 1 = Spectrum) and the current cursor index (for whichever Spectrum state is active) in Q1. Finally, File_Nav installs _File_Nav_Task to respond to dotted cursor movements by moving the file to the corresponding position.
_File_Nav_Task does this by checking to see if the current Spectrum mode is the same, and if so whether the dotted cursor is unchanged from the saved Q1 value. If changed, it reads the new waveform cursor position via QW=CursDotN, then finds the corresponding file position as a fraction of the whole and sets it via FilePosn#S=QW/1024*QN. A similar computation is done for Spectrum mode. The new cursor and file positions are then saved in Q1 and QP respectively.
If neither the Spectrum mode nor the cursor position has changed, _File_Nav_Task checks to see if the file position has changed via IF.QP=!FilePosn?S. This could be due to key scrolling, direct position entry, or unPause operation. If so, it saves the new position in QP and moves the cursor to the corresponding proportional screen position.
If the Spectrum mode state has changed, _File_Nav_Task simply sets the proper dotted cursor position for the new mode. If Spectrum is now off, the waveform dotted cursor QW is simply twice the former Spectrum cursor position QS. Conversely, if Spectrum is now on, the new QS is half the old QW.
Since any cursor position change causes a display update, which causes all installed tasks to be updated and will result in _File_Nav_Task being hit again, variable QX is used as a flag so that Spectrum toggles only act once; if the flag is set, the current Spectrum state is saved in Qs (ending the Spectrum change handling), and then QX is cleared to be ready for the next change.
;<Help=H490D Task="?_File_Nav_Task" ;Task installed? IF.Task=1 ;IF so, Task="-_File_Nav_Task" ;Uninstall it Buf0="<d-" ;Clear Buf0 display (wave) Buf1="<d-" ;Clear Buf1 display (Spectrum) Xpand=0 ;No X-axis eXpand Msg= ;Remove Message ELSE. ;Else if not installed yet, QN=FileInfo?S ;Get file size in samples IF.QN=0 ;File open? Msg="No File Open." +n +"Right-click here for Help." ELSE. IF.Ch?c=-1 Msg="No Channel Selected." +n +"Right-click here for Help." ELSE. QX=QN/1024 - 1 ;Else get # of full 1024-pt screens IF.QX=<2 ;Less than 2 screens? Msg="File Too Small." +n +"Right-click here for Help." ELSE. QP=FilePosn?S ;Current file position QW=QP*1024/QN ;Equivalent wave cursor index QS=QW/2 ;Equivalent Spectrum curs index Qs=Spect ;Get current Spectrum state Sgram=0 ;Not for Sgram mode FilePosn#S=0 ;Set file position to start Xpand=0 ;No X-axis eXpand DecX=QX ;Decimate Factor = num screens X_Env=1 ;Envelope shows extremes Decimate=1 ;Decimate now shows whole file Buf0="<=W(Ch?c)" ;Copy Decimate waveform to Buf0 Buf0="<dWB(255,128,0)" ;Orange wave display color Buf0#Z=64 ;Shift wave up by half screen UI=0 ;Index to find image for Spect WHILE.UI=<512 ;512 Spect screen points U0=Buf0[UI*2] ;Get initial wave max value U1=Buf0[(UI+1)*2] ;Get next wave max value IF.U1=>U0 ;Set U0 to most-positive U0=U1 ENDIF. Buf1[UI]=U0 ;Save as initial Spect max value UI=UI+1 ;Next index U0=Buf0[UI*2+1] ;Initial wave min value U1=Buf0[(UI+1)*2+1] ;Next wave min value IF.U1=<U0 ;Set U0 to most-negative U0=U1 ENDIF. Buf1[UI]=U0 ;Save as initial Spect min value UI=UI+1 ;Next index WEND. ;Do all 512 Spect points QX=0 ;Flag = no curs change yet Buf1="<dSB(255,128,0)" ;Orange Spect display color Buf1#Z=64 ;Shift display up by half screen Decimate=0 ;Done with main Decimate FilePosn#S=QP ;File to original position IF.Qs=0 ;Wave mode? CursDotN=QW ;Set position if so ELSE. CursDotN=QS ;Else set Spect position ENDIF. Q1=CursDotN ;Save curs index for task test Msg="Dotted cursor scrolls through file." +n +"Right-click here for Help." Task="_File_Nav_Task" ;Install task ENDIF. ENDIF. ENDIF. ENDIF.
;<Help=H490D QN=FileInfo?S ;Get file size in samples IF.QN=0 ;File no longer open? Task="-_File_Nav_Task" ;Uninstall task if not Buf0="<d-" ;Clear Buf0 display (wave) Buf1="<d-" ;Clear Buf1 display (Spectrum) Msg= ;Remove Message, if any ELSE. ;If file still open, IF.Sgram=0 ;Not for Sgram IF.Qs=Spect ;Same Spectrum state? IF.CursDotN=!Q1 ;If so, has dot curs moved? Msg= ;Remove Message, if any IF.Spect=0 ;Is this wave display? QW=CursDotN ;If so, get new dot curs FilePosn#S=QW/1024*QN ;File posn to curs fraction ELSE. ;Else Spectrum display QS=CursDotN FilePosn#S=Qs/512*QN ENDIF. Q1=CursDotN ;Save new dot curs as current QP=FilePosn?S ;Save current file posn ELSE. ;Spectrum state changed IF.QP=!FilePosn?S ;File posn changed? QP=FilePosn?S ;If so, save as current QW=QP*1024/QN ;New wave cursor index QS=QW/2 ;New Spectrum curs index IF.Spect=0 ;Is this wave display? CursDotN=QW ;Set dot curs if so ELSE. CursDotN=QS ;Else set Spect dot curs ENDIF. Q1=CursDotN ;Save current dot curs index ENDIF. ENDIF. ELSE. IF.QX=0 ;Flag = curs change in progress? IF.Spect=0 ;If not, is this now wave display? QW=QS*2 ;Wave index is twice Spect CursDotN=QW ;Wave curs posn matches Spect ELSE. ;Switch to Spectrum display QS=QW/2 ;Spect index is half of wave CursDotN=QS ;Spect curs posn matches wave ENDIF. QX=1 ;Flag = curs change in progress ELSE. ;Curs change after Spect state change Qs=Spect ;Save new Spect state QX=0 ;Flag = curs change done ENDIF. ENDIF. ENDIF. ENDIF.
Questions? Comments? Contact us!We respond to ALL inquiries, typically within 24 hrs.
Over 35 Years of Innovative Instrumentation
© Copyright 2007 - 2022 by Interstellar Research
All rights reserved