This commit is contained in:
Ingy döt Net 2013-04-10 21:29:02 -07:00
parent 764da6cbbb
commit db842d013d
19005 changed files with 197040 additions and 7 deletions

View file

@ -0,0 +1,6 @@
[[wp:Morse_code|Morse code]] is one of the simplest and most versatile methods of telecommunication in
existence. It has been in use for more than 160 years — longer than any other electronic encoding system.
The task: Send a string as audible morse code to an audio device (e.g., the PC speaker).
As the standard Morse code does not contain all possible characters, you may either ignore unknown characters in the file, or indicate them somehow (e.g. with a different pitch).

View file

@ -0,0 +1,4 @@
---
note: Temporal media
requires:
- Sound

View file

@ -0,0 +1,24 @@
BEGIN { FS="";
m="A.-B-...C-.-.D-..E.F..-.G--.H....I..J.---K-.-L.-..M--N-.";
m=m "O---P.--.Q--.-R.-.S...T-U..-V...-W.--X-..-Y-.--Z--.. ";
}
{ for(i=1; i<=NF; i++)
{
c=toupper($i); n=1; b=".";
while((c!=b)&&(b!=" ")) { b=substr(m,n,1); n++; }
b=substr(m,n,1);
while((b==".")||(b=="-")) { printf("%s",b); n++; b=substr(m,n,1); }
printf("|");
}
printf("\n");
}
usage: awk -f morse.awk [inputfile]
sos sos titanic
...|---|...||...|---|...||-|..|-|.-|-.|..|-.-.|

View file

@ -0,0 +1,40 @@
package Morse is
type Symbols is (Nul, '-', '.', ' ');
-- Nul is the letter separator, space the word separator;
Dash : constant Symbols := '-';
Dot : constant Symbols := '.';
type Morse_Str is array (Positive range <>) of Symbols;
pragma Pack (Morse_Str);
function Convert (Input : String) return Morse_Str;
procedure Morsebeep (Input : Morse_Str);
private
subtype Reschars is Character range ' ' .. 'Z';
-- restricted set of characters from 16#20# to 16#60#
subtype Length is Natural range 1 .. 5;
subtype Codes is Morse_Str (Length);
-- using the current ITU standard with 5 signs
-- only alphanumeric characters are taken into consideration
type Codings is record
L : Length;
Code : Codes;
end record;
Table : constant array (Reschars) of Codings :=
('A' => (2, ".- "), 'B' => (4, "-... "), 'C' => (4, "-.-. "),
'D' => (3, "-.. "), 'E' => (1, ". "), 'F' => (4, "..-. "),
'G' => (3, "--. "), 'H' => (4, ".... "), 'I' => (2, ".. "),
'J' => (4, ".--- "), 'K' => (3, "-.- "), 'L' => (4, ".-.. "),
'M' => (2, "-- "), 'N' => (2, "-. "), 'O' => (3, "--- "),
'P' => (4, "--.- "), 'Q' => (4, "--.- "), 'R' => (3, ".-. "),
'S' => (3, "... "), 'T' => (1, "- "), 'U' => (3, "..- "),
'V' => (4, "...- "), 'W' => (3, ".-- "), 'X' => (4, "-..- "),
'Y' => (4, "-.-- "), 'Z' => (4, "--.. "), '1' => (5, ".----"),
'2' => (5, "..---"), '3' => (5, "...--"), '4' => (5, "....-"),
'5' => (5, "....."), '6' => (5, "-...."), '7' => (5, "--..."),
'8' => (5, "---.."), '9' => (5, "----."), '0' => (5, "-----"),
others => (1, " ")); -- Dummy => Other characters do not need code.
end Morse;

View file

@ -0,0 +1,72 @@
with Ada.Strings.Maps, Ada.Characters.Handling, Interfaces.C;
use Ada, Ada.Strings, Ada.Strings.Maps, Interfaces;
package body Morse is
Dit, Dah, Lettergap, Wordgap : Duration; -- in seconds
Dit_ms, Dah_ms : C.unsigned; -- durations expressed in ms
Freq : constant C.unsigned := 1280; -- in Herz
Morse_Sequence : constant Character_Sequence :=
" ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
Morse_charset : constant Character_Set := To_Set (Morse_Sequence);
function Convert (Input : String) return Morse_Str is
Cap_String : constant String := Characters.Handling.To_Upper (Input);
Result : Morse_Str (1 .. 7 * Input'Length); -- Upper Capacity
First, Last : Natural := 0;
Char_code : Codings;
begin
for I in Cap_String'Range loop
if Is_In (Cap_String (I), Morse_charset) then
First := Last + 1;
if Cap_String (I) = ' ' then
Result (First) := ' ';
Last := Last + 1;
else
Char_code := Table (Reschars (Cap_String (I)));
Last := First + Char_code.L - 1;
Result (First .. Last) := Char_code.Code (1 .. Char_code.L);
Last := Last + 1;
Result (Last) := Nul;
end if;
end if;
end loop;
if Result (Last) /= ' ' then
Last := Last + 1;
Result (Last) := ' ';
end if;
return Result (1 .. Last);
end Convert;
procedure Morsebeep (Input : Morse_Str) is
-- Beep is not portable : adapt to your OS/sound board
-- Implementation for Windows XP / interface to fn in stdlib
procedure win32xp_beep
(dwFrequency : C.unsigned;
dwDuration : C.unsigned);
pragma Import (C, win32xp_beep, "_beep");
begin
for I in Input'Range loop
case Input (I) is
when Nul =>
delay Lettergap;
when Dot =>
win32xp_beep (Freq, Dit_ms);
delay Dit;
when Dash =>
win32xp_beep (Freq, Dah_ms);
delay Dit;
when ' ' =>
delay Wordgap;
end case;
end loop;
end Morsebeep;
begin
Dit := 0.20;
Lettergap := 2 * Dit;
Dah := 3 * Dit;
Wordgap := 4 * Dit;
Dit_ms := C.unsigned (Integer (Dit * 1000));
Dah_ms := C.unsigned (Integer (Dah * 1000));
end Morse;

View file

@ -0,0 +1,5 @@
with Morse; use Morse;
procedure Morse_Tx is
begin
Morsebeep (Convert ("Science sans Conscience"));
end Morse_Tx;

View file

@ -0,0 +1,139 @@
TestString := "Hello World! abcdefg @\;" ; Create a string to be sent with multiple caps and some punctuation
MorseBeep(teststring) ; Beeps our string after conversion
return ; End Auto-Execute Section
MorseBeep(passedString)
{
StringLower, passedString, passedString ; Convert to lowercase for simpler checking
loop, parse, passedString ; This loop stores each character in A_loopField one by one
{
If (A_LoopField = " ")
morse .= " " ; Add a long delay between words (5*e)
If (A_LoopField = "a")
morse .=".- " ; Morse is a local variable
If (A_LoopField = "b")
morse .="-... " ; .= is the simple way of appending to a string
If (A_LoopField = "c")
morse .="-.-. " ; we add a space after every character to pause for e
If (A_LoopField = "d")
morse .="-.. "
If (A_LoopField = "e")
morse .=". "
If (A_LoopField = "f")
morse .="..-. "
If (A_LoopField = "g")
morse .="--. "
If (A_LoopField = "h")
morse .=".... "
If (A_LoopField = "i")
morse .=".. "
If (A_LoopField = "j")
morse .=".--- "
If (A_LoopField = "k")
morse .="-.- "
If (A_LoopField = "l")
morse .=".-.. "
If (A_LoopField = "m")
morse .="-- "
If (A_LoopField = "n")
morse .="-. "
If (A_LoopField = "o")
morse .="--- "
If (A_LoopField = "p")
morse .=".--. "
If (A_LoopField = "q")
morse .="--.- "
If (A_LoopField = "r")
morse .=".-. "
If (A_LoopField = "s")
morse .="... "
If (A_LoopField = "t")
morse .="- "
If (A_LoopField = "u")
morse .="..- "
If (A_LoopField = "v")
morse .="...- "
If (A_LoopField = "w")
morse .=".-- "
If (A_LoopField = "x")
morse .="-..- "
If (A_LoopField = "y")
morse .="-.-- "
If (A_LoopField = "z")
morse .="--.. "
If (A_LoopField = "!")
morse .="---. "
If (A_LoopField = "\")
morse .=".-..-. "
If (A_LoopField = "$")
morse .="...-..- "
If (A_LoopField = "'")
morse .=".----. "
If (A_LoopField = "(")
morse .="-.--. "
If (A_LoopField = ")")
morse .="-.--.- "
If (A_LoopField = "+")
morse .=".-.-. "
If (A_LoopField = ",")
morse .="--..-- "
If (A_LoopField = "-")
morse .="-....- "
If (A_LoopField = ".")
morse .=".-.-.- "
If (A_LoopField = "/")
morse .="-..-. "
If (A_LoopField = "0")
morse .="----- "
If (A_LoopField = "1")
morse .=".---- "
If (A_LoopField = "2")
morse .="..--- "
If (A_LoopField = "3")
morse .="...-- "
If (A_LoopField = "4")
morse .="....- "
If (A_LoopField = "5")
morse .="..... "
If (A_LoopField = "6")
morse .="-.... "
If (A_LoopField = "7")
morse .="--... "
If (A_LoopField = "8")
morse .="---.. "
If (A_LoopField = "9")
morse .="----. "
If (A_LoopField = ":")
morse .="---... "
If (A_LoopField = ";")
morse .="-.-.-. "
If (A_LoopField = "=")
morse .="-...- "
If (A_LoopField = "?")
morse .="..--.. "
If (A_LoopField = "@")
morse .=".--.-. "
If (A_LoopField = "[")
morse .="-.--. "
If (A_LoopField = "]")
morse .="-.--.- "
If (A_LoopField = "_")
morse .="..--.- "
} ; ---End conversion loop---
Freq=1280 ; Frequency between 37 and 32767
e=120 ; element time in milliseconds
; . is one e, - is 3, and a space is a pause of one e
loop, parse, morse
{
if (A_LoopField = ".")
SoundBeep, Freq, e ;Format: SoundBeep, frequency, duration
If (A_LoopField = "-")
SoundBeep, Freq, 3*e ; duration can be an expression
If (A_LoopField = " ")
Sleep, e ; Above, each character is followed by a space, and literal
} ; spaces are extended. Sleep pauses the script.
} ; ---End Function Morse---

View file

@ -0,0 +1,60 @@
DECLARE SUB player (what AS STRING)
'this determines the length of the notes
'lower number = longer duration
CONST noteLen = 16
DIM tones(62) AS STRING
FOR n% = 0 TO 62
READ tones(n%)
NEXT n%
'set up the playing system
PLAY "t255o4l" + LTRIM$(STR$(noteLen))
LINE INPUT "String to convert to Morse code: "; x$
FOR n% = 1 TO LEN(x$)
c$ = UCASE$(MID$(x$, n%, 1))
PLAY "p" + LTRIM$(STR$(noteLen / 2)) + "."
SELECT CASE UCASE$(c$)
CASE " "
'since each char is effectively wrapped with 6 p's, we only need to add 1:
PLAY "p" + LTRIM$(STR$(noteLen))
PRINT " ";
CASE "!" TO "_"
PRINT tones(ASC(c$) - 33); " ";
player tones(ASC(c$) - 33)
CASE ELSE
PRINT "# ";
player "#"
END SELECT
PLAY "p" + LTRIM$(STR$(noteLen / 2)) + "."
NEXT n%
PRINT
'all the Morse codes in ASCII order, from "!" to "_"
DATA "-.-.--", ".-..-.", "#", "...-..-", "#", ".-...", ".----.", "-.--."
DATA "-.--.-", "#", ".-.-.", "--..--", "-....-", ".-.-.-", "-..-.", "-----"
DATA ".----", "..---", "...--", "....-", ".....", "-....", "--...", "---.."
DATA "----.", "---...", "-.-.-.", "#", "-...-", "#", "..--..", ".--.-.", ".-"
DATA "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-"
DATA ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-"
DATA "...-", ".--", "-..-", "-.--", "--..", "#", "#", "#", "#", "..--.-"
SUB player (what AS STRING)
FOR i% = 1 TO LEN(what)
z$ = MID$(what, i%, 1)
SELECT CASE z$
CASE "."
o$ = "g"
CASE "-"
o$ = "g" + LTRIM$(STR$(noteLen / 2)) + "."
CASE ELSE
o$ = "<<<<c>>>>"
END SELECT
PLAY o$
PLAY "p" + LTRIM$(STR$(noteLen))
NEXT i%
END SUB

View file

@ -0,0 +1,26 @@
*TEMPO 8
DIM morse$(63)
FOR char% = 0 TO 63 : READ morse$(char%) : NEXT char%
PROCmorse("The five boxing wizards jump quickly.")
END
DEF PROCmorse(text$)
LOCAL element%, index%, char&, morse$
FOR index% = 1 TO LEN(text$)
char& = ASC(MID$(text$,index%)) AND &7F
IF char& < 32 char& = 32
IF char& > 95 char& -= 32
morse$ = morse$(char&-32)
FOR element% = 1 TO LEN(morse$)
SOUND 1, -15, 148, VAL(MID$(morse$,element%,1))
SOUND 1, -15, 0, 1
NEXT element%
SOUND 1, -15, 0, 2
NEXT index%
ENDPROC
DATA 00,313133,131131,6,1113113,6,13111,133331,31331,313313,6,13131,331133,311113,131313,31131
DATA 33333,13333,11333,11133,11113,11111,31111,33111,33311,33331,333111,313131,6,31113,6,113311
DATA 133131,13,3111,3131,311,1,1131,331,1111,11,1333,313,1311,33,31,333
DATA 1331,3313,131,111,3,113,1113,133,3113,3133,3311,6,6,6,6,113313

View file

@ -0,0 +1,78 @@
/*
David Lambert, 2010-Dec-09
filter producing morse beep commands.
build:
make morse
use:
$ echo tie a. | ./morse
beep -n -f 440 -l 300 -D 100 -n -D 200 -n -f 440 -l 100 -D 100 -n -f 440 -l 100 -D 100 -n -D 200 -n -f 440 -l 100 -D 100 -n -D 200 -n -D 400 -n -f 440 -l 100 -D 100 -n -f 440 -l 300 -D 100 -n -D 200 -n -f 440 -l 100 -D 100 -n -f 440 -l 300 -D 100 -n -f 440 -l 100 -D 100 -n -f 440 -l 300 -D 100 -n -f 440 -l 100 -D 100 -n -f 440 -l 300 -D 100 -n -D 200 -n -D 400 -n -D 400
bugs:
What is the space between letter and punctuation?
Demo truncates input lines at 71 characters or so.
*/
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BIND(A,L,H) ((L)<(A)?(A)<(H)?(A):(H):(L))
/*
BIND(-1,0,9) is 0
BIND( 7,0,9) is 7
BIND(77,0,9) is 9
*/
char
/* beep args for */
/* dit dah extra space */
dih[50],dah[50],medium[30],word[30],
*dd[2] = {dih,dah};
const char
*ascii = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,?'!/()&:;=+-_\"$@",
*itu[] = {
"13","3111","3131","311","1","1131","331","1111","11","1333","313","1311","33","31","333","1331","3313","131","111","3","113","1113","133","3113","3133","3311","33333","13333","11333","11133","11113","11111","31111","33111","33311","33331","131313","331133","113311","133331","313133","31131","31331","313313","13111","333111","313131","31113","13131","311113","113313","131131","1113113","133131"
};
void append(char*s,const char*morse) {
for (; *morse; ++morse)
strcat(s,dd['3'==*morse]);
strcat(s,medium);
}
char*translate(const char*i,char*o) {
const char*pc;
sprintf(o,"beep");
for (; *i; ++i)
if (NULL == (pc = strchr(ascii,toupper(*i))))
strcat(o,word);
else
append(o,itu[pc-ascii]);
strcat(o,word);
return o;
}
int main(int ac,char*av[]) {
char
sin[73],sout[100000];
int
dit = 100;
if (1 < ac) {
if (strlen(av[1]) != strspn(av[1],"0123456789"))
return 0*fprintf(stderr,"use: %s [duration] dit in ms, default %d\n",*av,dit);
dit = BIND(atoi(av[1]),1,1000);
}
sprintf(dah," -n -f 440 -l %d -D %d",3*dit,dit);
sprintf(dih," -n -f 440 -l %d -D %d",dit,dit);
sprintf(medium," -n -D %d",(3-1)*dit);
sprintf(word," -n -D %d",(7-(3-1)-1)*dit);
while (NULL != fgets(sin,72,stdin))
puts(translate(sin,sout));
return 0;
}

View file

@ -0,0 +1,55 @@
(import [javax.sound.sampled AudioFormat AudioSystem SourceDataLine])
(defn play [sample-rate bs]
(let [af (AudioFormat. sample-rate 8 1 true true)]
(doto (AudioSystem/getSourceDataLine af)
(.open af sample-rate)
.start
(.write bs 0 (count bs))
.drain
.close)))
(defn note [hz sample-rate ms]
(let [period (/ hz sample-rate)]
(->> (range (* sample-rate ms 1/1000))
(map #(->> (* 2 Math/PI % period)
Math/sin
(* 127 ,)
byte) ,))))
(def morse-codes
{\A ".-" \J ".---" \S "..." \1 ".----" \. ".-.-.-" \: "---..."
\B "-..." \K "-.-" \T "-" \2 "..---" \, "--..--" \; "-.-.-."
\C "-.-." \L ".-.." \U "..-" \3 "...--" \? "..--.." \= "-...-"
\D "-.." \M "--" \V "...-" \4 "....-" \' ".----." \+ ".-.-."
\E "." \N "-." \W ".--" \5 "....." \! "-.-.--" \- "-....-"
\F "..-." \O "---" \X "-..-" \6 "-...." \/ "-..-." \_ "..--.-"
\G "--." \P ".--." \Y "-.--" \7 "--..." \( "-.--." \" ".-..-." ;"
\H "...." \Q "--.-" \Z "--.." \8 "---.." \) "-.--.-" \$ "...-..-"
\I ".." \R ".-." \0 "-----" \9 "----." \& ".-..." \@ ".--.-."
\space " "})
(def sample-rate 1024)
(let [hz 440
ms 50]
(def sounds
{\. (note hz sample-rate (* 1 ms))
\- (note hz sample-rate(* 3 ms))
:element-gap (note 0 sample-rate (* 1 ms))
:letter-gap (note 0 sample-rate (* 3 ms))
\space (note 0 sample-rate (* 1 ms))})) ;includes letter-gap on either side
(defn convert-letter [letter]
(->> (get morse-codes letter "")
(map sounds ,)
(interpose (:element-gap sounds) ,)
(apply concat ,)))
(defn morse [s]
(->> (.toUpperCase s)
(map convert-letter ,)
(interpose (:letter-gap sounds) ,)
(apply concat ,)
byte-array
(play sample-rate ,)))

View file

@ -0,0 +1,10 @@
import System.IO
import MorseCode
import MorsePlaySox
-- Read standard input, converting text to Morse code, then playing the result.
-- We turn off buffering on stdin so it will play as you type.
main = do
hSetBuffering stdin NoBuffering
text <- getContents
play $ toMorse text

View file

@ -0,0 +1,36 @@
module MorseCode (Morse, MSym(..), toMorse) where
import Data.List
import Data.Maybe
import qualified Data.Map as M
type Morse = [MSym]
data MSym = Dot | Dash | SGap | CGap | WGap deriving (Show)
-- Based on the table of International Morse Code letters and numerals at
-- http://en.wikipedia.org/wiki/Morse_code.
dict = M.fromList
[('a', m ".-" ), ('b', m "-..." ), ('c', m "-.-." ), ('d', m "-.." ),
('e', m "." ), ('f', m "..-." ), ('g', m "--." ), ('h', m "...." ),
('i', m ".." ), ('j', m ".---" ), ('k', m "-.-" ), ('l', m ".-.." ),
('m', m "--" ), ('n', m "-." ), ('o', m "---" ), ('p', m ".--." ),
('q', m "--.-" ), ('r', m ".-." ), ('s', m "..." ), ('t', m "-" ),
('u', m "..-" ), ('v', m "...-" ), ('w', m ".--" ), ('x', m "-..-" ),
('y', m "-.--" ), ('z', m "--.." ), ('1', m ".----"), ('2', m "..---"),
('3', m "...--"), ('4', m "....-"), ('5', m "....."), ('6', m "-...."),
('7', m "--..."), ('8', m "---.."), ('9', m "----."), ('0', m "-----")]
where m = intersperse SGap . map toSym
toSym '.' = Dot
toSym '-' = Dash
-- Convert a string to a stream of Morse symbols. We enhance the usual dots
-- and dashes with special "gap" symbols, which indicate the border between
-- symbols, characters and words. This allows a player to easily adjust its
-- timing by simply looking at the current symbol, rather than trying to keep
-- track of state.
toMorse :: String -> Morse
toMorse = fromWords . words . weed
where fromWords = intercalate [WGap] . map fromWord
fromWord = intercalate [CGap] . map fromChar
fromChar = fromJust . flip M.lookup dict
weed = filter (\c -> c == ' ' || M.member c dict)

View file

@ -0,0 +1,39 @@
module MorsePlaySox (play) where
import Sound.Sox.Play
import Sound.Sox.Option.Format
import Sound.Sox.Signal.List
import Data.Int
import System.Exit
import MorseCode
samps = 15 -- samples/cycle
freq = 700 -- cycles/second (frequency)
rate = samps * freq -- samples/second (sampling rate)
type Samples = [Int16]
-- One cycle of silence and a sine wave.
mute, sine :: Samples
mute = replicate samps 0
sine = let n = fromIntegral samps
f k = 8000.0 * sin (2*pi*k/n)
in map (round . f . fromIntegral) [0..samps-1]
-- Repeat samples until we have the specified duration in seconds.
rep :: Float -> Samples -> Samples
rep dur = take n . cycle
where n = round (dur * fromIntegral rate)
-- Convert Morse symbols to samples. Durations are in seconds, based on
-- http://en.wikipedia.org/wiki/Morse_code#Representation.2C_timing_and_speeds.
toSamples :: MSym -> Samples
toSamples Dot = rep 0.1 sine
toSamples Dash = rep 0.3 sine
toSamples SGap = rep 0.1 mute
toSamples CGap = rep 0.3 mute
toSamples WGap = rep 0.7 mute
-- Interpret the stream of Morse symbols as sound.
play :: Morse -> IO ExitCode
play = simple put none rate . concatMap toSamples

View file

@ -0,0 +1,9 @@
require'strings media/wav'
morse=:[:; [:(' ',~' .-' {~ 3&#.inv)&.> (_96{.".0 :0-.LF) {~ a.&i.@toupper
79 448 0 1121 0 0 484 214 644 0 151 692 608 455 205 242 161 134 125 122
121 202 229 238 241 715 637 0 203 0 400 475 5 67 70 22 1 43 25 40 4 53
23 49 8 7 26 52 77 16 13 2 14 41 17 68 71 76 214 0 644 0 401
)
onoffdur=: 0.01*100<.@*(1.2%[)*(4 4#:2 5 13){~' .-'i.]
playmorse=: 30&$: :((wavnote&, 63 __"1)@(onoffdur morse))

View file

@ -0,0 +1,6 @@
morse'this is an example'
- .... .. ... .. ... .- -. . -..- .- -- .--. .-.. .
playmorse'this is an example'
1
12 playmorse'as is this'
1

View file

@ -0,0 +1,83 @@
var globalAudioContext = new webkitAudioContext();
function morsecode(text, unit, freq) {
'use strict';
// defaults
unit = unit ? unit : 0.05;
freq = freq ? freq : 700;
var cont = globalAudioContext;
var time = cont.currentTime;
// morsecode
var code = {
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: '__..', 0: '_____', 1: '.____', 2: '..___', 3: '...__',
4: '...._', 5: '.....', 6: '_....', 7: '__...', 8: '___..', 9: '____.'
};
// generate code for text
function makecode(data) {
for (var i = 0; i <= data.length; i ++) {
var codedata = data.substr(i, 1).toLowerCase();
codedata = code[codedata];
// recognised character
if (codedata !== undefined) {
maketime(codedata);
}
// unrecognised character
else {
time += unit * 7;
}
}
}
// generate time for code
function maketime(data) {
for (var i = 0; i <= data.length; i ++) {
var timedata = data.substr(i, 1);
timedata = (timedata === '.') ? 1 : (timedata === '_') ? 3 : 0;
timedata *= unit;
if (timedata > 0) {
maketone(timedata);
time += timedata;
// tone gap
time += unit * 1;
}
}
// char gap
time += unit * 2;
}
// generate tone for time
function maketone(data) {
var start = time;
var stop = time + data;
// filter: envelope the tone slightly
gain.gain.linearRampToValueAtTime(0, start);
gain.gain.linearRampToValueAtTime(1, start + (unit / 8));
gain.gain.linearRampToValueAtTime(1, stop - (unit / 16));
gain.gain.linearRampToValueAtTime(0, stop);
}
// create: oscillator, gain, destination
var osci = cont.createOscillator();
osci.frequency.value = freq;
var gain = cont.createGainNode();
gain.gain.value = 0;
var dest = cont.destination;
// connect: oscillator -> gain -> destination
osci.connect(gain);
gain.connect(dest);
// start oscillator
osci.start(time);
// begin encoding: text -> code -> time -> tone
makecode(text);
// return web audio context for reuse / control
return cont;
}

View file

@ -0,0 +1 @@
morsecode('Hello World');

View file

@ -0,0 +1,55 @@
'The following code relies on the Windows API
Input "Input the text to translate to Morse Code... "; string$
Print PlayMorse$(string$)
End
Function PlayMorse$(string$)
'LetterGap = (3 * BaseTime)
'WordGap = (7 * BaseTime)
BaseTime = 50
freq = 1250
PlayMorse$ = TranslateToMorse$(string$)
morseCode$ = "./-"
For i = 1 To Len(PlayMorse$)
Scan
dwDuration = (Instr(morseCode$, Mid$(PlayMorse$, i, 1)) * BaseTime)
If (Mid$(PlayMorse$, i, 1) <> " ") Then
CallDLL #kernel32, "Beep", freq As ulong, dwDuration As ulong, ret As long
CallDLL #kernel32, "Sleep", BaseTime As long, ret As void
End If
If (Mid$(PlayMorse$, i, 1) <> " ") Then
sleep = (3 * BaseTime)
Else
sleep = (7 * BaseTime)
End If
CallDLL #kernel32, "Sleep", sleep As long, ret As void
Next i
End Function
Function TranslateToMorse$(string$)
string$ = Upper$(string$)
For i = 1 To Len(string$)
While desc$ <> "End"
Read desc$, value$
If desc$ = "" Then desc$ = chr$(34)
If desc$ = Mid$(string$, i, 1) Then
If Mid$(string$, i, 1) <> " " Then value$ = " " + value$
TranslateToMorse$ = TranslateToMorse$ + value$
Exit While
End If
Wend
If desc$ = "End" Then Notice Mid$(string$, i, 1) + " is not accounted for in the Morse Code Table."
Restore
Next i
TranslateToMorse$ = Trim$(TranslateToMorse$)
Data "A", ".-", "B", "-...", "C", "-.-.", "D", "-..", "E", ".", "F", "..-.", "G", "--."
Data "H", "....", "I", "..", "J", ".---", "K", "-.-", "L", ".-..", "M", "--", "N", "-."
Data "O", "---", "P", ".--.", "Q", "--.-", "R", ".-.", "S", "...", "T", "-", "U", "..-"
Data "V", "...-", "W", ".--", "X", "-..-", "Y", "-.--", "Z", "--..", "Á", "--.-", "Ä", ".-.-"
Data "É", "..-..", "Ñ", "--.--", "Ö", "---.", "Ü", "..--", "1", ".----", "2", "..---"
Data "3", "...--", "4", "....-", "5", ".....", "6", "-....", "7", "--...", "8", "---.."
Data "9", "----.", "0", "-----", ",", "--..--", ".", ".-.-.-", "?", "..--..", ";", "-.-.-"
Data ":", "---...", "/", "-..-.", "-", "-....-", "'", ".----.", "+", ".-.-.", "", ".-..-."
Data "@", ".--.-.", "(", "-.--.", ")", "-.--.-", "_", "..--.-", "$", "...-..-", "&", ".-..."
Data "=", "-...-", "!", "..--.", " ", " ", "End", ""
End Function

View file

@ -0,0 +1,71 @@
function [morseText,morseSound] = text2morse(string,playSound)
%% Translate AlphaNumeric Text to Morse Text
string = lower(string);
%Defined such that the ascii code of the characters in the string map
%to the indecies of the dictionary.
morseDictionary = {{' ',' '},{'',''},{'',''},{'',''},...
{'',''},{'',''},{'',''},{'',''},{'',''},{'',''},...
{'',''},{'',''},{'',''},{'',''},{'',''},{'',''},...
{'0','-----'},{'1','.----'},{'2','..---'},{'3','...--'},...
{'4','....-'},{'5','.....'},{'6','-....'},{'7','--...'},...
{'8','---..'},{'9','----.'},...
{'',''},{'',''},{'',''},{'',''},{'',''},{'',''},...
{'',''},{'',''},{'',''},{'',''},{'',''},{'',''},...
{'',''},{'',''},{'',''},{'',''},{'',''},{'',''},...
{'',''},{'',''},{'',''},{'',''},{'',''},{'',''},...
{'',''},{'',''},{'',''},{'',''},{'',''},{'',''},...
{'',''},{'',''},{'',''},{'',''},{'',''},{'',''},...
{'',''},{'',''},{'',''},...
{'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','--..'}};
%Iterates through each letter in the string and converts it to morse
%code
morseText = arrayfun(@(x)[morseDictionary{x}{2} '|'],(string - 31),'UniformOutput',false);
%The output of the previous operation is a cell array, we want it to be
%a string. This line accomplishes that.
morseText = cell2mat(morseText);
morseText(end) = []; %delete extra pipe
%% Translate Morse Text to Morse Audio
%Generate the tones for each element of the code
SamplingFrequency = 8192; %Hz
ditLength = .1; %s
dit = (0:1/SamplingFrequency:ditLength);
dah = (0:1/SamplingFrequency:3*ditLength);
dit = sin(3520*dit);
dah = sin(3520*dah);
silent = zeros(1,length(dit));
%A dictionary of the audio components of each symbol
morseTiming = {{'.',[dit silent]},{'-',[dah silent]},{'|',[silent silent]},{' ',[silent silent]}};
morseSound = [];
for i = (1:length(morseText))
%Iterate through each cell in the morseTiming cell array and
%find which timing sequence corresponds to the current morse
%text symbol.
cellNum = find(cellfun(@(x)(x{1}==morseText(i)),morseTiming));
morseSound = [morseSound morseTiming{cellNum}{2}];
end
morseSound(end-length(silent):end) = []; %Delete the extra silent tone at the end
if(playSound)
sound(morseSound,SamplingFrequency); %Play sound
end
end %text2morse

View file

@ -0,0 +1,5 @@
>> text2morse('Call me Ishmael.',true)
ans =
-.-.|.-|.-..|.-..| |--|.| |..|...|....|--|.-|.|.-..|

View file

@ -0,0 +1,33 @@
Dictionary = Join[CharacterRange["a", "z"], CharacterRange["0", "9"]];
mark = 0.1; gap = 0.125; (* gap should be equal to mark. But longer gap makes audio code easier to decode *)
shortgap = 3*gap; medgap = 7*gap;
longmark = 3*mark;
MorseDictionary = {
".-", "-...", "-.-.", "-..",
".", "..-.", "--.", "....", "..",
".---", "-.-", ".-..", "--", "-.",
"---", ".--.", "--.-", ".-.",
"...", "-", "..-", "...-", ".--",
"-..-", "-.--", "--..",
"-----", ".----", "..---", "...--", "....-", ".....",
"-....", "--...", "---..", "----."
};
MorseDictionary = # <> " " & /@ MorseDictionary; (* Force short gap silence after each letter/digit *)
Tones = {
SoundNote[None, medgap],
SoundNote[None, shortgap],
{SoundNote["C", mark, "Clarinet"], SoundNote[None, gap]},
{SoundNote["C", longmark, "Clarinet"], SoundNote[None, gap]},
{SoundNote["F#", mark, "Clarinet"], SoundNote[None, gap]} (* Use F# short mark to denote unrecognized character *)
};
codeRules = MapThread[Rule, {Dictionary, MorseDictionary}];
decodeRules = MapThread[Rule, {MorseDictionary, Dictionary}];
soundRules = MapThread[Rule, {{" ", " ", ".", "-", "?"}, Tones}];
(* The order of the rules here is important. Otherwise medium gaps and short gaps get confounded *)
morseCode[s_String] := StringReplace[ToLowerCase@s, codeRules~Join~{x_ /; FreeQ[Flatten@{Dictionary, " "}, x] -> "? "}]
morseDecode[s_String] := StringReplace[s, decodeRules]
sonicMorse[s_String] := EmitSound@Sound@Flatten[Characters@morseCode@s /. soundRules]

View file

@ -0,0 +1,4 @@
use Acme::AGMorse qw(SetMorseVals SendMorseMsg);
SetMorseVals(20,30,400);
SendMorseMsg('Hello World! abcdefg @\;'); # note, caps are ingnored in Morse Code
exit;

View file

@ -0,0 +1,43 @@
# *Morse *Dit *Dah
(balance '*Morse
(mapcar
'((L)
(def (car L)
(mapcar = (chop (cadr L)) '("." .)) ) )
(quote
("!" "---.") ("\"" ".-..-.") ("$" "...-..-") ("'" ".----.")
("(" "-.--.") (")" "-.--.-") ("+" ".-.-.") ("," "--..--")
("-" "-....-") ("." ".-.-.-") ("/" "-..-.")
("0" "-----") ("1" ".----") ("2" "..---") ("3" "...--")
("4" "....-") ("5" ".....") ("6" "-....") ("7" "--...")
("8" "---..") ("9" "----.")
(":" "---...") (";" "-.-.-.") ("=" "-...-") ("?" "..--..")
("@" ".--.-.")
("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" "--..")
("[" "-.--.") ("]" "-.--.-") ("_" "..--.-") ) ) )
# Words per minute
(de wpm (N)
(setq *Dit (*/ 1200 N) *Dah (* 3 *Dit)) )
(wpm 20)
# Morse a string
(de morse (Str)
(for C (chop Str)
(cond
((sp? C) (wait (+ *Dah *Dit))) # White space: Pause
((idx '*Morse (uppc C)) # Known character
(for Flg (val (car @))
(call "/usr/bin/beep" "-D" *Dit "-l" (if Flg *Dit *Dah)) ) )
(T (call "/usr/bin/beep" "-f" 370)) ) # Unkown character
(wait (- *Dah *Dit)) ) )
(morse "Hello world!")

View file

@ -0,0 +1,61 @@
import time, winsound #, sys
char2morse = {
"!": "---.", "\"": ".-..-.", "$": "...-..-", "'": ".----.",
"(": "-.--.", ")": "-.--.-", "+": ".-.-.", ",": "--..--",
"-": "-....-", ".": ".-.-.-", "/": "-..-.",
"0": "-----", "1": ".----", "2": "..---", "3": "...--",
"4": "....-", "5": ".....", "6": "-....", "7": "--...",
"8": "---..", "9": "----.",
":": "---...", ";": "-.-.-.", "=": "-...-", "?": "..--..",
"@": ".--.-.",
"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": "--..",
"[": "-.--.", "]": "-.--.-", "_": "..--.-",
}
e = 50 # Element time in ms. one dit is on for e then off for e
f = 1280 # Tone freq. in hertz
chargap = 1 # Time between characters of a word, in units of e
wordgap = 7 # Time between words, in units of e
def gap(n=1):
time.sleep(n * e / 1000)
off = gap
def on(n=1):
winsound.Beep(f, n * e)
def dit():
on(); off()
def dah():
on(3); off()
def bloop(n=3):
winsound.Beep(f//2, n * e)
def windowsmorse(text):
for word in text.strip().upper().split():
for char in word:
for element in char2morse.get(char, '?'):
if element == '-':
dah()
elif element == '.':
dit()
else:
bloop()
gap(chargap)
gap(wordgap)
# Outputs its own source file as Morse. An audible quine!
#with open(sys.argv[0], 'r') as thisfile:
# windowsmorse(thisfile.read())
while True:
windowsmorse(input('A string to change into morse: '))

View file

@ -0,0 +1,65 @@
require 'win32/sound'
class MorseCode
MORSE = {
"!" => "---.", "\"" => ".-..-.", "$" => "...-..-", "'" => ".----.",
"(" => "-.--.", ")" => "-.--.-", "+" => ".-.-.", "," => "--..--",
"-" => "-....-", "." => ".-.-.-", "/" => "-..-.", "0" => "-----",
"1" => ".----", "2" => "..---", "3" => "...--", "4" => "....-", "5" => ".....",
"6" => "-....", "7" => "--...", "8" => "---..", "9" => "----.", ":" => "---...",
";" => "-.-.-.", "=" => "-...-", "?" => "..--..", "@" => ".--.-.", "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" => "--..",
"[" => "-.--.", "]" => "-.--.-", "_" => "..--.-",
}
T_UNIT = 75 # ms
FREQ = 700
DIT = 1 * T_UNIT
DAH = 3 * T_UNIT
CHARGAP = 1 * T_UNIT
WORDGAP = 7 * T_UNIT
def initialize(string)
@message = string
puts "your message is #{string.inspect}"
end
def send
@message.strip.upcase.split.each do |word|
word.each_char do |char|
send_char char
pause CHARGAP
print " "
end
pause WORDGAP
puts ""
end
end
private
def send_char(char)
MORSE[char].each_char do |code|
case code
when '.' then beep DIT
when '-' then beep DAH
end
pause CHARGAP
print code
end
end
def beep(ms)
::Win32::Sound.beep(FREQ, ms)
end
def pause(ms)
sleep(ms.to_f/1000.0)
end
end
MorseCode.new('sos').send
MorseCode.new('this is a test.').send

View file

@ -0,0 +1,62 @@
# This uses the GUI-free part of the Snack library
package require sound
# A simple pause while running the event loop, in terms of basic time units
proc pause n {
global t
after [expr {$t * $n}] set ok 1
vwait ok
}
# Generate using a sine-wave filter
proc beep n {
global frequency
set f [snack::filter generator $frequency 30000 0.0 sine -1]
set s [snack::sound -rate 22050]
$s play -filter $f
pause $n
$s stop
$s destroy
$f destroy
pause 1
}
# The dits and the dahs are just beeps of different lengths
interp alias {} dit {} beep 1
interp alias {} dah {} beep 3
set MORSE_CODE {
"!" "---." "\"" ".-..-." "$" "...-..-" "'" ".----."
"(" "-.--." ")" "-.--.-" "+" ".-.-." "," "--..--"
"-" "-....-" "." ".-.-.-" "/" "-..-."
":" "---..." ";" "-.-.-." "=" "-...-" "?" "..--.."
"@" ".--.-." "[" "-.--." "]" "-.--.-" "_" "..--.-"
"0" "-----" "1" ".----" "2" "..---" "3" "...--"
"4" "....-" "5" "....." "6" "-...." "7" "--..."
"8" "---.." "9" "----."
"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" "--.."
}
# The code to translate text to morse code and play it
proc morse {str wpm} {
global t MORSE_CODE
set t [expr {1200 / $wpm}]
# Backslash and space are special cases in various ways
set map {"\\" {} " " {[pause 4]}}
# Append each item in the code to the map, with an inter-letter pause after
foreach {from to} $MORSE_CODE {lappend map $from "$to\[pause 3\]"}
# Convert to dots and dashes
set s [string map $map [string toupper $str]]
# Play the dots and dashes by substituting commands for them
subst [string map {"." [dit] "-" [dah]} $s]
return
}
# We'll play at a fairly high pitch
set frequency 700
morse "Morse code with Tcl and Snack." 20