Created
May 20, 2021 03:07
-
-
Save luigi-rosso/358d068569d029d9959785c5a2b1effd to your computer and use it in GitHub Desktop.
Test of simple autocorrelation from https://github.com/cycfi/bitstream_autocorrelation/blob/master/bcf2.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef _DAISY_BISTREAM_AUTOCORRELATION_HPP_ | |
#define _DAISY_BISTREAM_AUTOCORRELATION_HPP_ | |
#include <cmath> | |
#include <cstdint> | |
#include <type_traits> | |
#include <vector> | |
// smallest power of 2 that fits n | |
template <typename T> constexpr T smallest_pow2(T n, T m = 1) | |
{ | |
return (m < n) ? smallest_pow2(n, m << 1) : m; | |
} | |
std::uint32_t count_bits(std::uint32_t i) | |
{ | |
// GCC only!!! | |
return __builtin_popcount(i); | |
} | |
std::uint64_t count_bits(std::uint64_t i) | |
{ | |
// GCC only!!! | |
return __builtin_popcountll(i); | |
} | |
template <typename T = std::uint32_t> struct bitstream | |
{ | |
static_assert(std::is_unsigned<T>::value, "T must be unsigned"); | |
static constexpr auto nbits = 8 * sizeof(T); | |
bitstream(std::size_t size_) | |
{ | |
size = smallest_pow2(size_); | |
array_size = size / nbits; | |
bits.resize(array_size, 0); | |
} | |
void clear() { std::fill(bits.begin(), bits.end(), 0); } | |
void set(std::uint32_t i, bool val) | |
{ | |
auto mask = 1 << (i % nbits); | |
auto& ref = bits[i / nbits]; | |
ref ^= (-T(val) ^ ref) & mask; | |
} | |
bool get(std::uint32_t i) const | |
{ | |
auto mask = 1 << (i % nbits); | |
return (bits[i / nbits] & mask) != 0; | |
} | |
template <typename F> void auto_correlate(std::size_t start_pos, F f) | |
{ | |
auto mid_array = (array_size / 2) - 1; | |
auto mid_pos = size / 2; | |
auto index = start_pos / nbits; | |
auto shift = start_pos % nbits; | |
for (auto pos = start_pos; pos != mid_pos; ++pos) | |
{ | |
auto* p1 = bits.data(); | |
auto* p2 = bits.data() + index; | |
auto count = 0; | |
if (shift == 0) | |
{ | |
for (auto i = 0; i != mid_array; ++i) | |
count += count_bits(*p1++ ^ *p2++); | |
} | |
else | |
{ | |
auto shift2 = nbits - shift; | |
for (auto i = 0; i != mid_array; ++i) | |
{ | |
auto v = *p2++ >> shift; | |
v |= *p2 << shift2; | |
count += count_bits(*p1++ ^ v); | |
} | |
} | |
++shift; | |
if (shift == nbits) | |
{ | |
shift = 0; | |
++index; | |
} | |
f(pos, count); | |
} | |
} | |
std::vector<T> bits; | |
std::size_t size; | |
std::size_t array_size; | |
}; | |
struct zero_cross | |
{ | |
bool operator()(float s) | |
{ | |
if (s < -0.1f) | |
y = 0; | |
else if (s > 0.0f) | |
y = 1; | |
return y; | |
} | |
bool y = 0; | |
}; | |
struct noise | |
{ | |
float operator()() const { return (float(rand()) / (RAND_MAX / 2)) - 1.0; } | |
}; | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment