#include "morse.h" #include "utils.h" // Spočteme číslo (pro 1kHz) jako (1000 << 32) / 24000 (24 kHz je samplerate). static constexpr unsigned F0 = (1000ull << 32) / 24000u; static constexpr const char * const morse_code [] = { /* nedefinované znaky nahrazeny mezerou */ " ", /* */ " ", /*!*/ ".-..-.", /*\"*/ " ", /*#*/ " ", /*$*/ " ", /*%*/ " ", /*&*/ ".----.", /*\'*/ "-.--.", /*(*/ "-.--.-", /*)*/ " ", /***/ ".-.-.", /*+*/ "--..--", /*,*/ "-....-", /*-*/ ".-.-.-", /*.*/ "-..-." , /*/*/ "-----", /*0*/ ".----", /*1*/ "..---", /*2*/ "...--", /*3*/ "....-", /*4*/ ".....", /*5*/ "-....", /*6*/ "--...", /*7*/ "---..", /*8*/ "----.", /*9*/ "---...", /*:*/ "-.-.-.", /*;*/ " ", /*<*/ "-...-" , /*=*/ " ", /*>*/ "..--..", /*?*/ ".--.-.", /*@*/ ".-", /*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*/ " ", " ", " ", " ", "..--.-", /*_*/ }; static constexpr unsigned slen (const char * const str) { unsigned n = 0; while (str[n]) n++; return n; } static constexpr unsigned char compress (const unsigned n) { const char * const ptr = morse_code [n]; const unsigned len = slen (ptr); unsigned char mb = 0u; if (ptr [0] == ' ') return mb; mb = (len & 7u) << 5; for (unsigned n=0; n compressed_table (compress); extern void print_morse_table (const TABLE & tab); Morse::Morse(const GpioClass & pin, const unsigned int ms) noexcept : unit (ms), led (pin), gen (F0), pwm () { pwm.attach(gen); #ifdef __linux__ print_morse_table (compressed_table); #endif } const Morse & Morse::operator<< (const char * text) { for (unsigned n=0; ; n++) { const char c = text [n]; if (c == '\0') break; morse_byte mb; if (c < '\x20') { } else if (c < '`') { const int i = c - '\x20'; mb.byte = compressed_table [i]; } else if (c == '`') { } else if (c <= 'z') { const int i = c - '\x40'; mb.byte = compressed_table [i]; } else { } out (mb); } gen.delay (10 * unit); return * this; } /* . => 1 x unit * - => 3 x unit * mezera mezi značkami => 1 x unit * mezera mezi znaky => 3 x unit * mezera mezi slovy => 7 x unit * */ void Morse::out (const morse_byte mb) { /* Finta je v tom, že i když se pole mlen a bits překrývají, * nevadí to - maximální délka je 6, takže v nejnižším bitu * mlen může být obsažen 1 bit 6.bitového znaku. * Takhle napsáno to běhá jen na malém indiánu, přepisovat * to do bitových posunů nebudu, i když by to bylo čistší. * */ const unsigned len = mb.mlen > 6u ? 6u : mb.mlen; if (!len) { gen.delay (4 * unit); return; } for (unsigned n=0; n