Improve CW decoding performance and complexity
This commit is contained in:
parent
5d9fc19e3b
commit
94eef1463c
|
@ -59,17 +59,22 @@ namespace gr
|
|||
d_window_size(0),
|
||||
d_window_cnt(0),
|
||||
d_dot_windows_num(0),
|
||||
d_state (IDLE),
|
||||
d_dec_state (NO_SYNC),
|
||||
d_prev_space_symbol (true),
|
||||
d_sync_state (SYNC_TRIGGER_OFF)
|
||||
d_prev_space_symbol (true)
|
||||
{
|
||||
if(wpm < MIN_WPM){
|
||||
throw std::invalid_argument("Decoder can not handle such low WPM setting");
|
||||
if (wpm < MIN_WPM) {
|
||||
throw std::invalid_argument (
|
||||
"Decoder can not handle such low WPM setting");
|
||||
}
|
||||
|
||||
if(wpm > MAX_WPM) {
|
||||
throw std::invalid_argument("Decoder can not handle such high WPM setting");
|
||||
if (wpm > MAX_WPM) {
|
||||
throw std::invalid_argument (
|
||||
"Decoder can not handle such high WPM setting");
|
||||
}
|
||||
|
||||
if (conf_level > 1.0 || conf_level < 0.5) {
|
||||
throw std::invalid_argument (
|
||||
"Confidence level should be in the range [0.5, 1.0]");
|
||||
}
|
||||
|
||||
message_port_register_in (pmt::mp ("act_threshold"));
|
||||
|
@ -137,6 +142,12 @@ namespace gr
|
|||
message_port_pub (pmt::mp ("out"), pmt::from_long (s));
|
||||
}
|
||||
|
||||
inline bool
|
||||
cw_to_symbol_impl::check_conf_level(size_t cnt, size_t target)
|
||||
{
|
||||
return ((float)cnt > target * d_confidence_level);
|
||||
}
|
||||
|
||||
/*
|
||||
* Our virtual destructor.
|
||||
*/
|
||||
|
@ -150,14 +161,13 @@ namespace gr
|
|||
inline void
|
||||
cw_to_symbol_impl::set_idle ()
|
||||
{
|
||||
d_state = IDLE;
|
||||
d_dec_state = NO_SYNC;
|
||||
d_window_cnt = 0;
|
||||
}
|
||||
|
||||
inline void
|
||||
cw_to_symbol_impl::set_short_on ()
|
||||
{
|
||||
d_state = TRIGGED;
|
||||
d_dec_state = SEARCH_DOT;
|
||||
d_window_cnt = 1;
|
||||
}
|
||||
|
@ -169,18 +179,12 @@ namespace gr
|
|||
}
|
||||
|
||||
inline void
|
||||
cw_to_symbol_impl::set_short_off ()
|
||||
cw_to_symbol_impl::set_search_space ()
|
||||
{
|
||||
d_dec_state = SEARCH_SHORT_OFF;
|
||||
d_dec_state = SEARCH_SPACE;
|
||||
d_window_cnt = 1;
|
||||
}
|
||||
|
||||
inline void
|
||||
cw_to_symbol_impl::set_long_off ()
|
||||
{
|
||||
d_dec_state = SEARCH_LONG_OFF;
|
||||
}
|
||||
|
||||
void
|
||||
cw_to_symbol_impl::set_act_threshold_msg_handler (pmt::pmt_t msg)
|
||||
{
|
||||
|
@ -194,15 +198,13 @@ namespace gr
|
|||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items)
|
||||
{
|
||||
int32_t cnt;
|
||||
bool triggered;
|
||||
int i;
|
||||
const float *in_old = (const float *) input_items[0];
|
||||
const float *in = in_old + history() - 1;
|
||||
float conf;
|
||||
|
||||
/* During idle state search for a possible trigger */
|
||||
if(d_state == IDLE) {
|
||||
if(d_dec_state == NO_SYNC) {
|
||||
for(i = 0; i < noutput_items; i++) {
|
||||
/*
|
||||
* Clamp the input so the window mean is not affected by strong spikes
|
||||
|
@ -210,19 +212,76 @@ namespace gr
|
|||
*/
|
||||
triggered = is_triggered(in_old + i, d_window_size);
|
||||
if(triggered) {
|
||||
LOG_DEBUG("Triggered!");
|
||||
set_short_on();
|
||||
return i+1;
|
||||
}
|
||||
}
|
||||
return noutput_items;
|
||||
}
|
||||
else{
|
||||
/* From now one, we handle the input in multiples of a window */
|
||||
for (i = 0; i < noutput_items / d_window_size; i++) {
|
||||
triggered = is_triggered(in + i * d_window_size, d_window_size);
|
||||
|
||||
/* From now one, we handle the input in multiples of a window */
|
||||
for (i = 0; i < noutput_items / d_window_size; i++) {
|
||||
triggered = is_triggered(in + i * d_window_size, d_window_size);
|
||||
switch(d_dec_state) {
|
||||
case SEARCH_DOT:
|
||||
if(triggered) {
|
||||
d_window_cnt++;
|
||||
if(d_window_cnt > d_dot_windows_num) {
|
||||
set_long_on();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(check_conf_level(d_window_cnt, d_dot_windows_num)) {
|
||||
LOG_DEBUG("DOT");
|
||||
send_symbol_msg(MORSE_DOT);
|
||||
}
|
||||
set_search_space ();
|
||||
}
|
||||
break;
|
||||
case SEARCH_DASH:
|
||||
if(triggered) {
|
||||
d_window_cnt++;
|
||||
}
|
||||
else{
|
||||
if(check_conf_level(d_window_cnt, d_dash_windows_num)) {
|
||||
LOG_DEBUG("DASH");
|
||||
send_symbol_msg(MORSE_DASH);
|
||||
}
|
||||
else{
|
||||
LOG_DEBUG("DOT");
|
||||
send_symbol_msg(MORSE_DOT);
|
||||
}
|
||||
set_search_space ();
|
||||
}
|
||||
break;
|
||||
case SEARCH_SPACE:
|
||||
if (triggered) {
|
||||
if(check_conf_level(d_window_cnt, d_long_pause_windows_num)) {
|
||||
LOG_DEBUG("LONG SPACE");
|
||||
send_symbol_msg(MORSE_L_SPACE);
|
||||
}
|
||||
else if(check_conf_level(d_window_cnt, d_short_pause_windows_num)){
|
||||
LOG_DEBUG("SHORT SPACE");
|
||||
send_symbol_msg(MORSE_S_SPACE);
|
||||
}
|
||||
set_short_on();
|
||||
}
|
||||
else{
|
||||
d_window_cnt++;
|
||||
if(d_window_cnt > d_long_pause_windows_num) {
|
||||
LOG_DEBUG("LONG SPACE");
|
||||
send_symbol_msg(MORSE_L_SPACE);
|
||||
set_idle();
|
||||
return (i + 1) * d_window_size;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("Invalid decoder state");
|
||||
}
|
||||
}
|
||||
return noutput_items;
|
||||
return i * d_window_size;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -32,25 +32,12 @@ namespace gr
|
|||
|
||||
class cw_to_symbol_impl : public cw_to_symbol
|
||||
{
|
||||
typedef enum
|
||||
{
|
||||
IDLE, TRIGGED
|
||||
} cw_state_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
NO_SYNC, SEARCH_DOT, SEARCH_DASH, SEARCH_SHORT_OFF, SEARCH_LONG_OFF,
|
||||
NO_SYNC, SEARCH_DOT, SEARCH_DASH, SEARCH_SPACE
|
||||
} cw_dec_state_t;
|
||||
|
||||
/**
|
||||
* Different states during the WPM auto synchronization
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
SYNC_TRIGGER_OFF, //!< SYNC_TRIGGER_OFF Signal is below threshold
|
||||
SYNC_TRIGGER_ON //!< SYNC_TRIGGER_ON Signal is above threshold
|
||||
} sync_state_t;
|
||||
|
||||
private:
|
||||
const double d_sampling_rate;
|
||||
float d_act_thrshld;
|
||||
|
@ -62,10 +49,8 @@ namespace gr
|
|||
size_t d_dash_windows_num;
|
||||
size_t d_short_pause_windows_num;
|
||||
size_t d_long_pause_windows_num;
|
||||
cw_state_t d_state;
|
||||
cw_dec_state_t d_dec_state;
|
||||
bool d_prev_space_symbol;
|
||||
sync_state_t d_sync_state;
|
||||
float *d_const_val;
|
||||
float *d_tmp;
|
||||
int32_t *d_out;
|
||||
|
@ -80,10 +65,7 @@ namespace gr
|
|||
set_long_on ();
|
||||
|
||||
inline void
|
||||
set_short_off ();
|
||||
|
||||
inline void
|
||||
set_long_off ();
|
||||
set_search_space ();
|
||||
|
||||
inline int32_t
|
||||
hadd (const int32_t *in, size_t len);
|
||||
|
@ -97,6 +79,9 @@ namespace gr
|
|||
inline void
|
||||
send_symbol_msg (morse_symbol_t s);
|
||||
|
||||
inline bool
|
||||
check_conf_level(size_t cnt, size_t target);
|
||||
|
||||
void
|
||||
set_act_threshold_msg_handler (pmt::pmt_t msg);
|
||||
|
||||
|
|
Loading…
Reference in New Issue