Daqarta
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:

Features:

Oscilloscope

Spectrum Analyzer

8-Channel
Signal Generator

(Absolutely FREE!)

Spectrogram

Pitch Tracker

Pitch-to-MIDI

DaqMusiq Generator
(Free Music... Forever!)

Engine Simulator

LCR Meter

Remote Operation

DC Measurements

True RMS Voltmeter

Sound Level Meter

Frequency Counter
    Period
    Event
    Spectral Event

    Temperature
    Pressure
    MHz Frequencies

Data Logger

Waveform Averager

Histogram

Post-Stimulus Time
Histogram (PSTH)

THD Meter

IMD Meter

Precision Phase Meter

Pulse Meter

Macro System

Multi-Trace Arrays

Trigger Controls

Auto-Calibration

Spectral Peak Track

Spectrum Limit Testing

Direct-to-Disk Recording

Accessibility

Applications:

Frequency response

Distortion measurement

Speech and music

Microphone calibration

Loudspeaker test

Auditory phenomena

Musical instrument tuning

Animal sound

Evoked potentials

Rotating machinery

Automotive

Product test

Contact us about
your application!

Sound Card THD Meter Mini-App

Introduction:

Note: Before using these automated THD meters, you may want to review the fundamentals of distortion measurement.

THD_Meter and THD_Meter_LF are macro mini-apps included with Daqarta that provide resizeable meters showing Total Harmonic Distortion. They can generate test signals and analyze the distortion of amplifiers, speakers, microphones, or other systems. They can also be used without the signal generator to analyze the distortion of external oscillators or similar signals.

THD_Meter is intended for most ordinary audio-frequency distortion measurements, while THD_Meter_LF is a modified version that has been optimized for low frequencies, for uses such as woofer or subwoofer speaker measurements, or portable AC mains-replacement generators.

You can run THD_Meter by hitting the F8 key followed by the SHIFT+T keys, or hitting CTRL+F8 to open the Macro Dialog and double-clicking on THD_Meter in the Macro List.

Similarly, THD_Meter_LF can be run by hitting the F8 key followed by the unshifted t key, or hitting CTRL+F8 and double-clicking on it in the list.

Both meters use the same Custom Controls dialog to allow adjustment of various parameters. You can open this Help topic by right-clicking anywhere in the dialog, or on the separate meter itself.

The following subtopics specifically describe THD_Meter use and operation, but in general they also apply to THD_Meter_LF as well. The Low Frequency Operation subtopic discusses specific differences.

The THD_Meter macro sets Spectrum display mode and loads the THDmeter.GEN Generator setup. It also opens a Custom Controls dialog with an edit/slider control to set the Fundamental (test) frequency, a Max Harmonic control, an adjustable time constant for the meter, an Internal / External Source button, an Arbitrary / Spectral Line Lock frequency mode button, a channel select button, a Raw / Spectrum Average / Wave Average button, a time constant reset button, and a Percent / dB meter toggle button.

THD_Meter was used for the THD+N and THD 25 measurements under the Harmonic Distortion section of Sound Card Performance Tests.


Initial Set-Up:

The meter itself is a separate Custom Meter that shows both THD+N (Total Harmonic Distortion plus noise) and THD, as well as the selected channel. If that channel is not active, the meter shows "No Signal" plus the channel. Note that THD_Meter does not automatically toggle Input on (nor set Input Channels, Lines, or Levels), so the default Left In channel may show "No Signal" unless you do that manually.

It does, however, default to Internal Source which automatically toggles the Daqarta Generator on to produce an undistorted sine wave for driving the system being measured. If you have speakers connected, the default output may be too loud. You can use the F9 key to open the Volume/dB Slider Dialog to reduce or mute the sound while you are getting things set up for testing.

In either Internal or External Source modes, it is important that you adjust output and input signal levels for best results. If the input signal is too high, it can overload the sound card input and cause distortion. As the input approaches clipping, you will see a forest of spectrum peaks rise up. Reduce the level until you are satisfied that the system is not near clipping. (This is usually visible in the Spectrum display before it becomes audible.)

Note that clipping can be caused by excessive levels at the sound card input even when the amp (or other device under test) is not itself clipping. Some sound card outputs may have clipping or other increased distortion when run at maximum levels. And of course the device under test will distort when driven at high levels.

When you measure the distortion of any device or system, the operating level is an important parameter. With most amplifiers, the distortion increases gently with level until there is a dramatic increase near clipping. But at low levels the situation is reversed due to the presence of crossover distortion. As the waveform passes through zero and the amp switches between "push" and "pull" circuitry, there is a glitch in the waveform. It's roughly the same size at all levels, so it's a bigger percentage of a smaller waveform.

The meter continues to run after closing the control dialog, until it is closed separately.

When you close the THD Meter Controls and THD Meter windows, the THDmeter.GEN Generator setup remains loaded and active. The setup includes current output volume settings, so if you have changed them and want to use those settings again in the future, save the setup. (Current input settings are always saved automatically when Daqarta is closed, and restored on the next restart.)


How It Works:

THD+N is computed by integrating the energy of the spectrum at all frequencies higher than the fundamental, plus all frequencies below the fundamental (except DC), and dividing that by the energy at the fundamental. The sSig() (Spectrum Sigma) function is used to integrate energies.

THD is computed by including only frequencies that are integer multiples of the fundamental, then dividing by the energy at the fundamental. For both THD+N and THD the measurement is limited to frequencies below the Nyquist frequency, which is 24000 Hz (half the sample rate).

The Max Harmonic control allows you to restrict the harmonics included in the THD measurement. (It has no effect on THD+N.) You might want to use this to compare with discrete measurements of the first few harmonics, for example. (See Sound Card Performance Tests.)

The default setting is 25, but frequencies are also restricted to less than 24000 Hz. In the default Spectral Lime Lock mode, the default fundamental is 984.375 Hz (nearest spectral line to 1000), so the actual maximum harmonic would be 24, or 23625 Hz.

Note that distortion measurements do not require any system calibration, since they are always measured as a percentage of the fundamental amplitude.


Spectral Line Lock:

By default the controls start with the frequency mode set to Spectral Line Lock. This causes the test frequency to move only to frequencies that fall exactly on spectral lines, so no window function is needed. This gives a greatly improved noise floor and hence better resolution of low THD levels. If you toggle it to Arbitrary, a Blackman-Harris window is automatically used.

For comparison, toggle the channel from Left In to Left Out. This causes the meter to look at the original signal, as generated, without passing through the output D/A and the input A/D. The default fundamental is 984.375 Hz, the nearest spectral line to the standard 1000 Hz test frequency.

With Spectral Line Lock active, THD+N reads 0.0012% and THD alone reads 0.0002%. Toggling to Arbitrary Frequency and setting Fundamental to 1000 Hz causes those readings to jump to 0.1335% and 0.0180%, respectively. Those are the lowest readings you could get, assuming perfect D/A and A/D and device under test. So, unless you absolutely must use 1000 Hz or another specified frequency, use the closest Line Lock frequency instead.


External Source:

To measure the THD of an external oscillator, toggle the Internal Source button to External Source. In this mode the Generator is toggled off and the Fundamental control is disabled, along with the frequency mode button. Spectrum Cursor Peak and Track modes are enabled so Daqarta can automatically find the oscillator fundamental. Since that won't be locked to a spectrum line, a Blackman-Harris window function is used.


Meter Time Constant:

For noisy signals, the Time Constant Exponent control provides simple smoothing of jittery meter values. The control value ranges from 0 to 10 and is applied as a power of 2 to determine the actual time constant, which then ranges from 1 (no smoothing) to 1024 (about 10 seconds). The default exponent is 5, which yields a time constant of 32.

The smoothed value is reset with the current instantaneous value whenever you change any control that could affect the reading, including the test frequency, Max Harmonics, channel, or Internal/External, Arbitrary/Locked, or Raw/Average modes.

You can use the TC Reset button to reset the smoothed value manually. You might want to do this when using a high time constant, if something changes in the system under test and you don't want to wait for the meter to settle. Note, however, that a reset just starts smoothing from the current value, which may happen to be high due to jitter.


Spectrum and Waveform Averaging:

Clicking the Raw button once toggles Spectrum Average. This activates a continuous Exponential average with a 32-frame time-constant. The averaged spectrum shows the same fundamental and harmonic peaks, but with an averaged noise floor that reduces the jumpiness of the meter readouts while still showing the same average values.

A second click toggles Waveform Average, likewise a continuous Exponential average with a 32-frame time-constant. But unlike spectrum averaging, waveform averaging actually reduces the noise floor... here by a factor of 32, or 15 dB. Although this means the THD+N values are no longer correct (due to the noise reduction), this does allow reading correct THD values in the presence of noise that might otherwise mask a low THD system.

Note that the Waveform Average option is not available in External Source mode since a "perfect" trigger signal can't be assured, as it can with an internal signal.


Low Frequency Operation:

The separate THD_Meter_LF macro is optimized for low frequency operation. The main difference is that it uses decimation to effectively reduce the input sample rate by a factor of 10, down to 4800 Hz instead of 48000. This gives 10x better resolution at low frequencies, which are now limited to 2400 Hz (half the effective sample rate) instead of 24000. (The Fundamental Frequency control is limited to 1000 Hz, at which setting you can only measure the 2nd harmonic.)

Since this macro was developed specifically for measuring distortion of portable AC mains-replacement generators, it loads THD_Mtr_LF.GEN to produce a USA standard 60 Hz sine wave when you select Internal Source, but it defaults to External Source. If you are using this macro for similar external-source purposes you could use Internal Source just to get familiar with the controls.

Otherwise, if you are measuring THD of a low-frequency system such as a woofer or subwoofer loudspeaker, you would normally run in Internal Source mode to produce the signal that drives the system.

Besides better resolution, this macro includes a Distortion Test button at the lower left. It is only enabled in Internal Source mode. When toggled on, it adds a 2nd harmonic component to the signal at a level of about 5%. If you set the input channel to Left Out (instead of the default Left In) you will be monitoring the output of the Daqarta Generator directly, and you can see the THD 25 value jump from near zero to 5% when Distortion Test is toggled on. (The THD+N value goes to about 7%.)

If you want to experiment with different distortion amounts, you can edit Level % in Left Stream 1 of THD_Mtr_LF.GEN. The fundamental Level in Stream 0 is set to 90%, so you can set Stream 1 up to 10% before clipping. The approximate distortion percent D is found by D = 100% * L1 / (L0 + L1), where L0 is the Stream 0 Level and L1 is Stream 1. To get a given D, set L1 = (D * L0) / (100 - D). For D=5% this gives L1 = 4.7368, the default value. Note that whatever you set will only persist for that session unless you save the changed THD_Mtr_LF.GEN setup, using the Save Setup button at the bottom of the Generator dialog.

If you want to use a different harmonic than the 2nd, locate the following line in the _THD_Freq macro subroutine (near the end of the macro list) and replace the 2 with the desired harmonic number:

L.1.ToneFreq=2 * A     ;2nd harmonic (only used in _LF)

To make that permanent, you'll need to use the Save File button at the bottom of the macro dialog.


Voltage Range and Safety:

If you are using this macro for measuring distortion of portable AC mains-replacement generators, use extreme caution when measuring mains voltages. You must reduce the voltage down to a range that will not destroy the sound card. (1 Vrms is a safe value.) You can do this with a voltage divider or a transformer. The transformer has the advantage that it can also provide isolation, but it has the disadvantage that it may also add its own distortion. In addition, it may be difficult to find the proper model for this purpose.

A voltage divider is much simpler, and resistor values can be easily computed and obtained. But there is no isolation, so you must pay careful attention to grounding. Preferably, you should use a laptop running on battery, with no other external connections. Alternatively, you can use a USB sound card with a separate USB isolator. See the Isolation, Electrical topic for details.

This macro will work without modification for generators running at 50 Hz, or any other low frequency.


THD_Meter Macro Listing:

The overall THD_Meter mini-app actually consists of the initial THD_Meter macro which launches both the Custom Controls dialog handler _THD_Ctrls, and also the Custom Meter handler _THD_Task. _THD_Ctrls invokes another macro called _THD_Freq to handle fundamental frequency changes.

;<Help=H4900
Close=                             ;Close any open data file
Task="-_THD_Task"                  ;Uninstall task, if present
Spect=1
Ylog=1
TrackThresh=-20                    ;Peak Track details
TrackMin=200                       ; for External Source
TrackMax=10000
TrackFund=0
SpectWind=BkHr                     ;Window for Arbitrary Freq
SpectWindOn=0
SmplRate=48000
UI=Input                           ;Save current Input state
A.LoadGEN="THDmeter"               ;Load Gen setup
Input=UI                           ;Restore initial Input state
Ctrls="<<THD Meter Controls"       ;Custom Controls title
Ctrl0="<<Fundamental Frequency"    ;Ctrl0 label
Ctrl1="<<Max Harmonic"
Ctrl3="<<Time Constant Exponent"
Btn0="Internal Source"
Btn1="Spectral Line Lock"
Ch=0
Btn2=""+Ch(c)
Avg=0                              ;Start with Average off
Btn3="Raw"                         ;Non-Avg
Btn4="TC Reset"
Btn5="Percent"
UT=TrigMode                        ;Save trigger mode for exit
TrigMode=GenSync                   ;Trigger on Gen Sync
Ctrl0="<S(20,10000)"               ;Fund freq range
Ctrl1="<S(2,25)"                   ;Max harmonics to include
Ctrl1="<p(0)"                      ;Integer display
Ctrl2="<X"                         ;No Ctrl2
Ctrl3="<S(0,10)"                   ;TC Exponent range
Ctrl3="<p(0)"                      ;Integer display
Ctrl0=984.375                      ;Fund freq default
Ctrl1=25                           ;Include up to 25 harmonics
UN=Ctrl1
Ctrl3=5                            ;Time Constant Exp. default
QT=32                              ;TC default (2^Ctrl3)
UK=1                               ;Reset TC on next update
Btn0="<T"                          ;Btn0 = Toggle type
Btn1="<T"
Btn2="<M"                          ;Momentary
Btn3="<M"
Btn4="<M"
Btn5="<T"
Btn0=0                             ;Internal source default
Btn1=0                             ;Line Lock default
Btn2=0                             ;Left In default chan
Btn3=0                             ;Raw (non-Avg) default
U3=0
Btn5=0                             ;Percent default
U5=0
Mtr0="<<THD Meter"                 ;Meter title
Mtr0="<C(0)"                       ;Black meter text
Mtr0="<B(hFFFFFF)"                 ;White meter background
Mtr0="<H4900"                      ;Right-click opens this Help
Task="_THD_Task"                   ;Install task that does the work
@_THD_Ctrls=Ctrls                  ;Open Custom Controls dialog
;Mtr0=                  ;Add this code for Mtr0 close
;Task="-_THD_Task"      ; on Ctrls close
;Avg=0
;TrigMode=UT

THD_Meter_LF Macro Listing:

Like the THD_Meter mini-app, THD_Meter_LF consists of an initial THD_Meter_LF macro, which launches both the Custom Controls dialog handler _THD_Ctrls and also the Custom Meter handler _THD_Task. _THD_Ctrls invokes another macro called _THD_Freq to handle fundamental frequency changes. These are the same _THD_Ctrls, _THD_Freq and _THD_Task subroutines also used by THD_Meter

;<Help=H4900 - Modified for 60 Hz external input
Close=                             ;Close any open data file
Task="-_THD_Task"                  ;Uninstall task, if present
Spect=1
Ylog=1
TrackThresh=-20                    ;Peak Track details
TrackMin=20                        ; for External Source
TrackMax=1000
TrackFund=0
SpectWind=BkHr                     ;Window for Arbitrary Freq
SpectWindOn=1
SmplRate=48000
DecX=10                            ;Decimate by 10x factor
Decimate=1                         ;Decimation on
UI=Input                           ;Save current Input state
A.LoadGEN="THD_Mtr_LF"             ;Load Gen setup
Gen=0
Input=UI                           ;Restore initial Input state
FstepLine=1/DecX                    ;Spect Line Lock to smaller steps
Ctrls="<<THD Meter Controls - Low Frequency" ;Custom Controls title
Ctrl0="<<Fundamental Frequency"    ;Ctrl0 label
Ctrl1="<<Max Harmonic"
Ctrl3="<<Time Constant Exponent"
Btn0="External Source"
Btn1="Arbitrary Frequency"
Ch=0
Btn2=""+Ch(c)
Avg=0                              ;Start with Average off
Btn3="Raw"                         ;Non-Avg
Btn4="TC Reset"
Btn5="Percent"
Btn6="Distortion Test"
UT=TrigMode                        ;Save trigger mode for exit
TrigMode=Auto                      ;Automatic Trigger sync
Trig=0                             ;Trigger off for now
Ctrl0="<S(20,1000)"                ;Fund freq range
Ctrl1="<S(2,25)"                   ;Max harmonics to include
Ctrl1="<p(0)"                      ;Integer display
Ctrl2="<X"                         ;No Ctrl2
Ctrl3="<S(0,10)"                   ;TC Exponent range
Ctrl3="<p(0)"                      ;Integer display
Ctrl0=60                           ;Fund freq default
Ctrl1=25                           ;Include up to 25 harmonics
UN=Ctrl1
Ctrl3=5                            ;Time Constant Exp. default
QT=32                              ;TC default (2^Ctrl3)
UK=1                               ;Reset TC on next update
Btn0="<T"                          ;Toggle External or Internal Source
Btn1="<T"                          ;Arbitrary Freq or Spectral Line Lock
Btn2="<M"                          ;Left/Right In/Out channel select
Btn3="<M"                          ;Raw or Spectrum Average
Btn4="<M"                          ;Momentary TC Reset
Btn5="<T"                          ;Percent / dB toggle
Btn6="<T"                          ;Distortion Test toggle
Btn0=1                             ;External source default
Btn1=1                             ;Arbitrary Frequency default
Btn2=0                             ;Left In default chan
Btn3=0                             ;Raw (non-Avg) default
U3=0
Btn5=0                             ;Percent default
U5=0
Btn6=0
Ctrl0="<D"
Btn1="<D"
Btn6="<D"
SpectPeak=1                        ;Spectrum peak readout on
SpectTrack=1                       ;Spectrum cursor tracking on
Mtr0="<<THD Meter - Low Frequency" ;Meter title
Mtr0="<C(0)"                       ;Black meter text
Mtr0="<B(hFFFFFF)"                 ;White meter background
Mtr0="<H4900"                      ;Right-click opens this Help
Task="_THD_Task"                   ;Install task that does the work
@_THD_Ctrls=Ctrls                  ;Open Custom Controls dialog
;Mtr0=                  ;Add this code for Mtr0 close
;Task="-_THD_Task"      ; on Ctrls close
;Avg=0
;TrigMode=UT
;Decimate=0

_THD_Ctrls Macro Listing:

;<Help=H4900
IF.Ctrls=0                 ;Ctrl0 = Freq change?
    @_THD_Freq                     ;Use separate macro
ENDIF.

IF.Ctrls=1                     ;Ctrl1 = Max Harmonics?
    UN=Ctrl1                       ;Get integer
    Ctrl1=UN                       ;Show integer
    UK=1                           ;Reset TC next update
ENDIF.

IF.Ctrls=3                     ;Ctrl3 = TC Exponent?
    Q3=Ctrl3                       ;Get integer
    Ctrl3=Q3                       ;Show integer
    QT=2^Q3                        ;TC = 2^Ctrl3
ENDIF.

IF.Ctrls=4                     ;Btn0 = Int/Ext Source?
    IF.Btn0=1                      ;External?
        Btn0="External Source"
        Ctrl0="<D"                     ;Disable Freq
        Btn1="<D"                      ;Disable Arb/Line Lock
        IF.Decimate=1                  ;Is this THD_Meter_LF?
            Btn6="<D"                      ;Disable Distortion Test if so
        ENDIF.
        IF.U3=2                        ;Wave avg running?
            U3=0                           ;Switch to Raw if so
            Btn3="Raw"
            Avg=0                          ;Avg off
        ENDIF.
        IF.U3=1                        ;Spectrum avg running?
            Avg=1                          ;Restart if so
        ENDIF.
        SpectWindOn=1              ;Use windowing
        SpectPeak=1                ;Use peak track
        SpectTrack=1
        Gen=0                      ;No Generator
    ELSE.                          ;Else Internal source
        Btn0="Internal Source"
        Ctrl0="<N"                     ;Re-enable Ctrl0 Freq
        Btn1="<N"                      ;Re-enable Btn1 Arb/Line Lock
        IF.Decimate=1                  ;Is this THD_Meter_LF?
            Btn6="<N"                      ;Enable Distortion Test if so
        ENDIF.
        SpectWindOn=Btn1               ;Use Window if Arb
        Gen=1                          ;Generator on
        @_THD_Freq                     ;Set freq
    ENDIF.
    UK=10                          ;Reset TC on 10th update
ENDIF.

IF.Ctrls=5                     ;Btn1 = Arb/Locked freq?
    IF.Btn1=1                      ;Arb freq?
        Btn1="Arbitrary Frequency"
        Fstep=Dir                  ;Allow any freq entry
    ELSE.
        Btn1="Spectral Line Lock"
        Fstep=Line                 ;Allow only Line steps
    ENDIF.
    SpectWindOn=Btn1                   ;Use Window if Arb
    @_THD_Freq                         ;Update freq
ENDIF.

IF.Ctrls=6                     ;Btn2 = Channel?
    Ch=(Ch+1) & 3                  ;Next chan, 0-3 only
    Btn2="" + Ch(c)                ;Show chan
    UK=1                           ;Reset TC on next update
ENDIF.

IF.Ctrls=7                     ;Btn3 = Raw / Avg modes
    Trig=1                             ;Trigger for Avg
    U3=U3+1                        ;Next mode
    IF.U3=>2                       ;Limit to 0-2
        U3=0
    ENDIF.
    IF.U3=2                        ;Roll to Wave avg?
        IF.Btn0=1                      ;Ext source?
            U3=0                           ;Force Raw instead
        ENDIF.
    ENDIF.
    IF.U3=0                        ;Raw?
        Btn3="Raw"
        Avg=0                          ;No Average
    ENDIF.
    IF.U3=1                        ;Spectrum Avg?
        Btn3="Spectrum Average"
        SpavgMode=Exp                  :Exponential mode
        SpavgFrames=32                 ;32 frames
        Avg=1                          ;Start Avg
    ENDIF.
    IF.U3=2                        ;Wave Avg?
        Btn3="Wave Average"
        WavgMode=Exp                   ;Exonential mode
        WavgFrames=32                  ;32 frames
        Avg=0                          ;(Spect) avg off
        Spect=0                        ;Spect display off
        Avg=1                          ;Start Wave avg
        Spect=1                        ;Display in Spect mode
    ENDIF.
    UK=10                          ;Reset TC on 10th update
ENDIF.

IF.Ctrls=8                     ;Btn4 = TC Reset
    UK=1                           ;Reset on next update
ENDIF.

IF.Ctrls=9                     ;Btn5 = Percent/dB
    U5=Btn5                        ;Mode copy (use if Ctrls closed)
    IF.Btn5=0
        Btn5="Percent"
    ELSE.
        Btn5="dB"
    ENDIF.
ENDIF.

IF.Ctrls=10                    ;Btn6 = Distortion Test (_LF only)?
    L.1.StreamOn=Btn6              ;Toggle 2nd harmonic on/off
ENDIF.



_THD_Freq Macro Listing:

;<Help=H4900
IF.Btn1=0                          ;Spectral Line Lock?
    IF.Ctrl0?u=!0                      ;Inc/Decrement?
        L.0.ToneFreq=>Ctrl0?u          ;Add/sub Line step so
    ELSE.
        L.0.ToneFreq=Ctrl0             ;Else line-limited direct
    ENDIF.
ELSE.
    L.0.ToneFreq=Ctrl0             ;Arb freq = direct set
ENDIF.
A=L.0.ToneFreq                     ;Copy freq for test
IF.A=0                             ;0 (after Line limit)?
    A=SmplRate?X/1024                  ;Set min Line if so
    L.0.ToneFreq=A
ENDIF.
Ctrl0=A                            ;Show (limited) Ctrl0 freq value
L.1.ToneFreq=2 * A                 ;2nd harmonic (only used in _LF)
IF.U3=1                            ;Spectrum Avg active?
    Avg=1                              ;Restart if so
ENDIF.
IF.U3=2                            ;Waveform avg active?
    Spect=0                            ;Spect display off
    Avg=1                              ;Restart Wave avg
    Spect=1                            ;Display in Spect mode
ENDIF.
UK=10                              ;Reset TC on 10th update

_THD_Task Macro Listing:

;<Help=H4900
IF.Gen=1                               ;Generator on (Internal Source)?
    F=L.0.ToneFreq                     ;Fund = tone freq
ELSE.
    F=Posn?F                           ;Else Fund = tracked freq
ENDIF.
X=SpectWindOn * 4                  ;0 if Line Lock, 4 if Arb
I=cint(F * 1024 / SmplRate?X)  ;Integer spectral line
A=Sp(Ch,I)                         ;Magnitude of fund peak
IF.A=0                                 ;No fundamental?
    Mtr0="No Signal" +n + Ch(c)
ELSE.
    L=sSig(3,I-X-1)                        ;Energy below fund
    U=sSig(I+X+1,511)                      ;Energy above fund
    D=100*(sqrt(U^2 + L^2) / A)            ;Total THD+N as % of fund

    N=2                                    ;Start w. 2nd harmonic
    T=0                                    ;Total energy so far
    H=N * F                                ;Freq of 2nd harm
    WHILE.H=<(SmplRate?X/2)            ;Test all freqs in range
        I=cint(H * 1024 / SmplRate?X)          ;Spectral line
        U=Sp(Ch,I)                             ;Magnitude at line
        T=sqrt(T^2 + U^2)                      ;Combine w. total (RMS)
        N=N + 1                                ;Next harmonic
        IF.N=>UN                               ;Past limit?
            LoopBreak=2                            ;Stop if so
        ENDIF.
        H=N * F                                ;Else next freq
    WEND.
    H=100 * T / A                          ;THD as % of fund
    IF.(D + H)=>100                        ;Err if no signal
        Mtr0="No Signal" +n + Ch(c)
    ELSE.
        UK=UK-1                            ;TC countdown after change
        IF.UK=0                            ;Reset at 0
            Q=D                                ;Accums = latest
            R=H
        ENDIF.
        Q=Q + (D - Q) / QT                 ;Apply TC to display values
        R=R + (H - R) / QT
        IF.U5=0                            ;Percent?
            Mtr0=Q(0.4) + "% THD+N" +n + R(0.4) + "% THD " +UN +n + Ch(c)
        ELSE.                              ;Else show dB
            D=20 * log10(Q/100)            ;Convert TC accums to dB
            H=20 * log10(R/100)
            Mtr0=D(0.2) + " dB THD+N" +n + H(0.2) + " dB THD " +UN +n + Ch(c)
        ENDIF.
    ENDIF.
ENDIF.

IF.Mtr0?E=1                            ;Meter close?
    Task="-_THD_Task"                      ;Uninstall task
    Avg=0                                  ;Average off
    TrigMode=UT                            ;Restore Trigger mode
    Decimate=0                             ;Decimation off (for _LF)
ENDIF.

See also Macro Examples and Mini-Apps

GO:

Questions? Comments? Contact us!

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