1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-11-29 19:28:47 -05:00

CW Keyer: interim state (2)

This commit is contained in:
f4exb 2016-12-09 19:34:38 +01:00
parent 35baa46f3d
commit 808a8c85fd
2 changed files with 237 additions and 82 deletions

View File

@ -15,8 +15,14 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. // // along with this program. If not, see <http://www.gnu.org/licenses/>. //
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
#include <QChar>
#include "cwkeyer.h" #include "cwkeyer.h"
/**
* 0: dot
* 1: dash
* -1: end of sequence
*/
const char m_asciiToMorse[][128] = { const char m_asciiToMorse[][128] = {
{-1}, // 0 {-1}, // 0
{-1}, // 1 {-1}, // 1
@ -50,7 +56,7 @@ const char m_asciiToMorse[][128] = {
{-1}, // 29 {-1}, // 29
{-1}, // 30 {-1}, // 30
{-1}, // 31 {-1}, // 31
{-1}, // 32 {-1}, // 32 space is treated as word separator
{1,0,1,0,1,1,-1}, // 33 ! {1,0,1,0,1,1,-1}, // 33 !
{0,1,0,0,1,0,-1}, // 34 " {0,1,0,0,1,0,-1}, // 34 "
{-1}, // 35 {-1}, // 35
@ -115,7 +121,7 @@ const char m_asciiToMorse[][128] = {
{-1}, // 94 ^ {-1}, // 94 ^
{-1}, // 95 _ {-1}, // 95 _
{-1}, // 96 ` {-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,0,0,-1}, // 98 B
{1,0,1,0,-1}, // 99 C {1,0,1,0,-1}, // 99 C
{1,0,0,-1}, // 100 D {1,0,0,-1}, // 100 D
@ -152,14 +158,17 @@ CWKeyer::CWKeyer() :
m_sampleRate(48000), m_sampleRate(48000),
m_textPointer(0), m_textPointer(0),
m_elementPointer(0), m_elementPointer(0),
m_samplePointer(0),
m_elementSpace(false), m_elementSpace(false),
m_characterSpace(false), m_characterSpace(false),
m_key(false), m_key(false),
m_dot(false), m_dot(false),
m_dash(false), m_dash(false),
m_elementOn(false), m_elementOn(false),
m_asciiChar('\0'),
m_mode(CWKey), m_mode(CWKey),
m_keyState(KeySilent) m_keyIambicState(KeySilent),
m_textState(TextStart)
{ {
setWPM(13); setWPM(13);
} }
@ -211,83 +220,212 @@ int CWKeyer::getSample()
} }
else if (m_mode == CWIambic) else if (m_mode == CWIambic)
{ {
switch (m_keyState) 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: case KeySilent:
if (m_dot) if (m_dot)
{ {
m_keyState = KeyDot; m_keyIambicState = KeyDot;
m_elementPointer = 0; m_samplePointer = 0;
} }
else if (m_dash) else if (m_dash)
{ {
m_keyState = KeyDash; m_keyIambicState = KeyDash;
m_elementPointer = 0; m_samplePointer = 0;
} }
m_key = false; m_key = false;
break; break;
case KeyDot: case KeyDot:
if (m_elementPointer < m_dotLength) // dot key if (m_samplePointer < m_dotLength) // dot key
{ {
m_key = true; m_key = true;
m_elementPointer++; m_samplePointer++;
} }
else if (m_elementPointer < 2*m_dotLength) // dot silence else if (m_samplePointer < 2*m_dotLength) // dot silence (+1 dot length)
{ {
m_key = false; m_key = false;
m_elementPointer++; m_samplePointer++;
} }
else // end else // end
{ {
if (m_dash) if (m_dash)
{ {
m_elementPointer = 0; m_samplePointer = 0;
m_keyState = KeyDash; m_keyIambicState = KeyDash;
} }
else if (!m_dot) else if (!m_dot)
{ {
m_keyState = KeySilent; m_keyIambicState = KeySilent;
} }
m_elementPointer = 0; m_samplePointer = 0;
m_key = false; m_key = false;
} }
break; break;
case KeyDash: case KeyDash:
if (m_elementPointer < 3*m_dotLength) // dash key if (m_samplePointer < 3*m_dotLength) // dash key
{ {
m_key = true; m_key = true;
m_elementPointer++; m_samplePointer++;
} }
else if (m_elementPointer < 4*m_dotLength) // dash silence else if (m_samplePointer < 4*m_dotLength) // dash silence (+1 dot length)
{ {
m_key = false; m_key = false;
m_elementPointer++; m_samplePointer++;
} }
else // end else // end
{ {
if (m_dot) if (m_dot)
{ {
m_elementPointer = 0; m_samplePointer = 0;
m_keyState = KeyDot; m_keyIambicState = KeyDot;
} }
else if (!m_dash) else if (!m_dash)
{ {
m_keyState = KeySilent; m_keyIambicState = KeySilent;
} }
m_elementPointer = 0; m_samplePointer = 0;
m_key = false; m_key = false;
} }
break; break;
default: default:
m_samplePointer = 0;
m_key = false;
break;
}
}
void CWKeyer::nextStateText()
{
// TODO...
switch (m_textState)
{
case TextStart:
m_samplePointer = 0;
m_elementPointer = 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; m_key = false;
break; break;
} }
return m_key ? 1 : 0;
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;
}
}
} }
} }

View File

@ -37,7 +37,18 @@ public:
KeySilent, KeySilent,
KeyDot, KeyDot,
KeyDash KeyDash
} CWKeyState; } CWKeyIambicState;
typedef enum
{
TextStart,
TextStartChar,
TextStartElement,
TextElement,
TextCharSpace,
TextWordSpace,
TextEnd
} CWTextState;
CWKeyer(); CWKeyer();
~CWKeyer(); ~CWKeyer();
@ -61,16 +72,22 @@ private:
QString m_text; QString m_text;
int m_textPointer; int m_textPointer;
int m_elementPointer; int m_elementPointer;
int m_samplePointer;
bool m_elementSpace; bool m_elementSpace;
bool m_characterSpace; bool m_characterSpace;
bool m_key; bool m_key;
bool m_dot; bool m_dot;
bool m_dash; bool m_dash;
bool m_elementOn; bool m_elementOn;
char m_asciiChar;
CWMode m_mode; CWMode m_mode;
CWKeyState m_keyState; CWKeyIambicState m_keyIambicState;
CWTextState m_textState;
static const char m_asciiToMorse[][128]; static const char m_asciiToMorse[][128];
void nextStateIambic();
void nextStateText();
}; };