kopia lustrzana https://github.com/f4exb/sdrangel
				
				
				
			
		
			
				
	
	
		
			85 wiersze
		
	
	
		
			1.7 KiB
		
	
	
	
		
			C++
		
	
	
			
		
		
	
	
			85 wiersze
		
	
	
		
			1.7 KiB
		
	
	
	
		
			C++
		
	
	
// Copyright 2020 Mobilinkd LLC.
 | 
						|
 | 
						|
#pragma once
 | 
						|
 | 
						|
#include "IirFilter.h"
 | 
						|
 | 
						|
#include <array>
 | 
						|
#include <algorithm>
 | 
						|
#include <numeric>
 | 
						|
#include <tuple>
 | 
						|
 | 
						|
namespace modemm17
 | 
						|
{
 | 
						|
 | 
						|
template <size_t N>
 | 
						|
struct SymbolEvm
 | 
						|
{
 | 
						|
    using filter_type = BaseIirFilter<N>;
 | 
						|
    using symbol_t = int;
 | 
						|
    using result_type = std::tuple<symbol_t, float>;
 | 
						|
 | 
						|
    filter_type filter_;
 | 
						|
    float erasure_limit_;
 | 
						|
    float evm_ = 0.0;
 | 
						|
 | 
						|
    SymbolEvm(filter_type&& filter, float erasure_limit = 0.0) :
 | 
						|
        filter_(std::forward<filter_type>(filter)),
 | 
						|
        erasure_limit_(erasure_limit)
 | 
						|
    {}
 | 
						|
 | 
						|
    float evm() const { return evm_; }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Decode a normalized sample into a symbol.  Symbols
 | 
						|
     * are decoded into +3, +1, -1, -3.  If an erasure limit
 | 
						|
     * is set, symbols outside this limit are 'erased' and
 | 
						|
     * returned as 0.
 | 
						|
     */
 | 
						|
    result_type operator()(float sample)
 | 
						|
    {
 | 
						|
        symbol_t symbol;
 | 
						|
        float evm;
 | 
						|
 | 
						|
        sample = std::min(3.0f, std::max(-3.0f, sample));
 | 
						|
 | 
						|
        if (sample > 2)
 | 
						|
        {
 | 
						|
            symbol = 3;
 | 
						|
            evm = (sample - 3) * 0.333333;
 | 
						|
        }
 | 
						|
        else if (sample > 0)
 | 
						|
        {
 | 
						|
            symbol = 1;
 | 
						|
            evm = sample - 1;
 | 
						|
        }
 | 
						|
        else if (sample >= -2)
 | 
						|
        {
 | 
						|
            symbol = -1;
 | 
						|
            evm = sample + 1;
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
            symbol = -3;
 | 
						|
            evm = (sample + 3) * 0.333333;
 | 
						|
        }
 | 
						|
 | 
						|
        if (erasure_limit_ and (std::abs(evm) > erasure_limit_)) symbol = 0;
 | 
						|
 | 
						|
        evm_ = filter_(evm);
 | 
						|
 | 
						|
        return std::make_tuple(symbol, evm);
 | 
						|
    }
 | 
						|
};
 | 
						|
 | 
						|
template <size_t N>
 | 
						|
SymbolEvm<N> makeSymbolEvm(
 | 
						|
    BaseIirFilter<N>&& filter,
 | 
						|
    float erasure_limit = 0.0f
 | 
						|
)
 | 
						|
{
 | 
						|
    return std::move(SymbolEvm<N>(std::move(filter), erasure_limit));
 | 
						|
}
 | 
						|
 | 
						|
} // modemm17
 |