feat: add audio demodulation and FFT processing, enhance audio input handling and visualization
This commit is contained in:
106
android/app/src/main/cpp/audio_demod.cpp
Normal file
106
android/app/src/main/cpp/audio_demod.cpp
Normal file
@@ -0,0 +1,106 @@
|
||||
#include "audio_demod.h"
|
||||
#include "demod.h"
|
||||
#include <android/log.h>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
|
||||
#define LOG_TAG "AudioDemod"
|
||||
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
|
||||
|
||||
#define FINE_CLKT_HI 1.90
|
||||
#define FINE_CLKT_LO 0.32
|
||||
#define SAMPLE_RATE 48000
|
||||
#define BAUD_RATE 1200
|
||||
|
||||
static double watch_ctr = 0.0;
|
||||
static double atb_ctr = 0.0;
|
||||
static double clkt = (double)SAMPLE_RATE / BAUD_RATE;
|
||||
static int last_value = 0;
|
||||
static int preamble_count = 0;
|
||||
static int pocbit = 0;
|
||||
static bool preamble_detected = false;
|
||||
static int crossing_count = 0;
|
||||
static int nSamples = 0;
|
||||
|
||||
static const int AUDIO_THRESHOLD = 128;
|
||||
|
||||
void resetAudioDemod() {
|
||||
watch_ctr = 0.0;
|
||||
atb_ctr = 0.0;
|
||||
clkt = (double)SAMPLE_RATE / BAUD_RATE;
|
||||
last_value = 0;
|
||||
preamble_count = 0;
|
||||
pocbit = 0;
|
||||
preamble_detected = false;
|
||||
crossing_count = 0;
|
||||
nSamples = 0;
|
||||
LOGD("Audio demodulator reset");
|
||||
}
|
||||
|
||||
void processAudioSamples(int16_t *samples, int size) {
|
||||
for (int i = 0; i < size; i++) {
|
||||
int audio_value = (samples[i] + 32768) / 256;
|
||||
|
||||
if (audio_value < 0) audio_value = 0;
|
||||
if (audio_value > 255) audio_value = 255;
|
||||
|
||||
int current_bit = (audio_value > AUDIO_THRESHOLD) ? 1 : 0;
|
||||
|
||||
if (current_bit != last_value) {
|
||||
crossing_count++;
|
||||
|
||||
if ((nSamples > 28) && (nSamples < 44)) {
|
||||
preamble_count++;
|
||||
|
||||
if (preamble_count > 50 && !preamble_detected) {
|
||||
preamble_detected = true;
|
||||
pocbit = 0;
|
||||
LOGD("Preamble detected! crossings=%d samples=%d", preamble_count, nSamples);
|
||||
}
|
||||
}
|
||||
|
||||
nSamples = 0;
|
||||
}
|
||||
|
||||
nSamples++;
|
||||
last_value = current_bit;
|
||||
|
||||
watch_ctr += 1.0;
|
||||
|
||||
if (watch_ctr - atb_ctr < 1.0) {
|
||||
int bit = current_bit;
|
||||
|
||||
if (preamble_detected) {
|
||||
processBasebandSample(bit);
|
||||
pocbit++;
|
||||
|
||||
if (pocbit > 1250) {
|
||||
LOGD("POCSAG timeout - no sync after 1250 bits");
|
||||
preamble_detected = false;
|
||||
preamble_count = 0;
|
||||
pocbit = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (crossing_count > 0) {
|
||||
double offset = watch_ctr - atb_ctr;
|
||||
|
||||
if (offset > FINE_CLKT_HI) {
|
||||
clkt -= 0.01;
|
||||
if (clkt < (SAMPLE_RATE / BAUD_RATE) * 0.95) {
|
||||
clkt = (SAMPLE_RATE / BAUD_RATE) * 0.95;
|
||||
}
|
||||
} else if (offset < FINE_CLKT_LO) {
|
||||
clkt += 0.01;
|
||||
if (clkt > (SAMPLE_RATE / BAUD_RATE) * 1.05) {
|
||||
clkt = (SAMPLE_RATE / BAUD_RATE) * 1.05;
|
||||
}
|
||||
}
|
||||
|
||||
crossing_count = 0;
|
||||
}
|
||||
|
||||
atb_ctr += clkt;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user