mirror of
https://github.com/eried/portapack-mayhem.git
synced 2025-01-11 07:19:34 -05:00
Change baseband floats to normalize at +/-1.0.
This commit is contained in:
parent
a5ed3b20b4
commit
ef86848139
@ -40,8 +40,7 @@ float GainComputer::operator()(const float x) const {
|
||||
void FeedForwardCompressor::execute_in_place(const buffer_f32_t& buffer) {
|
||||
constexpr float makeup_gain = std::pow(10.0f, (threshold - (threshold / ratio)) / -20.0f);
|
||||
for(size_t i=0; i<buffer.count; i++) {
|
||||
// TODO: Terrible hack here due to not normalizing float samples to +/-1.0.
|
||||
buffer.p[i] = execute_once(buffer.p[i] * (1.0f / 32768.0f)) * (makeup_gain * 32768.0f);
|
||||
buffer.p[i] = execute_once(buffer.p[i]) * makeup_gain;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ void AudioOutput::write(
|
||||
) {
|
||||
std::array<float, 32> audio_f;
|
||||
for(size_t i=0; i<audio.count; i++) {
|
||||
audio_f[i] = audio.p[i];
|
||||
audio_f[i] = audio.p[i] * ki;
|
||||
}
|
||||
write(buffer_f32_t {
|
||||
audio_f.data(),
|
||||
@ -89,7 +89,7 @@ void AudioOutput::on_block(
|
||||
void AudioOutput::fill_audio_buffer(const buffer_f32_t& audio) {
|
||||
auto audio_buffer = audio::dma::tx_empty_buffer();
|
||||
for(size_t i=0; i<audio_buffer.count; i++) {
|
||||
const int32_t sample_int = audio.p[i];
|
||||
const int32_t sample_int = audio.p[i] * k;
|
||||
const int32_t sample_saturated = __SSAT(sample_int, 16);
|
||||
audio_buffer.p[i].left = audio_buffer.p[i].right = sample_saturated;
|
||||
}
|
||||
|
@ -44,6 +44,9 @@ public:
|
||||
void write(const buffer_f32_t& audio);
|
||||
|
||||
private:
|
||||
static constexpr float k = 32768.0f;
|
||||
static constexpr float ki = 1.0f / k;
|
||||
|
||||
BlockDecimator<float, 32> block_buffer { 1 };
|
||||
|
||||
IIRBiquadFilter hpf;
|
||||
|
@ -42,8 +42,8 @@ bool AudioStatsCollector::update_stats(const size_t sample_count, const size_t s
|
||||
const size_t samples_per_update = sampling_rate * update_interval;
|
||||
|
||||
if( count >= samples_per_update ) {
|
||||
statistics.rms_db = complex16_mag_squared_to_dbv_norm(squared_sum / count);
|
||||
statistics.max_db = complex16_mag_squared_to_dbv_norm(max_squared);
|
||||
statistics.rms_db = mag2_to_dbv_norm(squared_sum / count);
|
||||
statistics.max_db = mag2_to_dbv_norm(max_squared);
|
||||
statistics.count = count;
|
||||
|
||||
squared_sum = 0;
|
||||
|
@ -49,7 +49,7 @@ public:
|
||||
|
||||
if( count >= samples_per_update ) {
|
||||
const float max_squared_f = max_squared;
|
||||
const int32_t max_db = complex16_mag_squared_to_dbv_norm(max_squared_f);
|
||||
const int32_t max_db = mag2_to_dbv_norm(max_squared_f * (1.0f / (32768.0f * 32768.0f)));
|
||||
callback({ max_db, count });
|
||||
|
||||
max_squared = 0;
|
||||
|
@ -42,8 +42,8 @@ buffer_f32_t AM::execute(
|
||||
const uint32_t sample1 = *__SIMD32(src_p)++;
|
||||
const uint32_t mag_sq0 = __SMUAD(sample0, sample0);
|
||||
const uint32_t mag_sq1 = __SMUAD(sample1, sample1);
|
||||
*(dst_p++) = __builtin_sqrtf(mag_sq0);
|
||||
*(dst_p++) = __builtin_sqrtf(mag_sq1);
|
||||
*(dst_p++) = __builtin_sqrtf(mag_sq0) * k;
|
||||
*(dst_p++) = __builtin_sqrtf(mag_sq1) * k;
|
||||
}
|
||||
|
||||
return { dst.p, src.count, src.sampling_rate };
|
||||
@ -57,10 +57,10 @@ buffer_f32_t SSB::execute(
|
||||
const auto src_end = &src.p[src.count];
|
||||
auto dst_p = dst.p;
|
||||
while(src_p < src_end) {
|
||||
*(dst_p++) = (src_p++)->real();
|
||||
*(dst_p++) = (src_p++)->real();
|
||||
*(dst_p++) = (src_p++)->real();
|
||||
*(dst_p++) = (src_p++)->real();
|
||||
*(dst_p++) = (src_p++)->real() * k;
|
||||
*(dst_p++) = (src_p++)->real() * k;
|
||||
*(dst_p++) = (src_p++)->real() * k;
|
||||
*(dst_p++) = (src_p++)->real() * k;
|
||||
}
|
||||
|
||||
return { dst.p, src.count, src.sampling_rate };
|
||||
@ -99,8 +99,8 @@ buffer_f32_t FM::execute(
|
||||
const auto t0 = multiply_conjugate_s16_s32(s0, z);
|
||||
const auto t1 = multiply_conjugate_s16_s32(s1, s0);
|
||||
z = s1;
|
||||
*(dst_p++) = angle_precise(t0) * k;
|
||||
*(dst_p++) = angle_precise(t1) * k;
|
||||
*(dst_p++) = angle_precise(t0) * kf;
|
||||
*(dst_p++) = angle_precise(t1) * kf;
|
||||
}
|
||||
z_ = z;
|
||||
|
||||
@ -122,9 +122,9 @@ buffer_s16_t FM::execute(
|
||||
const auto t0 = multiply_conjugate_s16_s32(s0, z);
|
||||
const auto t1 = multiply_conjugate_s16_s32(s1, s0);
|
||||
z = s1;
|
||||
const int32_t theta0_int = angle_approx_0deg27(t0) * k;
|
||||
const int32_t theta0_int = angle_approx_0deg27(t0) * ks16;
|
||||
const int32_t theta0_sat = __SSAT(theta0_int, 16);
|
||||
const int32_t theta1_int = angle_approx_0deg27(t1) * k;
|
||||
const int32_t theta1_int = angle_approx_0deg27(t1) * ks16;
|
||||
const int32_t theta1_sat = __SSAT(theta1_int, 16);
|
||||
*__SIMD32(dst_p)++ = __PKHBT(
|
||||
theta0_sat,
|
||||
@ -143,7 +143,8 @@ void FM::configure(const float sampling_rate, const float deviation_hz) {
|
||||
* Maximum delta-theta (output of atan2) at maximum deviation frequency:
|
||||
* delta_theta_max = 2 * pi * deviation / sampling_rate
|
||||
*/
|
||||
k = static_cast<float>(32767.0f / (2.0 * pi * deviation_hz / sampling_rate));
|
||||
kf = static_cast<float>(1.0f / (2.0 * pi * deviation_hz / sampling_rate));
|
||||
ks16 = 32767.0f * kf;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -33,6 +33,9 @@ public:
|
||||
const buffer_c16_t& src,
|
||||
const buffer_f32_t& dst
|
||||
);
|
||||
|
||||
private:
|
||||
static constexpr float k = 1.0f / 32768.0f;
|
||||
};
|
||||
|
||||
class SSB {
|
||||
@ -41,6 +44,9 @@ public:
|
||||
const buffer_c16_t& src,
|
||||
const buffer_f32_t& dst
|
||||
);
|
||||
|
||||
private:
|
||||
static constexpr float k = 1.0f / 32768.0f;
|
||||
};
|
||||
|
||||
class FM {
|
||||
@ -59,7 +65,8 @@ public:
|
||||
|
||||
private:
|
||||
complex16_t::rep_type z_ { 0 };
|
||||
float k { 0 };
|
||||
float kf { 0 };
|
||||
float ks16 { 0 };
|
||||
};
|
||||
|
||||
} /* namespace demodulate */
|
||||
|
@ -117,8 +117,8 @@ void SpectrumCollector::update() {
|
||||
// Three point Hamming window.
|
||||
const auto corrected_sample = channel_spectrum[i] * 0.54f
|
||||
+ (channel_spectrum[(i-1) & 0xff] + channel_spectrum[(i+1) & 0xff]) * -0.23f;
|
||||
const auto mag2 = magnitude_squared(corrected_sample);
|
||||
const float db = complex16_mag_squared_to_dbv_norm(mag2);
|
||||
const auto mag2 = magnitude_squared(corrected_sample * (1.0f / 32768.0f));
|
||||
const float db = mag2_to_dbv_norm(mag2);
|
||||
constexpr float mag_scale = 5.0f;
|
||||
const unsigned int v = (db * mag_scale) + 255.0f;
|
||||
spectrum.db[i] = std::max(0U, std::min(255U, v));
|
||||
|
@ -82,15 +82,14 @@ float fast_pow2(const float val) {
|
||||
return u.f;
|
||||
}
|
||||
|
||||
float complex16_mag_squared_to_dbv_norm(const float c16_mag_squared) {
|
||||
constexpr float input_component_max = 32768;
|
||||
constexpr float mag2_max = (input_component_max * input_component_max) * 2;
|
||||
float mag2_to_dbv_norm(const float mag2) {
|
||||
constexpr float mag2_max = 1.0f;
|
||||
constexpr float mag2_log2_max = std::log2(mag2_max);
|
||||
constexpr float log_mag2_mag_factor = 0.5f;
|
||||
constexpr float log2_log10_factor = std::log10(2.0f);
|
||||
constexpr float log10_dbv_factor = 20.0f;
|
||||
constexpr float mag2_to_db_factor = log_mag2_mag_factor * log2_log10_factor * log10_dbv_factor;
|
||||
return (fast_log2(c16_mag_squared) - mag2_log2_max) * mag2_to_db_factor;
|
||||
return (fast_log2(mag2) - mag2_log2_max) * mag2_to_db_factor;
|
||||
}
|
||||
|
||||
/* GCD implementation derived from recursive implementation at
|
||||
|
@ -72,7 +72,7 @@ constexpr size_t log_2(const size_t n, const size_t p = 0) {
|
||||
float fast_log2(const float val);
|
||||
float fast_pow2(const float val);
|
||||
|
||||
float complex16_mag_squared_to_dbv_norm(const float c16_mag_squared);
|
||||
float mag2_to_dbv_norm(const float mag2);
|
||||
|
||||
inline float magnitude_squared(const std::complex<float> c) {
|
||||
const auto r = c.real();
|
||||
|
Loading…
Reference in New Issue
Block a user