|
|
|
|
@ -72,6 +72,7 @@ class RadioAudioEngine {
|
|
|
|
|
@Volatile private var captureRunning = false |
|
|
|
|
@Volatile private var playbackRunning = false |
|
|
|
|
@Volatile private var requestedTalk = false |
|
|
|
|
private val pttHolds = RadioPttHolds() |
|
|
|
|
@Volatile private var talkRequestNs = 0L |
|
|
|
|
@Volatile private var generation = 0L |
|
|
|
|
private var audioGroup = 0L |
|
|
|
|
@ -135,6 +136,7 @@ class RadioAudioEngine {
|
|
|
|
|
active = true |
|
|
|
|
groupId = group |
|
|
|
|
requestedTalk = false |
|
|
|
|
pttHolds.cancel() |
|
|
|
|
_talkingFlow.value = false |
|
|
|
|
io.execute { |
|
|
|
|
if (!active || generation != version) return@execute |
|
|
|
|
@ -156,6 +158,7 @@ class RadioAudioEngine {
|
|
|
|
|
mainHandler.removeCallbacks(releaseTalk) |
|
|
|
|
active = false |
|
|
|
|
requestedTalk = false |
|
|
|
|
pttHolds.cancel() |
|
|
|
|
_talkingFlow.value = false |
|
|
|
|
++generation |
|
|
|
|
io.execute { releaseLocked() } |
|
|
|
|
@ -513,7 +516,7 @@ class RadioAudioEngine {
|
|
|
|
|
restoreAudioMode() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fun talkBegin(): Boolean { |
|
|
|
|
internal fun talkBegin(source: RadioPttSource = RadioPttSource.BUTTON): Boolean { |
|
|
|
|
if (!active) return false |
|
|
|
|
if (!MicrophonePermission.granted()) { |
|
|
|
|
MicrophonePermission.request("PTT") { |
|
|
|
|
@ -524,6 +527,8 @@ class RadioAudioEngine {
|
|
|
|
|
return false |
|
|
|
|
} |
|
|
|
|
mainHandler.removeCallbacks(releaseTalk) |
|
|
|
|
pttHolds.press(source) |
|
|
|
|
LogManager.addLog("DEBUG", "RadioAudio", "PTT hold source=$source transmitting=$requestedTalk group=$groupId") |
|
|
|
|
if (requestedTalk) return true |
|
|
|
|
talkRequestNs = SystemClock.elapsedRealtimeNanos() |
|
|
|
|
requestedTalk = true |
|
|
|
|
@ -540,15 +545,17 @@ class RadioAudioEngine {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** Отпускание: 250мс передачи, повторное касание отменяет завершение. */ |
|
|
|
|
fun talkEnd() { |
|
|
|
|
internal fun talkEnd(source: RadioPttSource = RadioPttSource.BUTTON) { |
|
|
|
|
if (!pttHolds.release(source)) return |
|
|
|
|
if (!active || !requestedTalk) return |
|
|
|
|
mainHandler.removeCallbacks(releaseTalk) |
|
|
|
|
mainHandler.postDelayed(releaseTalk, RELEASE_HOLD_MS) |
|
|
|
|
LogManager.addLog("DEBUG", "RadioAudio", "PTT release scheduled +${RELEASE_HOLD_MS}ms") |
|
|
|
|
LogManager.addLog("DEBUG", "RadioAudio", "PTT release source=$source scheduled +${RELEASE_HOLD_MS}ms") |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** Отмена без хвоста передачи при выключении/потере разрешений. */ |
|
|
|
|
fun cancelTalk() { |
|
|
|
|
internal fun cancelTalk(source: RadioPttSource? = null) { |
|
|
|
|
if (!pttHolds.cancel(source)) return |
|
|
|
|
mainHandler.removeCallbacks(releaseTalk) |
|
|
|
|
finishTalk() |
|
|
|
|
} |
|
|
|
|
|