diff --git a/app/src/main/java/ru/ua1zbe/svxremote/audio/OpusEngine.kt b/app/src/main/java/ru/ua1zbe/svxremote/audio/OpusEngine.kt index 8f9c5ae..9f3a944 100644 --- a/app/src/main/java/ru/ua1zbe/svxremote/audio/OpusEngine.kt +++ b/app/src/main/java/ru/ua1zbe/svxremote/audio/OpusEngine.kt @@ -331,10 +331,15 @@ class OpusEngine( private fun updateRxStats(seq: Int) { val now = System.currentTimeMillis() if (lastSeq >= 0) { - val gap = ((seq - lastSeq - 1) and 0xFFFF).toLong() - if (gap > 0) lossCount += gap - pktCount++ val dt = now - lastPktTime + // seq — счётчик ГОВОРЯЩЕГО: при повторах кадров он может + // повторяться или идти назад — это не потери. Пауза > 200 мс + // между пакетами — смена реплики/говорящего, тоже не потери. + if (dt <= 200) { + val gap = (seq - lastSeq - 1).toLong() + if (gap in 1..50000) lossCount += gap + } + pktCount++ val j = abs(dt - 20).toDouble() if (j < 100) { jitterAccum += j @@ -350,6 +355,7 @@ class OpusEngine( if (now - lastEvalTime < 5000 || pktCount < 30) return val lossPct = lossCount * 100.0 / pktCount val jitterMs = if (jitterN > 0) jitterAccum / jitterN else 0.0 + Log.d(TAG, "stats window: pkt=$pktCount loss=$lossCount pct=$lossPct j=$jitterMs lastSeq=$lastSeq") if (lossPct > 3.0 || jitterMs > 60.0) { if (autoKbps > AUTO_BITRATE_MIN) { autoKbps -= AUTO_BITRATE_STEP diff --git a/app/src/main/java/ru/ua1zbe/svxremote/proto/ReflectorClient.kt b/app/src/main/java/ru/ua1zbe/svxremote/proto/ReflectorClient.kt index ca2abca..b08ca3e 100644 --- a/app/src/main/java/ru/ua1zbe/svxremote/proto/ReflectorClient.kt +++ b/app/src/main/java/ru/ua1zbe/svxremote/proto/ReflectorClient.kt @@ -541,7 +541,7 @@ class ReflectorClient( if (data.size < 6) return val r = BinReader(data) val type = r.u16() - r.u16() // client id + val cid = r.u16() // client id val seq = r.u16() val payload = data.copyOfRange(6, data.size) when (type) { @@ -549,7 +549,7 @@ class ReflectorClient( ReflectorProtocol.MSG_UDP_AUDIO -> { val audio = MsgParser.udpAudio(payload) if (audio != null && audio.isNotEmpty()) { - Log.d(TAG, "UDP RX audio seq=$seq len=${audio.size}") + Log.d(TAG, "UDP RX audio seq=$seq cid=$cid len=${audio.size}") callbacks.onAudioPacket(audio, seq) } else { Log.w(TAG, "UDP RX audio empty/null len=${payload.size}")