Home | Programming Resources |     Share This Page
JavaScript Signal Generator / Spectrum Analyzer

A JavaScript-based signal generation / analysis utility

P. Lutus Message Page

Copyright © 2015, P. Lutus

Current Version: 1.7 (09.21.2015)

Introduction | Generator/Analyzer | Advanced Features
Revision History

(double-click any word to see its definition)


Introduction

This is the fourth Web-based signal generator I've written in the past ten years. Its three predecessors:

The first incarnation suffered from non-portability between platforms. The next try was better, certainly easier to write, but it had a similar issue — Python programs aren't easy to port between platforms. The third try was a Java program that, had it not been for the recent Java applet "Perfect Storm" debacle, would have ended the series and I and others would have the handy tool I wanted.

This new version has a time/frequency domain scope attached to the signal generator, so it's significantly better than its predecessors. It's written in JavaScript, which means it lives in a Web page — it can't be made into an app separate from a browser — but I don't see that as a serious objection.

Unfortunately, there's one drawback — Microsoft's older browsers can't run this generator/analyzer. If you own such a browser, the program will fail harmlessly, alert you and make a diplomatic suggestion. :)

The provided time/frequency domain spectrum analyzer is an efficient way to explore the spectra of various waveforms created by the generator — sine, square, triangle, sawtooth. For the record, here are the formal mathematical definitions for the non-sinusoidal waveforms this generator creates:

In the following equations, $\omega = 2 \pi f$, where $f$ = frequency.

Square Wave:

(1) $ \displaystyle \large y(t) = \frac{4 \sum\limits_{n=1}^\infty \frac{\sin{(\omega t(2n-1))}}{2n-1}}{\pi} $

Triangle Wave:

(2) $ \displaystyle \large y(t) = \frac{8 \sum\limits_{n=1}^\infty \frac{(-1)^{n+1} \sin{(\omega t (2n-1))}}{(2n-1)^2}} {\pi^2} $

Sawtooth Wave:

(3) $ \displaystyle \large y(t) = \frac{2 \sum\limits_{n=1}^\infty \frac{\sin{(\omega t)}}{n} }{\pi}$

The generator should be easy to learn and use — that was one of my goals. A knowledge of spectrum analysis can increase this tool's usefulness.

Note: Be sure to read the "Advanced Features" section below the main program panel.


Generator/Analyzer

Adjust the generator/analyzer's values by changing the sliders' positions, at first coarsely with your mouse or other pointing device. Then finer control over frequencies, sync trip point and display time/frequency range can be had using your keyboard's arrow keys and (on some advanced browsers) by spinning your mouse wheel while your mouse cursor rests within the numeric entry panes.

Your browser doesn't support the features this program requires.
0.00100.00
Time/Frequency scale:
Sync Trigger level:    Enable

Sync Trigger Source:

Signal Generator    Microphone  Domain: Time    Frequency
FFT Binsize: 512 1024 2048 4096 8192 16384 32768

Activate    Mute output audio |  Signal Source:    Signal Generator    Microphone

Signal Generator:

Properties:
Carrier: Gain: Frequency:
Modulation: Gain: Frequency:
Noise: Gain: Enable

Carrier waveform:

Sine Square Triangle Sawtooth

Modulation:

AM FM

Modulation Waveform:

Sine Square Triangle Sawtooth

Microphone:

Gain:
0.00

 


Advanced Features

FFT Binsize

This setting selects the array size for the Fast Fourier Transform algorithm and the time-domain scope display. High values improve spectral resolution but slow program response time. When displaying the frequency domain, the program's response time declines roughly as the square of the selected bin size.

The effect of this control is particularly noticeable when using the microphone input as a signal source. When displaying the time domain, smaller settings greatly improve the response rate to rapidy changing input. In exchange, when displaying the frequency domain, large settings improve resolution and show more spectrum detail.

Selectable Sync

Starting with Version 1.4, the analyzer can accept the system microphone as a signal source, and the sync trigger source can be set to use either the generator or the live input.

Why is this important? It allows the user to measure the frequency of live audio data sources with very high accuracy by comparing them to a known frequency standard (i.e. this program's signal generator). Here's how to set this up:

  • For "Signal Source," Select "Microphone". Your system will ask permission to access this resource.
  • For "Sync Trigger Source," select "Signal Generator".
  • Set the "Sync Trigger Level" to mid-range.
  • Set the analyzer domain to "Time".
  • Set the "Carrier" level to mid-range.
  • Set the "Modulation" level to zero.
  • Disable the noise source.
  • For carrier frequency, choose any frequency of interest, such as the expected frequency of a musical instrument.

With the above settings, the analyzer scope will display live microphone data but be synchronized to the generator's frequency. This means a live signal waveform, such as a musical instrument or a radio signal, that is not at the same frequency as the generator, will drift to the right or the left in proportion to the degree that it differs in frequency from the internal generator.

This method for comparing frequencies is exquisitely sensitive to small differences. As a test case, I set things up as described above and used a tuning fork as a live test signal. I set the internal generator to 440 Hz (my tuning fork's frequency) and positioned the tuning fork in front of the microphone. I saw right away that there was a significant difference between the tuning fork and the internally generated reference frequency. By carefully adjusting the internal generator until the waveform became stationary, I established that my 440 Hz tuning fork actually oscillates at 440.65 Hz, an error of 0.14%.

Here are some useful hints:

  • A live microphone signal that's at exactly the same frequency as the generator will show a stationary waveform — drifting neither to the left or right.
  • If the live signal is higher in frequency than the internal generator, the waveform will drift to the left.
  • If the live signal is lower in frequency than the internal generator, the waveform will drift to the right.
  • To estimate the error beween a signal and the generator, time the displayed rate of drift — if it requires one second for the displayed waveform to drift by one full cycle, that represents an error of one Hertz.
  • To establish the exact frequency of a live signal, adjust the generator's frequency until the displayed waveform is stationary.
  • To change the frequency of a live signal, for example a musical instrument, tune the instrument until the displayed waveform is stationary.
  • To use this feature routinely, create a table of frequencies of interest, and set the generator to each frequency as required while tuning your instrument.

For example, here is a list of guitar string frequencies, starting with the highest-frequency string (source):

String String name Frequency Hz Scientific pitch name
1 (E) 329.63 E4
2 (B) 246.94 B3
3 (G) 196.00 G3
4 (D) 146.83 D3
5 (A) 110.00 A2
6 (E) 82.41 E2

The Mathematical Way

Here's a more general approach to converting musical notes to corresponding frequencies in Hertz, one that relies on mathematics.

  • Let's start by establishing a note index that's equal to zero at Middle A (440 Hz).
  • If we decrease the index by one, we move down in frequency by one semitone in the chromatic scale — to G♯ or A♭.
  • If we increase the index by one, we move up in frequency by one semitone — to A♯ or B♭.
  • If we increase or decrease the index by 12, we move up or down an octave.
  • The relationship between index number and frequency is unlimited — it extends up and down past the range of any imaginable musical instruments.

The mathematical equation that converts index numbers to frequencies is:

(1) $ \large f = 440 \times 2^{\frac{n}{12}} $

Where:

  • $f$ = frequency in Hertz
  • $n$ = index number as explained above, 0 = middle A.

Generator Accuracy

Readers may wonder, "How accurate is the internal generator? Is it a reliable frequency standard?" To answer this question with respect to my development computer, I compared this program's generated frequencies with radio signals providing known frequencies of high accuracy (for example, the WWV radio signals maintained by the National Institute of Standards and Technology), and this test showed that the generator's accuracy is very high — much higher than traditional standards like tuning forks. Most modern computers will turn out to have an audio generator/detector of comparable accuracy.

In another test, I ran one copy of this program set up as a generator, driving the machine's speakers with a 440 Hz test tone, and on a separate computer I ran another copy set up as explained above, configured to detect small frequency discrepancies at the same frequency. To a very high standard of precision, the two machines agreed.

Revision History
  • 09.21.2015 Version 1.7. Cleaned up some discrepancies in the analyzer display and the method for white noise generation.
  • 09.20.2015 Version 1.6. Optimized the graphic rendering methods for better display appearance.
  • 09.19.2015 Version 1.5. Added an FFT binsize selector control, changed default FFT binsize for faster program response to microphone input, changed program layout for better readability, added a flyout time/frequency/amplitude indicator that follows the mouse cursor in the scope display.
  • 09.18.2015 Version 1.4. Added live microphone signal source, configured analyzer so the sync trigger source can be either the generator or the live microphone input. Read the "Advanced Features" section above to learn how to use this feature.
  • 09.15.2015 Version 1.3. Improved scale of scope and controls. Added mute checkbox, enabled by default, that allows analysis scope to function without output audio.
  • 09.14.2015 Version 1.2. Fixed JavaScript bug that prevented operation in Microsoft Edge (Microsoft Internet Explorer can't run this program).
  • 08.30.2015 Version 1.1. Improved the interface, changed default settings.
  • 08.27.2015 Version 1.0. Initial Public Release.

Home | Programming Resources |     Share This Page