Preliminary SSDV support.

ssdv
Michal Fratczak 2020-04-23 18:03:37 +02:00
rodzic 2a35d32e4b
commit 1d198baa22
9 zmienionych plików z 260 dodań i 8 usunięć

3
.gitmodules vendored 100644
Wyświetl plik

@ -0,0 +1,3 @@
[submodule "code/ssdv"]
path = code/ssdv
url = https://github.com/fsphil/ssdv.git

Wyświetl plik

@ -17,6 +17,7 @@ message ( "CMAKE_INSTALL_PREFIX: " ${CMAKE_INSTALL_PREFIX} )
add_subdirectory("Decoder")
add_subdirectory("IQSource")
add_subdirectory("ssdv_build")
add_subdirectory("websocketServer")
option( fltkGUI "fltkGUI" OFF )

Wyświetl plik

@ -31,6 +31,7 @@ set ( Decoder_src
sentence_extract.h sentence_extract.cpp
SpectrumInfo.h
SymbolExtractor.h
ssdv_wrapper.cpp
)
SET( CMAKE_CXX_FLAGS " -O3 " )
@ -50,6 +51,7 @@ endif()
add_library( Decoder ${Decoder_src})
target_link_libraries( Decoder
ssdv_lib
#${SoapySDR_LIBRARIES}
${FFTW3f_LIBRARIES}
${PlatformSpecificLinking} )

Wyświetl plik

@ -42,6 +42,7 @@
#include "SpectrumInfo.h"
#include "print_habhub_sentence.h"
#include "CRC.h"
#include "ssdv_wrapper.h"
namespace habdec
{
@ -178,6 +179,9 @@ private:
std::string last_sentence_; // result of rtty
// size_t last_sentence_len_ = 0; // optimization for regexp run
// SSDV
SSDV_wraper_t ssdv_;
// threading
mutable std::mutex process_mutex_; // mutex for main processing
@ -555,14 +559,19 @@ void habdec::Decoder<TReal>::process()
return;
auto decoded_chars = rtty_.get();
rtty_char_stream_.insert( rtty_char_stream_.end(), decoded_chars.begin(), decoded_chars.end() );
chr_callback_stream_.insert( chr_callback_stream_.end(), decoded_chars.begin(), decoded_chars.end() );
vector<char> raw_chars = rtty_.get();
ssdv_.push(raw_chars);
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_)
{
for( auto c : decoded_chars )
for( auto c : printable_chars )
cout<<c;
cout.flush();
}

Wyświetl plik

@ -84,7 +84,7 @@ size_t RTTY<TBit>::operator()()
using namespace std;
size_t decoded_chars = 0;
size_t n_decoded_chars = 0;
size_t last_decoded_bit_index = 0;
for(size_t i=0; i<bits_.size()/*-char_bitlen*/; /**/)
@ -118,10 +118,10 @@ size_t RTTY<TBit>::operator()()
++i;
}
if( isprint(c) || c == '\n' )
// if( isprint(c) || c == '\n' )
{
chars_.push_back(c);
++decoded_chars;
++n_decoded_chars;
}
i += nstops_;
@ -133,7 +133,7 @@ size_t RTTY<TBit>::operator()()
if(last_decoded_bit_index)
bits_.erase( bits_.begin(), bits_.begin() + last_decoded_bit_index + 1 );
return decoded_chars;
return n_decoded_chars;
}

Wyświetl plik

@ -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;
}
}

Wyświetl plik

@ -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;
};
}

1
code/ssdv 160000

@ -0,0 +1 @@
Subproject commit 035f920f5c96880bfd89d4469428b934e830c7c9

Wyświetl plik

@ -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} )