Daqarta
Data AcQuisition And RealTime Analysis
Scope  Spectrum  Spectrogram  Signal Generator
Software for Windows Science with your Sound Card! 

The following is from the Daqarta Help system:

Features:OscilloscopeSpectrum Analyzer 8Channel

Applications:Frequency responseDistortion measurementSpeech and musicMicrophone calibrationLoudspeaker testAuditory phenomenaMusical instrument tuningAnimal soundEvoked potentialsRotating machineryAutomotiveProduct testContact us about


Macro Math Functions
Introduction:A macro math function consists of a keyword followed by an argument (value or expression in parentheses), such as sqrt(A^2 + B^2). In the tables that follow, functions will be shown wih empty parentheses, as in sqrt(). Some special functions take two arguments, and some can take either one or two arguments. If two arguments are given, they are separated by a comma. Note that math functions may not be used in string expressions, only math expressions. For example, you may not use Msg="Number = " + rand(0,100). Instead, you can use A=rand(0,100) followed by Msg="Number = " + A.
Logarithmic and Exponential Functions:log() Natural logarithm (base e) ln() (Same as above) log10() Common logarithm (base 10) log2() Base2 logarithm exp10() Raise 10 to a power exp() Raise e to a power exp2() Raise 2 to a power sqrt() Square root Note that the logarithm of zero or a negative number is undefined, and will return an error value equal to the maximum negative for the type of variable in use. There is no such issue with exponentials or square roots, although the square root of a negative number will be positive.
Trigonometric Functions:All angles are in radians. There are 2 * pi radians in a circle of 360 degrees, so to convert radians to degrees, multiply by 360 / (2 * pi). To convert degrees to radians, multiply by 2 * pi / 360. sin() Sine of an angle cos() Cosine of an angle tan() Tangent of an angle asin() Arc sine; angle whose sine is () acos() Arc cosine; angle whose cosine is () atan() Arc tangent; angle whose tangent is () Note: The atan() function can accept either one or two arguments. If two arguments are given they are assumed to be in the form atan(Y,X), which is the angle whose tangent is Y / X. In the C programming language this would be called atan2. This twoargument form is preferable where possible, because it does not have the dividebyzero issues that would result from predividing Y / X, and because it can can keep track of the sign of the resultant angle over all 4 quadrants
Hyperbolic Functions:sinh() Hyperbolic sine cosh() Hyperbolic cosine tanh() Hyperbolic tangent asinh() Hyperbolic arc sine acosh() Hyperbolic arc cosine atanh() Hyperbolic arc tangent
Integer and Sign Functions:abs() Absolute value sgn() Sign of () = 0, +1, or 1 sign() Sign of () = +1 or 1 int() Integer part of (), no rounding fix() As above, but negatives truncate toward 0 cint() Rounds away from 0 if abs(fraction) >= 0.5 ceil() Rounds to nexthighest integer Examples: A abs(A) sgn(A) sign(A) int(A) fix(A) cint(A) ceil(A) 3.7 3.7 1.0 1.0 3.0 3.0 4.0 4.0 3.1 3.1 1.0 1.0 3.0 3.0 3.0 4.0 0 0 0 1.0 0 0 0 0 3.1 3.1 1.0 1.0 4.0 3.0 3.0 3.0 3.7 3.7 1.0 1.0 4.0 3.0 4.0 3.0 Note: If you are familiar with the C programming language, Daqarta's int() is equivalent to C's floor(). Similarly, fix() is equivalent to trunc().
Unsigned Integer To Float Function:uns(UA) Daqarta's integer and fixedpoint variables are assumed to be signed values in the range of 2^311 to 2^31. However, you may encounter unsigned 32bit integers from such sources as Arduino boards. If an unsigned integer is less than 2^31 there is no problem, but if it is larger it will be treated as a negative value by Daqarta. To avoid this issue, you can use the uns() function to force it to be treated as an unsigned float variable. For example, if you use UA=Port?4 to read a 4byte unsigned Arduino 'long' value into integer UA, you can follow it with A=uns(UA) to make sure that floating point variable A is properly unsigned over the full 32bit range.
Integer To String Function:str(UI) This function accepts an unsigned 32bit binary integer in UI and returns the equivalent ASCII string. The returned value is always 4 ASCII characters, padded with zeros as needed. For example, if UI = 32 then str(UI) = h30303332 = "0032". Note that the 4character result limits the useful range to 09999. Larger values will be truncated after conversion. For example, if UI = 123456789 then str(UI) will be h31323334 = "1234". A typical use is to build up a stringequivalent integer. For example, UA="Nu" << 16 + (str(UI) & hFFFF) will give "Nu08" if UI is 8, "Nu16" if 16, "Nu32" if 32, etc.
Bit Count Function:bcnt(X) returns the number of bits set in the integer representation of (X), which may be a variable or expression. Values are rounded to 32bit integers before evaluation; a value of 1 always returns 32.
Byte Swap Functions:Values in the x86compatible family of processors used by Windows are known as "littleendian". In the 4 bytes that make up a 32bit integer, the leastsignificant byte appears first in memory, followed by increasingly significant bytes at higher memory locations. Consider the hexadecimal value A0A1A2A3; the bytes would be stored in this order in memory: A3, A2, A1, A0. Other processors may be "bigendian", such that the bytes are stored in the order that humans would write them down: A0, A1, A2, A3. bswp() and bswp2 simplify handling of binary files that use the bigendian format, such as .JPG image files. (See, for example, the use of bswp2 by the _Music_JPG subroutine of the Music_from_Anything macro miniapp.) bswp(UX) reverses the order of the 4 bytes that make up 32bit integer UX, so A0A1A2A3 would become A3A2A1A0. Note: If a float variable such as X or a fixedpoint varible such as VarX contains a fractional part, the 32bit integer and 32bit fraction parts are handled separately and recombined; there is no swapping between the integer and fraction parts. For example, if the value in hex was 12345678.9ABCDE00, after bswp the value would be 78563412.00DEBC9A. bswp2(UX) is a special form for 16bit values that have been read into a 32bit integer. The hex value A0A1 would be stored in UX as 0000A1A0, such that the above bswp(UX) would give A0A10000, whereas bswp2(UX) returns the desired 0000A0A1. Note that if you use bswp2 with a full 32bit value, the high 16bit byte pair and the low 16bit byte pair will be swapped separately. Hex A0A1A2A3 would become A1A0A3A2. With floats like X or fixedpoint variables like VarX, the integer and fraction parts are also handled separately, as noted for bswp above, but now bswp2 would convert 12345678.9ABCDE00 into 34127856.BC9A00DE.
Random Value Functions:rand() Random 64bit value between specified limits rnd() Random 32bit value between specified limits Posn?R Random 32bit integer using above generator Posn?r Read seed of above generator Posn#r Set seed of above generator rand(A,B) returns a random floatingpoint value having 64bit resolution between A and B, where A and B may be constants, variables, or expressions. If only one parameter is given, the other is assumed to be 0. rnd(A,B) behaves the same way, but uses a simpler 32bit linear congruential generator. This reduced resolution will rarely be significant, but this generator has the advantage that it is simple to repeat a sequence of values by setting the same seed with Posn#r. You can also read the current seed via Posn?r and save it to a fixedpoint variable Var0Z to continue the current sequence in the next Daqarta session. You can even experiment with different generator parameters... see the Advanced Users section at the end of Mouse and Miscellaneous Position Macros. You can use Buf0="<r(A,B)" to effectively apply the rnd(A,B) math function to fill all 1024 elements in an array. The rnd() generator can be invoked from a MIDI Changes script via ?r(min,max). It is identical to but independent from the default ?(min,max) MIDI random generator when the latter is in pseudorandom mode via the ?x=0 command. See Random Macro Values for a discussion of use.
Limit Functions:lim(X,min,max) Limit X to given range. lim(X) Limit X to preset range. limx(X,min,max) Limit X to given range, else 0. limx(X) Limit X to preset range, else 0. limr(X,min,max) If X is outside range, roll to other end. limr(X) As above but with preset range. Lim=max Preset max limit. (Also Lim#M=max.) Lim#m=min Preset min limit. Lim Returns preset max limit. (Also Lim?M.) Lim?m Returns preset min limit. lim(X,A,B) limits X to values in the range between A and B. The order of A and B does not matter; either can be the maximum or minimum. Values outside the range are limited to the maximum or minimum. lim(X) works just like the above, except that the limits must be set ahead of time with the Lim command (see below). limx(X,A,B) behaves like lim(X,A,B) except that values outside the specified range are limited to zero. limx(X) works just like the above, except that the limits must be set ahead of time with the Lim command. limr(X,A,B) limits X to the specified range, but if it is above the range it "rolls" to the minimum, and if it is below it rolls to the maximum. limr(X) works just like the above, except that the limits must be set ahead of time with the Lim command. Lim (note case) is a command, not a function. It sets the limits for the above lim() and limx() functions. Lim=A or Lim#M=A sets the maximum limit to A. Lim#m=B sets the minimum limit to B. It doesn't matter if the "minimum" is greater than the "maximum", since the lim() and limx commands reorder the limits in operation. These preset limits are only changed by the Lim commands. They are completely independent of the limits that may be explicitly specified directly in the lim() or limx() functions. You can read the preset limit values as needed. Lim or Lim?M returns the maximum, and Lim?m returns the minimum. Note: If you set both limits to the same value, either explicitly in the function or preset via Lim, the lim() function will always return that value. However, limx() will return that value only if the input variable is exactly equal; otherwise it returns 0. This can be useful with integers, but with real numbers there may be tiny rounding or trucation errors in calculation results (as small as one part in 2^64) that make this method unreliable. In such cases, you should convert to an integer first. (See Integer and Sign Functions, above.) You can handle a desired number of decimal places by premultiplying by that number of decades, then converting to an integer. For example, instead of limx(X,123.456,123.456) to exclude all values of X other than 123.456, you can use limx(int(1000*X),123456,123456) / 1000.
Color Function:colr(Hue,Tint) colr(Hue) This function returns a 24bit ColorNum value in the range of 0 to 0xFFFFFF (16777215). The purpose of this function is to allow one or two variables to smoothly control color, which involves 3 separate color components: Red, Green, and Blue. Color numbers used by Windows are of the form 0x00bbggrr, where 'rr' is the low byte and controls the amount of red, 'gg' is the nexthighest byte and controls green, and 'bb' is blue. A single control (such as a slider) that covers this entire range does not give a useful color response, since the settability of such a control is far too coarse. Slight twitches result in huge and seeminglyrandom color jumps. Even if resolution was not an issue, a linear control would not give a userfriendly response. As the control smoothly increased from 0 (pure black) it would hit pure red at 255 (0X0000FF). But the very next step would be pure black with one unit of green (0x000100), indistinguishable from black. Continued increase would again increase red to maximum, then drop back to black with 2 units of green. And so on. The colr() function resolves the resolution issue and also arranges the colors into a conventional color wheel. (Note that a visiblelight spectrum contains only colors that can be perceived with singlewavelength light, as seen in a rainbow, or by passing white light through a prism. It runs from red through yellow, green, cyan, and blue, but does not include magenta. The brain perceives magenta when both red and blue receptors are stimulated, but not green.) As Hue (which may be a simple value, variable or expression) varies from 01535 the returned color number varies from pure red through all the fullysaturated colors of the color wheel and back to red. Hue values from 1536 to 1791 vary from black through shades of gray (all color components equal) to white. The Tint value, which may be from 255 to +255, is then added to each of the three color components of the saturated color number. No component is allowed to exceed 255 or go lower than 0. The effect of this is that positive Tint values move the effective color toward white (washed out) and negative values move the color toward black. You can omit the Tint value to obtain fullysaturated colors from a single Hue variable. A typical use for this function is shown in the Line Color control of the Diff_Chan macro miniapp. It is also used in the Input Color Mod function implemented in _Liss_Task of the Lissajous miniapp, and in the color button of the FFT Filter miniapp. See Mouse and Miscellaneous Position Macros for an example of a Task that allows the mouse position to change trace color, where Hue is controlled by horizontal position and Sat by vertical position. See also the _Color_Tint macro to lighten or darken an existing color.
Channel Status Function:chan() Input or output channel state chan(C) returns 1 if the channel specified by C is active, else 0. C may be a constant, variable, or expression, which is rounded to an integer to get the channel number whose status is to be tested: 0 = Left In 1 = Right In 2 = Left Out 3 = Right Out Any value outside this range will return 0. A channel is considered to be active if there are data values available, even though its display button may be off. This function is especially useful with Data Point Functions (below) and Sigma (Summation) Functions, which require a valid channel number. It can be used by Custom Controls to restrict selection to only active channels, such as for use with a Custom Meter that uses the sSig() function. (The custom control would set the validated channel for use via the Channel Select Ch command.)
Data Point Functions:Wv() Waveform data value for channel and index Sp() Spectrum magnitude for channel and index Av() Averager data value for channel and index These functions return single values from internal Daqarta arrays. There is a separate function for each type of array: Wv() for waveform, Sp() for Spectrum, and Av() for Averager array data. All data point functions use the form Wv(C,N) to return the Nth data point of channel C, where N and C may be constants, variables, or expressions. N is limited to 01023 or 0512, depending on mode. (See individual function descriptions below.) Channels are limited to 03: 0 = Left In 1 = Right In 2 = Left Out 3 = Right Out The data point functions also have a singleargument form Wv(N) which requires that the channel be previously set via the Channel Select macro Ch. Returned data point values are effective ADC or DAC counts, such that +/32767 represents a fullscale signal. To convert to volts or User Units, see Macro Data Unit Conversions. Exceptions: For Histogram and PSTH averages, Av() return values are percentage of "hits" on each histogram bin, scaled such that 32768 is 100%. TIP: You can use CursN to get the N index from the current solid cursor position, or CursDotN for the dotted cursor. For example, A=Wv(0,CursN) sets variable A to the Left In waveform data point that is under the cursor. Note that the index values returned by CursN and CursDotN are modespecific. In waveform display mode they can range from 01023, while in Spectrum mode they only range from 0511. Wv(C,N) returns the Nth instantaneous (not averaged) waveform data point of channel C. Index N is limited to 01023. You can use Wv() in any display mode, even Spectrum or Spectrogram, since those both start out with raw waveform data. Sp(C,N) is similar to Wv(), but returns the Nth instantaneous spectrum magnitude data point of channel C. Index N is limited to 0511. Results are only valid if Spectrum or Spectrogram modes are active. Av(C,N) returns the Nth averaged data point of channel C for the current (wave or Spectrum) mode. The result is only valid for a running or completed Average. For wave mode, data point index N is limited to 01023, except for Histogram averages where it is limited to 0511. In Spectrum mode it is always limited to 0511.
Sigma (Summation) Functions:wSig() Waveform Sigma (RMS) between indices BwSig() Buf07 waveform Sigma between indices sSig() Spectrum Sigma (magnitude) between indices BsSig() Buf07 spectrum Sigma between indices The summation functions operate on internal Daqarta arrays, including macro arrays Buf0Buf7. Unlike the previous data point functions, summation functions operate on a range of index values. They all use the general form of wSig(M,N), where index values M and N may be constants, variables, or expressions. These functions behave like the Sigma display of the cursor readouts, which depends upon display mode. The 'w' versions wSig() and BwSig() operate on waveform data, while the 's' versions sSig() and BsSig() operate on spectrum data. The channel number must be set ahead of time via the Channel Select command Ch. Channels are limited to 03 for wSig() and sSig(), as for the above data point functions. BwSig() and BsSig() operate on Buf0Buf7 data arrays, where the "channel" is really the buffer number 07. The waveform functions wSig() and BwSig() compute the effective RMS (Root Mean Square) of the raw data between (and including) the index values. Each raw data value is squared and added to a total, the final total is divided by the number of values to yield a mean, and the square root of the mean is returned. This is the same fundamental operation as performed by the waveform cursor Sigma mode or the RMS mode of the Voltmeter. Unlike the Voltmeter, however, you can specify a specific region of the waveform, and unlike the Sigma mode you don't have to move the cursors to select that region. (But you can use CursN and CursDotN as indices to get that same function.) You can easily find separate RMS values for different parts of a waveform. You can also use Posn?S to find the number of samples to use for waveformsynchronous RMS measurements. See the Macro Notes section under Voltmeter RMS. As with the above data point functions, returned Sigma values are effective ADC or DAC counts, such that 32767 represents a fullscale (zerotopeak) signal. However, note that RMS values are typically less (sometimes much less) than full scale. For example, a fullscale sine wave will have an RMS value equal to 0.707 times the peak, or about 23170 here. To convert to RMS volts or User Units, see Macro Data Unit Conversions. wSig() index values are limited to 01023. The current instantaneous waveform data is used to compute the RMS value unless a waveform average is running or done, in which case Averager data is used. For Histogram averages, wSig() index values are limited to 0511 (corresponding to the 512 "bins" of the Histogram display). The function returns a simple summation of the contents of the included bins, scaled to read in percent. This gives the percent of samples whose amplitudes fall between the index values, inclusive, so a value of 100.000 means that all the samples in the waveform are included. For PostStimulus Time Histogram (PSTH) averages, wSig() index values are limited to 01023. A simple summation of PSTH bins is used, such that the return value indicates the percent of averager frames with events above the PSTH threshold at each time point. In an idealized case, if the threshold is set to zero and the signal is a pure sine wave, the PSTH display would show spikes of 100% at each positivegoing zero crossing. If the wSig() indices surround one such zero crossing spike, the function would return a value of 100.000. (If there are multiple cycles in the waveform display and more than one spike is included between the indices, the return value would be a multiple of 100.) In a more typical PSTH case, the signal will have noise or jitter which causes the threshold to be reached a little earlier or later on different repetitions. Instead of a single 100% spike at each zerocrossing, there would be a distribution of spikes that together should total 100%. wSig() can give the total percent of spikes at any given distance from a chosen target value. By varying the index values, you can generate a cumulative distribution curve. You can use wSig() in any display mode, including Spectrum and Spectrogram, but only instantaneous waveform data will be used in those cases. BwSig(M,N) returns the effective waveform RMS value between index numbers M and N, inclusive, for the selected macro array Buf0Buf7. Index values are limited to 01023. The buffer number (07) must be preset via the Ch Channel Select command. BwSig() behaves like wSig(), except it is completely independent of the current display mode or Averager state. In particular, it does not provide special summationonly handling for Histogram or PSTH averages. If you copy Linear or Exponential averaged data to a buffer and apply BwSig(), you will get the same result as if you had used wSig() directly on the averaged data. You will not get equivalent results for Histogram or PSTH data. The Spectrum summation functions sSig() and BsSig() compute the effective magnitude of the raw spectrum data between (and including) the index values. They compute the square root of the sum of squares of the magnitudes at each included spectral line. (Unlike waveform RMS, there is no "Mean".) The result is the "effective" amplitude of a sine wave that has the same energy as the included components. See the Sigma topic for an example. The returned value can equal or even exceed the fullscale (zerotopeak) value of 32767. For example, a fullscale square wave will return a value of 1.414 times this if the indices include the full spectrum. (If you convert this "effective sine wave" amplitude to RMS by multiplying by 0.707, you will see that the RMS value of a square wave is the same as its amplitude. This makes perfect sense, since the RMS value is the equivalent DC value that would provide the same heating energy in a simple resistance; a square wave is essentially a DC value switched between positive and negative, both of which heat a resistor equally well.) sSig(M,N) returns the effective Spectrum magnitude value between indices M and N, inclusive, for the selected channel. Index values are limited to 0511, and channels (set via the Ch Channel Select command ahead of time) are limited to 03. Results are only valid if Spectrum or Spectrogram modes are active, otherwise the return value is 0. If a Spectrum Average is running or done the averaged magnitude values are used, otherwise the current instantaneous spectrum is used. BsSig() behaves just like sSig() except that it works on macro data arrays Buf0Buf7, so you must preset the desired "channel" to 07 with the Ch Channel Select command. Also, this function may be used in any display mode, as long as the Buf07 array holds raw FFT spectrum data. It does not work with Spectrum Average data, even if you copy it to the buffer ahead of time. Note that although both sSig() and BsSig() only allow indices in the 0511 range, they are really working on arrays of 1024 values. The raw instantaneous FFT spectrum consists of 512 pairs of values called "Real" and "Imaginary" (Re and Im), each pair representing one of 512 spectral lines designated 0511. See Macro Arrays Buf0Buf7 for information on how to access individual Re and Im values for instantaneous spectra. (A Spectrum Average, however, consists of only 512 average magnitude values, no separate Re and Im values.)
Peak Functions, Buf0Buf7:pkB(N) returns the mostpositive value in the BufN array, where N = 07. After this operation the index (01023) of the peak will be in readonly variable Posn?p. pkb(N) is identical to the above, but only scans the first 512 points in the designated BufN array. This is useful for scanning spectrum magnitudes or curves that only occupy the lower 512 points, since it ignores any remains of prior 1024point data in the upper half. pkB(N) and pkb(N) only find the mostpositive value. (But see below.) To find the mostnegative, negate the array first with Buf0="<~(0)", then use the pkB() or pkb() function. Negate the peak to get its original sign. Alternatively, you could take the absolute value of each Buf0 element using Buf0="<", then use the pk function to find the largest peak regardless of sign. The above peak functions allow you to specify the BufN array number via a variable or expression. If you don't need that ability, and you want the peak of all 1024 points, you can use an explicit BufN math operation to return the positive or negative peak. For example, X=Buf0?p sets X to the mostpositive peak in Buf0 (identical to X=pkB(0)), while X=Buf0?n sets the mostnegative peak. See also Macro Arrays Buf0Buf7, Macro Overview 

GO:
Questions? Comments? Contact us!We respond to ALL inquiries, typically within 24 hrs.INTERSTELLAR RESEARCH: Over 35 Years of Innovative Instrumentation © Copyright 2007  2021 by Interstellar Research All rights reserved 