Data AcQuisition And Real-Time Analysis
Scope - Spectrum - Spectrogram - Signal Generator
Software for Windows
Science with your Sound Card!
The following is from the Daqarta Help system:



Spectrum Analyzer

Signal Generator

(Absolutely FREE!)


Pitch Tracker


DaqMusiq Generator
(Free Music... Forever!)

Engine Simulator

LCR Meter

Remote Operation

DC Measurements

True RMS Voltmeter

Sound Level Meter

Frequency Counter
    Spectral Event

    MHz Frequencies

Data Logger

Waveform Averager


Post-Stimulus Time
Histogram (PSTH)

THD Meter

IMD Meter

Precision Phase Meter

Pulse Meter

Macro System

Multi-Trace Arrays

Trigger Controls


Spectral Peak Track

Spectrum Limit Testing

Direct-to-Disk Recording



Frequency response

Distortion measurement

Speech and music

Microphone calibration

Loudspeaker test

Auditory phenomena

Musical instrument tuning

Animal sound

Evoked potentials

Rotating machinery


Product test

Contact us about
your application!

File Navigator Mini-App


The File_Nav macro mini-app is included with Daqarta. To run it, hit the F8 key followed by the N key, or hit CTRL+F8 to open the Macro Dialog, then double-click on File_Nav in the Macro List.

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.

If you unPause, Daqarta will run through the file using DDisk Read Step Size steps between screens. File_Nav will move the dotted cursor along to the current location as it changes.

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.

Theory of Operation:

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[0]) and the second positive peak (Buf0[2]) to get the first Buf1 positive peak (Buf1[0]) for Spectrum mode. Then it finds the most-negative of Buf0[1] and Buf0[3] to get Buf1[1], 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.

File_Nav Macro Listing:

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."
            Msg="No Channel Selected." +n +"Right-click here for Help."
            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."
                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
                    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
                    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
                    CursDotN=QS        ;Else set Spect position
                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

_File_Nav_Task Macro Listing:

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
                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
                        CursDotN=QS        ;Else set Spect dot curs
                    Q1=CursDotN        ;Save current dot curs index
            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
                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

See also Macro Examples and Mini-Apps, Reading DDisk Files


Questions? Comments? Contact us!

We respond to ALL inquiries, typically within 24 hrs.
Over 35 Years of Innovative Instrumentation
© Copyright 2007 - 2023 by Interstellar Research
All rights reserved