# Morse Code Spacing

Trying to make a function to convert text into morse code and play the sound. Have it pretty much completed, but I cannot get mathematica to emit no sound so I can have a pause between the dots and dashes. I have defined each letter in terms of dots and dashes, with spaces in between. For example:

a := {dot, ps, dash, lps};
b := {dash, ps, dot, ps, dot, ps, dot, lps};
c := {dash, ps, dot, ps, dash, ps, dot, lps};


ps is a pause between dots and dashes, while lps is a pause between letters. Currently they are defined as:

ps = EmitSound[Play[Sin[400 t], {t, 0, .2}]]
lps := EmitSound[Play[Sin[1/200 t], {t, 0, .5}]];


This emits a small beat sound, but I want to get away to have that just be silence. For spaces in between words I have used

space := EmitSound[Sound[None]];


and used StringReplace to replace " " with "space", and that works, but it doesn't work when trying to define ps and lps.

You're close. For the silences, just multiply the amplitude of the sine waves by 0.

dot := EmitSound[Play[Sin[2000 t], {t, 0, 0.2}, SampleRate -> 22050]];
dash := EmitSound[Play[Sin[2000 t], {t, 0, 0.5}, SampleRate -> 22050]];
ps := EmitSound[0 Play[Sin[2000 t], {t, 0, 0.2}, SampleRate -> 22050]];
lps := EmitSound[0 Play[Sin[2000 t], {t, 0, 0.5}, SampleRate -> 22050]];


Now you can set up the letters:

a := {dot, ps, dash, lps};

a

(sound pattern out)

• Or use Piecewise to make a sound that ends before the sound finishes playing. Since the pause is actually part of the dot or dash, I think that could be a better approach. Commented Dec 14, 2015 at 2:00
• I don't think this actually works. If you crank up the upper limit for t to something like 10 seconds, it doesn't change the break between the tones. Commented Jan 27, 2016 at 21:30

Play seems to have the property that it autoscales the volume to some constant level, regardless of the specified amplitude. The following code should play two tones, the first one loud and the second one quiet:

louddot := Play[Sin[2000 t], {t, 0, 1}, SampleRate -> 22050];
quietdot := Play[0.01 Sin[2000 t], {t, 0, 1}, SampleRate -> 22050];
EmitSound[{louddot, quietdot}]


On my system, this results in two tones that have the same volume. The fact that it does this means that trying to feed silence into Play fails (without throwing an error message!):

pause = Play[0, {t, 0, 1}, SampleRate -> 22050]

(* Sound[SampledSoundFunction[CompiledFunction[Argument count: 1; Argument types: {_Integer}],4410,22050]] *)


This is probably because Mathematica is trying to normalize the input signal to some common maximum level, which (for a zero signal) would result in a divide-by-zero error.

To actually get silence, you can use Sound and SoundNote instead, which accept the SoundVolume option:

dot := Play[Sin[2000 t], {t, 0, 0.2}, SampleRate -> 22050];
dash := Play[Sin[2000 t], {t, 0, 0.5}, SampleRate -> 22050];
ps := Sound[SoundNote[0, 0.2, SoundVolume -> 0]];
lps := Sound[SoundNote[0, 0.5, SoundVolume -> 0]];
EmitSound[{dot, ps, dot, ps, dash, ps, dot, lps, dash, lps, dot, ps, dash, ps, dash}]


This is kludgey as hell, but I couldn't find another way to do it. Trying to combine Sound objects with different volumes doesn't seem to work (it yields silence), and trying to create a silent sound with ListPlay gave an error.

I will give the morse code - generating part of this question another go:

First let's query Wolfram Alpha for some morse code:

query[letter_]:= WolframAlpha["morse code " <> letter, "PodPlaintext"][[2]]


and create an Association for easy lookup

charToMorse = query ~AssociationMap~ CharacterRange["A","Z"]


The following function translates a given string into a list of ., -, S, C and W where . and _ are your typical morse symbols, S is a space between to morse symbols, C is a space between characters and W is the space between two words. For better understanding just out-comment it from top to bottom to see what every operation does.

morseCode[string_]:= string
//ToUpperCase
//StringSplit
//Characters
//ReplaceAll[charToMorse]
//Map[Riffle[#,"C"]&]  (*character spaces*)
//Map[Characters]
//Flatten[#, 1]&
//Map[Riffle[#, "S"]&] (*symbol spaces*)
//Flatten


Lets test:

"an apple" //morseCode
(* {.,S,-,C,-,S,.,W,.,S,-,C,.,S,-,S,-,S,.,C,.,S,-,S,-,S,.,C,.,S,-,S,.,S,.,C,.} *)


and compare to:

WolframAlpha["morse code an apple" , "PodCells"][[2]]


Now you can use replacement rules in the fashion bill showed you in his answer to translate the morse symbols and spacings into sound.

• I would have added numbers and special characters to my lookup-table of morse codes but I couldn't convince W|A to reliably accept queries like WolframAlpha["morse code 1"] Commented Jan 27, 2016 at 21:24