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 = -pipe -Wall -pedantic -Wextra -Wno-vla -I.
|
||||
COMMON_FLAGS += -D__STDC_CONSTANT_MACROS -I./libpsk/include
|
||||
#Code profiler
|
||||
COMMON_FLAGS += -pg
|
||||
|
||||
#C compiler options
|
||||
CFLAGS += $(COMMON_FLAGS)
|
||||
CFLAGS += -std=gnu99
|
||||
|
||||
#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 += -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 <functional>
|
||||
#include "imd_calculator.hpp"
|
||||
#include "dsp/nco_mixer.hpp"
|
||||
/* ------------------------------------------------------------------------- */
|
||||
namespace ham {
|
||||
namespace psk {
|
||||
|
@ -127,8 +128,9 @@ private:
|
|||
private:
|
||||
//Event handler
|
||||
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 };
|
||||
double m_vco_phz {};
|
||||
int m_afc_timer {};
|
||||
bool m_afc_capture_on {};
|
||||
int m_rx_frequency { 1500 };
|
||||
|
|
|
@ -409,19 +409,6 @@ namespace
|
|||
auto constexpr AFC_TIMELIMIT = 10;
|
||||
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
|
||||
|
@ -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
|
||||
{
|
||||
//Generate complex sample by mixing input sample with NCO's sin/cos
|
||||
m_que1[m_fir1_state] = std::complex<double>(
|
||||
//samples[smpl]*cos( m_vco_phz ),
|
||||
//samples[smpl]*sin( m_vco_phz )
|
||||
(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_vco_phz += m_nco_phzinc + m_freq_error;
|
||||
if( m_vco_phz > PI2) //handle 2 Pi wrap around
|
||||
m_vco_phz -= PI2;
|
||||
//m_que1[m_fir1_state] = std::complex<double>(
|
||||
// (samples[smpl]*icosinus(m_vco_phz)) >> 15,
|
||||
// (samples[smpl]*isinus(m_vco_phz)) >> 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 += ();
|
||||
//if( m_vco_phz > isinmax() ) //handle 2 Pi wrap around
|
||||
// m_vco_phz -= isinmax();
|
||||
//decimate by 4 filter
|
||||
if( ( (++m_sample_cnt)%4 ) == 0 ) //calc first decimation filter every 4 samples
|
||||
{
|
||||
|
|
Ładowanie…
Reference in New Issue