mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-13 00:57:31 -05:00
#90 [WIP] merged metadata management for channel state, decoder states and audio metadata into a new metadata class. The new metadata class is maintained for each decoding audio channel, or in the future, a decoding TDMA channel. Audio playback, recording and streaming all use the same metadata object for the channel. The list of channel processing gui panels have been deleted and channel processing status will now reside in a table where each table row is a metadata instance from the processing channel. The channel processing manager is responsible for adding/removing the channel's metadata instance to/from the metadata table. This allows the channel processing table to be the controller for the messages, events and channel spectrum views, keyed to the selected table row metadata.
I still have to clean up the gui components and wire in the table selection listeners.
This commit is contained in:
@@ -1,226 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* sdrtrunk
|
||||
* Copyright (C) 2014-2017 Dennis Sheirer
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
******************************************************************************/
|
||||
package module.decode.p25;
|
||||
|
||||
import alias.Alias;
|
||||
import icon.IconManager;
|
||||
import channel.metadata.Attribute;
|
||||
import channel.state.DecoderPanel;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import settings.ColorSetting;
|
||||
import settings.Setting;
|
||||
import settings.SettingsManager;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
public class P25DecoderPanel extends DecoderPanel
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private JLabel mProtocol;
|
||||
private JLabel mTo = new JLabel(" ");
|
||||
private JLabel mToAlias = new JLabel(" ");
|
||||
|
||||
private JLabel mNAC = new JLabel("NAC:");
|
||||
private JLabel mFrom = new JLabel(" ");
|
||||
private JLabel mFromAlias = new JLabel(" ");
|
||||
|
||||
private JLabel mSystem = new JLabel("SYS:");
|
||||
private JLabel mSite = new JLabel("Site:");
|
||||
private JLabel mSiteAlias = new JLabel("");
|
||||
|
||||
|
||||
public P25DecoderPanel(IconManager iconManager, SettingsManager settingsManager, P25DecoderState decoderState)
|
||||
{
|
||||
super(iconManager, settingsManager, decoderState);
|
||||
|
||||
mProtocol = new JLabel("P25-1 " + decoderState.getModulation().getShortLabel());
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
public void init()
|
||||
{
|
||||
super.init();
|
||||
|
||||
setLayout(new MigLayout("insets 0 0 0 0", "[grow,fill]", "[]0[]0[]"));
|
||||
|
||||
mProtocol.setFont(mFontDecoder);
|
||||
mProtocol.setForeground(mColorLabelDecoder);
|
||||
|
||||
mTo.setFont(mFontDecoder);
|
||||
mTo.setForeground(mColorLabelDecoder);
|
||||
|
||||
mToAlias.setFont(mFontDecoder);
|
||||
mToAlias.setForeground(mColorLabelDecoder);
|
||||
|
||||
mNAC.setFont(mFontDetails);
|
||||
mNAC.setForeground(mColorLabelDecoder);
|
||||
|
||||
mFrom.setFont(mFontDecoder);
|
||||
mFrom.setForeground(mColorLabelDecoder);
|
||||
|
||||
mFromAlias.setFont(mFontDecoder);
|
||||
mFromAlias.setForeground(mColorLabelDecoder);
|
||||
|
||||
mSystem.setFont(mFontDetails);
|
||||
mSystem.setForeground(mColorLabelDecoder);
|
||||
|
||||
mSiteAlias.setFont(mFontDecoder);
|
||||
mSiteAlias.setForeground(mColorLabelDecoder);
|
||||
|
||||
mSite.setFont(mFontDetails);
|
||||
mSite.setForeground(mColorLabelDecoder);
|
||||
|
||||
add(mProtocol);
|
||||
add(mTo);
|
||||
add(mToAlias, "wrap");
|
||||
|
||||
add(mNAC);
|
||||
add(mFrom);
|
||||
add(mFromAlias, "wrap");
|
||||
|
||||
add(mSystem);
|
||||
add(mSite);
|
||||
add(mSiteAlias, "wrap");
|
||||
}
|
||||
|
||||
public P25DecoderState getDecoderState()
|
||||
{
|
||||
return (P25DecoderState) super.getDecoderState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(final Attribute attribute)
|
||||
{
|
||||
final P25DecoderState state = getDecoderState();
|
||||
|
||||
EventQueue.invokeLater(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
|
||||
switch(attribute)
|
||||
{
|
||||
case NAC:
|
||||
mNAC.setText("NAC:" + state.getNAC());
|
||||
break;
|
||||
case SYSTEM:
|
||||
mSystem.setText("SYS:" + state.getSystem());
|
||||
break;
|
||||
case SITE:
|
||||
mSite.setText("SITE:" + state.getSite());
|
||||
break;
|
||||
case SITE_ALIAS:
|
||||
mSiteAlias.setText(state.getSiteAlias());
|
||||
break;
|
||||
case FROM_TALKGROUP:
|
||||
if(state.getFromTalkgroup() == null)
|
||||
{
|
||||
mFrom.setText(" ");
|
||||
}
|
||||
else
|
||||
{
|
||||
mFrom.setText(state.getFromTalkgroup());
|
||||
}
|
||||
break;
|
||||
case FROM_TALKGROUP_ALIAS:
|
||||
Alias from = state.getFromAlias();
|
||||
|
||||
if(from != null)
|
||||
{
|
||||
mFromAlias.setText(from.getName());
|
||||
|
||||
final String icon = from.getIconName();
|
||||
|
||||
if(icon != null && mIconManager != null)
|
||||
{
|
||||
mFromAlias.setIcon(mIconManager.getIcon(icon, IconManager.DEFAULT_ICON_SIZE));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mFromAlias.setText(" ");
|
||||
mFromAlias.setIcon(null);
|
||||
}
|
||||
break;
|
||||
case TO_TALKGROUP:
|
||||
if(state.getToTalkgroup() == null)
|
||||
{
|
||||
mTo.setText(" ");
|
||||
}
|
||||
else
|
||||
{
|
||||
mTo.setText(state.getToTalkgroup());
|
||||
}
|
||||
break;
|
||||
case TO_TALKGROUP_ALIAS:
|
||||
final Alias to = state.getToAlias();
|
||||
|
||||
if(to != null)
|
||||
{
|
||||
mToAlias.setText(to.getName());
|
||||
|
||||
final String icon = to.getIconName();
|
||||
|
||||
if(icon != null && mIconManager != null)
|
||||
{
|
||||
mToAlias.setIcon(mIconManager.getIcon(icon, IconManager.DEFAULT_ICON_SIZE));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mToAlias.setText(" ");
|
||||
mToAlias.setIcon(null);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
repaint();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void settingChanged(Setting setting)
|
||||
{
|
||||
super.settingChanged(setting);
|
||||
|
||||
if(setting instanceof ColorSetting)
|
||||
{
|
||||
ColorSetting colorSetting = (ColorSetting) setting;
|
||||
|
||||
switch(colorSetting.getColorSettingName())
|
||||
{
|
||||
case CHANNEL_STATE_LABEL_DECODER:
|
||||
if(mProtocol != null)
|
||||
{
|
||||
mProtocol.setForeground(mColorLabelDecoder);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,8 +21,14 @@ import alias.Alias;
|
||||
import alias.AliasList;
|
||||
import alias.PatchGroupAlias;
|
||||
import alias.id.talkgroup.TalkgroupID;
|
||||
import audio.metadata.Metadata;
|
||||
import audio.metadata.MetadataType;
|
||||
import channel.metadata.Attribute;
|
||||
import channel.metadata.AttributeChangeRequest;
|
||||
import channel.state.ChangeChannelTimeoutEvent;
|
||||
import channel.state.DecoderState;
|
||||
import channel.state.DecoderStateEvent;
|
||||
import channel.state.DecoderStateEvent.Event;
|
||||
import channel.state.State;
|
||||
import channel.traffic.TrafficChannelAllocationEvent;
|
||||
import controller.channel.Channel.ChannelType;
|
||||
import message.Message;
|
||||
import module.decode.DecoderType;
|
||||
@@ -123,13 +129,6 @@ import module.decode.p25.reference.IPProtocol;
|
||||
import module.decode.p25.reference.LinkControlOpcode;
|
||||
import module.decode.p25.reference.Response;
|
||||
import module.decode.p25.reference.Vendor;
|
||||
import channel.state.ChangeChannelTimeoutEvent;
|
||||
import channel.metadata.Attribute;
|
||||
import channel.state.DecoderState;
|
||||
import channel.state.DecoderStateEvent;
|
||||
import channel.state.DecoderStateEvent.Event;
|
||||
import channel.state.State;
|
||||
import channel.traffic.TrafficChannelAllocationEvent;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -159,10 +158,10 @@ public class P25DecoderState extends DecoderState
|
||||
private Set<module.decode.p25.message.tsbk.osp.control.SecondaryControlChannelBroadcast> mSecondaryControlChannels =
|
||||
new TreeSet<>();
|
||||
|
||||
private Map<Integer, IdentifierUpdate> mBands = new HashMap<>();
|
||||
private Map<String, Long> mRegistrations = new HashMap<>();
|
||||
private Map<String, IAdjacentSite> mNeighborMap = new HashMap<>();
|
||||
private Map<String, List<String>> mPatchGroupMap = new HashMap<>();
|
||||
private Map<Integer,IdentifierUpdate> mBands = new HashMap<>();
|
||||
private Map<String,Long> mRegistrations = new HashMap<>();
|
||||
private Map<String,IAdjacentSite> mNeighborMap = new HashMap<>();
|
||||
private Map<String,List<String>> mPatchGroupMap = new HashMap<>();
|
||||
|
||||
private String mLastCommandEventID;
|
||||
private String mLastPageEventID;
|
||||
@@ -188,7 +187,7 @@ public class P25DecoderState extends DecoderState
|
||||
|
||||
private P25CallEvent mCurrentCallEvent;
|
||||
private List<String> mCallDetectTalkgroups = new ArrayList<>();
|
||||
private Map<String, P25CallEvent> mChannelCallMap = new HashMap<>();
|
||||
private Map<String,P25CallEvent> mChannelCallMap = new HashMap<>();
|
||||
|
||||
public P25DecoderState(AliasList aliasList,
|
||||
ChannelType channelType,
|
||||
@@ -225,9 +224,10 @@ public class P25DecoderState extends DecoderState
|
||||
{
|
||||
resetState();
|
||||
|
||||
updateNAC(null);
|
||||
updateSite(null);
|
||||
updateSystem(null);
|
||||
mNAC = null;
|
||||
mSite = null;
|
||||
mSiteAlias = null;
|
||||
mSystem = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -236,16 +236,9 @@ public class P25DecoderState extends DecoderState
|
||||
private void resetState()
|
||||
{
|
||||
mFromTalkgroup = null;
|
||||
broadcast(Attribute.FROM_TALKGROUP);
|
||||
|
||||
mFromAlias = null;
|
||||
broadcast(Attribute.FROM_TALKGROUP_ALIAS);
|
||||
|
||||
mToTalkgroup = null;
|
||||
broadcast(Attribute.TO_TALKGROUP);
|
||||
|
||||
mToAlias = null;
|
||||
broadcast(Attribute.TO_TALKGROUP_ALIAS);
|
||||
|
||||
mCallDetectTalkgroups.clear();
|
||||
|
||||
@@ -496,7 +489,7 @@ public class P25DecoderState extends DecoderState
|
||||
}
|
||||
break;
|
||||
case CALL_TERMINATION_OR_CANCELLATION:
|
||||
/* This opcode as handled at the beginning of the method */
|
||||
/* This opcode as handled at the beginning of the method */
|
||||
break;
|
||||
case CHANNEL_IDENTIFIER_UPDATE:
|
||||
//TODO: does the activity summary need this message?
|
||||
@@ -2843,7 +2836,7 @@ public class P25DecoderState extends DecoderState
|
||||
patchedTalkgroups = new ArrayList<>();
|
||||
}
|
||||
|
||||
for(String talkgroupToAdd: talkgroupsToAdd)
|
||||
for(String talkgroupToAdd : talkgroupsToAdd)
|
||||
{
|
||||
//Exclude the patch group ID if it is included in the patched talkgroup list so that we don't have
|
||||
//an infinite loop situation
|
||||
@@ -2887,7 +2880,7 @@ public class P25DecoderState extends DecoderState
|
||||
|
||||
if(patchedTalkgroups != null)
|
||||
{
|
||||
for(String talkgroupToRemove: talkgroupsToRemove)
|
||||
for(String talkgroupToRemove : talkgroupsToRemove)
|
||||
{
|
||||
if(patchedTalkgroups.contains(talkgroupToRemove))
|
||||
{
|
||||
@@ -2929,7 +2922,7 @@ public class P25DecoderState extends DecoderState
|
||||
|
||||
if(existingAlias instanceof PatchGroupAlias)
|
||||
{
|
||||
patchGroupAlias = (PatchGroupAlias)existingAlias;
|
||||
patchGroupAlias = (PatchGroupAlias) existingAlias;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2953,7 +2946,7 @@ public class P25DecoderState extends DecoderState
|
||||
|
||||
patchGroupAlias.clearPatchedAliases();
|
||||
|
||||
for(String patchedTalkgroup: patchedTalkgroups)
|
||||
for(String patchedTalkgroup : patchedTalkgroups)
|
||||
{
|
||||
Alias patchedAlias = getAliasList().getTalkgroupAlias(patchedTalkgroup);
|
||||
|
||||
@@ -2974,7 +2967,7 @@ public class P25DecoderState extends DecoderState
|
||||
|
||||
if(alias instanceof PatchGroupAlias)
|
||||
{
|
||||
PatchGroupAlias patchGroupAlias = (PatchGroupAlias)alias;
|
||||
PatchGroupAlias patchGroupAlias = (PatchGroupAlias) alias;
|
||||
|
||||
getAliasList().removeAlias(patchGroupAlias);
|
||||
|
||||
@@ -3372,8 +3365,6 @@ public class P25DecoderState extends DecoderState
|
||||
{
|
||||
mToTalkgroup = to;
|
||||
|
||||
broadcast(Attribute.TO_TALKGROUP);
|
||||
|
||||
if(hasAliasList())
|
||||
{
|
||||
mToAlias = getAliasList().getTalkgroupAlias(mToTalkgroup);
|
||||
@@ -3383,14 +3374,10 @@ public class P25DecoderState extends DecoderState
|
||||
mToAlias = null;
|
||||
}
|
||||
|
||||
broadcast(Attribute.TO_TALKGROUP_ALIAS);
|
||||
|
||||
/* Send audio metadata update */
|
||||
broadcast(new Metadata(MetadataType.TO, mToTalkgroup, mToAlias, true));
|
||||
broadcast(new AttributeChangeRequest<String>(Attribute.PRIMARY_ADDRESS_TO, mToTalkgroup, mToAlias));
|
||||
|
||||
if(mCurrentCallEvent != null &&
|
||||
(mCurrentCallEvent.getToID() == null ||
|
||||
!mCurrentCallEvent.getToID().contentEquals(to)))
|
||||
(mCurrentCallEvent.getToID() == null || !mCurrentCallEvent.getToID().contentEquals(to)))
|
||||
{
|
||||
mCurrentCallEvent.setToID(to);
|
||||
broadcast(mCurrentCallEvent);
|
||||
@@ -3409,7 +3396,6 @@ public class P25DecoderState extends DecoderState
|
||||
if(mFromTalkgroup == null || !mFromTalkgroup.contentEquals(from))
|
||||
{
|
||||
mFromTalkgroup = from;
|
||||
broadcast(Attribute.FROM_TALKGROUP);
|
||||
|
||||
if(hasAliasList())
|
||||
{
|
||||
@@ -3420,14 +3406,11 @@ public class P25DecoderState extends DecoderState
|
||||
mFromAlias = null;
|
||||
}
|
||||
|
||||
broadcast(Attribute.FROM_TALKGROUP_ALIAS);
|
||||
|
||||
/* Send audio metadata update */
|
||||
broadcast(new Metadata(MetadataType.FROM, mFromTalkgroup, mFromAlias, true));
|
||||
broadcast(new AttributeChangeRequest<String>(Attribute.PRIMARY_ADDRESS_FROM, mFromTalkgroup,
|
||||
mFromAlias));
|
||||
|
||||
if(mCurrentCallEvent != null &&
|
||||
(mCurrentCallEvent.getFromID() == null ||
|
||||
!mCurrentCallEvent.getFromID().contentEquals(from)))
|
||||
(mCurrentCallEvent.getFromID() == null || !mCurrentCallEvent.getFromID().contentEquals(from)))
|
||||
{
|
||||
mCurrentCallEvent.setFromID(from);
|
||||
broadcast(mCurrentCallEvent);
|
||||
@@ -3437,19 +3420,6 @@ public class P25DecoderState extends DecoderState
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcasts an update to the NAC
|
||||
*/
|
||||
private void updateNAC(String nac)
|
||||
{
|
||||
if(mNAC == null || (nac != null && !mNAC.contentEquals(nac)))
|
||||
{
|
||||
mNAC = nac;
|
||||
|
||||
broadcast(Attribute.NAC);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the site information
|
||||
*/
|
||||
@@ -3459,8 +3429,6 @@ public class P25DecoderState extends DecoderState
|
||||
{
|
||||
mSite = site;
|
||||
|
||||
broadcast(Attribute.SITE);
|
||||
|
||||
if(hasAliasList())
|
||||
{
|
||||
Alias alias = getAliasList().getSiteID(mSite);
|
||||
@@ -3475,7 +3443,7 @@ public class P25DecoderState extends DecoderState
|
||||
}
|
||||
}
|
||||
|
||||
broadcast(Attribute.SITE_ALIAS);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3484,11 +3452,28 @@ public class P25DecoderState extends DecoderState
|
||||
if(mSystem == null || (system != null && !mSystem.contentEquals(system)))
|
||||
{
|
||||
mSystem = system;
|
||||
|
||||
broadcast(Attribute.SYSTEM);
|
||||
broadcastSystemAndNACUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcasts an update to the NAC
|
||||
*/
|
||||
private void updateNAC(String nac)
|
||||
{
|
||||
if(mNAC == null || (nac != null && !mNAC.contentEquals(nac)))
|
||||
{
|
||||
mNAC = nac;
|
||||
broadcastSystemAndNACUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
private void broadcastSystemAndNACUpdate()
|
||||
{
|
||||
String label = String.format("SYS:%s NAC:%s", mSystem, mNAC);
|
||||
broadcast(new AttributeChangeRequest<String>(Attribute.NETWORK_ID_1, label));
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a unit paging event message
|
||||
*/
|
||||
@@ -3816,27 +3801,24 @@ public class P25DecoderState extends DecoderState
|
||||
mCurrentCallEvent = (P25CallEvent) allocationEvent.getCallEvent();
|
||||
|
||||
mCurrentChannel = allocationEvent.getCallEvent().getChannel();
|
||||
broadcast(Attribute.CHANNEL_NUMBER);
|
||||
broadcast(new AttributeChangeRequest<String>(Attribute.CHANNEL_FREQUENCY_LABEL, mCurrentChannel));
|
||||
|
||||
mCurrentChannelFrequency = allocationEvent.getCallEvent().getFrequency();
|
||||
broadcast(Attribute.SOURCE);
|
||||
broadcast(new AttributeChangeRequest<Long>(Attribute.CHANNEL_FREQUENCY, mCurrentChannelFrequency));
|
||||
|
||||
mFromTalkgroup = allocationEvent.getCallEvent().getFromID();
|
||||
broadcast(Attribute.FROM_TALKGROUP);
|
||||
|
||||
mToTalkgroup = allocationEvent.getCallEvent().getToID();
|
||||
broadcast(Attribute.TO_TALKGROUP);
|
||||
|
||||
if(allocationEvent.getCallEvent().hasAliasList())
|
||||
{
|
||||
AliasList aliasList = allocationEvent.getCallEvent().getAliasList();
|
||||
|
||||
mFromAlias = aliasList.getTalkgroupAlias(mFromTalkgroup);
|
||||
broadcast(Attribute.FROM_TALKGROUP_ALIAS);
|
||||
|
||||
mToAlias = aliasList.getTalkgroupAlias(mToTalkgroup);
|
||||
broadcast(Attribute.TO_TALKGROUP_ALIAS);
|
||||
}
|
||||
|
||||
broadcast(new AttributeChangeRequest<String>(Attribute.PRIMARY_ADDRESS_FROM, mFromTalkgroup, mFromAlias));
|
||||
broadcast(new AttributeChangeRequest<String>(Attribute.PRIMARY_ADDRESS_TO, mToTalkgroup, mToAlias));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1,56 +1,42 @@
|
||||
package module.decode.p25.audio;
|
||||
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
|
||||
import audio.AudioFormats;
|
||||
import audio.AudioPacket;
|
||||
import audio.IAudioPacketProvider;
|
||||
import audio.squelch.ISquelchStateListener;
|
||||
import audio.squelch.SquelchState;
|
||||
import channel.metadata.Metadata;
|
||||
import dsp.gain.NonClippingGain;
|
||||
import jmbe.iface.AudioConversionLibrary;
|
||||
import jmbe.iface.AudioConverter;
|
||||
import message.IMessageListener;
|
||||
import message.Message;
|
||||
import module.Module;
|
||||
import module.decode.p25.message.ldu.LDUMessage;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import sample.Listener;
|
||||
import audio.AudioFormats;
|
||||
import audio.AudioPacket;
|
||||
import audio.IAudioPacketProvider;
|
||||
import audio.metadata.AudioMetadata;
|
||||
import audio.metadata.IMetadataListener;
|
||||
import audio.metadata.Metadata;
|
||||
import audio.squelch.ISquelchStateListener;
|
||||
import audio.squelch.SquelchState;
|
||||
import controller.channel.ChannelEvent;
|
||||
import controller.channel.IChannelEventListener;
|
||||
import dsp.gain.NonClippingGain;
|
||||
|
||||
public class P25AudioModule extends Module implements Listener<Message>,
|
||||
IAudioPacketProvider, IMessageListener, IChannelEventListener,
|
||||
IMetadataListener, ISquelchStateListener
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
|
||||
public class P25AudioModule extends Module implements Listener<Message>, IAudioPacketProvider, IMessageListener,
|
||||
ISquelchStateListener
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger(P25AudioModule.class);
|
||||
|
||||
private static final String IMBE_CODEC = "IMBE";
|
||||
|
||||
/* Provides a unique identifier for this audio module instance to use as a
|
||||
* source identifier for all audio packets */
|
||||
private static int UNIQUE_ID = 0;
|
||||
private int mSourceID;
|
||||
private static boolean mLibraryLoadStatusLogged = false;
|
||||
private boolean mCanConvertAudio = false;
|
||||
private AudioConverter mAudioConverter;
|
||||
private Listener<AudioPacket> mAudioPacketListener;
|
||||
private AudioMetadata mAudioMetadata;
|
||||
private ChannelEventListener mChannelEventListener = new ChannelEventListener();
|
||||
private SquelchStateListener mSquelchStateListener = new SquelchStateListener();
|
||||
private NonClippingGain mGain = new NonClippingGain(5.0f, 0.95f);
|
||||
private Metadata mMetadata;
|
||||
|
||||
public P25AudioModule(boolean record)
|
||||
public P25AudioModule(Metadata metadata)
|
||||
{
|
||||
mSourceID = ++UNIQUE_ID;
|
||||
mAudioMetadata = new AudioMetadata(mSourceID, record);
|
||||
|
||||
mMetadata = metadata;
|
||||
loadConverter();
|
||||
}
|
||||
|
||||
@@ -75,7 +61,6 @@ public class P25AudioModule extends Module implements Listener<Message>,
|
||||
@Override
|
||||
public void reset()
|
||||
{
|
||||
mAudioMetadata.reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -113,8 +98,7 @@ public class P25AudioModule extends Module implements Listener<Message>,
|
||||
|
||||
audio = mGain.apply(audio);
|
||||
|
||||
mAudioPacketListener.receive(
|
||||
new AudioPacket(audio, mAudioMetadata.copyOf()));
|
||||
mAudioPacketListener.receive(new AudioPacket(audio, mMetadata.copyOf()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -211,41 +195,6 @@ public class P25AudioModule extends Module implements Listener<Message>,
|
||||
mAudioPacketListener = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Listener<Metadata> getMetadataListener()
|
||||
{
|
||||
return mAudioMetadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Listener<ChannelEvent> getChannelEventListener()
|
||||
{
|
||||
return mChannelEventListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for channel event listener. Responds to channel state reset
|
||||
* events to remove/cleanup current audio metadata
|
||||
*/
|
||||
public class ChannelEventListener implements Listener<ChannelEvent>
|
||||
{
|
||||
@Override
|
||||
public void receive(ChannelEvent event)
|
||||
{
|
||||
switch (event.getEvent())
|
||||
{
|
||||
case NOTIFICATION_STATE_RESET:
|
||||
mAudioMetadata.reset();
|
||||
break;
|
||||
case NOTIFICATION_SELECTION_CHANGE:
|
||||
mAudioMetadata.setSelected(event.getChannel().isSelected());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for squelch state listener. Internally, the P25 audio module
|
||||
* doesn't have a squelch state. If there are IMBE audio frames, we have
|
||||
@@ -259,10 +208,7 @@ public class P25AudioModule extends Module implements Listener<Message>,
|
||||
{
|
||||
if (state == SquelchState.SQUELCH && mAudioPacketListener != null)
|
||||
{
|
||||
mAudioPacketListener.receive(new AudioPacket(AudioPacket.Type.END,
|
||||
mAudioMetadata.copyOf()));
|
||||
|
||||
mAudioMetadata.reset();
|
||||
mAudioPacketListener.receive(new AudioPacket(AudioPacket.Type.END, mMetadata.copyOf()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user