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!

Arb_From_Equation Macro Mini-App

Introduction:

Arb_From_Equation is one of the Macro Examples and Mini-Apps included with Daqarta. It allows you to create an Arb waveform file from an equation that you provide, or modify from one of the included examples.

An Arb file normally holds a single complete cycle of the waveform you want to create, such that when the Daqarta Generator steps through it repeatedly you get a continuous wave at whatever Tone Frequency you have chosen.

However, you are not limited to "normal" continuous waves like sine, triangle, or square; you can use any arbitrary shape that you can define by equations. (See Arb_From_List for another way to create Arb files.) The only requirement is that the equation must produce a series of output values that correspond to increasing X-axis steps: The output can't move backwards in time (or on the screen), so the waveform can't have undercuts. That means, for example, that you can't draw a complete circle on the screen with a single output channel... but you can draw the top half with one channel and the bottom with another. (See the Circle wave discussion, below.)

But producing unusual waveforms is only one use of Arb files. Arbs can also be used as modulator sources for other streams, such as to create waves with arbitrary amplitude or frequency changes. They can serve as lookup tables, such as the Expnote.DAT table of musical note frequency values that can be randomly selected to modulate a stream that creates music. (See the Composer.GEN discussion for an example.)


Operation:

When you run Arb_From_Equation it loads a Generator setup called ArbTest.GEN and fills a Memory Arb (MemArb) with samples computed from the parameters and equation in the macro code. The MemArb is used to create a repeating waveform, with one full cycle displayed on the screen. Note that it may take a few seconds for the full wave to appear; you'll see a "Creating Arb in Memory..." message during this time.

Arb_From_Equation then opens a standard Windows Save As dialog that prompts you for the name of a file to save the Arb as. By default it will be a .DAT file in Daqarta's User_Data folder, but you can navigate elsewhere, or change the file type via the Save as type drop-down control.

You can enter any file name you want, but starting it with Arb_ will make it easier to distinguish from other files in the same folder.

You can hit Cancel if you aren't ready to save the file. Note that at this point the Generator is set to maximum loudness, but muted so you don't have to listen to it. The Y axis thus shows the full-scale output values; the range will be +/-1000 mV (1 V) unless you have done a Full-Scale Range calibration, in which case it will be +/- the calibration value. You can use the cursor readouts to check the values at various points on the waveform.

You can then modify the code and re-run it until you are satisfied with the result.


Setting Arb File Size:

By default, the created Arb will be 16K (16384) samples, the largest size Daqarta supports, for maximum resolution. This size is set via the UK=16 line near the start of the macro code. You can change it to 1, 2, 4, or 8 instead to get smaller files.


Waveform Width Control:

The W=100 line sets the Width of the created wave in percent; assuming that your equation is written to produce one full cycle of the waveform (as in the examples provided), reducing W will compress the waveform into a smaller percentage and fill the remainder with zeros.

For example, the Arb_Sine50.DAT file used W=50 to squeeze one cycle of the sine into the first half of the Arb. If you use this Arb with Tone Freq set to 1000 Hz, for example, you'll get a spectrum with a peak at 1000 (the expected fundamental), plus a peak at 2000 (since the sine wave takes only half the Arb cycle it is twice its frequency), plus components at 3000, 5000, 7000, and all odd multiples of the fundamental. This provides a controlled distortion that adds rich harmonics but is less harsh than other types of distortion such as clipping. This richness is especially noticeable (and pleasant) at low tone frequencies.

You can modify the code to create more than one cycle of the sine wave (or any waveform) in the Width interval. That's especially easy for the sine: Just multiply the contents of the parentheses by the desired number of cycles. For example, the normal sine equation is MemArbV[UA]=K*sin(2*pi*UA/US), so to get UC cycles use MemArbV[UA]=K*sin(UC * 2*pi*UA/US).


Equation Scripts For Included Arbs:

Below are code examples for the Arb files included with Daqarta. You can modify them for your specific needs, or use them as templates to create Arbs from completely different equations.

To use each section below, copy and paste it to replace the section in Arb_From_Equation designated between ;====... comment lines.

Preceding each equation section, the initial part of Arb_From_Equation sets common variables that all equations use.

K=32767, which is the maximum positive output value of the sound card. It is used as a scaling factor so that (for example) a sin() function with a +/-1.00 range will extend over the full range of the sound card.

UN is the number of samples in the Arb, either 1024, 2048, 4096, 8192, or 16384 (default). It is obtained via UN=MemArbV?N after creating the MemArb using MemArbV#N=UK, where UK=16 (or 1, 2, 4, or 8) was given at the start of Arb_From_Equation to set the size.

W is the Width percentage, as described in the Waveform Width Control section above. It defaults to W=100 and can never be greater than 100.

US is set via US=W/100 * UN, giving the number of output samples in the active Width region.

Variable UA starts at 0, and is used as the output sample index.

Each equation section typically consists of one or more WHILE/WEND loops that ultimately step from index 0 to US-1 to create the active output samples. Since the MemArb was filled with all zeros when created, this leaves any remaining samples at 0 if Width is less than 100 percent.

Since each equation section must produce one complete waveform cycle in US samples, each step is 1/US wide and the current step is UA/US.

The Sine Wave equation section below shows how all these variables work together in a typical case.


Sine Wave:

There's never any need for a plain sine wave Arb, since Sine is one of the standard Daqarta wave types. However, this code can be used as the basis for other equations of your own, or for creating "compressed" waveforms with null padding as discussed under Operation - Waveform Width Control, above.

The Arb_Sine50.DAT file included with Daqarta was created using the code section below, with W=50 (near the start of Arb_From_Equation) instead of the default W=100.

;==== Sine Wave ===========================
WHILE.UA=<US
    MemArbV[UA]=K*sin(2*pi*UA/US)  ;Sine wave, scaled to fit in Width
    UA=UA+1
WEND.
;==========================================

Rectified Sines:

Half-Wave Rectified Sine:

The following code produces a sine wave with only the positive half-cycle present; the negative half is replaced with nulls. This is the waveform created by a single diode rectifier acting upon a sine wave source, as in a simple power supply.

Arb_HalfRectSine.DAT was created with this code.

Note that the code is identical to the normal Sine wave code above, except that the limit of the WHILE loop has been cut in half so that only the first half of the waveform is created.

;==== Half-Wave Rectified Sine ==============
WHILE.UA=<US/2                 ;NOTE the /2 is only difference from Sine
    MemArbV[UA]=K*sin(2*pi*UA/US)  ;Half-cycle of sine
    UA=UA+1
WEND.
;===========================================

Full-Wave Rectified Sine:

This code is identical to the normal Sine wave code given earlier, except that it uses the {\b abs()} function to take the absolute value. This "flips up" the negative half-cycle to produce a full-wave rectification such as might be found in a power supply using a 4-diode bridge, or 2 diodes with a split-secondary transformer.

Arb_FullRectSine.DAT was created with this code.

;==== Full-Wave Rectified Sine ==============
WHILE.UA=<US
    MemArbV[UA]=abs(K*sin(2*pi*UA/US))
    UA=UA+1
WEND.
;==================================================

Triangle Wave:

As for the Sine Wave code above, there is never any need for a plain triangle wave Arb, since Triangle is one of the standard Daqarta wave types. However, this can be used as the basis for other equations of your own, or for creating "compressed" waveforms with null padding as discussed under Operation - Waveform Width Control, above.

Arb_Triangle50.DAT was created with this code, using W=50.

;=== Triangle Wave ========================
US=US/4
S=K / US
WHILE.UA=<US
    MemArbV[UA]=UA * S
    UA=UA+1
WEND.
WHILE.UA=<3*US
    MemArbV[UA]=2*K - (UA * S)
    UA=UA+1
WEND.
WHILE.UA=<4*US
    MemArbV[UA]=(UA * S) - 4 * K
    UA=UA+1
WEND.
;============================================

Ramp Wave:

As for the Sine Wave and Triangle Wave code above, there is never any need for a plain ramp wave Arb, since Ramp is one of the standard Daqarta wave types. In fact, the Daqarta Ramp dialog allows easy change of the Ramp Rise (otherwise done via R=75 in the code here), as well as a staircase option and selection of either Phase or Slope modulation types when used with Daqarta's standard Phase Modulation option.

However, Daqarta's Ramp wave doesn't have a built-in Width option for creating "compressed" waveforms with null padding as discussed under Operation - Waveform Width Control, above.

Arb_75Ramp50.DAT was created with this code, using W=50 together with the default R=75 here.

;=====Ramp Wave=============================
R=75                ;Ramp rise percent
S=K / (US * R/100)
WHILE.UA=<US * R/100
    MemArbV[UA]=UA * S
    UA=UA+1
WEND.
UB=UA
S=K / ((1-R/100) * US)
WHILE.UA=<US
    MemArbV[UA]=K - ((UA-UB) * S)
    UA=UA+1
WEND.
;==========================================

Square Wave:

As for Sine and Triangle, above, there's rarely any need for a plain square wave Arb like the included Arb_Square.DAT, since Square is one of the standard Daqarta wave types. However, this code can be used as the basis for other equations of your own, or for creating "compressed" waveforms with null padding as discussed under Operation - Waveform Width Control, above.

The Arb_Square50.DAT file included with Daqarta was created using the code section below, with W=50 (near the start of Arb_From_Equation) instead of the default W=100.

For normal square waves, however, there is another reason to favor the built-in Square over an Arb version: Edge sharpness at low frequencies. The standard Square using Snap mode has edges that always transition in a single sample, although there will be some amount of edge jitter except for particular frequencies.

In Interpolate edge mode, the standard Square has far less jitter, by using softer edge transitions that may take up to 2 samples.

On the other hand, the Arb approach has minimal jitter (at least with the Arb set to Interpolate instead of Round or Step), but at frequencies less than a few Hz the transitions will be spread out over multiple samples. That's because the Arb just does an ordinary overall waveform interpolation, unlike the edge-only Square Interpolate. The image below shows Arb_Square.DAT at a Tone Frequency of 1 Hz, with Trigger Delay and X-Axis eXpand set to show an expanded version of a falling edge. The transition takes 4 samples, although you only see two obvious kinks because the central region is on a straight-line section of the interpolation:

;======= Square Wave ======================
WHILE.UA=<US/2
    MemArbV[UA]=K
    UA=UA+1
WEND.
WHILE.UA=<US
    MemArbV[UA]=-K
    UA=UA+1
WEND.
;===========================================

Pulse Wave:

As with the above Square wave, Pulse is one of the standard Daqarta wave types. In fact, the Pulse dialog allows much more control than this simple code, which just produces a single positive pulse whose width is set via the W parameter. (The Pulse dialog allows two separate adjacent pulses with independent widths, levels, and polarities, as well as adjustable baseline and different width/modulation modes.)

Instead, consider this simple code as a starting point for more advanced pulse creation.

Note that if W=100 the pulse will stay high for the full cycle, resulting in a constant full-scale DC waveform. Since standard sound cards block DC, there will be no output at all. (True, you could use this to provide a DC modulation source, but you can do that simply by using the built-in Sine wave with Phase set to 90 degrees.)

Arb_Pulse50.DAT was created with this code, using W=50. This gives a positive-only square wave output. (Again, since sound cards are AC-coupled, this is only useful as a modulation source.)

;======= Pulse Wave ========================
;NOTE that if W=100 this just gives constant K level
WHILE.UA=<US
    MemArbV[UA]=K
    UA=UA+1
WEND.
;===========================================

Full-Scale Pulse Wave:

This is just like the above Pulse Wave, except that instead of a full-scale positive pulse that returns to a baseline of zero, this returns to full-scale negative. Also as above, this could have been done with the Pulse that is one of the standard Daqarta wave types, just by adjusting the zero level in the Pulse dialog, so consider this as a code example.

Likewise, if W=100 the pulse will stay high for the full cycle, resulting in a constant full-scale DC waveform.

Arb_FSPulse25.DAT was created with this code, using W=25 to produce a pulse that is high for 25% of the cycle.

;======= FS Pulse Wave ======================
;NOTE that if W=100 this just gives constant K level
WHILE.UA=<US
    MemArbV[UA]=K
    UA=UA+1
WEND.
WHILE.UA=<UN
    MemArbV[UA]=-K
    UA=UA+1
WEND.
;============================================

Tangent Wave:

This code was used to create Arb_Tan.DAT, which is a plot of the tangent function over one full circle. Note that the tangent is discontinuous at pi/2 and 3*pi/2 radians, where it goes from positive to negative infinity. Since this would be awkward to try to reproduce with a sound card that is limited to +/-32767, the waveform has been scaled down by a factor of 128. Feel free to experiment with other scale factors depending on your needs.

;======= Tan Wave ===========================
;NOTE that this has two peaks per cycle
K=K/128            ;Reduce scale factor for less peak clipping
WHILE.UA=<US
    MemArbV[UA]=K*tan(2*pi*UA/US)
    UA=UA+1
WEND.
;============================================

Half-Tangent Wave:

As above, but Arb_HalfTan.DAT produced with this code only covers half of a full circle by using tan(pi*UA/US) instead of tan(2*pi*UA/US). This give a single biphasic +/- full-scale spike at the center of the waveform (pi radians), instead of narrower spikes at pi/2 and 3*pi/2.

;======= Half Tan Wave ===========================
;As above, but single peak per cycle
K=K/128            ;Reduce scale factor for less peak clipping
WHILE.UA=<US
    MemArbV[UA]=K*tan(pi*UA/US)
    UA=UA+1
WEND.
;============================================

Gaussian Wave:

The Gaussian curve describes what is known as a 'normal' distribution in statistics. It is the standard example of a "bell-shaped curve". The code included here is for a 'standardized' version, in which the central peak is always unity (full scale here). The standard deviation D adjusts the width of the peak, with the default 1.00 producing tails that are 0.0072 (236 counts out of the full-scale 32767 counts). This was used to create the included Arb_Gauss.DAT file.

If you set D=0.70 instead, the tails will be 0.00003, or one count out of 32767.

The width of the peak at half-maximum (FWHM) as a fraction of the total width is found by FWHM = 0.375 * D.

;======= Gaussian ===========
;With D=1.00, tails = 0.0072
;With D=0.70, tails = 0.00003
;Central peak always 1.000 (Full scale)
M=0                        ;Mean = 0
D=1.00                     ;Standard Deviation
D=D / (2 * pi)             ;Working value
C=sqrt(2 * pi)             ;0.3989
K=K * C
WHILE.UA=<US
    X=(UA-(US/2)) / US
    Z=(X - M) / D
    MemArbV[UA]=K * exp(-Z^2 / 2) / C
    UA=UA+1
WEND.
;==============================

Lorentz And Derivative:

Lorentz:

The Lorentz or Lorentzian distribution is also known as a Cauchy distribution. It is similar to a Gaussian in that it is a "bell-shaped curve" tapering from a central peak. The simplified equation is Y=1/(X^2 + 1), but we'd like to control the width of the peak, the way standard deviation does for the Gaussian.

We use P as the width of the peak at half-maximum height (FWHM), and working variable G=P / 2. The revised simplified equation then becomes Y=G / (X^2 + G^2). Note, however, that this formulation is not normalized: The peak height changes with width. The code below keeps a constant full-scale height using Y=G^2 / (X^2 + G^2).

Arb_Lorentz_8th.DAT was created with the default P=0.125, which gives a width that is 1/8 of the full Arb cycle:

;======= Lorentz ================
P=0.125             ;Width of peak at half height
G=P / 2
WHILE.UA=<US
    X=(UA-US/2)/US
    MemArbV[UA]=K * G^2 / (X^2 + G^2)
    UA=UA+1
WEND.
;==============================

D_Lorentz:

The derivative of the Lorentz function is a biphasic pulse. The 'standard' equation is Y=-2 * X / (X^2 + 1)^2. Using the same width control P from the above raw Lorentz, along with working variable G=P / 2, the derivative would be Y=-2 * X / (X^2 + G^2)^2. However, as with the raw Lorentz, we also normalize to keep constant full-scale peak heights. The normalized formula is Y=-2 * X * G^3 / (X^2 + G^2)^2.

Note that although the peak heights are normalized, this does not automatically provide for a useful repeating waveform. The problem is that unless the width is kept very small (P=0.017 or less), the starting amplitude and the ending amplitude are different, which would result in an abrupt step at the end of each cycle. Below are plots for various P values:

The Arb_D_Lorentz.DAT file is shown as the green curve for P=0.017. The tails are both zero, so there is no step. If the full-scale output range is +/-1000 mV, the steps for the other P values are:

      P         Step, +/-mV
    0.500       247
    0.250       42.6
    0.125       5.8
    0.017       0.0
;======= D-Lorentz ================
P=0.017         ;Width of raw Lorentz peak
G=P/2
K=K / 0.6495    ;Scaling for full-scale peaks
WHILE.UA=<US
    X=(UA-US/2)/US
    MemArbV[UA]=K * (-2 * X) * G^3 / (X^2 + G^2)^2
    UA=UA+1
WEND.
;==============================

Witch Of Agnesi:

This is another "bell-shaped curve" like the Gaussian and Lorentz. According to Wikipedia and Wolfram, it was described by Maria Agnesi in a 1748 book that is the oldest surviving mathematical work by a woman. The "witch" in the name comes from a later mis-translation of averisera, the Italian for a "turning sine curve" into avversiera, a female devil, and later simply "witch".

The P parameter controls the width of the curve, as a fraction of the full cycle width. This is the width of the peak at half-maximum height (FWHM).

Arb_Agnesi.DAT was created with the default P=0.05:

;==== Witch of Agnesi ====================
P=0.05
A=P * 2
K=K / (2 * A)
WHILE.UA=<US
    X=2 * UA/US - 1
    MemArbV[UA]=K * 8 * A^3 / (X^2 + 4*A^2)
    UA=UA+1
WEND.
;==========================================

Catenary Curve:

A catenary curve describes the shape of an idealized rope or chain hanging freely between two end points, with no other load than its own weight. The value of A used here is selected such that the ends are at full scale. This was used to create the included Arb_Catenary.DAT file.

;======= Catenary ===========
A=0.0765                   ;Selected to get full scale in 16K samples
WHILE.UA=<US
    X=0.5 * (UA-US/2)/US
    MemArbV[UA]=K*A*cosh(X / A)
    UA=UA+1
WEND.
;==============================

Exponential Growth:

The Exponential Growth Arb Arb_Exp_Growth.DAT plots the growth of something whose growth rate is proportional to the current value - the greater it is, the faster the rise. Here we use B as the growth factor and A as the number of time constants to be plotted, where one time constant is the time for the output to increase by the factor B. The time constant is thus 1/A.

The default code uses B=2 and A=4, which could represent a plot of 4 doublings (4 time constants) of a bacterial colony:

;===========Exponential Growth ===============
A=4                    ;Include 4 time-constants in Arb
B=2                    ;Growth factor: Output multiplies by B in 1/A time
K=K / (B^A)            ;Initial value to reach full scale at end
WHILE.UA=<US
    X=UA/US
    MemArbV[UA]=K * B^(A * X)
    UA=UA+1
WEND.
;==============================

Exponential Charge And Decay:

Exponential Charge:

The Exponential Charge Arb Arb_Exp_Charge.DAT is the shape of the voltage-versus-time curve for a capacitor C being charged through a resistor R, where the charging voltage is the full-scale range of the sound card K = 32767. The product of R * C has units of seconds and is known as the time constant, which we'll call T here. This is the time at which the capacitor reaches 63.2% of the maximum voltage. (That's 1 - 1/e or 0.6321056.)

In the code below, we use A to specify how many of these T time constants will be included in the Arb. We don't use T directly there.

To use the Arb to model real resistors and capacitors, you need to consider the Tone Frequency used by the Arb. That determines the period of Arb model of the charging curve. Arb_From_Equation sets this as:

L.0.ToneFreq=SmplRate / 1024

This spreads the curve over one full waveform screen of 1024 samples, to aid in evaluating the Arb being created. But you are not limited to that when you later use the created Arb for your own applications. The time for one period of the Arb (A time constants) will be 1 / ToneFreq, so the time T for one time constant will be:

T = R * C = 1 / (A * ToneFreq).

Substituting, we can solve solve for R, C, A, or ToneFreq:

R = 1 / (R * A * ToneFreq)

C = 1 / (C * A * ToneFreq)

A = 1 / (R * C * ToneFreq)

ToneFreq = 1 / (R * C * A)


;======= Exponential Charge ============
A=4                    ;Include 4 time-constants in Arb
WHILE.UA=<US
    X=UA/US
    MemArbV[UA]=K * (1 - exp(-A * X))
    UA=UA+1
WEND.
;==============================

Exponential Decay:

Conversely, the Exponential Decay Arb Arb_Exp_Decay.DAT is the shape of the voltage-versus-time curve for a capacitor C being discharged through a resistor R, from an initial starting voltage equal to the full-scale range of the sound card. All the same time constant math applies.

;======= Exponential Decay =============
A=4                    ;Include 4 time-constants in Arb
WHILE.UA=<US
    X=UA/US
    MemArbV[UA]=K * exp(-A * X)
    UA=UA+1
WEND.
;==============================

RC Low-Pass Square Wave:

Arb_RC_LowPass_Square.DAT combines the above Exponential Charge and Exponential Decay to simulate a square wave passed through a simple RC lowpass filter.

Note that this code is for a bipolar square wave that is symmetrical about zero volts, such as the normal Generator Square Wave option. This is slightly more complex than a positive-only square wave, but in either case we need more than a simple concatenation of Charge and Decay code.

To understand the issue, consider simulating a positive-only square. We start with the Charge code for half the cycle, followed by the Decay code for the remainder. But note that the Charge curve starts at zero volts but doesn't reach the full-scale value; it only approaches it as you increase the number of time constants. Conversely, the Decay curve starts at full scale but doesn't reach zero. The simple code concatenation would thus produce an abrupt step up at the start of the Decay phase, and an abrupt step down to zero at the start of the following Charge.

To correct for this, we need to shift each phase by an amount that depends on its end value, which we must pre-compute so we can include the shift in each sample. For the bipolar square we must also double the range and shift it down so half is negative.

Note that here A is the number of time constants in each phase of the square wave.


;======= RC Low-Pass Square Wave =============
A=4                    ;Include 4 time-constants in each phase
D=K * (1 - exp(-A))    ;Precompute end of Charge phase (where X=1)
Q=K - D                ;Difference from full-scale K
A=A * 2                ;Double A to cover half cycle
WHILE.UA=<US/2
    X=UA/US
    V=K * (1 - exp(-A * X))
    MemArbV[UA]=2 * V - D
    UA=UA+1
WEND.

UA=0
D=D + 2 * Q
WHILE.UA=<US/2
    X=UA/US
    V=K * exp(-A * X)
    MemArbV[UA+US/2]=2 * V - D
    UA=UA+1
WEND.
;==============================

Logarithm:

Arb_Log.DAT is the plot of a logarithmic curve that has been scaled and offset so that it runs from negative full scale to positive full scale.

The raw equation would look something like Y=ln(X). To facilitate the scaling and offset calculations, we first rewrite it to Y=K * (1 + ln(X)). We then replace X with X=A * UA/US + B, where US is the total number of sample points in the Arb, and UA is the sample index which runs from 0 to US-1.

The sound card full-scale value is K=32767, and we want the 0th point to be -K or -32767. When UA = 0, X=A * UA/US + B becomes X=B, so we can insert that into Y=K * (1 + ln(X)) to get Y=K * (1 + ln(B)). Since we want the result to be -K here, we can set Y=-K and get -K=K * (1 + ln(B)). Dividing both sides by K gives -1=1 + ln(B), thus ln(B)=-2, hence B=exp(-2).

To find the value for A we use the condition when UA=(US-1) and set that to give an output of +K. K=K * (1 + ln(X)) then becomes 1=1 + ln(X) and ln(X)=0. Since X=A * UA/US + B, we get ln(A * UA/US + B) = 0. But we know that 0 is the log of 1, so we can remove the logarithm to get A * UA/US + B = 1 and solve for A when UA=US-1 to get A=(1 - B) * US / (US-1).

We solve for B and A outside the main loop, since these don't change during the Arb calculation.


;======= Log =============
B=exp(-2)                  ;Constant to set 0th point to -K
A=(1 - B) * US / (US-1)    ;Constant to set final point to +K
WHILE.UA=<US
    X=A * UA/US + B        ;Scaling and offset to get +/-FS range
    MemArbV[UA]=K * (1 + ln(X))
    UA=UA+1
WEND.
;=========================

Square Root:

Arb_SquareRoot.DAT is the plot of Y=sqrt(X) as X runs from 0 to 1, scaled so that the output runs from 0 to K, the sound card full-scale value.

;======= Square Root =============
WHILE.UA=<US
    X=UA/US
    MemArbV[UA]=K * sqrt(X)
    UA=UA+1
WEND.
;==============================

Ellipses And Circles:

Half Ellipse (Half Circle):

Arb_Half_Ellipse.DAT is the plot of the top half of an ellipse or a circle; the appearance depends on the Y-axis magnification and the tone frequency the Arb is run at. At full-scale magnification with one Arb cycle (one half of the ellipse) on the screen, as shown when you run this code in Arb_From_Equation, you see a half-ellipse that looks like a slightly squashed circle. If you double the tone frequency you see two half-circles (assuming your monitor has square pixels).


;======= Half Ellipse (Half Circle) =============
WHILE.UA=<US
    X=2 *(UA-US/2)/US
    MemArbV[UA]=K * sqrt(1 - X^2)
    UA=UA+1
WEND.
;=============================

Alternating Half Ellipse And Dual Circles

Arb_Alt_Half_Ellipse.DAT alternates the top (positive) half of an ellipse or circle with the bottom (negative) half in each full cycle of the Arb. It looks somewhat like a deformed sine wave. However, when the same wave is output on both Left and Right channels, but with one channel inverted, you see two adjacent full circles. The Circles.GEN generator setup has been created to do exactly this.

If you cut the screen magnification in half (PgDn key) you will see two ellipses. If you then double the Left and Right tone frequencies from 46.875 to 93.75 Hz you will see 4 circles.

;======= Alternating Half Ellipse ("Circle" Wave)===
WHILE.UA=<US/2
    X=4 * (UA-US/4)/US
    MemArbV[UA]=K * sqrt(1 - X^2)
    MemArbV[UA+US/2]=-K * sqrt(1 - X^2)
    UA=UA+1
WEND.
;==============================

Sinc Function sin(x)/x:

The sinc function looks like a sinusoid that decays on either side of a central peak, somewhat like a "ringing" bell-shaped curve:

In the code supplied here, parameter F controls the "frequency" of the sinusoid; it is essentially the number of half-cycles (positive or negative peaks) in each half of the waveform, counting the central peak.

Note that if F is an integer, the waveform will start at 0 and end at 0. However, since the waveform is mirrored about the center, that also means that when the waveform repeats it is likewise mirrored about its ends. For example, if the start is at 0 with a positive slope, the end will have a negative slope down to 0 that will not "splice" smoothly with the next start rising up from 0.

To get a smooth splice-free wave, you must set F to halfway between two integers. The image above (which is also the Arb_Sinc85.DAT waveform) used the default F=8.5. Note that it starts and ends at a positive peak, instead of a zero, so it will splice perfectly.

;=== Sinc Function ===============================
F=8.5                      ;"Frequency"
WHILE.UA=<US/2
    X=F*2*pi*UA/US
    Y=K*sin(X) / X
    MemArbV[UA+US/2]=Y         ;Fill from center up
    MemArbV[US/2-UA]=Y         ;Fill from center down
    UA=UA+1
WEND.
MemArbV[US/2]=K            ;Center = 1.00
;============================================

Cosine Window Functions:

Here we include code to create Arbs of several common window functions, the same ones used by Daqarta to reduce spectral leakage. They all use the same code, but with different parameter values. (Note that in the plot below all three Blackman curves nearly overlay, so at this scale they appear as a single yellow line.)


Hann (Haversine):

Arb_Hann.DAT was created with the code below:

;===============================================
A=0.5              ;Hann (same as Haversine)
B=0.5
C=0

;General Cosine Window:
WHILE.UA=<US
    X=2 * pi * (UA / (US-1))            ;Center the window in Width
    Y=A - B * cos(X) + C * cos(2 * X)
    Y=Y * K
    MemArbV[UA]=Y
    UA=UA+1
WEND.
;===============================================


Hamming:

Arb_Hamming.DAT was created using the following parameters in the above Cosine Window code:

A=0.54             ;Hamming
B=0.46
C=0

Blackman:

Arb_Blackman.DAT was created using the following parameters in the above Cosine Window code:

A=0.42             ;Blackman
B=0.5
C=0.08

Blackman Exact:

Arb_BkmExact.DAT was created using the following parameters in the above Cosine Window code:

A=0.42659071       ;Blackman Exact
B=0.49656062
C=0.07684867

Blackman-Harris:

Arb_BkmHarris.DAT was created using the following parameters in the above Cosine Window code:

A=0.42323          ;Blackman-Harris
B=0.49755
C=0.07922

Flat-Top:

Arb_FlatTop.DAT was created using the following parameters in the above Cosine Window code:

A=0.2810639        ;Flat-Top
B=0.5208972
C=0.1980399


Arb_From_Equation Macro Listing:

;<Help=H491F
UK=16                  ;16K = 16384 samples (1,2,4,8,16 allowed)
W=100                  ;Waveform uses 100% Width of above
W=abs(W)               ;Must be positive
IF.W=>100              ;Can't use more than 100%
    W=100
ENDIF.

Spect=0                ;Spectrum off
Sgram=0                ;Spectrogram off
Xpand=0                ;Show full horzontal range
TraceMag=0             ;Show full vertical range
Msg="Creating Arb in Memory..."
A.LoadGEN="ArbTest"    ;GEN to hold MemArb, muted Full Scale range
Ch=0                   ;Use MemArb0
MemArbV#X=0            ;Remove existing MemArb or Arb, if any
MemArbV#N=UK           ;Create 1, 2, 4, 8, or 16K MemArb
L.0.Arb0=1             ;Set output active
UN=MemArbV?N           ;Get size in samples
K=32767                ;Sound card +/- full-scale value

Decimate=0             ;Decimate OFF
L.0.ToneFreq=SmplRate / 1024    ;One cycle on screen
US=W/100 * UN          ;Samples in active Width section
UA=0                   ;MemArb sample index

;==== Sine Wave === (REPLACE as desired) ====================
WHILE.UA=<US
    MemArbV[UA]=K*sin(2*pi*UA/US)  ;Sine wave, scaled to fit in Width
    UA=UA+1
WEND.
;============================================================

WaitSecs=3         ;Wait for sound card output buffer fill
Msg=
MemArbV="<Save:"

See also Memory Arbs (MemArb0-7), Arb Files as Controllers, MemArb_To_File Macro, Wave Dialog, Arb Wave.



GO:

Questions? Comments? Contact us!

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