kopia lustrzana https://github.com/lucckb/libpsk
Numeric controlled oscilator and mixer as a base class
rodzic
aeafd05482
commit
e1a98f710c
4
Makefile
4
Makefile
|
@ -11,13 +11,15 @@ OPT ?= 2
|
||||||
#Common flags
|
#Common flags
|
||||||
COMMON_FLAGS = -pipe -Wall -pedantic -Wextra -Wno-vla -I.
|
COMMON_FLAGS = -pipe -Wall -pedantic -Wextra -Wno-vla -I.
|
||||||
COMMON_FLAGS += -D__STDC_CONSTANT_MACROS -I./libpsk/include
|
COMMON_FLAGS += -D__STDC_CONSTANT_MACROS -I./libpsk/include
|
||||||
|
#Code profiler
|
||||||
|
COMMON_FLAGS += -pg
|
||||||
|
|
||||||
#C compiler options
|
#C compiler options
|
||||||
CFLAGS += $(COMMON_FLAGS)
|
CFLAGS += $(COMMON_FLAGS)
|
||||||
CFLAGS += -std=gnu99
|
CFLAGS += -std=gnu99
|
||||||
|
|
||||||
#C++ compiler options
|
#C++ compiler options
|
||||||
CXXFLAGS += $(COMMON_FLAGS) -std=c++11 -ftemplate-depth=2048
|
CXXFLAGS += $(COMMON_FLAGS) -std=c++11 -ftemplate-depth=2048
|
||||||
|
|
||||||
#LDflags libraries etc.
|
#LDflags libraries etc.
|
||||||
LDFLAGS += -lavformat -lavcodec -lz -lavutil -lswresample
|
LDFLAGS += -lavformat -lavcodec -lz -lavutil -lswresample
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* nco_mixer.hpp
|
||||||
|
*
|
||||||
|
* Created on: 02-04-2013
|
||||||
|
* Author: lucck
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NCO_MIXER_HPP_
|
||||||
|
#define NCO_MIXER_HPP_
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
#include <cstddef>
|
||||||
|
#include <complex>
|
||||||
|
#include "array_sinus.hpp"
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
namespace dsp {
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
template <typename R, typename P, int SHIFT, std::size_t SSIN_SIZE > class nco_mixer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::complex<R> operator()(R signal, P phz_inc )
|
||||||
|
{
|
||||||
|
const std::complex<R> ret(
|
||||||
|
(signal*icosinus(m_vco_phz)) >> SHIFT ,
|
||||||
|
(signal*isinus(m_vco_phz)) >> SHIFT
|
||||||
|
);
|
||||||
|
m_vco_phz += phz_inc;
|
||||||
|
if( m_vco_phz > isinmax() ) //handle 2 Pi wrap around
|
||||||
|
m_vco_phz -= isinmax();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
constexpr R max_angle( )
|
||||||
|
{
|
||||||
|
return dsp::integer::trig::sin_arg_max<R, SSIN_SIZE>();
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
inline int isinus( short value )
|
||||||
|
{
|
||||||
|
return dsp::integer::trig::sin<R, SSIN_SIZE>( value );
|
||||||
|
}
|
||||||
|
constexpr short isinmax( )
|
||||||
|
{
|
||||||
|
return dsp::integer::trig::sin_arg_max<R, SSIN_SIZE>();
|
||||||
|
}
|
||||||
|
inline int icosinus( short value )
|
||||||
|
{
|
||||||
|
return dsp::integer::trig::sin<R, SSIN_SIZE>( isinmax()/4 + value );
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
P m_vco_phz {};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
#endif /* NCO_MIXER_HPP_ */
|
|
@ -15,6 +15,7 @@
|
||||||
#include <complex>
|
#include <complex>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include "imd_calculator.hpp"
|
#include "imd_calculator.hpp"
|
||||||
|
#include "dsp/nco_mixer.hpp"
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
namespace ham {
|
namespace ham {
|
||||||
namespace psk {
|
namespace psk {
|
||||||
|
@ -127,8 +128,9 @@ private:
|
||||||
private:
|
private:
|
||||||
//Event handler
|
//Event handler
|
||||||
event_callback_type m_callback;
|
event_callback_type m_callback;
|
||||||
|
//Numeric controlled oscilator and mixer
|
||||||
|
dsp::nco_mixer<short, int, 15 ,512> m_nco_mix;
|
||||||
baudrate m_baudrate { baudrate::b63 };
|
baudrate m_baudrate { baudrate::b63 };
|
||||||
double m_vco_phz {};
|
|
||||||
int m_afc_timer {};
|
int m_afc_timer {};
|
||||||
bool m_afc_capture_on {};
|
bool m_afc_capture_on {};
|
||||||
int m_rx_frequency { 1500 };
|
int m_rx_frequency { 1500 };
|
||||||
|
|
|
@ -409,19 +409,6 @@ namespace
|
||||||
auto constexpr AFC_TIMELIMIT = 10;
|
auto constexpr AFC_TIMELIMIT = 10;
|
||||||
auto constexpr AFC_FTIMELIMIT = 2;
|
auto constexpr AFC_FTIMELIMIT = 2;
|
||||||
|
|
||||||
constexpr size_t sinarray_size = 512;
|
|
||||||
inline int isinus( short value )
|
|
||||||
{
|
|
||||||
return dsp::integer::trig::sin<short, sinarray_size>( value );
|
|
||||||
}
|
|
||||||
constexpr short isinmax( )
|
|
||||||
{
|
|
||||||
return dsp::integer::trig::sin_arg_max<short, sinarray_size>();
|
|
||||||
}
|
|
||||||
inline int icosinus( short value )
|
|
||||||
{
|
|
||||||
return dsp::integer::trig::sin<short, sinarray_size>( isinmax()/4 + value );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
//Construct the decoder object
|
//Construct the decoder object
|
||||||
|
@ -1007,15 +994,14 @@ void decoder::operator()( const sample_type* samples, std::size_t sample_size )
|
||||||
for( std::size_t smpl = 0; smpl<sample_size; smpl++ ) // put new samples into Queue
|
for( std::size_t smpl = 0; smpl<sample_size; smpl++ ) // put new samples into Queue
|
||||||
{
|
{
|
||||||
//Generate complex sample by mixing input sample with NCO's sin/cos
|
//Generate complex sample by mixing input sample with NCO's sin/cos
|
||||||
m_que1[m_fir1_state] = std::complex<double>(
|
//m_que1[m_fir1_state] = std::complex<double>(
|
||||||
//samples[smpl]*cos( m_vco_phz ),
|
// (samples[smpl]*icosinus(m_vco_phz)) >> 15,
|
||||||
//samples[smpl]*sin( m_vco_phz )
|
// (samples[smpl]*isinus(m_vco_phz)) >> 15
|
||||||
(samples[smpl]*icosinus(int((m_vco_phz/PI2) * isinmax()+ 0.5))) >> 15,
|
//);
|
||||||
(samples[smpl]*isinus(int((m_vco_phz/PI2) * isinmax() + 0.5))) >> 15
|
m_que1[m_fir1_state] = m_nco_mix( samples[smpl], (m_nco_phzinc + m_freq_error)/PI2 *double( m_nco_mix.max_angle() ) );
|
||||||
);
|
//m_vco_phz += ();
|
||||||
m_vco_phz += m_nco_phzinc + m_freq_error;
|
//if( m_vco_phz > isinmax() ) //handle 2 Pi wrap around
|
||||||
if( m_vco_phz > PI2) //handle 2 Pi wrap around
|
// m_vco_phz -= isinmax();
|
||||||
m_vco_phz -= PI2;
|
|
||||||
//decimate by 4 filter
|
//decimate by 4 filter
|
||||||
if( ( (++m_sample_cnt)%4 ) == 0 ) //calc first decimation filter every 4 samples
|
if( ( (++m_sample_cnt)%4 ) == 0 ) //calc first decimation filter every 4 samples
|
||||||
{
|
{
|
||||||
|
|
Ładowanie…
Reference in New Issue