File tree Expand file tree Collapse file tree 1 file changed +12
-0
lines changed
AudioCoder/src/main/java/org/operatorfoundation/audiocoder Expand file tree Collapse file tree 1 file changed +12
-0
lines changed Original file line number Diff line number Diff line change @@ -4,6 +4,7 @@ import org.operatorfoundation.audiocoder.WSPRBandplan.getDefaultFrequency
44import org.operatorfoundation.audiocoder.WSPRConstants.WSPR_REQUIRED_SAMPLE_RATE
55import org.operatorfoundation.audiocoder.WSPRConstants.SYMBOLS_PER_MESSAGE
66import timber.log.Timber
7+ import kotlin.math.pow
78
89/* *
910 * High-level WSPR audio processing with buffering and multiple decode strategies.
@@ -223,6 +224,9 @@ class WSPRProcessor
223224 Timber .d(" Frequency: ${dialFrequencyMHz} MHz" )
224225 Timber .d(" LSB: $useLowerSideband " )
225226
227+ val audioQuality = analyzeAudioQuality(windowSamples)
228+ Timber .d(" Audio quality: $audioQuality " )
229+
226230 val messages = CJarInterface .WSPRDecodeFromPcm (audioBytes, dialFrequencyMHz, useLowerSideband)
227231
228232 Timber .d(" Native decoder returned: ${messages?.size ? : " null" } messages" )
@@ -263,6 +267,14 @@ class WSPRProcessor
263267 }
264268 }
265269
270+ private fun analyzeAudioQuality (samples : ShortArray ): String
271+ {
272+ val rms = kotlin.math.sqrt(samples.map { (it.toFloat() / Short .MAX_VALUE ).pow(2 ) }.average())
273+ val peakSample = samples.maxOfOrNull { kotlin.math.abs(it.toInt()) } ? : 0
274+ val peak = peakSample.toFloat() / Short .MAX_VALUE
275+ return " RMS=%.3f, Peak=%.3f" .format(rms, peak)
276+ }
277+
266278 /* *
267279 * Converts 16-bit audio samples to byte array for native decoder.
268280 * Uses little-endian byte order as expected by the WSPR decoder.
You can’t perform that action at this time.
0 commit comments