diff --git a/src/bits/BinaryMessage.java b/src/bits/BinaryMessage.java
index 31516602..c3caba05 100644
--- a/src/bits/BinaryMessage.java
+++ b/src/bits/BinaryMessage.java
@@ -136,6 +136,17 @@ public class BinaryMessage extends BitSet
{
mCRC = crc;
}
+
+ /**
+ * Indicates the number of bit errors that were corrected in this message.
+ *
+ * @see CorrectedBinaryMessage subclass that supports setting this value
+ * @return number of corrected bits in this message
+ */
+ public int getCorrectedBitCount()
+ {
+ return 0;
+ }
/**
* Current pointer index
diff --git a/src/bits/CorrectedBinaryMessage.java b/src/bits/CorrectedBinaryMessage.java
new file mode 100644
index 00000000..597830d3
--- /dev/null
+++ b/src/bits/CorrectedBinaryMessage.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * 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
+ *
+ ******************************************************************************/
+package bits;
+
+import java.util.BitSet;
+
+public class CorrectedBinaryMessage extends BinaryMessage
+{
+ private int mCorrectedBitCount;
+
+ /**
+ * Subclass of binary message class to allow capturing a corrected bits metric.
+ * @param size of message to create.
+ */
+ public CorrectedBinaryMessage(int size)
+ {
+ super(size);
+ }
+
+ public CorrectedBinaryMessage(int size, boolean[] bitsToPreload)
+ {
+ super(size, bitsToPreload);
+ }
+
+ public CorrectedBinaryMessage(BitSet bitset, int size)
+ {
+ super(bitset, size);
+ }
+
+ public CorrectedBinaryMessage(byte[] data)
+ {
+ super(data);
+ }
+
+ @Override
+ public int getCorrectedBitCount()
+ {
+ return mCorrectedBitCount;
+ }
+
+ /**
+ * Sets the number of bits that were corrected in this message
+ * @param count of corrected bits
+ */
+ public void setCorrectedBitCount(int count)
+ {
+ mCorrectedBitCount = count;
+ }
+}
diff --git a/src/edac/trellis/DMRNode.java b/src/edac/trellis/DMRNode.java
new file mode 100644
index 00000000..4124bd83
--- /dev/null
+++ b/src/edac/trellis/DMRNode.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * 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
+ *
+ ******************************************************************************/
+package edac.trellis;
+
+public class DMRNode extends Node
+{
+ //Hamming error values indicating the number of bits set in each indexed value, 0-15
+ public static final int[] HAMMING_ERROR_COUNT = new int[]{0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4};
+
+ /**
+ * Transmitted quad-bit value, derived from ETSI TS 102-361-1, Table B.7 Trellis encoder state transition table
+ *
+ * Note: the B.7 table contains constellation point ID numbers that have to be converted into actual bit values
+ * where the bits represent the dibit pair for the constellation point.
+ */
+ public static final int[][] DMR_TRANSITION_MATRIX = new int[][]
+ {
+ {2,13,14,1,7,8,11,4},
+ {14,1,7,8,11,4,2,13},
+ {10,5,6,9,15,0,3,12},
+ {6,9,15,0,3,12,10,5},
+ {15,0,3,12,10,5,6,9},
+ {3,12,10,5,6,9,15,0},
+ {7,8,11,4,2,13,14,1},
+ {11,4,2,13,14,1,7,8}
+ };
+
+ /**
+ * Trellis Coded Modulation (TCM) 3/4-rate trellis node for decoding DMR
+ *
+ * @param inputValue for the trellis time instant
+ * @param transmittedOutputValue the actual four-bit output value that was transmitted.
+ */
+ public DMRNode(int inputValue, int transmittedOutputValue)
+ {
+ super(inputValue, transmittedOutputValue);
+ }
+
+ /**
+ * Calculates the error between the preceeding node and this node as the Hamming distance between the expected
+ * four-bit output value versus the actual transmitted output value.
+ *
+ * @param precedingNode that precedes this node
+ * @return error value for this node relative to the preceeding node argument
+ */
+ @Override
+ public int getError(Node precedingNode)
+ {
+ if(precedingNode != null)
+ {
+ int expectedOutputValue = getOutputValue(precedingNode);
+ int errorMask = expectedOutputValue ^ getTransmittedOutputValue();
+ return HAMMING_ERROR_COUNT[errorMask];
+ }
+
+ return 0;
+ }
+
+ /**
+ * Expected output four-bit value when this node is preceeded by the argument node.
+ *
+ * @param precedingNode that precedes this node
+ * @return expected output value
+ */
+ @Override
+ public int getOutputValue(Node precedingNode)
+ {
+ return DMR_TRANSITION_MATRIX[precedingNode.getInputValue()][getInputValue()];
+ }
+}
diff --git a/src/edac/trellis/Node.java b/src/edac/trellis/Node.java
new file mode 100644
index 00000000..3e54ebf0
--- /dev/null
+++ b/src/edac/trellis/Node.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * 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
+ *
+ ******************************************************************************/
+package edac.trellis;
+
+public abstract class Node
+{
+ private int mInputValue;
+ private int mTransmittedOutputValue;
+
+ /**
+ * Trellis Coded Modulation (TCM) node. A node represents a time instant on the trellis and contains an input
+ * value and the corresponding transmitted output value for the time instant. A node does not maintain the
+ * state at the time instant -- the state is determined by the input value of a preceeding node.
+ *
+ * @param inputValue for this node
+ * @param transmittedOutputValue for this node
+ */
+ public Node(int inputValue, int transmittedOutputValue)
+ {
+ mInputValue = inputValue;
+ mTransmittedOutputValue = transmittedOutputValue;
+ }
+
+ /**
+ * Input value for this node.
+ *
+ * @return input value
+ */
+ public int getInputValue()
+ {
+ return mInputValue;
+ }
+
+ /**
+ * Transmitted output value for this node
+ * @return transmitted output value
+ */
+ public int getTransmittedOutputValue()
+ {
+ return mTransmittedOutputValue;
+ }
+
+ /**
+ * Calculates the error value for this node (time instant) by determining the expected output value that would have
+ * been transmitted using the state from the preceding node argument and this node's input value and comparing that
+ * expected value to the actual transmitted output value. This error is normally represented as the Hamming
+ * distance between the two values.
+ *
+ * @param precedingNode that precedes this node
+ * @return error value for this node relative to the preceeding node
+ */
+ public abstract int getError(Node precedingNode);
+
+ /**
+ * Expected output value when this node is preceeded by the node specified in the argument.
+ *
+ * @param precedingNode that precedes this node
+ * @return expected output value
+ */
+ public abstract int getOutputValue(Node precedingNode);
+}
diff --git a/src/edac/trellis/Path.java b/src/edac/trellis/Path.java
new file mode 100644
index 00000000..667bc7eb
--- /dev/null
+++ b/src/edac/trellis/Path.java
@@ -0,0 +1,131 @@
+/*******************************************************************************
+ * 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
+ *
+ ******************************************************************************/
+package edac.trellis;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Path
+{
+ private List mNodes = new ArrayList<>();
+ private int mError = 0;
+
+ /**
+ * Trellis Coded Modulation (TCM) path. Represents a sequence of nodes that traverse various time instants and
+ * states across a trellis.
+ *
+ * Note: each node can be shared across multiple paths. This class does not assume that any nodes are unique.
+ * @param startingNode to start the path. This node normally contains an input value of zero, but is implementation
+ * specific.
+ */
+ public Path(Node startingNode)
+ {
+ add(startingNode);
+ }
+
+ /**
+ * Trellis Coded Modulation (TCM) path. Represents a sequence of nodes that traverse various time instants and
+ * states across a trellis.
+ *
+ * Note: each node can be shared across multiple paths. This class does not assume that any nodes are unique.
+ *
+ * @param original path to create a copy from. Each of the nodes in the original will be added to this path and
+ * after construction both this path and the original will contain the exact same set of nodes.
+ */
+ private Path(Path original)
+ {
+ for(Node node: original.getNodes())
+ {
+ add(node);
+ }
+ }
+
+ /**
+ * Cumulative error across all nodes contained within this path. Error value is updated as each new node is added
+ * to this path.
+ *
+ * @return cumulative error value
+ */
+ public int getError()
+ {
+ return mError;
+ }
+
+ /**
+ * Length or number of nodes contained within this path. Note: this value includes the starting node and may
+ * also include a flushing node. The values contained in the starting and flushing nodes are normally not used
+ * when decoding a path.
+ *
+ * @return number of nodes in this path
+ */
+ public int getLength()
+ {
+ return mNodes.size() - 1;
+ }
+
+ /**
+ * The set of nodes contained in this path.
+ * @return nodes
+ */
+ public List getNodes()
+ {
+ return mNodes;
+ }
+
+ /**
+ * Adds the node to this path and updates the cumulative error value for this path by adding the node's error
+ * value to the running error total.
+ *
+ * @param node to add to this path
+ */
+ public void add(Node node)
+ {
+ if(!mNodes.isEmpty())
+ {
+ mError += node.getError(getLastNode());
+ }
+
+ mNodes.add(node);
+ }
+
+ /**
+ * Last node in this path.
+ *
+ * @return last node
+ */
+ public Node getLastNode()
+ {
+ if(!mNodes.isEmpty())
+ {
+ return mNodes.get(mNodes.size() - 1);
+ }
+
+ return null;
+ }
+
+ /**
+ * Utility method to create an exact copy of this path.
+ *
+ * @return a new copy of this path.
+ */
+ public Path copyOf()
+ {
+ return new Path(this);
+ }
+}
diff --git a/src/edac/trellis/ViterbiDecoder.java b/src/edac/trellis/ViterbiDecoder.java
new file mode 100644
index 00000000..6341f1a6
--- /dev/null
+++ b/src/edac/trellis/ViterbiDecoder.java
@@ -0,0 +1,226 @@
+/*******************************************************************************
+ * 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
+ *
+ ******************************************************************************/
+package edac.trellis;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+public abstract class ViterbiDecoder
+{
+ private int mInputBitLength;
+ private int mInputValueCount;
+ private int mOutputBitLength;
+ private int mOutputValueCount;
+
+ /**
+ * Viterbi decoder for trellis coded modulation (TCM) encoded binary sequences.
+ *
+ * @param inputBitLength for coding (e.g. 3/4 rate input bit length is 3)
+ * @param outputBitLength for coding (e.g. 3/4 rate output bit length is 4)
+ */
+ public ViterbiDecoder(int inputBitLength, int outputBitLength)
+ {
+ mInputBitLength = inputBitLength;
+ mOutputBitLength = outputBitLength;
+
+ mInputValueCount = (int)Math.pow(2.0, mInputBitLength);
+ mOutputValueCount = (int)Math.pow(2.0, mOutputBitLength);
+ }
+
+ /**
+ * Creates a node that represents an input value and the actual/transmitted output value.
+ *
+ * Note: this method must be implemented by a sub-class since the node requires a specific state transition
+ * table/matrix implementation.
+ *
+ * @param inputValue for the specific trellis node
+ * @param transmittedOutputValue the actual transmitted output value
+ * @return node for decoding
+ */
+ protected abstract Node createNode(int inputValue, int transmittedOutputValue);
+
+ /**
+ * Creates a flushing or final node that represents an actual/transmitted output value and a flushing input value.
+ *
+ * The final flushing input value is implementation-specific, therefore this will be implemented in any subclass
+ * of this decoder. A normal flushing input value is zero.
+ *
+ * @param transmittedOutputValue the actual transmitted output value
+ * @return flushing node
+ */
+ protected abstract Node createFlushingNode(int transmittedOutputValue);
+
+ /**
+ * Creates a starting node that represents a starting state and notional transmitted output value.
+ *
+ * The starting input value is implementation-specific, therefore this will be implemented in any subclass
+ * of this decoder. A normal starting input value is zero.
+ *
+ * @return starting node
+ */
+ protected abstract Node createStartingNode();
+
+ /**
+ * Size in bits of the input and state values (e.g. 3/4 rate input size is 3)
+ *
+ * @return input bit size
+ */
+ public int getInputBitLength()
+ {
+ return mInputBitLength;
+ }
+
+ /**
+ * Count of input or state values where the set of values is in the range of 0 <> count - 1
+ *
+ * @return input or state values count
+ */
+ public int getInputValueCount()
+ {
+ return mInputValueCount;
+ }
+
+ /**
+ * Size in bits of the output constellation or transmitted symbol value (e.g. 3/4 rate output size is 4)
+ *
+ * @return output size in bits
+ */
+ public int getOutputBitLength()
+ {
+ return mOutputBitLength;
+ }
+
+ /**
+ * Count of input or state values where the set of values is in the range of 0 <> count - 1
+ *
+ * @return input or state values count
+ */
+ public int getOutputValueCount()
+ {
+ return mOutputValueCount;
+ }
+
+ /**
+ * Decodes the TCM encoded transmitted output values and returns a path the represents the most likely transmitted
+ * sequence of nodes.
+ *
+ * @param transmittedOutputValues from the encoded message
+ * @return most likely path representing the transmitted values
+ */
+ public Path decode(int[] transmittedOutputValues)
+ {
+ Collection survivingPaths = new ArrayList<>();
+
+ survivingPaths.add(new Path(createStartingNode()));
+
+ //Add all but the last transmitted value to the starting path, creating a set of survivors at each iteration.
+ for(int x = 0; x < transmittedOutputValues.length - 1; x++)
+ {
+ survivingPaths = add(survivingPaths, transmittedOutputValues[x]);
+ }
+
+ //Flush the survivors with the final transmitted value and return the lone surviving path
+ return flush(survivingPaths, transmittedOutputValues[transmittedOutputValues.length - 1]);
+ }
+
+ /**
+ * Creates a set of new nodes representing all possible input values and the transmitted output value argument
+ * and iteratively adds the set of nodes to a copy of each of the surviving paths. A set of surviving paths is
+ * returned that represents each path that terminates at a distinct input/state value that has the least error
+ * value.
+ *
+ * @param survivingPaths from the previous time instant to evaluate for the next time instant in the trellis
+ * using the transmitted output value.
+ *
+ * @param transmittedOutputValue that will be decoded for this time instant.
+ *
+ * @return paths that have survived (ie have the lowest error value) after adding nodes for the transmitted
+ * output value
+ *
+ */
+ public Collection add(Collection survivingPaths, int transmittedOutputValue)
+ {
+ Map survivingPathMap = new HashMap<>();
+
+ for(int x = 0; x < getInputValueCount(); x++)
+ {
+ //Create a single/unique node for each possible input value combined with the transmitted output value
+ Node node = createNode(x, transmittedOutputValue);
+
+ //Evaluate each surviving path by creating a copy and adding the node to it and see if it survives
+ for(Path path: survivingPaths)
+ {
+ Path pathToEvaluate = path.copyOf();
+
+ pathToEvaluate.add(node);
+
+ if(survivingPathMap.containsKey(node.getInputValue()))
+ {
+ Path survivingPath = survivingPathMap.get(node.getInputValue());
+
+ //Replace the current survivor path if this evaluate path has a lower error value
+ if(pathToEvaluate.getError() < survivingPath.getError())
+ {
+ survivingPathMap.put(node.getInputValue(), pathToEvaluate);
+ }
+ }
+ else
+ {
+ //No survivor yet -- set this evaluate path as the first survivor
+ survivingPathMap.put(node.getInputValue(), pathToEvaluate);
+ }
+ }
+ }
+
+ return survivingPathMap.values();
+ }
+
+ /**
+ * Flushes each of the surviving paths with a final/flushing node using the transmitted symbol. A final flushing
+ * input value or state is implementation-specific, but normally uses a value of zero. Since all paths will be
+ * evaluated against each other as terminating at the same state, only the path with the lowest error value will
+ * be returned from this method.
+ *
+ * @param survivingPaths to flush with the final flushing node
+ * @param transmittedOutputValue to use for the final flushing node
+ *
+ * @return the single survivor path that remains after adding the flushing node to each of the candidate argument
+ * survivor paths.
+ */
+ public Path flush(Collection survivingPaths, int transmittedOutputValue)
+ {
+ Node flushingNode = createFlushingNode(transmittedOutputValue);
+
+ Path bestPath = null;
+
+ for(Path survivingPath: survivingPaths)
+ {
+ survivingPath.add(flushingNode);
+
+ if(bestPath == null || (survivingPath.getError() < bestPath.getError()))
+ {
+ bestPath = survivingPath;
+ }
+ }
+
+ return bestPath;
+ }
+}
diff --git a/src/edac/trellis/ViterbiDecoder_3_4_DMR.java b/src/edac/trellis/ViterbiDecoder_3_4_DMR.java
new file mode 100644
index 00000000..142c7ada
--- /dev/null
+++ b/src/edac/trellis/ViterbiDecoder_3_4_DMR.java
@@ -0,0 +1,159 @@
+/*******************************************************************************
+ * 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
+ *
+ ******************************************************************************/
+package edac.trellis;
+
+import bits.BinaryMessage;
+import bits.CorrectedBinaryMessage;
+
+import java.util.List;
+
+public class ViterbiDecoder_3_4_DMR extends ViterbiDecoder
+{
+ /**
+ * Viterbi decoder for Digital Mobile Radio (DMR) 3/4 rate Trellis Coded Modulation (TCM) encoded messages.
+ */
+ public ViterbiDecoder_3_4_DMR()
+ {
+ super(3,4);
+ }
+
+ /**
+ * Decodes a 3/4 rate trellis coded modulation (TCM) encoded DMR binary message containing 196 bits that have
+ * already been deinterleaved.
+ *
+ * @param encodedMessage to decode that has already been deinterleaved.
+ * @return decoded message
+ */
+ public BinaryMessage decode(BinaryMessage encodedMessage)
+ {
+ int[] symbols = getSymbols(encodedMessage);
+
+ Path mostLikelyPath = decode(symbols);
+
+ return getMessage(mostLikelyPath);
+ }
+
+ /**
+ * Extracts the decoded/corrected message from the surviving path argument.
+ *
+ * @param path to extract a message from
+ * @return corrected binary message.
+ */
+ private static CorrectedBinaryMessage getMessage(Path path)
+ {
+ List mNodes = path.getNodes();
+
+ //Each node contains an input value excluding the starting(0) and final flushing(0) nodes.
+ CorrectedBinaryMessage message = new CorrectedBinaryMessage((mNodes.size() - 2) * 3);
+
+ if(mNodes.size() > 2)
+ {
+ for(int x = 1; x < mNodes.size() - 1; x++)
+ {
+ int inputValue = mNodes.get(x).getInputValue();
+
+ int messageOffset = 3 * (x - 1);
+
+ if((inputValue & 4) == 4)
+ {
+ message.set(messageOffset);
+ }
+
+ if((inputValue & 2) == 2)
+ {
+ message.set(messageOffset + 1);
+ }
+
+ if((inputValue & 1) == 1)
+ {
+ message.set(messageOffset + 2);
+ }
+ }
+ }
+
+ //Transfer the corrected error count to the message
+ message.setCorrectedBitCount(path.getError());
+
+ return message;
+ }
+
+ /**
+ * Extracts (49) four-bit symbols (196 bits / 4) from the deinterleaved DMR binary message
+ *
+ * @param encodedMessage that deinterleaved and contains 196-bits of 3/4 TCM encoding
+ * @return symbols
+ */
+ public int[] getSymbols(BinaryMessage encodedMessage)
+ {
+ //Ensure we have an integral number of transmitted symbols (nibbles) in the message
+ if(encodedMessage.size() % getOutputBitLength() != 0)
+ {
+ throw new IllegalArgumentException("Encoded message must contain an integral number of 4-bit symbols -" +
+ " message size: " + encodedMessage.size());
+ }
+
+ int[] symbols = new int[encodedMessage.size() / getOutputBitLength()];
+
+ int index = 0;
+ int pointer = 0;
+
+ while(index < encodedMessage.size())
+ {
+ int symbol = encodedMessage.getInt(index, index + (getOutputBitLength() - 1));
+ symbols[pointer++] = symbol;
+ index += getOutputBitLength();
+ }
+
+ return symbols;
+ }
+
+ /**
+ * Creates a DMR node
+ * @param inputValue for the specific trellis node
+ * @param transmittedOutputValue the actual transmitted output value
+ * @return created node
+ */
+ @Override
+ protected Node createNode(int inputValue, int transmittedOutputValue)
+ {
+ return new DMRNode(inputValue, transmittedOutputValue);
+ }
+
+ /**
+ * Creates a DMR flushing node. DMR uses an input value of zero to flush the final output value out of the
+ * encoder.
+ *
+ * @param transmittedOutputValue the actual transmitted output value
+ * @return
+ */
+ @Override
+ protected Node createFlushingNode(int transmittedOutputValue)
+ {
+ return new DMRNode(0, transmittedOutputValue);
+ }
+
+ /**
+ * Creates a DMR starting node. DMR uses a starting input value of zero for the initial node.
+ */
+ @Override
+ protected Node createStartingNode()
+ {
+ return new DMRNode(0,0);
+ }
+}
diff --git a/src/external/radioreference/RadioReferenceService.java b/src/external/radioreference/RadioReferenceService.java
index df46e9f0..12eefcea 100644
--- a/src/external/radioreference/RadioReferenceService.java
+++ b/src/external/radioreference/RadioReferenceService.java
@@ -151,41 +151,4 @@ public class RadioReferenceService
return mClient.getUserFeedBroadcasts(mUserAuthorization);
}
-
-
- public static void main(String[] args)
- {
- try
- {
- RadioReferenceService service = new RadioReferenceService("dsheirer", "1dodgeram");
-
- Long expiration = service.getAccountExpirationDate();
-
- mLog.debug("Expiration Date:" + (expiration != null ? new Date(expiration).toString() : "unknown"));
-
- mLog.debug("Is Active: " + service.isAccountActive());
-
- UserFeedBroadcast[] feeds = service.getUserFeedBroadcasts();
-
- for(UserFeedBroadcast feed: feeds)
- {
- mLog.debug("Feed ID: " + feed.getFeedId() + " Desc:" + feed.getDescr());
- }
- }
- catch(AxisFault af)
- {
- mLog.debug("Hey, I caught an axis fault!");
- mLog.debug("Reason:" + af.getFaultReason());
- }
- catch(RemoteException re)
- {
- re.printStackTrace();
- }
- catch(Exception e)
- {
- e.printStackTrace();
- }
-
- mLog.debug("Finished!");
- }
}