mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-14 09:37:36 -05:00
#648 Resolves issue with audio panel sometimes displaying stale metadata that doesn't clear until the next audio segment is loaded. (#1545)
Co-authored-by: Dennis Sheirer <dsheirer@github.com>
This commit is contained in:
@@ -79,6 +79,7 @@ public abstract class AudioOutput implements LineListener, Listener<IdentifierUp
|
|||||||
private boolean mRunning = false;
|
private boolean mRunning = false;
|
||||||
private ScheduledExecutorService mScheduledExecutorService;
|
private ScheduledExecutorService mScheduledExecutorService;
|
||||||
private ScheduledFuture<?> mProcessorFuture;
|
private ScheduledFuture<?> mProcessorFuture;
|
||||||
|
private boolean mDropDuplicates;
|
||||||
private long mOutputLastTimestamp = 0;
|
private long mOutputLastTimestamp = 0;
|
||||||
private static final long STALE_PLAYBACK_THRESHOLD_MS = 500;
|
private static final long STALE_PLAYBACK_THRESHOLD_MS = 500;
|
||||||
|
|
||||||
@@ -104,6 +105,7 @@ public abstract class AudioOutput implements LineListener, Listener<IdentifierUp
|
|||||||
mScheduledExecutorService = Executors.newSingleThreadScheduledExecutor(new NamingThreadFactory(
|
mScheduledExecutorService = Executors.newSingleThreadScheduledExecutor(new NamingThreadFactory(
|
||||||
"sdrtrunk audio output " + mixerChannel.name()));
|
"sdrtrunk audio output " + mixerChannel.name()));
|
||||||
mUserPreferences = userPreferences;
|
mUserPreferences = userPreferences;
|
||||||
|
mDropDuplicates = mUserPreferences.getDuplicateCallDetectionPreference().isDuplicatePlaybackSuppressionEnabled();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -163,7 +165,7 @@ public abstract class AudioOutput implements LineListener, Listener<IdentifierUp
|
|||||||
|
|
||||||
updateToneInsertionAudioClips();
|
updateToneInsertionAudioClips();
|
||||||
|
|
||||||
//Register to receive directory preference update notifications so we can update the preference items
|
//Register to receive preference update notifications so we can update the preference items
|
||||||
MyEventBus.getGlobalEventBus().register(this);
|
MyEventBus.getGlobalEventBus().register(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,6 +228,10 @@ public abstract class AudioOutput implements LineListener, Listener<IdentifierUp
|
|||||||
{
|
{
|
||||||
updateToneInsertionAudioClips();
|
updateToneInsertionAudioClips();
|
||||||
}
|
}
|
||||||
|
else if(preferenceType == PreferenceType.DUPLICATE_CALL_DETECTION)
|
||||||
|
{
|
||||||
|
mDropDuplicates = mUserPreferences.getDuplicateCallDetectionPreference().isDuplicatePlaybackSuppressionEnabled();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -301,6 +307,7 @@ public abstract class AudioOutput implements LineListener, Listener<IdentifierUp
|
|||||||
mCurrentAudioSegment.decrementConsumerCount();
|
mCurrentAudioSegment.decrementConsumerCount();
|
||||||
mCurrentAudioSegment.removeIdentifierUpdateNotificationListener(this);
|
mCurrentAudioSegment.removeIdentifierUpdateNotificationListener(this);
|
||||||
mCurrentAudioSegment = null;
|
mCurrentAudioSegment = null;
|
||||||
|
broadcast(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -352,10 +359,7 @@ public abstract class AudioOutput implements LineListener, Listener<IdentifierUp
|
|||||||
*/
|
*/
|
||||||
private boolean isThrowaway(AudioSegment audioSegment)
|
private boolean isThrowaway(AudioSegment audioSegment)
|
||||||
{
|
{
|
||||||
return audioSegment != null &&
|
return audioSegment != null && (audioSegment.isDoNotMonitor() || mDropDuplicates && (audioSegment.isDuplicate()));
|
||||||
(audioSegment.isDoNotMonitor() ||
|
|
||||||
(audioSegment.isDuplicate() && mUserPreferences.getDuplicateCallDetectionPreference()
|
|
||||||
.isDuplicatePlaybackSuppressionEnabled()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -371,8 +375,8 @@ public abstract class AudioOutput implements LineListener, Listener<IdentifierUp
|
|||||||
loadNextAudioSegment();
|
loadNextAudioSegment();
|
||||||
}
|
}
|
||||||
|
|
||||||
//Reevaluate current audio segment to see if the status has changed for duplicate or do-not-monitor.
|
//Evaluate current audio segment to see if the status has changed for duplicate or do-not-monitor.
|
||||||
if(isThrowaway(mCurrentAudioSegment))
|
while(isThrowaway(mCurrentAudioSegment))
|
||||||
{
|
{
|
||||||
if(mCurrentBufferIndex > 0)
|
if(mCurrentBufferIndex > 0)
|
||||||
{
|
{
|
||||||
@@ -385,29 +389,42 @@ public abstract class AudioOutput implements LineListener, Listener<IdentifierUp
|
|||||||
|
|
||||||
while(mCurrentAudioSegment != null && mCurrentBufferIndex < mCurrentAudioSegment.getAudioBufferCount())
|
while(mCurrentAudioSegment != null && mCurrentBufferIndex < mCurrentAudioSegment.getAudioBufferCount())
|
||||||
{
|
{
|
||||||
if(mCurrentBufferIndex == 0)
|
//Continuously evaluate current audio segment to see if the status has changed for duplicate or do-not-monitor.
|
||||||
|
if(isThrowaway(mCurrentAudioSegment))
|
||||||
{
|
{
|
||||||
playAudio(mAudioSegmentStartTone);
|
if(mCurrentBufferIndex > 0)
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
float[] audioBuffer = mCurrentAudioSegment.getAudioBuffers().get(mCurrentBufferIndex++);
|
|
||||||
|
|
||||||
if(audioBuffer != null)
|
|
||||||
{
|
{
|
||||||
ByteBuffer audio = convert(audioBuffer);
|
playAudio(mAudioSegmentDropTone);
|
||||||
//This call blocks until all audio bytes are dumped into the data line.
|
|
||||||
playAudio(audio);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
disposeCurrentAudioSegment();
|
||||||
}
|
}
|
||||||
catch(Exception e)
|
else
|
||||||
{
|
{
|
||||||
mLog.error("Error while processing audio for [" + mMixerChannel.name() + "]", e);
|
if(mCurrentBufferIndex == 0)
|
||||||
|
{
|
||||||
|
playAudio(mAudioSegmentStartTone);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
float[] audioBuffer = mCurrentAudioSegment.getAudioBuffers().get(mCurrentBufferIndex++);
|
||||||
|
|
||||||
|
if(audioBuffer != null)
|
||||||
|
{
|
||||||
|
ByteBuffer audio = convert(audioBuffer);
|
||||||
|
//This call blocks until all audio bytes are dumped into the data line.
|
||||||
|
playAudio(audio);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
mLog.error("Error while processing audio for [" + mMixerChannel.name() + "]", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Check for completed and fully-played audio segment -- load next audio segment
|
//Check for completed and fully-played audio segment to closeout
|
||||||
if(mCurrentAudioSegment != null &&
|
if(mCurrentAudioSegment != null &&
|
||||||
mCurrentAudioSegment.isComplete() &&
|
mCurrentAudioSegment.isComplete() &&
|
||||||
(mCurrentBufferIndex >= mCurrentAudioSegment.getAudioBufferCount()))
|
(mCurrentBufferIndex >= mCurrentAudioSegment.getAudioBufferCount()))
|
||||||
@@ -649,16 +666,6 @@ public abstract class AudioOutput implements LineListener, Listener<IdentifierUp
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
//TODO: Debug hooks - remove after testing
|
|
||||||
if(mMixerChannel.name().equals("LEFT"))
|
|
||||||
{
|
|
||||||
int a = 0;
|
|
||||||
}
|
|
||||||
else if(mMixerChannel.name().equals("RIGHT"))
|
|
||||||
{
|
|
||||||
int a = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
processAudio();
|
processAudio();
|
||||||
}
|
}
|
||||||
catch(Throwable t)
|
catch(Throwable t)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* *****************************************************************************
|
* *****************************************************************************
|
||||||
* Copyright (C) 2014-2020 Dennis Sheirer
|
* Copyright (C) 2014-2023 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -27,6 +27,8 @@ import io.github.dsheirer.gui.control.PrefixIdentFormatter;
|
|||||||
import io.github.dsheirer.preference.UserPreferences;
|
import io.github.dsheirer.preference.UserPreferences;
|
||||||
import io.github.dsheirer.preference.identifier.IntegerFormat;
|
import io.github.dsheirer.preference.identifier.IntegerFormat;
|
||||||
import io.github.dsheirer.protocol.Protocol;
|
import io.github.dsheirer.protocol.Protocol;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import javafx.beans.value.ChangeListener;
|
import javafx.beans.value.ChangeListener;
|
||||||
import javafx.beans.value.ObservableValue;
|
import javafx.beans.value.ObservableValue;
|
||||||
import javafx.geometry.HPos;
|
import javafx.geometry.HPos;
|
||||||
@@ -38,9 +40,6 @@ import javafx.scene.layout.GridPane;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Editor for talkgroup range alias identifiers
|
* Editor for talkgroup range alias identifiers
|
||||||
*/
|
*/
|
||||||
@@ -291,6 +290,10 @@ public class TalkgroupRangeEditor extends IdentifierEditor<TalkgroupRange>
|
|||||||
private List<TalkgroupDetail> createTalkgroupDetails()
|
private List<TalkgroupDetail> createTalkgroupDetails()
|
||||||
{
|
{
|
||||||
List<TalkgroupDetail> details = new ArrayList<>();
|
List<TalkgroupDetail> details = new ArrayList<>();
|
||||||
|
details.add(new TalkgroupDetail(Protocol.AM, IntegerFormat.DECIMAL, new IntegerFormatter(0,65535),
|
||||||
|
new IntegerFormatter(0,65535), "Format 0 - 65535"));
|
||||||
|
details.add(new TalkgroupDetail(Protocol.AM, IntegerFormat.HEXADECIMAL, new IntegerFormatter(0,65535),
|
||||||
|
new IntegerFormatter(0,65535), "Format 0 - FFFF"));
|
||||||
details.add(new TalkgroupDetail(Protocol.APCO25, IntegerFormat.DECIMAL, new IntegerFormatter(0,65535),
|
details.add(new TalkgroupDetail(Protocol.APCO25, IntegerFormat.DECIMAL, new IntegerFormatter(0,65535),
|
||||||
new IntegerFormatter(0,65535), "Format: 0 - 65535"));
|
new IntegerFormatter(0,65535), "Format: 0 - 65535"));
|
||||||
details.add(new TalkgroupDetail(Protocol.APCO25, IntegerFormat.HEXADECIMAL, new HexFormatter(0,65535),
|
details.add(new TalkgroupDetail(Protocol.APCO25, IntegerFormat.HEXADECIMAL, new HexFormatter(0,65535),
|
||||||
@@ -307,6 +310,10 @@ public class TalkgroupRangeEditor extends IdentifierEditor<TalkgroupRange>
|
|||||||
details.add(new TalkgroupDetail(Protocol.MPT1327, IntegerFormat.FORMATTED,
|
details.add(new TalkgroupDetail(Protocol.MPT1327, IntegerFormat.FORMATTED,
|
||||||
new PrefixIdentFormatter(0,0xFFFFF), new PrefixIdentFormatter(0,0xFFFFF),
|
new PrefixIdentFormatter(0,0xFFFFF), new PrefixIdentFormatter(0,0xFFFFF),
|
||||||
"Format: PPP-IIII = Prefix (0-127), Ident (1-8191)"));
|
"Format: PPP-IIII = Prefix (0-127), Ident (1-8191)"));
|
||||||
|
details.add(new TalkgroupDetail(Protocol.NBFM, IntegerFormat.DECIMAL, new IntegerFormatter(0,65535),
|
||||||
|
new IntegerFormatter(0,65535), "Format 0 - 65535"));
|
||||||
|
details.add(new TalkgroupDetail(Protocol.NBFM, IntegerFormat.HEXADECIMAL, new IntegerFormatter(0,65535),
|
||||||
|
new IntegerFormatter(0,65535), "Format 0 - FFFF"));
|
||||||
details.add(new TalkgroupDetail(Protocol.PASSPORT, IntegerFormat.DECIMAL, new IntegerFormatter(0,0xFFFF),
|
details.add(new TalkgroupDetail(Protocol.PASSPORT, IntegerFormat.DECIMAL, new IntegerFormatter(0,0xFFFF),
|
||||||
new IntegerFormatter(0,0xFFFF), "Format: 0 - 65535"));
|
new IntegerFormatter(0,0xFFFF), "Format: 0 - 65535"));
|
||||||
details.add(new TalkgroupDetail(Protocol.PASSPORT, IntegerFormat.HEXADECIMAL, new HexFormatter(0,0xFFFF),
|
details.add(new TalkgroupDetail(Protocol.PASSPORT, IntegerFormat.HEXADECIMAL, new HexFormatter(0,0xFFFF),
|
||||||
|
|||||||
Reference in New Issue
Block a user