Generating audio Morse code

January 5, 2021    Article    734 words    4 mins read

This JavaScript code allows you to generate audio Morse code from a given string of text by using the Web Audio API. If you didn’t know, Morse code is a method used in telecommunication to encode text characters as standardized sequences of two different signal durations, called dots and dashes. Morse code is named after Samuel Morse, an inventor of the telegraph.

Web Audio API

The Web Audio API provides a powerful and versatile system for controlling audio on the Web, allowing developers to choose audio sources, add effects to audio, create audio visualizations, apply spatial effects (such as panning) and much more. Browser-compatibility is good (all browsers, bonus points for Firefox), except Internet Explorer, of course.

The Web Audio API involves handling audio operations inside an audio context, and has been designed to allow modular routing. Basic audio operations are performed with audio nodes, which are linked together to form an audio routing graph. Several sources — with different types of channel layout — are supported even within a single context. This modular design provides the flexibility to create complex audio functions with dynamic effects. Mozilla

Code

We start by defining the MORSE_CODES constant that will hold the characters and their Morse code representation.

const MORSE_CODES = {
	"A": ".-",		"B": "-...",	"C": "-.-.",	"D": "-..",		"E": ".",
	"F": "..-.",	"G": "--.",		"H": "....",	"I": "..",		"J": ".---",
	"K": "-.-",		"L": ".-..",	"M": "--",		"N": "-.",		"O": "---",
	"P": ".--.",	"Q": "--.-",	"R": ".-.",		"S": "...",		"T": "-",
	"U": "..-",		"V": "...-",	"W": ".--",		"X": "-..-",	"Y": "-.--",
	"Z": "--..",	"1": ".----",	"2": "..---",	"3": "...--",	"4": "....-",
	"5": ".....",	"6": "-....",	"7": "--...",	"8": "---..",	"9": "----.",
	"0": "-----",	".": ".-.-.-",	",": "--..--",	"?": "..--..",	"'": ".----.",
	"/": "-..-.",	"(": "-.--.",	")": "-.--.-",	"&": ".-...",	":": "---...",
	";": "-.-.-.",	"=": "-...-",	"+": ".-.-.",	"-": "-....-",	"_": "..--.-",
	"\"": ".-..-.",	"$": "...-..-",	"!": "-.-.--",	"@": ".--.-."
};

The AudioContext interface represents an audio-processing graph built from audio modules linked together, each represented by an AudioNode. We create an instance of it and assign it to our context variable.

let context = new (window.AudioContext || window.webkitAudioContext)();

The createOscillator() method of the BaseAudioContext interface creates an OscillatorNode, a source representing a periodic waveform. It basically generates a constant tone.

let oscillator = context.createOscillator();

The createGain() method of the BaseAudioContext interface creates a GainNode, which can be used to control the overall gain (or volume) of the audio graph.

let gain = context.createGain();

We set the frequency of oscillation in hertz (though the AudioParam returned is read-only, the value it represents is not) to 750. Also we should link our OscillatorNode and GainNode variables.

gain.gain.value = 0;
oscillator.frequency.value = 750;
oscillator.connect (gain);
let rate = 20;
let dot = 1.2 / rate;

The start() method of the OscillatorNode interface specifies the exact time to start playing the tone.

oscillator.start(0);
gain.connect(context.destination);

The play_char() function converts dots and dashes into audio.

function play_char (time, character) {
	for (let i = 0; i < character.length; i++) {
		switch (character[i]) {
			case '.':
				gain.gain.setValueAtTime(1.0, time);
				time += dot;
				gain.gain.setValueAtTime(0.0, time);
				break;
			case '-':
				gain.gain.setValueAtTime(1.0, time);
				time += 3 * dot;
				gain.gain.setValueAtTime(0.0, time);
				break;
		}
		time += dot;
	}
	return time;
};

The play() function takes one parameter, the text string we’re supposed to convert into audio Morse code.

function play (text) {
	let time = context.currentTime;
	text = text.toUpperCase();
	for (let i = 0; i < text.length; i++) {
		if (text[i] === ' ') {
			time += 3 * dot;
		} else if (MORSE_CODES[text[i]] !== undefined) {
			time = play_char(time, MORSE_CODES[text[i]]);
			time += 2 * dot;
		}
	}
	return time;
};

To wrap it up, call the play() function with the text you want converted into audio Morse code.

play('sos');

Demo

Options
Text
Output
Text

Download

Download the code above.

License

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.