From ef868481393e11f3ce5d3613ac374a45a17eb7c0 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 14 Feb 2016 12:38:50 -0800 Subject: [PATCH] Change baseband floats to normalize at +/-1.0. --- firmware/baseband/audio_compressor.cpp | 3 +-- firmware/baseband/audio_output.cpp | 4 ++-- firmware/baseband/audio_output.hpp | 3 +++ firmware/baseband/audio_stats_collector.cpp | 4 ++-- firmware/baseband/channel_stats_collector.hpp | 2 +- firmware/baseband/dsp_demodulate.cpp | 23 ++++++++++--------- firmware/baseband/dsp_demodulate.hpp | 9 +++++++- firmware/baseband/spectrum_collector.cpp | 4 ++-- firmware/common/utility.cpp | 7 +++--- firmware/common/utility.hpp | 2 +- 10 files changed, 35 insertions(+), 26 deletions(-) diff --git a/firmware/baseband/audio_compressor.cpp b/firmware/baseband/audio_compressor.cpp index b4138408..95bbaee3 100644 --- a/firmware/baseband/audio_compressor.cpp +++ b/firmware/baseband/audio_compressor.cpp @@ -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 audio_f; for(size_t i=0; i block_buffer { 1 }; IIRBiquadFilter hpf; diff --git a/firmware/baseband/audio_stats_collector.cpp b/firmware/baseband/audio_stats_collector.cpp index 227d5887..53fceea8 100644 --- a/firmware/baseband/audio_stats_collector.cpp +++ b/firmware/baseband/audio_stats_collector.cpp @@ -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; diff --git a/firmware/baseband/channel_stats_collector.hpp b/firmware/baseband/channel_stats_collector.hpp index d03f03a1..ca7d0eed 100644 --- a/firmware/baseband/channel_stats_collector.hpp +++ b/firmware/baseband/channel_stats_collector.hpp @@ -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; diff --git a/firmware/baseband/dsp_demodulate.cpp b/firmware/baseband/dsp_demodulate.cpp index 3a0b7f12..cf79d0d0 100644 --- a/firmware/baseband/dsp_demodulate.cpp +++ b/firmware/baseband/dsp_demodulate.cpp @@ -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(32767.0f / (2.0 * pi * deviation_hz / sampling_rate)); + kf = static_cast(1.0f / (2.0 * pi * deviation_hz / sampling_rate)); + ks16 = 32767.0f * kf; } } diff --git a/firmware/baseband/dsp_demodulate.hpp b/firmware/baseband/dsp_demodulate.hpp index 00f9236a..72706167 100644 --- a/firmware/baseband/dsp_demodulate.hpp +++ b/firmware/baseband/dsp_demodulate.hpp @@ -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 */ diff --git a/firmware/baseband/spectrum_collector.cpp b/firmware/baseband/spectrum_collector.cpp index 2b661c9a..0d288bee 100644 --- a/firmware/baseband/spectrum_collector.cpp +++ b/firmware/baseband/spectrum_collector.cpp @@ -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)); diff --git a/firmware/common/utility.cpp b/firmware/common/utility.cpp index 7959eba0..9e167101 100644 --- a/firmware/common/utility.cpp +++ b/firmware/common/utility.cpp @@ -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 diff --git a/firmware/common/utility.hpp b/firmware/common/utility.hpp index a23ad3e2..c6cfab94 100644 --- a/firmware/common/utility.hpp +++ b/firmware/common/utility.hpp @@ -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 c) { const auto r = c.real();