はじめに
無性にモースル信号音を聞きたくなった。「こっちのけんと」さんの曲「はいよろこんで→ギリギリダンス」とか、天空の城ラピュタのムスカ様とか、タイタニックとか、戦争ゲームとか、NHKスペシャルの戦時中特集で流れているトントン・ツーツーのあれだ。
「トン」は単音「・」
「ツー」は長音「ー」
となる。2進法でデジタル信号を電波に乗せて長距離通信が可能とする古い技術だ。詳細はWikipediaを見て欲しいが、文字入力して、モールス信号に変換して聞きたくなった。しかし、プログラムを一から作成するのもメンドクサイので、生成AIに作成してもらうことにした。
条件
プログラム言語:HTMLとJavaScript
手順
1 厳格モードで、プロンプト(命令文)をCopilotに入力
2 出力されたプログラムをコピペしHTMLファイルにコピペして実行
3 上手くいかなかったら1のプロンプトを編集
4 最後に調整
生成Aiに入力したプロンプト(命令文)
最終的に以下のプロンプトで比較的満足したHTMLとJavaScriptを出力が出来た。
尚、生成AIの性質上、以下のプロンプトを入力しても必ず同一結果が出力されるわけではないのでご注意下さい。
アルファベットと、ひらがなと、濁音と、半濁音と、数値を入力するとモールス信号の波形に変更できるJavaScriptのサンプルプログラムを教えてください。
ひらがなは50音全部入力できるようにしてください。
合成音でモールス音を鳴らすようにしてください。
生成プログラム(HTML+JavaScript)の出力結果
CodePen利用しています。以下のテキストボックスに文字(例SOS)を入力して「変換」ボタンを押すと動きます。★!音の大きさに注意!★
See the Pen モールス信号 by F.M (@kobe2018) on CodePen.
生成プログラム(HTML+JavaScript)【追記・手直後】
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>アルファベットとひらがなをモールス信号に変換</title>
</head>
<body>
<h1>アルファベット・ひらがな・カタカナ・数値をモールス信号で出力</h1>
<input type="text" id="inputText" placeholder="入力してください">
<button onclick="convertToMorse()">変換</button>
<p id="output"></p>
<script>
const morseCodeMap = {
"あ":"--.--","い":".-","う":"..-","え":"-.---","お":".-...",
"か":".-..","き":"-.-..","く":"...-","け":"-.--","こ":"----",
"さ":"-.-.-","し":"--.-.","す":"---.-","せ":".---.","そ":"---.",
"た":"-.","ち":"..-.","つ":".--.","て":".-.--","と":"..-..",
"な":".-.","に":"-.-.","ぬ":"....","ね":"--.-","の":"..--",
"は":"-...","ひ":"--..-","ふ":"--..","へ":".","ほ":"-..",
"ま":"-..-","み":"..-.-","む":"-","め":"-...-","も":"-..-.",
"や":".--","ゆ":"-..--","よ":"--",
"ら":"...","り":"--.","る":"-.--.","れ":"---","ろ":".-.-",
"わ":"-.-","ゐ":".-..-","ゑ":".--..","を":".---","ん":".-.-.",
'゛': '..',//濁点
'゜': '..--.', //半濁点
"ー":".--.-",//長音
"、":".-.-.-",//区切点
"(":"-.--.-",//括弧
")":".-..-.",//括弧閉
"ア":"--.--","イ":".-","ウ":"..-","エ":"-.---","オ":".-...",
"カ":".-..","キ":"-.-..","ク":"...-","ケ":"-.--","コ":"----",
"サ":"-.-.-","シ":"--.-.","ス":"---.-","セ":".---.","ソ":"---.",
"タ":"-.","チ":"..-.","ツ":".--.","テ":".-.--","ト":"..-..",
"ナ":".-.","ニ":"-.-.","ヌ":"....","ネ":"--.-","ノ":"..--",
"ハ":"-...","ヒ":"--..-","フ":"--..","ヘ":".","ホ":"-..",
"マ":"-..-","ミ":"..-.-","ム":"-","メ":"-...-","モ":"-..-.",
"ヤ":".--","ユ":"-..--","ヨ":"- ",
"ラ":"...","リ":"--.","ル":"-.--.","レ":"---","ロ":".-.-",
"ワ":"-.-","ヰ":".-..-","ヱ":".--..","ヲ":".---","ン":".-.-.",
'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': '----.',
'0': '-----', '1': '.----', '2': '..---', '3': '...--', '4': '....-', '5': '.....', '6': '-....', '7': '--...', '8': '---..', '9': '----.',
' ': ' ', ' ': ' ', // 半角全角の空白文字
};
const replacements = [
["ぁ", "あ"],["ぃ", "い"],["ぅ", "う"],["え", "え"],["ぉ", "お"],["っ", "つ"],
["ァ", "ア"],["ィ", "い"],["ゥ", "ウ"],["ェ", "エ"],["ォ", "オ"],["ッ", "ツ"],
["が", "か゛"],["ぎ", "き゛"],["ぐ", "く゛"],["げ", "け゛"],["ご", "こ゛"],
["ざ", "さ゛"],["じ", "し゛"],["ず", "す゛"],["ぜ", "せ゛"],["ぞ", "そ゛"],
["だ", "た゛"],["ぢ", "ち゛"],["づ", "つ゛"],["で", "て゛"],["ど", "と゛"],
["ば", "は゛"],["び", "ひ゛"],["ぶ", "ふ゛"],["べ", "へ゛"],["ぼ", "ほ゛"],
["ガ", "カ゛"],["ギ", "キ゛"],["グ", "ク゛"],["ゲ", "ケ゛"],["ゴ", "コ゛"],
["ザ", "サ゛"],["ジ", "シ゛"],["ズ", "ス゛"],["ゼ", "セ゛"],["ゾ", "ソ゛"],
["ダ", "タ゛"],["ヂ", "チ゛"],["ヅ", "ツ゛"],["デ", "テ゛"],["ド", "ト゛"],
["バ", "ハ゛"],["ビ", "ビ゛"],["ブ", "フ゛"],["ベ", "ヘ゛"],["ボ", "ホ゛"],
["パ", "は゜"],["ピ", "ビ゜"],["プ", "フ゜"],["ぺ", "ヘ゜"],["ポ", "ホ゜"],
];
function playMorseSound(morseCode) {
const audioContext = new (window.AudioContext || window.webkitAudioContext)();
const dotDuration = 0.07; // ドットの長さ(秒)
//const dashDuration = dotDuration * 1.8; // ダッシュの長さ(秒)
const dashDuration = dotDuration * 3; // ダッシュの長さは三倍(秒)
const gapDuration = dotDuration; // 各信号間のギャップ(秒)
let currentTime = audioContext.currentTime;
for (let symbol of morseCode) {
if (symbol === '.') {
playTone(audioContext, currentTime, dotDuration);
currentTime += dotDuration + gapDuration;
} else if (symbol === '-') {
playTone(audioContext, currentTime, dashDuration);
currentTime += dashDuration + gapDuration;
} else {
currentTime += gapDuration; // スペースの場合
}
}
}
function playTone(audioContext, startTime, duration) {
const oscillator = audioContext.createOscillator();
oscillator.type = 'sine';
oscillator.frequency.setValueAtTime(600, audioContext.currentTime); // 周波数600Hz
oscillator.connect(audioContext.destination);
oscillator.start(startTime);
oscillator.stop(startTime + duration);
}
function convertToMorse() {
const inputText = multiReplace(document.getElementById('inputText').value.toLowerCase(),replacements);
let morseCode = '';
for (let char of inputText) {
if (morseCodeMap[char]) {
morseCode += morseCodeMap[char] + ' ';
} else {
morseCode += '? ';
}
}
document.getElementById('output').innerText = morseCode;
playMorseSound(morseCode.trim());
}
function multiReplace(str, replacements) {
replacements.forEach(replacement => {
const [target, replacementText] = replacement;
const regex = new RegExp(target, 'g');
str = str.replace(regex, replacementText);
});
return str;
}
</script>
</body>
</html>
考察&感想
出力されたプログラムは100%完璧なものとは言えなくて、手直しは必要だったが、普段なら休日を1日つぶす仕事量なのに、生成AIを使ったら30分ほどで結果を得られた。
ああ、末恐ろしい。
参考
和文モールス符号