CINXE.COM
jscwlib - JavaScript CW (Morse Code) generator (Web Audio API)
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <base href="//fkurz.net/ham/jscwlib.html"> <title>jscwlib - JavaScript CW (Morse Code) generator (Web Audio API)</title> <meta name="keywords" lang="en" content="morse code, morse generator, morse sound generator, morse javascript"> <link rel="stylesheet" type="text/css" href="/fkurz.css"> <link href="/dj5cw.xml?filter=jscwlib" type="application/atom+xml" rel="alternate" title="jscwlib newsfeed"> <style> .container { display: inline-grid; grid-template-columns: auto auto; grid-gap: 5px; } </style> </head> <body> <h1>jscwlib - JavaScript Morse Code Library</h1> <hr> <nav> <a href="//fkurz.net/">Fabian Kurz</a> → <a href="/ham/">Ham Radio</a> → <a class="navself" href="/ham/jscwlib.html">jscwlib</a> </nav> <hr> <h2>Status</h2> <dl> <dt><strong>2024-April-13</strong></dt><dd>Release v0.3.0. Various bug fixes, extend character sets, improvements in usability.</dd> <dt><strong>2022-March-20</strong></dt><dd>Release v0.2.2. Added Arabic characters and some more improvements - see <a href="https://git.fkurz.net/dj1yfk/jscwlib/commits/branch/master">commit history!</a></dd> <dt><strong>2021-April-6</strong></dt><dd>Release v0.2.1. Various small improvements - see <a href="https://git.fkurz.net/dj1yfk/jscwlib/commits/branch/master">commit history!</a></dd> <dt><strong>2020-July-6</strong></dt><dd>Release v0.2.0. Added Japanese Wabun code (tnx JE1TRV). Allow changing frequency while playing. Implement command |W for extra word spacing. Some small bug fixes.</dd> <dt><strong>2020-May-15</strong></dt><dd>Release v0.1.0.</dd> <dt><strong>2020-April-24</strong></dt><dd>Website created. No release yet - very preliminary but working code in git.</dd> </dl> <hr> <h2>Introduction</h2> <p><em>jscwlib</em> is a JavaScript library that generates Morse code (sound and optional graphical output) in the browser. It can easily be embedded in websites. It is developed for <a href="https://lcwo.net/">LCWO</a>, but since it may be very useful for other purposes, it's available as a separate library.</p> <p>jscwlib works with current versions of Firefox, Chrome, Edge, Opera and Safari, using the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API">Web Audio API</a>. For browsers that do not support the Web Audio API (like the Internet Explorer), there's a fall-back to the <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/audio">Embed Audio element</a>.</p> <h2>Example usage</h2> <div class="container"> <div>Live Result (change the text if you wish)</div> <div>Code</div> <div style="color:black;background-color:#ffffff;border:1px solid #000000;"> <script src="https://fkurz.net/ham/jscwlib/src/jscwlib.js"></script> <div id="player"></div> <script> var m = new jscw({"wpm": 25}); m.setVolume(0.5); m.setText("hello cze艣膰 锌褉懈胁褨褌 <do>銇娿伅銈堛亞<sn>"); m.renderPlayer('player', m); function sync() { console.log("SYNC"); var txt = document.getElementById('ta').value; txt = txt.replace(/(?:\r\n|\r|\n)/g, " "); m.setText(txt); txt = txt.replace(/\"/g, '\\"'); document.getElementById('txt').textContent = txt; document.getElementById('wpm').textContent = m.wpm; } m.onParamChange = sync; </script> <textarea id='ta' style="margin:10px;" onkeyup="sync(this.value);" cols="25" rows="5">hello cze艣膰 锌褉懈胁褨褌 <do>銇娿伅銈堛亞<sn></textarea> </div> <div style="color:white;background-color:black;border:1px solid #000000;"> <pre><!DOCTYPE html> <script src="https://fkurz.net/ham/jscwlib/src/jscwlib.js"></script> <div id="player"></div> <script> var m = new jscw({"wpm": <span id='wpm'>25</span>}); m.setText("<span id='txt'>hello cze艣膰 锌褉懈胁褨褌 <do>銇娿伅銈堛亞<sn></span>"); m.renderPlayer('player', m); </script> </pre> </div> </div> <p>Note that browsers typically only play sound if it was created by a keyboard/mouse/touch event, therefore the need to press a button to start it.</p> <p>Live examples: <a href="jscwlib/example/min_example.html">Minimum example</a> (above), <a href="jscwlib/example/pileup.html">Pileup</a>, <a href="jscwlib/example/jscwtest.html">Oscilloscope, visualisation of CW timing</a>, <a href="jscwlib/example/radioactivity.html">radioactivity</a>.</p> <h2>Constructor</h2> <dl> <dt>new jscw(params)</dt> <dd><code>params</code> is an <em>optional</em> object containing initial settings corresponding to the variables that you can later also set by the methods listed below.<br>Example: <code>var m = new jscw({"wpm": 40, "freq": 700, "text": "Hello"});</code></dd> </dl> <h2>Methods</h2> <dl> <dt>init()</dt> <dd>Initialize the player (optional - will be called internally if not done by the user).</dd> <dt>setWpm(x)</dt> <dd>Sets the character speed to <code>x</code> words per minute.</dd> <dt>setEff(x)</dt> <dd>Sets the effective speed to <code>x</code> words per minute. If it's equal, higher than the character speed or zero, this parameter is ignored. Otherwise the spaces between the characters are stretched to achieve the effective speed with a higher character speed.</dd> <dt>setReal(bool)</dt> <dd>When true, generate code with <em>real</em> character speed, not PARIS timing.</dd> <dt>setEws(n)</dt> <dd>Add extra word spacing of <em>n</em> × the normal word space.</dd> <dt>setFreq(x)</dt> <dd>Set the tone frequency to <code>x</code> Hertz.</dd> <dt>setFilter(f)</dt> <dd>Set the cutoff-frequency of the low-pass filter that shapes the generated tone to <code>f</code> Hz.</dd> <dt>setQ(q)</dt> <dd>Set low-pass filter Q to <code>q</code>.</dd> <dt>setText(text)</dt> <dd>Set <code>text</code> to be played. Does not start playing yet. Text may contain Latin, Cyrillic, Arabic, Hebrew, Greek or Japanese characters. Additional character sets can easily be implemented.</dd> <dt>setTextB64(text)</dt> <dd>See <code>setText</code>, but the text has to be base64 encoded.</dd> <dt>setVolume(v)</dt> <dd>Sets the volume to <code>v</code> (0 .. 100).</dd> <dt>play(text)</dt> <dd>Plays <code>text</code> (if not set: the last text set by <code>play</code> or <code>setText</code> in Morse code, with the parameters currently set. The text may contain commands to change parameters on the fly: <ul> <li><code>|wXX</code> sets the character speed to <code>XX</code> WpM,</li> <li><code>|eXX</code> sets the effective speed to <code>XX</code> WpM,</li> <li><code>|WXX</code> sets the extra word space to <code>XX</code>,</li> <li><code>|fXXX</code> sets the tone frequency to <code>XXX</code> Hz,</li> <li><code>|vX</code> sets the volume to <code>X</code> (0.0 - 1.0),</li> <li><code>|SXXXX</code> inserts a silence period of <code>XXXX</code> milliseconds.</li> </ul> Furthermore, anything enclosed in angle brackets will be sent without letter spaces (like a prosign), for example <code><SK></code> will generate <code>...-.-</code> </dd> <dt>pause()</dt> <dd>Pauses or resumes the current text.</dd> <dt>stop()</dt> <dd>Stops the current text.</dd> <dt>setStartDelay(s)</dt> <dd>Delays the actual text by <code>s</code> seconds, after play() is invoked.</dd> <dt>setPrefix(p)</dt> <dd>Sets the transmission prefix to <code>p</code>. Each transmission is prefixed with this string (e.g. <code>VVV = </code>), but it does not influence the calculation of speed.</dd> <dt>setSuffix(s)</dt> <dd>Sets the transmission suffix to <code>s</code>. Each transmission is suffixed refixed with this string (e.g. <code> +</code>), but it does not influence the calculation of speed.</dd> <dt>enablePS(b)</dt> <dd>When set to true, enable the transmission of the prefix and suffix.</dd> <dt>getLength()</dt> <dd>Get the total play time of the current text in seconds.</dd> <dt>getRemaining()</dt> <dd>Get the remaining play time of the current text in seconds.</dd> <dt>getTime()</dt> <dd>Get the current time within the played text in seconds.</dd> <dt>draw(c)</dt> <dd>Draws the last generated Morse code as a timing diagram on a HTML5 canvas (<code>c</code>).</dd> <dt>renderPlayer(div, obj)</dt> <dd>Renders a player UI (with progress bar and buttons for Stop, Play/Pause and the possibility to change CW parameters) for player <code>obj</code> into a <code>div</code>.</dd> <dt>oscilloscope(c)</dt> <dd>Draws the currently generated waveform on canvas <code>c</code>.</dd> </dl> <h3>Events / Callbacks</h3> <dl> <dt>onParamChange<dt> <dd>A user defined function that will be invoked each time the user changed parameters if the player. E.g.: <pre><code>m.onParamChange = function () { alert("Parameters changed"); } </code></pre></dd> <dt>onPlay<dt> <dd>A user defined function that will be invoked each time the player is started. E.g.: <pre><code>m.onPlay = function () { alert("Player started"); } </code></pre></dd> </dl> <dt>onFinished<dt> <dd>A user defined function that will be invoked each time the player stopped playing. E.g.: <pre><code>m.onFinished = function () { alert("Player stopped"); } </code></pre></dd> <dt>onCharacterPlay</dt> <dd>A user defined function that will be invoked each time a character is played. <a href="jscwlib/example/oncharacterplay.html">See example usage</a>. E.g.: <pre><code>m.onCharacterPlay = function (c) { console.log(c); } </code></pre></dd> </dl> <hr> <h2>Download / Embedding</h2> <p>The latest version of the library can be found in the git repository: <a href="https://git.fkurz.net/dj1yfk/jscwlib/">https://git.fkurz.net/dj1yfk/jscwlib/</a>. It is published under the very liberal MIT license.</p> <p style="max-width: 90em;">You may directly embed the library into your own site by hot-linking to <a href="https://fkurz.net/ham/jscwlib/releases/jscwlib-0.3.0.js">https://fkurz.net/ham/jscwlib/releases/jscwlib-0.3.0.js</a> </p> <hr> <h2>Author</h2> <p><em>jscwlib</em> was written by Fabian Kurz, DJ5CW <<a href="mailto:fabian@fkurz.net" >fabian@fkurz.net</a>>. With contributions by <a href="https://github.com/qsantos">Quentin Santos</a> and <a href="https://github.com/Luci6fuge">Luci6fuge</a>.</p> <hr> <h2>Use cases</h2> <p>Here are a few real life examples where jscwlib is or can be used:</p> <ul> <li><a href="https://lcwo.net/">LCWO.net</a> uses jscwlib as the primary Morse generator</li> <li>You can embed jscwlib in <a href="https://apps.ankiweb.net/">Anki</a> cards (<a href="jscwlib/example/anki.html">template</a>)! (tnx Matt, KI5PGL)</li> <li>Some small neat CW trainers by <a href="https://ji1jdi.hatenablog.com/">JI1JDI</a> on his blog.</li> <li><a href="http://www.elkins.org/">K5JF's</a> Morse training site uses jscwlib.</li> <li><a href="https://morsle.fun/">Morsle</a> - a Wordle inspired Morse game by Remote Ham Radio/WW1X.</li> <li><a href="https://www.aa9pw.com/morsecode/test/">AA9PW Morse Code Generator</a> - generate various Morse code practice texts online.</li> <li><a href="http://k4jkg.atwebpages.com/radio/morse/CWmanna/">CW Manna</a> - listen to the full KJV Bible online (created by K4JKG).</li> <li><a href="https://yl3jd.fizioikskile.lv/qtc/">QTC trainer</a> - created by YL3JD</li> <li><a href="https://github.com/mgiugliano/morserunnerJS">MorseRunnerJS</a> - A clone of <a href="https://dxatlas.com/MorseRunner">MorseRunner</a> for the browser (under construction)</li> <li><a href="http://komugio.starfree.jp/sjmo/about.php">SJMO</a> - Study Japanese Morse Online</li> <li><a href="https://github.com/dancrew32/morsefire/">MorseFire</a> - A Firefox extension that plays highlighted text in Morse code</li> </ul> <h2>See also</h2> <p>Similar programs/apps/libraries:</p> <ul> <li><a href="https://github.com/numinos1/morse-player/">morse-player</a> by N7AST</li> </ul> <br> <hr> <nav> <a href="//fkurz.net/">Fabian Kurz</a> → <a href="/ham/">Ham Radio</a> → <a class="navself" href="/ham/jscwlib.html">jscwlib</a> </nav> <hr> Last modified: Monday, 20-May-2024 14:03:49 CEST </body> </html>