#817 Resolves issue with jittery audio playback and recording for MPT1327 channels. (#830)

Co-authored-by: Denny <denny@denny-desktop>
This commit is contained in:
Denny Sheirer
2020-05-24 07:58:59 -04:00
committed by GitHub
parent 3d816c3570
commit 2c3648f8c2
11 changed files with 131 additions and 52 deletions

View File

@@ -30,15 +30,28 @@ import io.github.dsheirer.controller.channel.Channel.ChannelType;
public class ChangeChannelTimeoutEvent extends DecoderStateEvent
{
private ChannelType mChannelType;
private long mCallTimeout;
private long mCallTimeoutMilliseconds;
/**
* Constructs an instance
* @param source of the event
* @param channelType for the event
* @param timeout in milliseconds
* @param timeslot of the event
*/
public ChangeChannelTimeoutEvent(Object source, ChannelType channelType, long timeout, int timeslot)
{
super(source, Event.CHANGE_CALL_TIMEOUT, State.IDLE, timeslot);
mChannelType = channelType;
mCallTimeout = timeout;
mCallTimeoutMilliseconds = timeout;
}
/**
* Constructs an instance
* @param source of the event
* @param channelType for the event
* @param timeout value in milliseconds
*/
public ChangeChannelTimeoutEvent(Object source, ChannelType channelType, long timeout)
{
this(source, channelType, timeout, 0);
@@ -49,8 +62,11 @@ public class ChangeChannelTimeoutEvent extends DecoderStateEvent
return mChannelType;
}
public long getCallTimeout()
/**
* Call timeout value in milliseconds
*/
public long getCallTimeoutMilliseconds()
{
return mCallTimeout;
return mCallTimeoutMilliseconds;
}
}

View File

@@ -115,14 +115,14 @@ public class MultiChannelState extends AbstractChannelState implements IDecoderS
stateMachine.setChannelType(mChannel.getChannelType());
stateMachine.setIdentifierUpdateListener(mutableIdentifierCollection);
stateMachine.setEndTimeoutBuffer(RESET_TIMEOUT_DELAY);
stateMachine.setEndTimeoutBufferMilliseconds(RESET_TIMEOUT_DELAY);
if(channel.getChannelType() == ChannelType.STANDARD)
{
stateMachine.setFadeTimeoutBuffer(FADE_TIMEOUT_DELAY);
stateMachine.setFadeTimeoutBufferMilliseconds(FADE_TIMEOUT_DELAY);
}
else
{
stateMachine.setFadeTimeoutBuffer(DecodeConfiguration.DEFAULT_CALL_TIMEOUT_DELAY_SECONDS * 1000);
stateMachine.setFadeTimeoutBufferMilliseconds(DecodeConfiguration.DEFAULT_CALL_TIMEOUT_DELAY_SECONDS * 1000);
}
}
@@ -529,7 +529,7 @@ public class MultiChannelState extends AbstractChannelState implements IDecoderS
if(event instanceof ChangeChannelTimeoutEvent)
{
ChangeChannelTimeoutEvent timeout = (ChangeChannelTimeoutEvent)event;
mStateMachineMap.get(event.getTimeslot()).setFadeTimeoutBuffer(timeout.getCallTimeout());
mStateMachineMap.get(event.getTimeslot()).setFadeTimeoutBufferMilliseconds(timeout.getCallTimeoutMilliseconds());
}
break;
case CONTINUATION:

View File

@@ -109,19 +109,19 @@ public class SingleChannelState extends AbstractChannelState implements IDecoder
mStateMachine.addListener(mSquelchController);
mStateMachine.setChannelType(mChannel.getChannelType());
mStateMachine.setIdentifierUpdateListener(mIdentifierCollection);
mStateMachine.setEndTimeoutBuffer(RESET_TIMEOUT_DELAY);
mStateMachine.setEndTimeoutBufferMilliseconds(RESET_TIMEOUT_DELAY);
if(channel.getChannelType() == ChannelType.STANDARD)
{
mStateMachine.setFadeTimeoutBuffer(FADE_TIMEOUT_DELAY);
mStateMachine.setFadeTimeoutBufferMilliseconds(FADE_TIMEOUT_DELAY);
}
else
{
final DecodeConfiguration decodeConfig = channel.getDecodeConfiguration();
final int fadeTimeoutSeconds = decodeConfig instanceof WithCallTimeout
? ((WithCallTimeout) decodeConfig).getCallTimeout()
? ((WithCallTimeout) decodeConfig).getCallTimeoutSeconds()
: DecodeConfiguration.DEFAULT_CALL_TIMEOUT_DELAY_SECONDS;
mStateMachine.setFadeTimeoutBuffer(fadeTimeoutSeconds * 1000);
mStateMachine.setFadeTimeoutBufferMilliseconds(fadeTimeoutSeconds * 1000);
}
}
@@ -412,7 +412,7 @@ public class SingleChannelState extends AbstractChannelState implements IDecoder
if(event instanceof ChangeChannelTimeoutEvent)
{
ChangeChannelTimeoutEvent timeout = (ChangeChannelTimeoutEvent)event;
mStateMachine.setFadeTimeoutBuffer(timeout.getCallTimeout());
mStateMachine.setFadeTimeoutBufferMilliseconds(timeout.getCallTimeoutMilliseconds());
}
case CONTINUATION:
case DECODE:

View File

@@ -42,9 +42,9 @@ public class StateMachine
protected State mState = State.IDLE;
protected long mFadeTimeout;
protected long mFadeTimeoutBuffer = 0;
protected long mFadeTimeoutBufferMilliseconds = 0;
protected long mEndTimeout;
protected long mEndTimeoutBuffer = 0;
protected long mEndTimeoutBufferMilliseconds = 0;
private int mTimeslot;
private EnumSet<State> mActiveStates;
private Channel.ChannelType mChannelType = Channel.ChannelType.STANDARD;
@@ -63,26 +63,42 @@ public class StateMachine
mActiveStates = activeStates;
}
/**
* Adds a state change listener
* @param listener to receive state change events
*/
public void addListener(IStateMachineListener listener)
{
mStateMachineListeners.add(listener);
}
/**
* Removes the state change listener
*/
public void removeListener(IStateMachineListener listener)
{
mStateMachineListeners.remove(listener);
}
/**
* Sets the listener to receive identifier update notifications (ie state identifier updates)
*/
public void setIdentifierUpdateListener(Listener<IdentifierUpdateNotification> listener)
{
mIdentifierUpdateListener = listener;
}
/**
* Sets the channel type for this state machine
*/
public void setChannelType(Channel.ChannelType channelType)
{
mChannelType = channelType;
}
/**
* Checks the state and transitions to FADE or TEARDOWN if timers have expired
*/
public void checkState()
{
if(mActiveStates.contains(mState) && mFadeTimeout <= System.currentTimeMillis())
@@ -95,11 +111,17 @@ public class StateMachine
}
}
/**
* Current state of the state machine
*/
public State getState()
{
return mState;
}
/**
* Sets the state
*/
public void setState(State state)
{
if(state == mState)
@@ -173,6 +195,9 @@ public class StateMachine
}
}
/**
* Broadcasts a channel state identifier update
*/
private void broadcast(ChannelStateIdentifier channelStateIdentifier)
{
if(mIdentifierUpdateListener != null)
@@ -182,43 +207,70 @@ public class StateMachine
}
}
/**
* Updates the fade timeout to current time plus the fade timeout buffer value.
*/
private void updateFadeTimeout()
{
mFadeTimeout = System.currentTimeMillis() + mFadeTimeoutBuffer;
mFadeTimeout = System.currentTimeMillis() + mFadeTimeoutBufferMilliseconds;
}
/**
* Manually sets the fade timeout
*/
public void setFadeTimeout(long timeout)
{
mFadeTimeout = timeout;
}
/**
* Fade timeout value
*/
public long getFadeTimeout()
{
return mFadeTimeout;
}
public void setFadeTimeoutBuffer(long buffer)
/**
* Sets the fade timeout buffer value. This value determines the maximum length of time the state machine
* can stay in any state (without an update) before automatically transitioning to FADE state.
* @param buffer in milliseconds
*/
public void setFadeTimeoutBufferMilliseconds(long buffer)
{
mFadeTimeoutBuffer = buffer;
mFadeTimeoutBufferMilliseconds = buffer;
updateFadeTimeout();
}
/**
* Updates the end timeout value to current system time plus the end timeout buffer value.
*/
private void updateEndTimeout()
{
mEndTimeout = System.currentTimeMillis() + mEndTimeoutBuffer;
mEndTimeout = System.currentTimeMillis() + mEndTimeoutBufferMilliseconds;
}
public void setEndTimeoutBuffer(long buffer)
/**
* Sets the end timeout buffer value. This value is the maximum length of time that the channel can
* stay in the FADE state (without an update) before transitioning to a TEARDOWN state.
*/
public void setEndTimeoutBufferMilliseconds(long buffer)
{
mEndTimeoutBuffer = buffer;
mEndTimeoutBufferMilliseconds = buffer;
updateEndTimeout();
}
/**
* Sets the end timeout value
*/
public void setEndTimeout(long endTimeout)
{
mEndTimeout = endTimeout;
}
/**
* Current end timeout value
*/
public long getEndTimeout()
{
return mEndTimeout;