Numeric controlled oscilator and mixer as a base class

master
Lucjan Bryndza 2013-04-02 22:55:51 +02:00
rodzic aeafd05482
commit e1a98f710c
4 zmienionych plików z 71 dodań i 24 usunięć

Wyświetl plik

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

Wyświetl plik

@ -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_ */

Wyświetl plik

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

Wyświetl plik

@ -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
{