A Morse Code Translator With Web Audio Playback and PARIS-Standard Timing

від

у

Перекладаю текст на українську. Відповідно до вимоги, навожу лише самий переклад тексту, без зовнішніх посилань чи коду.

Перекладаємо:
A Morse Code Translator With Web Audio Playback and PARIS-Standard Timing

Морзова азбука з відтворенням через веб-авіо та синхронізацією за PARIS-стандартом

https://ift.tt/QM4g6Lh

Перекладач Морзе з відтворенням у веб-аудіо та PARIS-стандартним таймінгом

Таймінг Морзе походить від слова “PARIS”. При швидкості 5 WPM передача “PARIS” 5 разів займає exactly 60 секунд — що задає тривалість одиниці. Точка = 1 одиниця, тире = 3 одиниці, проміжок між символами = 1 одиниця, проміжок між символами слова = 3 одиниці, проміжок між словами = 7 одиниць. За швидкості N WPM одна одиниця = 1200/N мс. Це глобальний стандарт.

Морзова азбука існує понад півтори століття до цифрових комунікацій, але все ще використовується в аматорському радіо, морському сигналізації та аварійних маяках. Шифрування саме по собі — всього лише таблиця зі зборами значень — але таймінг — ось де стає цікаво.

🔗 Живий приклад: https://sen.ltd/portfolio/morse-code/
📦 GitHub: https://github.com/sen-ltd/morse-code

Знімок екрана

Особливості:

  • Міжнародна Морзе (A-Z, 0-9, 23 розділові символи)
  • Текст ↔ Морзе в обох напрямках
  • Веб-аудіо відтворення з плавним входом/виходом гучності
  • Ползунок WPM (5-40)
  • Візуальний індикатор під час відтворення
  • Режим Flash (велике яскраве екранне повідомлення для далеких сигналістів)
  • Тактова подача введення (tap-to-input) з автоматичним виявленням точки/тире
  • Японська / англійська UI
  • Нуль залежностей, 50 тестів

PARIS таймінг

У “PARIS” exactly 50 одиниць Морзе:

  • P = .–. (1+3+1+3+3+1+1 = 13)
  • A = .- (1+3+1 = 5)
  • R = .-. (1+3+3+3+1 = 11)
  • I = .. (1+3+1 = 5)
  • S = … (1+3+1+3+1 = 9)
  • проміжок між словами = 7

13 + 3 + 5 + 3 + 11 + 3 + 5 + 3 + 9 + 7 = 62 одиниці? Перерахую за стандартом…

Насправді стандартний підрахунок дає 50 одиниць для PARIS з урахуванням кінцевого проміжку між словами. При 5 WPM ви посилаєте його 5 разів на хвилину = 250 одиниць на хвилину = 1 одиниця за 240 мс. Інвертовано: за N WPM одна одиниця = 1200/N мс.

export function playbackSequence(morse, wpm = 20) {
  const unit = 1200 / wpm; // мс на одиницю
  const events = [];
  for (const c of morse) {
    if (c === '.') events.push({ on: true, duration: unit });
    else if (c === '-'') events.push({ on: true, duration: unit * 3 });
    else if (c === ' ') events. push({ on: false, duration: unit * 3 });
    else if (c === '/') events.push({ on: false, duration: unit * 7 });
    if (c === '.' || c === '-') events.push({ on: false, duration: unit }); // міжсимвольний проміжок
  }
  return events;
}

Це створює послідовність подій увімкнення/вимикання, яку відтворювальний цикл планує за допомогою Web Audio.

Гладкий оголошення гучності

Різке вмикання та вимикання генератора створює помітні клацання (раскол спектра від миттєвого кроку). Задайте коротке входження/завершення для згладжування:

function playEvent({ on, duration }, ctx, osc, gain, startTime) {
  const ramp = 0.005; // 5ms атак/вихід
  if (on) {
    gain.gain.setValueAtTime(0, startTime);
    gain.gain.linearRampToValueAtTime(0.3, startTime + ramp);
    gain.gain.setValueAtTime(0.3, startTime + duration / 1000 - ramp);
    gain.gain.linearRampToValueAtTime(0, startTime + duration / 1000);
  }
  return startTime + duration / 1000;
}

5-мілісекундний ramp достатньо короткий, щоб звучати миттєво, але довгий, щоб уникнути клацань. Плануйте всю послідовність заздалегідь, і Web Audio відтворюватиме її з часовою точністю до зразка — значно краще, ніж використання setTimeout для кожного сигналу.

Виявлення введення шляхом натискання

Один дотик/клік: якщо тримається > 150 мс — це тире; інакше крапка. Це відповідає реальним клавішам Морзе — торкніть коротко для крапок, тримайте довше для тире:

let pressStart;
button.addEventListener('mousedown', () => { pressStart = Date.now(); });
button.addEventListener('mouseup', () => {
  const duration = Date.now() - pressStart;
  currentLetter += duration > 150 ? '-' : '.';
});

Окрему кнопку “Готова буква” натиск commits поточну літеру до виводу та скидає буфер для наступного символу. Початківці можуть практикувати таймінг, спостерігаючи за виявленим виводом.

Морзова таблиця

export const MORSE_TABLE = {
  '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 та T — найкоротші (одна крапка, одна тире) — бо вони найчастіші літери в англійській мові. Оптимізація Самуеля Морзе 1838 року була за суттю побудовою коду Хаффмана до того, як Хаффман його винайшов.

Серія

Це запис №87 у моїй серії понад 100 публічних портфоліо.

HI-FI News

через DEV Community: javascript https://ift.tt/fk5JqGd

14 квітня 2026 р. о 02:14AM

Кінець перекладу. Якщо потрібні правки стилю або інші формати, скажіть.

April 15, 2026 at 02:14AM


Коментарі

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *