{"id":485,"date":"2026-09-01T19:52:30","date_gmt":"2026-09-02T02:52:30","guid":{"rendered":"https:\/\/w7rjp.com\/index.php\/multi-code-decoder\/"},"modified":"2026-09-01T19:52:30","modified_gmt":"2026-09-02T02:52:30","slug":"multi-code-decoder","status":"publish","type":"page","link":"https:\/\/w7rjp.com\/index.php\/multi-code-decoder\/","title":{"rendered":"Multi-Code Decoder"},"content":{"rendered":"    <div class=\"tw-mcdp\">\n      <header><h2>Thinker Works Multi-Code Decoder Pro<\/h2><p>Local browser-side decoding and analysis for Morse\/CW, RTTY, ASCII serial, SDR\/IQ inputs, messaging utilities, and expanded experimental modes.<\/p><div class=\"tw-license\">Audio processing is performed in the browser. Encrypted traffic is not decrypted and RF transmission is disabled.<\/div><\/header>\n      <main>\n        <section class=\"panel\"><h3>Decoder mode<\/h3><div class=\"grid\">\n          <label>Code format<select id=\"mode\">\n            <optgroup label=\"Core\">\n              <option value=\"auto\" selected>Auto \u2014 Analyze signal and select mode<\/option><option value=\"morse\">Morse \/ CW<\/option><option value=\"ita2\">RTTY \/ Baudot ITA2<\/option><option value=\"ascii7\">ASCII serial 7-bit<\/option><option value=\"ascii8\">ASCII serial 8-bit<\/option>\n            <\/optgroup>\n            <optgroup label=\"Digital \/ Radio\">\n              <option value=\"tty\">TTY \/ Baudot 45.45<\/option><option value=\"rtty\">RTTY \/ Baudot<\/option><option value=\"psk31\">PSK31<\/option><option value=\"psk32\">PSK32 \/ 32-baud BPSK<\/option><option value=\"psk63\">PSK63<\/option><option value=\"aprs\">APRS \/ AX.25 AFSK1200<\/option><option value=\"same\">SAME \/ EAS<\/option><option value=\"dtmf\">DTMF<\/option>\n            <\/optgroup>\n            <optgroup label=\"Weather \/ Images\">\n              <option value=\"noaa-apt\">NOAA APT weather satellite<\/option><option value=\"weather\">Weather FAX \/ raster<\/option><option value=\"wefax\">HF WEFAX<\/option><option value=\"sstv\">SSTV Robot\/Martin\/Scottie<\/option>\n            <\/optgroup>\n            <optgroup label=\"Digital Voice (adapter\/vocoder)\">\n              <option value=\"dmr\">DMR<\/option><option value=\"p25p1\">P25 Phase 1<\/option><option value=\"p25p2\">P25 Phase 2<\/option><option value=\"dstar\">D-STAR<\/option><option value=\"ysf\">YSF<\/option><option value=\"nxdn\">NXDN<\/option><option value=\"dpmr\">dPMR<\/option><option value=\"tetra\">TETRA<\/option><option value=\"m17\">M17<\/option><option value=\"freedv\">FreeDV<\/option><option value=\"codec2\">Codec2<\/option>\n            <\/optgroup>\n          <\/select><\/label>\n          <label id=\"polarityWrap\">Input polarity<select id=\"polarity\"><option value=\"auto\" selected>Auto \u2014 test normal\/reverse<\/option><option value=\"normal\">Normal<\/option><option value=\"reverse\">Reverse mark\/space<\/option><\/select><\/label>\n          <label id=\"baudWrap\">Baud rate<select id=\"baud\"><option value=\"auto\" selected>Auto \u2014 detect baud<\/option><option value=\"45.45\">45.45<\/option><option value=\"50\">50<\/option><option value=\"75\">75<\/option><option value=\"100\">100<\/option><option value=\"110\">110<\/option><option value=\"300\">300<\/option><\/select><\/label>\n        <\/div><p class=\"note\">Updated 2.1.44: Input Source now supports Microphone, Audio File, Keyboard, Mouse, and Text File. Auto mode is the default. The decoder analyzes the loaded signal, ranks candidate modes, selects the best-supported mode, updates the controls, and then decodes with that mode. TTY 45.45, PSK32, Weather FAX\/WEFAX, NOAA APT, SSTV, APRS, SAME\/EAS, DTMF, and digital-voice adapter modes are now visible directly in the decoder. Full digital-voice speech decoding requires a compatible vocoder\/native or WebAssembly adapter.<\/p><\/section>\n        <section class=\"panel\"><h3>Input Source<\/h3><label>Input source<select id=\"inputSource\"><option value=\"microphone\" selected>Microphone \u2014 live audio<\/option><option value=\"file\">Audio File \u2014 recorded audio<\/option><option value=\"keyboard\">Keyboard \u2014 manual keying<\/option><option value=\"mouse\">Mouse \u2014 manual keying<\/option><option value=\"textfile\">Text File \u2014 code\/bitstream text<\/option><\/select><\/label><div id=\"microphonePanel\"><p class=\"tw-mic-actions\"><button id=\"micStart\" class=\"primary\" type=\"button\">Start microphone<\/button> <button id=\"micStop\" type=\"button\" disabled>Stop &amp; decode<\/button> <span class=\"tw-save-options\" role=\"radiogroup\" aria-label=\"Microphone recording format\"><label><input type=\"radio\" name=\"micSaveFormat\" value=\"wav\"> WAV<\/label> <label><input type=\"radio\" name=\"micSaveFormat\" value=\"mp3\" checked> MP3<\/label><\/span> <button id=\"micSaveRecording\" type=\"button\" disabled>Save microphone recording<\/button><\/p><p class=\"note\">Microphone is the default input. The browser will ask for microphone permission after you click Start. While listening, Auto mode continuously analyzes a rolling live sample and switches the decoder to the strongest detected mode. Choose WAV or MP3 at any time, then click Save microphone recording after capture.<\/p><\/div><div id=\"filePanel\" hidden><p><input id=\"audioFile\" type=\"file\" accept=\"audio\/*\"> <button id=\"decodeFile\" type=\"button\">Decode file<\/button> <button id=\"autoDetectFile\" type=\"button\">Auto Detect file<\/button><\/p><\/div><div id=\"textFilePanel\" hidden><p><input id=\"textInputFile\" type=\"file\" accept=\".txt,text\/plain\"> <button id=\"decodeTextFile\" type=\"button\">Load &amp; decode text file<\/button><\/p><p class=\"note\">Text File is a decoder input, separate from Text Encoder. For Morse, the file can contain dots, dashes, spaces, and \/ word separators. For RTTY\/TTY\/ASCII, it can contain a 0\/1 bitstream.<\/p><span id=\"textInputFileName\" class=\"note\"><\/span><textarea id=\"textFilePreview\" rows=\"4\" readonly hidden><\/textarea><\/div><div class=\"grid\">\n          <label id=\"toneWrap\">CW target tone (Hz)<input id=\"tone\" type=\"number\" min=\"200\" max=\"3000\" value=\"650\"><\/label>\n          <label id=\"wpmWrap\">Expected speed (WPM)<input id=\"wpm\" type=\"number\" min=\"3\" max=\"80\" value=\"15\"><\/label>\n          <label class=\"digitalOnly\">Mark frequency (Hz)<input id=\"markFreq\" type=\"number\" min=\"100\" max=\"4000\" value=\"2125\"><\/label>\n          <label class=\"digitalOnly\">Space frequency (Hz)<input id=\"spaceFreq\" type=\"number\" min=\"100\" max=\"4000\" value=\"2295\"><\/label>\n          <label>Detection threshold<input id=\"threshold\" type=\"range\" min=\"5\" max=\"80\" value=\"28\"><output id=\"thresholdOut\">28%<\/output><\/label>\n        <\/div><p id=\"status\">Microphone input is ready. Auto mode is selected by default.<\/p><\/section>\n        <section class=\"panel audio-feedback-panel\" id=\"audioFeedbackPanel\" style=\"display:block!important;visibility:visible!important\"><h3>Audio Feedback Controls<\/h3>\n          <p class=\"note\">Adjust the Morse hand-key sound before or while keying. These controls remain visible for every input source and decoder mode.<\/p>\n          <div class=\"audio-feedback-controls\" style=\"display:grid!important;visibility:visible!important\">\n            <label>Audio volume <input id=\"keyerVolume\" type=\"range\" min=\"0\" max=\"100\" value=\"55\" style=\"display:block!important;visibility:visible!important;width:100%!important\"><span id=\"keyerVolumeValue\">55%<\/span><\/label>\n            <label>Pitch \/ tone <input id=\"keyerPitch\" type=\"range\" min=\"100\" max=\"4000\" step=\"10\" value=\"650\" style=\"display:block!important;visibility:visible!important;width:100%!important\"><span id=\"keyerPitchValue\">650 Hz<\/span><\/label>\n          <\/div>\n        <\/section>\n        <section class=\"panel morse-keyer-panel\" hidden><h3>Morse Code Keyer \u2014 Keyboard, Mouse &amp; Touch<\/h3>\n          <p class=\"note\">Enter Morse manually using the keyboard <strong>Spacebar<\/strong> or any other key you assign, or press and hold the mouse or touchscreen key. Short press = dot, long press = dash. Hand-key speed, dot\/dash timing, and spacing are measured automatically as you key.<\/p>\n          <div class=\"morse-keyer-grid\"><div><button id=\"morseKey\" class=\"morse-key\" type=\"button\" aria-label=\"Morse key\">PRESS \/ HOLD<br><span>KEYBOARD \u2022 MOUSE \u2022 TOUCH<\/span><\/button><div id=\"touchKeyStatus\" class=\"touch-key-status\" aria-live=\"polite\"><\/div><\/div><div>\n            <label>Keyboard hand-key key<button id=\"keyerBind\" type=\"button\">\u2328 Set keyboard key<\/button> <span id=\"keyerKeyLabel\">Spacebar<\/span><\/label>\n            <label>Initial dash threshold<input id=\"keyerDash\" type=\"number\" min=\"1.5\" max=\"5\" step=\"0.1\" value=\"2.0\"><\/label>\n            <p><button id=\"keyerNewChar\" type=\"button\">New character<\/button> <button id=\"keyerNewWord\" type=\"button\">New word<\/button> <button id=\"keyerClear\" type=\"button\">Clear keyer<\/button><\/p>\n            <div id=\"keyerLive\" class=\"keyer-live\">Ready \u2014 hand-key speed is detected automatically.<\/div>\n            <p><label><input id=\"keyerAudible\" type=\"checkbox\" checked> Audible Morse (play while keying\/typing)<\/label> <button id=\"playMorse\" type=\"button\">\u25b6 Play Entered Morse<\/button><\/p>\n          <\/div><\/div>\n          <div class=\"keyer-display-grid\">\n            <label>Manual Morse code<textarea id=\"keyerOutput\" rows=\"5\" readonly placeholder=\"Your keyed Morse will appear here\u2026\"><\/textarea><\/label>\n            <label>Decoded text (live)<textarea id=\"keyerDecoded\" rows=\"5\" readonly placeholder=\"Decoded text will appear here as code is entered\u2026\"><\/textarea><\/label>\n          <\/div>\n          <div class=\"morse-analyzer\" id=\"morseAnalyzer\"><h4>Code Analyzer \u2014 Live<\/h4><div id=\"morseAnalyzerGrid\" class=\"morse-analyzer-grid\"><div><strong>Quality<\/strong><span id=\"anQuality\">\u2014<\/span><\/div><div><strong>Speed<\/strong><span id=\"anSpeed\">\u2014<\/span><\/div><div><strong>Avg dot<\/strong><span id=\"anDot\">\u2014<\/span><\/div><div><strong>Avg dash<\/strong><span id=\"anDash\">\u2014<\/span><\/div><div><strong>Dot : dash<\/strong><span id=\"anRatio\">\u2014<\/span><\/div><div><strong>Timing consistency<\/strong><span id=\"anConsistency\">\u2014<\/span><\/div><div><strong>Character gap<\/strong><span id=\"anCharGap\">\u2014<\/span><\/div><div><strong>Word gap<\/strong><span id=\"anWordGap\">\u2014<\/span><\/div><\/div><div id=\"anCritique\" class=\"morse-analyzer-critique\">Start keying to measure timing, speed and code quality.<\/div><\/div>\n          <p class=\"note\">The keyed Morse is copied into the <strong>Entered code or bitstream<\/strong> field and decoded live on the right while you key.<\/p>\n        <\/section>\n        <section class=\"panel\"><h3>Entered code or bitstream<\/h3><label id=\"morseLabel\">Morse or bits<textarea id=\"morse\" rows=\"5\" placeholder=\"Morse: ... --- ...   Bits: 001011...\"><\/textarea><\/label><label>Decoded text<textarea id=\"text\" rows=\"5\"><\/textarea><\/label><p><button id=\"decodeTyped\" type=\"button\">Decode entered code<\/button> <button id=\"copyText\" type=\"button\">Copy text<\/button> <button id=\"saveReport\" type=\"button\">Save report<\/button><\/p><\/section>\n        <section class=\"panel\"><h3>Experimental Digital Encoders<\/h3>\n          <p class=\"note\">Keyboard text and text files can now be converted into additional digital-code representations. These are experimental data encoders: they create code\/bitstream payloads for analysis, saving, or handoff to a compatible modem\/adapter. They do not transmit RF.<\/p>\n          <div class=\"grid\">\n            <label>Encoder mode<select id=\"encodeMode\">\n              <optgroup label=\"Core\">\n                <option value=\"morse\">Morse \/ CW<\/option><option value=\"ita2\">RTTY \/ Baudot ITA2<\/option><option value=\"ascii7\">ASCII serial 7-bit<\/option><option value=\"ascii8\">ASCII serial 8-bit<\/option>\n              <\/optgroup>\n              <optgroup label=\"Experimental digital\">\n                <option value=\"psk31\">PSK31 \/ Varicode<\/option><option value=\"psk32\">PSK32 \/ Varicode<\/option><option value=\"psk63\">PSK63 \/ Varicode<\/option><option value=\"dtmf\">DTMF keypad symbols<\/option><option value=\"same\">SAME \/ EAS header text<\/option><option value=\"aprs\">APRS \/ AX.25 payload<\/option>\n              <\/optgroup>\n            <\/select><\/label>\n            <label id=\"encodeSpeedWrap\">Morse speed (WPM)<input id=\"encodeSpeed\" type=\"number\" min=\"5\" max=\"60\" value=\"15\"><\/label>\n            <label>Text file<input id=\"encodeFile\" type=\"file\" accept=\".txt,.text,.log,.csv,text\/plain,text\/csv\"> <\/label>\n          <\/div>\n          <label>Keyboard text input<textarea id=\"encodeInput\" rows=\"6\" placeholder=\"Type or paste text to encode\u2026\"><\/textarea><\/label>\n          <div class=\"encode-preview\"><strong>Typed text preview<\/strong><div id=\"encodeSpacePreview\" aria-live=\"polite\"><\/div><\/div>\n          <p><button id=\"encodeText\" class=\"primary\" type=\"button\">Encode text<\/button> <button id=\"playEncoded\" type=\"button\">\u25b6 Play Morse at selected speed<\/button> <button id=\"downloadEncoded\" type=\"button\">Save encoded file<\/button> <button id=\"clearEncoder\" type=\"button\">Clear<\/button><\/p>\n          <label>Encoded output<textarea id=\"encodeOutput\" rows=\"8\" readonly placeholder=\"Encoded output will appear here.\"><\/textarea><\/label>\n          <p id=\"encodeStatus\" class=\"note\">Keyboard and text-file input are supported. Experimental PSK modes output Varicode bitstreams; DTMF outputs keypad symbols; SAME outputs an alert-header template; APRS outputs an AX.25 payload representation.<\/p>\n        <\/section>\n        <section class=\"panel\"><h3>Experimental Digital Voice Encoder<\/h3>\n          <p class=\"note\">Use the microphone as the voice source, choose a digital-voice protocol, and prepare a codec job. Open Codec2\/FreeDV can be connected through a native\/WebAssembly adapter; protocols using AMBE\/IMBE\/ACELP require the appropriate licensed\/compatible vocoder. RF transmission and encryption remain disabled.<\/p>\n          <div class=\"grid\">\n            <label>Digital voice mode<select id=\"voiceEncodeMode\"><option value=\"m17\">M17 \u2014 Codec2<\/option><option value=\"freedv\">FreeDV \u2014 Codec2<\/option><option value=\"codec2\">Codec2 stream<\/option><option value=\"dmr\">DMR \u2014 AMBE+2<\/option><option value=\"p25p1\">P25 Phase 1 \u2014 IMBE<\/option><option value=\"p25p2\">P25 Phase 2 \u2014 AMBE+2<\/option><option value=\"dstar\">D-STAR \u2014 AMBE<\/option><option value=\"ysf\">YSF \u2014 AMBE+2<\/option><option value=\"nxdn\">NXDN \u2014 AMBE+2<\/option><option value=\"dpmr\">dPMR \u2014 AMBE+2<\/option><option value=\"tetra\">TETRA \u2014 ACELP<\/option><\/select><\/label>\n            <label>Microphone capture (seconds)<input id=\"voiceCaptureSeconds\" type=\"number\" min=\"1\" max=\"60\" value=\"5\"><\/label>\n            <label>Microphone volume <span id=\"voiceMicVolumeValue\">100%<\/span><input id=\"voiceMicVolume\" type=\"range\" min=\"0\" max=\"2\" step=\"0.01\" value=\"1\" aria-label=\"Microphone volume\"><\/label>\n          <\/div>\n          <p class=\"tw-mic-actions\"><button id=\"voiceMicStart\" class=\"primary\" type=\"button\">Start voice microphone capture<\/button> <button id=\"voiceMicStop\" type=\"button\" disabled>Stop &amp; encode<\/button> <span class=\"tw-save-options\" role=\"radiogroup\" aria-label=\"Voice microphone recording format\"><label><input type=\"radio\" name=\"voiceSaveFormat\" value=\"wav\"> WAV<\/label> <label><input type=\"radio\" name=\"voiceSaveFormat\" value=\"mp3\" checked> MP3<\/label><\/span> <button id=\"voiceSaveRecording\" type=\"button\" disabled>Save microphone recording<\/button><\/p>\n          <p id=\"voiceEncodeStatus\" class=\"note\">Ready. After capture you can save the microphone recording as WAV or MP3, or pass the PCM audio to the selected digital-voice encoder.<\/p>\n          <label>Voice encoder result<textarea id=\"voiceEncodeOutput\" rows=\"8\" readonly placeholder=\"Voice encoding preparation\/result will appear here.\"><\/textarea><\/label>\n        <\/section>\n        <section class=\"panel\"><h3>Usage report<\/h3><div id=\"report\"><p>Decode an audio source or entered code to generate a report.<\/p><\/div><\/section>\n        <section class=\"panel\"><h3>Over-the-air controls<\/h3><div class=\"grid\"><label><input id=\"autoTone\" type=\"checkbox\" checked> Auto-track strongest tone<\/label><label><input id=\"agc\" type=\"checkbox\" checked> Adaptive threshold<\/label><label><input id=\"noiseGate\" type=\"checkbox\" checked> Noise gate<\/label><\/div><p class=\"note\">Route receiver or SDR audio to the browser input. Use narrow filtering appropriate to the signal.<\/p><\/section>\n      <\/main>\n      <footer>\u00a9 2026 Thinker Works \u00b7 ThinkerWorks.com<\/footer>\n    <\/div>\n    \n","protected":false},"excerpt":{"rendered":"","protected":false},"author":0,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-485","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/w7rjp.com\/index.php\/wp-json\/wp\/v2\/pages\/485","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/w7rjp.com\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/w7rjp.com\/index.php\/wp-json\/wp\/v2\/types\/page"}],"replies":[{"embeddable":true,"href":"https:\/\/w7rjp.com\/index.php\/wp-json\/wp\/v2\/comments?post=485"}],"version-history":[{"count":0,"href":"https:\/\/w7rjp.com\/index.php\/wp-json\/wp\/v2\/pages\/485\/revisions"}],"wp:attachment":[{"href":"https:\/\/w7rjp.com\/index.php\/wp-json\/wp\/v2\/media?parent=485"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}