Skip to content

Commit

Permalink
#6 DMR Decoder (#947)
Browse files Browse the repository at this point in the history
* #6 DMR decoder feature - work in progress

* #6 DMR Decoder.

* #6 DMR Decoder.  Code review updates.

Co-authored-by: Zhenyu Mao <maozhenyu@foxmail.com>
Co-authored-by: Denny <denny@denny-desktop>
  • Loading branch information
3 people committed Oct 12, 2020
1 parent b061db1 commit 7eec82d
Show file tree
Hide file tree
Showing 436 changed files with 36,250 additions and 2,401 deletions.
2 changes: 2 additions & 0 deletions .idea/dictionaries/denny.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 0 additions & 10 deletions .idea/modules.xml

This file was deleted.

1 change: 1 addition & 0 deletions build.gradle
Expand Up @@ -110,6 +110,7 @@ idea {
}

javafx {
version = "13.0.2"
modules = ['javafx.base', 'javafx.controls', 'javafx.graphics', 'javafx.swing']
}

Expand Down
Expand Up @@ -93,12 +93,6 @@ public void stop()
//No actions neeeded
}

@Override
public void dispose()
{
//No actions neeeded
}

/**
* IMessageListener interface ... delegates to this class implementation of Listener<Message>
*/
Expand Down
Expand Up @@ -36,6 +36,8 @@ public enum RadioFormat
{
APCO25("********", 0, 0xFFFFFF, "0 to 16,777,215",
"<html>APCO25 valid range is 0 to 16,777,215"),
DMR("********", 0, 0xFFFFFF, "0 to 16,777,215",
"<html>DMR unit id valid range is 0 to 16,777,215"),
PASSPORT("********", 0, 0x7FFFFF, "0 to 8,388,607",
"<html>PASSPORT valid range is 0 to 8,388,607"),
UNKNOWN("********", 1, 0xFFFFFF, "1 to 16,777,215",
Expand Down Expand Up @@ -112,6 +114,8 @@ public static RadioFormat get(Protocol protocol)
{
case APCO25:
return APCO25;
case DMR:
return DMR;
case PASSPORT:
return PASSPORT;
default:
Expand Down
Expand Up @@ -25,14 +25,14 @@
import io.github.dsheirer.preference.identifier.IntegerFormat;
import io.github.dsheirer.preference.identifier.talkgroup.APCO25TalkgroupFormatter;
import io.github.dsheirer.preference.identifier.talkgroup.AbstractIntegerFormatter;
import io.github.dsheirer.preference.identifier.talkgroup.DMRTalkgroupFormatter;
import io.github.dsheirer.preference.identifier.talkgroup.UnknownTalkgroupFormatter;
import io.github.dsheirer.protocol.Protocol;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.ParseException;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.Map;

/**
Expand All @@ -46,6 +46,7 @@ public class RadioFormatter
static
{
mFormatterMap.put(Protocol.APCO25, new APCO25TalkgroupFormatter());
mFormatterMap.put(Protocol.DMR, new DMRTalkgroupFormatter());
mFormatterMap.put(Protocol.UNKNOWN, new UnknownTalkgroupFormatter());
}

Expand Down
Expand Up @@ -34,8 +34,10 @@
*/
public enum TalkgroupFormat
{
APCO25("********", 0, 0xFFFFFF, "0 to 65,535",
APCO25("********", 0, 0xFFFF, "0 to 65,535",
"<html>APCO25 talkgroup valid range is 0 to 65,535"),
DMR("********", 0, 0xFFFFFF, "0 to 16,777,215",
"<html>DMR talkgroup valid range is 0 to 16,777,215"),
FLEETSYNC("###-####", 0, 0x7FFFFF, "001-0001 to 127-8192",
"<html>Fleetsync valid ranges are 1-127(prefix)<br>and 1-8192(ident) (ie. 001-0001 to 127-8192)"),
LTR("##-###", 0x101, 0x3FFF, "01-001 to 20-255",
Expand Down
Expand Up @@ -23,6 +23,7 @@
import io.github.dsheirer.preference.identifier.IntegerFormat;
import io.github.dsheirer.preference.identifier.talkgroup.APCO25TalkgroupFormatter;
import io.github.dsheirer.preference.identifier.talkgroup.AbstractIntegerFormatter;
import io.github.dsheirer.preference.identifier.talkgroup.DMRTalkgroupFormatter;
import io.github.dsheirer.preference.identifier.talkgroup.FleetsyncTalkgroupFormatter;
import io.github.dsheirer.preference.identifier.talkgroup.LTRTalkgroupFormatter;
import io.github.dsheirer.preference.identifier.talkgroup.MDC1200TalkgroupFormatter;
Expand All @@ -35,7 +36,6 @@

import java.text.ParseException;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.Map;

/**
Expand All @@ -49,6 +49,7 @@ public class TalkgroupFormatter
static
{
mFormatterMap.put(Protocol.APCO25, new APCO25TalkgroupFormatter());
mFormatterMap.put(Protocol.DMR, new DMRTalkgroupFormatter());
mFormatterMap.put(Protocol.FLEETSYNC, new FleetsyncTalkgroupFormatter());
LTRTalkgroupFormatter ltr = new LTRTalkgroupFormatter();
mFormatterMap.put(Protocol.LTR, ltr);
Expand Down
23 changes: 16 additions & 7 deletions src/main/java/io/github/dsheirer/audio/AbstractAudioModule.java
Expand Up @@ -36,39 +36,48 @@
public abstract class AbstractAudioModule extends Module implements IAudioSegmentProvider, IdentifierUpdateListener
{
private final static Logger mLog = LoggerFactory.getLogger(AbstractAudioModule.class);
private static final int DEFAULT_SEGMENT_AUDIO_SAMPLE_LENGTH = 60 * 8000; // 1 minute @ 8kHz

public static final long DEFAULT_SEGMENT_AUDIO_SAMPLE_LENGTH = 60 * 8000; // 1 minute @ 8kHz
public static final int DEFAULT_TIMESLOT = 0;
private final int mMaxSegmentAudioSampleLength;
private Listener<AudioSegment> mAudioSegmentListener;
protected MutableIdentifierCollection mIdentifierCollection = new MutableIdentifierCollection();
protected MutableIdentifierCollection mIdentifierCollection;
private Broadcaster<IdentifierUpdateNotification> mIdentifierUpdateNotificationBroadcaster = new Broadcaster<>();
private AliasList mAliasList;
private AudioSegment mAudioSegment;
private int mAudioSampleCount = 0;
private boolean mRecordAudioOverride;
private int mTimeslot;

/**
* Constructs an abstract audio module
*
* @param aliasList for aliasing identifiers
* @param maxSegmentAudioSampleLength in milliseconds
*/
public AbstractAudioModule(AliasList aliasList, long maxSegmentAudioSampleLength)
public AbstractAudioModule(AliasList aliasList, int timeslot, long maxSegmentAudioSampleLength)
{
mAliasList = aliasList;
mMaxSegmentAudioSampleLength = (int)(maxSegmentAudioSampleLength * 8); //Convert milliseconds to samples
mTimeslot = timeslot;
mIdentifierCollection = new MutableIdentifierCollection(getTimeslot());
mIdentifierUpdateNotificationBroadcaster.addListener(mIdentifierCollection);
}

/**
* Constructs an abstract audio module
* Constructs an abstract audio module with a default maximum audio segment length and a default timeslot 0.
*/
public AbstractAudioModule(AliasList aliasList)
{
this(aliasList, DEFAULT_SEGMENT_AUDIO_SAMPLE_LENGTH);
this(aliasList, DEFAULT_TIMESLOT, DEFAULT_SEGMENT_AUDIO_SAMPLE_LENGTH);
}

protected abstract int getTimeslot();
/**
* Timeslot for this audio module
*/
protected int getTimeslot()
{
return mTimeslot;
}

/**
* Closes the current audio segment
Expand Down
11 changes: 2 additions & 9 deletions src/main/java/io/github/dsheirer/audio/AudioModule.java
Expand Up @@ -83,9 +83,9 @@ public class AudioModule extends AbstractAudioModule implements ISquelchStateLis
* @param aliasList for aliasing identifiers
* @param maxAudioSegmentLength in milliseconds
*/
public AudioModule(AliasList aliasList, long maxAudioSegmentLength)
public AudioModule(AliasList aliasList, int timeslot, long maxAudioSegmentLength)
{
super(aliasList, maxAudioSegmentLength);
super(aliasList, timeslot, maxAudioSegmentLength);
}

/**
Expand All @@ -102,13 +102,6 @@ protected int getTimeslot()
return 0;
}

@Override
public void dispose()
{
removeAudioSegmentListener();
mSquelchStateListener = null;
}

@Override
public void reset()
{
Expand Down
Expand Up @@ -33,9 +33,9 @@ public abstract class AmbeAudioModule extends JmbeAudioModule
private static final String AMBE_CODEC = "AMBE 3600 x 2450";
private static boolean sLibraryStatusLogged = false;

public AmbeAudioModule(UserPreferences userPreferences, AliasList aliasList)
public AmbeAudioModule(UserPreferences userPreferences, AliasList aliasList, int timeslot)
{
super(userPreferences, aliasList);
super(userPreferences, aliasList, timeslot);

if(!sLibraryStatusLogged)
{
Expand Down
Expand Up @@ -35,7 +35,7 @@ public abstract class ImbeAudioModule extends JmbeAudioModule

public ImbeAudioModule(UserPreferences userPreferences, AliasList aliasList)
{
super(userPreferences, aliasList);
super(userPreferences, aliasList, DEFAULT_TIMESLOT);

if(!sLibraryStatusLogged)
{
Expand Down
Expand Up @@ -54,14 +54,22 @@ public abstract class JmbeAudioModule extends AbstractAudioModule implements Lis
private IAudioCodec mAudioCodec;
private UserPreferences mUserPreferences;

public JmbeAudioModule(UserPreferences userPreferences, AliasList aliasList)
public JmbeAudioModule(UserPreferences userPreferences, AliasList aliasList, int timeslot)
{
super(aliasList);
super(aliasList, timeslot, DEFAULT_SEGMENT_AUDIO_SAMPLE_LENGTH);
mUserPreferences = userPreferences;
MyEventBus.getEventBus().register(this);
MyEventBus.getGlobalEventBus().register(this);
loadConverter();
}

@Override
public void dispose()
{
super.dispose();
MyEventBus.getGlobalEventBus().unregister(this);
mAudioCodec = null;
}

protected IAudioCodec getAudioCodec()
{
return mAudioCodec;
Expand Down Expand Up @@ -236,10 +244,4 @@ protected void loadConverter()
mAudioCodec = null;
}
}

@Override
public void dispose()
{
mAudioCodec = null;
}
}
Expand Up @@ -77,11 +77,6 @@ public void start()
{
}

@Override
public void dispose()
{
}

/**
* Writes an MBE call sequence recording to the recording directory
* @param sequence to write
Expand Down
Expand Up @@ -129,7 +129,7 @@ public void preferenceUpdated(PreferenceType preferenceType)
public void dispose()
{
//Deregister from receiving preference update notifications
MyEventBus.getEventBus().unregister(this);
MyEventBus.getGlobalEventBus().unregister(this);

if(mAudioOutput != null)
{
Expand All @@ -141,7 +141,7 @@ public void dispose()
private void init()
{
//Register to receive preference updates
MyEventBus.getEventBus().register(this);
MyEventBus.getGlobalEventBus().register(this);

setLayout(new MigLayout("align center center, insets 0 0 0 0",
"[][][align right]0[grow,fill]", ""));
Expand Down
Expand Up @@ -168,7 +168,7 @@ public AudioOutput(Mixer mixer, MixerChannel mixerChannel, AudioFormat audioForm
updateToneInsertionAudioClips();

//Register to receive directory preference update notifications so we can update the preference items
MyEventBus.getEventBus().register(this);
MyEventBus.getGlobalEventBus().register(this);
}

/**
Expand Down Expand Up @@ -514,6 +514,7 @@ else if(mCurrentBufferIndex > 0 &&
*/
public void dispose()
{
MyEventBus.getGlobalEventBus().unregister(this);
mCanProcessAudio = false;

if(mProcessorFuture != null)
Expand Down
Expand Up @@ -183,7 +183,7 @@ public void mouseClicked(MouseEvent event)
@Override
public void actionPerformed(ActionEvent e)
{
MyEventBus.getEventBus().post(new ViewUserPreferenceEditorRequest(PreferenceEditorType.AUDIO_OUTPUT));
MyEventBus.getGlobalEventBus().post(new ViewUserPreferenceEditorRequest(PreferenceEditorType.AUDIO_OUTPUT));
}
});
popup.add(outputMenu);
Expand Down
Expand Up @@ -73,7 +73,7 @@ public class AudioPlaybackManager implements Listener<AudioSegment>, IAudioContr
public AudioPlaybackManager(UserPreferences userPreferences)
{
mUserPreferences = userPreferences;
MyEventBus.getEventBus().register(this);
MyEventBus.getGlobalEventBus().register(this);

MixerChannelConfiguration configuration = mUserPreferences.getPlaybackPreference().getMixerChannelConfiguration();

Expand Down Expand Up @@ -254,6 +254,7 @@ else if(audioSegment.isLinked())

public void dispose()
{
MyEventBus.getGlobalEventBus().unregister(this);
if(mProcessingTask != null)
{
mProcessingTask.cancel(true);
Expand Down
18 changes: 18 additions & 0 deletions src/main/java/io/github/dsheirer/bits/BinaryMessage.java
Expand Up @@ -834,6 +834,24 @@ public int getInt(int start, int end)
return value;
}

/**
* Returns the twos-complement value of the bits between start and end, inclusive
* @param start bit position
* @param end bit position
* @return twos complement value
*/
public int getTwosComplement(int start, int end)
{
BinaryMessage sub = getSubMessage(start, end);
boolean negative = sub.get(start);
sub.flip(0, sub.size());

int value = sub.getInt(0, sub.size()) + 1;
value *= (negative ? -1 : 1);
return value;
}


/**
* Returns the long value represented by the bit range. This method will
* parse the bits in big endian or little endian format. The start value
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/io/github/dsheirer/bits/SoftSyncDetector.java
Expand Up @@ -33,6 +33,10 @@ public SoftSyncDetector(long pattern, int threshold, ISyncDetectListener listene
mThreshold = threshold;
}

public SoftSyncDetector(long pattern, int threshold) {
mPattern = pattern;
mThreshold = threshold;
}
public void dispose()
{
mListener = null;
Expand Down
Expand Up @@ -25,9 +25,13 @@
import io.github.dsheirer.sample.Listener;
import net.miginfocom.swing.MigLayout;

import javax.swing.*;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.text.DefaultCaret;
import java.awt.*;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

Expand Down

0 comments on commit 7eec82d

Please sign in to comment.