kopia lustrzana https://github.com/ogre/habdec
Preliminary SSDV support.
rodzic
2a35d32e4b
commit
1d198baa22
|
@ -0,0 +1,3 @@
|
||||||
|
[submodule "code/ssdv"]
|
||||||
|
path = code/ssdv
|
||||||
|
url = https://github.com/fsphil/ssdv.git
|
|
@ -17,6 +17,7 @@ message ( "CMAKE_INSTALL_PREFIX: " ${CMAKE_INSTALL_PREFIX} )
|
||||||
|
|
||||||
add_subdirectory("Decoder")
|
add_subdirectory("Decoder")
|
||||||
add_subdirectory("IQSource")
|
add_subdirectory("IQSource")
|
||||||
|
add_subdirectory("ssdv_build")
|
||||||
add_subdirectory("websocketServer")
|
add_subdirectory("websocketServer")
|
||||||
|
|
||||||
option( fltkGUI "fltkGUI" OFF )
|
option( fltkGUI "fltkGUI" OFF )
|
||||||
|
|
|
@ -31,6 +31,7 @@ set ( Decoder_src
|
||||||
sentence_extract.h sentence_extract.cpp
|
sentence_extract.h sentence_extract.cpp
|
||||||
SpectrumInfo.h
|
SpectrumInfo.h
|
||||||
SymbolExtractor.h
|
SymbolExtractor.h
|
||||||
|
ssdv_wrapper.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
SET( CMAKE_CXX_FLAGS " -O3 " )
|
SET( CMAKE_CXX_FLAGS " -O3 " )
|
||||||
|
@ -50,6 +51,7 @@ endif()
|
||||||
|
|
||||||
add_library( Decoder ${Decoder_src})
|
add_library( Decoder ${Decoder_src})
|
||||||
target_link_libraries( Decoder
|
target_link_libraries( Decoder
|
||||||
|
ssdv_lib
|
||||||
#${SoapySDR_LIBRARIES}
|
#${SoapySDR_LIBRARIES}
|
||||||
${FFTW3f_LIBRARIES}
|
${FFTW3f_LIBRARIES}
|
||||||
${PlatformSpecificLinking} )
|
${PlatformSpecificLinking} )
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#include "SpectrumInfo.h"
|
#include "SpectrumInfo.h"
|
||||||
#include "print_habhub_sentence.h"
|
#include "print_habhub_sentence.h"
|
||||||
#include "CRC.h"
|
#include "CRC.h"
|
||||||
|
#include "ssdv_wrapper.h"
|
||||||
|
|
||||||
namespace habdec
|
namespace habdec
|
||||||
{
|
{
|
||||||
|
@ -178,6 +179,9 @@ private:
|
||||||
std::string last_sentence_; // result of rtty
|
std::string last_sentence_; // result of rtty
|
||||||
// size_t last_sentence_len_ = 0; // optimization for regexp run
|
// size_t last_sentence_len_ = 0; // optimization for regexp run
|
||||||
|
|
||||||
|
// SSDV
|
||||||
|
SSDV_wraper_t ssdv_;
|
||||||
|
|
||||||
// threading
|
// threading
|
||||||
mutable std::mutex process_mutex_; // mutex for main processing
|
mutable std::mutex process_mutex_; // mutex for main processing
|
||||||
|
|
||||||
|
@ -555,14 +559,19 @@ void habdec::Decoder<TReal>::process()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
auto decoded_chars = rtty_.get();
|
vector<char> raw_chars = rtty_.get();
|
||||||
rtty_char_stream_.insert( rtty_char_stream_.end(), decoded_chars.begin(), decoded_chars.end() );
|
ssdv_.push(raw_chars);
|
||||||
chr_callback_stream_.insert( chr_callback_stream_.end(), decoded_chars.begin(), decoded_chars.end() );
|
|
||||||
|
|
||||||
|
vector<char> printable_chars;
|
||||||
|
copy_if( raw_chars.begin(), raw_chars.end(), back_inserter(printable_chars),
|
||||||
|
[](char c){return isprint(c) || c == '\n';}
|
||||||
|
);
|
||||||
|
rtty_char_stream_.insert( rtty_char_stream_.end(), printable_chars.begin(), printable_chars.end() );
|
||||||
|
chr_callback_stream_.insert( chr_callback_stream_.end(), printable_chars.begin(), printable_chars.end() );
|
||||||
|
|
||||||
if(live_print_)
|
if(live_print_)
|
||||||
{
|
{
|
||||||
for( auto c : decoded_chars )
|
for( auto c : printable_chars )
|
||||||
cout<<c;
|
cout<<c;
|
||||||
cout.flush();
|
cout.flush();
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,7 +84,7 @@ size_t RTTY<TBit>::operator()()
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
size_t decoded_chars = 0;
|
size_t n_decoded_chars = 0;
|
||||||
size_t last_decoded_bit_index = 0;
|
size_t last_decoded_bit_index = 0;
|
||||||
|
|
||||||
for(size_t i=0; i<bits_.size()/*-char_bitlen*/; /**/)
|
for(size_t i=0; i<bits_.size()/*-char_bitlen*/; /**/)
|
||||||
|
@ -118,10 +118,10 @@ size_t RTTY<TBit>::operator()()
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( isprint(c) || c == '\n' )
|
// if( isprint(c) || c == '\n' )
|
||||||
{
|
{
|
||||||
chars_.push_back(c);
|
chars_.push_back(c);
|
||||||
++decoded_chars;
|
++n_decoded_chars;
|
||||||
}
|
}
|
||||||
|
|
||||||
i += nstops_;
|
i += nstops_;
|
||||||
|
@ -133,7 +133,7 @@ size_t RTTY<TBit>::operator()()
|
||||||
if(last_decoded_bit_index)
|
if(last_decoded_bit_index)
|
||||||
bits_.erase( bits_.begin(), bits_.begin() + last_decoded_bit_index + 1 );
|
bits_.erase( bits_.begin(), bits_.begin() + last_decoded_bit_index + 1 );
|
||||||
|
|
||||||
return decoded_chars;
|
return n_decoded_chars;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,167 @@
|
||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2018 Michal Fratczak
|
||||||
|
|
||||||
|
This file is part of habdec.
|
||||||
|
|
||||||
|
habdec is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
habdec is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with habdec. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ssdv_wrapper.h"
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstring>
|
||||||
|
#include <iostream>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "../ssdv/ssdv.h"
|
||||||
|
|
||||||
|
void print_hex(const std::vector<uint8_t>& v)
|
||||||
|
{
|
||||||
|
for(auto c : v) std::cout<<"0x"<<std::hex<<(int)c<<" ";
|
||||||
|
std::cout<<std::dec<<std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace habdec
|
||||||
|
{
|
||||||
|
|
||||||
|
SSDV_wraper_t::SSDV_wraper_t()
|
||||||
|
{
|
||||||
|
jpeg = new uint8_t[1024 * 1024 * 3];
|
||||||
|
ssdv_dec_init(&ssdv);
|
||||||
|
ssdv_dec_set_buffer(&ssdv, jpeg, 1024*1024*3);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SSDV_wraper_t::~SSDV_wraper_t()
|
||||||
|
{
|
||||||
|
delete [] jpeg;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool SSDV_wraper_t::push(const std::vector<char>& i_chars)
|
||||||
|
{
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
const size_t jpeg_data_sz_ = 1024 * 1024 * 3;
|
||||||
|
|
||||||
|
// copy to buff_
|
||||||
|
{
|
||||||
|
const size_t buff_end = buff_.size();
|
||||||
|
buff_.resize( buff_.size() + i_chars.size() );
|
||||||
|
memcpy( buff_.data() + buff_end, i_chars.data(), i_chars.size() );
|
||||||
|
}
|
||||||
|
|
||||||
|
if(buff_.size() < SSDV_PKT_SIZE)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// scan input for packet sync bytes: 0x55 [0x66|0x67] 0x0 0x0 0xb3 0xeb
|
||||||
|
const uint8_t _fec[6] = {0x55, 0x66, 0x0, 0x0, 0xb3, 0xeb};
|
||||||
|
const uint8_t _nofec[6] = {0x55, 0x67, 0x0, 0x0, 0xb3, 0xeb};
|
||||||
|
if(packet_begin_ == -1)
|
||||||
|
{
|
||||||
|
for(int i=0; i<buff_.size()-sizeof(_fec); ++i) //
|
||||||
|
{
|
||||||
|
int j=0;
|
||||||
|
while( j < sizeof(_fec) &&
|
||||||
|
( buff_[i+j] == _fec[j] || buff_[i+j] == _nofec[j] )
|
||||||
|
)
|
||||||
|
++j;
|
||||||
|
|
||||||
|
if(j == sizeof(_fec))
|
||||||
|
{
|
||||||
|
packet_begin_ = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(packet_begin_ == -1) { // no packet sync bits found
|
||||||
|
buff_.erase( buff_.begin(), buff_.end() - sizeof(_fec) );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(packet_begin_>0)
|
||||||
|
{
|
||||||
|
buff_.erase( buff_.begin(), buff_.begin()+packet_begin_ );
|
||||||
|
packet_begin_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// packet incomplete
|
||||||
|
if( buff_.size() < SSDV_PKT_SIZE )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// print_hex(buff_);
|
||||||
|
|
||||||
|
int errors = 0;
|
||||||
|
const int is_packet = ssdv_dec_is_packet( buff_.data(), &errors );
|
||||||
|
if( is_packet != 0 ) // not a packet
|
||||||
|
{
|
||||||
|
buff_.erase( buff_.begin(), buff_.begin()+SSDV_PKT_SIZE );
|
||||||
|
packet_begin_ = -1;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssdv_packet_info_t packet_header;
|
||||||
|
ssdv_dec_header( &packet_header, buff_.data() );
|
||||||
|
|
||||||
|
cout<<"SSDV Packet "
|
||||||
|
<<packet_header.packet_id<<" of image "<<(int)packet_header.image_id
|
||||||
|
<<" MCU id "<<(int)packet_header.mcu_id
|
||||||
|
<<" MCU offset "<<(int)packet_header.mcu_offset
|
||||||
|
<<" EOI "<<(int)packet_header.eoi
|
||||||
|
<<endl;
|
||||||
|
|
||||||
|
if(0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Decoded image packet. Callsign: %s, Image ID: %d, Packet ID: %d, Resolution: %dx%d, (%d errors corrected) "
|
||||||
|
"Type: %d, Quality: %d, EOI: %d, MCU Mode: %d, MCU Offset: %d, MCU ID: %d/%d\n",
|
||||||
|
packet_header.callsign_s,
|
||||||
|
packet_header.image_id,
|
||||||
|
packet_header.packet_id,
|
||||||
|
packet_header.width,
|
||||||
|
packet_header.height,
|
||||||
|
errors,
|
||||||
|
packet_header.type,
|
||||||
|
packet_header.quality,
|
||||||
|
packet_header.eoi,
|
||||||
|
packet_header.mcu_mode,
|
||||||
|
packet_header.mcu_offset,
|
||||||
|
packet_header.mcu_id,
|
||||||
|
packet_header.mcu_count
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssdv_dec_feed( &ssdv, buff_.data() );
|
||||||
|
buff_.erase( buff_.begin(), buff_.begin() + SSDV_PKT_SIZE);
|
||||||
|
packet_begin_ = -1;
|
||||||
|
|
||||||
|
// save jpeg
|
||||||
|
if(packet_header.eoi)
|
||||||
|
{
|
||||||
|
size_t jpeg_sz = 0;
|
||||||
|
ssdv_dec_get_jpeg(&ssdv, &jpeg, &jpeg_sz);
|
||||||
|
|
||||||
|
string fname = "./ssdv_" + string(packet_header.callsign_s) + "_" + std::to_string(int(packet_header.image_id)) + ".jpeg";
|
||||||
|
FILE* fh = fopen( fname.c_str(), "wb" );
|
||||||
|
fwrite(jpeg, 1, jpeg_sz, fh);
|
||||||
|
fclose(fh);
|
||||||
|
|
||||||
|
ssdv_dec_init(&ssdv);
|
||||||
|
ssdv_dec_set_buffer(&ssdv, jpeg, 1024*1024*3);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2018 Michal Fratczak
|
||||||
|
|
||||||
|
This file is part of habdec.
|
||||||
|
|
||||||
|
habdec is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
habdec is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with habdec. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
#include "../ssdv/ssdv.h"
|
||||||
|
|
||||||
|
namespace habdec
|
||||||
|
{
|
||||||
|
|
||||||
|
class SSDV_wraper_t
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
SSDV_wraper_t();
|
||||||
|
~SSDV_wraper_t();
|
||||||
|
bool push(const std::vector<char>& i_chars);
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint8_t* jpeg;
|
||||||
|
ssdv_t ssdv;
|
||||||
|
|
||||||
|
std::vector<uint8_t> buff_;
|
||||||
|
int packet_begin_ = -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 035f920f5c96880bfd89d4469428b934e830c7c9
|
|
@ -0,0 +1,23 @@
|
||||||
|
|
||||||
|
set ( ssdv_lib_src
|
||||||
|
${PROJECT_SOURCE_DIR}/ssdv/rs8.c
|
||||||
|
${PROJECT_SOURCE_DIR}/ssdv/ssdv.c
|
||||||
|
)
|
||||||
|
|
||||||
|
set_source_files_properties ( ${ssdv_lib_src} LANGUAGE "C" )
|
||||||
|
|
||||||
|
add_library( ssdv_lib ${ssdv_lib_src} )
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
set ( ssdv_exe_src
|
||||||
|
${PROJECT_SOURCE_DIR}/ssdv/rs8.c
|
||||||
|
${PROJECT_SOURCE_DIR}/ssdv/ssdv.c
|
||||||
|
${PROJECT_SOURCE_DIR}/ssdv/main.c
|
||||||
|
)
|
||||||
|
|
||||||
|
set_source_files_properties ( ${ssdv_exe_src} LANGUAGE "C" )
|
||||||
|
|
||||||
|
add_executable( ssdv ${ssdv_exe_src} )
|
Ładowanie…
Reference in New Issue