From e4f4d845ccb8cc6343c7e29a494b24daf34a4681 Mon Sep 17 00:00:00 2001 From: Wojciech Kaczmarski Date: Fri, 6 Feb 2026 16:43:06 +0100 Subject: [PATCH] updates - bump up libm17 - scheduler tweaks (Codec2 blocks) - "reset" message input in C2 decoder --- grc/m17_codec2_decoder.block.yml | 4 ++- include/gnuradio/m17/CMakeLists.txt | 2 +- lib/codec2_decoder_impl.cc | 55 ++++++++++++++++++++++++++--- lib/codec2_decoder_impl.h | 1 + lib/codec2_encoder_impl.cc | 24 +++++++------ libm17 | 2 +- 6 files changed, 70 insertions(+), 18 deletions(-) diff --git a/grc/m17_codec2_decoder.block.yml b/grc/m17_codec2_decoder.block.yml index d56be51..4ac340d 100644 --- a/grc/m17_codec2_decoder.block.yml +++ b/grc/m17_codec2_decoder.block.yml @@ -19,7 +19,9 @@ inputs: dtype: byte vlen: 1 optional: 0 - +- label: state_reset + domain: message + optional: 1 outputs: - label: out diff --git a/include/gnuradio/m17/CMakeLists.txt b/include/gnuradio/m17/CMakeLists.txt index c7d7822..5a0c02e 100644 --- a/include/gnuradio/m17/CMakeLists.txt +++ b/include/gnuradio/m17/CMakeLists.txt @@ -13,7 +13,7 @@ install(FILES api.h codec2_encoder.h codec2_decoder.h - symbol_sync.h + #symbol_sync.h m17_coder.h m17_decoder.h DESTINATION include/gnuradio/m17 ) diff --git a/lib/codec2_decoder_impl.cc b/lib/codec2_decoder_impl.cc index a0129c8..2660836 100644 --- a/lib/codec2_decoder_impl.cc +++ b/lib/codec2_decoder_impl.cc @@ -42,8 +42,45 @@ namespace gr codec2_decoder_impl::codec2_decoder_impl() : gr::block("codec2_decoder", gr::io_signature::make(1, 1, sizeof(uint8_t)), gr::io_signature::make(1, 1, sizeof(int16_t))) { + set_output_multiple(CODEC2_SAMPLES_PER_FRAME); + init_state(); + message_port_register_in(pmt::mp("state_reset")); + + set_msg_handler( + pmt::mp("state_reset"), + boost::bind(&codec2_decoder_impl::reset, this, + boost::placeholders::_1)); + } + + // TODO: fix this function! + void codec2_decoder_impl::reset(const pmt::pmt_t &msg) + { + std::string cmd = ""; + + if (pmt::is_symbol(msg)) + { + cmd = pmt::symbol_to_string(msg); + } + + time_t now = time(NULL); + struct tm t; + localtime_r(&now, &t); + + if (cmd == "SOT") + { + ; + return; + } + + if (cmd == "EOT") + { + codec2_init(&c2); // i hope this is the right place to put it + return; + } + + fprintf(stderr, "[%02d:%02d:%02d] Strange message received\n", t.tm_hour, t.tm_min, t.tm_sec); } void codec2_decoder_impl::init_state(void) @@ -62,7 +99,7 @@ namespace gr codec2_decoder_impl::forecast(int noutput_items, gr_vector_int &ninput_items_required) { - ninput_items_required[0] = CODEC2_BYTES_PER_FRAME; + ninput_items_required[0] = (noutput_items / CODEC2_SAMPLES_PER_FRAME) * CODEC2_BYTES_PER_FRAME; } int @@ -72,7 +109,6 @@ namespace gr gr_vector_void_star &output_items) { const uint8_t *bits = static_cast(input_items[0]); - int16_t *speech = static_cast(output_items[0]); if (ninput_items[0] < CODEC2_BYTES_PER_FRAME) @@ -81,11 +117,20 @@ namespace gr if (noutput_items < CODEC2_SAMPLES_PER_FRAME) return 0; - codec2_decode(&c2, speech, bits); + int frames = std::min( + ninput_items[0] / CODEC2_BYTES_PER_FRAME, + noutput_items / CODEC2_SAMPLES_PER_FRAME); - consume_each(CODEC2_BYTES_PER_FRAME); + for (int i = 0; i < frames; i++) + { + codec2_decode(&c2, + speech + i * CODEC2_SAMPLES_PER_FRAME, + bits + i * CODEC2_BYTES_PER_FRAME); + } - return CODEC2_SAMPLES_PER_FRAME; + consume_each(frames * CODEC2_BYTES_PER_FRAME); + + return frames * CODEC2_SAMPLES_PER_FRAME; } } /* namespace m17 */ } /* namespace gr */ diff --git a/lib/codec2_decoder_impl.h b/lib/codec2_decoder_impl.h index 52ff3a3..0afc67a 100644 --- a/lib/codec2_decoder_impl.h +++ b/lib/codec2_decoder_impl.h @@ -31,6 +31,7 @@ namespace gr private: codec2_t c2; + void reset(const pmt::pmt_t &msg); void init_state(void); public: diff --git a/lib/codec2_encoder_impl.cc b/lib/codec2_encoder_impl.cc index 90f2171..c2f5bb2 100644 --- a/lib/codec2_encoder_impl.cc +++ b/lib/codec2_encoder_impl.cc @@ -42,6 +42,8 @@ namespace gr codec2_encoder_impl::codec2_encoder_impl() : gr::block("codec2_encoder", gr::io_signature::make(1, 1, sizeof(int16_t)), gr::io_signature::make(1, 1, sizeof(uint8_t))) { + set_output_multiple(CODEC2_BYTES_PER_FRAME); + init_state(); message_port_register_in(pmt::mp("state_reset")); @@ -50,8 +52,6 @@ namespace gr pmt::mp("state_reset"), boost::bind(&codec2_encoder_impl::reset, this, boost::placeholders::_1)); - - ; } // TODO: fix this function! @@ -99,7 +99,7 @@ namespace gr codec2_encoder_impl::forecast(int noutput_items, gr_vector_int &ninput_items_required) { - ninput_items_required[0] = CODEC2_SAMPLES_PER_FRAME; // 160 samples + ninput_items_required[0] = (noutput_items / CODEC2_BYTES_PER_FRAME) * CODEC2_SAMPLES_PER_FRAME; } int @@ -109,7 +109,6 @@ namespace gr gr_vector_void_star &output_items) { const int16_t *speech = static_cast(input_items[0]); - uint8_t *bits = static_cast(output_items[0]); // we need one full speech frame @@ -120,14 +119,19 @@ namespace gr if (noutput_items < CODEC2_BYTES_PER_FRAME) return 0; - // encode exactly one frame - codec2_encode(&c2, bits, const_cast(speech)); + int frames = std::min( + ninput_items[0] / CODEC2_SAMPLES_PER_FRAME, + noutput_items / CODEC2_BYTES_PER_FRAME); - // consume 160 samples - consume_each(CODEC2_SAMPLES_PER_FRAME); + for (int i = 0; i < frames; i++) + { + codec2_encode(&c2, + bits + i * CODEC2_BYTES_PER_FRAME, + speech + i * CODEC2_SAMPLES_PER_FRAME); + } - // produce 8 bytes - return CODEC2_BYTES_PER_FRAME; + consume_each(frames * CODEC2_SAMPLES_PER_FRAME); + return frames * CODEC2_BYTES_PER_FRAME; } } /* namespace m17 */ } /* namespace gr */ diff --git a/libm17 b/libm17 index 0f84226..07926d0 160000 --- a/libm17 +++ b/libm17 @@ -1 +1 @@ -Subproject commit 0f84226f5a284610d565d52447867f26c6ca4da7 +Subproject commit 07926d08ade8509f1ce55d0289f229ab44cbcf51