Data AcQuisition And Real-Time AnalysisScope - Spectrum - Spectrogram - Signal Generator
Software for Windows
Science with your Sound Card!
Contact us about
This button activates a standard bipolar square wave, and also opens a separate dialog allowing you to adjust the frequency as well as select Snap or Interpolate edges.
It also displays jitter frequency and period for Snap operation.
Square waves have a fixed 50% duty cycle; use the Pulse wave to create other duty cycles (rectangular waves).
To understand the need for the Snap/Interpolate Edges selection, consider that the output of a sound card is made up of discrete samples that come at a uniform sample rate. A perfect square wave at 100% Level would consist of a half-cycle of samples at +100% (a digital value of 32767), followed by an equal number of samples at -100% (-32767). There would be no intermediate values, so the wave would "snap" from one extreme to the other; a rising edge goes from -32767 on one sample to +32767 on the next. The opposite is true for falling edges. (This applies to the digital waveform; your sound card's output filters will additionally affect the analog transitions.)
To produce a perfect square wave of a specified frequency, each cycle must have an equal number of positive and negative samples. This would seem to limit the possible square waves to those with N high and N low samples per cycle, where N is an integer due to the fixed sample rate. (The output can't change between sample times.)
The possible output frequencies would thus be SampleRate / (2 * N). Using the standard sample rate of 48000 Hz with N = 1, we'd get a frequency of 48000 / (2 * 1) = 24000 Hz. Increasing N would give 12000 Hz, 8000 Hz, 6000 Hz, 4800 Hz, etc, with no values in between. This would give good frequency resolution only at very low frequencies, such as N = 48000 for 1.000000 Hz and N = 48001 for 0.999979 Hz.
However, this is not the way Daqarta generates waveforms. Instead, it uses a phase accumulator approach whereby each sample adds a frequency-specific step size to a circular counter, which is really just an ordinary counter such that when it overflows simply wraps back to 0 and continues. The value of the counter determines whether the square wave output should be high or low. If the count is less than half of the counter limit, the output will be high or positive. If half or more it is low or negative.
Think of this like a conventional clock face, with the square wave output determined by the second hand; when it is between 12 and 6 the output is high, while between 6 and 12 it is low. At a standard tick rate (sample rate) of once per second, the second hand moves 1/60 of a revolution per tick. The output would be a square wave that is high for 30 seconds then low for 30 seconds, giving a period of 60 seconds, or 1/60 Hz.
Now suppose we keep the same tick rate, but allow each tick to advance the hand by any multiple of 1/60 revolution. If we set it so that each tick moves 2/60, the square wave frequency will be 2/60 Hz; if it moves 5/60 per tick the frequency will be 5/60 Hz, and so on. (Note: We must limit the tick step to 30/60, which is equivalent to the Nyquist frequency or half the sample rate, to prevent aliasing.)
This scheme allows for variable square wave frequencies while using a constant tick or sample rate. The frequency resolution of the square wave is determined by how fine we allow the tick motion to be.
Daqarta divides its "clock face" (circular counter) into 2^29 positions. That imposes another restriction on the above SampleRate / (2 * N) "perfect square wave" rule, since one cycle is always 2^29 counts and is thus only evenly divisible by powers of 2. If we insist on perfection, then the possible frequencies are even more limited than previously noted: SampleRate / 2^N gives 24000 Hz for N=1, then 12000, 6000, 3000, and so on in successive divisions by two. Note that 8000 and 4800 are missing, even though they would have adhered to the original SampleRate / (2 * N) rule.
A further limitation is that only frequencies that have integer step sizes are allowed, using the relationship that the step size US is cint(Z * 2^29 / SampleRate) where Z is the desired frequency. Then the actual frequency F will be US * SampleRate / 2^29.
Using the previous case of SampleRate / (2 * 3) = 8000 Hz we find that we can't exactly hit 8000 Hz; if we try we get 8000 * 2^29 / 48000 = 89478485.333333 counts per step, which we must round to 89478485. The actual frequency will then be 89478485 * 48000 / 2^29 = 7999.999970198 Hz. That's an error of less than 4 parts per billion, surely "close enough" considering that the sound card sample rate accuracy is probably no better than 10 parts per million even for a very good card.
The phase accumulator approach thus has excellent frequency accuracy. But note what happens after 3 of these 89478485-count sample steps are added together: We get 268435455 counts, one count shy of the 268435456 counts needed for a half cycle, to make the output go low. So the initial falling edge is delayed by one sample, making the initial high phase 4 samples wide instead of the expected 3:
Sample Accumulator Output 0 0 High 1 89478485 High 2 178956970 High 3 268435455 High (Half Cycle - 1) 4 357913940 Low 5 447392425 Low 6 536870910 Low (Full Cycle - 2) 7 89478483 High 8 178956968 High 9 268435453 High (Half Cycle - 3) 10 357913938 Low 11 447392423 Low 12 536870908 Low (Full Cycle - 4) . . .
After that initial long phase, the phases settle down to 3 samples wide. The accumulator wraps at 2^29 = 0, but the count continues to lag by 1 for each 3 samples. Finally, after the lag reaches the size of a half cycle at 89478485 * 3 = 268435455 samples, we get a 4-sample wide low phase. This is followed again by a return to 3 samples per phase for the same duration until the lag is a full cycle, whereupon the entire sequence repeats from 0.
At 48000 samples per second, we thus get one wide phase every 5592.4 seconds, or a full sequence repeat every 11184.8 sec, which is 3.1 hours. That's as close as you can get to a "perfect" 8000 Hz square wave with this system, if you require that the edges "snap" from high to low or low to high between samples.
Other frequencies can be much worse. At 8001 Hz the sequence repeat, or "jitter" period, is only 0.3333793 seconds. This means a jitter frequency of 2.9995864 Hz, which is plainly audible as a faint ticking noise superimposed on the sound.
In general, entering any frequency that would have fit the original "perfect" SampleRate / (2 * N) formula will result in a very close actual frequency, with a very long jitter period.
You can use the Jitter_Tbl macro included with Daqarta to generate a table of frequencies and jitter values at all even SampleRate divisors from 2 to 1024. This may allow you to optimize for certain square wave frequencies and sample rates.
The Square Wave dialog provides readouts of the calculated Jitter Frequency and Jitter Period. You can adjust the Square Wave Freq control (a duplicate of the main Tone Frequency) to see and hear the effects in real time. For an 8000 Hz square wave you see a stable, solid-looking display, while at 8001 you see it jittering back and forth. (The X-Axis eXpand button on the toolbar, together with the eXpand Max and Min controls at the top of the X-Axis control dialog, can show the back-and-forth motion of the waveform more clearly.)
The auditory effect is more pronounced at lower frequencies. A 1000 Hz square wave (actually 1000.00003) has a jitter period of 1398.1 seconds, which is hard to detect. But as you raise or lower the frequency you will clearly hear a changing "difference tone" whose frequency is not reflected in the Jitter Frequency value. As you continue to move the square wave frequency in the same direction, the difference tone moves up and down in pitch like an aliased harmonic, which you can see by switching the display to Spectrum mode.
Now toggle from Snap to Interpolate and the difference tone is no longer audible, even though the spectrum still shows moving aliases. (The Snap Jitter Freq and Snap Jitter Period displays are greyed out in Interpolate mode, but they are not disabled. They always show the same computed jitter for the current Square Wave Freq, whether in Snap or Interpolate mode.)
Interpolate mode uses softer edge transitions to reduce jitter. For example, if the rising transition from -100% to +100% is computed to ideally arrive halfway between the current sample and the next, the interpolated output value will be 0... halfway between -100% and +100%. If the ideal edge is only a quarter of the way to the next sample, the edge value would be +50%, and so on.
To see the difference visually, load the Default.GEN Generator setup and toggle it on. (You may want to reduce or mute the output; hit the F9 key to open the volume control dialog.)
Now click the Left Waveform Controls button to open the Left Stream 0 dialog, click on the Wave button, and set the type to Square. This will open the Square dialog with the default Snap mode active. Set the Square Frequency (actually the same as Tone Freq in the main Stream dialog) to 1000 Hz. Note that an exact 1000 Hz would give a 'perfect' square wave with N=24 in the SampleRate / (2 * N) formula; the actual frequency will be 1000.00003 Hz with a jitter period of 1398.1 seconds, so there will be no audible or visible jitter.
Now set 1000.2 Hz. With X-Axis eXpand off, you'll see the edges of the square jittering from side to side. The amount is small, only an occasional single sample, so it's not noticeable in a simple screen capture. The image below is a superposition of two captures, one in green and one in red, that shows the extent of the jitter. It appears to be mostly just alternating green and red lines because without X-Axis eXpand, two lines that are a single sample apart are less than one pixel apart here.
Next, set eXpand to cover 4.8 to 5.2 msec. Each sample period is 20.833 microsecond (1/48000 Hz), which is about 40% of a major X division of 50 microseconds. Daqarta "connects the dots" to show a continuous plot, so an "instantaneous" snap appears as a sloping line from -100% to +100%. With two traces (both green) superimposed below, you can see that the entire edge shifts by one sample, between starting or ending on 5.00 msec. Note that this is where we would expect to see a stable edge if the frequency was exactly 1000.0 Hz.
Now toggle from Snap to Interpolate. With eXpand off you see stable positions of the peaks, but there is a small jitter around the zero crossings. Unlike Snap mode, which had only vertical edges, here there are many intermediate zero-crossing points. You can see them as a changing pattern of tiny offsets of the center section of the edges, where the height of that offset varies over time. This is evident on a live display, but can still be seen faintly on a screen capture. To make it more obvious, below we show a superposition of green and red traces, as previously shown for Snap mode:
With eXpand active you can see varying 'kinks' at the edge, instead of the shifting edge seen for Snap. Below we show two of the many constantly-changing kink positions for the same edge:
You can make "perfect" jitter-free square (or other rectangular) waves using Burst. The idea is to apply Burst to a constant DC level, such that the burst envelope itself becomes the output waveform. By setting Rise and Fall to 0, the edges will be perfectly sharp. By setting Cycle to be exactly twice the High duration, the wave will be perfectly square.
This method only allows frequencies that follow the SampleRate / (2 * N) rule, but it is not limited to SampleRate / N^2 like the phase accumulator used by the normal Square Wave.
Leave the Wave type set to Sine, then set Tone Freq to 0, which will give a flat (DC) line at 0 volts because the sine of zero degrees is zero. Now set Phase to 90 degrees, and the DC level will jump to maximum, which is the default 100% Level setting.
Click on the Burst button to open its dialog, then toggle Burst On. The display will roll until you toggle Train Sync on as well. You'll see a very strange 'rounded gear tooth' shape due to the default Burst settings.
Now set Rise and Fall to 0. Leave the High value at 128 samples, and Cycle at 256, and you will see a perfect unipolar square wave. (There may appear to be kinks in the edges due to undithered graphics, but these will vanish if you use X-Axis eXpand.)
One drawback to the Burst method is that it's rather awkward to change frequencies, since you have to set both Cycle and High values. Of course, you also have to compute the values to set, namely High = SampleRate / (2 * F), where High is in samples and F is the desired frequency in Hz. Then you double this value to get the Cycle setting. (You can also set the Burst units from Smpls to sec and use High = 1 / (2 * F).)
Despite these inconveniences, this is the best approach when you want to set a particular fixed-frequency square wave that conforms to the SampleRate / (2 * N) rule, especially at extremely low frequencies. For example, if you want the wave to have a 3 second period, using the normal Square wave would require entering a value of one-third Hz as the Tone Frequency. The resolution of the control is 5 decimal places, and the conversion from decimal to binary and back results in 0.33331 Hz. Using the Frequency Counter in msec mode, this gives a period of 3000.217 msec. The next-higher Tone Frequency you can set is 0.33340, which gives 2999.413 msec.
But using the Burst approach you compute High = 72000 and Cycle = 144000 samples and you get a period of exactly 3 seconds, verified using the Frequency Counter with up to the maximum of 9 decimal places.
Curiously, you can also use the Burst method to get precision sine waves at ultra-low frequencies. Set Burst Shape to 1 (pure cosine), then set High to 0 and set Rise and Fall each to half of the desired Cycle.
See also Wave Dialog
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