mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-13 09:07:27 -05:00
Compare commits
9 Commits
v0.4.0-bet
...
v0.4.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2e37f1e687 | ||
|
|
5e8f2d0523 | ||
|
|
9fb6c33319 | ||
|
|
fdecac4230 | ||
|
|
85c27a6cca | ||
|
|
57f56d31a2 | ||
|
|
df25675d3f | ||
|
|
277a84702a | ||
|
|
c651296378 |
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_13" default="true" project-jdk-name="13" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_X" default="true" project-jdk-name="14" project-jdk-type="JavaSDK">
|
||||||
<output url="file://$PROJECT_DIR$/out" />
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
15
CHANGELOG
15
CHANGELOG
@@ -1,3 +1,18 @@
|
|||||||
|
0.4.0 20200404
|
||||||
|
- Release includes embedded Java 14 & JavaFX 13 runtime
|
||||||
|
- Adds Polyphase Channelizer with 2x channel oversampling and redesigned source management
|
||||||
|
- Adds P25 Phase 2 decoder
|
||||||
|
- Adds P25 radio identifier aliasing
|
||||||
|
- JMBE library 1.0.4 with support for AMBE tone metadata
|
||||||
|
- New JavaFX User Preferences dialog
|
||||||
|
- HackRF tuner enhanced (sample rates and saturation issues)
|
||||||
|
- Adds support for Airspy mini tuner
|
||||||
|
- Redesigned audio sub-system that uses AudioSegments
|
||||||
|
- USB tuner bus saturation management/monitoring
|
||||||
|
- Bitstream (.bits) recording
|
||||||
|
- MP3 Audio Recording
|
||||||
|
- Numerous bug fixes
|
||||||
|
|
||||||
0.3.4 20180418
|
0.3.4 20180418
|
||||||
- New P25 C4FM decoder that uses Differential QPSK decoder instead of FM demodulation with 4FSK.
|
- New P25 C4FM decoder that uses Differential QPSK decoder instead of FM demodulation with 4FSK.
|
||||||
- Adds channel auto-start and ordering capability with startup dialog allowing user to invoke or bypass channel
|
- Adds channel auto-start and ordering capability with startup dialog allowing user to invoke or bypass channel
|
||||||
|
|||||||
14
build.gradle
14
build.gradle
@@ -33,7 +33,7 @@ repositories {
|
|||||||
maven { url "https://jitpack.io" }
|
maven { url "https://jitpack.io" }
|
||||||
}
|
}
|
||||||
|
|
||||||
version = '0.4.0-beta.7'
|
version = '0.4.0'
|
||||||
sourceCompatibility = '13'
|
sourceCompatibility = '13'
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
@@ -114,7 +114,7 @@ jar {
|
|||||||
attributes (
|
attributes (
|
||||||
'Implementation-Title' : 'sdrtrunk project',
|
'Implementation-Title' : 'sdrtrunk project',
|
||||||
'Implementation-Version' : archiveVersion,
|
'Implementation-Version' : archiveVersion,
|
||||||
'Class-Path' : 'jmbe-1.0.1.jar',
|
'Class-Path' : 'jmbe-1.0.4.jar',
|
||||||
'Created-By' : "Gradle ${gradle.gradleVersion}",
|
'Created-By' : "Gradle ${gradle.gradleVersion}",
|
||||||
'Build-Timestamp' : new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").format(new Date()),
|
'Build-Timestamp' : new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").format(new Date()),
|
||||||
'Build-JDK' : "${System.properties['java.version']} (${System.properties['java.vendor']} ${System.properties['java.vm.version']}",
|
'Build-JDK' : "${System.properties['java.version']} (${System.properties['java.vendor']} ${System.properties['java.vm.version']}",
|
||||||
@@ -129,11 +129,11 @@ jar {
|
|||||||
* tasks to produce platform-specific builds. If none of these paths exists, then an image will be created for the
|
* tasks to produce platform-specific builds. If none of these paths exists, then an image will be created for the
|
||||||
* host OS using the installed JDK.
|
* host OS using the installed JDK.
|
||||||
*/
|
*/
|
||||||
def jdk_linux_x86_64 = '/media/denny/WD250GB/java/bellsoft/linux-x64/jdk-13.0.1'
|
def jdk_linux_x86_64 = '/media/denny/WD250GB/java/bellsoft/linux-x64/jdk-14'
|
||||||
def jdk_linux_x86_32 = '/media/denny/WD250GB/java/bellsoft/linux-x86/jdk-13.0.1'
|
def jdk_linux_x86_32 = '/media/denny/WD250GB/java/bellsoft/linux-x86/jdk-14'
|
||||||
def jdk_osx_x86_64 = '/media/denny/WD250GB/java/bellsoft/osx-x64/jdk-13.0.1.jdk'
|
def jdk_osx_x86_64 = '/media/denny/WD250GB/java/bellsoft/osx-x64/jdk-14.jdk'
|
||||||
def jdk_windows_x86_64 = '/media/denny/WD250GB/java/bellsoft/windows-x64/jdk-13.0.1'
|
def jdk_windows_x86_64 = '/media/denny/WD250GB/java/bellsoft/windows-x64/jdk-14'
|
||||||
def jdk_windows_x86_32 = '/media/denny/WD250GB/java/bellsoft/windows-x86/jdk-13.0.1'
|
def jdk_windows_x86_32 = '/media/denny/WD250GB/java/bellsoft/windows-x86/jdk-14'
|
||||||
|
|
||||||
def file_jdk_linux_x86_64 = new File(jdk_linux_x86_64)
|
def file_jdk_linux_x86_64 = new File(jdk_linux_x86_64)
|
||||||
def file_jdk_linux_x86_32 = new File(jdk_linux_x86_32)
|
def file_jdk_linux_x86_32 = new File(jdk_linux_x86_32)
|
||||||
|
|||||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
24
gradle/wrapper/gradle-wrapper.properties
vendored
24
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,27 +1,5 @@
|
|||||||
#
|
|
||||||
# /*
|
|
||||||
# * ******************************************************************************
|
|
||||||
# * Copyright (C) 2014-2019 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/>
|
|
||||||
# * *****************************************************************************
|
|
||||||
# */
|
|
||||||
#
|
|
||||||
#
|
|
||||||
|
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.0.1-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-bin.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|||||||
51
gradlew
vendored
51
gradlew
vendored
@@ -1,5 +1,21 @@
|
|||||||
#!/usr/bin/env sh
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright 2015 the original author or authors.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
##
|
##
|
||||||
## Gradle start up script for UN*X
|
## Gradle start up script for UN*X
|
||||||
@@ -28,7 +44,7 @@ APP_NAME="Gradle"
|
|||||||
APP_BASE_NAME=`basename "$0"`
|
APP_BASE_NAME=`basename "$0"`
|
||||||
|
|
||||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
DEFAULT_JVM_OPTS='"-Xmx64m"'
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
|
|
||||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
MAX_FD="maximum"
|
MAX_FD="maximum"
|
||||||
@@ -109,8 +125,8 @@ if $darwin; then
|
|||||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# For Cygwin, switch paths to Windows format before running java
|
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||||
if $cygwin ; then
|
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||||
@@ -138,19 +154,19 @@ if $cygwin ; then
|
|||||||
else
|
else
|
||||||
eval `echo args$i`="\"$arg\""
|
eval `echo args$i`="\"$arg\""
|
||||||
fi
|
fi
|
||||||
i=$((i+1))
|
i=`expr $i + 1`
|
||||||
done
|
done
|
||||||
case $i in
|
case $i in
|
||||||
(0) set -- ;;
|
0) set -- ;;
|
||||||
(1) set -- "$args0" ;;
|
1) set -- "$args0" ;;
|
||||||
(2) set -- "$args0" "$args1" ;;
|
2) set -- "$args0" "$args1" ;;
|
||||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
3) set -- "$args0" "$args1" "$args2" ;;
|
||||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -159,14 +175,9 @@ save () {
|
|||||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||||
echo " "
|
echo " "
|
||||||
}
|
}
|
||||||
APP_ARGS=$(save "$@")
|
APP_ARGS=`save "$@"`
|
||||||
|
|
||||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||||
|
|
||||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
|
||||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
|
||||||
cd "$(dirname "$0")"
|
|
||||||
fi
|
|
||||||
|
|
||||||
exec "$JAVACMD" "$@"
|
exec "$JAVACMD" "$@"
|
||||||
|
|||||||
18
gradlew.bat
vendored
18
gradlew.bat
vendored
@@ -1,3 +1,19 @@
|
|||||||
|
@rem
|
||||||
|
@rem Copyright 2015 the original author or authors.
|
||||||
|
@rem
|
||||||
|
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@rem you may not use this file except in compliance with the License.
|
||||||
|
@rem You may obtain a copy of the License at
|
||||||
|
@rem
|
||||||
|
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
@rem
|
||||||
|
@rem Unless required by applicable law or agreed to in writing, software
|
||||||
|
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@rem See the License for the specific language governing permissions and
|
||||||
|
@rem limitations under the License.
|
||||||
|
@rem
|
||||||
|
|
||||||
@if "%DEBUG%" == "" @echo off
|
@if "%DEBUG%" == "" @echo off
|
||||||
@rem ##########################################################################
|
@rem ##########################################################################
|
||||||
@rem
|
@rem
|
||||||
@@ -14,7 +30,7 @@ set APP_BASE_NAME=%~n0
|
|||||||
set APP_HOME=%DIRNAME%
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
set DEFAULT_JVM_OPTS="-Xmx64m"
|
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||||
|
|
||||||
@rem Find java.exe
|
@rem Find java.exe
|
||||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
|
|||||||
@@ -37,6 +37,6 @@ public abstract class RadioIdentifier extends IntegerIdentifier
|
|||||||
@Override
|
@Override
|
||||||
public boolean isValid()
|
public boolean isValid()
|
||||||
{
|
{
|
||||||
return getValue() >= 0;
|
return getValue() > 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ import io.github.dsheirer.gui.editor.EditorValidationException;
|
|||||||
import io.github.dsheirer.gui.editor.ValidatingEditor;
|
import io.github.dsheirer.gui.editor.ValidatingEditor;
|
||||||
import io.github.dsheirer.module.decode.config.DecodeConfiguration;
|
import io.github.dsheirer.module.decode.config.DecodeConfiguration;
|
||||||
import net.miginfocom.swing.MigLayout;
|
import net.miginfocom.swing.MigLayout;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import javax.swing.DefaultComboBoxModel;
|
import javax.swing.DefaultComboBoxModel;
|
||||||
import javax.swing.JButton;
|
import javax.swing.JButton;
|
||||||
@@ -41,10 +43,13 @@ import javax.swing.event.ChangeListener;
|
|||||||
import java.awt.EventQueue;
|
import java.awt.EventQueue;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
|
import java.awt.event.WindowAdapter;
|
||||||
|
import java.awt.event.WindowEvent;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class MPT1327DecoderEditor extends ValidatingEditor<Channel>
|
public class MPT1327DecoderEditor extends ValidatingEditor<Channel>
|
||||||
{
|
{
|
||||||
|
private final static Logger mLog = LoggerFactory.getLogger(MPT1327DecoderEditor.class);
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
private JComboBox<ChannelMap> mComboChannelMaps;
|
private JComboBox<ChannelMap> mComboChannelMaps;
|
||||||
@@ -65,12 +70,17 @@ public class MPT1327DecoderEditor extends ValidatingEditor<Channel>
|
|||||||
{
|
{
|
||||||
setLayout(new MigLayout("insets 0 0 0 0,wrap 4", "[right][grow,fill][right][grow,fill]", ""));
|
setLayout(new MigLayout("insets 0 0 0 0,wrap 4", "[right][grow,fill][right][grow,fill]", ""));
|
||||||
|
|
||||||
List<ChannelMap> maps = mChannelMapModel.getChannelMaps();
|
|
||||||
ChannelMap[] mapArray = maps.toArray(new ChannelMap[maps.size()]);
|
|
||||||
|
|
||||||
mComboChannelMaps = new JComboBox<ChannelMap>();
|
mComboChannelMaps = new JComboBox<ChannelMap>();
|
||||||
mComboChannelMaps.setModel(new DefaultComboBoxModel<ChannelMap>(mapArray));
|
refreshChannelMaps();
|
||||||
mComboChannelMaps.setEnabled(false);
|
mComboChannelMaps.setEnabled(false);
|
||||||
|
mComboChannelMaps.addActionListener(new ActionListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e)
|
||||||
|
{
|
||||||
|
setModified(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
add(new JLabel("Channel Map:"));
|
add(new JLabel("Channel Map:"));
|
||||||
add(mComboChannelMaps);
|
add(mComboChannelMaps);
|
||||||
|
|
||||||
@@ -80,8 +90,17 @@ public class MPT1327DecoderEditor extends ValidatingEditor<Channel>
|
|||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e)
|
public void actionPerformed(ActionEvent e)
|
||||||
{
|
{
|
||||||
final ChannelMapManagerFrame manager =
|
final ChannelMapManagerFrame manager = new ChannelMapManagerFrame(mChannelMapModel);
|
||||||
new ChannelMapManagerFrame(mChannelMapModel);
|
manager.addWindowListener(new WindowAdapter()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void windowClosed(WindowEvent e)
|
||||||
|
{
|
||||||
|
super.windowClosed(e);
|
||||||
|
mLog.debug("Refreshing channel maps combo box");
|
||||||
|
refreshChannelMaps();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
EventQueue.invokeLater(new Runnable()
|
EventQueue.invokeLater(new Runnable()
|
||||||
{
|
{
|
||||||
@@ -139,6 +158,22 @@ public class MPT1327DecoderEditor extends ValidatingEditor<Channel>
|
|||||||
add(mCallTimeout);
|
add(mCallTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void refreshChannelMaps()
|
||||||
|
{
|
||||||
|
List<ChannelMap> maps = mChannelMapModel.getChannelMaps();
|
||||||
|
|
||||||
|
ChannelMap[] mapArray = new ChannelMap[maps.size() + 1];
|
||||||
|
|
||||||
|
int index = 1;
|
||||||
|
|
||||||
|
for(ChannelMap channelMap: maps)
|
||||||
|
{
|
||||||
|
mapArray[index++] = channelMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
mComboChannelMaps.setModel(new DefaultComboBoxModel<ChannelMap>(mapArray));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void save()
|
public void save()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -280,7 +280,13 @@ public class MPT1327DecoderState extends DecoderState
|
|||||||
@Override
|
@Override
|
||||||
public void start()
|
public void start()
|
||||||
{
|
{
|
||||||
|
//Send call start event for traffic channels to unsquelch the audio. Decoded return to channel message
|
||||||
|
//or fade timeout expire will end the call event.
|
||||||
|
if(mChannelType == ChannelType.TRAFFIC)
|
||||||
|
{
|
||||||
|
//Broadcast a start call event so the squelch kicks on and the audio path opens
|
||||||
|
broadcast(new DecoderStateEvent(this, Event.START, State.CALL));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -190,8 +190,9 @@ public class P25P2AudioModule extends AmbeAudioModule implements IdentifierUpdat
|
|||||||
*/
|
*/
|
||||||
private void processMetadata(IAudioWithMetadata audioWithMetadata)
|
private void processMetadata(IAudioWithMetadata audioWithMetadata)
|
||||||
{
|
{
|
||||||
if(audioWithMetadata.hasMetadata() && mIdentifierUpdateNotificationListener != null)
|
if(audioWithMetadata.hasMetadata())
|
||||||
{
|
{
|
||||||
|
//JMBE only places 1 entry in the map, but for consistency we'll process the map entry set
|
||||||
for(Map.Entry<String,String> entry: audioWithMetadata.getMetadata().entrySet())
|
for(Map.Entry<String,String> entry: audioWithMetadata.getMetadata().entrySet())
|
||||||
{
|
{
|
||||||
//Each metadata map entry contains a tone-type (key) and tone (value)
|
//Each metadata map entry contains a tone-type (key) and tone (value)
|
||||||
@@ -203,6 +204,10 @@ public class P25P2AudioModule extends AmbeAudioModule implements IdentifierUpdat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mToneMetadataProcessor.closeMetadata();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -243,6 +248,7 @@ public class P25P2AudioModule extends AmbeAudioModule implements IdentifierUpdat
|
|||||||
public class ToneMetadataProcessor
|
public class ToneMetadataProcessor
|
||||||
{
|
{
|
||||||
private List<ToneMetadata> mToneMetadata = new ArrayList<>();
|
private List<ToneMetadata> mToneMetadata = new ArrayList<>();
|
||||||
|
private ToneMetadata mCurrentToneMetadata;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets or clears any accumulated call tone metadata to prepare for the next call.
|
* Resets or clears any accumulated call tone metadata to prepare for the next call.
|
||||||
@@ -265,18 +271,27 @@ public class P25P2AudioModule extends AmbeAudioModule implements IdentifierUpdat
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
ToneMetadata toneMetadata = (mToneMetadata.size() > 0 ? mToneMetadata.get(mToneMetadata.size() - 1) : null);
|
if(mCurrentToneMetadata != null && mCurrentToneMetadata.matches(type, value))
|
||||||
|
|
||||||
if(toneMetadata == null || !toneMetadata.matches(type, value))
|
|
||||||
{
|
{
|
||||||
toneMetadata = new ToneMetadata(type, value);
|
mCurrentToneMetadata.incrementCount();
|
||||||
mToneMetadata.add(toneMetadata);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mCurrentToneMetadata = new ToneMetadata(type, value);
|
||||||
|
mToneMetadata.add(mCurrentToneMetadata);
|
||||||
|
mCurrentToneMetadata.incrementCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
toneMetadata.incrementCount();
|
|
||||||
|
|
||||||
return P25ToneIdentifier.create(Joiner.on(",").join(mToneMetadata));
|
return P25ToneIdentifier.create(Joiner.on(",").join(mToneMetadata));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes current tone metadata when there is no metadata for the current audio frame.
|
||||||
|
*/
|
||||||
|
public void closeMetadata()
|
||||||
|
{
|
||||||
|
mCurrentToneMetadata = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -189,25 +189,40 @@ public class P25Channel implements IChannelDescriptor
|
|||||||
{
|
{
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
|
int downlinkChannelNumber = getDownlinkChannelNumber();
|
||||||
|
|
||||||
|
if(isTDMAChannel())
|
||||||
|
{
|
||||||
|
downlinkChannelNumber -= downlinkChannelNumber % getTimeslotCount();
|
||||||
|
}
|
||||||
|
|
||||||
if(getDownlinkBandIdentifier() == getUplinkBandIdentifier() && getDownlinkChannelNumber() == getUplinkChannelNumber())
|
if(getDownlinkBandIdentifier() == getUplinkBandIdentifier() && getDownlinkChannelNumber() == getUplinkChannelNumber())
|
||||||
{
|
{
|
||||||
sb.append(getDownlinkBandIdentifier()).append("-").append(getDownlinkLogicalChannelNumber());
|
sb.append(getDownlinkBandIdentifier()).append("-").append(downlinkChannelNumber);
|
||||||
}
|
}
|
||||||
else if(hasUplinkChannel())
|
else if(hasUplinkChannel())
|
||||||
{
|
{
|
||||||
|
|
||||||
|
int uplinkChannelNumber = getUplinkChannelNumber();
|
||||||
|
|
||||||
|
if(isTDMAChannel())
|
||||||
|
{
|
||||||
|
uplinkChannelNumber -= uplinkChannelNumber % getTimeslotCount();
|
||||||
|
}
|
||||||
|
|
||||||
sb.append(getDownlinkBandIdentifier())
|
sb.append(getDownlinkBandIdentifier())
|
||||||
.append("-")
|
.append("-")
|
||||||
.append(getDownlinkLogicalChannelNumber())
|
.append(downlinkChannelNumber)
|
||||||
.append("/")
|
.append("/")
|
||||||
.append(getUplinkBandIdentifier())
|
.append(getUplinkBandIdentifier())
|
||||||
.append("-")
|
.append("-")
|
||||||
.append(getUplinkLogicalChannelNumber());
|
.append(uplinkChannelNumber);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sb.append(getDownlinkBandIdentifier())
|
sb.append(getDownlinkBandIdentifier())
|
||||||
.append("-")
|
.append("-")
|
||||||
.append(getDownlinkLogicalChannelNumber())
|
.append(downlinkChannelNumber)
|
||||||
.append("/-----");
|
.append("/-----");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ package io.github.dsheirer.module.decode.p25.phase1.message.lc.motorola;
|
|||||||
|
|
||||||
import io.github.dsheirer.bits.BinaryMessage;
|
import io.github.dsheirer.bits.BinaryMessage;
|
||||||
import io.github.dsheirer.identifier.Identifier;
|
import io.github.dsheirer.identifier.Identifier;
|
||||||
import io.github.dsheirer.module.decode.p25.identifier.talkgroup.APCO25Talkgroup;
|
import io.github.dsheirer.module.decode.p25.identifier.radio.APCO25RadioIdentifier;
|
||||||
import io.github.dsheirer.module.decode.p25.phase1.message.lc.LinkControlWord;
|
import io.github.dsheirer.module.decode.p25.phase1.message.lc.LinkControlWord;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -94,7 +94,7 @@ public class LCMotorolaTalkComplete extends LinkControlWord
|
|||||||
{
|
{
|
||||||
if(mAddress == null)
|
if(mAddress == null)
|
||||||
{
|
{
|
||||||
mAddress = APCO25Talkgroup.create(getMessage().getInt(ADDRESS));
|
mAddress = APCO25RadioIdentifier.createFrom(getMessage().getInt(ADDRESS));
|
||||||
}
|
}
|
||||||
|
|
||||||
return mAddress;
|
return mAddress;
|
||||||
|
|||||||
@@ -336,11 +336,8 @@ public class P25P2DecoderState extends TimeslotDecoderState implements Identifie
|
|||||||
|
|
||||||
for(Identifier identifier : mac.getIdentifiers())
|
for(Identifier identifier : mac.getIdentifiers())
|
||||||
{
|
{
|
||||||
if(!(identifier.getForm() == Form.TALKGROUP && identifier.getRole() == Role.FROM))
|
//Add to the identifier collection after filtering through the patch group manager
|
||||||
{
|
getIdentifierCollection().update(mPatchGroupManager.update(identifier));
|
||||||
//Add to the identifier collection after filtering through the patch group manager
|
|
||||||
getIdentifierCollection().update(mPatchGroupManager.update(identifier));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -373,11 +370,8 @@ public class P25P2DecoderState extends TimeslotDecoderState implements Identifie
|
|||||||
|
|
||||||
for(Identifier identifier : mac.getIdentifiers())
|
for(Identifier identifier : mac.getIdentifiers())
|
||||||
{
|
{
|
||||||
if(!(identifier.getForm() == Form.TALKGROUP && identifier.getRole() == Role.FROM))
|
//Add to the identifier collection after filtering through the patch group manager
|
||||||
{
|
getIdentifierCollection().update(mPatchGroupManager.update(identifier));
|
||||||
//Add to the identifier collection after filtering through the patch group manager
|
|
||||||
getIdentifierCollection().update(mPatchGroupManager.update(identifier));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -410,11 +404,8 @@ public class P25P2DecoderState extends TimeslotDecoderState implements Identifie
|
|||||||
|
|
||||||
for(Identifier identifier : mac.getIdentifiers())
|
for(Identifier identifier : mac.getIdentifiers())
|
||||||
{
|
{
|
||||||
if(!(identifier.getForm() == Form.TALKGROUP && identifier.getRole() == Role.FROM))
|
//Add to the identifier collection after filtering through the patch group manager
|
||||||
{
|
getIdentifierCollection().update(mPatchGroupManager.update(identifier));
|
||||||
//Add to the identifier collection after filtering through the patch group manager
|
|
||||||
getIdentifierCollection().update(mPatchGroupManager.update(identifier));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -447,11 +438,8 @@ public class P25P2DecoderState extends TimeslotDecoderState implements Identifie
|
|||||||
|
|
||||||
for(Identifier identifier : mac.getIdentifiers())
|
for(Identifier identifier : mac.getIdentifiers())
|
||||||
{
|
{
|
||||||
if(!(identifier.getForm() == Form.TALKGROUP && identifier.getRole() == Role.FROM))
|
//Add to the identifier collection after filtering through the patch group manager
|
||||||
{
|
getIdentifierCollection().update(mPatchGroupManager.update(identifier));
|
||||||
//Add to the identifier collection after filtering through the patch group manager
|
|
||||||
getIdentifierCollection().update(mPatchGroupManager.update(identifier));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -484,11 +472,8 @@ public class P25P2DecoderState extends TimeslotDecoderState implements Identifie
|
|||||||
|
|
||||||
for(Identifier identifier : mac.getIdentifiers())
|
for(Identifier identifier : mac.getIdentifiers())
|
||||||
{
|
{
|
||||||
if(!(identifier.getForm() == Form.TALKGROUP && identifier.getRole() == Role.FROM))
|
//Add to the identifier collection after filtering through the patch group manager
|
||||||
{
|
getIdentifierCollection().update(mPatchGroupManager.update(identifier));
|
||||||
//Add to the identifier collection after filtering through the patch group manager
|
|
||||||
getIdentifierCollection().update(mPatchGroupManager.update(identifier));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ public enum TunerClass
|
|||||||
GIGABYTE_GTU7300( TunerType.FITIPOWER_FC0012, "1B80", "D393", "Gigabyte", "GT-U7300" ),
|
GIGABYTE_GTU7300( TunerType.FITIPOWER_FC0012, "1B80", "D393", "Gigabyte", "GT-U7300" ),
|
||||||
GTEK_T803( TunerType.FITIPOWER_FC0012, "1F4D", "B803", "GTek", "T803" ),
|
GTEK_T803( TunerType.FITIPOWER_FC0012, "1F4D", "B803", "GTek", "T803" ),
|
||||||
HACKRF_ONE( TunerType.HACKRF, "1D50", "6089", "Great Scott Gadgets", "HackRF One" ),
|
HACKRF_ONE( TunerType.HACKRF, "1D50", "6089", "Great Scott Gadgets", "HackRF One" ),
|
||||||
|
HACKRF_JAWBREAKER( TunerType.HACKRF, "1D50", "604B", "Great Scott Gadgets", "HackRF Jawbreaker" ),
|
||||||
RAD1O( TunerType.HACKRF, "1D50", "CC15", "Munich hackerspace", "Rad1o" ),
|
RAD1O( TunerType.HACKRF, "1D50", "CC15", "Munich hackerspace", "Rad1o" ),
|
||||||
LIFEVIEW_LV5T_DELUXE( TunerType.FITIPOWER_FC0012, "1F4D", "C803", "Liveview", "LV5T Deluxe" ),
|
LIFEVIEW_LV5T_DELUXE( TunerType.FITIPOWER_FC0012, "1F4D", "C803", "Liveview", "LV5T Deluxe" ),
|
||||||
MYGICA_TD312( TunerType.FITIPOWER_FC0012, "1F4D", "D286", "MyGica", "TD312" ),
|
MYGICA_TD312( TunerType.FITIPOWER_FC0012, "1F4D", "D286", "MyGica", "TD312" ),
|
||||||
@@ -196,6 +197,10 @@ public enum TunerClass
|
|||||||
{
|
{
|
||||||
retVal = HACKRF_ONE;
|
retVal = HACKRF_ONE;
|
||||||
}
|
}
|
||||||
|
else if( productID == 24651 ) //604B
|
||||||
|
{
|
||||||
|
retVal = HACKRF_JAWBREAKER;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 8013: //1F4D
|
case 8013: //1F4D
|
||||||
if( productID == 47107 ) //B803
|
if( productID == 47107 ) //B803
|
||||||
|
|||||||
@@ -304,6 +304,7 @@ public class TunerManager
|
|||||||
case FUNCUBE_DONGLE_PRO_PLUS:
|
case FUNCUBE_DONGLE_PRO_PLUS:
|
||||||
return initFuncubeProPlusTuner(device, descriptor);
|
return initFuncubeProPlusTuner(device, descriptor);
|
||||||
case HACKRF_ONE:
|
case HACKRF_ONE:
|
||||||
|
case HACKRF_JAWBREAKER:
|
||||||
case RAD1O:
|
case RAD1O:
|
||||||
return initHackRFTuner(device, descriptor);
|
return initHackRFTuner(device, descriptor);
|
||||||
case COMPRO_VIDEOMATE_U620F:
|
case COMPRO_VIDEOMATE_U620F:
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import io.github.dsheirer.source.SourceException;
|
|||||||
import io.github.dsheirer.source.tuner.configuration.TunerConfiguration;
|
import io.github.dsheirer.source.tuner.configuration.TunerConfiguration;
|
||||||
import io.github.dsheirer.source.tuner.usb.USBTransferProcessor;
|
import io.github.dsheirer.source.tuner.usb.USBTransferProcessor;
|
||||||
import io.github.dsheirer.source.tuner.usb.USBTunerController;
|
import io.github.dsheirer.source.tuner.usb.USBTunerController;
|
||||||
import io.github.dsheirer.source.tuner.usb.converter.ByteSampleConverter;
|
import io.github.dsheirer.source.tuner.usb.converter.SignedByteSampleConverter;
|
||||||
import io.github.dsheirer.source.tuner.usb.converter.NativeBufferConverter;
|
import io.github.dsheirer.source.tuner.usb.converter.NativeBufferConverter;
|
||||||
import org.apache.commons.io.EndianUtils;
|
import org.apache.commons.io.EndianUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@@ -60,7 +60,7 @@ public class HackRFTunerController extends USBTunerController
|
|||||||
public static final double USABLE_BANDWIDTH_PERCENT = 0.75;
|
public static final double USABLE_BANDWIDTH_PERCENT = 0.75;
|
||||||
public static final int DC_SPIKE_AVOID_BUFFER = 5000;
|
public static final int DC_SPIKE_AVOID_BUFFER = 5000;
|
||||||
|
|
||||||
private NativeBufferConverter mNativeBufferConverter = new ByteSampleConverter();
|
private NativeBufferConverter mNativeBufferConverter = new SignedByteSampleConverter();
|
||||||
private USBTransferProcessor mUSBTransferProcessor;
|
private USBTransferProcessor mUSBTransferProcessor;
|
||||||
|
|
||||||
private HackRFSampleRate mSampleRate = HackRFSampleRate.RATE2_016MHZ;
|
private HackRFSampleRate mSampleRate = HackRFSampleRate.RATE2_016MHZ;
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* sdr-trunk
|
||||||
|
* Copyright (C) 2014-2018 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 io.github.dsheirer.source.tuner.usb.converter;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.FloatBuffer;
|
||||||
|
|
||||||
|
public class SignedByteSampleConverter extends NativeBufferConverter
|
||||||
|
{
|
||||||
|
private final static float[] LOOKUP_VALUES;
|
||||||
|
|
||||||
|
//Creates a static lookup table that converts the signed 8-bit valued range from -128 to 127 into scaled float values
|
||||||
|
//of -1.0 to 0 to 1.0
|
||||||
|
static
|
||||||
|
{
|
||||||
|
LOOKUP_VALUES = new float[256];
|
||||||
|
|
||||||
|
for(int x = 0; x < 256; x++)
|
||||||
|
{
|
||||||
|
LOOKUP_VALUES[x] = (float)((byte)x) / 128.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private FloatBuffer mFloatBuffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts native byte buffers containing signed 8-bit complex samples into complex float samples loaded into a tracked,
|
||||||
|
* reusable complex sample buffer. Internally tracks the reusable buffer until all downstream consumers have finished
|
||||||
|
* processing the buffer contents and then reuses the buffer (and memory) for subsequent samples.
|
||||||
|
*/
|
||||||
|
public SignedByteSampleConverter()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts the signed 8-bit complex samples contained in the native buffer into floats that are loaded into a float
|
||||||
|
* buffer and subsequently transferred to a reusable complex buffer by the parent class.
|
||||||
|
*
|
||||||
|
* @param nativeBuffer containing signed 8-bit complex samples
|
||||||
|
* @param length of bytes to read from the native buffer
|
||||||
|
* @return float buffer loaded with converted samples
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected FloatBuffer convertSamples(ByteBuffer nativeBuffer, int length)
|
||||||
|
{
|
||||||
|
nativeBuffer.rewind();
|
||||||
|
|
||||||
|
if(mFloatBuffer == null || mFloatBuffer.capacity() != nativeBuffer.capacity())
|
||||||
|
{
|
||||||
|
mFloatBuffer = FloatBuffer.allocate(nativeBuffer.capacity());
|
||||||
|
}
|
||||||
|
|
||||||
|
mFloatBuffer.rewind();
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
while(nativeBuffer.hasRemaining() && count < length)
|
||||||
|
{
|
||||||
|
byte sample = nativeBuffer.get();
|
||||||
|
count++;
|
||||||
|
|
||||||
|
mFloatBuffer.put(LOOKUP_VALUES[(sample & 0xFF)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mFloatBuffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user