summaryrefslogtreecommitdiffstats
path: root/pica-client/echocanceller.h
diff options
context:
space:
mode:
authorAnton <anton@picapica.im>2026-09-01 00:13:30 +0400
committerAnton <anton@picapica.im>2026-09-01 00:13:30 +0400
commit6b01fe69c7125c01c9327a27f0d1bac0af244c17 (patch)
treefb8bc8cfd5a505ef1627c782d28e54912c9165ec /pica-client/echocanceller.h
parent412cf7250058c6fc03d42d396924dd1074e6623d (diff)
downloadpica-pica-6b01fe69c7125c01c9327a27f0d1bac0af244c17.tar.gz
pica-pica-6b01fe69c7125c01c9327a27f0d1bac0af244c17.zip
pica-client: increase jitter buffer, add echo canceller debug output
Diffstat (limited to 'pica-client/echocanceller.h')
-rw-r--r--pica-client/echocanceller.h34
1 files changed, 33 insertions, 1 deletions
diff --git a/pica-client/echocanceller.h b/pica-client/echocanceller.h
index 476e88e..c49962d 100644
--- a/pica-client/echocanceller.h
+++ b/pica-client/echocanceller.h
@@ -76,8 +76,27 @@ public:
// Rough measure of how well it is working, in dB - how much quieter the
// output is than the microphone input while the far end is active. Zero
// until enough far end audio has gone through to mean anything.
+ //
+ // Only meaningful while the far end is actually talking, which is what
+ // farEndLevelDb() is for: with nothing coming out of the speaker there is
+ // no echo to remove and the figure means nothing.
double erle();
+ // Recent signal levels in dBFS, averaged over the same window as erle().
+ // nearEndLevelDb() is the microphone before cancellation - a floor-level
+ // reading there means the capture path is dead and nothing else in the
+ // numbers is worth reading.
+ double nearEndLevelDb();
+ double farEndLevelDb();
+
+ // Far end samples waiting to be paired with microphone audio. In the
+ // steady state this settles at the depth of the sound card's output
+ // buffer and stays there, because both are drained by the same clock.
+ // Climbing towards m_farCapacity means capture and playback are running
+ // off different clocks - separate cards - and the reference is drifting
+ // out of alignment with the echo it is supposed to explain.
+ int farEndDepth();
+
private:
Q_DISABLE_COPY(EchoCanceller)
@@ -109,11 +128,24 @@ private:
// explain.
int m_farCapacity;
- // Running sums of near end and output energy, for erle().
+ // Exponentially averaged mean square of the near end (microphone), the
+ // cancelled output and the far end reference, for erle() and the level
+ // readings. Per sample rather than per call, so they stay comparable
+ // whatever block size the capture path hands us.
double m_nearEnergy;
double m_outEnergy;
+ double m_farEnergy;
QMutex m_statMutex;
+ // Drives the periodic qDebug() in processNearEnd(). Counted in samples
+ // rather than wall clock so the report interval does not depend on how
+ // punctually the capture thread is scheduled. Guarded by m_statMutex.
+ qint64 m_processedSamples;
+ qint64 m_nextReportSamples;
+
+ // How often the canceller reports how it is doing, in seconds.
+ static const int kReportIntervalSec = 2;
+
// Scratch far end block, reused by processNearEnd().
QVector<qint16> m_farBlock;