mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-12 08:37:25 -05:00
Compare commits
26 Commits
v0.6.0-bet
...
v0.6.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
09e19e1486 | ||
|
|
0f5478925c | ||
|
|
09dce0b0d1 | ||
|
|
ad98b1cb5e | ||
|
|
8effd97749 | ||
|
|
9dbed72c32 | ||
|
|
b4dd3692b8 | ||
|
|
030cbb856c | ||
|
|
511101e9b7 | ||
|
|
60dd2b2df7 | ||
|
|
218dc94e02 | ||
|
|
2440f578b1 | ||
|
|
09c87237cb | ||
|
|
3d974ddd91 | ||
|
|
1489c970ba | ||
|
|
9e0afca3d1 | ||
|
|
99eda4013e | ||
|
|
a62f81f890 | ||
|
|
66f0731731 | ||
|
|
dc239801c6 | ||
|
|
d4ba0988bc | ||
|
|
ad0f953b2a | ||
|
|
e1bc9eabd6 | ||
|
|
d3dc1a8667 | ||
|
|
bf278120de | ||
|
|
2f52f6e009 |
2
.github/workflows/gradle.yml
vendored
2
.github/workflows/gradle.yml
vendored
@@ -21,7 +21,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up JDK 20
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
|
||||
47
.github/workflows/nightly.yml
vendored
Normal file
47
.github/workflows/nightly.yml
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
# Create nightly release for Linux, Mac and Windows using the Linux runner.
|
||||
name: Nightly Release
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
# Don't run nightly build for pull requests - uncomment to test changes to this action within scope of the PR review
|
||||
# pull_request:
|
||||
# branches: [ master ]
|
||||
|
||||
jobs:
|
||||
nightly:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up JDK 20
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: '20'
|
||||
distribution: 'liberica'
|
||||
java-package: 'jdk+fx'
|
||||
|
||||
- name: Build Linux and Mac releases with Gradle
|
||||
uses: gradle/gradle-build-action@v2
|
||||
with:
|
||||
arguments: runtimeZipOthers -PprojectVersion=nightly
|
||||
|
||||
- name: Build Windows release with Gradle
|
||||
uses: gradle/gradle-build-action@v2
|
||||
with:
|
||||
arguments: runtimeZipWindows -PprojectVersion=nightly
|
||||
|
||||
- name: Create Build Info file
|
||||
run: |
|
||||
echo -e "ref: $GITHUB_REF \ncommit: $GITHUB_SHA\nbuild: $(date +"%Y-%m-%dT%H:%M:%SZ")" > build/image/build_info.txt
|
||||
|
||||
- name: Add build artifacts to nightly release
|
||||
uses: pyTooling/Actions/releaser@main
|
||||
with:
|
||||
tag: nightly
|
||||
rm: false
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
files: |
|
||||
build/image/*.zip
|
||||
build/image/build_info.txt
|
||||
@@ -1,8 +1,10 @@
|
||||

|
||||

|
||||
|
||||
# sdrtrunk
|
||||
A cross-platform java application for decoding, monitoring, recording and streaming trunked mobile and related radio protocols using Software Defined Radios (SDR).
|
||||
|
||||
* [Help/Wiki Home Page](https://github.com/DSheirer/sdrtrunk/wiki)
|
||||
* [Getting Started](https://github.com/DSheirer/sdrtrunk/wiki/Getting-Started)
|
||||
* [User's Manual](https://github.com/DSheirer/sdrtrunk/wiki/User-Manual)
|
||||
* [Download](https://github.com/DSheirer/sdrtrunk/releases)
|
||||
@@ -18,6 +20,13 @@ All release versions of sdrtrunk are available from the [releases](https://githu
|
||||
* **(beta)** These versions are currently being tested for bugs and functionality prior to final release.
|
||||
* **(final)** These versions have been tested and are the current release version.
|
||||
|
||||
## Download Nightly Software Build
|
||||
The [nightly](https://github.com/DSheirer/sdrtrunk/releases/tag/nightly) release contains current builds of the software
|
||||
for all supported operating systems. This version of the software may contain bugs and may not run correctly. However,
|
||||
it let's you preview the most recent changes and fixes before the next software release. **Always backup your
|
||||
playlist(s) before you use the nightly builds.** Note: the nightly release is updated each time code changes are
|
||||
committed to the code base, so it's not really 'nightly' as much as it is 'current'.
|
||||
|
||||
## Minimum System Requirements
|
||||
* **Operating System:** Windows (~~32 or~~ 64-bit), Linux (~~32 or~~ 64-bit) or Mac/Linux (64-bit, 10.14 or higher)
|
||||
* **CPU:** 4-core
|
||||
|
||||
@@ -53,8 +53,8 @@ repositories {
|
||||
maven { url "https://jitpack.io" }
|
||||
}
|
||||
|
||||
//Note: this should match the GitLab release tag.
|
||||
version = '0.6.0-beta-3'
|
||||
//Version is defined in gradle.properties so that we can CLI override it for nightly builds.
|
||||
version = project.findProperty('projectVersion')
|
||||
|
||||
//Java 20 is required for this version of the Project Panama preview/incubator feature
|
||||
java {
|
||||
|
||||
29
gradle.properties
Normal file
29
gradle.properties
Normal file
@@ -0,0 +1,29 @@
|
||||
#
|
||||
# ******************************************************************************
|
||||
# Copyright (C) 2014-2023 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/>
|
||||
# *****************************************************************************
|
||||
#
|
||||
|
||||
# Version naming conventions:
|
||||
# Alpha: maj.min.patch-alpha-build
|
||||
# Beta: maj.min.patch-beta-build
|
||||
# Release: maj.min.patch
|
||||
#
|
||||
# Note: this is so that the file names for the resultant release build products match the GitLab release asset
|
||||
# tag name, specifically the dashes inserted before and after the alpha/beta labels.
|
||||
# See: https://github.com/DSheirer/sdrtrunk/issues/1651
|
||||
|
||||
projectVersion=0.6.0-beta-4
|
||||
@@ -232,6 +232,9 @@ public class RdioScannerBroadcaster extends AbstractAudioBroadcaster<RdioScanner
|
||||
String talkgroupLabel = getTalkgroupLabel(audioRecording);
|
||||
String talkgroupGroup = getTalkgroupGroup(audioRecording);
|
||||
String systemLabel = getSystemLabel(audioRecording);
|
||||
String path = audioRecording.getPath().toString();
|
||||
// Remove TEMPORARY_STREAM_FILE_SUFFIX
|
||||
String audioName = path.substring(path.substring(0, path.lastIndexOf("_")).lastIndexOf("_") + 1);
|
||||
|
||||
try
|
||||
{
|
||||
@@ -252,6 +255,7 @@ public class RdioScannerBroadcaster extends AbstractAudioBroadcaster<RdioScanner
|
||||
RdioScannerBuilder bodyBuilder = new RdioScannerBuilder();
|
||||
bodyBuilder.addPart(FormField.KEY, getBroadcastConfiguration().getApiKey())
|
||||
.addPart(FormField.SYSTEM, getBroadcastConfiguration().getSystemID())
|
||||
.addAudioName(audioName)
|
||||
.addFile(audioBytes)
|
||||
.addPart(FormField.DATE_TIME, timestampSeconds)
|
||||
.addPart(FormField.TALKGROUP_ID, talkgroup)
|
||||
|
||||
@@ -34,7 +34,8 @@ public class RdioScannerBuilder
|
||||
private static final String DASH_DASH = "--";
|
||||
private static final String BOUNDARY = "--sdrtrunk-sdrtrunk-sdrtrunk";
|
||||
private List<Part> mParts = new ArrayList<>();
|
||||
private byte[] audioBytes = null;
|
||||
private byte[] audioBytes = null;
|
||||
private String audioName = null;
|
||||
|
||||
/**
|
||||
* Constructs an instance
|
||||
@@ -51,6 +52,15 @@ public class RdioScannerBuilder
|
||||
return BOUNDARY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a Audio file name part to the call
|
||||
*/
|
||||
public RdioScannerBuilder addAudioName(String value)
|
||||
{
|
||||
audioName = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a Audio bytes part to the call
|
||||
*/
|
||||
@@ -110,7 +120,8 @@ public class RdioScannerBuilder
|
||||
}
|
||||
StringBuilder sb= new StringBuilder();
|
||||
sb.append(DASH_DASH).append(boundary).append("\r\n");
|
||||
sb.append("Content-Disposition: form-data; name=\"").append("audio").append("\"\r\n\r\n");
|
||||
sb.append("Content-Disposition: form-data; filename =\"").append(audioName);
|
||||
sb.append("\"; name=\"").append("audio").append("\"\r\n\r\n");
|
||||
return sb.toString();
|
||||
|
||||
}
|
||||
|
||||
@@ -68,8 +68,8 @@ public class ComplexPolyphaseChannelizerM2 extends AbstractComplexPolyphaseChann
|
||||
*/
|
||||
private static final int PROCESSED_CHANNEL_RESULTS_THRESHOLD = 1024;
|
||||
|
||||
//Sized to process 1/20th batch of 152 buffers a second, at 40 times per second
|
||||
private IFFTProcessorDispatcher mIFFTProcessorDispatcher = new IFFTProcessorDispatcher(152 / 20, 25);
|
||||
//Sized to process 40 times per second
|
||||
private IFFTProcessorDispatcher mIFFTProcessorDispatcher = new IFFTProcessorDispatcher(25);
|
||||
private FloatFFT_1D mFFT;
|
||||
private float[] mInlineSamples;
|
||||
private float[] mInlineFilter;
|
||||
@@ -406,9 +406,9 @@ public class ComplexPolyphaseChannelizerM2 extends AbstractComplexPolyphaseChann
|
||||
*/
|
||||
public class IFFTProcessorDispatcher extends Dispatcher<List<float[]>>
|
||||
{
|
||||
public IFFTProcessorDispatcher(int batchSize, long interval)
|
||||
public IFFTProcessorDispatcher(long interval)
|
||||
{
|
||||
super("sdrtrunk polyphase ifft processor", batchSize, interval);
|
||||
super("sdrtrunk polyphase ifft processor", interval);
|
||||
|
||||
//We create a listener interface to receive the batched channel results arrays from the scheduled thread pool
|
||||
//dispatcher thread that is part of this continuous buffer processor. We perform an IFFT on each
|
||||
|
||||
@@ -110,7 +110,7 @@ public class PolyphaseChannelManager implements ISourceEventProcessor
|
||||
}
|
||||
|
||||
mChannelCalculator = new ChannelCalculator(sampleRate, channelCount, frequency, CHANNEL_OVERSAMPLING);
|
||||
mBufferDispatcher = new Dispatcher("sdrtrunk polyphase buffer processor", 50, 10);
|
||||
mBufferDispatcher = new Dispatcher("sdrtrunk polyphase buffer processor", 10);
|
||||
mBufferDispatcher.setListener(mNativeBufferReceiver);
|
||||
}
|
||||
|
||||
|
||||
@@ -50,8 +50,7 @@ public abstract class ChannelOutputProcessor implements IPolyphaseChannelOutputP
|
||||
mInputChannelCount = inputChannelCount;
|
||||
//Process 1/10th of the sample rate per second at a rate of 20 times a second (200% of anticipated rate)
|
||||
mHeartbeatManager = heartbeatManager;
|
||||
mChannelResultsDispatcher = new Dispatcher("sdrtrunk polyphase channel", (int)(sampleRate / 10),
|
||||
50, mHeartbeatManager);
|
||||
mChannelResultsDispatcher = new Dispatcher("sdrtrunk polyphase channel",50, mHeartbeatManager);
|
||||
mChannelResultsDispatcher.setListener(floats -> {
|
||||
try
|
||||
{
|
||||
|
||||
@@ -1,33 +1,29 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2023 Dennis Sheirer
|
||||
*
|
||||
* * ******************************************************************************
|
||||
* * Copyright (C) 2014-2020 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/>
|
||||
* * *****************************************************************************
|
||||
* 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.gui.control;
|
||||
|
||||
import java.util.function.UnaryOperator;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.control.TextFormatter;
|
||||
import javafx.util.converter.IntegerStringConverter;
|
||||
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
/**
|
||||
* Text field control for integer values.
|
||||
*/
|
||||
@@ -52,7 +48,7 @@ public class IntegerTextField extends TextField
|
||||
return null;
|
||||
};
|
||||
|
||||
setTextFormatter(new TextFormatter<Integer>(new IntegerStringConverter(), 0, filter));
|
||||
setTextFormatter(new TextFormatter<Integer>(new IntegerStringConverter(), null, filter));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -71,7 +67,7 @@ public class IntegerTextField extends TextField
|
||||
//Do nothing ... we couldn't parse the value
|
||||
}
|
||||
|
||||
return null;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -92,9 +92,9 @@ public class AMConfigurationEditor extends ChannelConfigurationEditor
|
||||
* @param userPreferences for preferences
|
||||
*/
|
||||
public AMConfigurationEditor(PlaylistManager playlistManager, TunerManager tunerManager,
|
||||
UserPreferences userPreferences)
|
||||
UserPreferences userPreferences, IFilterProcessor filterProcessor)
|
||||
{
|
||||
super(playlistManager, tunerManager, userPreferences);
|
||||
super(playlistManager, tunerManager, userPreferences, filterProcessor);
|
||||
getTitledPanesBox().getChildren().add(getSourcePane());
|
||||
getTitledPanesBox().getChildren().add(getDecoderPane());
|
||||
getTitledPanesBox().getChildren().add(getEventLogPane());
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||
* Copyright (C) 2014-2023 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
|
||||
@@ -38,6 +38,8 @@ import io.github.dsheirer.source.config.SourceConfigTuner;
|
||||
import io.github.dsheirer.source.config.SourceConfiguration;
|
||||
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||
import io.github.dsheirer.util.ThreadPool;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Predicate;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
@@ -69,9 +71,6 @@ import org.controlsfx.control.ToggleSwitch;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* Channel configuration editor
|
||||
*/
|
||||
@@ -100,6 +99,7 @@ public abstract class ChannelConfigurationEditor extends Editor<Channel>
|
||||
private IconNode mPlayGraphicNode;
|
||||
private IconNode mStopGraphicNode;
|
||||
private ChannelProcessingMonitor mChannelProcessingMonitor = new ChannelProcessingMonitor();
|
||||
private IFilterProcessor mFilterProcessor;
|
||||
|
||||
/**
|
||||
* Constructs an instance
|
||||
@@ -108,11 +108,12 @@ public abstract class ChannelConfigurationEditor extends Editor<Channel>
|
||||
* @param userPreferences for preferences
|
||||
*/
|
||||
public ChannelConfigurationEditor(PlaylistManager playlistManager, TunerManager tunerManager,
|
||||
UserPreferences userPreferences)
|
||||
UserPreferences userPreferences, IFilterProcessor filterProcessor)
|
||||
{
|
||||
mPlaylistManager = playlistManager;
|
||||
mTunerManager = tunerManager;
|
||||
mUserPreferences = userPreferences;
|
||||
mFilterProcessor = filterProcessor;
|
||||
|
||||
setMaxWidth(Double.MAX_VALUE);
|
||||
|
||||
@@ -689,7 +690,16 @@ public abstract class ChannelConfigurationEditor extends Editor<Channel>
|
||||
mSaveButton.setMaxWidth(Double.MAX_VALUE);
|
||||
mSaveButton.disableProperty().bind(modifiedProperty().not());
|
||||
mSaveButton.setOnAction(event -> {
|
||||
save();
|
||||
if(mFilterProcessor != null)
|
||||
{
|
||||
mFilterProcessor.clearFilter();
|
||||
save();
|
||||
mFilterProcessor.restoreFilter();
|
||||
}
|
||||
else
|
||||
{
|
||||
save();
|
||||
}
|
||||
|
||||
if(getItem().isProcessing())
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||
* Copyright (C) 2014-2023 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
|
||||
@@ -23,11 +23,10 @@ import io.github.dsheirer.module.decode.DecoderType;
|
||||
import io.github.dsheirer.playlist.PlaylistManager;
|
||||
import io.github.dsheirer.preference.UserPreferences;
|
||||
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Provides access to channel configuration editors for various decoder types.
|
||||
@@ -41,31 +40,35 @@ public class ChannelConfigurationEditorFactory
|
||||
* Constructs an editor for the specified decoder type
|
||||
* @param decoderType to create
|
||||
* @param playlistManager for the editor
|
||||
* @param tunerManager for tuners
|
||||
* @param userPreferences for preferences
|
||||
* @param filterProcessor to be notified to clear and restore any applied filters.
|
||||
* @return constructed editor
|
||||
*/
|
||||
public static ChannelConfigurationEditor getEditor(DecoderType decoderType, PlaylistManager playlistManager,
|
||||
TunerManager tunerManager, UserPreferences userPreferences)
|
||||
TunerManager tunerManager, UserPreferences userPreferences,
|
||||
IFilterProcessor filterProcessor)
|
||||
{
|
||||
switch(decoderType)
|
||||
{
|
||||
case AM:
|
||||
return new AMConfigurationEditor(playlistManager, tunerManager, userPreferences);
|
||||
return new AMConfigurationEditor(playlistManager, tunerManager, userPreferences, filterProcessor);
|
||||
case DMR:
|
||||
return new DMRConfigurationEditor(playlistManager, tunerManager, userPreferences);
|
||||
return new DMRConfigurationEditor(playlistManager, tunerManager, userPreferences, filterProcessor);
|
||||
case NBFM:
|
||||
return new NBFMConfigurationEditor(playlistManager, tunerManager, userPreferences);
|
||||
return new NBFMConfigurationEditor(playlistManager, tunerManager, userPreferences, filterProcessor);
|
||||
case LTR_NET:
|
||||
return new LTRNetConfigurationEditor(playlistManager, tunerManager, userPreferences);
|
||||
return new LTRNetConfigurationEditor(playlistManager, tunerManager, userPreferences, filterProcessor);
|
||||
case LTR:
|
||||
return new LTRConfigurationEditor(playlistManager, tunerManager, userPreferences);
|
||||
return new LTRConfigurationEditor(playlistManager, tunerManager, userPreferences, filterProcessor);
|
||||
case MPT1327:
|
||||
return new MPT1327ConfigurationEditor(playlistManager, tunerManager, userPreferences);
|
||||
return new MPT1327ConfigurationEditor(playlistManager, tunerManager, userPreferences, filterProcessor);
|
||||
case PASSPORT:
|
||||
return new PassportConfigurationEditor(playlistManager, tunerManager, userPreferences);
|
||||
return new PassportConfigurationEditor(playlistManager, tunerManager, userPreferences, filterProcessor);
|
||||
case P25_PHASE1:
|
||||
return new P25P1ConfigurationEditor(playlistManager, tunerManager, userPreferences);
|
||||
return new P25P1ConfigurationEditor(playlistManager, tunerManager, userPreferences, filterProcessor);
|
||||
case P25_PHASE2:
|
||||
return new P25P2ConfigurationEditor(playlistManager, tunerManager, userPreferences);
|
||||
return new P25P2ConfigurationEditor(playlistManager, tunerManager, userPreferences, filterProcessor);
|
||||
default:
|
||||
if(decoderType != null && !mLoggedUnrecognizedTypes.contains(decoderType))
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||
* Copyright (C) 2014-2023 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
|
||||
@@ -26,6 +26,12 @@ import io.github.dsheirer.module.decode.DecoderType;
|
||||
import io.github.dsheirer.playlist.PlaylistManager;
|
||||
import io.github.dsheirer.preference.UserPreferences;
|
||||
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Predicate;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
@@ -63,17 +69,10 @@ import org.controlsfx.control.textfield.TextFields;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* JavaFX editor for managing channel configurations.
|
||||
*/
|
||||
public class ChannelEditor extends SplitPane
|
||||
public class ChannelEditor extends SplitPane implements IFilterProcessor
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger(ChannelEditor.class);
|
||||
private PlaylistManager mPlaylistManager;
|
||||
@@ -106,7 +105,8 @@ public class ChannelEditor extends SplitPane
|
||||
mPlaylistManager = playlistManager;
|
||||
mTunerManager = tunerManager;
|
||||
mUserPreferences = userPreferences;
|
||||
mUnknownConfigurationEditor = new UnknownConfigurationEditor(mPlaylistManager, mTunerManager, userPreferences);
|
||||
mUnknownConfigurationEditor = new UnknownConfigurationEditor(mPlaylistManager, mTunerManager,
|
||||
userPreferences, this);
|
||||
|
||||
HBox channelsBox = new HBox();
|
||||
channelsBox.setSpacing(10.0);
|
||||
@@ -203,7 +203,7 @@ public class ChannelEditor extends SplitPane
|
||||
if(editor == null)
|
||||
{
|
||||
editor = ChannelConfigurationEditorFactory.getEditor(channelDecoderType, mPlaylistManager,
|
||||
mTunerManager, mUserPreferences);
|
||||
mTunerManager, mUserPreferences, this);
|
||||
|
||||
if(editor != null)
|
||||
{
|
||||
@@ -374,6 +374,24 @@ public class ChannelEditor extends SplitPane
|
||||
mChannelFilteredList.setPredicate(mChannelListFilter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Temporarily clear the filter when the channel configuration editor is applying changes.
|
||||
*/
|
||||
@Override
|
||||
public void clearFilter()
|
||||
{
|
||||
mChannelFilteredList.setPredicate(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore the filter once the channel configuration editor has completed applying changes.
|
||||
*/
|
||||
@Override
|
||||
public void restoreFilter()
|
||||
{
|
||||
mChannelFilteredList.setPredicate(mChannelListFilter);
|
||||
}
|
||||
|
||||
private TableView<Channel> getChannelTableView()
|
||||
{
|
||||
if(mChannelTableView == null)
|
||||
@@ -449,6 +467,25 @@ public class ChannelEditor extends SplitPane
|
||||
nameColumn.setPrefWidth(200);
|
||||
|
||||
TableColumn frequencyColumn = new TableColumn("Frequency");
|
||||
frequencyColumn.setComparator((o1, o2) -> {
|
||||
if(o1 instanceof Channel c1 && o2 instanceof Channel c2)
|
||||
{
|
||||
if(!c1.getFrequencyList().isEmpty() && !c2.getFrequencyList().isEmpty())
|
||||
{
|
||||
return Long.compare(c1.getFrequencyList().get(0), c2.getFrequencyList().get(0));
|
||||
}
|
||||
else if(!c1.getFrequencyList().isEmpty())
|
||||
{
|
||||
return Long.compare(c1.getFrequencyList().get(0), 0l);
|
||||
}
|
||||
else if(!c2.getFrequencyList().isEmpty())
|
||||
{
|
||||
return Long.compare(0l, c2.getFrequencyList().get(0));
|
||||
}
|
||||
}
|
||||
|
||||
return Integer.compare(o1.hashCode(), o2.hashCode());
|
||||
});
|
||||
frequencyColumn.setCellValueFactory(new FrequencyCellValueFactory());
|
||||
frequencyColumn.setPrefWidth(100);
|
||||
|
||||
|
||||
@@ -99,9 +99,9 @@ public class DMRConfigurationEditor extends ChannelConfigurationEditor
|
||||
* @param userPreferences for preferences
|
||||
*/
|
||||
public DMRConfigurationEditor(PlaylistManager playlistManager, TunerManager tunerManager,
|
||||
UserPreferences userPreferences)
|
||||
UserPreferences userPreferences, IFilterProcessor filterProcessor)
|
||||
{
|
||||
super(playlistManager, tunerManager, userPreferences);
|
||||
super(playlistManager, tunerManager, userPreferences, filterProcessor);
|
||||
getTitledPanesBox().getChildren().add(getSourcePane());
|
||||
getTitledPanesBox().getChildren().add(getDecoderPane());
|
||||
getTitledPanesBox().getChildren().add(getEventLogPane());
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2023 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.gui.playlist.channel;
|
||||
|
||||
/**
|
||||
* Interface for a processor that implements a filtering mechanism and can be commanded by an external controller to
|
||||
* temporarily clear a filter and then restore the filter.
|
||||
*/
|
||||
public interface IFilterProcessor
|
||||
{
|
||||
void clearFilter();
|
||||
void restoreFilter();
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||
* Copyright (C) 2014-2023 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
|
||||
@@ -37,6 +37,8 @@ import io.github.dsheirer.record.RecorderType;
|
||||
import io.github.dsheirer.record.config.RecordConfiguration;
|
||||
import io.github.dsheirer.source.config.SourceConfiguration;
|
||||
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javafx.geometry.HPos;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.control.Label;
|
||||
@@ -50,9 +52,6 @@ import org.controlsfx.control.SegmentedButton;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* LTR (standard) channel configuration editor
|
||||
*/
|
||||
@@ -77,9 +76,9 @@ public class LTRConfigurationEditor extends ChannelConfigurationEditor
|
||||
* @param userPreferences for preferences
|
||||
*/
|
||||
public LTRConfigurationEditor(PlaylistManager playlistManager, TunerManager tunerManager,
|
||||
UserPreferences userPreferences)
|
||||
UserPreferences userPreferences, IFilterProcessor filterProcessor)
|
||||
{
|
||||
super(playlistManager, tunerManager, userPreferences);
|
||||
super(playlistManager, tunerManager, userPreferences, filterProcessor);
|
||||
getTitledPanesBox().getChildren().add(getSourcePane());
|
||||
getTitledPanesBox().getChildren().add(getDecoderPane());
|
||||
getTitledPanesBox().getChildren().add(getAuxDecoderPane());
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||
* Copyright (C) 2014-2023 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
|
||||
@@ -37,6 +37,8 @@ import io.github.dsheirer.record.RecorderType;
|
||||
import io.github.dsheirer.record.config.RecordConfiguration;
|
||||
import io.github.dsheirer.source.config.SourceConfiguration;
|
||||
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javafx.geometry.HPos;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.control.Label;
|
||||
@@ -50,9 +52,6 @@ import org.controlsfx.control.SegmentedButton;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* LTR-Net channel configuration editor
|
||||
*/
|
||||
@@ -76,9 +75,10 @@ public class LTRNetConfigurationEditor extends ChannelConfigurationEditor
|
||||
* @param tunerManager for tuners
|
||||
* @param userPreferences for preferences
|
||||
*/
|
||||
public LTRNetConfigurationEditor(PlaylistManager playlistManager, TunerManager tunerManager, UserPreferences userPreferences)
|
||||
public LTRNetConfigurationEditor(PlaylistManager playlistManager, TunerManager tunerManager,
|
||||
UserPreferences userPreferences, IFilterProcessor filterProcessor)
|
||||
{
|
||||
super(playlistManager, tunerManager, userPreferences);
|
||||
super(playlistManager, tunerManager, userPreferences, filterProcessor);
|
||||
getTitledPanesBox().getChildren().add(getSourcePane());
|
||||
getTitledPanesBox().getChildren().add(getDecoderPane());
|
||||
getTitledPanesBox().getChildren().add(getAuxDecoderPane());
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||
* Copyright (C) 2014-2023 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
|
||||
@@ -38,6 +38,8 @@ import io.github.dsheirer.record.RecorderType;
|
||||
import io.github.dsheirer.record.config.RecordConfiguration;
|
||||
import io.github.dsheirer.source.config.SourceConfiguration;
|
||||
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.geometry.HPos;
|
||||
@@ -56,9 +58,6 @@ import javafx.scene.layout.VBox;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static io.github.dsheirer.module.decode.config.DecodeConfiguration.CALL_TIMEOUT_MAXIMUM;
|
||||
import static io.github.dsheirer.module.decode.config.DecodeConfiguration.CALL_TIMEOUT_MINIMUM;
|
||||
|
||||
@@ -87,9 +86,9 @@ public class MPT1327ConfigurationEditor extends ChannelConfigurationEditor
|
||||
* @param userPreferences for preferences
|
||||
*/
|
||||
public MPT1327ConfigurationEditor(PlaylistManager playlistManager, TunerManager tunerManager,
|
||||
UserPreferences userPreferences)
|
||||
UserPreferences userPreferences, IFilterProcessor filterProcessor)
|
||||
{
|
||||
super(playlistManager, tunerManager, userPreferences);
|
||||
super(playlistManager, tunerManager, userPreferences, filterProcessor);
|
||||
getTitledPanesBox().getChildren().add(getSourcePane());
|
||||
getTitledPanesBox().getChildren().add(getDecoderPane());
|
||||
getTitledPanesBox().getChildren().add(getEventLogPane());
|
||||
|
||||
@@ -27,7 +27,6 @@ import io.github.dsheirer.gui.playlist.eventlog.EventLogConfigurationEditor;
|
||||
import io.github.dsheirer.gui.playlist.source.FrequencyEditor;
|
||||
import io.github.dsheirer.gui.playlist.source.SourceConfigurationEditor;
|
||||
import io.github.dsheirer.module.decode.DecoderType;
|
||||
import io.github.dsheirer.module.decode.analog.DecodeConfigAnalog;
|
||||
import io.github.dsheirer.module.decode.config.AuxDecodeConfiguration;
|
||||
import io.github.dsheirer.module.decode.config.DecodeConfiguration;
|
||||
import io.github.dsheirer.module.decode.nbfm.DecodeConfigNBFM;
|
||||
@@ -41,6 +40,8 @@ import io.github.dsheirer.record.RecorderType;
|
||||
import io.github.dsheirer.record.config.RecordConfiguration;
|
||||
import io.github.dsheirer.source.config.SourceConfiguration;
|
||||
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.collections.ListChangeListener;
|
||||
@@ -58,9 +59,6 @@ import javafx.scene.text.TextAlignment;
|
||||
import org.controlsfx.control.SegmentedButton;
|
||||
import org.controlsfx.control.ToggleSwitch;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Narrow-Band FM channel configuration editor
|
||||
*/
|
||||
@@ -95,9 +93,9 @@ public class NBFMConfigurationEditor extends ChannelConfigurationEditor
|
||||
* @param userPreferences for preferences
|
||||
*/
|
||||
public NBFMConfigurationEditor(PlaylistManager playlistManager, TunerManager tunerManager,
|
||||
UserPreferences userPreferences)
|
||||
UserPreferences userPreferences, IFilterProcessor filterProcessor)
|
||||
{
|
||||
super(playlistManager, tunerManager, userPreferences);
|
||||
super(playlistManager, tunerManager, userPreferences, filterProcessor);
|
||||
getTitledPanesBox().getChildren().add(getSourcePane());
|
||||
getTitledPanesBox().getChildren().add(getDecoderPane());
|
||||
getTitledPanesBox().getChildren().add(getAuxDecoderPane());
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||
* Copyright (C) 2014-2023 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
|
||||
@@ -36,6 +36,8 @@ import io.github.dsheirer.record.RecorderType;
|
||||
import io.github.dsheirer.record.config.RecordConfiguration;
|
||||
import io.github.dsheirer.source.config.SourceConfiguration;
|
||||
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.geometry.HPos;
|
||||
@@ -54,9 +56,6 @@ import org.controlsfx.control.ToggleSwitch;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* P25 Phase 1 channel configuration editor
|
||||
*/
|
||||
@@ -83,9 +82,9 @@ public class P25P1ConfigurationEditor extends ChannelConfigurationEditor
|
||||
* @param userPreferences for preferences
|
||||
*/
|
||||
public P25P1ConfigurationEditor(PlaylistManager playlistManager, TunerManager tunerManager,
|
||||
UserPreferences userPreferences)
|
||||
UserPreferences userPreferences, IFilterProcessor filterProcessor)
|
||||
{
|
||||
super(playlistManager, tunerManager, userPreferences);
|
||||
super(playlistManager, tunerManager, userPreferences, filterProcessor);
|
||||
getTitledPanesBox().getChildren().add(getSourcePane());
|
||||
getTitledPanesBox().getChildren().add(getDecoderPane());
|
||||
getTitledPanesBox().getChildren().add(getEventLogPane());
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||
* Copyright (C) 2014-2023 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
|
||||
@@ -37,6 +37,8 @@ import io.github.dsheirer.record.RecorderType;
|
||||
import io.github.dsheirer.record.config.RecordConfiguration;
|
||||
import io.github.dsheirer.source.config.SourceConfiguration;
|
||||
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javafx.geometry.HPos;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.control.Label;
|
||||
@@ -46,9 +48,6 @@ import javafx.scene.layout.VBox;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* P25 Phase 2 channel configuration editor
|
||||
*/
|
||||
@@ -72,9 +71,9 @@ public class P25P2ConfigurationEditor extends ChannelConfigurationEditor
|
||||
* @param userPreferences
|
||||
*/
|
||||
public P25P2ConfigurationEditor(PlaylistManager playlistManager, TunerManager tunerManager,
|
||||
UserPreferences userPreferences)
|
||||
UserPreferences userPreferences, IFilterProcessor filterProcessor)
|
||||
{
|
||||
super(playlistManager, tunerManager, userPreferences);
|
||||
super(playlistManager, tunerManager, userPreferences, filterProcessor);
|
||||
getTitledPanesBox().getChildren().add(getSourcePane());
|
||||
getTitledPanesBox().getChildren().add(getDecoderPane());
|
||||
getTitledPanesBox().getChildren().add(getEventLogPane());
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||
* Copyright (C) 2014-2023 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
|
||||
@@ -36,6 +36,8 @@ import io.github.dsheirer.record.RecorderType;
|
||||
import io.github.dsheirer.record.config.RecordConfiguration;
|
||||
import io.github.dsheirer.source.config.SourceConfiguration;
|
||||
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TitledPane;
|
||||
@@ -43,9 +45,6 @@ import javafx.scene.layout.VBox;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Passport channel configuration editor
|
||||
*/
|
||||
@@ -68,9 +67,9 @@ public class PassportConfigurationEditor extends ChannelConfigurationEditor
|
||||
* @param userPreferences
|
||||
*/
|
||||
public PassportConfigurationEditor(PlaylistManager playlistManager, TunerManager tunerManager,
|
||||
UserPreferences userPreferences)
|
||||
UserPreferences userPreferences, IFilterProcessor filterProcessor)
|
||||
{
|
||||
super(playlistManager, tunerManager, userPreferences);
|
||||
super(playlistManager, tunerManager, userPreferences, filterProcessor);
|
||||
getTitledPanesBox().getChildren().add(getSourcePane());
|
||||
getTitledPanesBox().getChildren().add(getDecoderPane());
|
||||
getTitledPanesBox().getChildren().add(getAuxDecoderPane());
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||
* Copyright (C) 2014-2023 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
|
||||
@@ -45,9 +45,9 @@ public class UnknownConfigurationEditor extends ChannelConfigurationEditor
|
||||
* @param aliasModel
|
||||
*/
|
||||
public UnknownConfigurationEditor(PlaylistManager playlistManager, TunerManager tunerManager,
|
||||
UserPreferences userPreferences)
|
||||
UserPreferences userPreferences, IFilterProcessor filterProcessor)
|
||||
{
|
||||
super(playlistManager, tunerManager, userPreferences);
|
||||
super(playlistManager, tunerManager, userPreferences, filterProcessor);
|
||||
getTitledPanesBox().getChildren().add(getDecoderPane());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||
* Copyright (C) 2014-2023 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
|
||||
@@ -28,6 +28,11 @@ import io.github.dsheirer.audio.broadcast.broadcastify.BroadcastifyFeedConfigura
|
||||
import io.github.dsheirer.playlist.PlaylistManager;
|
||||
import io.github.dsheirer.rrapi.type.UserFeedBroadcast;
|
||||
import io.github.dsheirer.util.ThreadPool;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
@@ -48,6 +53,7 @@ import javafx.scene.control.TabPane;
|
||||
import javafx.scene.control.TableCell;
|
||||
import javafx.scene.control.TableColumn;
|
||||
import javafx.scene.control.TableView;
|
||||
import javafx.scene.control.Tooltip;
|
||||
import javafx.scene.control.cell.PropertyValueFactory;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Priority;
|
||||
@@ -58,12 +64,6 @@ import jiconfont.javafx.IconNode;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Editor for broadcast audio stream configurations
|
||||
*/
|
||||
@@ -75,6 +75,7 @@ public class StreamingEditor extends SplitPane
|
||||
private TableView<ConfiguredBroadcast> mConfiguredBroadcastTableView;
|
||||
private MenuButton mNewButton;
|
||||
private Button mDeleteButton;
|
||||
private Button mRefreshButton;
|
||||
private TabPane mTabPane;
|
||||
private Tab mConfigurationTab;
|
||||
private Tab mAliasTab;
|
||||
@@ -101,7 +102,7 @@ public class StreamingEditor extends SplitPane
|
||||
refreshBroadcastifyStreams();
|
||||
|
||||
VBox buttonsBox = new VBox();
|
||||
buttonsBox.getChildren().addAll(getNewButton(), getDeleteButton());
|
||||
buttonsBox.getChildren().addAll(getNewButton(), getDeleteButton(), getRefreshButton());
|
||||
buttonsBox.setPadding(new Insets(0, 0, 0, 10));
|
||||
buttonsBox.setSpacing(10);
|
||||
|
||||
@@ -231,21 +232,16 @@ public class StreamingEditor extends SplitPane
|
||||
{
|
||||
if(mPlaylistManager.getRadioReference().availableProperty().get())
|
||||
{
|
||||
ThreadPool.CACHED.submit(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
ThreadPool.CACHED.submit(() -> {
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
List<UserFeedBroadcast> feeds = mPlaylistManager.getRadioReference().getService().getUserFeeds();
|
||||
mBroadcastifyFeeds.clear();
|
||||
mBroadcastifyFeeds.addAll(feeds);
|
||||
}
|
||||
catch(Throwable t)
|
||||
{
|
||||
mLog.error("Unable to refresh broadcastify stream configuration(s)");
|
||||
}
|
||||
List<UserFeedBroadcast> feeds = mPlaylistManager.getRadioReference().getService().getUserFeeds();
|
||||
mBroadcastifyFeeds.clear();
|
||||
mBroadcastifyFeeds.addAll(feeds);
|
||||
}
|
||||
catch(Throwable t)
|
||||
{
|
||||
mLog.error("Unable to refresh broadcastify stream configuration(s)");
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -348,6 +344,22 @@ public class StreamingEditor extends SplitPane
|
||||
return mNewButton;
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh broadcastify feeds.
|
||||
* @return button to refresh.
|
||||
*/
|
||||
private Button getRefreshButton()
|
||||
{
|
||||
if(mRefreshButton == null)
|
||||
{
|
||||
mRefreshButton = new Button("Refresh");
|
||||
mRefreshButton.setTooltip(new Tooltip("Refresh streams available from Broadcastify"));
|
||||
mRefreshButton.setOnAction(event -> refreshBroadcastifyStreams());
|
||||
}
|
||||
|
||||
return mRefreshButton;
|
||||
}
|
||||
|
||||
private Button getDeleteButton()
|
||||
{
|
||||
if(mDeleteButton == null)
|
||||
|
||||
@@ -166,12 +166,12 @@ public class PatchGroup
|
||||
|
||||
if(hasPatchedTalkgroups())
|
||||
{
|
||||
sb.append(getPatchedTalkgroupIdentifiers());
|
||||
sb.append(" ").append(getPatchedTalkgroupIdentifiers());
|
||||
}
|
||||
|
||||
if(hasPatchedRadios())
|
||||
{
|
||||
sb.append(getPatchedRadioIdentifiers());
|
||||
sb.append(" ").append(getPatchedRadioIdentifiers());
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*******************************************************************************
|
||||
* sdrtrunk
|
||||
* Copyright (C) 2014-2017 Dennis Sheirer
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2023 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
|
||||
@@ -14,16 +14,13 @@
|
||||
*
|
||||
* 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.properties;
|
||||
|
||||
import io.github.dsheirer.gui.SDRTrunk;
|
||||
import io.github.dsheirer.util.ThreadPool;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.Color;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
@@ -37,6 +34,8 @@ import java.util.Properties;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.jar.Manifest;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* SystemProperties - provides an isolated instance of properties for the application
|
||||
@@ -48,6 +47,7 @@ public class SystemProperties
|
||||
private static String DEFAULT_APP_ROOT = "SDRTrunk";
|
||||
private static String PROPERTIES_FILENAME = "SDRTrunk.properties";
|
||||
private static String MANIFEST_VERSION = "Implementation-Version";
|
||||
private static String BUILD_TIMESTAMP = "Build-Timestamp";
|
||||
|
||||
private static SystemProperties INSTANCE;
|
||||
private static Properties mProperties;
|
||||
@@ -208,11 +208,19 @@ public class SystemProperties
|
||||
if(manifest != null)
|
||||
{
|
||||
String version = manifest.getMainAttributes().getValue(MANIFEST_VERSION);
|
||||
String timestamp = manifest.getMainAttributes().getValue(BUILD_TIMESTAMP);
|
||||
|
||||
if(version != null)
|
||||
{
|
||||
sb.append(" v");
|
||||
sb.append(version);
|
||||
if(version.contains("nightly") && timestamp != null)
|
||||
{
|
||||
sb.append( " nightly - ").append(timestamp);
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.append(" v");
|
||||
sb.append(version);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ public class BinaryRecorder extends Module implements IByteBufferListener
|
||||
private final static Logger mLog = LoggerFactory.getLogger(BinaryRecorder.class);
|
||||
private static final int MAX_RECORDING_BYTE_SIZE = 524288; //500 kB
|
||||
|
||||
private Dispatcher<ByteBuffer> mBufferProcessor = new Dispatcher<>("sdrtrunk binary recorder", 200, 250);
|
||||
private Dispatcher<ByteBuffer> mBufferProcessor = new Dispatcher<>("sdrtrunk binary recorder", 250);
|
||||
private AtomicBoolean mRunning = new AtomicBoolean();
|
||||
private Path mBaseRecordingPath;
|
||||
private String mRecordingIdentifier;
|
||||
|
||||
@@ -44,7 +44,7 @@ public class ComplexSamplesWaveRecorder extends Module implements IComplexSample
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger(ComplexSamplesWaveRecorder.class);
|
||||
|
||||
private Dispatcher<ComplexSamples> mBufferProcessor = new Dispatcher<>("sdrtrunk complex wave recorder", 100, 250);
|
||||
private Dispatcher<ComplexSamples> mBufferProcessor = new Dispatcher<>("sdrtrunk complex wave recorder", 250);
|
||||
private AtomicBoolean mRunning = new AtomicBoolean();
|
||||
private BufferWaveWriter mWriter;
|
||||
private String mFilePrefix;
|
||||
|
||||
@@ -47,7 +47,7 @@ public class NativeBufferWaveRecorder extends Module implements Listener<INative
|
||||
private static final Logger mLog = LoggerFactory.getLogger(ComplexSamplesWaveRecorder.class);
|
||||
private static final long STATUS_UPDATE_BYTE_INTERVAL = 1_048_576;
|
||||
private static final long MAX_RECORDING_SIZE = (long)Integer.MAX_VALUE * 2l;
|
||||
private Dispatcher<INativeBuffer> mBufferProcessor = new Dispatcher<>("sdrtrunk native buffer wave recorder", 100, 250);
|
||||
private Dispatcher<INativeBuffer> mBufferProcessor = new Dispatcher<>("sdrtrunk native buffer wave recorder", 250);
|
||||
|
||||
private AtomicBoolean mRunning = new AtomicBoolean();
|
||||
private NativeBufferWaveWriter mWriter;
|
||||
|
||||
@@ -74,8 +74,7 @@ public class HalfBandTunerChannelSource<T extends INativeBuffer> extends TunerCh
|
||||
mQDecimationFilter = DecimationFilterFactory.getRealDecimationFilter(decimation);
|
||||
|
||||
//Set dispatcher to process 1/10 of estimated sample arrival rate, 20 times per second (up to 200% per interval)
|
||||
mBufferDispatcher = new Dispatcher("sdrtrunk heterodyne channel " + tunerChannel.getFrequency(),
|
||||
(int)(sampleRate / 10), 50, getHeartbeatManager());
|
||||
mBufferDispatcher = new Dispatcher("sdrtrunk heterodyne channel " + tunerChannel.getFrequency(), 50, getHeartbeatManager());
|
||||
mBufferDispatcher.setListener(new NativeBufferProcessor());
|
||||
|
||||
//Setup the frequency mixer to the current source frequency
|
||||
|
||||
@@ -55,7 +55,7 @@ public class PassThroughChannelSource extends TunerChannelSource implements ISou
|
||||
super(listener, tunerChannel);
|
||||
mTunerController = tunerController;
|
||||
mBufferDispatcher = new Dispatcher<>("sdrtrunk pass-through channel " + tunerChannel.getFrequency(),
|
||||
250, 50, getHeartbeatManager());
|
||||
50, getHeartbeatManager());
|
||||
mBufferDispatcher.setListener(new BufferProcessor());
|
||||
}
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ public class SDRplay
|
||||
private static final Logger mLog = LoggerFactory.getLogger(SDRplay.class);
|
||||
|
||||
/**
|
||||
* Foreign memory arenaallocation resource scope
|
||||
* Foreign memory arena allocation resource scope
|
||||
*/
|
||||
private final Arena mArena = Arena.openShared();
|
||||
|
||||
|
||||
@@ -32,7 +32,8 @@ public enum Version
|
||||
V3_08(3.08f, true),
|
||||
V3_09(3.09f, true),
|
||||
V3_10(3.10f, true),
|
||||
V3_11(3.11f, true);
|
||||
V3_11(3.11f, true),
|
||||
V3_12(3.12f, true);
|
||||
|
||||
private float mValue;
|
||||
private boolean mSupported;
|
||||
|
||||
@@ -37,24 +37,24 @@ public class CallbackFunctions
|
||||
|
||||
/**
|
||||
* Constructs a callback functions for single-tuner use.
|
||||
* @param arena for native memory allocation
|
||||
* @param longLifecycleArena for native memory allocation for long lifecycle objects.
|
||||
* @param deviceEventListener for device events
|
||||
* @param streamListener for streaming samples
|
||||
* @param streamCallbackListener for streaming events
|
||||
*/
|
||||
public CallbackFunctions(Arena arena, IDeviceEventListener deviceEventListener,
|
||||
public CallbackFunctions(Arena longLifecycleArena, IDeviceEventListener deviceEventListener,
|
||||
IStreamListener streamListener, IStreamCallbackListener streamCallbackListener)
|
||||
{
|
||||
//Create the event callback function
|
||||
mDeviceEventAdapter = new DeviceEventAdapter(arena, deviceEventListener);
|
||||
MemorySegment eventFunction = sdrplay_api_EventCallback_t.allocate(mDeviceEventAdapter, arena.scope());
|
||||
mDeviceEventAdapter = new DeviceEventAdapter(deviceEventListener);
|
||||
MemorySegment eventFunction = sdrplay_api_EventCallback_t.allocate(mDeviceEventAdapter, longLifecycleArena.scope());
|
||||
|
||||
//Create the stream A callback function
|
||||
mStreamACallbackAdapter = new StreamCallbackAdapter(arena, streamListener, streamCallbackListener);
|
||||
MemorySegment streamAFunction = sdrplay_api_StreamCallback_t.allocate(mStreamACallbackAdapter, arena.scope());
|
||||
mStreamACallbackAdapter = new StreamCallbackAdapter(streamListener, streamCallbackListener);
|
||||
MemorySegment streamAFunction = sdrplay_api_StreamCallback_t.allocate(mStreamACallbackAdapter, longLifecycleArena.scope());
|
||||
|
||||
//Create the callback functions union and populate the callback functions
|
||||
mCallbackFunctionsMemorySegment = sdrplay_api_CallbackFnsT.allocate(arena);
|
||||
mCallbackFunctionsMemorySegment = sdrplay_api_CallbackFnsT.allocate(longLifecycleArena);
|
||||
sdrplay_api_CallbackFnsT.EventCbFn$set(mCallbackFunctionsMemorySegment, eventFunction);
|
||||
sdrplay_api_CallbackFnsT.StreamACbFn$set(mCallbackFunctionsMemorySegment, streamAFunction);
|
||||
}
|
||||
@@ -72,15 +72,15 @@ public class CallbackFunctions
|
||||
IStreamCallbackListener streamCallbackListener)
|
||||
{
|
||||
//Create the event callback function
|
||||
mDeviceEventAdapter = new DeviceEventAdapter(arena, deviceEventListener);
|
||||
mDeviceEventAdapter = new DeviceEventAdapter(deviceEventListener);
|
||||
MemorySegment eventFunction = sdrplay_api_EventCallback_t.allocate(mDeviceEventAdapter, arena.scope());
|
||||
|
||||
//Create the stream A callback function
|
||||
mStreamACallbackAdapter = new StreamCallbackAdapter(arena, streamAListener, streamCallbackListener);
|
||||
mStreamACallbackAdapter = new StreamCallbackAdapter(streamAListener, streamCallbackListener);
|
||||
MemorySegment streamAFunction = sdrplay_api_StreamCallback_t.allocate(mStreamACallbackAdapter, arena.scope());
|
||||
|
||||
//Create the stream B callback function
|
||||
mStreamBCallbackAdapter = new StreamCallbackAdapter(arena, streamBListener, streamCallbackListener);
|
||||
mStreamBCallbackAdapter = new StreamCallbackAdapter(streamBListener, streamCallbackListener);
|
||||
MemorySegment streamBFunction = sdrplay_api_StreamCallback_t.allocate(mStreamBCallbackAdapter, arena.scope());
|
||||
|
||||
//Create the callback functions union and populate the callback functions
|
||||
|
||||
@@ -36,24 +36,14 @@ import org.slf4j.LoggerFactory;
|
||||
public class DeviceEventAdapter implements sdrplay_api_EventCallback_t
|
||||
{
|
||||
private static final Logger mLog = LoggerFactory.getLogger(DeviceEventAdapter.class);
|
||||
|
||||
private Arena mArena;
|
||||
private IDeviceEventListener mDeviceEventListener;
|
||||
|
||||
/**
|
||||
* Constructs an instance.
|
||||
* @param arena to use in creating foreign memory segments to access foreign structures.
|
||||
* @param listener to receive translated device events.
|
||||
*/
|
||||
public DeviceEventAdapter(Arena arena, IDeviceEventListener listener)
|
||||
public DeviceEventAdapter(IDeviceEventListener listener)
|
||||
{
|
||||
if(arena == null)
|
||||
{
|
||||
throw new IllegalArgumentException("Resource scope must be non-null");
|
||||
}
|
||||
|
||||
mArena = arena;
|
||||
|
||||
setListener(listener);
|
||||
}
|
||||
|
||||
@@ -75,35 +65,44 @@ public class DeviceEventAdapter implements sdrplay_api_EventCallback_t
|
||||
public void apply(int eventTypeId, int tunerSelectId, MemorySegment eventParametersPointer,
|
||||
MemorySegment callbackContext)
|
||||
{
|
||||
MemorySegment memorySegment = sdrplay_api_EventParamsT.ofAddress(eventParametersPointer, mArena.scope());
|
||||
EventType eventType = EventType.fromValue(eventTypeId);
|
||||
TunerSelect tunerSelect = TunerSelect.fromValue(tunerSelectId);
|
||||
|
||||
switch(eventType)
|
||||
try(Arena arena = Arena.openConfined())
|
||||
{
|
||||
case GAIN_CHANGE -> {
|
||||
mDeviceEventListener.processGainChange(tunerSelect,
|
||||
EventParametersFactory.createGainCallbackParameters(memorySegment));
|
||||
}
|
||||
case POWER_OVERLOAD_CHANGE -> {
|
||||
mDeviceEventListener.processPowerOverload(tunerSelect,
|
||||
EventParametersFactory.createPowerOverloadCallbackParameters(memorySegment));
|
||||
}
|
||||
case DEVICE_REMOVED -> {
|
||||
mDeviceEventListener.processDeviceRemoval(tunerSelect);
|
||||
}
|
||||
case RSP_DUO_MODE_CHANGE -> {
|
||||
mDeviceEventListener.processRspDuoModeChange(tunerSelect,
|
||||
EventParametersFactory.createRspDuoModeCallbackParameters(memorySegment));
|
||||
}
|
||||
case UNKNOWN -> {
|
||||
mLog.warn("Unknown device event callback ignored. Please contact the library developer as this may " +
|
||||
"indicate a change to the SDRPlay API change. Tuner:" + tunerSelect + " Event Type ID:" +
|
||||
eventTypeId);
|
||||
mDeviceEventListener.processEvent(eventType, tunerSelect);
|
||||
}
|
||||
default -> {
|
||||
throw new IllegalStateException("DeviceEventAdapter must be updated handle EventType." + eventType);
|
||||
MemorySegment memorySegment = sdrplay_api_EventParamsT.ofAddress(eventParametersPointer, arena.scope());
|
||||
EventType eventType = EventType.fromValue(eventTypeId);
|
||||
TunerSelect tunerSelect = TunerSelect.fromValue(tunerSelectId);
|
||||
|
||||
switch(eventType)
|
||||
{
|
||||
case GAIN_CHANGE ->
|
||||
{
|
||||
mDeviceEventListener.processGainChange(tunerSelect,
|
||||
EventParametersFactory.createGainCallbackParameters(memorySegment));
|
||||
}
|
||||
case POWER_OVERLOAD_CHANGE ->
|
||||
{
|
||||
mDeviceEventListener.processPowerOverload(tunerSelect,
|
||||
EventParametersFactory.createPowerOverloadCallbackParameters(memorySegment));
|
||||
}
|
||||
case DEVICE_REMOVED ->
|
||||
{
|
||||
mDeviceEventListener.processDeviceRemoval(tunerSelect);
|
||||
}
|
||||
case RSP_DUO_MODE_CHANGE ->
|
||||
{
|
||||
mDeviceEventListener.processRspDuoModeChange(tunerSelect,
|
||||
EventParametersFactory.createRspDuoModeCallbackParameters(memorySegment));
|
||||
}
|
||||
case UNKNOWN ->
|
||||
{
|
||||
mLog.warn("Unknown device event callback ignored. Please contact the library developer as this may " +
|
||||
"indicate a change to the SDRPlay API change. Tuner:" + tunerSelect + " Event Type ID:" +
|
||||
eventTypeId);
|
||||
mDeviceEventListener.processEvent(eventType, tunerSelect);
|
||||
}
|
||||
default ->
|
||||
{
|
||||
throw new IllegalStateException("DeviceEventAdapter must be updated handle EventType." + eventType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,24 +35,16 @@ import org.slf4j.LoggerFactory;
|
||||
public class StreamCallbackAdapter implements sdrplay_api_StreamCallback_t
|
||||
{
|
||||
private static final Logger mLog = LoggerFactory.getLogger(StreamCallbackAdapter.class);
|
||||
private Arena mArena;
|
||||
private IStreamListener mStreamListener;
|
||||
private IStreamCallbackListener mStreamCallbackListener;
|
||||
|
||||
/**
|
||||
* Constructs an instance of the callback implementation
|
||||
* @param arena for defining new foreign memory segments
|
||||
* @param streamListener to receive transferred I/Q samples and event details
|
||||
* @param listener to receive callback parameters
|
||||
*/
|
||||
public StreamCallbackAdapter(Arena arena, IStreamListener streamListener, IStreamCallbackListener listener)
|
||||
public StreamCallbackAdapter(IStreamListener streamListener, IStreamCallbackListener listener)
|
||||
{
|
||||
if(arena == null)
|
||||
{
|
||||
throw new IllegalArgumentException("Arena must be non-null");
|
||||
}
|
||||
|
||||
mArena = arena;
|
||||
mStreamCallbackListener = listener;
|
||||
setListener(streamListener);
|
||||
}
|
||||
@@ -81,24 +73,27 @@ public class StreamCallbackAdapter implements sdrplay_api_StreamCallback_t
|
||||
{
|
||||
if(mStreamListener != null || mStreamCallbackListener != null)
|
||||
{
|
||||
//Translate the callback parameters pointer to a memory segment and re-construct the parameters as a Java object
|
||||
StreamCallbackParameters parameters = new StreamCallbackParameters(sdrplay_api_StreamCbParamsT
|
||||
.ofAddress(parametersPointer, mArena.scope()));
|
||||
|
||||
if(mStreamCallbackListener != null)
|
||||
try(Arena arena = Arena.openConfined())
|
||||
{
|
||||
mStreamCallbackListener.process(mStreamListener.getTunerSelect(), parameters, reset);
|
||||
}
|
||||
//Translate the callback parameters pointer to a memory segment and re-construct the parameters as a Java object
|
||||
StreamCallbackParameters parameters = new StreamCallbackParameters(sdrplay_api_StreamCbParamsT
|
||||
.ofAddress(parametersPointer, arena.scope()));
|
||||
|
||||
if(mStreamListener != null)
|
||||
{
|
||||
//Allocate memory segments from I/Q pointers, transfer from native to JVM array, and send to listener
|
||||
long arrayByteSize = ValueLayout.JAVA_SHORT.byteSize() * sampleCount;
|
||||
MemorySegment iSamples = MemorySegment.ofAddress(iSamplesPointer.address(), arrayByteSize, mArena.scope());
|
||||
MemorySegment qSamples = MemorySegment.ofAddress(qSamplesPointer.address(), arrayByteSize, mArena.scope());
|
||||
short[] i = iSamples.toArray(ValueLayout.JAVA_SHORT);
|
||||
short[] q = qSamples.toArray(ValueLayout.JAVA_SHORT);
|
||||
mStreamListener.processStream(i, q, parameters, Flag.evaluate(reset));
|
||||
if(mStreamCallbackListener != null)
|
||||
{
|
||||
mStreamCallbackListener.process(mStreamListener.getTunerSelect(), parameters, reset);
|
||||
}
|
||||
|
||||
if(mStreamListener != null)
|
||||
{
|
||||
//Allocate memory segments from I/Q pointers, transfer from native to JVM array, and send to listener
|
||||
long arrayByteSize = ValueLayout.JAVA_SHORT.byteSize() * sampleCount;
|
||||
MemorySegment iSamples = MemorySegment.ofAddress(iSamplesPointer.address(), arrayByteSize, arena.scope());
|
||||
MemorySegment qSamples = MemorySegment.ofAddress(qSamplesPointer.address(), arrayByteSize, arena.scope());
|
||||
short[] i = iSamples.toArray(ValueLayout.JAVA_SHORT);
|
||||
short[] q = qSamples.toArray(ValueLayout.JAVA_SHORT);
|
||||
mStreamListener.processStream(i, q, parameters, Flag.evaluate(reset));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,46 +41,35 @@ import org.slf4j.LoggerFactory;
|
||||
public class Dispatcher<E> implements Listener<E>
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger(Dispatcher.class);
|
||||
private static final long OVERFLOW_LOG_EVENT_WAIT_PERIOD = TimeUnit.SECONDS.toMillis(10);
|
||||
private LinkedTransferQueue<E> mQueue = new LinkedTransferQueue<>();
|
||||
private final LinkedTransferQueue<E> mQueue = new LinkedTransferQueue<>();
|
||||
private Listener<E> mListener;
|
||||
private AtomicBoolean mRunning = new AtomicBoolean();
|
||||
private String mThreadName;
|
||||
private final AtomicBoolean mRunning = new AtomicBoolean();
|
||||
private final String mThreadName;
|
||||
private ScheduledExecutorService mExecutorService;
|
||||
private ScheduledFuture<?> mScheduledFuture;
|
||||
private int mBatchSize;
|
||||
private long mInterval;
|
||||
private final long mInterval;
|
||||
private HeartbeatManager mHeartbeatManager;
|
||||
|
||||
/**
|
||||
* Constructs an instance of a Dispatcher with integrated heartbeat support.
|
||||
* @param threadName to name the dispatcher thread
|
||||
* @param batchSize is maximum number of elements to process from the queue per interval. This should be sized to
|
||||
* the anticipated number of elements per second, divided by the number of intervals per second and increased by
|
||||
* a factor of two. This serves to constrain how many elements are processed per interval when the queue starts
|
||||
* to back up, so that the thread doesn't dominate CPU resources.
|
||||
* @param interval for processing each batch in milliseconds.
|
||||
* @param heartbeatManager to receive a heartbeat command at each processing interval.
|
||||
*/
|
||||
public Dispatcher(String threadName, int batchSize, long interval, HeartbeatManager heartbeatManager)
|
||||
public Dispatcher(String threadName, long interval, HeartbeatManager heartbeatManager)
|
||||
{
|
||||
this(threadName, batchSize, interval);
|
||||
this(threadName, interval);
|
||||
mHeartbeatManager = heartbeatManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an instance
|
||||
* @param threadName to name the dispatcher thread
|
||||
* @param batchSize is maximum number of elements to process from the queue per interval. This should be sized to
|
||||
* the anticipated number of elements per second, divided by the number of intervals per second and increased by
|
||||
* a factor of two. This serves to constrain how many elements are processed per interval when the queue starts
|
||||
* to back up, so that the thread doesn't dominate CPU resources.
|
||||
* @param interval for processing each batch in milliseconds.
|
||||
*/
|
||||
public Dispatcher(String threadName, int batchSize, long interval)
|
||||
public Dispatcher(String threadName, long interval)
|
||||
{
|
||||
mThreadName = threadName;
|
||||
mBatchSize = batchSize;
|
||||
mInterval = interval;
|
||||
}
|
||||
|
||||
@@ -171,7 +160,7 @@ public class Dispatcher<E> implements Listener<E>
|
||||
{
|
||||
List<E> elements = new ArrayList<>();
|
||||
|
||||
mQueue.drainTo(elements, mBatchSize);
|
||||
mQueue.drainTo(elements);
|
||||
|
||||
for(E element: elements)
|
||||
{
|
||||
@@ -195,7 +184,7 @@ public class Dispatcher<E> implements Listener<E>
|
||||
*/
|
||||
class Processor implements Runnable
|
||||
{
|
||||
private AtomicBoolean mRunning = new AtomicBoolean();
|
||||
private final AtomicBoolean mRunning = new AtomicBoolean();
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
@@ -214,7 +203,7 @@ public class Dispatcher<E> implements Listener<E>
|
||||
*/
|
||||
class ProcessorWithHeartbeat implements Runnable
|
||||
{
|
||||
private AtomicBoolean mRunning = new AtomicBoolean();
|
||||
private final AtomicBoolean mRunning = new AtomicBoolean();
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
|
||||
Reference in New Issue
Block a user