mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-26 09:48:45 -05:00
CW Keyer: interim state (2)
This commit is contained in:
parent
35baa46f3d
commit
808a8c85fd
@ -15,8 +15,14 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <QChar>
|
||||
#include "cwkeyer.h"
|
||||
|
||||
/**
|
||||
* 0: dot
|
||||
* 1: dash
|
||||
* -1: end of sequence
|
||||
*/
|
||||
const char m_asciiToMorse[][128] = {
|
||||
{-1}, // 0
|
||||
{-1}, // 1
|
||||
@ -50,7 +56,7 @@ const char m_asciiToMorse[][128] = {
|
||||
{-1}, // 29
|
||||
{-1}, // 30
|
||||
{-1}, // 31
|
||||
{-1}, // 32
|
||||
{-1}, // 32 space is treated as word separator
|
||||
{1,0,1,0,1,1,-1}, // 33 !
|
||||
{0,1,0,0,1,0,-1}, // 34 "
|
||||
{-1}, // 35
|
||||
@ -115,7 +121,7 @@ const char m_asciiToMorse[][128] = {
|
||||
{-1}, // 94 ^
|
||||
{-1}, // 95 _
|
||||
{-1}, // 96 `
|
||||
{0,1,-1}, // 97 A
|
||||
{0,1,-1}, // 97 A lowercase same as uppercase
|
||||
{1,0,0,0,-1}, // 98 B
|
||||
{1,0,1,0,-1}, // 99 C
|
||||
{1,0,0,-1}, // 100 D
|
||||
@ -151,15 +157,18 @@ const char m_asciiToMorse[][128] = {
|
||||
CWKeyer::CWKeyer() :
|
||||
m_sampleRate(48000),
|
||||
m_textPointer(0),
|
||||
m_elementPointer(0),
|
||||
m_elementPointer(0),
|
||||
m_samplePointer(0),
|
||||
m_elementSpace(false),
|
||||
m_characterSpace(false),
|
||||
m_key(false),
|
||||
m_dot(false),
|
||||
m_dash(false),
|
||||
m_elementOn(false),
|
||||
m_asciiChar('\0'),
|
||||
m_mode(CWKey),
|
||||
m_keyState(KeySilent)
|
||||
m_keyIambicState(KeySilent),
|
||||
m_textState(TextStart)
|
||||
{
|
||||
setWPM(13);
|
||||
}
|
||||
@ -211,83 +220,212 @@ int CWKeyer::getSample()
|
||||
}
|
||||
else if (m_mode == CWIambic)
|
||||
{
|
||||
switch (m_keyState)
|
||||
{
|
||||
case KeySilent:
|
||||
if (m_dot)
|
||||
{
|
||||
m_keyState = KeyDot;
|
||||
m_elementPointer = 0;
|
||||
}
|
||||
else if (m_dash)
|
||||
{
|
||||
m_keyState = KeyDash;
|
||||
m_elementPointer = 0;
|
||||
}
|
||||
|
||||
m_key = false;
|
||||
break;
|
||||
case KeyDot:
|
||||
if (m_elementPointer < m_dotLength) // dot key
|
||||
{
|
||||
m_key = true;
|
||||
m_elementPointer++;
|
||||
}
|
||||
else if (m_elementPointer < 2*m_dotLength) // dot silence
|
||||
{
|
||||
m_key = false;
|
||||
m_elementPointer++;
|
||||
}
|
||||
else // end
|
||||
{
|
||||
if (m_dash)
|
||||
{
|
||||
m_elementPointer = 0;
|
||||
m_keyState = KeyDash;
|
||||
}
|
||||
else if (!m_dot)
|
||||
{
|
||||
m_keyState = KeySilent;
|
||||
}
|
||||
|
||||
m_elementPointer = 0;
|
||||
m_key = false;
|
||||
}
|
||||
break;
|
||||
case KeyDash:
|
||||
if (m_elementPointer < 3*m_dotLength) // dash key
|
||||
{
|
||||
m_key = true;
|
||||
m_elementPointer++;
|
||||
}
|
||||
else if (m_elementPointer < 4*m_dotLength) // dash silence
|
||||
{
|
||||
m_key = false;
|
||||
m_elementPointer++;
|
||||
}
|
||||
else // end
|
||||
{
|
||||
if (m_dot)
|
||||
{
|
||||
m_elementPointer = 0;
|
||||
m_keyState = KeyDot;
|
||||
}
|
||||
else if (!m_dash)
|
||||
{
|
||||
m_keyState = KeySilent;
|
||||
}
|
||||
|
||||
m_elementPointer = 0;
|
||||
m_key = false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
m_elementPointer = 0;
|
||||
m_key = false;
|
||||
break;
|
||||
}
|
||||
|
||||
nextStateIambic();
|
||||
return m_key ? 1 : 0;
|
||||
}
|
||||
else if (m_mode == CWText)
|
||||
{
|
||||
nextStateText();
|
||||
return m_key ? 1 : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void CWKeyer::nextStateIambic()
|
||||
{
|
||||
switch (m_keyIambicState)
|
||||
{
|
||||
case KeySilent:
|
||||
if (m_dot)
|
||||
{
|
||||
m_keyIambicState = KeyDot;
|
||||
m_samplePointer = 0;
|
||||
}
|
||||
else if (m_dash)
|
||||
{
|
||||
m_keyIambicState = KeyDash;
|
||||
m_samplePointer = 0;
|
||||
}
|
||||
|
||||
m_key = false;
|
||||
break;
|
||||
case KeyDot:
|
||||
if (m_samplePointer < m_dotLength) // dot key
|
||||
{
|
||||
m_key = true;
|
||||
m_samplePointer++;
|
||||
}
|
||||
else if (m_samplePointer < 2*m_dotLength) // dot silence (+1 dot length)
|
||||
{
|
||||
m_key = false;
|
||||
m_samplePointer++;
|
||||
}
|
||||
else // end
|
||||
{
|
||||
if (m_dash)
|
||||
{
|
||||
m_samplePointer = 0;
|
||||
m_keyIambicState = KeyDash;
|
||||
}
|
||||
else if (!m_dot)
|
||||
{
|
||||
m_keyIambicState = KeySilent;
|
||||
}
|
||||
|
||||
m_samplePointer = 0;
|
||||
m_key = false;
|
||||
}
|
||||
break;
|
||||
case KeyDash:
|
||||
if (m_samplePointer < 3*m_dotLength) // dash key
|
||||
{
|
||||
m_key = true;
|
||||
m_samplePointer++;
|
||||
}
|
||||
else if (m_samplePointer < 4*m_dotLength) // dash silence (+1 dot length)
|
||||
{
|
||||
m_key = false;
|
||||
m_samplePointer++;
|
||||
}
|
||||
else // end
|
||||
{
|
||||
if (m_dot)
|
||||
{
|
||||
m_samplePointer = 0;
|
||||
m_keyIambicState = KeyDot;
|
||||
}
|
||||
else if (!m_dash)
|
||||
{
|
||||
m_keyIambicState = KeySilent;
|
||||
}
|
||||
|
||||
m_samplePointer = 0;
|
||||
m_key = false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
m_samplePointer = 0;
|
||||
m_key = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CWKeyer::nextStateText()
|
||||
{
|
||||
// TODO...
|
||||
switch (m_textState)
|
||||
{
|
||||
case TextStart:
|
||||
m_samplePointer = 0;
|
||||
m_elementPointer = 0;
|
||||
m_textPointer = 0;
|
||||
m_textState = TextStartChar;
|
||||
nextStateText();
|
||||
break;
|
||||
case TextStartChar:
|
||||
m_samplePointer = 0;
|
||||
m_elementPointer = 0;
|
||||
m_textState = TextStartElement;
|
||||
break;
|
||||
case TextStartElement:
|
||||
m_samplePointer = 0;
|
||||
m_textState = TextElement;
|
||||
break;
|
||||
case TextElement:
|
||||
nextStateIambic(); // dash or dot
|
||||
if (m_samplePointer == 0) // done
|
||||
{
|
||||
m_textState = TextStartElement; // next element
|
||||
}
|
||||
break;
|
||||
case TextCharSpace:
|
||||
if (m_samplePointer < 3*m_dotLength)
|
||||
{
|
||||
m_samplePointer++;
|
||||
m_key = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_samplePointer = 0;
|
||||
m_textState = TextStartChar;
|
||||
}
|
||||
break;
|
||||
case TextWordSpace:
|
||||
if (m_samplePointer < 7*m_dotLength)
|
||||
{
|
||||
m_samplePointer++;
|
||||
m_key = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_samplePointer = 0;
|
||||
m_textState = TextStartChar;
|
||||
}
|
||||
break;
|
||||
case TextEnd:
|
||||
default:
|
||||
m_key = false;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (m_samplePointer == 0) // element not started or finished
|
||||
{
|
||||
if (m_asciiToMorse[m_elementPointer][m_asciiChar] == -1) // end of morse symbol
|
||||
{
|
||||
m_keyIambicState = KeyCharSpace;
|
||||
m_samplePointer++;
|
||||
m_key = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_asciiToMorse[m_elementPointer][m_asciiChar] == 0) // dot
|
||||
{
|
||||
m_dot = true;
|
||||
m_dash = false;
|
||||
}
|
||||
else // dash
|
||||
{
|
||||
m_dot = false;
|
||||
m_dash = true;
|
||||
}
|
||||
|
||||
nextStateIambic();
|
||||
}
|
||||
|
||||
if (m_textPointer < m_text.length())
|
||||
{
|
||||
m_asciiChar = (m_text[m_textPointer]).toAscii();
|
||||
|
||||
if (m_asciiChar < 0) {
|
||||
m_asciiChar = 0;
|
||||
}
|
||||
|
||||
m_elementPointer = 0;
|
||||
m_textPointer++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: end of text
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((m_keyIambicState == KeyDot) || (m_keyIambicState == KeyDash))
|
||||
{
|
||||
nextStateIambic();
|
||||
}
|
||||
else if (m_keyIambicState == KeyCharSpace)
|
||||
{
|
||||
if (m_samplePointer < 2*m_dotLength) // rest of a dash period (+2 dot periods)
|
||||
{
|
||||
m_samplePointer++;
|
||||
m_key = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -37,7 +37,18 @@ public:
|
||||
KeySilent,
|
||||
KeyDot,
|
||||
KeyDash
|
||||
} CWKeyState;
|
||||
} CWKeyIambicState;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TextStart,
|
||||
TextStartChar,
|
||||
TextStartElement,
|
||||
TextElement,
|
||||
TextCharSpace,
|
||||
TextWordSpace,
|
||||
TextEnd
|
||||
} CWTextState;
|
||||
|
||||
CWKeyer();
|
||||
~CWKeyer();
|
||||
@ -61,16 +72,22 @@ private:
|
||||
QString m_text;
|
||||
int m_textPointer;
|
||||
int m_elementPointer;
|
||||
int m_samplePointer;
|
||||
bool m_elementSpace;
|
||||
bool m_characterSpace;
|
||||
bool m_key;
|
||||
bool m_dot;
|
||||
bool m_dash;
|
||||
bool m_elementOn;
|
||||
char m_asciiChar;
|
||||
CWMode m_mode;
|
||||
CWKeyState m_keyState;
|
||||
CWKeyIambicState m_keyIambicState;
|
||||
CWTextState m_textState;
|
||||
|
||||
static const char m_asciiToMorse[][128];
|
||||
|
||||
void nextStateIambic();
|
||||
void nextStateText();
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user