morse-wip/src/misc.cxx

203 wiersze
5.1 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;
for (int i = 0; i < n; i++) {
array[i] = hamming((double)i/(double)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;
for (int i = 0; i < n; i++) {
array[i] = hanning((double)i/(double)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;
for (int i = 0; i < n; i++) {
array[i] = blackman((double)i/(double)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;
for (int i = 0; i < n / 4; i++) {
array[i] = 4.0 * (double)i / (double)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;
}