모르스_부호_변환기
차이
문서의 선택한 두 판 사이의 차이를 보여줍니다.
| 양쪽 이전 판이전 판다음 판 | 이전 판 | ||
| 모르스_부호_변환기 [2026/09/05 08:13] – akpil | 모르스_부호_변환기 [2026/09/05 09:28] (현재) – akpil | ||
|---|---|---|---|
| 줄 8: | 줄 8: | ||
| < | < | ||
| - | # pip3 install flask jamo | + | # 2026.09.05 |
| + | # morse-letter to morse ver 0.7 | ||
| + | # written by 6K2LSV | ||
| + | # python3 에서 작동 | ||
| + | # pip3 install flask jamo | ||
| + | # port number 3040 | ||
| from flask import Flask, request, render_template_string | from flask import Flask, request, render_template_string | ||
| + | import json | ||
| from jamo import h2j, j2hcj | from jamo import h2j, j2hcj | ||
| app = Flask(__name__) | app = Flask(__name__) | ||
| + | # 모르스 부호 사전 | ||
| MORSE_DICT = { | MORSE_DICT = { | ||
| - | ' | + | ' |
| - | | + | |
| - | ' | + | |
| - | ' | + | |
| - | ' | + | |
| + | | ||
| + | ' | ||
| + | | ||
| + | | ||
| + | | ||
| + | ' | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | ' | ||
| + | | ||
| ' ': '/' | ' ': '/' | ||
| } | } | ||
| 줄 27: | 줄 47: | ||
| < | < | ||
| < | < | ||
| - | < | + | < |
| < | < | ||
| body { font-family: | body { font-family: | ||
| - | .container { width: | + | .container { width: |
| - | textarea { width: 95%; height: | + | textarea { width: 95%; height: |
| - | button { background-color: | + | button { background-color: |
| - | | + | |
| - | .box { text-align: left; margin-top: 25px; padding: | + | .unit { display: inline-block; margin-right: 15px; margin-bottom: 10px; padding: |
| - | .morse-box | + | .char { display: block; color: #fff; font-size: |
| - | | + | |
| </ | </ | ||
| </ | </ | ||
| < | < | ||
| <div class=" | <div class=" | ||
| - | < | + | < |
| <form method=" | <form method=" | ||
| - | < | + | < |
| - | <button type=" | + | <button type=" |
| </ | </ | ||
| - | {% if result | + | {% if pair_data |
| - | <div class=" | + | <div class=" |
| - | < | + | |
| - | <div style=" | + | |
| - | </ | + | |
| - | + | ||
| - | <div class=" | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| < | < | ||
| - | const fullText | + | const pairData |
| - | const displayElement | + | const displayArea |
| - | let index = 0; | + | |
| - | + | ||
| - | // Web Audio API 설정 | + | |
| const audioCtx = new (window.AudioContext || window.webkitAudioContext)(); | const audioCtx = new (window.AudioContext || window.webkitAudioContext)(); | ||
| - | function playBeep(isDash) { | + | function playBeep(symbol) { |
| + | if (symbol === ' ' || symbol === '/' | ||
| const oscillator = audioCtx.createOscillator(); | const oscillator = audioCtx.createOscillator(); | ||
| const gainNode = audioCtx.createGain(); | const gainNode = audioCtx.createGain(); | ||
| - | | + | |
| oscillator.connect(gainNode); | oscillator.connect(gainNode); | ||
| gainNode.connect(audioCtx.destination); | gainNode.connect(audioCtx.destination); | ||
| - | | ||
| oscillator.type = ' | oscillator.type = ' | ||
| - | oscillator.frequency.setValueAtTime(600, | + | oscillator.frequency.setValueAtTime(600, |
| - | + | ||
| - | const duration = isDash | + | const duration = (symbol === ' |
| gainNode.gain.setValueAtTime(0.1, | gainNode.gain.setValueAtTime(0.1, | ||
| - | | + | |
| oscillator.start(); | oscillator.start(); | ||
| oscillator.stop(audioCtx.currentTime + duration); | oscillator.stop(audioCtx.currentTime + duration); | ||
| + | |||
| + | return duration; // 재생된 시간 반환 | ||
| } | } | ||
| - | function | + | |
| - | | + | |
| - | const char = fullText.charAt(index); | + | // 한 글자 단위 박스 생성 |
| - | | + | const unit = document.createElement(' |
| + | | ||
| + | unit.innerHTML = `<span class=" | ||
| + | displayArea.appendChild(unit); | ||
| - | | + | |
| - | | + | |
| - | | + | for (const symbol of item.morse) { |
| - | } else if (char === '-') { | + | |
| - | playBeep(true); | + | |
| - | } else if (char === '/') { | + | |
| - | | + | // 스페이스 기호가 |
| + | await new Promise(resolve => setTimeout(resolve, | ||
| + | } else { | ||
| + | playBeep(symbol); | ||
| + | // 일반 기호는 음길이 이후 다음 기호와의 간격을 위해 기존 150ms 대기 | ||
| + | await new Promise(resolve => setTimeout(resolve, | ||
| + | } | ||
| } | } | ||
| - | |||
| - | index++; | ||
| - | setTimeout(typeAndPlay, | ||
| } | } | ||
| } | } | ||
| - | window.onload = () => { | + | window.onload = startDisplay; |
| - | if (fullText.length > 0) { | + | |
| - | typeAndPlay(); | + | |
| - | } | + | |
| - | }; | + | |
| </ | </ | ||
| {% endif %} | {% endif %} | ||
| 줄 117: | 줄 130: | ||
| @app.route('/', | @app.route('/', | ||
| def index(): | def index(): | ||
| - | result = "" | ||
| input_text = "" | input_text = "" | ||
| + | pair_data = [] | ||
| if request.method == ' | if request.method == ' | ||
| input_text = request.form.get(' | input_text = request.form.get(' | ||
| - | | + | |
| - | | + | processed_chars |
| - | | + | |
| - | return render_template_string(HTML_TEMPLATE, | + | |
| + | pair_data.append({ | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | }) | ||
| + | |||
| + | return render_template_string(HTML_TEMPLATE, | ||
| if __name__ == ' | if __name__ == ' | ||
| app.run(host=' | app.run(host=' | ||
| + | |||
| + | |||
| </ | </ | ||
모르스_부호_변환기.1788595999.txt.gz · 마지막으로 수정됨: 저자 akpil
