kopia lustrzana https://github.com/jamescoxon/dl-fldigi
207 wiersze
5.3 KiB
C++
207 wiersze
5.3 KiB
C++
// ----------------------------------------------------------------------------
|
|
// misc.cxx -- Miscellaneous helper functions
|
|
//
|
|
// Copyright (C) 2006-2007
|
|
// Dave Freese, W1HKJ
|
|
//
|
|
// This file is part of fldigi. These filters were adapted from code contained
|
|
// in the gmfsk source code distribution.
|
|
//
|
|
// Fldigi is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// Fldigi is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with fldigi. If not, see <http://www.gnu.org/licenses/>.
|
|
// ----------------------------------------------------------------------------
|
|
|
|
#include <config.h>
|
|
|
|
#include "misc.h"
|
|
#include <time.h>
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*
|
|
* Hamming weight (number of bits that are ones).
|
|
*/
|
|
unsigned long hweight32(unsigned long w)
|
|
{
|
|
w = (w & 0x55555555) + ((w >> 1) & 0x55555555);
|
|
w = (w & 0x33333333) + ((w >> 2) & 0x33333333);
|
|
w = (w & 0x0F0F0F0F) + ((w >> 4) & 0x0F0F0F0F);
|
|
w = (w & 0x00FF00FF) + ((w >> 8) & 0x00FF00FF);
|
|
w = (w & 0x0000FFFF) + ((w >> 16) & 0x0000FFFF);
|
|
return w;
|
|
}
|
|
|
|
unsigned short int hweight16(unsigned short int w)
|
|
{
|
|
w = (w & 0x5555) + ((w >> 1) & 0x5555);
|
|
w = (w & 0x3333) + ((w >> 2) & 0x3333);
|
|
w = (w & 0x0F0F) + ((w >> 4) & 0x0F0F);
|
|
w = (w & 0x00FF) + ((w >> 8) & 0x00FF);
|
|
return w;
|
|
}
|
|
|
|
unsigned char hweight8(unsigned char w)
|
|
{
|
|
w = (w & 0x55) + ((w >> 1) & 0x55);
|
|
w = (w & 0x33) + ((w >> 2) & 0x33);
|
|
w = (w & 0x0F) + ((w >> 4) & 0x0F);
|
|
return w;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*
|
|
* Parity function. Return one if `w' has odd number of ones, zero otherwise.
|
|
*/
|
|
|
|
int parity(unsigned long w)
|
|
{
|
|
return hweight32(w) & 1;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*
|
|
* Reverse order of bits.
|
|
*/
|
|
unsigned long rbits32(unsigned long w)
|
|
{
|
|
w = ((w >> 1) & 0x55555555) | ((w << 1) & 0xAAAAAAAA);
|
|
w = ((w >> 2) & 0x33333333) | ((w << 2) & 0xCCCCCCCC);
|
|
w = ((w >> 4) & 0x0F0F0F0F) | ((w << 4) & 0xF0F0F0F0);
|
|
w = ((w >> 8) & 0x00FF00FF) | ((w << 8) & 0xFF00FF00);
|
|
w = ((w >> 16) & 0x0000FFFF) | ((w << 16) & 0xFFFF0000);
|
|
return w;
|
|
}
|
|
|
|
unsigned short int rbits16(unsigned short int w)
|
|
{
|
|
w = ((w >> 1) & 0x5555) | ((w << 1) & 0xAAAA);
|
|
w = ((w >> 2) & 0x3333) | ((w << 2) & 0xCCCC);
|
|
w = ((w >> 4) & 0x0F0F) | ((w << 4) & 0xF0F0);
|
|
w = ((w >> 8) & 0x00FF) | ((w << 8) & 0xFF00);
|
|
return w;
|
|
}
|
|
|
|
unsigned char rbits8(unsigned char w)
|
|
{
|
|
w = ((w >> 1) & 0x55) | ((w << 1) & 0xFF);
|
|
w = ((w >> 2) & 0x33) | ((w << 2) & 0xCC);
|
|
w = ((w >> 4) & 0x0F) | ((w << 4) & 0xF0);
|
|
return w;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// Integer base-2 logarithm
|
|
|
|
unsigned int log2u(unsigned int x)
|
|
{
|
|
int y = 0;
|
|
x >>= 1;
|
|
while (x) {
|
|
x >>= 1;
|
|
y++;
|
|
}
|
|
return y;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// Gray encoding and decoding (8 bit)
|
|
|
|
unsigned char grayencode(unsigned char data)
|
|
//unsigned char graydecode(unsigned char data)
|
|
{
|
|
unsigned char bits = data;
|
|
|
|
bits ^= data >> 1;
|
|
bits ^= data >> 2;
|
|
bits ^= data >> 3;
|
|
bits ^= data >> 4;
|
|
bits ^= data >> 5;
|
|
bits ^= data >> 6;
|
|
bits ^= data >> 7;
|
|
|
|
return bits;
|
|
}
|
|
|
|
unsigned char graydecode(unsigned char data)
|
|
//unsigned char grayencode(unsigned char data)
|
|
{
|
|
return data ^ (data >> 1);
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// Rectangular - no pre filtering of data array
|
|
void RectWindow(double *array, int n) {
|
|
for (int i = 0; i < n; i++)
|
|
array[i] = 1.0;
|
|
}
|
|
|
|
// Hamming - used by gmfsk
|
|
void HammingWindow(double *array, int n) {
|
|
double pwr = 0.0;
|
|
double inv_n = 1.0 / (double)n;
|
|
for (int i = 0; i < n; i++) {
|
|
array[i] = hamming((double)i * inv_n);
|
|
pwr += array[i] * array[i];
|
|
}
|
|
pwr = sqrt((double)n/pwr);
|
|
for (int i = 0; i < n; i++)
|
|
array[i] *= pwr;
|
|
}
|
|
|
|
// Hanning - used by winpsk
|
|
void HanningWindow(double *array, int n) {
|
|
double pwr = 0.0;
|
|
double inv_n = 1.0 / (double)n;
|
|
for (int i = 0; i < n; i++) {
|
|
array[i] = hanning((double)i * inv_n);
|
|
pwr += array[i] * array[i];
|
|
}
|
|
pwr = sqrt((double)n/pwr);
|
|
for (int i = 0; i < n; i++)
|
|
array[i] *= pwr;
|
|
}
|
|
|
|
// Best lob suppression - least in band ripple
|
|
void BlackmanWindow(double *array, int n) {
|
|
double pwr = 0.0;
|
|
double inv_n = 1.0 / (double)n;
|
|
for (int i = 0; i < n; i++) {
|
|
array[i] = blackman((double)i * inv_n);
|
|
pwr += array[i] * array[i];
|
|
}
|
|
pwr = sqrt((double)n/pwr);
|
|
for (int i = 0; i < n; i++)
|
|
array[i] *= pwr;
|
|
}
|
|
|
|
// Simple about effective as Hamming or Hanning
|
|
void TriangularWindow(double *array, int n) {
|
|
double pwr = 0.0;
|
|
for (int i = 0; i < n; i++) array[i] = 1.0;
|
|
double inv_n = 1.0 / (double)n;
|
|
for (int i = 0; i < n / 4; i++) {
|
|
array[i] = 4.0 * (double)i * inv_n ;
|
|
array[n-i] = array[i];
|
|
}
|
|
for (int i = 0; i < n; i++) pwr += array[i] * array[i];
|
|
pwr = sqrt((double)n/pwr);
|
|
for (int i = 0; i < n; i++)
|
|
array[i] *= pwr;
|
|
}
|
|
|