Compare commits

...

5 Commits

Author SHA1 Message Date
Denny Sheirer
2e37f1e687 Updates gradle wrapper to 6.3. Updates embeded java to JDK 14 for building platform releases. (#729)
Co-authored-by: Denny <denny@denny-desktop>
2020-04-04 09:22:13 -04:00
Denny Sheirer
5e8f2d0523 Updates build to 0.4.0 final and updates CHANGELOG revision history. (#727)
Co-authored-by: Denny <denny@denny-desktop>
2020-04-04 08:19:29 -04:00
crsawyer
9fb6c33319 Fix HackRF-JawBreaker and HackRF sample conversion (#725) 2020-04-04 08:02:17 -04:00
Denny Sheirer
fdecac4230 Resovles #721 Suppress RID values of 0. (#723)
Co-authored-by: Denny <denny@denny-desktop>
2020-04-01 05:05:28 -04:00
Denny Sheirer
85c27a6cca Resolves #719 P25 Phase 2 display channel number (#722)
Co-authored-by: Denny <denny@denny-desktop>
2020-04-01 03:28:26 -04:00
15 changed files with 192 additions and 86 deletions

2
.idea/misc.xml generated
View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<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" />
</component>
</project>

View File

@@ -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
- 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

View File

@@ -33,7 +33,7 @@ repositories {
maven { url "https://jitpack.io" }
}
version = '0.4.0-beta.8'
version = '0.4.0'
sourceCompatibility = '13'
sourceSets {
@@ -114,7 +114,7 @@ jar {
attributes (
'Implementation-Title' : 'sdrtrunk project',
'Implementation-Version' : archiveVersion,
'Class-Path' : 'jmbe-1.0.1.jar',
'Class-Path' : 'jmbe-1.0.4.jar',
'Created-By' : "Gradle ${gradle.gradleVersion}",
'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']}",
@@ -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
* 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_32 = '/media/denny/WD250GB/java/bellsoft/linux-x86/jdk-13.0.1'
def jdk_osx_x86_64 = '/media/denny/WD250GB/java/bellsoft/osx-x64/jdk-13.0.1.jdk'
def jdk_windows_x86_64 = '/media/denny/WD250GB/java/bellsoft/windows-x64/jdk-13.0.1'
def jdk_windows_x86_32 = '/media/denny/WD250GB/java/bellsoft/windows-x86/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-14'
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-14'
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_32 = new File(jdk_linux_x86_32)

Binary file not shown.

View File

@@ -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
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
zipStorePath=wrapper/dists

51
gradlew vendored
View File

@@ -1,5 +1,21 @@
#!/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
@@ -28,7 +44,7 @@ APP_NAME="Gradle"
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.
DEFAULT_JVM_OPTS='"-Xmx64m"'
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
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\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
@@ -138,19 +154,19 @@ if $cygwin ; then
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
i=`expr $i + 1`
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
@@ -159,14 +175,9 @@ save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
APP_ARGS=`save "$@"`
# 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"
# 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" "$@"

18
gradlew.bat vendored
View File

@@ -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
@rem ##########################################################################
@rem
@@ -14,7 +30,7 @@ set APP_BASE_NAME=%~n0
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.
set DEFAULT_JVM_OPTS="-Xmx64m"
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome

View File

@@ -37,6 +37,6 @@ public abstract class RadioIdentifier extends IntegerIdentifier
@Override
public boolean isValid()
{
return getValue() >= 0;
return getValue() > 0;
}
}

View File

@@ -189,25 +189,40 @@ public class P25Channel implements IChannelDescriptor
{
StringBuilder sb = new StringBuilder();
int downlinkChannelNumber = getDownlinkChannelNumber();
if(isTDMAChannel())
{
downlinkChannelNumber -= downlinkChannelNumber % getTimeslotCount();
}
if(getDownlinkBandIdentifier() == getUplinkBandIdentifier() && getDownlinkChannelNumber() == getUplinkChannelNumber())
{
sb.append(getDownlinkBandIdentifier()).append("-").append(getDownlinkLogicalChannelNumber());
sb.append(getDownlinkBandIdentifier()).append("-").append(downlinkChannelNumber);
}
else if(hasUplinkChannel())
{
int uplinkChannelNumber = getUplinkChannelNumber();
if(isTDMAChannel())
{
uplinkChannelNumber -= uplinkChannelNumber % getTimeslotCount();
}
sb.append(getDownlinkBandIdentifier())
.append("-")
.append(getDownlinkLogicalChannelNumber())
.append(downlinkChannelNumber)
.append("/")
.append(getUplinkBandIdentifier())
.append("-")
.append(getUplinkLogicalChannelNumber());
.append(uplinkChannelNumber);
}
else
{
sb.append(getDownlinkBandIdentifier())
.append("-")
.append(getDownlinkLogicalChannelNumber())
.append(downlinkChannelNumber)
.append("/-----");
}

View File

@@ -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.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 java.util.ArrayList;
@@ -94,7 +94,7 @@ public class LCMotorolaTalkComplete extends LinkControlWord
{
if(mAddress == null)
{
mAddress = APCO25Talkgroup.create(getMessage().getInt(ADDRESS));
mAddress = APCO25RadioIdentifier.createFrom(getMessage().getInt(ADDRESS));
}
return mAddress;

View File

@@ -336,11 +336,8 @@ public class P25P2DecoderState extends TimeslotDecoderState implements Identifie
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
@@ -373,11 +370,8 @@ public class P25P2DecoderState extends TimeslotDecoderState implements Identifie
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
@@ -410,11 +404,8 @@ public class P25P2DecoderState extends TimeslotDecoderState implements Identifie
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
@@ -447,11 +438,8 @@ public class P25P2DecoderState extends TimeslotDecoderState implements Identifie
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
@@ -484,11 +472,8 @@ public class P25P2DecoderState extends TimeslotDecoderState implements Identifie
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

View File

@@ -40,6 +40,7 @@ public enum TunerClass
GIGABYTE_GTU7300( TunerType.FITIPOWER_FC0012, "1B80", "D393", "Gigabyte", "GT-U7300" ),
GTEK_T803( TunerType.FITIPOWER_FC0012, "1F4D", "B803", "GTek", "T803" ),
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" ),
LIFEVIEW_LV5T_DELUXE( TunerType.FITIPOWER_FC0012, "1F4D", "C803", "Liveview", "LV5T Deluxe" ),
MYGICA_TD312( TunerType.FITIPOWER_FC0012, "1F4D", "D286", "MyGica", "TD312" ),
@@ -196,6 +197,10 @@ public enum TunerClass
{
retVal = HACKRF_ONE;
}
else if( productID == 24651 ) //604B
{
retVal = HACKRF_JAWBREAKER;
}
break;
case 8013: //1F4D
if( productID == 47107 ) //B803

View File

@@ -304,6 +304,7 @@ public class TunerManager
case FUNCUBE_DONGLE_PRO_PLUS:
return initFuncubeProPlusTuner(device, descriptor);
case HACKRF_ONE:
case HACKRF_JAWBREAKER:
case RAD1O:
return initHackRFTuner(device, descriptor);
case COMPRO_VIDEOMATE_U620F:

View File

@@ -25,7 +25,7 @@ import io.github.dsheirer.source.SourceException;
import io.github.dsheirer.source.tuner.configuration.TunerConfiguration;
import io.github.dsheirer.source.tuner.usb.USBTransferProcessor;
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 org.apache.commons.io.EndianUtils;
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 int DC_SPIKE_AVOID_BUFFER = 5000;
private NativeBufferConverter mNativeBufferConverter = new ByteSampleConverter();
private NativeBufferConverter mNativeBufferConverter = new SignedByteSampleConverter();
private USBTransferProcessor mUSBTransferProcessor;
private HackRFSampleRate mSampleRate = HackRFSampleRate.RATE2_016MHZ;

View File

@@ -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;
}
}