kopia lustrzana https://github.com/lucckb/libpsk
Initial version of the PSK application
rodzic
7ee79e5ee5
commit
23763c6bc7
|
@ -22,11 +22,10 @@ class spectrum_calculator {
|
|||
public:
|
||||
//Spectrum data type
|
||||
typedef short pow_t;
|
||||
//FFT scale
|
||||
enum class scale : char
|
||||
{
|
||||
lin,
|
||||
log
|
||||
//! FFT scale
|
||||
enum class scale : char { //! Type of FFT scale
|
||||
lin, //! Normal linear
|
||||
log //! Logarithm scale
|
||||
};
|
||||
private:
|
||||
//Number of samples
|
||||
|
@ -42,39 +41,49 @@ public:
|
|||
spectrum_calculator()
|
||||
{}
|
||||
public:
|
||||
bool copy_samples( const pow_t* samples, size_t len )
|
||||
{
|
||||
/** Copy input samples to buffer
|
||||
* @param[in] samples Input buffer sample pointer
|
||||
* @param[in] len Sample buffer len
|
||||
* @return true if fail
|
||||
*/
|
||||
bool copy_samples( const pow_t* samples, size_t len ) {
|
||||
size_t cpyn = WIDTH - m_sample_buf_cnt;
|
||||
if( len < cpyn ) cpyn = len;
|
||||
std::memcpy( &m_real[m_sample_buf_cnt], samples, sizeof(pow_t) * cpyn );
|
||||
m_sample_buf_cnt += cpyn;
|
||||
m_energy_calculated = false;
|
||||
if( m_sample_buf_cnt >= WIDTH )
|
||||
{
|
||||
if( m_sample_buf_cnt >= WIDTH ) {
|
||||
m_sample_buf_cnt = 0;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//Get buffer samples and calculate it
|
||||
const pow_t& operator[]( size_t idx )
|
||||
{
|
||||
if( !m_energy_calculated )
|
||||
{
|
||||
/** Function return sample buffer
|
||||
* @return Pointer to sample data
|
||||
*/
|
||||
const pow_t* buffer() {
|
||||
if( !m_energy_calculated ) {
|
||||
m_energy_calculated = true;
|
||||
calculate_samples();
|
||||
}
|
||||
//TODO: Range checking
|
||||
return m_real[idx];
|
||||
return m_real;
|
||||
}
|
||||
//Set scale
|
||||
void set_scale( scale sc, pow_t factor = std::numeric_limits<pow_t>::max() )
|
||||
{
|
||||
if( sc != m_scale)
|
||||
{
|
||||
/** Index overloaded operator for access the
|
||||
* data input FFT calculato
|
||||
* @param[in] idx Input index
|
||||
*/
|
||||
const pow_t& operator[]( size_t idx ) {
|
||||
//TODO: Range checking
|
||||
return buffer()[idx];
|
||||
}
|
||||
/** Set FFT scale ad scale type
|
||||
* @param[in] sc Input scale type @see scale
|
||||
* @param[in] factor Limit value factor for variable
|
||||
*/
|
||||
void set_scale( scale sc, pow_t factor = std::numeric_limits<pow_t>::max() ) {
|
||||
if( sc != m_scale) {
|
||||
m_scale = sc;
|
||||
m_energy_calculated = false;
|
||||
}
|
||||
|
@ -84,19 +93,27 @@ public:
|
|||
m_energy_calculated = false;
|
||||
}
|
||||
}
|
||||
//Get min and max value
|
||||
int min_value() const
|
||||
{
|
||||
/** Get minimum value represented by the app type
|
||||
* @return Minimum value variable type representation
|
||||
*/
|
||||
int min_value() const {
|
||||
constexpr int minv = 20 * std::log10( 1.0/std::numeric_limits<pow_t>::max() );
|
||||
if( m_scale == scale::log ) return minv;
|
||||
else return 0;
|
||||
}
|
||||
/** Get maximum value represented by the returnet type
|
||||
* @returm Maximum value available as the fft representtation */
|
||||
//Get MAX scale value
|
||||
int max_value() const
|
||||
{
|
||||
int max_value() const {
|
||||
if( m_scale == scale::log ) return 0;
|
||||
else return 100;
|
||||
}
|
||||
|
||||
/** return available buffer size
|
||||
* @return available buffer size */
|
||||
static constexpr size_t buffer_len() {
|
||||
return WIDTH / 2;
|
||||
}
|
||||
private:
|
||||
//Calculate samplees
|
||||
void calculate_samples();
|
||||
|
@ -113,7 +130,7 @@ private:
|
|||
*/
|
||||
pow_t* const m_real { reinterpret_cast<pow_t* const>(m_cplx) };
|
||||
bool m_energy_calculated { false }; //Energy is calculated
|
||||
scale m_scale { scale::log }; //Current scale
|
||||
scale m_scale { scale::lin }; //Current scale
|
||||
pow_t m_factor { std::numeric_limits<pow_t>::max() };
|
||||
short m_sample_buf_cnt {}; //Sample buffer counter
|
||||
};
|
||||
|
|
|
@ -16,11 +16,9 @@
|
|||
namespace ham {
|
||||
namespace psk {
|
||||
/*----------------------------------------------------------*/
|
||||
namespace
|
||||
{
|
||||
namespace {
|
||||
//Inline POW2
|
||||
constexpr inline unsigned pow2( unsigned u )
|
||||
{
|
||||
constexpr inline unsigned pow2( unsigned u ) {
|
||||
return u * u;
|
||||
}
|
||||
}
|
||||
|
@ -33,18 +31,15 @@ void spectrum_calculator::calculate_samples()
|
|||
//Calculate FFT real transform
|
||||
fft::fft_real( m_cplx, m_real, MLOG2 );
|
||||
//Calculate energies
|
||||
for( int i=0; i<WIDTH/2; i++ )
|
||||
{
|
||||
for( int i=0; i<WIDTH/2; i++ ) {
|
||||
m_real[i] = dint::sqrt( pow2(m_cplx[i].real()) + pow2(m_cplx[i].imag()) );
|
||||
}
|
||||
//Normalize the graph and do log
|
||||
const int max_sample = *std::max_element( m_real, m_real + WIDTH/2 );
|
||||
const int max_value = (m_scale==scale::log)?(std::numeric_limits<pow_t>::max()):(m_factor);
|
||||
for( int i=0; i<WIDTH/2; i++ )
|
||||
{
|
||||
for( int i=0; i<WIDTH/2; i++ ) {
|
||||
m_real[i] = (int(m_real[i])* max_value) / max_sample;
|
||||
if(m_scale == scale::log )
|
||||
{
|
||||
if(m_scale == scale::log ) {
|
||||
const int lsample = dint::log2_0_1<unsigned,LOG_SCALE>( m_real[i])>>LOGVAL_SCALE;
|
||||
if( m_factor == std::numeric_limits<pow_t>::max() )
|
||||
m_real[i] = lsample;
|
||||
|
|
Ładowanie…
Reference in New Issue